49static bool inRange(
const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,
50 bool AllowSymbol =
false) {
52 int64_t
Value = CE->getValue();
98 SMLoc StartLoc, EndLoc;
127 unsigned MemKind : 4;
128 unsigned RegKind : 4;
151 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
162 SystemZOperand(OperandKind Kind, SMLoc StartLoc, SMLoc EndLoc)
163 : Kind(Kind), StartLoc(StartLoc), EndLoc(EndLoc) {}
166 static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
168 return std::make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
171 static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
172 auto Op = std::make_unique<SystemZOperand>(KindToken, Loc, Loc);
173 Op->Token.Data = Str.data();
174 Op->Token.Length = Str.size();
178 static std::unique_ptr<SystemZOperand>
179 createReg(RegisterKind Kind,
unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
180 auto Op = std::make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
186 static std::unique_ptr<SystemZOperand>
187 createImm(
const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
188 auto Op = std::make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
193 static std::unique_ptr<SystemZOperand>
194 createMem(MemoryKind MemKind, RegisterKind RegKind,
unsigned Base,
195 const MCExpr *Disp,
unsigned Index,
const MCExpr *LengthImm,
196 unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {
197 auto Op = std::make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
198 Op->Mem.MemKind = MemKind;
199 Op->Mem.RegKind = RegKind;
203 if (MemKind == BDLMem)
204 Op->Mem.Length.Imm = LengthImm;
205 if (MemKind == BDRMem)
206 Op->Mem.Length.Reg = LengthReg;
210 static std::unique_ptr<SystemZOperand>
211 createImmTLS(
const MCExpr *Imm,
const MCExpr *Sym,
212 SMLoc StartLoc, SMLoc EndLoc) {
213 auto Op = std::make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
214 Op->ImmTLS.Imm =
Imm;
215 Op->ImmTLS.Sym = Sym;
220 bool isToken()
const override {
221 return Kind == KindToken;
224 assert(Kind == KindToken &&
"Not a token");
225 return StringRef(Token.Data, Token.Length);
229 bool isReg()
const override {
230 return Kind == KindReg;
232 bool isReg(RegisterKind RegKind)
const {
233 return Kind == KindReg &&
Reg.Kind == RegKind;
235 MCRegister
getReg()
const override {
236 assert(Kind == KindReg &&
"Not a register");
241 bool isImm()
const override {
242 return Kind == KindImm;
244 bool isImm(int64_t MinValue, int64_t MaxValue)
const {
245 return Kind == KindImm &&
inRange(Imm, MinValue, MaxValue,
true);
247 const MCExpr *
getImm()
const {
248 assert(Kind == KindImm &&
"Not an immediate");
253 bool isImmTLS()
const {
254 return Kind == KindImmTLS;
257 const ImmTLSOp getImmTLS()
const {
258 assert(Kind == KindImmTLS &&
"Not a TLS immediate");
263 bool isMem()
const override {
264 return Kind == KindMem;
266 bool isMem(MemoryKind MemKind)
const {
267 return (Kind == KindMem &&
268 (Mem.MemKind == MemKind ||
271 (Mem.MemKind == BDMem && MemKind == BDXMem)));
273 bool isMem(MemoryKind MemKind, RegisterKind RegKind)
const {
274 return isMem(MemKind) && Mem.RegKind == RegKind;
276 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind)
const {
277 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, 0, 0xfff,
true);
279 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind)
const {
280 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, -524288, 524287,
true);
282 bool isMemDisp12Len4(RegisterKind RegKind)
const {
283 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x10);
285 bool isMemDisp12Len8(RegisterKind RegKind)
const {
286 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x100);
289 const MemOp& getMem()
const {
290 assert(Kind == KindMem &&
"Not a Mem operand");
295 SMLoc getStartLoc()
const override {
return StartLoc; }
296 SMLoc getEndLoc()
const override {
return EndLoc; }
297 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
301 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
305 void addRegOperands(MCInst &Inst,
unsigned N)
const {
306 assert(
N == 1 &&
"Invalid number of operands");
309 void addImmOperands(MCInst &Inst,
unsigned N)
const {
310 assert(
N == 1 &&
"Invalid number of operands");
313 void addBDAddrOperands(MCInst &Inst,
unsigned N)
const {
314 assert(
N == 2 &&
"Invalid number of operands");
317 addExpr(Inst, Mem.Disp);
319 void addBDXAddrOperands(MCInst &Inst,
unsigned N)
const {
320 assert(
N == 3 &&
"Invalid number of operands");
323 addExpr(Inst, Mem.Disp);
326 void addBDLAddrOperands(MCInst &Inst,
unsigned N)
const {
327 assert(
N == 3 &&
"Invalid number of operands");
330 addExpr(Inst, Mem.Disp);
331 addExpr(Inst, Mem.Length.Imm);
333 void addBDRAddrOperands(MCInst &Inst,
unsigned N)
const {
334 assert(
N == 3 &&
"Invalid number of operands");
337 addExpr(Inst, Mem.Disp);
340 void addBDVAddrOperands(MCInst &Inst,
unsigned N)
const {
341 assert(
N == 3 &&
"Invalid number of operands");
344 addExpr(Inst, Mem.Disp);
347 void addLXAAddrOperands(MCInst &Inst,
unsigned N)
const {
348 assert(
N == 3 &&
"Invalid number of operands");
351 addExpr(Inst, Mem.Disp);
354 void addImmTLSOperands(MCInst &Inst,
unsigned N)
const {
355 assert(
N == 2 &&
"Invalid number of operands");
356 assert(Kind == KindImmTLS &&
"Invalid operand type");
357 addExpr(Inst, ImmTLS.Imm);
359 addExpr(Inst, ImmTLS.Sym);
363 bool isGR32()
const {
return isReg(GR32Reg); }
364 bool isGRH32()
const {
return isReg(GRH32Reg); }
365 bool isGRX32()
const {
return false; }
366 bool isGR64()
const {
return isReg(GR64Reg); }
367 bool isGR128()
const {
return isReg(GR128Reg); }
368 bool isADDR32()
const {
return isReg(GR32Reg); }
369 bool isADDR64()
const {
return isReg(GR64Reg); }
370 bool isADDR128()
const {
return false; }
371 bool isFP16()
const {
return isReg(FP16Reg); }
372 bool isFP32()
const {
return isReg(FP32Reg); }
373 bool isFP64()
const {
return isReg(FP64Reg); }
374 bool isFP128()
const {
return isReg(FP128Reg); }
375 bool isVR16()
const {
return isReg(VR16Reg); }
376 bool isVR32()
const {
return isReg(VR32Reg); }
377 bool isVR64()
const {
return isReg(VR64Reg); }
378 bool isVF128()
const {
return false; }
379 bool isVR128()
const {
return isReg(VR128Reg); }
380 bool isAR32()
const {
return isReg(AR32Reg); }
381 bool isCR64()
const {
return isReg(CR64Reg); }
382 bool isAnyReg()
const {
return (
isReg() || isImm(0, 15)); }
383 bool isBDAddr32Disp12()
const {
return isMemDisp12(BDMem, GR32Reg); }
384 bool isBDAddr32Disp20()
const {
return isMemDisp20(BDMem, GR32Reg); }
385 bool isBDAddr64Disp12()
const {
return isMemDisp12(BDMem, GR64Reg); }
386 bool isBDAddr64Disp20()
const {
return isMemDisp20(BDMem, GR64Reg); }
387 bool isBDXAddr64Disp12()
const {
return isMemDisp12(BDXMem, GR64Reg); }
388 bool isBDXAddr64Disp20()
const {
return isMemDisp20(BDXMem, GR64Reg); }
389 bool isBDLAddr64Disp12Len4()
const {
return isMemDisp12Len4(GR64Reg); }
390 bool isBDLAddr64Disp12Len8()
const {
return isMemDisp12Len8(GR64Reg); }
391 bool isBDRAddr64Disp12()
const {
return isMemDisp12(BDRMem, GR64Reg); }
392 bool isBDVAddr64Disp12()
const {
return isMemDisp12(BDVMem, GR64Reg); }
393 bool isLXAAddr64Disp20()
const {
return isMemDisp20(LXAMem, GR64Reg); }
394 bool isU1Imm()
const {
return isImm(0, 1); }
395 bool isU2Imm()
const {
return isImm(0, 3); }
396 bool isU3Imm()
const {
return isImm(0, 7); }
397 bool isU4Imm()
const {
return isImm(0, 15); }
398 bool isU8Imm()
const {
return isImm(0, 255); }
399 bool isS8Imm()
const {
return isImm(-128, 127); }
400 bool isU12Imm()
const {
return isImm(0, 4095); }
401 bool isU16Imm()
const {
return isImm(0, 65535); }
402 bool isS16Imm()
const {
return isImm(-32768, 32767); }
403 bool isU32Imm()
const {
return isImm(0, (1LL << 32) - 1); }
404 bool isS32Imm()
const {
return isImm(-(1LL << 31), (1LL << 31) - 1); }
405 bool isU48Imm()
const {
return isImm(0, (1LL << 48) - 1); }
409#define GET_ASSEMBLER_HEADER
410#include "SystemZGenAsmMatcher.inc"
430 SMLoc StartLoc, EndLoc;
433 SystemZTargetStreamer &getTargetStreamer() {
434 assert(getParser().getStreamer().getTargetStreamer() &&
435 "do not have a target streamer");
436 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
437 return static_cast<SystemZTargetStreamer &
>(TS);
440 bool parseRegister(Register &
Reg,
bool RequirePercent,
441 bool RestoreOnFailure =
false);
443 bool parseIntegerRegister(Register &
Reg, RegisterGroup Group);
449 bool parseAddress(
bool &HaveReg1, Register &Reg1,
bool &HaveReg2,
450 Register &Reg2,
const MCExpr *&Disp,
const MCExpr *&
Length,
451 bool HasLength =
false,
bool HasVectorIndex =
false);
452 bool parseAddressRegister(Register &
Reg);
454 bool parseDirectiveInsn(SMLoc L);
455 bool parseDirectiveMachine(SMLoc L);
456 bool parseGNUAttribute(SMLoc L);
459 RegisterKind RegKind);
462 int64_t MaxVal,
bool AllowTLS);
483 unsigned getMAIAssemblerDialect() {
484 return Parser.getContext().getAsmInfo()->getAssemblerDialect();
489 inline bool isHLASMAlpha(
char C) {
494 inline bool isHLASMAlnum(
char C) {
return isHLASMAlpha(
C) ||
isDigit(
C); }
497 inline bool isParsingHLASM() {
return getMAIAssemblerDialect() ==
AD_HLASM; }
500 inline bool isParsingGNU() {
return getMAIAssemblerDialect() ==
AD_GNU; }
503 SystemZAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
504 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
505 : MCTargetAsmParser(
Options, sti, MII), Parser(parser) {
512 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
516 ParseStatus parseDirective(AsmToken DirectiveID)
override;
517 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
518 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
519 bool RequirePercent,
bool RestoreOnFailure);
520 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
521 SMLoc &EndLoc)
override;
522 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
524 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
527 bool MatchingInlineAsm)
override;
528 bool isLabel(AsmToken &Token)
override;
532 return parseRegister(
Operands, GR32Reg);
535 return parseRegister(
Operands, GRH32Reg);
541 return parseRegister(
Operands, GR64Reg);
544 return parseRegister(
Operands, GR128Reg);
548 return parseRegister(
Operands, GR32Reg);
552 return parseRegister(
Operands, GR64Reg);
558 return parseRegister(
Operands, FP16Reg);
561 return parseRegister(
Operands, FP32Reg);
564 return parseRegister(
Operands, FP64Reg);
567 return parseRegister(
Operands, FP128Reg);
570 return parseRegister(
Operands, VR16Reg);
573 return parseRegister(
Operands, VR32Reg);
576 return parseRegister(
Operands, VR64Reg);
582 return parseRegister(
Operands, VR128Reg);
585 return parseRegister(
Operands, AR32Reg);
588 return parseRegister(
Operands, CR64Reg);
594 return parseAddress(
Operands, BDMem, GR32Reg);
597 return parseAddress(
Operands, BDMem, GR64Reg);
600 return parseAddress(
Operands, BDXMem, GR64Reg);
603 return parseAddress(
Operands, BDLMem, GR64Reg);
606 return parseAddress(
Operands, BDRMem, GR64Reg);
609 return parseAddress(
Operands, BDVMem, GR64Reg);
612 return parseAddress(
Operands, LXAMem, GR64Reg);
615 return parsePCRel(
Operands, -(1LL << 12), (1LL << 12) - 1,
false);
618 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
false);
621 return parsePCRel(
Operands, -(1LL << 24), (1LL << 24) - 1,
false);
624 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
false);
627 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
true);
630 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
true);
636#define GET_REGISTER_MATCHER
637#define GET_SUBTARGET_FEATURE_NAME
638#define GET_MATCHER_IMPLEMENTATION
639#define GET_MNEMONIC_SPELL_CHECKER
640#include "SystemZGenAsmMatcher.inc"
654 return LHS.Format < RHS;
657 return LHS < RHS.Format;
660 return LHS.Format < RHS.Format;
667 {
"e", SystemZ::InsnE, 1,
669 {
"ri", SystemZ::InsnRI, 3,
670 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
671 {
"rie", SystemZ::InsnRIE, 4,
672 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
673 {
"ril", SystemZ::InsnRIL, 3,
674 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
675 {
"rilu", SystemZ::InsnRILU, 3,
676 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
677 {
"ris", SystemZ::InsnRIS, 5,
678 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
679 {
"rr", SystemZ::InsnRR, 3,
680 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
681 {
"rre", SystemZ::InsnRRE, 3,
682 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
683 {
"rrf", SystemZ::InsnRRF, 5,
684 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
685 {
"rrs", SystemZ::InsnRRS, 5,
686 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
687 {
"rs", SystemZ::InsnRS, 4,
688 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
689 {
"rse", SystemZ::InsnRSE, 4,
690 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
691 {
"rsi", SystemZ::InsnRSI, 4,
692 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
693 {
"rsy", SystemZ::InsnRSY, 4,
694 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
695 {
"rx", SystemZ::InsnRX, 3,
696 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
697 {
"rxe", SystemZ::InsnRXE, 3,
698 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
699 {
"rxf", SystemZ::InsnRXF, 4,
700 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
701 {
"rxy", SystemZ::InsnRXY, 3,
702 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
703 {
"s", SystemZ::InsnS, 2,
704 { MCK_U32Imm, MCK_BDAddr64Disp12 } },
705 {
"si", SystemZ::InsnSI, 3,
706 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
707 {
"sil", SystemZ::InsnSIL, 3,
708 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
709 {
"siy", SystemZ::InsnSIY, 3,
710 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
711 {
"ss", SystemZ::InsnSS, 4,
712 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
713 {
"sse", SystemZ::InsnSSE, 3,
714 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
715 {
"ssf", SystemZ::InsnSSF, 4,
716 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
717 {
"vri", SystemZ::InsnVRI, 6,
718 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
719 {
"vrr", SystemZ::InsnVRR, 7,
720 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
722 {
"vrs", SystemZ::InsnVRS, 5,
723 { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
724 {
"vrv", SystemZ::InsnVRV, 4,
725 { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
726 {
"vrx", SystemZ::InsnVRX, 4,
727 { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
728 {
"vsi", SystemZ::InsnVSI, 4,
729 { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }
747 if (getImmTLS().Sym) {
753 const MemOp &
Op = getMem();
758 if (
Op.MemKind == BDLMem) {
761 }
else if (
Op.MemKind == BDRMem)
776bool SystemZAsmParser::parseRegister(
Register &
Reg,
bool RequirePercent,
777 bool RestoreOnFailure) {
778 const AsmToken &PercentTok = Parser.
getTok();
784 return Error(PercentTok.
getLoc(),
"register expected");
792 if (RestoreOnFailure && HasPercent)
793 getLexer().UnLex(PercentTok);
795 HasPercent ?
"invalid register" :
"register expected");
800 if (
Name.size() < 2) {
801 if (RestoreOnFailure && HasPercent)
802 getLexer().UnLex(PercentTok);
803 return Error(
Reg.StartLoc,
"invalid register");
808 if (
Name.substr(1).getAsInteger(10,
Reg.Num)) {
809 if (RestoreOnFailure && HasPercent)
810 getLexer().UnLex(PercentTok);
811 return Error(
Reg.StartLoc,
"invalid register");
815 if (Prefix ==
'r' &&
Reg.Num < 16)
817 else if (Prefix ==
'f' &&
Reg.Num < 16)
819 else if (Prefix ==
'v' &&
Reg.Num < 32)
821 else if (Prefix ==
'a' &&
Reg.Num < 16)
823 else if (Prefix ==
'c' &&
Reg.Num < 16)
826 if (RestoreOnFailure && HasPercent)
827 getLexer().UnLex(PercentTok);
828 return Error(
Reg.StartLoc,
"invalid register");
870 if (parseRegister(
Reg,
true))
880 if (Group !=
Reg.Group)
881 return Error(
Reg.StartLoc,
"invalid operand for instruction");
884 if (
Reg.Group != RegV &&
Reg.Group != RegFP)
885 return Error(
Reg.StartLoc,
"invalid operand for instruction");
889 if (parseIntegerRegister(
Reg, Group))
898 const unsigned *Regs;
916 if (Regs[
Reg.Num] == 0)
917 return Error(
Reg.StartLoc,
"invalid register pair");
920 SystemZOperand::createReg(Kind, Regs[
Reg.Num],
Reg.StartLoc,
Reg.EndLoc));
935 int64_t
Value =
CE->getValue();
937 return Error(StartLoc,
"invalid register");
946 if (isParsingHLASM())
950 if (parseRegister(
Reg,
true))
954 return Error(StartLoc,
"invalid register");
959 if (
Reg.Group == RegGR) {
963 else if (
Reg.Group == RegFP) {
967 else if (
Reg.Group == RegV) {
971 else if (
Reg.Group == RegAR) {
975 else if (
Reg.Group == RegCR) {
983 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
984 Reg.StartLoc,
Reg.EndLoc));
989bool SystemZAsmParser::parseIntegerRegister(
Register &
Reg,
990 RegisterGroup Group) {
1001 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
1002 int64_t
Value =
CE->getValue();
1018bool SystemZAsmParser::parseAddress(
bool &HaveReg1,
Register &Reg1,
1020 const MCExpr *&Disp,
const MCExpr *&
Length,
1021 bool HasLength,
bool HasVectorIndex) {
1023 if (getParser().parseExpression(Disp))
1049 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
1057 if (parseRegister(Reg1,
true))
1068 if (getParser().parseExpression(
Length))
1076 if (parseIntegerRegister(Reg1, RegGroup))
1083 if (getParser().parseExpression(
Length))
1094 if (parseIntegerRegister(Reg2, RegGR))
1096 }
else if (isParsingGNU()) {
1098 if (parseRegister(Reg2,
true))
1104 Reg2.StartLoc = Reg2.EndLoc = Parser.
getTok().
getLoc();
1119SystemZAsmParser::parseAddressRegister(
Register &
Reg) {
1120 if (
Reg.Group == RegV) {
1121 Error(
Reg.StartLoc,
"invalid use of vector addressing");
1124 if (
Reg.Group != RegGR) {
1125 Error(
Reg.StartLoc,
"invalid address register");
1135 RegisterKind RegKind) {
1137 unsigned Base = 0,
Index = 0, LengthReg = 0;
1139 bool HaveReg1, HaveReg2;
1143 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1144 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1145 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1149 const unsigned *Regs;
1160 if (parseAddressRegister(Reg1))
1162 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1166 return Error(StartLoc,
"invalid use of indexed addressing");
1172 const unsigned *IndexRegs = Regs;
1173 if (MemKind == LXAMem)
1176 if (parseAddressRegister(Reg1))
1181 if (HaveReg2 || isParsingHLASM())
1182 Index = Reg1.Num == 0 ? 0 : IndexRegs[Reg1.Num];
1184 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1188 if (parseAddressRegister(Reg2))
1190 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1196 if (parseAddressRegister(Reg2))
1198 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1201 if (HaveReg1 && HaveReg2)
1202 return Error(StartLoc,
"invalid use of indexed addressing");
1205 return Error(StartLoc,
"missing length in address");
1209 if (!HaveReg1 || Reg1.Group != RegGR)
1210 return Error(StartLoc,
"invalid operand for instruction");
1214 if (parseAddressRegister(Reg2))
1216 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1221 if (!HaveReg1 || Reg1.Group != RegV)
1222 return Error(StartLoc,
"vector index required in address");
1226 if (isParsingGNU() && !HaveReg2)
1227 return Error(Reg1.StartLoc,
"invalid use of vector addressing");
1230 if (parseAddressRegister(Reg2))
1232 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1239 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1240 Index,
Length, LengthReg,
1245ParseStatus SystemZAsmParser::parseDirective(AsmToken DirectiveID) {
1248 if (IDVal ==
".insn")
1249 return parseDirectiveInsn(DirectiveID.
getLoc());
1250 if (IDVal ==
".machine")
1251 return parseDirectiveMachine(DirectiveID.
getLoc());
1253 return parseGNUAttribute(DirectiveID.
getLoc());
1260bool SystemZAsmParser::parseDirectiveInsn(SMLoc L) {
1261 MCAsmParser &Parser = getParser();
1267 return Error(ErrorLoc,
"expected instruction format");
1277 if (EntryRange.first == EntryRange.second)
1278 return Error(ErrorLoc,
"unrecognized format");
1280 struct InsnMatchEntry *
Entry = EntryRange.first;
1286 for (
int I = 0;
I <
Entry->NumOperands;
I++) {
1287 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1293 return Error(StartLoc,
"unexpected token in directive");
1298 if (Kind == MCK_AnyReg)
1300 else if (Kind == MCK_VR128)
1302 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1304 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1306 else if (Kind == MCK_BDVAddr64Disp12)
1308 else if (Kind == MCK_LXAAddr64Disp20)
1310 else if (Kind == MCK_PCRel32)
1312 else if (Kind == MCK_PCRel16)
1321 return Error(StartLoc,
"unexpected token in directive");
1326 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1335 MCInst Inst = MCInstBuilder(
Entry->Opcode);
1338 MCParsedAsmOperand &Operand = *
Operands[
I];
1339 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1342 unsigned Res = validateOperandClass(Operand, Kind, *STI);
1343 if (Res != Match_Success)
1347 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1348 if (ZOperand.isReg())
1349 ZOperand.addRegOperands(Inst, 1);
1350 else if (ZOperand.isMem(BDMem))
1351 ZOperand.addBDAddrOperands(Inst, 2);
1352 else if (ZOperand.isMem(BDXMem))
1353 ZOperand.addBDXAddrOperands(Inst, 3);
1354 else if (ZOperand.isMem(BDVMem))
1355 ZOperand.addBDVAddrOperands(Inst, 3);
1356 else if (ZOperand.isMem(LXAMem))
1357 ZOperand.addLXAAddrOperands(Inst, 3);
1358 else if (ZOperand.isImm())
1359 ZOperand.addImmOperands(Inst, 1);
1372bool SystemZAsmParser::parseDirectiveMachine(SMLoc L) {
1373 MCAsmParser &Parser = getParser();
1376 return TokError(
"unexpected token in '.machine' directive");
1388 MachineStack.
push_back(getAvailableFeatures());
1389 }
else if (Id ==
"pop") {
1391 if (MachineStack.
empty())
1393 "pop without corresponding push in '.machine' directive");
1394 setAvailableFeatures(MachineStack.
back());
1399 MCSubtargetInfo &STI = copySTI();
1401 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1403 getTargetStreamer().emitMachine(Id);
1408bool SystemZAsmParser::parseGNUAttribute(SMLoc L) {
1410 int64_t IntegerValue;
1412 return Error(L,
"malformed .gnu_attribute directive");
1415 if (
Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))
1416 return Error(L,
"unrecognized .gnu_attribute tag/value pair.");
1423bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1424 SMLoc &EndLoc,
bool RequirePercent,
1425 bool RestoreOnFailure) {
1427 if (parseRegister(
Reg, RequirePercent, RestoreOnFailure))
1429 if (
Reg.Group == RegGR)
1431 else if (
Reg.Group == RegFP)
1433 else if (
Reg.Group == RegV)
1435 else if (
Reg.Group == RegAR)
1437 else if (
Reg.Group == RegCR)
1439 StartLoc =
Reg.StartLoc;
1440 EndLoc =
Reg.EndLoc;
1444bool SystemZAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1446 return ParseRegister(
Reg, StartLoc, EndLoc,
false,
1450ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1452 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
false,
1454 bool PendingErrors = getParser().hasPendingError();
1455 getParser().clearPendingErrors();
1463bool SystemZAsmParser::parseInstruction(ParseInstructionInfo &
Info,
1464 StringRef Name, SMLoc NameLoc,
1471 Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
1476 if (parseOperand(
Operands, Name)) {
1487 "No space allowed between comma that separates operand entries");
1489 if (parseOperand(
Operands, Name)) {
1500 StringRef
Remark(getLexer().LexUntilEndOfStatement());
1512 getStreamer().AddComment(
Remark);
1516 SMLoc Loc = getLexer().getLoc();
1517 return Error(Loc,
"unexpected token in argument list");
1527 StringRef Mnemonic) {
1533 FeatureBitset AvailableFeatures = getAvailableFeatures();
1536 setAvailableFeatures(
All);
1537 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic);
1538 setAvailableFeatures(AvailableFeatures);
1554 if (parseRegister(
Reg,
true))
1556 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1565 bool HaveReg1, HaveReg2;
1568 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1573 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1574 && parseAddressRegister(Reg1))
1576 if (HaveReg2 && parseAddressRegister(Reg2))
1581 if (HaveReg1 || HaveReg2 ||
Length)
1582 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1584 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1588bool SystemZAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1591 uint64_t &ErrorInfo,
1592 bool MatchingInlineAsm) {
1594 unsigned MatchResult;
1596 unsigned Dialect = getMAIAssemblerDialect();
1598 FeatureBitset MissingFeatures;
1599 MatchResult = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
1600 MatchingInlineAsm, Dialect);
1601 switch (MatchResult) {
1607 case Match_MissingFeature: {
1608 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1611 std::string Msg =
"instruction requires:";
1612 for (
unsigned I = 0,
E = MissingFeatures.
size();
I !=
E; ++
I) {
1613 if (MissingFeatures[
I]) {
1618 return Error(IDLoc, Msg);
1621 case Match_InvalidOperand: {
1622 SMLoc ErrorLoc = IDLoc;
1623 if (ErrorInfo != ~0ULL) {
1625 return Error(IDLoc,
"too few operands for instruction");
1627 ErrorLoc = ((SystemZOperand &)*
Operands[ErrorInfo]).getStartLoc();
1628 if (ErrorLoc == SMLoc())
1631 return Error(ErrorLoc,
"invalid operand for instruction");
1634 case Match_MnemonicFail: {
1635 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1636 std::string Suggestion = SystemZMnemonicSpellCheck(
1638 return Error(IDLoc,
"invalid instruction" + Suggestion,
1639 ((SystemZOperand &)*
Operands[0]).getLocRange());
1647 int64_t MinVal, int64_t MaxVal,
1650 MCStreamer &Out = getStreamer();
1653 if (getParser().parseExpression(Expr))
1656 auto IsOutOfRangeConstant = [&](
const MCExpr *
E,
bool Negate) ->
bool {
1658 int64_t
Value =
CE->getValue();
1670 if (isParsingHLASM())
1671 return Error(StartLoc,
"Expected PC-relative expression");
1672 if (IsOutOfRangeConstant(CE,
false))
1673 return Error(StartLoc,
"offset out of range");
1674 int64_t
Value =
CE->getValue();
1684 if (IsOutOfRangeConstant(BE->getLHS(),
false) ||
1685 IsOutOfRangeConstant(BE->getRHS(),
1687 return Error(StartLoc,
"offset out of range");
1690 const MCExpr *Sym =
nullptr;
1699 if (Name ==
"tls_gdcall")
1701 else if (Name ==
"tls_ldcall")
1724 Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1727 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1732bool SystemZAsmParser::isLabel(AsmToken &Token) {
1748 SMLoc Loc = Token.
getLoc();
1751 if (!RawLabel.
size())
1752 return !
Error(Loc,
"HLASM Label cannot be empty");
1755 if (RawLabel.
size() > 63)
1756 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1759 if (!isHLASMAlpha(RawLabel[0]))
1760 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1761 "character or the underscore character");
1766 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1767 if (!isHLASMAlnum(RawLabel[
I]))
1768 return !
Error(Loc,
"HLASM Label has to be alphanumeric");
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
mir Rename Register Operands
Promote Memory to Register
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
This file defines the SmallVector class.
static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue, bool AllowSymbol=false)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmParser()
static struct InsnMatchEntry InsnMatchTable[]
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
LLVM_ABI SMLoc getLoc() const
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.
constexpr size_t size() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Generic assembler parser interface, for use by target specific assembly parsers.
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.
MCStreamer & getStreamer()
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI 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.
void addOperand(const MCOperand Op)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual 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.
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, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
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 VR16Regs[32]
const unsigned GR128Regs[16]
const unsigned GRH32Regs[16]
const unsigned FP32Regs[16]
const unsigned FP16Regs[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)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSystemZTarget()
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
bool isAlpha(char C)
Checks if character C is a valid letter as classified by "C" locale.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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,...