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;
230 unsigned getReg()
const override {
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");
1087 }
else if (
Reg.Group != RegGR) {
1088 Error(
Reg.StartLoc,
"invalid address register");
1098 RegisterKind RegKind) {
1100 unsigned Base = 0,
Index = 0, LengthReg = 0;
1102 bool HaveReg1, HaveReg2;
1106 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1107 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1108 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1112 const unsigned *Regs;
1123 if (parseAddressRegister(Reg1))
1125 Base = Regs[Reg1.Num];
1129 return Error(StartLoc,
"invalid use of indexed addressing");
1134 if (parseAddressRegister(Reg1))
1139 Index = Regs[Reg1.Num];
1141 Base = Regs[Reg1.Num];
1145 if (parseAddressRegister(Reg2))
1147 Base = Regs[Reg2.Num];
1153 if (parseAddressRegister(Reg2))
1155 Base = Regs[Reg2.Num];
1158 if (HaveReg1 && HaveReg2)
1159 return Error(StartLoc,
"invalid use of indexed addressing");
1162 return Error(StartLoc,
"missing length in address");
1166 if (!HaveReg1 || Reg1.Group != RegGR)
1167 return Error(StartLoc,
"invalid operand for instruction");
1171 if (parseAddressRegister(Reg2))
1173 Base = Regs[Reg2.Num];
1178 if (!HaveReg1 || Reg1.Group != RegV)
1179 return Error(StartLoc,
"vector index required in address");
1183 if (parseAddressRegister(Reg2))
1185 Base = Regs[Reg2.Num];
1192 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1201 if (IDVal ==
".insn")
1202 return ParseDirectiveInsn(DirectiveID.
getLoc());
1203 if (IDVal ==
".machine")
1204 return ParseDirectiveMachine(DirectiveID.
getLoc());
1206 return ParseGNUAttribute(DirectiveID.
getLoc());
1213bool SystemZAsmParser::ParseDirectiveInsn(
SMLoc L) {
1220 return Error(ErrorLoc,
"expected instruction format");
1230 if (EntryRange.first == EntryRange.second)
1231 return Error(ErrorLoc,
"unrecognized format");
1239 for (
int i = 0; i < Entry->NumOperands; i++) {
1240 MatchClassKind
Kind = Entry->OperandKinds[i];
1246 return Error(StartLoc,
"unexpected token in directive");
1251 if (Kind == MCK_AnyReg)
1253 else if (Kind == MCK_VR128)
1255 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1257 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1259 else if (Kind == MCK_BDVAddr64Disp12)
1261 else if (Kind == MCK_PCRel32)
1263 else if (Kind == MCK_PCRel16)
1272 return Error(StartLoc,
"unexpected token in directive");
1277 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1288 for (
size_t i = 0; i <
Operands.size(); i++) {
1290 MatchClassKind
Kind = Entry->OperandKinds[i];
1293 unsigned Res = validateOperandClass(Operand, Kind);
1294 if (Res != Match_Success)
1298 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1299 if (ZOperand.isReg())
1300 ZOperand.addRegOperands(Inst, 1);
1301 else if (ZOperand.isMem(BDMem))
1302 ZOperand.addBDAddrOperands(Inst, 2);
1303 else if (ZOperand.isMem(BDXMem))
1304 ZOperand.addBDXAddrOperands(Inst, 3);
1305 else if (ZOperand.isMem(BDVMem))
1306 ZOperand.addBDVAddrOperands(Inst, 3);
1307 else if (ZOperand.isImm())
1308 ZOperand.addImmOperands(Inst, 1);
1321bool SystemZAsmParser::ParseDirectiveMachine(
SMLoc L) {
1325 return TokError(
"unexpected token in '.machine' directive");
1334 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1336 getTargetStreamer().emitMachine(CPU);
1341bool SystemZAsmParser::ParseGNUAttribute(
SMLoc L) {
1343 int64_t IntegerValue;
1345 return Error(L,
"malformed .gnu_attribute directive");
1348 if (
Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))
1349 return Error(L,
"unrecognized .gnu_attribute tag/value pair.");
1356bool SystemZAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
1357 SMLoc &EndLoc,
bool RestoreOnFailure) {
1359 if (parseRegister(Reg, RestoreOnFailure))
1361 if (
Reg.Group == RegGR)
1363 else if (
Reg.Group == RegFP)
1365 else if (
Reg.Group == RegV)
1367 else if (
Reg.Group == RegAR)
1369 else if (
Reg.Group == RegCR)
1371 StartLoc =
Reg.StartLoc;
1372 EndLoc =
Reg.EndLoc;
1378 return ParseRegister(Reg, StartLoc, EndLoc,
false);
1383 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
true);
1384 bool PendingErrors = getParser().hasPendingError();
1385 getParser().clearPendingErrors();
1401 Operands.push_back(SystemZOperand::createToken(
Name, NameLoc));
1417 "No space allowed between comma that separates operand entries");
1442 getStreamer().AddComment(
Remark);
1446 SMLoc Loc = getLexer().getLoc();
1447 return Error(Loc,
"unexpected token in argument list");
1466 setAvailableFeatures(
All);
1468 setAvailableFeatures(AvailableFeatures);
1484 if (parseRegister(Reg))
1486 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1495 bool HaveReg1, HaveReg2;
1498 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1503 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1504 && parseAddressRegister(Reg1))
1506 if (HaveReg2 && parseAddressRegister(Reg2))
1511 if (HaveReg1 || HaveReg2 ||
Length)
1512 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1514 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1518bool SystemZAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &
Opcode,
1522 bool MatchingInlineAsm) {
1524 unsigned MatchResult;
1526 unsigned Dialect = getMAIAssemblerDialect();
1530 MatchingInlineAsm, Dialect);
1531 switch (MatchResult) {
1537 case Match_MissingFeature: {
1538 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1541 std::string
Msg =
"instruction requires:";
1542 for (
unsigned I = 0,
E = MissingFeatures.
size();
I !=
E; ++
I) {
1543 if (MissingFeatures[
I]) {
1548 return Error(IDLoc, Msg);
1551 case Match_InvalidOperand: {
1552 SMLoc ErrorLoc = IDLoc;
1555 return Error(IDLoc,
"too few operands for instruction");
1558 if (ErrorLoc ==
SMLoc())
1561 return Error(ErrorLoc,
"invalid operand for instruction");
1564 case Match_MnemonicFail: {
1565 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1566 std::string Suggestion = SystemZMnemonicSpellCheck(
1567 ((SystemZOperand &)*
Operands[0]).getToken(), FBS, Dialect);
1568 return Error(IDLoc,
"invalid instruction" + Suggestion,
1569 ((SystemZOperand &)*
Operands[0]).getLocRange());
1577 int64_t MinVal, int64_t MaxVal,
1583 if (getParser().parseExpression(Expr))
1586 auto isOutOfRangeConstant = [&](
const MCExpr *
E,
bool Negate) ->
bool {
1587 if (
auto *CE = dyn_cast<MCConstantExpr>(
E)) {
1588 int64_t
Value =
CE->getValue();
1591 if ((
Value & 1) || Value < MinVal || Value > MaxVal)
1599 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1600 if (isParsingHLASM())
1601 return Error(StartLoc,
"Expected PC-relative expression");
1602 if (isOutOfRangeConstant(CE,
false))
1603 return Error(StartLoc,
"offset out of range");
1604 int64_t
Value =
CE->getValue();
1614 if (
const auto *BE = dyn_cast<MCBinaryExpr>(Expr))
1615 if (isOutOfRangeConstant(BE->getLHS(),
false) ||
1616 isOutOfRangeConstant(BE->getRHS(),
1618 return Error(StartLoc,
"offset out of range");
1630 if (
Name ==
"tls_gdcall")
1632 else if (
Name ==
"tls_ldcall")
1655 Operands.push_back(SystemZOperand::createImmTLS(Expr,
Sym,
1658 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1663bool SystemZAsmParser::isLabel(
AsmToken &Token) {
1682 if (!RawLabel.
size())
1683 return !
Error(Loc,
"HLASM Label cannot be empty");
1686 if (RawLabel.
size() > 63)
1687 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1690 if (!isHLASMAlpha(RawLabel[0]))
1691 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1692 "character or the underscore character");
1697 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1698 if (!isHLASMAlnum(RawLabel[
I]))
1699 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.
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 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 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.
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()
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,...