46static bool inRange(
const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,
47 bool AllowSymbol =
false) {
48 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
49 int64_t
Value = CE->getValue();
92 SMLoc StartLoc, EndLoc;
121 unsigned MemKind : 4;
122 unsigned RegKind : 4;
149 else if (
auto *CE = dyn_cast<MCConstantExpr>(Expr))
156 SystemZOperand(OperandKind kind,
SMLoc startLoc,
SMLoc endLoc)
157 :
Kind(kind), StartLoc(startLoc), EndLoc(endLoc) {}
160 static std::unique_ptr<SystemZOperand> createInvalid(
SMLoc StartLoc,
162 return std::make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
165 static std::unique_ptr<SystemZOperand> createToken(
StringRef Str,
SMLoc Loc) {
166 auto Op = std::make_unique<SystemZOperand>(KindToken, Loc, Loc);
167 Op->Token.Data = Str.data();
168 Op->Token.Length = Str.size();
172 static std::unique_ptr<SystemZOperand>
173 createReg(RegisterKind Kind,
unsigned Num,
SMLoc StartLoc,
SMLoc EndLoc) {
174 auto Op = std::make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
180 static std::unique_ptr<SystemZOperand>
182 auto Op = std::make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
187 static std::unique_ptr<SystemZOperand>
188 createMem(MemoryKind MemKind, RegisterKind RegKind,
unsigned Base,
190 unsigned LengthReg,
SMLoc StartLoc,
SMLoc EndLoc) {
191 auto Op = std::make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
192 Op->Mem.MemKind = MemKind;
193 Op->Mem.RegKind = RegKind;
197 if (MemKind == BDLMem)
198 Op->Mem.Length.Imm = LengthImm;
199 if (MemKind == BDRMem)
200 Op->Mem.Length.Reg = LengthReg;
204 static std::unique_ptr<SystemZOperand>
207 auto Op = std::make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
208 Op->ImmTLS.Imm =
Imm;
209 Op->ImmTLS.Sym = Sym;
214 bool isToken()
const override {
215 return Kind == KindToken;
218 assert(Kind == KindToken &&
"Not a token");
219 return StringRef(Token.Data, Token.Length);
223 bool isReg()
const override {
224 return Kind == KindReg;
226 bool isReg(RegisterKind RegKind)
const {
227 return Kind == KindReg &&
Reg.Kind == RegKind;
229 unsigned getReg()
const override {
230 assert(Kind == KindReg &&
"Not a register");
235 bool isImm()
const override {
236 return Kind == KindImm;
238 bool isImm(int64_t MinValue, int64_t MaxValue)
const {
239 return Kind == KindImm &&
inRange(Imm, MinValue, MaxValue);
241 const MCExpr *getImm()
const {
242 assert(Kind == KindImm &&
"Not an immediate");
247 bool isImmTLS()
const {
248 return Kind == KindImmTLS;
251 const ImmTLSOp getImmTLS()
const {
252 assert(Kind == KindImmTLS &&
"Not a TLS immediate");
257 bool isMem()
const override {
258 return Kind == KindMem;
260 bool isMem(MemoryKind MemKind)
const {
261 return (Kind == KindMem &&
262 (Mem.MemKind == MemKind ||
265 (Mem.MemKind == BDMem && MemKind == BDXMem)));
267 bool isMem(MemoryKind MemKind, RegisterKind RegKind)
const {
268 return isMem(MemKind) && Mem.RegKind == RegKind;
270 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind)
const {
271 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, 0, 0xfff,
true);
273 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind)
const {
274 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, -524288, 524287,
true);
276 bool isMemDisp12Len4(RegisterKind RegKind)
const {
277 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x10);
279 bool isMemDisp12Len8(RegisterKind RegKind)
const {
280 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x100);
283 const MemOp& getMem()
const {
284 assert(Kind == KindMem &&
"Not a Mem operand");
299 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
300 assert(
N == 1 &&
"Invalid number of operands");
303 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
304 assert(
N == 1 &&
"Invalid number of operands");
305 addExpr(Inst, getImm());
307 void addBDAddrOperands(
MCInst &Inst,
unsigned N)
const {
308 assert(
N == 2 &&
"Invalid number of operands");
311 addExpr(Inst, Mem.Disp);
313 void addBDXAddrOperands(
MCInst &Inst,
unsigned N)
const {
314 assert(
N == 3 &&
"Invalid number of operands");
317 addExpr(Inst, Mem.Disp);
320 void addBDLAddrOperands(
MCInst &Inst,
unsigned N)
const {
321 assert(
N == 3 &&
"Invalid number of operands");
324 addExpr(Inst, Mem.Disp);
325 addExpr(Inst, Mem.Length.Imm);
327 void addBDRAddrOperands(
MCInst &Inst,
unsigned N)
const {
328 assert(
N == 3 &&
"Invalid number of operands");
331 addExpr(Inst, Mem.Disp);
334 void addBDVAddrOperands(
MCInst &Inst,
unsigned N)
const {
335 assert(
N == 3 &&
"Invalid number of operands");
338 addExpr(Inst, Mem.Disp);
341 void addImmTLSOperands(
MCInst &Inst,
unsigned N)
const {
342 assert(
N == 2 &&
"Invalid number of operands");
343 assert(Kind == KindImmTLS &&
"Invalid operand type");
344 addExpr(Inst, ImmTLS.Imm);
346 addExpr(Inst, ImmTLS.Sym);
350 bool isGR32()
const {
return isReg(GR32Reg); }
351 bool isGRH32()
const {
return isReg(GRH32Reg); }
352 bool isGRX32()
const {
return false; }
353 bool isGR64()
const {
return isReg(GR64Reg); }
354 bool isGR128()
const {
return isReg(GR128Reg); }
355 bool isADDR32()
const {
return isReg(GR32Reg); }
356 bool isADDR64()
const {
return isReg(GR64Reg); }
357 bool isADDR128()
const {
return false; }
358 bool isFP32()
const {
return isReg(FP32Reg); }
359 bool isFP64()
const {
return isReg(FP64Reg); }
360 bool isFP128()
const {
return isReg(FP128Reg); }
361 bool isVR32()
const {
return isReg(VR32Reg); }
362 bool isVR64()
const {
return isReg(VR64Reg); }
363 bool isVF128()
const {
return false; }
364 bool isVR128()
const {
return isReg(VR128Reg); }
365 bool isAR32()
const {
return isReg(AR32Reg); }
366 bool isCR64()
const {
return isReg(CR64Reg); }
367 bool isAnyReg()
const {
return (
isReg() ||
isImm(0, 15)); }
368 bool isBDAddr32Disp12()
const {
return isMemDisp12(BDMem, GR32Reg); }
369 bool isBDAddr32Disp20()
const {
return isMemDisp20(BDMem, GR32Reg); }
370 bool isBDAddr64Disp12()
const {
return isMemDisp12(BDMem, GR64Reg); }
371 bool isBDAddr64Disp20()
const {
return isMemDisp20(BDMem, GR64Reg); }
372 bool isBDXAddr64Disp12()
const {
return isMemDisp12(BDXMem, GR64Reg); }
373 bool isBDXAddr64Disp20()
const {
return isMemDisp20(BDXMem, GR64Reg); }
374 bool isBDLAddr64Disp12Len4()
const {
return isMemDisp12Len4(GR64Reg); }
375 bool isBDLAddr64Disp12Len8()
const {
return isMemDisp12Len8(GR64Reg); }
376 bool isBDRAddr64Disp12()
const {
return isMemDisp12(BDRMem, GR64Reg); }
377 bool isBDVAddr64Disp12()
const {
return isMemDisp12(BDVMem, GR64Reg); }
378 bool isU1Imm()
const {
return isImm(0, 1); }
379 bool isU2Imm()
const {
return isImm(0, 3); }
380 bool isU3Imm()
const {
return isImm(0, 7); }
381 bool isU4Imm()
const {
return isImm(0, 15); }
382 bool isU6Imm()
const {
return isImm(0, 63); }
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");
421 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);
439 RegisterKind RegKind);
442 int64_t MaxVal,
bool AllowTLS);
463 unsigned getMAIAssemblerDialect() {
469 inline bool isHLASMAlpha(
char C) {
474 inline bool isHLASMAlnum(
char C) {
return isHLASMAlpha(
C) ||
isDigit(
C); }
477 inline bool isParsingHLASM() {
return getMAIAssemblerDialect() ==
AD_HLASM; }
480 inline bool isParsingATT() {
return getMAIAssemblerDialect() ==
AD_ATT; }
499 SMLoc &EndLoc)
override;
501 bool RestoreOnFailure);
503 SMLoc &EndLoc)
override;
509 bool MatchingInlineAsm)
override;
570 return parseAddress(
Operands, BDMem, GR32Reg);
573 return parseAddress(
Operands, BDMem, GR64Reg);
576 return parseAddress(
Operands, BDXMem, GR64Reg);
579 return parseAddress(
Operands, BDLMem, GR64Reg);
582 return parseAddress(
Operands, BDRMem, GR64Reg);
585 return parseAddress(
Operands, BDVMem, GR64Reg);
588 return parsePCRel(
Operands, -(1LL << 12), (1LL << 12) - 1,
false);
591 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
false);
594 return parsePCRel(
Operands, -(1LL << 24), (1LL << 24) - 1,
false);
597 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
false);
600 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
true);
603 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
true);
609#define GET_REGISTER_MATCHER
610#define GET_SUBTARGET_FEATURE_NAME
611#define GET_MATCHER_IMPLEMENTATION
612#define GET_MNEMONIC_SPELL_CHECKER
613#include "SystemZGenAsmMatcher.inc"
633 return LHS.Format <
RHS.Format;
640 {
"e", SystemZ::InsnE, 1,
642 {
"ri", SystemZ::InsnRI, 3,
643 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
644 {
"rie", SystemZ::InsnRIE, 4,
645 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
646 {
"ril", SystemZ::InsnRIL, 3,
647 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
648 {
"rilu", SystemZ::InsnRILU, 3,
649 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
650 {
"ris", SystemZ::InsnRIS, 5,
651 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
652 {
"rr", SystemZ::InsnRR, 3,
653 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
654 {
"rre", SystemZ::InsnRRE, 3,
655 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
656 {
"rrf", SystemZ::InsnRRF, 5,
657 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
658 {
"rrs", SystemZ::InsnRRS, 5,
659 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
660 {
"rs", SystemZ::InsnRS, 4,
661 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
662 {
"rse", SystemZ::InsnRSE, 4,
663 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
664 {
"rsi", SystemZ::InsnRSI, 4,
665 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
666 {
"rsy", SystemZ::InsnRSY, 4,
667 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
668 {
"rx", SystemZ::InsnRX, 3,
669 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
670 {
"rxe", SystemZ::InsnRXE, 3,
671 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
672 {
"rxf", SystemZ::InsnRXF, 4,
673 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
674 {
"rxy", SystemZ::InsnRXY, 3,
675 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
676 {
"s", SystemZ::InsnS, 2,
677 { MCK_U32Imm, MCK_BDAddr64Disp12 } },
678 {
"si", SystemZ::InsnSI, 3,
679 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
680 {
"sil", SystemZ::InsnSIL, 3,
681 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
682 {
"siy", SystemZ::InsnSIY, 3,
683 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
684 {
"ss", SystemZ::InsnSS, 4,
685 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
686 {
"sse", SystemZ::InsnSSE, 3,
687 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
688 {
"ssf", SystemZ::InsnSSF, 4,
689 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
690 {
"vri", SystemZ::InsnVRI, 6,
691 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
692 {
"vrr", SystemZ::InsnVRR, 7,
693 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
695 {
"vrs", SystemZ::InsnVRS, 5,
696 { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
697 {
"vrv", SystemZ::InsnVRV, 4,
698 { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
699 {
"vrx", SystemZ::InsnVRX, 4,
700 { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
701 {
"vsi", SystemZ::InsnVSI, 4,
702 { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }
708 if (
auto *CE = dyn_cast<MCConstantExpr>(
E))
710 else if (
auto *UE = dyn_cast<MCUnaryExpr>(
E))
712 else if (
auto *BE = dyn_cast<MCBinaryExpr>(
E))
714 else if (
auto *SRE = dyn_cast<MCSymbolRefExpr>(
E))
723 OS <<
"Token:" << getToken();
735 if (getImmTLS().Sym) {
742 OS <<
"Mem:" << *cast<MCConstantExpr>(
Op.Disp);
745 if (
Op.MemKind == BDLMem)
746 OS << *cast<MCConstantExpr>(
Op.Length.Imm) <<
",";
747 else if (
Op.MemKind == BDRMem)
762bool SystemZAsmParser::parseRegister(
Register &Reg,
bool RestoreOnFailure) {
773 if (RestoreOnFailure)
774 getLexer().UnLex(PercentTok);
775 return Error(
Reg.StartLoc,
"invalid register");
780 if (
Name.size() < 2) {
781 if (RestoreOnFailure)
782 getLexer().UnLex(PercentTok);
783 return Error(
Reg.StartLoc,
"invalid register");
788 if (
Name.substr(1).getAsInteger(10,
Reg.Num)) {
789 if (RestoreOnFailure)
790 getLexer().UnLex(PercentTok);
791 return Error(
Reg.StartLoc,
"invalid register");
795 if (Prefix ==
'r' &&
Reg.Num < 16)
797 else if (Prefix ==
'f' &&
Reg.Num < 16)
799 else if (Prefix ==
'v' &&
Reg.Num < 32)
801 else if (Prefix ==
'a' &&
Reg.Num < 16)
803 else if (Prefix ==
'c' &&
Reg.Num < 16)
806 if (RestoreOnFailure)
807 getLexer().UnLex(PercentTok);
808 return Error(
Reg.StartLoc,
"invalid register");
848 if (parseRegister(Reg))
858 if (Group !=
Reg.Group) {
859 Error(
Reg.StartLoc,
"invalid operand for instruction");
864 if (
Reg.Group != RegV &&
Reg.Group != RegFP) {
865 Error(
Reg.StartLoc,
"invalid operand for instruction");
871 if (parseIntegerRegister(Reg, Group))
879 const unsigned *Regs;
894 if (Regs[
Reg.Num] == 0) {
895 Error(
Reg.StartLoc,
"invalid register pair");
900 SystemZOperand::createReg(Kind, Regs[
Reg.Num],
Reg.StartLoc,
Reg.EndLoc));
915 if (
auto *CE = dyn_cast<MCConstantExpr>(
Register)) {
916 int64_t
Value =
CE->getValue();
917 if (Value < 0 || Value > 15) {
918 Error(StartLoc,
"invalid register");
929 if (isParsingHLASM())
933 if (parseRegister(Reg))
937 Error(StartLoc,
"invalid register");
944 if (
Reg.Group == RegGR) {
948 else if (
Reg.Group == RegFP) {
952 else if (
Reg.Group == RegV) {
956 else if (
Reg.Group == RegAR) {
960 else if (
Reg.Group == RegCR) {
968 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
969 Reg.StartLoc,
Reg.EndLoc));
974bool SystemZAsmParser::parseIntegerRegister(
Register &Reg,
975 RegisterGroup Group) {
982 const auto *
CE = dyn_cast<MCConstantExpr>(
Register);
986 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
987 int64_t
Value =
CE->getValue();
988 if (Value < 0 || Value > MaxRegNum) {
1003bool SystemZAsmParser::parseAddress(
bool &HaveReg1,
Register &Reg1,
1006 bool HasLength,
bool HasVectorIndex) {
1008 if (getParser().parseExpression(Disp))
1034 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
1042 if (parseRegister(Reg1))
1053 if (getParser().parseExpression(
Length))
1061 if (parseIntegerRegister(Reg1, RegGroup))
1068 if (getParser().parseExpression(
Length))
1079 if (parseIntegerRegister(Reg2, RegGR))
1082 if (isParsingATT() && parseRegister(Reg2))
1097SystemZAsmParser::parseAddressRegister(
Register &Reg) {
1098 if (
Reg.Group == RegV) {
1099 Error(
Reg.StartLoc,
"invalid use of vector addressing");
1101 }
else if (
Reg.Group != RegGR) {
1102 Error(
Reg.StartLoc,
"invalid address register");
1112 RegisterKind RegKind) {
1114 unsigned Base = 0,
Index = 0, LengthReg = 0;
1116 bool HaveReg1, HaveReg2;
1120 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1121 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1122 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1126 const unsigned *Regs;
1137 if (parseAddressRegister(Reg1))
1139 Base = Regs[Reg1.Num];
1143 Error(StartLoc,
"invalid use of indexed addressing");
1150 if (parseAddressRegister(Reg1))
1155 Index = Regs[Reg1.Num];
1157 Base = Regs[Reg1.Num];
1161 if (parseAddressRegister(Reg2))
1163 Base = Regs[Reg2.Num];
1169 if (parseAddressRegister(Reg2))
1171 Base = Regs[Reg2.Num];
1174 if (HaveReg1 && HaveReg2) {
1175 Error(StartLoc,
"invalid use of indexed addressing");
1180 Error(StartLoc,
"missing length in address");
1186 if (!HaveReg1 || Reg1.Group != RegGR) {
1187 Error(StartLoc,
"invalid operand for instruction");
1193 if (parseAddressRegister(Reg2))
1195 Base = Regs[Reg2.Num];
1200 if (!HaveReg1 || Reg1.Group != RegV) {
1201 Error(StartLoc,
"vector index required in address");
1207 if (parseAddressRegister(Reg2))
1209 Base = Regs[Reg2.Num];
1216 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1222bool SystemZAsmParser::ParseDirective(
AsmToken DirectiveID) {
1225 if (IDVal ==
".insn")
1226 return ParseDirectiveInsn(DirectiveID.
getLoc());
1227 if (IDVal ==
".machine")
1228 return ParseDirectiveMachine(DirectiveID.
getLoc());
1230 return ParseGNUAttribute(DirectiveID.
getLoc());
1237bool SystemZAsmParser::ParseDirectiveInsn(
SMLoc L) {
1244 return Error(ErrorLoc,
"expected instruction format");
1254 if (EntryRange.first == EntryRange.second)
1255 return Error(ErrorLoc,
"unrecognized format");
1263 for (
int i = 0; i < Entry->NumOperands; i++) {
1264 MatchClassKind
Kind = Entry->OperandKinds[i];
1270 return Error(StartLoc,
"unexpected token in directive");
1275 if (Kind == MCK_AnyReg)
1277 else if (Kind == MCK_VR128)
1279 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1281 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1283 else if (Kind == MCK_BDVAddr64Disp12)
1285 else if (Kind == MCK_PCRel32)
1287 else if (Kind == MCK_PCRel16)
1296 return Error(StartLoc,
"unexpected token in directive");
1301 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1312 for (
size_t i = 0; i <
Operands.size(); i++) {
1314 MatchClassKind
Kind = Entry->OperandKinds[i];
1317 unsigned Res = validateOperandClass(Operand, Kind);
1318 if (Res != Match_Success)
1322 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1323 if (ZOperand.isReg())
1324 ZOperand.addRegOperands(Inst, 1);
1325 else if (ZOperand.isMem(BDMem))
1326 ZOperand.addBDAddrOperands(Inst, 2);
1327 else if (ZOperand.isMem(BDXMem))
1328 ZOperand.addBDXAddrOperands(Inst, 3);
1329 else if (ZOperand.isMem(BDVMem))
1330 ZOperand.addBDVAddrOperands(Inst, 3);
1331 else if (ZOperand.isImm())
1332 ZOperand.addImmOperands(Inst, 1);
1345bool SystemZAsmParser::ParseDirectiveMachine(
SMLoc L) {
1349 return Error(L,
"unexpected token in '.machine' directive");
1354 return addErrorSuffix(
" in '.machine' directive");
1358 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1360 getTargetStreamer().emitMachine(CPU);
1365bool SystemZAsmParser::ParseGNUAttribute(
SMLoc L) {
1367 int64_t IntegerValue;
1372 if (
Tag != 8 || (IntegerValue < 0 || IntegerValue > 2)) {
1374 "Unrecognized .gnu_attribute tag/value pair.");
1383bool SystemZAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
1384 SMLoc &EndLoc,
bool RestoreOnFailure) {
1386 if (parseRegister(Reg, RestoreOnFailure))
1388 if (
Reg.Group == RegGR)
1390 else if (
Reg.Group == RegFP)
1392 else if (
Reg.Group == RegV)
1394 else if (
Reg.Group == RegAR)
1396 else if (
Reg.Group == RegCR)
1398 StartLoc =
Reg.StartLoc;
1399 EndLoc =
Reg.EndLoc;
1403bool SystemZAsmParser::parseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
1405 return ParseRegister(RegNo, StartLoc, EndLoc,
false);
1412 ParseRegister(RegNo, StartLoc, EndLoc,
true);
1413 bool PendingErrors = getParser().hasPendingError();
1414 getParser().clearPendingErrors();
1430 Operands.push_back(SystemZOperand::createToken(
Name, NameLoc));
1446 "No space allowed between comma that separates operand entries");
1471 getStreamer().AddComment(
Remark);
1475 SMLoc Loc = getLexer().getLoc();
1476 return Error(Loc,
"unexpected token in argument list");
1495 setAvailableFeatures(
All);
1497 setAvailableFeatures(AvailableFeatures);
1513 if (parseRegister(Reg))
1515 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1524 bool HaveReg1, HaveReg2;
1527 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1532 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1533 && parseAddressRegister(Reg1))
1535 if (HaveReg2 && parseAddressRegister(Reg2))
1540 if (HaveReg1 || HaveReg2 ||
Length)
1541 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1543 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1547bool SystemZAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &
Opcode,
1551 bool MatchingInlineAsm) {
1553 unsigned MatchResult;
1555 unsigned Dialect = getMAIAssemblerDialect();
1559 MatchingInlineAsm, Dialect);
1560 switch (MatchResult) {
1566 case Match_MissingFeature: {
1567 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1570 std::string
Msg =
"instruction requires:";
1571 for (
unsigned I = 0,
E = MissingFeatures.
size();
I !=
E; ++
I) {
1572 if (MissingFeatures[
I]) {
1577 return Error(IDLoc, Msg);
1580 case Match_InvalidOperand: {
1581 SMLoc ErrorLoc = IDLoc;
1584 return Error(IDLoc,
"too few operands for instruction");
1587 if (ErrorLoc ==
SMLoc())
1590 return Error(ErrorLoc,
"invalid operand for instruction");
1593 case Match_MnemonicFail: {
1594 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1595 std::string Suggestion = SystemZMnemonicSpellCheck(
1596 ((SystemZOperand &)*
Operands[0]).getToken(), FBS, Dialect);
1597 return Error(IDLoc,
"invalid instruction" + Suggestion,
1598 ((SystemZOperand &)*
Operands[0]).getLocRange());
1607 int64_t MaxVal,
bool AllowTLS) {
1612 if (getParser().parseExpression(Expr))
1615 auto isOutOfRangeConstant = [&](
const MCExpr *
E,
bool Negate) ->
bool {
1616 if (
auto *CE = dyn_cast<MCConstantExpr>(
E)) {
1617 int64_t
Value =
CE->getValue();
1620 if ((
Value & 1) || Value < MinVal || Value > MaxVal)
1628 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1629 if (isParsingHLASM()) {
1630 Error(StartLoc,
"Expected PC-relative expression");
1633 if (isOutOfRangeConstant(CE,
false)) {
1634 Error(StartLoc,
"offset out of range");
1637 int64_t
Value =
CE->getValue();
1647 if (
const auto *BE = dyn_cast<MCBinaryExpr>(Expr))
1648 if (isOutOfRangeConstant(BE->getLHS(),
false) ||
1649 isOutOfRangeConstant(BE->getRHS(),
1651 Error(StartLoc,
"offset out of range");
1656 const MCExpr *Sym =
nullptr;
1667 if (
Name ==
"tls_gdcall")
1669 else if (
Name ==
"tls_ldcall")
1698 Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1701 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1706bool SystemZAsmParser::isLabel(
AsmToken &Token) {
1725 if (!RawLabel.
size())
1726 return !
Error(Loc,
"HLASM Label cannot be empty");
1729 if (RawLabel.
size() > 63)
1730 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1733 if (!isHLASMAlpha(RawLabel[0]))
1734 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1735 "character or the underscore character");
1740 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1741 if (!isHLASMAlnum(RawLabel[
I]))
1742 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)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#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.
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 createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual unsigned getReg() const =0
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 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 bool ParseDirective(AsmToken DirectiveID)=0
ParseDirective - Parse a target specific assembler directive.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool isLabel(AsmToken &Token)
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
virtual OperandMatchResultTy tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
Target specific streamer interface.
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
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.
constexpr size_t size() const
size - Get the string size.
bool startswith(StringRef Prefix) const
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 CustomOperand< const MCSubtargetInfo & > Msg[]
@ 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()
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,...