50static bool inRange(
const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,
51 bool AllowSymbol =
false) {
53 int64_t
Value = CE->getValue();
99 SMLoc StartLoc, EndLoc;
128 unsigned MemKind : 4;
129 unsigned RegKind : 4;
152 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
163 SystemZOperand(OperandKind Kind, SMLoc StartLoc, SMLoc EndLoc)
164 : Kind(Kind), StartLoc(StartLoc), EndLoc(EndLoc) {}
167 static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
169 return std::make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
172 static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
173 auto Op = std::make_unique<SystemZOperand>(KindToken, Loc, Loc);
174 Op->Token.Data = Str.data();
175 Op->Token.Length = Str.size();
179 static std::unique_ptr<SystemZOperand>
180 createReg(RegisterKind Kind,
unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
181 auto Op = std::make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
187 static std::unique_ptr<SystemZOperand>
188 createImm(
const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
189 auto Op = std::make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
194 static std::unique_ptr<SystemZOperand>
195 createMem(MemoryKind MemKind, RegisterKind RegKind,
unsigned Base,
196 const MCExpr *Disp,
unsigned Index,
const MCExpr *LengthImm,
197 unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {
198 auto Op = std::make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
199 Op->Mem.MemKind = MemKind;
200 Op->Mem.RegKind = RegKind;
204 if (MemKind == BDLMem)
205 Op->Mem.Length.Imm = LengthImm;
206 if (MemKind == BDRMem)
207 Op->Mem.Length.Reg = LengthReg;
211 static std::unique_ptr<SystemZOperand>
212 createImmTLS(
const MCExpr *Imm,
const MCExpr *Sym,
213 SMLoc StartLoc, SMLoc EndLoc) {
214 auto Op = std::make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
215 Op->ImmTLS.Imm =
Imm;
216 Op->ImmTLS.Sym = Sym;
221 bool isToken()
const override {
222 return Kind == KindToken;
225 assert(Kind == KindToken &&
"Not a token");
226 return StringRef(Token.Data, Token.Length);
230 bool isReg()
const override {
231 return Kind == KindReg;
233 bool isReg(RegisterKind RegKind)
const {
234 return Kind == KindReg &&
Reg.Kind == RegKind;
236 MCRegister
getReg()
const override {
237 assert(Kind == KindReg &&
"Not a register");
242 bool isImm()
const override {
243 return Kind == KindImm;
245 bool isImm(int64_t MinValue, int64_t MaxValue)
const {
246 return Kind == KindImm &&
inRange(Imm, MinValue, MaxValue,
true);
248 const MCExpr *
getImm()
const {
249 assert(Kind == KindImm &&
"Not an immediate");
254 bool isImmTLS()
const {
255 return Kind == KindImmTLS;
258 const ImmTLSOp getImmTLS()
const {
259 assert(Kind == KindImmTLS &&
"Not a TLS immediate");
264 bool isMem()
const override {
265 return Kind == KindMem;
267 bool isMem(MemoryKind MemKind)
const {
268 return (Kind == KindMem &&
269 (Mem.MemKind == MemKind ||
272 (Mem.MemKind == BDMem && MemKind == BDXMem)));
274 bool isMem(MemoryKind MemKind, RegisterKind RegKind)
const {
275 return isMem(MemKind) && Mem.RegKind == RegKind;
277 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind)
const {
278 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, 0, 0xfff,
true);
280 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind)
const {
281 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, -524288, 524287,
true);
283 bool isMemDisp12Len4(RegisterKind RegKind)
const {
284 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x10);
286 bool isMemDisp12Len8(RegisterKind RegKind)
const {
287 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x100);
290 const MemOp& getMem()
const {
291 assert(Kind == KindMem &&
"Not a Mem operand");
296 SMLoc getStartLoc()
const override {
return StartLoc; }
297 SMLoc getEndLoc()
const override {
return EndLoc; }
298 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
302 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
306 void addRegOperands(MCInst &Inst,
unsigned N)
const {
307 assert(
N == 1 &&
"Invalid number of operands");
310 void addImmOperands(MCInst &Inst,
unsigned N)
const {
311 assert(
N == 1 &&
"Invalid number of operands");
314 void addBDAddrOperands(MCInst &Inst,
unsigned N)
const {
315 assert(
N == 2 &&
"Invalid number of operands");
318 addExpr(Inst, Mem.Disp);
320 void addBDXAddrOperands(MCInst &Inst,
unsigned N)
const {
321 assert(
N == 3 &&
"Invalid number of operands");
324 addExpr(Inst, Mem.Disp);
327 void addBDLAddrOperands(MCInst &Inst,
unsigned N)
const {
328 assert(
N == 3 &&
"Invalid number of operands");
331 addExpr(Inst, Mem.Disp);
332 addExpr(Inst, Mem.Length.Imm);
334 void addBDRAddrOperands(MCInst &Inst,
unsigned N)
const {
335 assert(
N == 3 &&
"Invalid number of operands");
338 addExpr(Inst, Mem.Disp);
341 void addBDVAddrOperands(MCInst &Inst,
unsigned N)
const {
342 assert(
N == 3 &&
"Invalid number of operands");
345 addExpr(Inst, Mem.Disp);
348 void addLXAAddrOperands(MCInst &Inst,
unsigned N)
const {
349 assert(
N == 3 &&
"Invalid number of operands");
352 addExpr(Inst, Mem.Disp);
355 void addImmTLSOperands(MCInst &Inst,
unsigned N)
const {
356 assert(
N == 2 &&
"Invalid number of operands");
357 assert(Kind == KindImmTLS &&
"Invalid operand type");
358 addExpr(Inst, ImmTLS.Imm);
360 addExpr(Inst, ImmTLS.Sym);
364 bool isGR32()
const {
return isReg(GR32Reg); }
365 bool isGRH32()
const {
return isReg(GRH32Reg); }
366 bool isGRX32()
const {
return false; }
367 bool isGR64()
const {
return isReg(GR64Reg); }
368 bool isGR128()
const {
return isReg(GR128Reg); }
369 bool isADDR32()
const {
return isReg(GR32Reg); }
370 bool isADDR64()
const {
return isReg(GR64Reg); }
371 bool isADDR128()
const {
return false; }
372 bool isFP16()
const {
return isReg(FP16Reg); }
373 bool isFP32()
const {
return isReg(FP32Reg); }
374 bool isFP64()
const {
return isReg(FP64Reg); }
375 bool isFP128()
const {
return isReg(FP128Reg); }
376 bool isVR16()
const {
return isReg(VR16Reg); }
377 bool isVR32()
const {
return isReg(VR32Reg); }
378 bool isVR64()
const {
return isReg(VR64Reg); }
379 bool isVF128()
const {
return false; }
380 bool isVR128()
const {
return isReg(VR128Reg); }
381 bool isAR32()
const {
return isReg(AR32Reg); }
382 bool isCR64()
const {
return isReg(CR64Reg); }
383 bool isAnyReg()
const {
return (
isReg() || isImm(0, 15)); }
384 bool isBDAddr32Disp12()
const {
return isMemDisp12(BDMem, GR32Reg); }
385 bool isBDAddr32Disp20()
const {
return isMemDisp20(BDMem, GR32Reg); }
386 bool isBDAddr64Disp12()
const {
return isMemDisp12(BDMem, GR64Reg); }
387 bool isBDAddr64Disp20()
const {
return isMemDisp20(BDMem, GR64Reg); }
388 bool isBDXAddr64Disp12()
const {
return isMemDisp12(BDXMem, GR64Reg); }
389 bool isBDXAddr64Disp20()
const {
return isMemDisp20(BDXMem, GR64Reg); }
390 bool isBDLAddr64Disp12Len4()
const {
return isMemDisp12Len4(GR64Reg); }
391 bool isBDLAddr64Disp12Len8()
const {
return isMemDisp12Len8(GR64Reg); }
392 bool isBDRAddr64Disp12()
const {
return isMemDisp12(BDRMem, GR64Reg); }
393 bool isBDVAddr64Disp12()
const {
return isMemDisp12(BDVMem, GR64Reg); }
394 bool isLXAAddr64Disp20()
const {
return isMemDisp20(LXAMem, GR64Reg); }
395 bool isU1Imm()
const {
return isImm(0, 1); }
396 bool isU2Imm()
const {
return isImm(0, 3); }
397 bool isU3Imm()
const {
return isImm(0, 7); }
398 bool isU4Imm()
const {
return isImm(0, 15); }
399 bool isU8Imm()
const {
return isImm(0, 255); }
400 bool isS8Imm()
const {
return isImm(-128, 127); }
401 bool isU12Imm()
const {
return isImm(0, 4095); }
402 bool isU16Imm()
const {
return isImm(0, 65535); }
403 bool isS16Imm()
const {
return isImm(-32768, 32767); }
404 bool isU32Imm()
const {
return isImm(0, (1LL << 32) - 1); }
405 bool isS32Imm()
const {
return isImm(-(1LL << 31), (1LL << 31) - 1); }
406 bool isU48Imm()
const {
return isImm(0, (1LL << 48) - 1); }
410#define GET_ASSEMBLER_HEADER
411#include "SystemZGenAsmMatcher.inc"
431 SMLoc StartLoc, EndLoc;
434 SystemZTargetStreamer &getTargetStreamer() {
435 assert(getParser().getStreamer().getTargetStreamer() &&
436 "do not have a target streamer");
437 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
438 return static_cast<SystemZTargetStreamer &
>(TS);
441 bool parseRegister(Register &
Reg,
bool RequirePercent,
442 bool RestoreOnFailure =
false);
444 bool parseIntegerRegister(Register &
Reg, RegisterGroup Group);
450 bool parseAddress(
bool &HaveReg1, Register &Reg1,
bool &HaveReg2,
451 Register &Reg2,
const MCExpr *&Disp,
const MCExpr *&
Length,
452 bool HasLength =
false,
bool HasVectorIndex =
false);
453 bool parseAddressRegister(Register &
Reg);
455 bool parseDirectiveInsn(SMLoc L);
456 bool parseDirectiveMachine(SMLoc L);
457 bool parseGNUAttribute(SMLoc L);
460 RegisterKind RegKind);
463 int64_t MaxVal,
bool AllowTLS);
484 unsigned getMAIAssemblerDialect() {
485 return Parser.getContext().getAsmInfo().getAssemblerDialect();
490 inline bool isHLASMAlpha(
char C) {
495 inline bool isHLASMAlnum(
char C) {
return isHLASMAlpha(
C) ||
isDigit(
C); }
498 inline bool isParsingHLASM() {
return getMAIAssemblerDialect() ==
AD_HLASM; }
501 inline bool isParsingGNU() {
return getMAIAssemblerDialect() ==
AD_GNU; }
504 SystemZAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
505 const MCInstrInfo &MII)
506 : MCTargetAsmParser(sti, MII), Parser(parser) {
513 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
517 ParseStatus parseDirective(AsmToken DirectiveID)
override;
518 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
519 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
520 bool RequirePercent,
bool RestoreOnFailure);
521 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
522 SMLoc &EndLoc)
override;
523 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
525 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
528 bool MatchingInlineAsm)
override;
529 bool isLabel(AsmToken &Token)
override;
533 return parseRegister(
Operands, GR32Reg);
536 return parseRegister(
Operands, GRH32Reg);
542 return parseRegister(
Operands, GR64Reg);
545 return parseRegister(
Operands, GR128Reg);
549 return parseRegister(
Operands, GR32Reg);
553 return parseRegister(
Operands, GR64Reg);
559 return parseRegister(
Operands, FP16Reg);
562 return parseRegister(
Operands, FP32Reg);
565 return parseRegister(
Operands, FP64Reg);
568 return parseRegister(
Operands, FP128Reg);
571 return parseRegister(
Operands, VR16Reg);
574 return parseRegister(
Operands, VR32Reg);
577 return parseRegister(
Operands, VR64Reg);
583 return parseRegister(
Operands, VR128Reg);
586 return parseRegister(
Operands, AR32Reg);
589 return parseRegister(
Operands, CR64Reg);
595 return parseAddress(
Operands, BDMem, GR32Reg);
598 return parseAddress(
Operands, BDMem, GR64Reg);
601 return parseAddress(
Operands, BDXMem, GR64Reg);
604 return parseAddress(
Operands, BDLMem, GR64Reg);
607 return parseAddress(
Operands, BDRMem, GR64Reg);
610 return parseAddress(
Operands, BDVMem, GR64Reg);
613 return parseAddress(
Operands, LXAMem, GR64Reg);
616 return parsePCRel(
Operands, -(1LL << 12), (1LL << 12) - 1,
false);
619 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
false);
622 return parsePCRel(
Operands, -(1LL << 24), (1LL << 24) - 1,
false);
625 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
false);
628 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
true);
631 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
true);
637#define GET_REGISTER_MATCHER
638#define GET_SUBTARGET_FEATURE_NAME
639#define GET_MATCHER_IMPLEMENTATION
640#define GET_MNEMONIC_SPELL_CHECKER
641#include "SystemZGenAsmMatcher.inc"
655 return LHS.Format < RHS;
658 return LHS < RHS.Format;
661 return LHS.Format < RHS.Format;
668 {
"e", SystemZ::InsnE, 1,
670 {
"ri", SystemZ::InsnRI, 3,
671 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
672 {
"rie", SystemZ::InsnRIE, 4,
673 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
674 {
"ril", SystemZ::InsnRIL, 3,
675 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
676 {
"rilu", SystemZ::InsnRILU, 3,
677 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
678 {
"ris", SystemZ::InsnRIS, 5,
679 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
680 {
"rr", SystemZ::InsnRR, 3,
681 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
682 {
"rre", SystemZ::InsnRRE, 3,
683 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
684 {
"rrf", SystemZ::InsnRRF, 5,
685 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
686 {
"rrs", SystemZ::InsnRRS, 5,
687 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
688 {
"rs", SystemZ::InsnRS, 4,
689 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
690 {
"rse", SystemZ::InsnRSE, 4,
691 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
692 {
"rsi", SystemZ::InsnRSI, 4,
693 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
694 {
"rsy", SystemZ::InsnRSY, 4,
695 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
696 {
"rx", SystemZ::InsnRX, 3,
697 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
698 {
"rxe", SystemZ::InsnRXE, 3,
699 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
700 {
"rxf", SystemZ::InsnRXF, 4,
701 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
702 {
"rxy", SystemZ::InsnRXY, 3,
703 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
704 {
"s", SystemZ::InsnS, 2,
705 { MCK_U32Imm, MCK_BDAddr64Disp12 } },
706 {
"si", SystemZ::InsnSI, 3,
707 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
708 {
"sil", SystemZ::InsnSIL, 3,
709 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
710 {
"siy", SystemZ::InsnSIY, 3,
711 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
712 {
"ss", SystemZ::InsnSS, 4,
713 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
714 {
"sse", SystemZ::InsnSSE, 3,
715 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
716 {
"ssf", SystemZ::InsnSSF, 4,
717 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
718 {
"vri", SystemZ::InsnVRI, 6,
719 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
720 {
"vrr", SystemZ::InsnVRR, 7,
721 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
723 {
"vrs", SystemZ::InsnVRS, 5,
724 { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
725 {
"vrv", SystemZ::InsnVRV, 4,
726 { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
727 {
"vrx", SystemZ::InsnVRX, 4,
728 { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
729 {
"vsi", SystemZ::InsnVSI, 4,
730 { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }
748 if (getImmTLS().Sym) {
754 const MemOp &
Op = getMem();
759 if (
Op.MemKind == BDLMem) {
762 }
else if (
Op.MemKind == BDRMem)
777bool SystemZAsmParser::parseRegister(
Register &
Reg,
bool RequirePercent,
778 bool RestoreOnFailure) {
779 const AsmToken &PercentTok = Parser.
getTok();
785 return Error(PercentTok.
getLoc(),
"register expected");
793 if (RestoreOnFailure && HasPercent)
794 getLexer().UnLex(PercentTok);
796 HasPercent ?
"invalid register" :
"register expected");
801 if (
Name.size() < 2) {
802 if (RestoreOnFailure && HasPercent)
803 getLexer().UnLex(PercentTok);
804 return Error(
Reg.StartLoc,
"invalid register");
809 if (
Name.substr(1).getAsInteger(10,
Reg.Num)) {
810 if (RestoreOnFailure && HasPercent)
811 getLexer().UnLex(PercentTok);
812 return Error(
Reg.StartLoc,
"invalid register");
816 if (Prefix ==
'r' &&
Reg.Num < 16)
818 else if (Prefix ==
'f' &&
Reg.Num < 16)
820 else if (Prefix ==
'v' &&
Reg.Num < 32)
822 else if (Prefix ==
'a' &&
Reg.Num < 16)
824 else if (Prefix ==
'c' &&
Reg.Num < 16)
827 if (RestoreOnFailure && HasPercent)
828 getLexer().UnLex(PercentTok);
829 return Error(
Reg.StartLoc,
"invalid register");
871 if (parseRegister(
Reg,
true))
881 if (Group !=
Reg.Group)
882 return Error(
Reg.StartLoc,
"invalid operand for instruction");
885 if (
Reg.Group != RegV &&
Reg.Group != RegFP)
886 return Error(
Reg.StartLoc,
"invalid operand for instruction");
890 if (parseIntegerRegister(
Reg, Group))
899 const unsigned *Regs;
917 if (Regs[
Reg.Num] == 0)
918 return Error(
Reg.StartLoc,
"invalid register pair");
921 SystemZOperand::createReg(Kind, Regs[
Reg.Num],
Reg.StartLoc,
Reg.EndLoc));
936 int64_t
Value =
CE->getValue();
938 return Error(StartLoc,
"invalid register");
947 if (isParsingHLASM())
951 if (parseRegister(
Reg,
true))
955 return Error(StartLoc,
"invalid register");
960 if (
Reg.Group == RegGR) {
964 else if (
Reg.Group == RegFP) {
968 else if (
Reg.Group == RegV) {
972 else if (
Reg.Group == RegAR) {
976 else if (
Reg.Group == RegCR) {
984 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
985 Reg.StartLoc,
Reg.EndLoc));
990bool SystemZAsmParser::parseIntegerRegister(
Register &
Reg,
991 RegisterGroup Group) {
1002 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
1003 int64_t
Value =
CE->getValue();
1019bool SystemZAsmParser::parseAddress(
bool &HaveReg1,
Register &Reg1,
1021 const MCExpr *&Disp,
const MCExpr *&
Length,
1022 bool HasLength,
bool HasVectorIndex) {
1024 if (getParser().parseExpression(Disp))
1050 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
1058 if (parseRegister(Reg1,
true))
1069 if (getParser().parseExpression(
Length))
1077 if (parseIntegerRegister(Reg1, RegGroup))
1084 if (getParser().parseExpression(
Length))
1095 if (parseIntegerRegister(Reg2, RegGR))
1097 }
else if (isParsingGNU()) {
1099 if (parseRegister(Reg2,
true))
1105 Reg2.StartLoc = Reg2.EndLoc = Parser.
getTok().
getLoc();
1120SystemZAsmParser::parseAddressRegister(
Register &
Reg) {
1121 if (
Reg.Group == RegV) {
1122 Error(
Reg.StartLoc,
"invalid use of vector addressing");
1125 if (
Reg.Group != RegGR) {
1126 Error(
Reg.StartLoc,
"invalid address register");
1136 RegisterKind RegKind) {
1138 unsigned Base = 0,
Index = 0, LengthReg = 0;
1140 bool HaveReg1, HaveReg2;
1144 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1145 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1146 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1150 const unsigned *Regs;
1161 if (parseAddressRegister(Reg1))
1163 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1167 return Error(StartLoc,
"invalid use of indexed addressing");
1173 const unsigned *IndexRegs = Regs;
1174 if (MemKind == LXAMem)
1177 if (parseAddressRegister(Reg1))
1182 if (HaveReg2 || isParsingHLASM())
1183 Index = Reg1.Num == 0 ? 0 : IndexRegs[Reg1.Num];
1185 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1189 if (parseAddressRegister(Reg2))
1191 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1197 if (parseAddressRegister(Reg2))
1199 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1202 if (HaveReg1 && HaveReg2)
1203 return Error(StartLoc,
"invalid use of indexed addressing");
1206 return Error(StartLoc,
"missing length in address");
1210 if (!HaveReg1 || Reg1.Group != RegGR)
1211 return Error(StartLoc,
"invalid operand for instruction");
1215 if (parseAddressRegister(Reg2))
1217 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1222 if (!HaveReg1 || Reg1.Group != RegV)
1223 return Error(StartLoc,
"vector index required in address");
1227 if (isParsingGNU() && !HaveReg2)
1228 return Error(Reg1.StartLoc,
"invalid use of vector addressing");
1231 if (parseAddressRegister(Reg2))
1233 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1240 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1241 Index,
Length, LengthReg,
1246ParseStatus SystemZAsmParser::parseDirective(AsmToken DirectiveID) {
1249 if (IDVal ==
".insn")
1250 return parseDirectiveInsn(DirectiveID.
getLoc());
1251 if (IDVal ==
".machine")
1252 return parseDirectiveMachine(DirectiveID.
getLoc());
1254 return parseGNUAttribute(DirectiveID.
getLoc());
1261bool SystemZAsmParser::parseDirectiveInsn(SMLoc L) {
1262 MCAsmParser &Parser = getParser();
1268 return Error(ErrorLoc,
"expected instruction format");
1278 if (EntryRange.first == EntryRange.second)
1279 return Error(ErrorLoc,
"unrecognized format");
1281 struct InsnMatchEntry *
Entry = EntryRange.first;
1287 for (
int I = 0;
I <
Entry->NumOperands;
I++) {
1288 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1294 return Error(StartLoc,
"unexpected token in directive");
1299 if (Kind == MCK_AnyReg)
1301 else if (Kind == MCK_VR128)
1303 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1305 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1307 else if (Kind == MCK_BDVAddr64Disp12)
1309 else if (Kind == MCK_LXAAddr64Disp20)
1311 else if (Kind == MCK_PCRel32)
1313 else if (Kind == MCK_PCRel16)
1322 return Error(StartLoc,
"unexpected token in directive");
1327 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1336 MCInst Inst = MCInstBuilder(
Entry->Opcode);
1339 MCParsedAsmOperand &Operand = *
Operands[
I];
1340 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1343 unsigned Res = validateOperandClass(Operand, Kind, *STI);
1344 if (Res != Match_Success)
1348 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1349 if (ZOperand.isReg())
1350 ZOperand.addRegOperands(Inst, 1);
1351 else if (ZOperand.isMem(BDMem))
1352 ZOperand.addBDAddrOperands(Inst, 2);
1353 else if (ZOperand.isMem(BDXMem))
1354 ZOperand.addBDXAddrOperands(Inst, 3);
1355 else if (ZOperand.isMem(BDVMem))
1356 ZOperand.addBDVAddrOperands(Inst, 3);
1357 else if (ZOperand.isMem(LXAMem))
1358 ZOperand.addLXAAddrOperands(Inst, 3);
1359 else if (ZOperand.isImm())
1360 ZOperand.addImmOperands(Inst, 1);
1373bool SystemZAsmParser::parseDirectiveMachine(SMLoc L) {
1374 MCAsmParser &Parser = getParser();
1377 return TokError(
"unexpected token in '.machine' directive");
1389 MachineStack.
push_back(getAvailableFeatures());
1390 }
else if (Id ==
"pop") {
1392 if (MachineStack.
empty())
1394 "pop without corresponding push in '.machine' directive");
1395 setAvailableFeatures(MachineStack.
back());
1400 MCSubtargetInfo &STI = copySTI();
1402 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1404 getTargetStreamer().emitMachine(Id);
1409bool SystemZAsmParser::parseGNUAttribute(SMLoc L) {
1411 int64_t IntegerValue;
1413 return Error(L,
"malformed .gnu_attribute directive");
1416 if (
Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))
1417 return Error(L,
"unrecognized .gnu_attribute tag/value pair.");
1424bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1425 SMLoc &EndLoc,
bool RequirePercent,
1426 bool RestoreOnFailure) {
1428 if (parseRegister(
Reg, RequirePercent, RestoreOnFailure))
1430 if (
Reg.Group == RegGR)
1432 else if (
Reg.Group == RegFP)
1434 else if (
Reg.Group == RegV)
1436 else if (
Reg.Group == RegAR)
1438 else if (
Reg.Group == RegCR)
1440 StartLoc =
Reg.StartLoc;
1441 EndLoc =
Reg.EndLoc;
1445bool SystemZAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1447 return ParseRegister(
Reg, StartLoc, EndLoc,
false,
1451ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1453 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
false,
1455 bool PendingErrors = getParser().hasPendingError();
1456 getParser().clearPendingErrors();
1464bool SystemZAsmParser::parseInstruction(ParseInstructionInfo &Info,
1465 StringRef Name, SMLoc NameLoc,
1472 Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
1477 if (parseOperand(
Operands, Name)) {
1488 "No space allowed between comma that separates operand entries");
1490 if (parseOperand(
Operands, Name)) {
1501 StringRef
Remark(getLexer().LexUntilEndOfStatement());
1513 getStreamer().AddComment(
Remark);
1517 SMLoc Loc = getLexer().getLoc();
1518 return Error(Loc,
"unexpected token in argument list");
1528 StringRef Mnemonic) {
1534 FeatureBitset AvailableFeatures = getAvailableFeatures();
1537 setAvailableFeatures(
All);
1538 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic);
1539 setAvailableFeatures(AvailableFeatures);
1555 if (parseRegister(
Reg,
true))
1557 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1566 bool HaveReg1, HaveReg2;
1569 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1574 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1575 && parseAddressRegister(Reg1))
1577 if (HaveReg2 && parseAddressRegister(Reg2))
1582 if (HaveReg1 || HaveReg2 ||
Length)
1583 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1585 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1589bool SystemZAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1592 uint64_t &ErrorInfo,
1593 bool MatchingInlineAsm) {
1595 unsigned MatchResult;
1597 unsigned Dialect = getMAIAssemblerDialect();
1599 FeatureBitset MissingFeatures;
1600 MatchResult = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
1601 MatchingInlineAsm, Dialect);
1602 switch (MatchResult) {
1608 case Match_MissingFeature: {
1609 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1612 std::string
Msg =
"instruction requires:";
1613 for (
unsigned I = 0,
E = MissingFeatures.
size();
I !=
E; ++
I) {
1614 if (MissingFeatures[
I]) {
1622 case Match_InvalidOperand: {
1623 SMLoc ErrorLoc = IDLoc;
1624 if (ErrorInfo != ~0ULL) {
1626 return Error(IDLoc,
"too few operands for instruction");
1628 ErrorLoc = ((SystemZOperand &)*
Operands[ErrorInfo]).getStartLoc();
1629 if (ErrorLoc == SMLoc())
1632 return Error(ErrorLoc,
"invalid operand for instruction");
1635 case Match_MnemonicFail: {
1636 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1637 std::string Suggestion = SystemZMnemonicSpellCheck(
1639 return Error(IDLoc,
"invalid instruction" + Suggestion,
1640 ((SystemZOperand &)*
Operands[0]).getLocRange());
1648 int64_t MinVal, int64_t MaxVal,
1651 MCStreamer &Out = getStreamer();
1654 if (getParser().parseExpression(Expr))
1657 auto IsOutOfRangeConstant = [&](
const MCExpr *
E,
bool Negate) ->
bool {
1659 int64_t
Value =
CE->getValue();
1671 if (isParsingHLASM())
1672 return Error(StartLoc,
"Expected PC-relative expression");
1673 if (IsOutOfRangeConstant(CE,
false))
1674 return Error(StartLoc,
"offset out of range");
1675 int64_t
Value =
CE->getValue();
1685 if (IsOutOfRangeConstant(BE->getLHS(),
false) ||
1686 IsOutOfRangeConstant(BE->getRHS(),
1688 return Error(StartLoc,
"offset out of range");
1691 const MCExpr *Sym =
nullptr;
1700 if (Name ==
"tls_gdcall")
1702 else if (Name ==
"tls_ldcall")
1725 Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1728 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1733bool SystemZAsmParser::isLabel(AsmToken &Token) {
1749 SMLoc Loc = Token.
getLoc();
1752 if (!RawLabel.
size())
1753 return !
Error(Loc,
"HLASM Label cannot be empty");
1756 if (RawLabel.
size() > 63)
1757 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1760 if (!isHLASMAlpha(RawLabel[0]))
1761 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1762 "character or the underscore character");
1767 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1768 if (!isHLASMAlnum(RawLabel[
I]))
1769 return !
Error(Loc,
"HLASM Label has to be alphanumeric");
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Function Alias Analysis false
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file defines the SmallVector class.
static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue, bool AllowSymbol=false)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmParser()
static struct InsnMatchEntry InsnMatchTable[]
LLVM_ABI SMLoc getLoc() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
constexpr size_t size() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Generic assembler parser interface, for use by target specific assembly parsers.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
bool parseGNUAttribute(SMLoc L, int64_t &Tag, int64_t &IntegerValue)
Parse a .gnu_attribute.
MCStreamer & getStreamer()
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
void addOperand(const MCOperand Op)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual void emitGNUAttribute(unsigned Tag, unsigned Value)
Emit a .gnu_attribute directive.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
const FeatureBitset & getFeatureBits() const
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
Get the string size.
static const char * getRegisterName(MCRegister Reg)
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned VR16Regs[32]
const unsigned GR128Regs[16]
const unsigned GRH32Regs[16]
const unsigned FP32Regs[16]
const unsigned FP16Regs[16]
const unsigned GR32Regs[16]
const unsigned FP64Regs[16]
const unsigned VR64Regs[32]
const unsigned FP128Regs[16]
const unsigned AR32Regs[16]
const unsigned VR32Regs[32]
const unsigned CR64Regs[16]
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSystemZTarget()
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
bool isAlpha(char C)
Checks if character C is a valid letter as classified by "C" locale.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool operator()(const InsnMatchEntry &LHS, StringRef RHS)
MatchClassKind OperandKinds[7]
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...