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,
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");
421 bool parseIntegerRegister(
Register &Reg, RegisterGroup Group);
427 bool parseAddress(
bool &HaveReg1,
Register &Reg1,
bool &HaveReg2,
429 bool HasLength =
false,
bool HasVectorIndex =
false);
430 bool parseAddressRegister(
Register &Reg);
432 bool ParseDirectiveInsn(
SMLoc L);
433 bool ParseDirectiveMachine(
SMLoc L);
434 bool ParseGNUAttribute(
SMLoc L);
437 RegisterKind RegKind);
440 int64_t MaxVal,
bool AllowTLS);
461 unsigned getMAIAssemblerDialect() {
467 inline bool isHLASMAlpha(
char C) {
472 inline bool isHLASMAlnum(
char C) {
return isHLASMAlpha(
C) ||
isDigit(
C); }
475 inline bool isParsingHLASM() {
return getMAIAssemblerDialect() ==
AD_HLASM; }
478 inline bool isParsingATT() {
return getMAIAssemblerDialect() ==
AD_ATT; }
498 bool RestoreOnFailure);
500 SMLoc &EndLoc)
override;
506 bool MatchingInlineAsm)
override;
567 return parseAddress(
Operands, BDMem, GR32Reg);
570 return parseAddress(
Operands, BDMem, GR64Reg);
573 return parseAddress(
Operands, BDXMem, GR64Reg);
576 return parseAddress(
Operands, BDLMem, GR64Reg);
579 return parseAddress(
Operands, BDRMem, GR64Reg);
582 return parseAddress(
Operands, BDVMem, GR64Reg);
585 return parsePCRel(
Operands, -(1LL << 12), (1LL << 12) - 1,
false);
588 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
false);
591 return parsePCRel(
Operands, -(1LL << 24), (1LL << 24) - 1,
false);
594 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
false);
597 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
true);
600 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
true);
606#define GET_REGISTER_MATCHER
607#define GET_SUBTARGET_FEATURE_NAME
608#define GET_MATCHER_IMPLEMENTATION
609#define GET_MNEMONIC_SPELL_CHECKER
610#include "SystemZGenAsmMatcher.inc"
630 return LHS.Format <
RHS.Format;
637 {
"e", SystemZ::InsnE, 1,
639 {
"ri", SystemZ::InsnRI, 3,
640 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
641 {
"rie", SystemZ::InsnRIE, 4,
642 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
643 {
"ril", SystemZ::InsnRIL, 3,
644 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
645 {
"rilu", SystemZ::InsnRILU, 3,
646 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
647 {
"ris", SystemZ::InsnRIS, 5,
648 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
649 {
"rr", SystemZ::InsnRR, 3,
650 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
651 {
"rre", SystemZ::InsnRRE, 3,
652 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
653 {
"rrf", SystemZ::InsnRRF, 5,
654 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
655 {
"rrs", SystemZ::InsnRRS, 5,
656 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
657 {
"rs", SystemZ::InsnRS, 4,
658 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
659 {
"rse", SystemZ::InsnRSE, 4,
660 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
661 {
"rsi", SystemZ::InsnRSI, 4,
662 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
663 {
"rsy", SystemZ::InsnRSY, 4,
664 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
665 {
"rx", SystemZ::InsnRX, 3,
666 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
667 {
"rxe", SystemZ::InsnRXE, 3,
668 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
669 {
"rxf", SystemZ::InsnRXF, 4,
670 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
671 {
"rxy", SystemZ::InsnRXY, 3,
672 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
673 {
"s", SystemZ::InsnS, 2,
674 { MCK_U32Imm, MCK_BDAddr64Disp12 } },
675 {
"si", SystemZ::InsnSI, 3,
676 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
677 {
"sil", SystemZ::InsnSIL, 3,
678 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
679 {
"siy", SystemZ::InsnSIY, 3,
680 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
681 {
"ss", SystemZ::InsnSS, 4,
682 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
683 {
"sse", SystemZ::InsnSSE, 3,
684 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
685 {
"ssf", SystemZ::InsnSSF, 4,
686 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
687 {
"vri", SystemZ::InsnVRI, 6,
688 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
689 {
"vrr", SystemZ::InsnVRR, 7,
690 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
692 {
"vrs", SystemZ::InsnVRS, 5,
693 { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
694 {
"vrv", SystemZ::InsnVRV, 4,
695 { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
696 {
"vrx", SystemZ::InsnVRX, 4,
697 { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
698 {
"vsi", SystemZ::InsnVSI, 4,
699 { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }
705 if (
auto *CE = dyn_cast<MCConstantExpr>(E))
707 else if (
auto *UE = dyn_cast<MCUnaryExpr>(E))
709 else if (
auto *BE = dyn_cast<MCBinaryExpr>(E))
711 else if (
auto *SRE = dyn_cast<MCSymbolRefExpr>(E))
720 OS <<
"Token:" << getToken();
732 if (getImmTLS().
Sym) {
739 OS <<
"Mem:" << *cast<MCConstantExpr>(
Op.Disp);
742 if (
Op.MemKind == BDLMem)
743 OS << *cast<MCConstantExpr>(
Op.Length.Imm) <<
",";
744 else if (
Op.MemKind == BDRMem)
759bool SystemZAsmParser::parseRegister(
Register &Reg,
bool RestoreOnFailure) {
770 if (RestoreOnFailure)
771 getLexer().UnLex(PercentTok);
772 return Error(
Reg.StartLoc,
"invalid register");
777 if (
Name.size() < 2) {
778 if (RestoreOnFailure)
779 getLexer().UnLex(PercentTok);
780 return Error(
Reg.StartLoc,
"invalid register");
785 if (
Name.substr(1).getAsInteger(10,
Reg.Num)) {
786 if (RestoreOnFailure)
787 getLexer().UnLex(PercentTok);
788 return Error(
Reg.StartLoc,
"invalid register");
792 if (Prefix ==
'r' &&
Reg.Num < 16)
794 else if (Prefix ==
'f' &&
Reg.Num < 16)
796 else if (Prefix ==
'v' &&
Reg.Num < 32)
798 else if (Prefix ==
'a' &&
Reg.Num < 16)
800 else if (Prefix ==
'c' &&
Reg.Num < 16)
803 if (RestoreOnFailure)
804 getLexer().UnLex(PercentTok);
805 return Error(
Reg.StartLoc,
"invalid register");
845 if (parseRegister(Reg))
855 if (Group !=
Reg.Group)
856 return Error(
Reg.StartLoc,
"invalid operand for instruction");
859 if (
Reg.Group != RegV &&
Reg.Group != RegFP)
860 return Error(
Reg.StartLoc,
"invalid operand for instruction");
864 if (parseIntegerRegister(Reg, Group))
872 const unsigned *Regs;
887 if (Regs[
Reg.Num] == 0)
888 return Error(
Reg.StartLoc,
"invalid register pair");
891 SystemZOperand::createReg(Kind, Regs[
Reg.Num],
Reg.StartLoc,
Reg.EndLoc));
905 if (
auto *CE = dyn_cast<MCConstantExpr>(
Register)) {
906 int64_t
Value =
CE->getValue();
907 if (Value < 0 || Value > 15)
908 return Error(StartLoc,
"invalid register");
917 if (isParsingHLASM())
921 if (parseRegister(Reg))
925 return Error(StartLoc,
"invalid register");
930 if (
Reg.Group == RegGR) {
934 else if (
Reg.Group == RegFP) {
938 else if (
Reg.Group == RegV) {
942 else if (
Reg.Group == RegAR) {
946 else if (
Reg.Group == RegCR) {
954 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
955 Reg.StartLoc,
Reg.EndLoc));
960bool SystemZAsmParser::parseIntegerRegister(
Register &Reg,
961 RegisterGroup Group) {
968 const auto *
CE = dyn_cast<MCConstantExpr>(
Register);
972 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
973 int64_t
Value =
CE->getValue();
974 if (Value < 0 || Value > MaxRegNum) {
989bool SystemZAsmParser::parseAddress(
bool &HaveReg1,
Register &Reg1,
992 bool HasLength,
bool HasVectorIndex) {
994 if (getParser().parseExpression(Disp))
1020 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
1028 if (parseRegister(Reg1))
1039 if (getParser().parseExpression(
Length))
1047 if (parseIntegerRegister(Reg1, RegGroup))
1054 if (getParser().parseExpression(
Length))
1065 if (parseIntegerRegister(Reg2, RegGR))
1068 if (isParsingATT() && parseRegister(Reg2))
1083SystemZAsmParser::parseAddressRegister(
Register &Reg) {
1084 if (
Reg.Group == RegV) {
1085 Error(
Reg.StartLoc,
"invalid use of vector addressing");
1088 if (
Reg.Group != RegGR) {
1089 Error(
Reg.StartLoc,
"invalid address register");
1099 RegisterKind RegKind) {
1101 unsigned Base = 0,
Index = 0, LengthReg = 0;
1103 bool HaveReg1, HaveReg2;
1107 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1108 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1109 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1113 const unsigned *Regs;
1124 if (parseAddressRegister(Reg1))
1126 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1130 return Error(StartLoc,
"invalid use of indexed addressing");
1135 if (parseAddressRegister(Reg1))
1140 Index = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1142 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1146 if (parseAddressRegister(Reg2))
1148 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1154 if (parseAddressRegister(Reg2))
1156 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1159 if (HaveReg1 && HaveReg2)
1160 return Error(StartLoc,
"invalid use of indexed addressing");
1163 return Error(StartLoc,
"missing length in address");
1167 if (!HaveReg1 || Reg1.Group != RegGR)
1168 return Error(StartLoc,
"invalid operand for instruction");
1172 if (parseAddressRegister(Reg2))
1174 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1179 if (!HaveReg1 || Reg1.Group != RegV)
1180 return Error(StartLoc,
"vector index required in address");
1184 if (parseAddressRegister(Reg2))
1186 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1193 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1202 if (IDVal ==
".insn")
1203 return ParseDirectiveInsn(DirectiveID.
getLoc());
1204 if (IDVal ==
".machine")
1205 return ParseDirectiveMachine(DirectiveID.
getLoc());
1207 return ParseGNUAttribute(DirectiveID.
getLoc());
1214bool SystemZAsmParser::ParseDirectiveInsn(
SMLoc L) {
1221 return Error(ErrorLoc,
"expected instruction format");
1231 if (EntryRange.first == EntryRange.second)
1232 return Error(ErrorLoc,
"unrecognized format");
1240 for (
int I = 0;
I <
Entry->NumOperands;
I++) {
1241 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1247 return Error(StartLoc,
"unexpected token in directive");
1252 if (Kind == MCK_AnyReg)
1254 else if (Kind == MCK_VR128)
1256 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1258 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1260 else if (Kind == MCK_BDVAddr64Disp12)
1262 else if (Kind == MCK_PCRel32)
1264 else if (Kind == MCK_PCRel16)
1273 return Error(StartLoc,
"unexpected token in directive");
1278 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1291 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1294 unsigned Res = validateOperandClass(Operand, Kind);
1295 if (Res != Match_Success)
1299 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1300 if (ZOperand.isReg())
1301 ZOperand.addRegOperands(Inst, 1);
1302 else if (ZOperand.isMem(BDMem))
1303 ZOperand.addBDAddrOperands(Inst, 2);
1304 else if (ZOperand.isMem(BDXMem))
1305 ZOperand.addBDXAddrOperands(Inst, 3);
1306 else if (ZOperand.isMem(BDVMem))
1307 ZOperand.addBDVAddrOperands(Inst, 3);
1308 else if (ZOperand.isImm())
1309 ZOperand.addImmOperands(Inst, 1);
1322bool SystemZAsmParser::ParseDirectiveMachine(
SMLoc L) {
1326 return TokError(
"unexpected token in '.machine' directive");
1335 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1337 getTargetStreamer().emitMachine(CPU);
1342bool SystemZAsmParser::ParseGNUAttribute(
SMLoc L) {
1344 int64_t IntegerValue;
1346 return Error(L,
"malformed .gnu_attribute directive");
1349 if (
Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))
1350 return Error(L,
"unrecognized .gnu_attribute tag/value pair.");
1357bool SystemZAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
1358 SMLoc &EndLoc,
bool RestoreOnFailure) {
1360 if (parseRegister(Reg, RestoreOnFailure))
1362 if (
Reg.Group == RegGR)
1364 else if (
Reg.Group == RegFP)
1366 else if (
Reg.Group == RegV)
1368 else if (
Reg.Group == RegAR)
1370 else if (
Reg.Group == RegCR)
1372 StartLoc =
Reg.StartLoc;
1373 EndLoc =
Reg.EndLoc;
1379 return ParseRegister(Reg, StartLoc, EndLoc,
false);
1384 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
true);
1385 bool PendingErrors = getParser().hasPendingError();
1386 getParser().clearPendingErrors();
1402 Operands.push_back(SystemZOperand::createToken(
Name, NameLoc));
1418 "No space allowed between comma that separates operand entries");
1443 getStreamer().AddComment(
Remark);
1447 SMLoc Loc = getLexer().getLoc();
1448 return Error(Loc,
"unexpected token in argument list");
1467 setAvailableFeatures(
All);
1469 setAvailableFeatures(AvailableFeatures);
1485 if (parseRegister(Reg))
1487 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1496 bool HaveReg1, HaveReg2;
1499 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1504 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1505 && parseAddressRegister(Reg1))
1507 if (HaveReg2 && parseAddressRegister(Reg2))
1512 if (HaveReg1 || HaveReg2 ||
Length)
1513 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1515 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1519bool SystemZAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &
Opcode,
1523 bool MatchingInlineAsm) {
1525 unsigned MatchResult;
1527 unsigned Dialect = getMAIAssemblerDialect();
1531 MatchingInlineAsm, Dialect);
1532 switch (MatchResult) {
1538 case Match_MissingFeature: {
1539 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1542 std::string Msg =
"instruction requires:";
1543 for (
unsigned I = 0, E = MissingFeatures.
size();
I != E; ++
I) {
1544 if (MissingFeatures[
I]) {
1549 return Error(IDLoc, Msg);
1552 case Match_InvalidOperand: {
1553 SMLoc ErrorLoc = IDLoc;
1556 return Error(IDLoc,
"too few operands for instruction");
1559 if (ErrorLoc ==
SMLoc())
1562 return Error(ErrorLoc,
"invalid operand for instruction");
1565 case Match_MnemonicFail: {
1566 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1567 std::string Suggestion = SystemZMnemonicSpellCheck(
1568 ((SystemZOperand &)*
Operands[0]).getToken(), FBS, Dialect);
1569 return Error(IDLoc,
"invalid instruction" + Suggestion,
1570 ((SystemZOperand &)*
Operands[0]).getLocRange());
1578 int64_t MinVal, int64_t MaxVal,
1584 if (getParser().parseExpression(Expr))
1587 auto IsOutOfRangeConstant = [&](
const MCExpr *E,
bool Negate) ->
bool {
1588 if (
auto *CE = dyn_cast<MCConstantExpr>(E)) {
1589 int64_t
Value =
CE->getValue();
1592 if ((
Value & 1) || Value < MinVal || Value > MaxVal)
1600 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1601 if (isParsingHLASM())
1602 return Error(StartLoc,
"Expected PC-relative expression");
1603 if (IsOutOfRangeConstant(CE,
false))
1604 return Error(StartLoc,
"offset out of range");
1605 int64_t
Value =
CE->getValue();
1615 if (
const auto *BE = dyn_cast<MCBinaryExpr>(Expr))
1616 if (IsOutOfRangeConstant(BE->getLHS(),
false) ||
1617 IsOutOfRangeConstant(BE->getRHS(),
1619 return Error(StartLoc,
"offset out of range");
1631 if (
Name ==
"tls_gdcall")
1633 else if (
Name ==
"tls_ldcall")
1656 Operands.push_back(SystemZOperand::createImmTLS(Expr,
Sym,
1659 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1664bool SystemZAsmParser::isLabel(
AsmToken &Token) {
1683 if (!RawLabel.
size())
1684 return !
Error(Loc,
"HLASM Label cannot be empty");
1687 if (RawLabel.
size() > 63)
1688 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1691 if (!isHLASMAlpha(RawLabel[0]))
1692 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1693 "character or the underscore character");
1698 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1699 if (!isHLASMAlnum(RawLabel[
I]))
1700 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 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 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 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 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 ...
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,...