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 isX8Imm()
const {
return isS8Imm() || isU8Imm(); }
401 bool isU12Imm()
const {
return isImm(0, 4095); }
402 bool isU16Imm()
const {
return isImm(0, 65535); }
403 bool isS16Imm()
const {
return isImm(-32768, 32767); }
404 bool isX16Imm()
const {
return isS16Imm() || isU16Imm(); }
405 bool isU32Imm()
const {
return isImm(0, (1LL << 32) - 1); }
406 bool isS32Imm()
const {
return isImm(-(1LL << 31), (1LL << 31) - 1); }
407 bool isX32Imm()
const {
return isS32Imm() || isU32Imm(); }
408 bool isU48Imm()
const {
return isImm(0, (1LL << 48) - 1); }
412#define GET_ASSEMBLER_HEADER
413#include "SystemZGenAsmMatcher.inc"
433 SMLoc StartLoc, EndLoc;
436 SystemZTargetStreamer &getTargetStreamer() {
437 assert(getParser().getStreamer().getTargetStreamer() &&
438 "do not have a target streamer");
439 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
440 return static_cast<SystemZTargetStreamer &
>(TS);
443 bool parseRegister(Register &
Reg,
bool RequirePercent,
444 bool RestoreOnFailure =
false);
446 bool parseIntegerRegister(Register &
Reg, RegisterGroup Group);
452 bool parseAddress(
bool &HaveReg1, Register &Reg1,
bool &HaveReg2,
453 Register &Reg2,
const MCExpr *&Disp,
const MCExpr *&
Length,
454 bool HasLength =
false,
bool HasVectorIndex =
false);
455 bool parseAddressRegister(Register &
Reg);
457 bool parseDirectiveInsn(SMLoc L);
458 bool parseDirectiveMachine(SMLoc L);
459 bool parseGNUAttribute(SMLoc L);
462 RegisterKind RegKind);
465 int64_t MaxVal,
bool AllowTLS);
486 unsigned getMAIAssemblerDialect() {
487 return Parser.getContext().getAsmInfo().getAssemblerDialect();
492 inline bool isHLASMAlpha(
char C) {
497 inline bool isHLASMAlnum(
char C) {
return isHLASMAlpha(
C) ||
isDigit(
C); }
500 inline bool isParsingHLASM() {
return getMAIAssemblerDialect() ==
AD_HLASM; }
503 inline bool isParsingGNU() {
return getMAIAssemblerDialect() ==
AD_GNU; }
506 SystemZAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
507 const MCInstrInfo &MII)
508 : MCTargetAsmParser(sti, MII), Parser(parser) {
515 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
519 ParseStatus parseDirective(AsmToken DirectiveID)
override;
520 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
521 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
522 bool RequirePercent,
bool RestoreOnFailure);
523 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
524 SMLoc &EndLoc)
override;
525 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
527 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
530 bool MatchingInlineAsm)
override;
531 bool isLabel(AsmToken &Token)
override;
535 return parseRegister(
Operands, GR32Reg);
538 return parseRegister(
Operands, GRH32Reg);
544 return parseRegister(
Operands, GR64Reg);
547 return parseRegister(
Operands, GR128Reg);
551 return parseRegister(
Operands, GR32Reg);
555 return parseRegister(
Operands, GR64Reg);
561 return parseRegister(
Operands, FP16Reg);
564 return parseRegister(
Operands, FP32Reg);
567 return parseRegister(
Operands, FP64Reg);
570 return parseRegister(
Operands, FP128Reg);
573 return parseRegister(
Operands, VR16Reg);
576 return parseRegister(
Operands, VR32Reg);
579 return parseRegister(
Operands, VR64Reg);
585 return parseRegister(
Operands, VR128Reg);
588 return parseRegister(
Operands, AR32Reg);
591 return parseRegister(
Operands, CR64Reg);
597 return parseAddress(
Operands, BDMem, GR32Reg);
600 return parseAddress(
Operands, BDMem, GR64Reg);
603 return parseAddress(
Operands, BDXMem, GR64Reg);
606 return parseAddress(
Operands, BDLMem, GR64Reg);
609 return parseAddress(
Operands, BDRMem, GR64Reg);
612 return parseAddress(
Operands, BDVMem, GR64Reg);
615 return parseAddress(
Operands, LXAMem, GR64Reg);
618 return parsePCRel(
Operands, -(1LL << 12), (1LL << 12) - 1,
false);
621 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
false);
624 return parsePCRel(
Operands, -(1LL << 24), (1LL << 24) - 1,
false);
627 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
false);
630 return parsePCRel(
Operands, -(1LL << 16), (1LL << 16) - 1,
true);
633 return parsePCRel(
Operands, -(1LL << 32), (1LL << 32) - 1,
true);
639#define GET_REGISTER_MATCHER
640#define GET_SUBTARGET_FEATURE_NAME
641#define GET_MATCHER_IMPLEMENTATION
642#define GET_MNEMONIC_SPELL_CHECKER
643#include "SystemZGenAsmMatcher.inc"
649#include "SystemZGenInsnMatchTable.inc"
668 if (getImmTLS().Sym) {
674 const MemOp &
Op = getMem();
679 if (
Op.MemKind == BDLMem) {
682 }
else if (
Op.MemKind == BDRMem)
697bool SystemZAsmParser::parseRegister(
Register &
Reg,
bool RequirePercent,
698 bool RestoreOnFailure) {
699 const AsmToken &PercentTok = Parser.
getTok();
705 return Error(PercentTok.
getLoc(),
"register expected");
713 if (RestoreOnFailure && HasPercent)
714 getLexer().UnLex(PercentTok);
716 HasPercent ?
"invalid register" :
"register expected");
721 if (
Name.size() < 2) {
722 if (RestoreOnFailure && HasPercent)
723 getLexer().UnLex(PercentTok);
724 return Error(
Reg.StartLoc,
"invalid register");
729 if (
Name.substr(1).getAsInteger(10,
Reg.Num)) {
730 if (RestoreOnFailure && HasPercent)
731 getLexer().UnLex(PercentTok);
732 return Error(
Reg.StartLoc,
"invalid register");
736 if (Prefix ==
'r' &&
Reg.Num < 16)
738 else if (Prefix ==
'f' &&
Reg.Num < 16)
740 else if (Prefix ==
'v' &&
Reg.Num < 32)
742 else if (Prefix ==
'a' &&
Reg.Num < 16)
744 else if (Prefix ==
'c' &&
Reg.Num < 16)
747 if (RestoreOnFailure && HasPercent)
748 getLexer().UnLex(PercentTok);
749 return Error(
Reg.StartLoc,
"invalid register");
791 if (parseRegister(
Reg,
true))
801 if (Group !=
Reg.Group)
802 return Error(
Reg.StartLoc,
"invalid operand for instruction");
805 if (
Reg.Group != RegV &&
Reg.Group != RegFP)
806 return Error(
Reg.StartLoc,
"invalid operand for instruction");
810 if (parseIntegerRegister(
Reg, Group))
819 const unsigned *Regs;
837 if (Regs[
Reg.Num] == 0)
838 return Error(
Reg.StartLoc,
"invalid register pair");
841 SystemZOperand::createReg(Kind, Regs[
Reg.Num],
Reg.StartLoc,
Reg.EndLoc));
856 int64_t
Value =
CE->getValue();
858 return Error(StartLoc,
"invalid register");
867 if (isParsingHLASM())
871 if (parseRegister(
Reg,
true))
875 return Error(StartLoc,
"invalid register");
880 if (
Reg.Group == RegGR) {
884 else if (
Reg.Group == RegFP) {
888 else if (
Reg.Group == RegV) {
892 else if (
Reg.Group == RegAR) {
896 else if (
Reg.Group == RegCR) {
904 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
905 Reg.StartLoc,
Reg.EndLoc));
910bool SystemZAsmParser::parseIntegerRegister(
Register &
Reg,
911 RegisterGroup Group) {
922 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
923 int64_t
Value =
CE->getValue();
939bool SystemZAsmParser::parseAddress(
bool &HaveReg1,
Register &Reg1,
941 const MCExpr *&Disp,
const MCExpr *&
Length,
942 bool HasLength,
bool HasVectorIndex) {
944 if (getParser().parseExpression(Disp))
970 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
978 if (parseRegister(Reg1,
true))
989 if (getParser().parseExpression(
Length))
997 if (parseIntegerRegister(Reg1, RegGroup))
1004 if (getParser().parseExpression(
Length))
1015 if (parseIntegerRegister(Reg2, RegGR))
1017 }
else if (isParsingGNU()) {
1019 if (parseRegister(Reg2,
true))
1025 Reg2.StartLoc = Reg2.EndLoc = Parser.
getTok().
getLoc();
1040SystemZAsmParser::parseAddressRegister(
Register &
Reg) {
1041 if (
Reg.Group == RegV) {
1042 Error(
Reg.StartLoc,
"invalid use of vector addressing");
1045 if (
Reg.Group != RegGR) {
1046 Error(
Reg.StartLoc,
"invalid address register");
1056 RegisterKind RegKind) {
1058 unsigned Base = 0,
Index = 0, LengthReg = 0;
1060 bool HaveReg1, HaveReg2;
1064 bool HasLength = (MemKind == BDLMem) ?
true :
false;
1065 bool HasVectorIndex = (MemKind == BDVMem) ?
true :
false;
1066 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp,
Length, HasLength,
1070 const unsigned *Regs;
1081 if (parseAddressRegister(Reg1))
1083 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1087 return Error(StartLoc,
"invalid use of indexed addressing");
1093 const unsigned *IndexRegs = Regs;
1094 if (MemKind == LXAMem)
1097 if (parseAddressRegister(Reg1))
1102 if (HaveReg2 || isParsingHLASM())
1103 Index = Reg1.Num == 0 ? 0 : IndexRegs[Reg1.Num];
1105 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];
1109 if (parseAddressRegister(Reg2))
1111 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1117 if (parseAddressRegister(Reg2))
1119 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1122 if (HaveReg1 && HaveReg2)
1123 return Error(StartLoc,
"invalid use of indexed addressing");
1126 return Error(StartLoc,
"missing length in address");
1130 if (!HaveReg1 || Reg1.Group != RegGR)
1131 return Error(StartLoc,
"invalid operand for instruction");
1135 if (parseAddressRegister(Reg2))
1137 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1142 if (!HaveReg1 || Reg1.Group != RegV)
1143 return Error(StartLoc,
"vector index required in address");
1147 if (isParsingGNU() && !HaveReg2)
1148 return Error(Reg1.StartLoc,
"invalid use of vector addressing");
1151 if (parseAddressRegister(Reg2))
1153 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1160 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind,
Base, Disp,
1161 Index,
Length, LengthReg,
1166ParseStatus SystemZAsmParser::parseDirective(AsmToken DirectiveID) {
1169 if (IDVal ==
".insn")
1170 return parseDirectiveInsn(DirectiveID.
getLoc());
1171 if (IDVal ==
".machine")
1172 return parseDirectiveMachine(DirectiveID.
getLoc());
1174 return parseGNUAttribute(DirectiveID.
getLoc());
1193 case MCK_BDAddr64Disp12:
1194 case MCK_BDAddr64Disp20:
1199 case MCK_BDXAddr64Disp12:
1200 case MCK_BDXAddr64Disp20:
1201 case MCK_BDRAddr64Disp12:
1202 case MCK_BDVAddr64Disp12:
1203 case MCK_LXAAddr64Disp20:
1209 case MCK_BDLAddr64Disp12Len4:
1210 case MCK_BDLAddr64Disp12Len8:
1224bool SystemZAsmParser::parseDirectiveInsn(SMLoc L) {
1225 MCAsmParser &Parser = getParser();
1231 return Error(ErrorLoc,
"expected instruction format");
1238 std::equal_range(std::begin(InsnMatchTable), std::end(InsnMatchTable),
1242 if (EntryRange.first == EntryRange.second)
1243 return Error(ErrorLoc,
"unrecognized format");
1247 const InsnMatchEntry *
Entry = EntryRange.first;
1250 unsigned NumMandatoryOperands =
1251 Entry->NumOperands -
Entry->NumOptionalOperands;
1254 for (
unsigned I = 0;
I <
Entry->NumOperands;
I++) {
1259 if (
I >= NumMandatoryOperands)
1262 return Error(StartLoc,
"too few operands to .insn directive");
1267 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1269 if (Kind == MCK_AnyReg)
1271 else if (Kind == MCK_VR128)
1273 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1275 else if (Kind == MCK_BDRAddr64Disp12)
1277 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1279 else if (Kind == MCK_BDVAddr64Disp12)
1281 else if (Kind == MCK_LXAAddr64Disp20)
1283 else if (Kind == MCK_PCRel32)
1285 else if (Kind == MCK_PCRel16)
1287 else if (Kind == MCK_PCRel12)
1289 else if (Kind == MCK_PCRel24)
1291 else if (Kind == MCK_BDLAddr64Disp12Len4 || Kind == MCK_BDLAddr64Disp12Len8)
1300 return Error(StartLoc,
"unexpected token in .insn directive");
1305 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1317 "too many operands to .insn directive");
1324 MCInst Inst = MCInstBuilder(
Entry->Opcode);
1327 MCParsedAsmOperand &Operand = *
Operands[
I];
1328 MatchClassKind
Kind =
Entry->OperandKinds[
I];
1331 unsigned Res = validateOperandClass(Operand, Kind, *STI);
1332 if (Res != Match_Success)
1336 SystemZOperand &ZOperand =
static_cast<SystemZOperand &
>(Operand);
1337 if (ZOperand.isReg())
1338 ZOperand.addRegOperands(Inst, 1);
1339 else if (ZOperand.isMem(BDMem))
1340 ZOperand.addBDAddrOperands(Inst, 2);
1341 else if (ZOperand.isMem(BDXMem))
1342 ZOperand.addBDXAddrOperands(Inst, 3);
1343 else if (ZOperand.isMem(BDRMem))
1344 ZOperand.addBDRAddrOperands(Inst, 3);
1345 else if (ZOperand.isMem(BDVMem))
1346 ZOperand.addBDVAddrOperands(Inst, 3);
1347 else if (ZOperand.isMem(BDLMem))
1348 ZOperand.addBDLAddrOperands(Inst, 3);
1349 else if (ZOperand.isMem(LXAMem))
1350 ZOperand.addLXAAddrOperands(Inst, 3);
1351 else if (ZOperand.isImm())
1352 ZOperand.addImmOperands(Inst, 1);
1369bool SystemZAsmParser::parseDirectiveMachine(SMLoc L) {
1370 MCAsmParser &Parser = getParser();
1373 return TokError(
"unexpected token in '.machine' directive");
1385 MachineStack.
push_back(getAvailableFeatures());
1386 }
else if (Id ==
"pop") {
1388 if (MachineStack.
empty())
1390 "pop without corresponding push in '.machine' directive");
1391 setAvailableFeatures(MachineStack.
back());
1396 MCSubtargetInfo &STI = copySTI();
1398 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
1400 getTargetStreamer().emitMachine(Id);
1405bool SystemZAsmParser::parseGNUAttribute(SMLoc L) {
1407 int64_t IntegerValue;
1409 return Error(L,
"malformed .gnu_attribute directive");
1412 if (
Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))
1413 return Error(L,
"unrecognized .gnu_attribute tag/value pair.");
1420bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1421 SMLoc &EndLoc,
bool RequirePercent,
1422 bool RestoreOnFailure) {
1424 if (parseRegister(
Reg, RequirePercent, RestoreOnFailure))
1426 if (
Reg.Group == RegGR)
1428 else if (
Reg.Group == RegFP)
1430 else if (
Reg.Group == RegV)
1432 else if (
Reg.Group == RegAR)
1434 else if (
Reg.Group == RegCR)
1436 StartLoc =
Reg.StartLoc;
1437 EndLoc =
Reg.EndLoc;
1441bool SystemZAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1443 return ParseRegister(
Reg, StartLoc, EndLoc,
false,
1447ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1449 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
false,
1451 bool PendingErrors = getParser().hasPendingError();
1452 getParser().clearPendingErrors();
1460bool SystemZAsmParser::parseInstruction(ParseInstructionInfo &Info,
1461 StringRef Name, SMLoc NameLoc,
1468 Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
1473 if (parseOperand(
Operands, Name)) {
1484 "No space allowed between comma that separates operand entries");
1486 if (parseOperand(
Operands, Name)) {
1497 StringRef
Remark(getLexer().LexUntilEndOfStatement());
1509 getStreamer().AddComment(
Remark);
1513 SMLoc Loc = getLexer().getLoc();
1514 return Error(Loc,
"unexpected token in argument list");
1524 StringRef Mnemonic) {
1530 FeatureBitset AvailableFeatures = getAvailableFeatures();
1533 setAvailableFeatures(
All);
1534 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic);
1535 setAvailableFeatures(AvailableFeatures);
1551 if (parseRegister(
Reg,
true))
1553 Operands.push_back(SystemZOperand::createInvalid(
Reg.StartLoc,
Reg.EndLoc));
1562 bool HaveReg1, HaveReg2;
1565 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr,
Length,
1570 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1571 && parseAddressRegister(Reg1))
1573 if (HaveReg2 && parseAddressRegister(Reg2))
1578 if (HaveReg1 || HaveReg2 ||
Length)
1579 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1581 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1585bool SystemZAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1589 bool MatchingInlineAsm) {
1591 unsigned MatchResult;
1593 unsigned Dialect = getMAIAssemblerDialect();
1595 FeatureBitset MissingFeatures;
1596 MatchResult = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
1597 MatchingInlineAsm, Dialect);
1598 switch (MatchResult) {
1601 Out.emitInstruction(Inst, getSTI());
1604 case Match_MissingFeature: {
1605 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
1608 std::string
Msg =
"instruction requires:";
1609 for (
unsigned I = 0,
E = MissingFeatures.
size();
I !=
E; ++
I) {
1610 if (MissingFeatures[
I]) {
1618 case Match_InvalidOperand: {
1619 SMLoc ErrorLoc = IDLoc;
1620 if (ErrorInfo != ~0ULL) {
1622 return Error(IDLoc,
"too few operands for instruction");
1624 ErrorLoc = ((SystemZOperand &)*
Operands[ErrorInfo]).getStartLoc();
1625 if (ErrorLoc == SMLoc())
1628 return Error(ErrorLoc,
"invalid operand for instruction");
1631 case Match_MnemonicFail: {
1632 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1633 std::string Suggestion = SystemZMnemonicSpellCheck(
1635 return Error(IDLoc,
"invalid instruction" + Suggestion,
1636 ((SystemZOperand &)*
Operands[0]).getLocRange());
1644 int64_t MinVal, int64_t MaxVal,
1647 MCStreamer &
Out = getStreamer();
1650 if (getParser().parseExpression(Expr))
1653 auto IsOutOfRangeConstant = [&](
const MCExpr *
E,
bool Negate) ->
bool {
1655 int64_t
Value =
CE->getValue();
1667 if (isParsingHLASM())
1668 return Error(StartLoc,
"Expected PC-relative expression");
1669 if (IsOutOfRangeConstant(CE,
false))
1670 return Error(StartLoc,
"offset out of range");
1671 int64_t
Value =
CE->getValue();
1681 if (IsOutOfRangeConstant(BE->getLHS(),
false) ||
1682 IsOutOfRangeConstant(BE->getRHS(),
1684 return Error(StartLoc,
"offset out of range");
1687 const MCExpr *Sym =
nullptr;
1696 if (Name ==
"tls_gdcall")
1698 else if (Name ==
"tls_ldcall")
1721 Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1724 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1729bool SystemZAsmParser::isLabel(AsmToken &Token) {
1745 SMLoc Loc = Token.
getLoc();
1748 if (!RawLabel.
size())
1749 return !
Error(Loc,
"HLASM Label cannot be empty");
1752 if (RawLabel.
size() > 63)
1753 return !
Error(Loc,
"Maximum length for HLASM Label is 63 characters");
1756 if (!isHLASMAlpha(RawLabel[0]))
1757 return !
Error(Loc,
"HLASM Label has to start with an alphabetic "
1758 "character or the underscore character");
1763 for (
unsigned I = 1;
I < RawLabel.
size(); ++
I)
1764 if (!isHLASMAlnum(RawLabel[
I]))
1765 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,...