63 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
68#define GET_ASSEMBLER_HEADER
69#include "SparcGenAsmMatcher.inc"
77 bool MatchingInlineAsm)
override;
80 SMLoc &EndLoc)
override;
86 unsigned Kind)
override;
97 template <TailRelocKind Kind>
106 ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand);
117 bool isPossibleExpression(
const AsmToken &Token);
120 MatchResultTy mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
125 bool matchSparcAsmModifiers(
const MCExpr *&EVal,
SMLoc &EndLoc);
146 MRI(*Parser.getContext().getRegisterInfo()) {
163 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
164 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
165 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
166 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
167 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
168 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
169 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
170 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
173 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
174 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
175 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
176 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
177 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
178 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
179 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
180 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
183 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
184 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
185 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
186 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
189 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
190 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
191 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
192 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
195 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
196 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
197 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
198 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
230 SMLoc StartLoc, EndLoc;
262 SparcOperand(KindTy K) :
Kind(
K) {}
264 bool isToken()
const override {
return Kind == k_Token; }
265 bool isReg()
const override {
return Kind == k_Register; }
266 bool isImm()
const override {
return Kind == k_Immediate; }
267 bool isMem()
const override {
return isMEMrr() || isMEMri(); }
268 bool isMEMrr()
const {
return Kind == k_MemoryReg; }
269 bool isMEMri()
const {
return Kind == k_MemoryImm; }
270 bool isMembarTag()
const {
return Kind == k_Immediate; }
271 bool isASITag()
const {
return Kind == k_ASITag; }
272 bool isPrefetchTag()
const {
return Kind == k_PrefetchTag; }
273 bool isTailRelocSym()
const {
return Kind == k_TailRelocSym; }
275 bool isCallTarget()
const {
280 return CE->getValue() % 4 == 0;
285 bool isShiftAmtImm5()
const {
290 return isUInt<5>(
CE->getValue());
295 bool isShiftAmtImm6()
const {
300 return isUInt<6>(
CE->getValue());
306 return (Kind == k_Register &&
Reg.Kind == rk_IntReg);
309 bool isFloatReg()
const {
310 return (Kind == k_Register &&
Reg.Kind == rk_FloatReg);
313 bool isFloatOrDoubleReg()
const {
314 return (Kind == k_Register && (
Reg.Kind == rk_FloatReg
315 ||
Reg.Kind == rk_DoubleReg));
318 bool isCoprocReg()
const {
319 return (Kind == k_Register &&
Reg.Kind == rk_CoprocReg);
323 assert(Kind == k_Token &&
"Invalid access!");
328 assert((Kind == k_Register) &&
"Invalid access!");
333 assert((Kind == k_Immediate) &&
"Invalid access!");
337 unsigned getMemBase()
const {
338 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) &&
"Invalid access!");
342 unsigned getMemOffsetReg()
const {
343 assert((Kind == k_MemoryReg) &&
"Invalid access!");
344 return Mem.OffsetReg;
347 const MCExpr *getMemOff()
const {
348 assert((Kind == k_MemoryImm) &&
"Invalid access!");
352 unsigned getASITag()
const {
353 assert((Kind == k_ASITag) &&
"Invalid access!");
357 unsigned getPrefetchTag()
const {
358 assert((Kind == k_PrefetchTag) &&
"Invalid access!");
362 const MCExpr *getTailRelocSym()
const {
363 assert((Kind == k_TailRelocSym) &&
"Invalid access!");
378 case k_Token:
OS <<
"Token: " << getToken() <<
"\n";
break;
379 case k_Register:
OS <<
"Reg: #" <<
getReg() <<
"\n";
break;
380 case k_Immediate:
OS <<
"Imm: " <<
getImm() <<
"\n";
break;
381 case k_MemoryReg:
OS <<
"Mem: " << getMemBase() <<
"+"
382 << getMemOffsetReg() <<
"\n";
break;
383 case k_MemoryImm:
assert(getMemOff() !=
nullptr);
384 OS <<
"Mem: " << getMemBase() <<
"+";
389 OS <<
"ASI tag: " << getASITag() <<
"\n";
392 OS <<
"Prefetch tag: " << getPrefetchTag() <<
"\n";
395 OS <<
"TailReloc: " << getTailRelocSym() <<
"\n";
400 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
401 assert(
N == 1 &&
"Invalid number of operands!");
405 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
406 assert(
N == 1 &&
"Invalid number of operands!");
411 void addShiftAmtImm5Operands(
MCInst &Inst,
unsigned N)
const {
412 assert(
N == 1 &&
"Invalid number of operands!");
415 void addShiftAmtImm6Operands(
MCInst &Inst,
unsigned N)
const {
416 assert(
N == 1 &&
"Invalid number of operands!");
424 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
430 void addMEMrrOperands(
MCInst &Inst,
unsigned N)
const {
431 assert(
N == 2 &&
"Invalid number of operands!");
435 assert(getMemOffsetReg() != 0 &&
"Invalid offset");
439 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
440 assert(
N == 2 &&
"Invalid number of operands!");
444 const MCExpr *Expr = getMemOff();
448 void addASITagOperands(
MCInst &Inst,
unsigned N)
const {
449 assert(
N == 1 &&
"Invalid number of operands!");
453 void addPrefetchTagOperands(
MCInst &Inst,
unsigned N)
const {
454 assert(
N == 1 &&
"Invalid number of operands!");
458 void addMembarTagOperands(
MCInst &Inst,
unsigned N)
const {
459 assert(
N == 1 &&
"Invalid number of operands!");
465 assert(
N == 1 &&
"Invalid number of operands!");
469 void addTailRelocSymOperands(
MCInst &Inst,
unsigned N)
const {
470 assert(
N == 1 &&
"Invalid number of operands!");
471 addExpr(Inst, getTailRelocSym());
474 static std::unique_ptr<SparcOperand> CreateToken(
StringRef Str,
SMLoc S) {
475 auto Op = std::make_unique<SparcOperand>(k_Token);
476 Op->Tok.Data = Str.data();
477 Op->Tok.Length = Str.size();
483 static std::unique_ptr<SparcOperand> CreateReg(
unsigned RegNum,
unsigned Kind,
485 auto Op = std::make_unique<SparcOperand>(k_Register);
486 Op->Reg.RegNum = RegNum;
487 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
493 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
495 auto Op = std::make_unique<SparcOperand>(k_Immediate);
502 static std::unique_ptr<SparcOperand> CreateASITag(
unsigned Val,
SMLoc S,
504 auto Op = std::make_unique<SparcOperand>(k_ASITag);
511 static std::unique_ptr<SparcOperand> CreatePrefetchTag(
unsigned Val,
SMLoc S,
513 auto Op = std::make_unique<SparcOperand>(k_PrefetchTag);
520 static std::unique_ptr<SparcOperand> CreateTailRelocSym(
const MCExpr *Val,
522 auto Op = std::make_unique<SparcOperand>(k_TailRelocSym);
529 static bool MorphToIntPairReg(SparcOperand &
Op) {
532 unsigned regIdx = 32;
533 if (
Reg >= Sparc::G0 &&
Reg <= Sparc::G7)
534 regIdx =
Reg - Sparc::G0;
535 else if (
Reg >= Sparc::O0 &&
Reg <= Sparc::O7)
536 regIdx =
Reg - Sparc::O0 + 8;
537 else if (
Reg >= Sparc::L0 &&
Reg <= Sparc::L7)
538 regIdx =
Reg - Sparc::L0 + 16;
539 else if (
Reg >= Sparc::I0 &&
Reg <= Sparc::I7)
540 regIdx =
Reg - Sparc::I0 + 24;
541 if (regIdx % 2 || regIdx > 31)
544 Op.Reg.Kind = rk_IntPairReg;
548 static bool MorphToDoubleReg(SparcOperand &
Op) {
551 unsigned regIdx =
Reg - Sparc::F0;
552 if (regIdx % 2 || regIdx > 31)
555 Op.Reg.Kind = rk_DoubleReg;
559 static bool MorphToQuadReg(SparcOperand &
Op) {
562 switch (
Op.Reg.Kind) {
565 regIdx =
Reg - Sparc::F0;
566 if (regIdx % 4 || regIdx > 31)
571 regIdx =
Reg - Sparc::D0;
572 if (regIdx % 2 || regIdx > 31)
578 Op.Reg.Kind = rk_QuadReg;
582 static bool MorphToCoprocPairReg(SparcOperand &
Op) {
584 assert(
Op.Reg.Kind == rk_CoprocReg);
585 unsigned regIdx = 32;
586 if (
Reg >= Sparc::C0 &&
Reg <= Sparc::C31)
587 regIdx =
Reg - Sparc::C0;
588 if (regIdx % 2 || regIdx > 31)
591 Op.Reg.Kind = rk_CoprocPairReg;
595 static std::unique_ptr<SparcOperand>
596 MorphToMEMrr(
unsigned Base, std::unique_ptr<SparcOperand>
Op) {
598 Op->Kind = k_MemoryReg;
600 Op->Mem.OffsetReg = offsetReg;
601 Op->Mem.Off =
nullptr;
605 static std::unique_ptr<SparcOperand>
607 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
609 Op->Mem.OffsetReg = Sparc::G0;
610 Op->Mem.Off =
nullptr;
616 static std::unique_ptr<SparcOperand>
617 MorphToMEMri(
unsigned Base, std::unique_ptr<SparcOperand>
Op) {
619 Op->Kind = k_MemoryImm;
621 Op->Mem.OffsetReg = 0;
629#define GET_MATCHER_IMPLEMENTATION
630#define GET_REGISTER_MATCHER
631#define GET_MNEMONIC_SPELL_CHECKER
632#include "SparcGenAsmMatcher.inc"
636SparcAsmParser::MatchResultTy
637SparcAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
642 const MatchEntry *Start, *
End;
647 Start = std::begin(MatchTable0);
648 End = std::end(MatchTable0);
653 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
655 if (MnemonicRange.first == MnemonicRange.second)
656 return Match_MnemonicFail;
658 for (
const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
661 FeatureBitsets[it->RequiredFeaturesIdx];
662 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
663 return Match_Success;
665 return Match_MissingFeature;
668bool SparcAsmParser::expandSET(
MCInst &Inst,
SMLoc IDLoc,
677 int64_t RawImmValue = IsImm ? MCValOp.
getImm() : 0;
680 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
682 "set: argument must be between -2147483648 and 4294967295");
687 int32_t ImmValue = RawImmValue;
691 bool IsEffectivelyImm13 =
692 IsImm && ((
is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
704 if (!IsEffectivelyImm13) {
706 const MCExpr *Expr = adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr);
725 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
728 if (IsEffectivelyImm13)
731 Expr = adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
742bool SparcAsmParser::expandSETSW(
MCInst &Inst,
SMLoc IDLoc,
751 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
755 bool IsSmallImm = IsImm && isInt<13>(ImmValue);
756 bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);
760 if (!isInt<32>(ImmValue)) {
762 "set: argument must be between -2147483648 and 2147483647");
771 .
addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
777 if (!NoLowBitsImm || IsSmallImm) {
779 IsSmallImm ? ValExpr : adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
793 if (!IsImm || ImmValue < 0) {
804bool SparcAsmParser::expandSETX(
MCInst &Inst,
SMLoc IDLoc,
813 bool IsImm = MCValOp.
isImm();
814 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
820 if (IsImm && isInt<13>(ImmValue)) {
835 .
addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
841 .
addExpr(adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr)));
845 if (IsImm && isUInt<32>(ImmValue))
855 ValExpr, ELF::R_SPARC_HH22, getContext())));
861 ValExpr, ELF::R_SPARC_HM10, getContext())));
876bool SparcAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
880 bool MatchingInlineAsm) {
885 switch (MatchResult) {
886 case Match_Success: {
893 if (expandSET(Inst, IDLoc, Instructions))
897 if (expandSETSW(Inst, IDLoc, Instructions))
901 if (expandSETX(Inst, IDLoc, Instructions))
906 for (
const MCInst &
I : Instructions) {
912 case Match_MissingFeature:
914 "instruction requires a CPU feature not currently enabled");
916 case Match_InvalidOperand: {
917 SMLoc ErrorLoc = IDLoc;
920 return Error(IDLoc,
"too few operands for instruction");
923 if (ErrorLoc ==
SMLoc())
927 return Error(ErrorLoc,
"invalid operand for instruction");
929 case Match_MnemonicFail:
930 return Error(IDLoc,
"invalid instruction mnemonic");
937 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
938 return Error(StartLoc,
"invalid register name");
947 Reg = Sparc::NoRegister;
951 unsigned RegKind = SparcOperand::rk_None;
952 Reg = matchRegisterName(Tok, RegKind);
958 getLexer().UnLex(Tok);
974 MatchResultTy MS = mnemonicIsValid(
Name, 0);
978 case Match_MissingFeature:
979 return Error(NameLoc,
980 "instruction requires a CPU feature not currently enabled");
981 case Match_MnemonicFail:
982 return Error(NameLoc,
983 "invalid instruction mnemonic" +
984 SparcMnemonicSpellCheck(
Name, getAvailableFeatures(), 0));
990 Operands.push_back(SparcOperand::CreateToken(
Name, NameLoc));
998 if (!parseBranchModifiers(
Operands).isSuccess()) {
999 SMLoc Loc = getLexer().getLoc();
1000 return Error(Loc,
"unexpected token");
1004 SMLoc Loc = getLexer().getLoc();
1005 return Error(Loc,
"unexpected token");
1016 SMLoc Loc = getLexer().getLoc();
1017 return Error(Loc,
"unexpected token");
1022 SMLoc Loc = getLexer().getLoc();
1023 return Error(Loc,
"unexpected token");
1032 if (IDVal ==
".register") {
1037 if (IDVal ==
".proc") {
1051 std::unique_ptr<SparcOperand>
LHS;
1052 if (!parseSparcAsmOperand(LHS).isSuccess())
1057 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
1061 if (!
LHS->isIntReg())
1062 return Error(
LHS->getStartLoc(),
"invalid register kind for this operand");
1064 AsmToken Tok = getLexer().getTok();
1070 std::unique_ptr<SparcOperand>
RHS;
1071 if (!parseSparcAsmOperand(RHS).isSuccess())
1074 if (
RHS->isReg() && !
RHS->isIntReg())
1076 "invalid register kind for this operand");
1080 ? SparcOperand::MorphToMEMri(
LHS->getReg(), std::move(RHS))
1086 Operands.push_back(SparcOperand::CreateMEMr(
LHS->getReg(), S, E));
1090template <
unsigned N>
1100 if (getParser().parseExpression(Expr))
1105 return Error(S,
"constant expression expected");
1107 if (!isUInt<N>(
CE->getValue()))
1108 return Error(S,
"immediate shift value out of range");
1110 Operands.push_back(SparcOperand::CreateImm(Expr, S, E));
1114template <SparcAsmParser::TailRelocKind Kind>
1119 auto MatchesKind = [](
uint16_t RelType) ->
bool {
1121 case TailRelocKind::Load_GOT:
1124 return RelType == ELF::R_SPARC_GOTDATA_OP;
1125 case TailRelocKind::Add_TLS:
1129 case ELF::R_SPARC_TLS_GD_ADD:
1130 case ELF::R_SPARC_TLS_IE_ADD:
1131 case ELF::R_SPARC_TLS_LDM_ADD:
1132 case ELF::R_SPARC_TLS_LDO_ADD:
1137 case TailRelocKind::Load_TLS:
1141 case ELF::R_SPARC_TLS_IE_LD:
1142 case ELF::R_SPARC_TLS_IE_LDX:
1147 case TailRelocKind::Call_TLS:
1151 case ELF::R_SPARC_TLS_GD_CALL:
1152 case ELF::R_SPARC_TLS_LDM_CALL:
1168 return Error(getLoc(),
"expected valid identifier for operand modifier");
1173 return Error(getLoc(),
"invalid relocation specifier");
1175 if (!MatchesKind(RelType)) {
1177 getLexer().UnLex(Tok);
1183 return Error(getLoc(),
"expected '('");
1187 if (getParser().parseParenExpression(SubExpr, E))
1190 const MCExpr *Val = adjustPICRelocation(RelType, SubExpr);
1191 Operands.push_back(SparcOperand::CreateTailRelocSym(Val, S, E));
1200 std::unique_ptr<SparcOperand>
Mask;
1201 if (parseSparcAsmOperand(Mask).isSuccess()) {
1202 if (!
Mask->isImm() || !
Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1203 ImmVal < 0 || ImmVal > 127)
1204 return Error(S,
"invalid membar mask number");
1208 SMLoc TagStart = getLexer().getLoc();
1211 .
Case(
"LoadLoad", 0x1)
1212 .
Case(
"StoreLoad", 0x2)
1213 .
Case(
"LoadStore", 0x4)
1214 .
Case(
"StoreStore", 0x8)
1215 .
Case(
"Lookaside", 0x10)
1216 .
Case(
"MemIssue", 0x20)
1223 return Error(TagStart,
"unknown membar tag");
1233 Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
1245 ParseStatus ParseExprStatus = parseExpression(ASIVal);
1247 return ParseExprStatus;
1249 if (!isUInt<8>(ASIVal))
1250 return Error(S,
"invalid ASI number, must be between 0 and 255");
1252 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1258 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1263 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1267 return Error(TagStart,
"unknown ASI tag");
1271 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1278 int64_t PrefetchVal = 0;
1283 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1285 return ParseExprStatus;
1287 if (!isUInt<8>(PrefetchVal))
1288 return Error(S,
"invalid prefetch number, must be between 0 and 31");
1290 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1294 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1298 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1302 return Error(TagStart,
"unknown prefetch tag");
1304 PrefetchVal = PrefetchTag->
Encoding;
1306 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1314 switch (getLexer().getKind()) {
1325 if (getParser().parseExpression(DestValue))
1328 Operands.push_back(SparcOperand::CreateImm(DestValue, S, E));
1345 Operands.push_back(SparcOperand::CreateToken(
"[",
1349 if (Mnemonic ==
"cas" || Mnemonic ==
"casl" || Mnemonic ==
"casa" ||
1350 Mnemonic ==
"casx" || Mnemonic ==
"casxl" || Mnemonic ==
"casxa") {
1363 Operands.push_back(SparcOperand::CreateReg(Reg, RegKind, S, E));
1375 Operands.push_back(SparcOperand::CreateToken(
"]",
1386 S,
"malformed ASI tag, must be a constant integer expression");
1397 if (OldMemOp.isMEMrr()) {
1398 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1399 return Error(S,
"invalid operand for instruction");
1402 OldMemOp.getMemBase(),
1404 OldMemOp.getStartLoc(),
1405 OldMemOp.getEndLoc()));
1412 Operands.push_back(SparcOperand::CreateToken(
"%asi", S));
1416 return Error(S,
"malformed ASI tag, must be %asi, a constant integer "
1417 "expression, or a named tag");
1428 std::unique_ptr<SparcOperand>
Op;
1430 Res = parseSparcAsmOperand(
Op);
1441SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &
Op) {
1447 switch (getLexer().getKind()) {
1457 if (Reg == Sparc::ICC &&
Name ==
"xcc")
1458 Op = SparcOperand::CreateToken(
"%xcc", S);
1460 Op = SparcOperand::CreateReg(Reg, RegKind, S, E);
1463 if (matchSparcAsmModifiers(EVal, E)) {
1465 Op = SparcOperand::CreateImm(EVal, S, E);
1476 if (getParser().parseExpression(EVal, E))
1479 Op = SparcOperand::CreateImm(EVal, S, E);
1494 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
1495 Operands.push_back(SparcOperand::CreateToken(modName,
1503ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1504 AsmToken Tok = getLexer().getTok();
1506 if (!isPossibleExpression(Tok))
1509 return getParser().parseAbsoluteExpression(Val);
1513 unsigned &RegKind) {
1514 RegKind = SparcOperand::rk_None;
1516 return SP::NoRegister;
1530 if (Reg == SP::ASR4 &&
Name ==
"tick") {
1531 RegKind = SparcOperand::rk_Special;
1535 if (
MRI.getRegClass(SP::IntRegsRegClassID).contains(Reg)) {
1536 RegKind = SparcOperand::rk_IntReg;
1539 if (
MRI.getRegClass(SP::FPRegsRegClassID).contains(Reg)) {
1540 RegKind = SparcOperand::rk_FloatReg;
1543 if (
MRI.getRegClass(SP::CoprocRegsRegClassID).contains(Reg)) {
1544 RegKind = SparcOperand::rk_CoprocReg;
1549 if (
MRI.getRegClass(SP::IntPairRegClassID).contains(Reg)) {
1550 RegKind = SparcOperand::rk_IntReg;
1551 return MRI.getSubReg(Reg, SP::sub_even);
1555 if (
MRI.getRegClass(SP::DFPRegsRegClassID).contains(Reg)) {
1558 RegKind = SparcOperand::rk_FloatReg;
1561 RegKind = SparcOperand::rk_DoubleReg;
1567 assert(!
MRI.getRegClass(SP::QFPRegsRegClassID).contains(Reg));
1570 if (
MRI.getRegClass(SP::CoprocPairRegClassID).contains(Reg)) {
1571 RegKind = SparcOperand::rk_CoprocReg;
1572 return MRI.getSubReg(Reg, SP::sub_even);
1576 RegKind = SparcOperand::rk_Special;
1585 if (
Name.starts_with_insensitive(
"r") &&
1586 !
Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {
1587 RegKind = SparcOperand::rk_IntReg;
1591 if (
Name ==
"xcc") {
1593 RegKind = SparcOperand::rk_Special;
1599 if (
Name ==
"pcr") {
1600 RegKind = SparcOperand::rk_Special;
1603 if (
Name ==
"pic") {
1604 RegKind = SparcOperand::rk_Special;
1607 if (
Name ==
"dcr") {
1608 RegKind = SparcOperand::rk_Special;
1611 if (
Name ==
"gsr") {
1612 RegKind = SparcOperand::rk_Special;
1615 if (
Name ==
"set_softint") {
1616 RegKind = SparcOperand::rk_Special;
1619 if (
Name ==
"clear_softint") {
1620 RegKind = SparcOperand::rk_Special;
1623 if (
Name ==
"softint") {
1624 RegKind = SparcOperand::rk_Special;
1627 if (
Name ==
"tick_cmpr") {
1628 RegKind = SparcOperand::rk_Special;
1631 if (
Name ==
"stick" ||
Name ==
"sys_tick") {
1632 RegKind = SparcOperand::rk_Special;
1635 if (
Name ==
"stick_cmpr" ||
Name ==
"sys_tick_cmpr") {
1636 RegKind = SparcOperand::rk_Special;
1640 return SP::NoRegister;
1675SparcAsmParser::adjustPICRelocation(
uint16_t RelType,
const MCExpr *subExpr) {
1681 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1684 case ELF::R_SPARC_LO10:
1688 case ELF::R_SPARC_HI22:
1698bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
1709 Error(getLoc(),
"invalid relocation specifier");
1712 case ELF::R_SPARC_GOTDATA_OP:
1713 case ELF::R_SPARC_TLS_GD_ADD:
1714 case ELF::R_SPARC_TLS_GD_CALL:
1715 case ELF::R_SPARC_TLS_IE_ADD:
1716 case ELF::R_SPARC_TLS_IE_LD:
1717 case ELF::R_SPARC_TLS_IE_LDX:
1718 case ELF::R_SPARC_TLS_LDM_ADD:
1719 case ELF::R_SPARC_TLS_LDM_CALL:
1720 case ELF::R_SPARC_TLS_LDO_ADD:
1737 EVal = adjustPICRelocation(VK, subExpr);
1741bool SparcAsmParser::isPossibleExpression(
const AsmToken &Token) {
1764 SparcOperand &
Op = (SparcOperand &)GOp;
1765 if (
Op.isFloatOrDoubleReg()) {
1769 if (!
Op.isFloatReg() || SparcOperand::MorphToDoubleReg(
Op))
1773 if (SparcOperand::MorphToQuadReg(
Op))
1778 if (
Op.isIntReg() &&
Kind == MCK_IntPair) {
1779 if (SparcOperand::MorphToIntPairReg(
Op))
1782 if (
Op.isCoprocReg() &&
Kind == MCK_CoprocPair) {
1783 if (SparcOperand::MorphToCoprocPairReg(
Op))
1786 return Match_InvalidOperand;
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info, bool IsDynamicVGPRChainCall=false)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
This file defines the SmallVector class.
static const MCPhysReg DoubleRegs[32]
static bool hasGOTReference(const MCExpr *Expr)
static const MCPhysReg IntRegs[32]
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser()
static const MCPhysReg IntPairRegs[]
static const MCPhysReg QuadFPRegs[32]
static const MCPhysReg CoprocPairRegs[]
static bool is64Bit(const char *name)
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() 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
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
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
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression, assuming that an initial '(' has already been consumed.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
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
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Interface to description of machine instruction set.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual void print(raw_ostream &, const MCAsmInfo &) const =0
print - Print a debug representation of the operand to the given stream.
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Extension point for target-specific MCExpr subclasses with a relocation specifier,...
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
StringRef getName() const
getName - Get the symbol name.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
ArchType getArch() const
Get the parsed architecture type of this triple.
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.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
bool isIntReg(MCRegister Reg)
MCExpr const & getExpr(MCExpr const &Expr)
uint16_t parseSpecifier(StringRef name)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSparcTarget()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Target & getTheSparcV9Target()
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Target & getTheSparcelTarget()
Implement std::hash so that hash_code can be used in STL containers.
A record for a potential prefetch made during the initial scan of the loop.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...