47static bool inRange(
const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,
48 bool AllowSymbol =
false) {
49 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
50 int64_t
Value = CE->getValue();
94 SMLoc StartLoc, EndLoc;
123 unsigned MemKind : 4;
124 unsigned RegKind : 4;
151 else if (
auto *CE = dyn_cast<MCConstantExpr>(Expr))
158 SystemZOperand(OperandKind Kind,
SMLoc StartLoc,
SMLoc EndLoc)
159 :
Kind(
Kind), StartLoc(StartLoc), EndLoc(EndLoc) {}
162 static std::unique_ptr<SystemZOperand> createInvalid(
SMLoc StartLoc,
164 return std::make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
167 static std::unique_ptr<SystemZOperand> createToken(
StringRef Str,
SMLoc Loc) {
168 auto Op = std::make_unique<SystemZOperand>(KindToken, Loc, Loc);
169 Op->Token.Data = Str.data();
170 Op->Token.Length = Str.size();
174 static std::unique_ptr<SystemZOperand>
175 createReg(RegisterKind Kind,
unsigned Num,
SMLoc StartLoc,
SMLoc EndLoc) {
176 auto Op = std::make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
182 static std::unique_ptr<SystemZOperand>
184 auto Op = std::make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
189 static std::unique_ptr<SystemZOperand>
190 createMem(MemoryKind MemKind, RegisterKind RegKind,
unsigned Base,
191 const MCExpr *Disp,
unsigned Index,
const MCExpr *LengthImm,
192 unsigned LengthReg,
SMLoc StartLoc,
SMLoc EndLoc) {
193 auto Op = std::make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
194 Op->Mem.MemKind = MemKind;
195 Op->Mem.RegKind = RegKind;
199 if (MemKind == BDLMem)
200 Op->Mem.Length.Imm = LengthImm;
201 if (MemKind == BDRMem)
202 Op->Mem.Length.Reg = LengthReg;
206 static std::unique_ptr<SystemZOperand>
209 auto Op = std::make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
210 Op->ImmTLS.Imm =
Imm;
211 Op->ImmTLS.Sym =
Sym;
216 bool isToken()
const override {
217 return Kind == KindToken;
220 assert(Kind == KindToken &&
"Not a token");
221 return StringRef(Token.Data, Token.Length);
225 bool isReg()
const override {
226 return Kind == KindReg;
228 bool isReg(RegisterKind RegKind)
const {
229 return Kind == KindReg &&
Reg.Kind == RegKind;
232 assert(Kind == KindReg &&
"Not a register");
237 bool isImm()
const override {
238 return Kind == KindImm;
240 bool isImm(int64_t MinValue, int64_t MaxValue)
const {
241 return Kind == KindImm &&
inRange(Imm, MinValue, MaxValue,
true);
243 const MCExpr *getImm()
const {
244 assert(Kind == KindImm &&
"Not an immediate");
249 bool isImmTLS()
const {
250 return Kind == KindImmTLS;
253 const ImmTLSOp getImmTLS()
const {
254 assert(Kind == KindImmTLS &&
"Not a TLS immediate");
259 bool isMem()
const override {
260 return Kind == KindMem;
262 bool isMem(MemoryKind MemKind)
const {
263 return (Kind == KindMem &&
264 (Mem.MemKind == MemKind ||
267 (Mem.MemKind == BDMem && MemKind == BDXMem)));
269 bool isMem(MemoryKind MemKind, RegisterKind RegKind)
const {
270 return isMem(MemKind) && Mem.RegKind == RegKind;
272 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind)
const {
273 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, 0, 0xfff,
true);
275 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind)
const {
276 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, -524288, 524287,
true);
278 bool isMemDisp12Len4(RegisterKind RegKind)
const {
279 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x10);
281 bool isMemDisp12Len8(RegisterKind RegKind)
const {
282 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x100);
285 const MemOp& getMem()
const {
286 assert(Kind == KindMem &&
"Not a Mem operand");
301 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
302 assert(
N == 1 &&
"Invalid number of operands");
305 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
306 assert(
N == 1 &&
"Invalid number of operands");
307 addExpr(Inst, getImm());
309 void addBDAddrOperands(
MCInst &Inst,
unsigned N)
const {
310 assert(
N == 2 &&
"Invalid number of operands");
313 addExpr(Inst, Mem.Disp);
315 void addBDXAddrOperands(
MCInst &Inst,
unsigned N)
const {
316 assert(
N == 3 &&
"Invalid number of operands");
319 addExpr(Inst, Mem.Disp);
322 void addBDLAddrOperands(
MCInst &Inst,
unsigned N)
const {
323 assert(
N == 3 &&
"Invalid number of operands");
326 addExpr(Inst, Mem.Disp);
327 addExpr(Inst, Mem.Length.Imm);
329 void addBDRAddrOperands(
MCInst &Inst,
unsigned N)
const {
330 assert(
N == 3 &&
"Invalid number of operands");
333 addExpr(Inst, Mem.Disp);
336 void addBDVAddrOperands(
MCInst &Inst,
unsigned N)
const {
337 assert(
N == 3 &&
"Invalid number of operands");
340 addExpr(Inst, Mem.Disp);
343 void addLXAAddrOperands(
MCInst &Inst,
unsigned N)
const {
344 assert(
N == 3 &&
"Invalid number of operands");
347 addExpr(Inst, Mem.Disp);
350 void addImmTLSOperands(
MCInst &Inst,
unsigned N)
const {
351 assert(
N == 2 &&
"Invalid number of operands");
352 assert(Kind == KindImmTLS &&
"Invalid operand type");
353 addExpr(Inst, ImmTLS.Imm);
355 addExpr(Inst, ImmTLS.Sym);
359 bool isGR32()
const {
return isReg(GR32Reg); }
360 bool isGRH32()
const {
return isReg(GRH32Reg); }
361 bool isGRX32()
const {
return false; }
362 bool isGR64()
const {
return isReg(GR64Reg); }
363 bool isGR128()
const {
return isReg(GR128Reg); }
364 bool isADDR32()
const {
return isReg(GR32Reg); }
365 bool isADDR64()
const {
return isReg(GR64Reg); }
366 bool isADDR128()
const {
return false; }
367 bool isFP32()
const {
return isReg(FP32Reg); }
368 bool isFP64()
const {
return isReg(FP64Reg); }
369 bool isFP128()
const {
return isReg(FP128Reg); }
370 bool isVR32()
const {
return isReg(VR32Reg); }
371 bool isVR64()
const {
return isReg(VR64Reg); }
372 bool isVF128()
const {
return false; }
373 bool isVR128()
const {
return isReg(VR128Reg); }
374 bool isAR32()
const {
return isReg(AR32Reg); }
375 bool isCR64()
const {
return isReg(CR64Reg); }
376 bool isAnyReg()
const {
return (
isReg() ||
isImm(0, 15)); }
377 bool isBDAddr32Disp12()
const {
return isMemDisp12(BDMem, GR32Reg); }
378 bool isBDAddr32Disp20()
const {
return isMemDisp20(BDMem, GR32Reg); }
379 bool isBDAddr64Disp12()
const {
return isMemDisp12(BDMem, GR64Reg); }
380 bool isBDAddr64Disp20()
const {
return isMemDisp20(BDMem, GR64Reg); }
381 bool isBDXAddr64Disp12()
const {
return isMemDisp12(BDXMem, GR64Reg); }
382 bool isBDXAddr64Disp20()
const {
return isMemDisp20(BDXMem, GR64Reg); }
383 bool isBDLAddr64Disp12Len4()
const {
return isMemDisp12Len4(GR64Reg); }
384 bool isBDLAddr64Disp12Len8()
const {
return isMemDisp12Len8(GR64Reg); }
385 bool isBDRAddr64Disp12()
const {
return isMemDisp12(BDRMem, GR64Reg); }
386 bool isBDVAddr64Disp12()
const {
return isMemDisp12(BDVMem, GR64Reg); }
387 bool isLXAAddr64Disp20()
const {
return isMemDisp20(LXAMem, GR64Reg); }
388 bool isU1Imm()
const {
return isImm(0, 1); }
389 bool isU2Imm()
const {
return isImm(0, 3); }
390 bool isU3Imm()
const {
return isImm(0, 7); }
391 bool isU4Imm()
const {
return isImm(0, 15); }
392 bool isU8Imm()
const {
return isImm(0, 255); }
393 bool isS8Imm()
const {
return isImm(-128, 127); }
394 bool isU12Imm()
const {
return isImm(0, 4095); }
395 bool isU16Imm()
const {
return isImm(0, 65535); }
396 bool isS16Imm()
const {
return isImm(-32768, 32767); }
397 bool isU32Imm()
const {
return isImm(0, (1LL << 32) - 1); }
398 bool isS32Imm()
const {
return isImm(-(1LL << 31), (1LL << 31) - 1); }
399 bool isU48Imm()
const {
return isImm(0, (1LL << 48) - 1); }
403#define GET_ASSEMBLER_HEADER
404#include "SystemZGenAsmMatcher.inc"
418 SMLoc StartLoc, EndLoc;
423 "do not have a target streamer");
429 bool RestoreOnFailure =
false);
431 bool parseIntegerRegister(
Register &Reg, RegisterGroup Group);
437 bool parseAddress(
bool &HaveReg1,
Register &Reg1,
bool &HaveReg2,
439 bool HasLength =
false,
bool HasVectorIndex =
false);
440 bool parseAddressRegister(
Register &Reg);
442 bool ParseDirectiveInsn(
SMLoc L);
443 bool ParseDirectiveMachine(
SMLoc L);
444 bool ParseGNUAttribute(
SMLoc L);
447 RegisterKind RegKind);
450 int64_t MaxVal,
bool AllowTLS);
471 unsigned getMAIAssemblerDialect() {
477 inline bool isHLASMAlpha(
char C) {
482 inline bool isHLASMAlnum(
char C) {
return isHLASMAlpha(
C) ||
isDigit(
C); }
485 inline bool isParsingHLASM() {
return getMAIAssemblerDialect() ==
AD_HLASM; }
488 inline bool isParsingGNU() {
return getMAIAssemblerDialect() ==
AD_GNU; }
508 bool RequirePercent,
bool RestoreOnFailure);
510 SMLoc &EndLoc)
override;
516 bool MatchingInlineAsm)
override;
577 return parseAddress(
Operands, BDMem, GR32Reg);
580 return parseAddress(
Operands, BDMem, GR64Reg);
583 return parseAddress(
Operands, BDXMem, GR64Reg);
586 return parseAddress(
Operands, BDLMem, GR64Reg);
589 return parseAddress(
Operands, BDRMem, GR64Reg);
592 return parseAddress(
Operands, BDVMem, GR64Reg);
595 return parseAddress(
Operands, LXAMem, GR64Reg);
598 return parsePCRel(
Operands, -(1LL << 12), (1LL << 12) - 1,
false);
601 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
false);
604 return parsePCRel(
Operands, -(1LL << 24), (1LL << 24) - 1,
false);
607 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
false);
610 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
true);
613 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
true);
619#define GET_REGISTER_MATCHER
620#define GET_SUBTARGET_FEATURE_NAME
621#define GET_MATCHER_IMPLEMENTATION
622#define GET_MNEMONIC_SPELL_CHECKER
623#include "SystemZGenAsmMatcher.inc"
643 return LHS.Format <
RHS.Format;
650 {
"e", SystemZ::InsnE, 1,
652 {
"ri", SystemZ::InsnRI, 3,
653 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
654 {
"rie", SystemZ::InsnRIE, 4,
655 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
656 {
"ril", SystemZ::InsnRIL, 3,
657 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
658 {
"rilu", SystemZ::InsnRILU, 3,
659 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
660 {
"ris", SystemZ::InsnRIS, 5,
661 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
662 {
"rr", SystemZ::InsnRR, 3,
663 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
664 {
"rre", SystemZ::InsnRRE, 3,
665 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
666 {
"rrf", SystemZ::InsnRRF, 5,
667 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
668 {
"rrs", SystemZ::InsnRRS, 5,
669 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
670 {
"rs", SystemZ::InsnRS, 4,
671 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
672 {
"rse", SystemZ::InsnRSE, 4,
673 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
674 {
"rsi", SystemZ::InsnRSI, 4,
675 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
676 {
"rsy", SystemZ::InsnRSY, 4,
677 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
678 {
"rx", SystemZ::InsnRX, 3,
679 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
680 {
"rxe", SystemZ::InsnRXE, 3,
681 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
682 {
"rxf", SystemZ::InsnRXF, 4,
683 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
684 {
"rxy", SystemZ::InsnRXY, 3,
685 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
686 {
"s", SystemZ::InsnS, 2,
687 { MCK_U32Imm, MCK_BDAddr64Disp12 } },
688 {
"si", SystemZ::InsnSI, 3,
689 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
690 {
"sil", SystemZ::InsnSIL, 3,
691 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
692 {
"siy", SystemZ::InsnSIY, 3,
693 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
694 {
"ss", SystemZ::InsnSS, 4,
695 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
696 {
"sse", SystemZ::InsnSSE, 3,
697 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
698 {
"ssf", SystemZ::InsnSSF, 4,
699 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
700 {
"vri", SystemZ::InsnVRI, 6,
701 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
702 {
"vrr", SystemZ::InsnVRR, 7,
703 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
705 {
"vrs", SystemZ::InsnVRS, 5,
706 { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
707 {
"vrv", SystemZ::InsnVRV, 4,
708 { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
709 {
"vrx", SystemZ::InsnVRX, 4,
710 { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
711 {
"vsi", SystemZ::InsnVSI, 4,
712 { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }
718 if (
auto *CE = dyn_cast<MCConstantExpr>(E))
720 else if (
auto *UE = dyn_cast<MCUnaryExpr>(E))
722 else if (
auto *BE = dyn_cast<MCBinaryExpr>(E))
724 else if (
auto *SRE = dyn_cast<MCSymbolRefExpr>(E))
733 OS <<
"Token:" << getToken();
745 if (getImmTLS().
Sym) {
752 OS <<
"Mem:" << *cast<MCConstantExpr>(
Op.Disp);
755 if (
Op.MemKind == BDLMem)
756 OS << *cast<MCConstantExpr>(
Op.Length.Imm) <<
",";
757 else if (
Op.MemKind == BDRMem)
772bool SystemZAsmParser::parseRegister(
Register &Reg,
bool RequirePercent,
773 bool RestoreOnFailure) {
780 return Error(PercentTok.
getLoc(),
"register expected");
788 if (RestoreOnFailure && HasPercent)
789 getLexer().UnLex(PercentTok);
791 HasPercent ?
"invalid register" :
"register expected");
796 if (
Name.size() < 2) {
797 if (RestoreOnFailure && HasPercent)
798 getLexer().UnLex(PercentTok);
799 return Error(
Reg.StartLoc,
"invalid register");
804 if (
Name.substr(1).getAsInteger(10,
Reg.Num)) {
805 if (RestoreOnFailure && HasPercent)
806 getLexer().UnLex(PercentTok);
807 return Error(
Reg.StartLoc,
"invalid register");
811 if (Prefix ==
'r' &&
Reg.Num < 16)
813 else if (Prefix ==
'f' &&
Reg.Num < 16)
815 else if (Prefix ==
'v' &&
Reg.Num < 32)
817 else if (Prefix ==
'a' &&
Reg.Num < 16)
819 else if (Prefix ==
'c' &&
Reg.Num < 16)
822 if (RestoreOnFailure && HasPercent)
823 getLexer().UnLex(PercentTok);
824 return Error(
Reg.StartLoc,
"invalid register");
864 if (parseRegister(Reg,
true))
874 if (Group !=
Reg.Group)
875 return Error(
Reg.StartLoc,
"invalid operand for instruction");
878 if (
Reg.Group != RegV &&
Reg.Group != RegFP)
879 return Error(
Reg.StartLoc,
"invalid operand for instruction");
883 if (parseIntegerRegister(Reg, Group))
891 const unsigned *Regs;
906 if (Regs[
Reg.Num] == 0)
907 return Error(
Reg.StartLoc,
"invalid register pair");
910 SystemZOperand::createReg(Kind, Regs[
Reg.Num],
Reg.StartLoc,
Reg.EndLoc));
924 if (
auto *CE = dyn_cast<MCConstantExpr>(
Register)) {
925 int64_t
Value =
CE->getValue();
926 if (Value < 0 || Value > 15)
927 return Error(StartLoc,
"invalid register");
936 if (isParsingHLASM())
940 if (parseRegister(Reg,
true))
944 return Error(StartLoc,
"invalid register");
949 if (
Reg.Group == RegGR) {
953 else if (
Reg.Group == RegFP) {
957 else if (
Reg.Group == RegV) {
961 else if (
Reg.Group == RegAR) {
965 else if (
Reg.Group == RegCR) {
973 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
974 Reg.StartLoc,
Reg.EndLoc));
979bool SystemZAsmParser::parseIntegerRegister(
Register &Reg,
980 RegisterGroup Group) {
987 const auto *
CE = dyn_cast<MCConstantExpr>(
Register);
991 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
992 int64_t
Value =
CE->getValue();
993 if (Value < 0 || Value > MaxRegNum) {
1008bool SystemZAsmParser::parseAddress(
bool &HaveReg1,
Register &Reg1,
1011 bool HasLength,
bool HasVectorIndex) {
1013 if (getParser().parseExpression(Disp))
1039 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
1047 if (parseRegister(Reg1,
true))
1058 if (getParser().parseExpression(
Length))
1066 if (parseIntegerRegister(Reg1, RegGroup))
1073 if (getParser().parseExpression(
Length))
1084 if (parseIntegerRegister(Reg2, RegGR))
1086 }
else if (isParsingGNU()) {
1088 if (parseRegister(Reg2,
true))
1094 Reg2.StartLoc = Reg2.EndLoc = Parser.
getTok().
getLoc();
1109SystemZAsmParser::parseAddressRegister(
Register &Reg) {
1110 if (
Reg.Group == RegV) {
1111 Error(
Reg.StartLoc,
"invalid use of vector addressing");
1114 if (
Reg.Group != RegGR) {
1115 Error(
Reg.StartLoc,
"invalid address register");
1125 RegisterKind RegKind) {
1127 unsigned Base = 0,
Index = 0, LengthReg = 0;
1129 bool HaveReg1, HaveReg2;
1133 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1134 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1135 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1139 const unsigned *Regs;
1150 if (parseAddressRegister(Reg1))
1152 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1156 return Error(StartLoc,
"invalid use of indexed addressing");
1162 const unsigned *IndexRegs = Regs;
1163 if (MemKind == LXAMem)
1166 if (parseAddressRegister(Reg1))
1171 if (HaveReg2 || isParsingHLASM())
1172 Index = Reg1.Num == 0 ? 0 : IndexRegs[Reg1.Num];
1174 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1178 if (parseAddressRegister(Reg2))
1180 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1186 if (parseAddressRegister(Reg2))
1188 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1191 if (HaveReg1 && HaveReg2)
1192 return Error(StartLoc,
"invalid use of indexed addressing");
1195 return Error(StartLoc,
"missing length in address");
1199 if (!HaveReg1 || Reg1.Group != RegGR)
1200 return Error(StartLoc,
"invalid operand for instruction");
1204 if (parseAddressRegister(Reg2))
1206 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1211 if (!HaveReg1 || Reg1.Group != RegV)
1212 return Error(StartLoc,
"vector index required in address");
1216 if (isParsingGNU() && !HaveReg2)
1217 return Error(Reg1.StartLoc,
"invalid use of vector addressing");
1220 if (parseAddressRegister(Reg2))
1222 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1229 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1230 Index,
Length, LengthReg,
1238 if (IDVal ==
".insn")
1239 return ParseDirectiveInsn(DirectiveID.
getLoc());
1240 if (IDVal ==
".machine")
1241 return ParseDirectiveMachine(DirectiveID.
getLoc());
1243 return ParseGNUAttribute(DirectiveID.
getLoc());
1250bool SystemZAsmParser::ParseDirectiveInsn(
SMLoc L) {
1257 return Error(ErrorLoc,
"expected instruction format");
1267 if (EntryRange.first == EntryRange.second)
1268 return Error(ErrorLoc,
"unrecognized format");
1276 for (
int I = 0;
I <
Entry->NumOperands;
I++) {
1277 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1283 return Error(StartLoc,
"unexpected token in directive");
1288 if (Kind == MCK_AnyReg)
1290 else if (Kind == MCK_VR128)
1292 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1294 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1296 else if (Kind == MCK_BDVAddr64Disp12)
1298 else if (Kind == MCK_LXAAddr64Disp20)
1300 else if (Kind == MCK_PCRel32)
1302 else if (Kind == MCK_PCRel16)
1311 return Error(StartLoc,
"unexpected token in directive");
1316 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1329 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1332 unsigned Res = validateOperandClass(Operand, Kind);
1333 if (Res != Match_Success)
1337 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1338 if (ZOperand.isReg())
1339 ZOperand.addRegOperands(Inst, 1);
1340 else if (ZOperand.isMem(BDMem))
1341 ZOperand.addBDAddrOperands(Inst, 2);
1342 else if (ZOperand.isMem(BDXMem))
1343 ZOperand.addBDXAddrOperands(Inst, 3);
1344 else if (ZOperand.isMem(BDVMem))
1345 ZOperand.addBDVAddrOperands(Inst, 3);
1346 else if (ZOperand.isMem(LXAMem))
1347 ZOperand.addLXAAddrOperands(Inst, 3);
1348 else if (ZOperand.isImm())
1349 ZOperand.addImmOperands(Inst, 1);
1362bool SystemZAsmParser::ParseDirectiveMachine(
SMLoc L) {
1366 return TokError(
"unexpected token in '.machine' directive");
1375 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1377 getTargetStreamer().emitMachine(CPU);
1382bool SystemZAsmParser::ParseGNUAttribute(
SMLoc L) {
1384 int64_t IntegerValue;
1386 return Error(L,
"malformed .gnu_attribute directive");
1389 if (Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))
1390 return Error(L,
"unrecognized .gnu_attribute tag/value pair.");
1397bool SystemZAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
1398 SMLoc &EndLoc,
bool RequirePercent,
1399 bool RestoreOnFailure) {
1401 if (parseRegister(Reg, RequirePercent, RestoreOnFailure))
1403 if (
Reg.Group == RegGR)
1405 else if (
Reg.Group == RegFP)
1407 else if (
Reg.Group == RegV)
1409 else if (
Reg.Group == RegAR)
1411 else if (
Reg.Group == RegCR)
1413 StartLoc =
Reg.StartLoc;
1414 EndLoc =
Reg.EndLoc;
1420 return ParseRegister(Reg, StartLoc, EndLoc,
false,
1426 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
false,
1428 bool PendingErrors = getParser().hasPendingError();
1429 getParser().clearPendingErrors();
1445 Operands.push_back(SystemZOperand::createToken(
Name, NameLoc));
1461 "No space allowed between comma that separates operand entries");
1486 getStreamer().AddComment(
Remark);
1490 SMLoc Loc = getLexer().getLoc();
1491 return Error(Loc,
"unexpected token in argument list");
1510 setAvailableFeatures(
All);
1512 setAvailableFeatures(AvailableFeatures);
1528 if (parseRegister(Reg,
true))
1530 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1539 bool HaveReg1, HaveReg2;
1542 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1547 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1548 && parseAddressRegister(Reg1))
1550 if (HaveReg2 && parseAddressRegister(Reg2))
1555 if (HaveReg1 || HaveReg2 ||
Length)
1556 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1558 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1562bool SystemZAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &
Opcode,
1566 bool MatchingInlineAsm) {
1568 unsigned MatchResult;
1570 unsigned Dialect = getMAIAssemblerDialect();
1574 MatchingInlineAsm, Dialect);
1575 switch (MatchResult) {
1581 case Match_MissingFeature: {
1582 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1585 std::string Msg =
"instruction requires:";
1586 for (
unsigned I = 0, E = MissingFeatures.
size();
I != E; ++
I) {
1587 if (MissingFeatures[
I]) {
1592 return Error(IDLoc, Msg);
1595 case Match_InvalidOperand: {
1596 SMLoc ErrorLoc = IDLoc;
1599 return Error(IDLoc,
"too few operands for instruction");
1602 if (ErrorLoc ==
SMLoc())
1605 return Error(ErrorLoc,
"invalid operand for instruction");
1608 case Match_MnemonicFail: {
1609 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1610 std::string Suggestion = SystemZMnemonicSpellCheck(
1611 ((SystemZOperand &)*
Operands[0]).getToken(), FBS, Dialect);
1612 return Error(IDLoc,
"invalid instruction" + Suggestion,
1613 ((SystemZOperand &)*
Operands[0]).getLocRange());
1621 int64_t MinVal, int64_t MaxVal,
1627 if (getParser().parseExpression(Expr))
1630 auto IsOutOfRangeConstant = [&](
const MCExpr *E,
bool Negate) ->
bool {
1631 if (
auto *CE = dyn_cast<MCConstantExpr>(E)) {
1632 int64_t
Value =
CE->getValue();
1635 if ((
Value & 1) || Value < MinVal || Value > MaxVal)
1643 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1644 if (isParsingHLASM())
1645 return Error(StartLoc,
"Expected PC-relative expression");
1646 if (IsOutOfRangeConstant(CE,
false))
1647 return Error(StartLoc,
"offset out of range");
1648 int64_t
Value =
CE->getValue();
1658 if (
const auto *BE = dyn_cast<MCBinaryExpr>(Expr))
1659 if (IsOutOfRangeConstant(BE->getLHS(),
false) ||
1660 IsOutOfRangeConstant(BE->getRHS(),
1662 return Error(StartLoc,
"offset out of range");
1674 if (
Name ==
"tls_gdcall")
1676 else if (
Name ==
"tls_ldcall")
1699 Operands.push_back(SystemZOperand::createImmTLS(Expr,
Sym,
1702 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1707bool SystemZAsmParser::isLabel(
AsmToken &Token) {
1726 if (!RawLabel.
size())
1727 return !
Error(Loc,
"HLASM Label cannot be empty");
1730 if (RawLabel.
size() > 63)
1731 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1734 if (!isHLASMAlpha(RawLabel[0]))
1735 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1736 "character or the underscore character");
1741 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1742 if (!isHLASMAlnum(RawLabel[
I]))
1743 return !
Error(Loc,
"HLASM Label has to be alphanumeric");
static const char * getSubtargetFeatureName(uint64_t Val)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue, bool AllowSymbol=false)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmParser()
static struct InsnMatchEntry InsnMatchTable[]
static void printMCExpr(const MCExpr *E, raw_ostream &OS)
Target independent representation for an assembler token.
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.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
unsigned getAssemblerDialect() const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
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.
virtual MCContext & getContext()=0
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Context object for machine code objects.
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
const MCAsmInfo * getAsmInfo() const
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.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
Interface to description of machine instruction set.
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 bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
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.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
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)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
virtual bool isLabel(AsmToken &Token)
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
Target specific streamer interface.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - 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
size - 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.
@ C
The default llvm calling convention, compatible with C.
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned GR128Regs[16]
const unsigned GRH32Regs[16]
const unsigned FP32Regs[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)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSystemZTarget()
DWARFExpression::Operation Op
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,...