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();
93 SMLoc StartLoc, EndLoc;
122 unsigned MemKind : 4;
123 unsigned RegKind : 4;
150 else if (
auto *CE = dyn_cast<MCConstantExpr>(Expr))
157 SystemZOperand(OperandKind Kind,
SMLoc StartLoc,
SMLoc EndLoc)
158 :
Kind(
Kind), StartLoc(StartLoc), EndLoc(EndLoc) {}
161 static std::unique_ptr<SystemZOperand> createInvalid(
SMLoc StartLoc,
163 return std::make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
166 static std::unique_ptr<SystemZOperand> createToken(
StringRef Str,
SMLoc Loc) {
167 auto Op = std::make_unique<SystemZOperand>(KindToken, Loc, Loc);
168 Op->Token.Data = Str.data();
169 Op->Token.Length = Str.size();
173 static std::unique_ptr<SystemZOperand>
174 createReg(RegisterKind Kind,
unsigned Num,
SMLoc StartLoc,
SMLoc EndLoc) {
175 auto Op = std::make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
181 static std::unique_ptr<SystemZOperand>
183 auto Op = std::make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
188 static std::unique_ptr<SystemZOperand>
189 createMem(MemoryKind MemKind, RegisterKind RegKind,
unsigned Base,
190 const MCExpr *Disp,
unsigned Index,
const MCExpr *LengthImm,
191 unsigned LengthReg,
SMLoc StartLoc,
SMLoc EndLoc) {
192 auto Op = std::make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
193 Op->Mem.MemKind = MemKind;
194 Op->Mem.RegKind = RegKind;
198 if (MemKind == BDLMem)
199 Op->Mem.Length.Imm = LengthImm;
200 if (MemKind == BDRMem)
201 Op->Mem.Length.Reg = LengthReg;
205 static std::unique_ptr<SystemZOperand>
208 auto Op = std::make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
209 Op->ImmTLS.Imm =
Imm;
210 Op->ImmTLS.Sym =
Sym;
215 bool isToken()
const override {
216 return Kind == KindToken;
219 assert(Kind == KindToken &&
"Not a token");
220 return StringRef(Token.Data, Token.Length);
224 bool isReg()
const override {
225 return Kind == KindReg;
227 bool isReg(RegisterKind RegKind)
const {
228 return Kind == KindReg &&
Reg.Kind == RegKind;
231 assert(Kind == KindReg &&
"Not a register");
236 bool isImm()
const override {
237 return Kind == KindImm;
239 bool isImm(int64_t MinValue, int64_t MaxValue)
const {
240 return Kind == KindImm &&
inRange(Imm, MinValue, MaxValue,
true);
242 const MCExpr *getImm()
const {
243 assert(Kind == KindImm &&
"Not an immediate");
248 bool isImmTLS()
const {
249 return Kind == KindImmTLS;
252 const ImmTLSOp getImmTLS()
const {
253 assert(Kind == KindImmTLS &&
"Not a TLS immediate");
258 bool isMem()
const override {
259 return Kind == KindMem;
261 bool isMem(MemoryKind MemKind)
const {
262 return (Kind == KindMem &&
263 (Mem.MemKind == MemKind ||
266 (Mem.MemKind == BDMem && MemKind == BDXMem)));
268 bool isMem(MemoryKind MemKind, RegisterKind RegKind)
const {
269 return isMem(MemKind) && Mem.RegKind == RegKind;
271 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind)
const {
272 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, 0, 0xfff,
true);
274 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind)
const {
275 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, -524288, 524287,
true);
277 bool isMemDisp12Len4(RegisterKind RegKind)
const {
278 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x10);
280 bool isMemDisp12Len8(RegisterKind RegKind)
const {
281 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x100);
284 const MemOp& getMem()
const {
285 assert(Kind == KindMem &&
"Not a Mem operand");
300 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
301 assert(
N == 1 &&
"Invalid number of operands");
304 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
305 assert(
N == 1 &&
"Invalid number of operands");
306 addExpr(Inst, getImm());
308 void addBDAddrOperands(
MCInst &Inst,
unsigned N)
const {
309 assert(
N == 2 &&
"Invalid number of operands");
312 addExpr(Inst, Mem.Disp);
314 void addBDXAddrOperands(
MCInst &Inst,
unsigned N)
const {
315 assert(
N == 3 &&
"Invalid number of operands");
318 addExpr(Inst, Mem.Disp);
321 void addBDLAddrOperands(
MCInst &Inst,
unsigned N)
const {
322 assert(
N == 3 &&
"Invalid number of operands");
325 addExpr(Inst, Mem.Disp);
326 addExpr(Inst, Mem.Length.Imm);
328 void addBDRAddrOperands(
MCInst &Inst,
unsigned N)
const {
329 assert(
N == 3 &&
"Invalid number of operands");
332 addExpr(Inst, Mem.Disp);
335 void addBDVAddrOperands(
MCInst &Inst,
unsigned N)
const {
336 assert(
N == 3 &&
"Invalid number of operands");
339 addExpr(Inst, Mem.Disp);
342 void addImmTLSOperands(
MCInst &Inst,
unsigned N)
const {
343 assert(
N == 2 &&
"Invalid number of operands");
344 assert(Kind == KindImmTLS &&
"Invalid operand type");
345 addExpr(Inst, ImmTLS.Imm);
347 addExpr(Inst, ImmTLS.Sym);
351 bool isGR32()
const {
return isReg(GR32Reg); }
352 bool isGRH32()
const {
return isReg(GRH32Reg); }
353 bool isGRX32()
const {
return false; }
354 bool isGR64()
const {
return isReg(GR64Reg); }
355 bool isGR128()
const {
return isReg(GR128Reg); }
356 bool isADDR32()
const {
return isReg(GR32Reg); }
357 bool isADDR64()
const {
return isReg(GR64Reg); }
358 bool isADDR128()
const {
return false; }
359 bool isFP32()
const {
return isReg(FP32Reg); }
360 bool isFP64()
const {
return isReg(FP64Reg); }
361 bool isFP128()
const {
return isReg(FP128Reg); }
362 bool isVR32()
const {
return isReg(VR32Reg); }
363 bool isVR64()
const {
return isReg(VR64Reg); }
364 bool isVF128()
const {
return false; }
365 bool isVR128()
const {
return isReg(VR128Reg); }
366 bool isAR32()
const {
return isReg(AR32Reg); }
367 bool isCR64()
const {
return isReg(CR64Reg); }
368 bool isAnyReg()
const {
return (
isReg() ||
isImm(0, 15)); }
369 bool isBDAddr32Disp12()
const {
return isMemDisp12(BDMem, GR32Reg); }
370 bool isBDAddr32Disp20()
const {
return isMemDisp20(BDMem, GR32Reg); }
371 bool isBDAddr64Disp12()
const {
return isMemDisp12(BDMem, GR64Reg); }
372 bool isBDAddr64Disp20()
const {
return isMemDisp20(BDMem, GR64Reg); }
373 bool isBDXAddr64Disp12()
const {
return isMemDisp12(BDXMem, GR64Reg); }
374 bool isBDXAddr64Disp20()
const {
return isMemDisp20(BDXMem, GR64Reg); }
375 bool isBDLAddr64Disp12Len4()
const {
return isMemDisp12Len4(GR64Reg); }
376 bool isBDLAddr64Disp12Len8()
const {
return isMemDisp12Len8(GR64Reg); }
377 bool isBDRAddr64Disp12()
const {
return isMemDisp12(BDRMem, GR64Reg); }
378 bool isBDVAddr64Disp12()
const {
return isMemDisp12(BDVMem, GR64Reg); }
379 bool isU1Imm()
const {
return isImm(0, 1); }
380 bool isU2Imm()
const {
return isImm(0, 3); }
381 bool isU3Imm()
const {
return isImm(0, 7); }
382 bool isU4Imm()
const {
return isImm(0, 15); }
383 bool isU8Imm()
const {
return isImm(0, 255); }
384 bool isS8Imm()
const {
return isImm(-128, 127); }
385 bool isU12Imm()
const {
return isImm(0, 4095); }
386 bool isU16Imm()
const {
return isImm(0, 65535); }
387 bool isS16Imm()
const {
return isImm(-32768, 32767); }
388 bool isU32Imm()
const {
return isImm(0, (1LL << 32) - 1); }
389 bool isS32Imm()
const {
return isImm(-(1LL << 31), (1LL << 31) - 1); }
390 bool isU48Imm()
const {
return isImm(0, (1LL << 48) - 1); }
394#define GET_ASSEMBLER_HEADER
395#include "SystemZGenAsmMatcher.inc"
409 SMLoc StartLoc, EndLoc;
414 "do not have a target streamer");
420 bool RestoreOnFailure =
false);
422 bool parseIntegerRegister(
Register &Reg, RegisterGroup Group);
428 bool parseAddress(
bool &HaveReg1,
Register &Reg1,
bool &HaveReg2,
430 bool HasLength =
false,
bool HasVectorIndex =
false);
431 bool parseAddressRegister(
Register &Reg);
433 bool ParseDirectiveInsn(
SMLoc L);
434 bool ParseDirectiveMachine(
SMLoc L);
435 bool ParseGNUAttribute(
SMLoc L);
438 RegisterKind RegKind);
441 int64_t MaxVal,
bool AllowTLS);
462 unsigned getMAIAssemblerDialect() {
468 inline bool isHLASMAlpha(
char C) {
473 inline bool isHLASMAlnum(
char C) {
return isHLASMAlpha(
C) ||
isDigit(
C); }
476 inline bool isParsingHLASM() {
return getMAIAssemblerDialect() ==
AD_HLASM; }
479 inline bool isParsingGNU() {
return getMAIAssemblerDialect() ==
AD_GNU; }
499 bool RequirePercent,
bool RestoreOnFailure);
501 SMLoc &EndLoc)
override;
507 bool MatchingInlineAsm)
override;
568 return parseAddress(
Operands, BDMem, GR32Reg);
571 return parseAddress(
Operands, BDMem, GR64Reg);
574 return parseAddress(
Operands, BDXMem, GR64Reg);
577 return parseAddress(
Operands, BDLMem, GR64Reg);
580 return parseAddress(
Operands, BDRMem, GR64Reg);
583 return parseAddress(
Operands, BDVMem, GR64Reg);
586 return parsePCRel(
Operands, -(1LL << 12), (1LL << 12) - 1,
false);
589 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
false);
592 return parsePCRel(
Operands, -(1LL << 24), (1LL << 24) - 1,
false);
595 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
false);
598 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
true);
601 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
true);
607#define GET_REGISTER_MATCHER
608#define GET_SUBTARGET_FEATURE_NAME
609#define GET_MATCHER_IMPLEMENTATION
610#define GET_MNEMONIC_SPELL_CHECKER
611#include "SystemZGenAsmMatcher.inc"
631 return LHS.Format <
RHS.Format;
638 {
"e", SystemZ::InsnE, 1,
640 {
"ri", SystemZ::InsnRI, 3,
641 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
642 {
"rie", SystemZ::InsnRIE, 4,
643 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
644 {
"ril", SystemZ::InsnRIL, 3,
645 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
646 {
"rilu", SystemZ::InsnRILU, 3,
647 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
648 {
"ris", SystemZ::InsnRIS, 5,
649 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
650 {
"rr", SystemZ::InsnRR, 3,
651 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
652 {
"rre", SystemZ::InsnRRE, 3,
653 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
654 {
"rrf", SystemZ::InsnRRF, 5,
655 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
656 {
"rrs", SystemZ::InsnRRS, 5,
657 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
658 {
"rs", SystemZ::InsnRS, 4,
659 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
660 {
"rse", SystemZ::InsnRSE, 4,
661 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
662 {
"rsi", SystemZ::InsnRSI, 4,
663 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
664 {
"rsy", SystemZ::InsnRSY, 4,
665 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
666 {
"rx", SystemZ::InsnRX, 3,
667 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
668 {
"rxe", SystemZ::InsnRXE, 3,
669 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
670 {
"rxf", SystemZ::InsnRXF, 4,
671 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
672 {
"rxy", SystemZ::InsnRXY, 3,
673 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
674 {
"s", SystemZ::InsnS, 2,
675 { MCK_U32Imm, MCK_BDAddr64Disp12 } },
676 {
"si", SystemZ::InsnSI, 3,
677 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
678 {
"sil", SystemZ::InsnSIL, 3,
679 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
680 {
"siy", SystemZ::InsnSIY, 3,
681 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
682 {
"ss", SystemZ::InsnSS, 4,
683 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
684 {
"sse", SystemZ::InsnSSE, 3,
685 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
686 {
"ssf", SystemZ::InsnSSF, 4,
687 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
688 {
"vri", SystemZ::InsnVRI, 6,
689 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
690 {
"vrr", SystemZ::InsnVRR, 7,
691 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
693 {
"vrs", SystemZ::InsnVRS, 5,
694 { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
695 {
"vrv", SystemZ::InsnVRV, 4,
696 { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
697 {
"vrx", SystemZ::InsnVRX, 4,
698 { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
699 {
"vsi", SystemZ::InsnVSI, 4,
700 { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }
706 if (
auto *CE = dyn_cast<MCConstantExpr>(E))
708 else if (
auto *UE = dyn_cast<MCUnaryExpr>(E))
710 else if (
auto *BE = dyn_cast<MCBinaryExpr>(E))
712 else if (
auto *SRE = dyn_cast<MCSymbolRefExpr>(E))
721 OS <<
"Token:" << getToken();
733 if (getImmTLS().
Sym) {
740 OS <<
"Mem:" << *cast<MCConstantExpr>(
Op.Disp);
743 if (
Op.MemKind == BDLMem)
744 OS << *cast<MCConstantExpr>(
Op.Length.Imm) <<
",";
745 else if (
Op.MemKind == BDRMem)
760bool SystemZAsmParser::parseRegister(
Register &Reg,
bool RequirePercent,
761 bool RestoreOnFailure) {
768 return Error(PercentTok.
getLoc(),
"register expected");
776 if (RestoreOnFailure && HasPercent)
777 getLexer().UnLex(PercentTok);
779 HasPercent ?
"invalid register" :
"register expected");
784 if (
Name.size() < 2) {
785 if (RestoreOnFailure && HasPercent)
786 getLexer().UnLex(PercentTok);
787 return Error(
Reg.StartLoc,
"invalid register");
792 if (
Name.substr(1).getAsInteger(10,
Reg.Num)) {
793 if (RestoreOnFailure && HasPercent)
794 getLexer().UnLex(PercentTok);
795 return Error(
Reg.StartLoc,
"invalid register");
799 if (Prefix ==
'r' &&
Reg.Num < 16)
801 else if (Prefix ==
'f' &&
Reg.Num < 16)
803 else if (Prefix ==
'v' &&
Reg.Num < 32)
805 else if (Prefix ==
'a' &&
Reg.Num < 16)
807 else if (Prefix ==
'c' &&
Reg.Num < 16)
810 if (RestoreOnFailure && HasPercent)
811 getLexer().UnLex(PercentTok);
812 return Error(
Reg.StartLoc,
"invalid register");
852 if (parseRegister(Reg,
true))
862 if (Group !=
Reg.Group)
863 return Error(
Reg.StartLoc,
"invalid operand for instruction");
866 if (
Reg.Group != RegV &&
Reg.Group != RegFP)
867 return Error(
Reg.StartLoc,
"invalid operand for instruction");
871 if (parseIntegerRegister(Reg, Group))
879 const unsigned *Regs;
894 if (Regs[
Reg.Num] == 0)
895 return Error(
Reg.StartLoc,
"invalid register pair");
898 SystemZOperand::createReg(Kind, Regs[
Reg.Num],
Reg.StartLoc,
Reg.EndLoc));
912 if (
auto *CE = dyn_cast<MCConstantExpr>(
Register)) {
913 int64_t
Value =
CE->getValue();
914 if (Value < 0 || Value > 15)
915 return Error(StartLoc,
"invalid register");
924 if (isParsingHLASM())
928 if (parseRegister(Reg,
true))
932 return Error(StartLoc,
"invalid register");
937 if (
Reg.Group == RegGR) {
941 else if (
Reg.Group == RegFP) {
945 else if (
Reg.Group == RegV) {
949 else if (
Reg.Group == RegAR) {
953 else if (
Reg.Group == RegCR) {
961 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
962 Reg.StartLoc,
Reg.EndLoc));
967bool SystemZAsmParser::parseIntegerRegister(
Register &Reg,
968 RegisterGroup Group) {
975 const auto *
CE = dyn_cast<MCConstantExpr>(
Register);
979 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
980 int64_t
Value =
CE->getValue();
981 if (Value < 0 || Value > MaxRegNum) {
996bool SystemZAsmParser::parseAddress(
bool &HaveReg1,
Register &Reg1,
999 bool HasLength,
bool HasVectorIndex) {
1001 if (getParser().parseExpression(Disp))
1027 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
1035 if (parseRegister(Reg1,
true))
1046 if (getParser().parseExpression(
Length))
1054 if (parseIntegerRegister(Reg1, RegGroup))
1061 if (getParser().parseExpression(
Length))
1072 if (parseIntegerRegister(Reg2, RegGR))
1074 }
else if (isParsingGNU()) {
1076 if (parseRegister(Reg2,
true))
1082 Reg2.StartLoc = Reg2.EndLoc = Parser.
getTok().
getLoc();
1097SystemZAsmParser::parseAddressRegister(
Register &Reg) {
1098 if (
Reg.Group == RegV) {
1099 Error(
Reg.StartLoc,
"invalid use of vector addressing");
1102 if (
Reg.Group != RegGR) {
1103 Error(
Reg.StartLoc,
"invalid address register");
1113 RegisterKind RegKind) {
1115 unsigned Base = 0,
Index = 0, LengthReg = 0;
1117 bool HaveReg1, HaveReg2;
1121 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1122 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1123 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1127 const unsigned *Regs;
1138 if (parseAddressRegister(Reg1))
1140 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1144 return Error(StartLoc,
"invalid use of indexed addressing");
1149 if (parseAddressRegister(Reg1))
1154 if (HaveReg2 || isParsingHLASM())
1155 Index = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1157 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1161 if (parseAddressRegister(Reg2))
1163 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1169 if (parseAddressRegister(Reg2))
1171 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1174 if (HaveReg1 && HaveReg2)
1175 return Error(StartLoc,
"invalid use of indexed addressing");
1178 return Error(StartLoc,
"missing length in address");
1182 if (!HaveReg1 || Reg1.Group != RegGR)
1183 return Error(StartLoc,
"invalid operand for instruction");
1187 if (parseAddressRegister(Reg2))
1189 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1194 if (!HaveReg1 || Reg1.Group != RegV)
1195 return Error(StartLoc,
"vector index required in address");
1199 if (isParsingGNU() && !HaveReg2)
1200 return Error(Reg1.StartLoc,
"invalid use of vector addressing");
1203 if (parseAddressRegister(Reg2))
1205 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1212 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1213 Index,
Length, LengthReg,
1221 if (IDVal ==
".insn")
1222 return ParseDirectiveInsn(DirectiveID.
getLoc());
1223 if (IDVal ==
".machine")
1224 return ParseDirectiveMachine(DirectiveID.
getLoc());
1226 return ParseGNUAttribute(DirectiveID.
getLoc());
1233bool SystemZAsmParser::ParseDirectiveInsn(
SMLoc L) {
1240 return Error(ErrorLoc,
"expected instruction format");
1250 if (EntryRange.first == EntryRange.second)
1251 return Error(ErrorLoc,
"unrecognized format");
1259 for (
int I = 0;
I <
Entry->NumOperands;
I++) {
1260 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1266 return Error(StartLoc,
"unexpected token in directive");
1271 if (Kind == MCK_AnyReg)
1273 else if (Kind == MCK_VR128)
1275 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1277 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1279 else if (Kind == MCK_BDVAddr64Disp12)
1281 else if (Kind == MCK_PCRel32)
1283 else if (Kind == MCK_PCRel16)
1292 return Error(StartLoc,
"unexpected token in directive");
1297 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1310 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1313 unsigned Res = validateOperandClass(Operand, Kind);
1314 if (Res != Match_Success)
1318 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1319 if (ZOperand.isReg())
1320 ZOperand.addRegOperands(Inst, 1);
1321 else if (ZOperand.isMem(BDMem))
1322 ZOperand.addBDAddrOperands(Inst, 2);
1323 else if (ZOperand.isMem(BDXMem))
1324 ZOperand.addBDXAddrOperands(Inst, 3);
1325 else if (ZOperand.isMem(BDVMem))
1326 ZOperand.addBDVAddrOperands(Inst, 3);
1327 else if (ZOperand.isImm())
1328 ZOperand.addImmOperands(Inst, 1);
1341bool SystemZAsmParser::ParseDirectiveMachine(
SMLoc L) {
1345 return TokError(
"unexpected token in '.machine' directive");
1354 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1356 getTargetStreamer().emitMachine(CPU);
1361bool SystemZAsmParser::ParseGNUAttribute(
SMLoc L) {
1363 int64_t IntegerValue;
1365 return Error(L,
"malformed .gnu_attribute directive");
1368 if (Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))
1369 return Error(L,
"unrecognized .gnu_attribute tag/value pair.");
1376bool SystemZAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
1377 SMLoc &EndLoc,
bool RequirePercent,
1378 bool RestoreOnFailure) {
1380 if (parseRegister(Reg, RequirePercent, RestoreOnFailure))
1382 if (
Reg.Group == RegGR)
1384 else if (
Reg.Group == RegFP)
1386 else if (
Reg.Group == RegV)
1388 else if (
Reg.Group == RegAR)
1390 else if (
Reg.Group == RegCR)
1392 StartLoc =
Reg.StartLoc;
1393 EndLoc =
Reg.EndLoc;
1399 return ParseRegister(Reg, StartLoc, EndLoc,
false,
1405 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
false,
1407 bool PendingErrors = getParser().hasPendingError();
1408 getParser().clearPendingErrors();
1424 Operands.push_back(SystemZOperand::createToken(
Name, NameLoc));
1440 "No space allowed between comma that separates operand entries");
1465 getStreamer().AddComment(
Remark);
1469 SMLoc Loc = getLexer().getLoc();
1470 return Error(Loc,
"unexpected token in argument list");
1489 setAvailableFeatures(
All);
1491 setAvailableFeatures(AvailableFeatures);
1507 if (parseRegister(Reg,
true))
1509 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1518 bool HaveReg1, HaveReg2;
1521 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1526 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1527 && parseAddressRegister(Reg1))
1529 if (HaveReg2 && parseAddressRegister(Reg2))
1534 if (HaveReg1 || HaveReg2 ||
Length)
1535 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1537 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1541bool SystemZAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &
Opcode,
1545 bool MatchingInlineAsm) {
1547 unsigned MatchResult;
1549 unsigned Dialect = getMAIAssemblerDialect();
1553 MatchingInlineAsm, Dialect);
1554 switch (MatchResult) {
1560 case Match_MissingFeature: {
1561 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1564 std::string Msg =
"instruction requires:";
1565 for (
unsigned I = 0, E = MissingFeatures.
size();
I != E; ++
I) {
1566 if (MissingFeatures[
I]) {
1571 return Error(IDLoc, Msg);
1574 case Match_InvalidOperand: {
1575 SMLoc ErrorLoc = IDLoc;
1578 return Error(IDLoc,
"too few operands for instruction");
1581 if (ErrorLoc ==
SMLoc())
1584 return Error(ErrorLoc,
"invalid operand for instruction");
1587 case Match_MnemonicFail: {
1588 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1589 std::string Suggestion = SystemZMnemonicSpellCheck(
1590 ((SystemZOperand &)*
Operands[0]).getToken(), FBS, Dialect);
1591 return Error(IDLoc,
"invalid instruction" + Suggestion,
1592 ((SystemZOperand &)*
Operands[0]).getLocRange());
1600 int64_t MinVal, int64_t MaxVal,
1606 if (getParser().parseExpression(Expr))
1609 auto IsOutOfRangeConstant = [&](
const MCExpr *E,
bool Negate) ->
bool {
1610 if (
auto *CE = dyn_cast<MCConstantExpr>(E)) {
1611 int64_t
Value =
CE->getValue();
1614 if ((
Value & 1) || Value < MinVal || Value > MaxVal)
1622 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1623 if (isParsingHLASM())
1624 return Error(StartLoc,
"Expected PC-relative expression");
1625 if (IsOutOfRangeConstant(CE,
false))
1626 return Error(StartLoc,
"offset out of range");
1627 int64_t
Value =
CE->getValue();
1637 if (
const auto *BE = dyn_cast<MCBinaryExpr>(Expr))
1638 if (IsOutOfRangeConstant(BE->getLHS(),
false) ||
1639 IsOutOfRangeConstant(BE->getRHS(),
1641 return Error(StartLoc,
"offset out of range");
1653 if (
Name ==
"tls_gdcall")
1655 else if (
Name ==
"tls_ldcall")
1678 Operands.push_back(SystemZOperand::createImmTLS(Expr,
Sym,
1681 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1686bool SystemZAsmParser::isLabel(
AsmToken &Token) {
1705 if (!RawLabel.
size())
1706 return !
Error(Loc,
"HLASM Label cannot be empty");
1709 if (RawLabel.
size() > 63)
1710 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1713 if (!isHLASMAlpha(RawLabel[0]))
1714 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1715 "character or the underscore character");
1720 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1721 if (!isHLASMAlnum(RawLabel[
I]))
1722 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,...