48static bool inRange(
const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,
49 bool AllowSymbol =
false) {
51 int64_t
Value = CE->getValue();
97 SMLoc StartLoc, EndLoc;
126 unsigned MemKind : 4;
127 unsigned RegKind : 4;
150 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
161 SystemZOperand(OperandKind Kind, SMLoc StartLoc, SMLoc EndLoc)
162 : Kind(Kind), StartLoc(StartLoc), EndLoc(EndLoc) {}
165 static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
167 return std::make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
170 static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
171 auto Op = std::make_unique<SystemZOperand>(KindToken, Loc, Loc);
172 Op->Token.Data = Str.data();
173 Op->Token.Length = Str.size();
177 static std::unique_ptr<SystemZOperand>
178 createReg(RegisterKind Kind,
unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
179 auto Op = std::make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
185 static std::unique_ptr<SystemZOperand>
186 createImm(
const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
187 auto Op = std::make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
192 static std::unique_ptr<SystemZOperand>
193 createMem(MemoryKind MemKind, RegisterKind RegKind,
unsigned Base,
194 const MCExpr *Disp,
unsigned Index,
const MCExpr *LengthImm,
195 unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {
196 auto Op = std::make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
197 Op->Mem.MemKind = MemKind;
198 Op->Mem.RegKind = RegKind;
202 if (MemKind == BDLMem)
203 Op->Mem.Length.Imm = LengthImm;
204 if (MemKind == BDRMem)
205 Op->Mem.Length.Reg = LengthReg;
209 static std::unique_ptr<SystemZOperand>
210 createImmTLS(
const MCExpr *
Imm,
const MCExpr *Sym,
211 SMLoc StartLoc, SMLoc EndLoc) {
212 auto Op = std::make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
213 Op->ImmTLS.Imm =
Imm;
214 Op->ImmTLS.Sym = Sym;
219 bool isToken()
const override {
220 return Kind == KindToken;
223 assert(Kind == KindToken &&
"Not a token");
224 return StringRef(Token.Data, Token.Length);
228 bool isReg()
const override {
229 return Kind == KindReg;
231 bool isReg(RegisterKind RegKind)
const {
232 return Kind == KindReg &&
Reg.Kind == RegKind;
234 MCRegister
getReg()
const override {
235 assert(Kind == KindReg &&
"Not a register");
240 bool isImm()
const override {
241 return Kind == KindImm;
243 bool isImm(int64_t MinValue, int64_t MaxValue)
const {
244 return Kind == KindImm &&
inRange(
Imm, MinValue, MaxValue,
true);
246 const MCExpr *
getImm()
const {
247 assert(Kind == KindImm &&
"Not an immediate");
252 bool isImmTLS()
const {
253 return Kind == KindImmTLS;
256 const ImmTLSOp getImmTLS()
const {
257 assert(Kind == KindImmTLS &&
"Not a TLS immediate");
262 bool isMem()
const override {
263 return Kind == KindMem;
265 bool isMem(MemoryKind MemKind)
const {
266 return (Kind == KindMem &&
267 (Mem.MemKind == MemKind ||
270 (Mem.MemKind == BDMem && MemKind == BDXMem)));
272 bool isMem(MemoryKind MemKind, RegisterKind RegKind)
const {
273 return isMem(MemKind) && Mem.RegKind == RegKind;
275 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind)
const {
276 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, 0, 0xfff,
true);
278 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind)
const {
279 return isMem(MemKind, RegKind) &&
inRange(Mem.Disp, -524288, 524287,
true);
281 bool isMemDisp12Len4(RegisterKind RegKind)
const {
282 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x10);
284 bool isMemDisp12Len8(RegisterKind RegKind)
const {
285 return isMemDisp12(BDLMem, RegKind) &&
inRange(Mem.Length.Imm, 1, 0x100);
288 const MemOp& getMem()
const {
289 assert(Kind == KindMem &&
"Not a Mem operand");
294 SMLoc getStartLoc()
const override {
return StartLoc; }
295 SMLoc getEndLoc()
const override {
return EndLoc; }
296 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
300 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
304 void addRegOperands(MCInst &Inst,
unsigned N)
const {
305 assert(
N == 1 &&
"Invalid number of operands");
308 void addImmOperands(MCInst &Inst,
unsigned N)
const {
309 assert(
N == 1 &&
"Invalid number of operands");
312 void addBDAddrOperands(MCInst &Inst,
unsigned N)
const {
313 assert(
N == 2 &&
"Invalid number of operands");
316 addExpr(Inst, Mem.Disp);
318 void addBDXAddrOperands(MCInst &Inst,
unsigned N)
const {
319 assert(
N == 3 &&
"Invalid number of operands");
322 addExpr(Inst, Mem.Disp);
325 void addBDLAddrOperands(MCInst &Inst,
unsigned N)
const {
326 assert(
N == 3 &&
"Invalid number of operands");
329 addExpr(Inst, Mem.Disp);
330 addExpr(Inst, Mem.Length.Imm);
332 void addBDRAddrOperands(MCInst &Inst,
unsigned N)
const {
333 assert(
N == 3 &&
"Invalid number of operands");
336 addExpr(Inst, Mem.Disp);
339 void addBDVAddrOperands(MCInst &Inst,
unsigned N)
const {
340 assert(
N == 3 &&
"Invalid number of operands");
343 addExpr(Inst, Mem.Disp);
346 void addLXAAddrOperands(MCInst &Inst,
unsigned N)
const {
347 assert(
N == 3 &&
"Invalid number of operands");
350 addExpr(Inst, Mem.Disp);
353 void addImmTLSOperands(MCInst &Inst,
unsigned N)
const {
354 assert(
N == 2 &&
"Invalid number of operands");
355 assert(Kind == KindImmTLS &&
"Invalid operand type");
356 addExpr(Inst, ImmTLS.Imm);
358 addExpr(Inst, ImmTLS.Sym);
362 bool isGR32()
const {
return isReg(GR32Reg); }
363 bool isGRH32()
const {
return isReg(GRH32Reg); }
364 bool isGRX32()
const {
return false; }
365 bool isGR64()
const {
return isReg(GR64Reg); }
366 bool isGR128()
const {
return isReg(GR128Reg); }
367 bool isADDR32()
const {
return isReg(GR32Reg); }
368 bool isADDR64()
const {
return isReg(GR64Reg); }
369 bool isADDR128()
const {
return false; }
370 bool isFP16()
const {
return isReg(FP16Reg); }
371 bool isFP32()
const {
return isReg(FP32Reg); }
372 bool isFP64()
const {
return isReg(FP64Reg); }
373 bool isFP128()
const {
return isReg(FP128Reg); }
374 bool isVR16()
const {
return isReg(VR16Reg); }
375 bool isVR32()
const {
return isReg(VR32Reg); }
376 bool isVR64()
const {
return isReg(VR64Reg); }
377 bool isVF128()
const {
return false; }
378 bool isVR128()
const {
return isReg(VR128Reg); }
379 bool isAR32()
const {
return isReg(AR32Reg); }
380 bool isCR64()
const {
return isReg(CR64Reg); }
381 bool isAnyReg()
const {
return (
isReg() || isImm(0, 15)); }
382 bool isBDAddr32Disp12()
const {
return isMemDisp12(BDMem, GR32Reg); }
383 bool isBDAddr32Disp20()
const {
return isMemDisp20(BDMem, GR32Reg); }
384 bool isBDAddr64Disp12()
const {
return isMemDisp12(BDMem, GR64Reg); }
385 bool isBDAddr64Disp20()
const {
return isMemDisp20(BDMem, GR64Reg); }
386 bool isBDXAddr64Disp12()
const {
return isMemDisp12(BDXMem, GR64Reg); }
387 bool isBDXAddr64Disp20()
const {
return isMemDisp20(BDXMem, GR64Reg); }
388 bool isBDLAddr64Disp12Len4()
const {
return isMemDisp12Len4(GR64Reg); }
389 bool isBDLAddr64Disp12Len8()
const {
return isMemDisp12Len8(GR64Reg); }
390 bool isBDRAddr64Disp12()
const {
return isMemDisp12(BDRMem, GR64Reg); }
391 bool isBDVAddr64Disp12()
const {
return isMemDisp12(BDVMem, GR64Reg); }
392 bool isLXAAddr64Disp20()
const {
return isMemDisp20(LXAMem, GR64Reg); }
393 bool isU1Imm()
const {
return isImm(0, 1); }
394 bool isU2Imm()
const {
return isImm(0, 3); }
395 bool isU3Imm()
const {
return isImm(0, 7); }
396 bool isU4Imm()
const {
return isImm(0, 15); }
397 bool isU8Imm()
const {
return isImm(0, 255); }
398 bool isS8Imm()
const {
return isImm(-128, 127); }
399 bool isX8Imm()
const {
return isS8Imm() || isU8Imm(); }
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 isX16Imm()
const {
return isS16Imm() || isU16Imm(); }
404 bool isU32Imm()
const {
return isImm(0, (1LL << 32) - 1); }
405 bool isS32Imm()
const {
return isImm(-(1LL << 31), (1LL << 31) - 1); }
406 bool isX32Imm()
const {
return isS32Imm() || isU32Imm(); }
407 bool isU48Imm()
const {
return isImm(0, (1LL << 48) - 1); }
411#define GET_ASSEMBLER_HEADER
412#include "SystemZGenAsmMatcher.inc"
432 SMLoc StartLoc, EndLoc;
435 SystemZTargetStreamer &getTargetStreamer() {
436 assert(getParser().getStreamer().getTargetStreamer() &&
437 "do not have a target streamer");
438 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
439 return static_cast<SystemZTargetStreamer &
>(TS);
442 bool parseRegister(Register &
Reg,
bool RequirePercent,
443 bool RestoreOnFailure =
false);
445 bool parseIntegerRegister(Register &
Reg, RegisterGroup Group);
451 bool parseAddress(
bool &HaveReg1, Register &Reg1,
bool &HaveReg2,
452 Register &Reg2,
const MCExpr *&Disp,
const MCExpr *&
Length,
453 bool HasLength =
false,
bool HasVectorIndex =
false);
454 bool parseAddressRegister(Register &
Reg);
456 bool parseDirectiveInsn(SMLoc L);
457 bool parseDirectiveMachine(SMLoc L);
458 bool parseGNUAttribute(SMLoc L);
461 RegisterKind RegKind);
464 int64_t MaxVal,
bool AllowTLS);
485 unsigned getMAIAssemblerDialect() {
486 return Parser.getContext().getAsmInfo().getAssemblerDialect();
491 inline bool isHLASMAlpha(
char C) {
496 inline bool isHLASMAlnum(
char C) {
return isHLASMAlpha(
C) ||
isDigit(
C); }
499 inline bool isParsingHLASM() {
return getMAIAssemblerDialect() ==
AD_HLASM; }
502 inline bool isParsingGNU() {
return getMAIAssemblerDialect() ==
AD_GNU; }
505 SystemZAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
506 const MCInstrInfo &MII)
507 : MCTargetAsmParser(sti, MII), Parser(parser) {
514 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
518 ParseStatus parseDirective(AsmToken DirectiveID)
override;
519 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
520 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
521 bool RequirePercent,
bool RestoreOnFailure);
522 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
523 SMLoc &EndLoc)
override;
524 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
526 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
529 bool MatchingInlineAsm)
override;
530 bool isLabel(AsmToken &Token)
override;
534 return parseRegister(
Operands, GR32Reg);
537 return parseRegister(
Operands, GRH32Reg);
543 return parseRegister(
Operands, GR64Reg);
546 return parseRegister(
Operands, GR128Reg);
550 return parseRegister(
Operands, GR32Reg);
554 return parseRegister(
Operands, GR64Reg);
560 return parseRegister(
Operands, FP16Reg);
563 return parseRegister(
Operands, FP32Reg);
566 return parseRegister(
Operands, FP64Reg);
569 return parseRegister(
Operands, FP128Reg);
572 return parseRegister(
Operands, VR16Reg);
575 return parseRegister(
Operands, VR32Reg);
578 return parseRegister(
Operands, VR64Reg);
584 return parseRegister(
Operands, VR128Reg);
587 return parseRegister(
Operands, AR32Reg);
590 return parseRegister(
Operands, CR64Reg);
596 return parseAddress(
Operands, BDMem, GR32Reg);
599 return parseAddress(
Operands, BDMem, GR64Reg);
602 return parseAddress(
Operands, BDXMem, GR64Reg);
605 return parseAddress(
Operands, BDLMem, GR64Reg);
608 return parseAddress(
Operands, BDRMem, GR64Reg);
611 return parseAddress(
Operands, BDVMem, GR64Reg);
614 return parseAddress(
Operands, LXAMem, GR64Reg);
617 return parsePCRel(
Operands, -(1LL << 12), (1LL << 12) - 1,
false);
620 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
false);
623 return parsePCRel(
Operands, -(1LL << 24), (1LL << 24) - 1,
false);
626 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
false);
629 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
true);
632 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
true);
638#define GET_REGISTER_MATCHER
639#define GET_SUBTARGET_FEATURE_NAME
640#define GET_MATCHER_IMPLEMENTATION
641#define GET_MNEMONIC_SPELL_CHECKER
642#include "SystemZGenAsmMatcher.inc"
648#include "SystemZGenInsnMatchTable.inc"
667 if (getImmTLS().Sym) {
673 const MemOp &
Op = getMem();
678 if (
Op.MemKind == BDLMem) {
681 }
else if (
Op.MemKind == BDRMem)
696bool SystemZAsmParser::parseRegister(
Register &
Reg,
bool RequirePercent,
697 bool RestoreOnFailure) {
698 const AsmToken &PercentTok = Parser.
getTok();
704 return Error(PercentTok.
getLoc(),
"register expected");
712 if (RestoreOnFailure && HasPercent)
713 getLexer().UnLex(PercentTok);
715 HasPercent ?
"invalid register" :
"register expected");
720 if (
Name.size() < 2) {
721 if (RestoreOnFailure && HasPercent)
722 getLexer().UnLex(PercentTok);
723 return Error(
Reg.StartLoc,
"invalid register");
728 if (
Name.substr(1).getAsInteger(10,
Reg.Num)) {
729 if (RestoreOnFailure && HasPercent)
730 getLexer().UnLex(PercentTok);
731 return Error(
Reg.StartLoc,
"invalid register");
735 if (Prefix ==
'r' &&
Reg.Num < 16)
737 else if (Prefix ==
'f' &&
Reg.Num < 16)
739 else if (Prefix ==
'v' &&
Reg.Num < 32)
741 else if (Prefix ==
'a' &&
Reg.Num < 16)
743 else if (Prefix ==
'c' &&
Reg.Num < 16)
746 if (RestoreOnFailure && HasPercent)
747 getLexer().UnLex(PercentTok);
748 return Error(
Reg.StartLoc,
"invalid register");
790 if (parseRegister(
Reg,
true))
800 if (Group !=
Reg.Group)
801 return Error(
Reg.StartLoc,
"invalid operand for instruction");
804 if (
Reg.Group != RegV &&
Reg.Group != RegFP)
805 return Error(
Reg.StartLoc,
"invalid operand for instruction");
809 if (parseIntegerRegister(
Reg, Group))
818 const unsigned *Regs;
836 if (Regs[
Reg.Num] == 0)
837 return Error(
Reg.StartLoc,
"invalid register pair");
840 SystemZOperand::createReg(Kind, Regs[
Reg.Num],
Reg.StartLoc,
Reg.EndLoc));
855 int64_t
Value =
CE->getValue();
857 return Error(StartLoc,
"invalid register");
866 if (isParsingHLASM())
870 if (parseRegister(
Reg,
true))
874 return Error(StartLoc,
"invalid register");
879 if (
Reg.Group == RegGR) {
883 else if (
Reg.Group == RegFP) {
887 else if (
Reg.Group == RegV) {
891 else if (
Reg.Group == RegAR) {
895 else if (
Reg.Group == RegCR) {
903 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
904 Reg.StartLoc,
Reg.EndLoc));
909bool SystemZAsmParser::parseIntegerRegister(
Register &
Reg,
910 RegisterGroup Group) {
921 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
922 int64_t
Value =
CE->getValue();
938bool SystemZAsmParser::parseAddress(
bool &HaveReg1,
Register &Reg1,
940 const MCExpr *&Disp,
const MCExpr *&
Length,
941 bool HasLength,
bool HasVectorIndex) {
943 if (getParser().parseExpression(Disp))
969 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
977 if (parseRegister(Reg1,
true))
988 if (getParser().parseExpression(
Length))
996 if (parseIntegerRegister(Reg1, RegGroup))
1003 if (getParser().parseExpression(
Length))
1014 if (parseIntegerRegister(Reg2, RegGR))
1016 }
else if (isParsingGNU()) {
1018 if (parseRegister(Reg2,
true))
1024 Reg2.StartLoc = Reg2.EndLoc = Parser.
getTok().
getLoc();
1039SystemZAsmParser::parseAddressRegister(
Register &
Reg) {
1040 if (
Reg.Group == RegV) {
1041 Error(
Reg.StartLoc,
"invalid use of vector addressing");
1044 if (
Reg.Group != RegGR) {
1045 Error(
Reg.StartLoc,
"invalid address register");
1055 RegisterKind RegKind) {
1057 unsigned Base = 0,
Index = 0, LengthReg = 0;
1059 bool HaveReg1, HaveReg2;
1063 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1064 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1065 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1069 const unsigned *Regs;
1080 if (parseAddressRegister(Reg1))
1082 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1086 return Error(StartLoc,
"invalid use of indexed addressing");
1092 const unsigned *IndexRegs = Regs;
1093 if (MemKind == LXAMem)
1096 if (parseAddressRegister(Reg1))
1101 if (HaveReg2 || isParsingHLASM())
1102 Index = Reg1.Num == 0 ? 0 : IndexRegs[Reg1.Num];
1104 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1108 if (parseAddressRegister(Reg2))
1110 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1116 if (parseAddressRegister(Reg2))
1118 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1121 if (HaveReg1 && HaveReg2)
1122 return Error(StartLoc,
"invalid use of indexed addressing");
1125 return Error(StartLoc,
"missing length in address");
1129 if (!HaveReg1 || Reg1.Group != RegGR)
1130 return Error(StartLoc,
"invalid operand for instruction");
1134 if (parseAddressRegister(Reg2))
1136 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1141 if (!HaveReg1 || Reg1.Group != RegV)
1142 return Error(StartLoc,
"vector index required in address");
1146 if (isParsingGNU() && !HaveReg2)
1147 return Error(Reg1.StartLoc,
"invalid use of vector addressing");
1150 if (parseAddressRegister(Reg2))
1152 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1159 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1160 Index,
Length, LengthReg,
1165ParseStatus SystemZAsmParser::parseDirective(AsmToken DirectiveID) {
1168 if (IDVal ==
".insn")
1169 return parseDirectiveInsn(DirectiveID.
getLoc());
1170 if (IDVal ==
".machine")
1171 return parseDirectiveMachine(DirectiveID.
getLoc());
1173 return parseGNUAttribute(DirectiveID.
getLoc());
1192 case MCK_BDAddr64Disp12:
1193 case MCK_BDAddr64Disp20:
1198 case MCK_BDXAddr64Disp12:
1199 case MCK_BDXAddr64Disp20:
1200 case MCK_BDRAddr64Disp12:
1201 case MCK_BDVAddr64Disp12:
1202 case MCK_LXAAddr64Disp20:
1208 case MCK_BDLAddr64Disp12Len4:
1209 case MCK_BDLAddr64Disp12Len8:
1223bool SystemZAsmParser::parseDirectiveInsn(SMLoc L) {
1224 MCAsmParser &Parser = getParser();
1230 return Error(ErrorLoc,
"expected instruction format");
1237 std::equal_range(std::begin(InsnMatchTable), std::end(InsnMatchTable),
1241 if (EntryRange.first == EntryRange.second)
1242 return Error(ErrorLoc,
"unrecognized format");
1246 const InsnMatchEntry *
Entry = EntryRange.first;
1249 unsigned NumMandatoryOperands =
1250 Entry->NumOperands -
Entry->NumOptionalOperands;
1253 for (
unsigned I = 0;
I <
Entry->NumOperands;
I++) {
1258 if (
I >= NumMandatoryOperands)
1261 return Error(StartLoc,
"too few operands to .insn directive");
1266 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1268 if (Kind == MCK_AnyReg)
1270 else if (Kind == MCK_VR128)
1272 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1274 else if (Kind == MCK_BDRAddr64Disp12)
1276 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1278 else if (Kind == MCK_BDVAddr64Disp12)
1280 else if (Kind == MCK_LXAAddr64Disp20)
1282 else if (Kind == MCK_PCRel32)
1284 else if (Kind == MCK_PCRel16)
1286 else if (Kind == MCK_PCRel12)
1288 else if (Kind == MCK_PCRel24)
1290 else if (Kind == MCK_BDLAddr64Disp12Len4 || Kind == MCK_BDLAddr64Disp12Len8)
1299 return Error(StartLoc,
"unexpected token in .insn directive");
1304 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1316 "too many operands to .insn directive");
1323 MCInst Inst = MCInstBuilder(
Entry->Opcode);
1326 MCParsedAsmOperand &Operand = *
Operands[
I];
1327 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1330 unsigned Res = validateOperandClass(Operand, Kind, *STI);
1331 if (Res != Match_Success)
1335 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1336 if (ZOperand.isReg())
1337 ZOperand.addRegOperands(Inst, 1);
1338 else if (ZOperand.isMem(BDMem))
1339 ZOperand.addBDAddrOperands(Inst, 2);
1340 else if (ZOperand.isMem(BDXMem))
1341 ZOperand.addBDXAddrOperands(Inst, 3);
1342 else if (ZOperand.isMem(BDRMem))
1343 ZOperand.addBDRAddrOperands(Inst, 3);
1344 else if (ZOperand.isMem(BDVMem))
1345 ZOperand.addBDVAddrOperands(Inst, 3);
1346 else if (ZOperand.isMem(BDLMem))
1347 ZOperand.addBDLAddrOperands(Inst, 3);
1348 else if (ZOperand.isMem(LXAMem))
1349 ZOperand.addLXAAddrOperands(Inst, 3);
1350 else if (ZOperand.isImm())
1351 ZOperand.addImmOperands(Inst, 1);
1368bool SystemZAsmParser::parseDirectiveMachine(SMLoc L) {
1369 MCAsmParser &Parser = getParser();
1372 return TokError(
"unexpected token in '.machine' directive");
1384 MachineStack.
push_back(getAvailableFeatures());
1385 }
else if (Id ==
"pop") {
1387 if (MachineStack.
empty())
1389 "pop without corresponding push in '.machine' directive");
1390 setAvailableFeatures(MachineStack.
back());
1395 MCSubtargetInfo &STI = copySTI();
1397 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1399 getTargetStreamer().emitMachine(Id);
1404bool SystemZAsmParser::parseGNUAttribute(SMLoc L) {
1406 int64_t IntegerValue;
1408 return Error(L,
"malformed .gnu_attribute directive");
1411 if (
Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))
1412 return Error(L,
"unrecognized .gnu_attribute tag/value pair.");
1419bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1420 SMLoc &EndLoc,
bool RequirePercent,
1421 bool RestoreOnFailure) {
1423 if (parseRegister(
Reg, RequirePercent, RestoreOnFailure))
1425 if (
Reg.Group == RegGR)
1427 else if (
Reg.Group == RegFP)
1429 else if (
Reg.Group == RegV)
1431 else if (
Reg.Group == RegAR)
1433 else if (
Reg.Group == RegCR)
1435 StartLoc =
Reg.StartLoc;
1436 EndLoc =
Reg.EndLoc;
1440bool SystemZAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1442 return ParseRegister(
Reg, StartLoc, EndLoc,
false,
1446ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1448 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
false,
1450 bool PendingErrors = getParser().hasPendingError();
1451 getParser().clearPendingErrors();
1459bool SystemZAsmParser::parseInstruction(ParseInstructionInfo &Info,
1460 StringRef Name, SMLoc NameLoc,
1467 Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
1472 if (parseOperand(
Operands, Name)) {
1483 "No space allowed between comma that separates operand entries");
1485 if (parseOperand(
Operands, Name)) {
1496 StringRef
Remark(getLexer().LexUntilEndOfStatement());
1508 getStreamer().AddComment(
Remark);
1512 SMLoc Loc = getLexer().getLoc();
1513 return Error(Loc,
"unexpected token in argument list");
1523 StringRef Mnemonic) {
1529 FeatureBitset AvailableFeatures = getAvailableFeatures();
1532 setAvailableFeatures(
All);
1533 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic);
1534 setAvailableFeatures(AvailableFeatures);
1550 if (parseRegister(
Reg,
true))
1552 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1561 bool HaveReg1, HaveReg2;
1564 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1569 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1570 && parseAddressRegister(Reg1))
1572 if (HaveReg2 && parseAddressRegister(Reg2))
1577 if (HaveReg1 || HaveReg2 ||
Length)
1578 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1580 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1584bool SystemZAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1588 bool MatchingInlineAsm) {
1590 unsigned MatchResult;
1592 unsigned Dialect = getMAIAssemblerDialect();
1594 FeatureBitset MissingFeatures;
1595 MatchResult = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
1596 MatchingInlineAsm, Dialect);
1597 switch (MatchResult) {
1600 Out.emitInstruction(Inst, getSTI());
1603 case Match_MissingFeature: {
1604 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1607 std::string
Msg =
"instruction requires:";
1608 for (
unsigned I = 0,
E = MissingFeatures.
size();
I !=
E; ++
I) {
1609 if (MissingFeatures[
I]) {
1617 case Match_InvalidOperand: {
1618 SMLoc ErrorLoc = IDLoc;
1619 if (ErrorInfo != ~0ULL) {
1621 return Error(IDLoc,
"too few operands for instruction");
1623 ErrorLoc = ((SystemZOperand &)*
Operands[ErrorInfo]).getStartLoc();
1624 if (ErrorLoc == SMLoc())
1627 return Error(ErrorLoc,
"invalid operand for instruction");
1630 case Match_MnemonicFail: {
1631 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1632 std::string Suggestion = SystemZMnemonicSpellCheck(
1634 return Error(IDLoc,
"invalid instruction" + Suggestion,
1635 ((SystemZOperand &)*
Operands[0]).getLocRange());
1643 int64_t MinVal, int64_t MaxVal,
1646 MCStreamer &
Out = getStreamer();
1649 if (getParser().parseExpression(Expr))
1652 auto IsOutOfRangeConstant = [&](
const MCExpr *
E,
bool Negate) ->
bool {
1654 int64_t
Value =
CE->getValue();
1666 if (isParsingHLASM())
1667 return Error(StartLoc,
"Expected PC-relative expression");
1668 if (IsOutOfRangeConstant(CE,
false))
1669 return Error(StartLoc,
"offset out of range");
1670 int64_t
Value =
CE->getValue();
1680 if (IsOutOfRangeConstant(BE->getLHS(),
false) ||
1681 IsOutOfRangeConstant(BE->getRHS(),
1683 return Error(StartLoc,
"offset out of range");
1686 const MCExpr *Sym =
nullptr;
1695 if (Name ==
"tls_gdcall")
1697 else if (Name ==
"tls_ldcall")
1720 Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1723 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1728bool SystemZAsmParser::isLabel(AsmToken &Token) {
1744 SMLoc Loc = Token.
getLoc();
1747 if (!RawLabel.
size())
1748 return !
Error(Loc,
"HLASM Label cannot be empty");
1751 if (RawLabel.
size() > 63)
1752 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1755 if (!isHLASMAlpha(RawLabel[0]))
1756 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1757 "character or the underscore character");
1762 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1763 if (!isHLASMAlnum(RawLabel[
I]))
1764 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file defines the SmallVector class.
static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue, bool AllowSymbol=false)
static void addDefaultOperand(MCInst &Inst, MatchClassKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmParser()
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.
Instances of this class represent a single low-level machine instruction.
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.
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.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
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.
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)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSystemZTarget()
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...