61 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
66#define GET_ASSEMBLER_HEADER
67#include "SparcGenAsmMatcher.inc"
75 bool MatchingInlineAsm)
override;
78 SMLoc &EndLoc)
override;
84 unsigned Kind)
override;
95 template <TailRelocKind Kind>
104 ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
105 bool isCall =
false);
116 bool isPossibleExpression(
const AsmToken &Token);
119 MatchResultTy mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
124 bool matchSparcAsmModifiers(
const MCExpr *&EVal,
SMLoc &EndLoc);
142 MRI(*Parser.getContext().getRegisterInfo()) {
159 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
160 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
161 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
162 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
163 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
164 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
165 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
166 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
169 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
170 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
171 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
172 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
173 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
174 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
175 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
176 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
179 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
180 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
181 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
182 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
185 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
186 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
187 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
188 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
191 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
192 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
193 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
194 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
226 SMLoc StartLoc, EndLoc;
258 SparcOperand(KindTy K) :
Kind(
K) {}
260 bool isToken()
const override {
return Kind == k_Token; }
261 bool isReg()
const override {
return Kind == k_Register; }
262 bool isImm()
const override {
return Kind == k_Immediate; }
263 bool isMem()
const override {
return isMEMrr() || isMEMri(); }
264 bool isMEMrr()
const {
return Kind == k_MemoryReg; }
265 bool isMEMri()
const {
return Kind == k_MemoryImm; }
266 bool isMembarTag()
const {
return Kind == k_Immediate; }
267 bool isASITag()
const {
return Kind == k_ASITag; }
268 bool isPrefetchTag()
const {
return Kind == k_PrefetchTag; }
269 bool isTailRelocSym()
const {
return Kind == k_TailRelocSym; }
271 bool isCallTarget()
const {
276 return CE->getValue() % 4 == 0;
281 bool isShiftAmtImm5()
const {
286 return isUInt<5>(
CE->getValue());
291 bool isShiftAmtImm6()
const {
296 return isUInt<6>(
CE->getValue());
302 return (Kind == k_Register &&
Reg.Kind == rk_IntReg);
305 bool isFloatReg()
const {
306 return (Kind == k_Register &&
Reg.Kind == rk_FloatReg);
309 bool isFloatOrDoubleReg()
const {
310 return (Kind == k_Register && (
Reg.Kind == rk_FloatReg
311 ||
Reg.Kind == rk_DoubleReg));
314 bool isCoprocReg()
const {
315 return (Kind == k_Register &&
Reg.Kind == rk_CoprocReg);
319 assert(Kind == k_Token &&
"Invalid access!");
324 assert((Kind == k_Register) &&
"Invalid access!");
328 const MCExpr *getImm()
const {
329 assert((Kind == k_Immediate) &&
"Invalid access!");
333 unsigned getMemBase()
const {
334 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) &&
"Invalid access!");
338 unsigned getMemOffsetReg()
const {
339 assert((Kind == k_MemoryReg) &&
"Invalid access!");
340 return Mem.OffsetReg;
343 const MCExpr *getMemOff()
const {
344 assert((Kind == k_MemoryImm) &&
"Invalid access!");
348 unsigned getASITag()
const {
349 assert((Kind == k_ASITag) &&
"Invalid access!");
353 unsigned getPrefetchTag()
const {
354 assert((Kind == k_PrefetchTag) &&
"Invalid access!");
358 const MCExpr *getTailRelocSym()
const {
359 assert((Kind == k_TailRelocSym) &&
"Invalid access!");
374 case k_Token:
OS <<
"Token: " << getToken() <<
"\n";
break;
375 case k_Register:
OS <<
"Reg: #" <<
getReg() <<
"\n";
break;
376 case k_Immediate:
OS <<
"Imm: " << getImm() <<
"\n";
break;
377 case k_MemoryReg:
OS <<
"Mem: " << getMemBase() <<
"+"
378 << getMemOffsetReg() <<
"\n";
break;
379 case k_MemoryImm:
assert(getMemOff() !=
nullptr);
380 OS <<
"Mem: " << getMemBase()
381 <<
"+" << *getMemOff()
384 OS <<
"ASI tag: " << getASITag() <<
"\n";
387 OS <<
"Prefetch tag: " << getPrefetchTag() <<
"\n";
390 OS <<
"TailReloc: " << getTailRelocSym() <<
"\n";
395 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
396 assert(
N == 1 &&
"Invalid number of operands!");
400 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
401 assert(
N == 1 &&
"Invalid number of operands!");
402 const MCExpr *Expr = getImm();
406 void addShiftAmtImm5Operands(
MCInst &Inst,
unsigned N)
const {
407 assert(
N == 1 &&
"Invalid number of operands!");
408 addExpr(Inst, getImm());
410 void addShiftAmtImm6Operands(
MCInst &Inst,
unsigned N)
const {
411 assert(
N == 1 &&
"Invalid number of operands!");
412 addExpr(Inst, getImm());
419 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
425 void addMEMrrOperands(
MCInst &Inst,
unsigned N)
const {
426 assert(
N == 2 &&
"Invalid number of operands!");
430 assert(getMemOffsetReg() != 0 &&
"Invalid offset");
434 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
435 assert(
N == 2 &&
"Invalid number of operands!");
439 const MCExpr *Expr = getMemOff();
443 void addASITagOperands(
MCInst &Inst,
unsigned N)
const {
444 assert(
N == 1 &&
"Invalid number of operands!");
448 void addPrefetchTagOperands(
MCInst &Inst,
unsigned N)
const {
449 assert(
N == 1 &&
"Invalid number of operands!");
453 void addMembarTagOperands(
MCInst &Inst,
unsigned N)
const {
454 assert(
N == 1 &&
"Invalid number of operands!");
455 const MCExpr *Expr = getImm();
460 assert(
N == 1 &&
"Invalid number of operands!");
461 addExpr(Inst, getImm());
464 void addTailRelocSymOperands(
MCInst &Inst,
unsigned N)
const {
465 assert(
N == 1 &&
"Invalid number of operands!");
466 addExpr(Inst, getTailRelocSym());
469 static std::unique_ptr<SparcOperand> CreateToken(
StringRef Str,
SMLoc S) {
470 auto Op = std::make_unique<SparcOperand>(k_Token);
471 Op->Tok.Data = Str.data();
472 Op->Tok.Length = Str.size();
478 static std::unique_ptr<SparcOperand> CreateReg(
unsigned RegNum,
unsigned Kind,
480 auto Op = std::make_unique<SparcOperand>(k_Register);
481 Op->Reg.RegNum = RegNum;
482 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
488 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
490 auto Op = std::make_unique<SparcOperand>(k_Immediate);
497 static std::unique_ptr<SparcOperand> CreateASITag(
unsigned Val,
SMLoc S,
499 auto Op = std::make_unique<SparcOperand>(k_ASITag);
506 static std::unique_ptr<SparcOperand> CreatePrefetchTag(
unsigned Val,
SMLoc S,
508 auto Op = std::make_unique<SparcOperand>(k_PrefetchTag);
515 static std::unique_ptr<SparcOperand> CreateTailRelocSym(
const MCExpr *Val,
517 auto Op = std::make_unique<SparcOperand>(k_TailRelocSym);
524 static bool MorphToIntPairReg(SparcOperand &
Op) {
525 unsigned Reg =
Op.getReg();
527 unsigned regIdx = 32;
528 if (
Reg >= Sparc::G0 &&
Reg <= Sparc::G7)
529 regIdx =
Reg - Sparc::G0;
530 else if (
Reg >= Sparc::O0 &&
Reg <= Sparc::O7)
531 regIdx =
Reg - Sparc::O0 + 8;
532 else if (
Reg >= Sparc::L0 &&
Reg <= Sparc::L7)
533 regIdx =
Reg - Sparc::L0 + 16;
534 else if (
Reg >= Sparc::I0 &&
Reg <= Sparc::I7)
535 regIdx =
Reg - Sparc::I0 + 24;
536 if (regIdx % 2 || regIdx > 31)
539 Op.Reg.Kind = rk_IntPairReg;
543 static bool MorphToDoubleReg(SparcOperand &
Op) {
544 unsigned Reg =
Op.getReg();
546 unsigned regIdx =
Reg - Sparc::F0;
547 if (regIdx % 2 || regIdx > 31)
550 Op.Reg.Kind = rk_DoubleReg;
554 static bool MorphToQuadReg(SparcOperand &
Op) {
555 unsigned Reg =
Op.getReg();
557 switch (
Op.Reg.Kind) {
560 regIdx =
Reg - Sparc::F0;
561 if (regIdx % 4 || regIdx > 31)
566 regIdx =
Reg - Sparc::D0;
567 if (regIdx % 2 || regIdx > 31)
573 Op.Reg.Kind = rk_QuadReg;
577 static bool MorphToCoprocPairReg(SparcOperand &
Op) {
578 unsigned Reg =
Op.getReg();
579 assert(
Op.Reg.Kind == rk_CoprocReg);
580 unsigned regIdx = 32;
581 if (
Reg >= Sparc::C0 &&
Reg <= Sparc::C31)
582 regIdx =
Reg - Sparc::C0;
583 if (regIdx % 2 || regIdx > 31)
586 Op.Reg.Kind = rk_CoprocPairReg;
590 static std::unique_ptr<SparcOperand>
591 MorphToMEMrr(
unsigned Base, std::unique_ptr<SparcOperand>
Op) {
592 unsigned offsetReg =
Op->getReg();
593 Op->Kind = k_MemoryReg;
595 Op->Mem.OffsetReg = offsetReg;
596 Op->Mem.Off =
nullptr;
600 static std::unique_ptr<SparcOperand>
602 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
604 Op->Mem.OffsetReg = Sparc::G0;
605 Op->Mem.Off =
nullptr;
611 static std::unique_ptr<SparcOperand>
612 MorphToMEMri(
unsigned Base, std::unique_ptr<SparcOperand>
Op) {
614 Op->Kind = k_MemoryImm;
616 Op->Mem.OffsetReg = 0;
624#define GET_MATCHER_IMPLEMENTATION
625#define GET_REGISTER_MATCHER
626#define GET_MNEMONIC_SPELL_CHECKER
627#include "SparcGenAsmMatcher.inc"
631SparcAsmParser::MatchResultTy
632SparcAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
637 const MatchEntry *Start, *
End;
642 Start = std::begin(MatchTable0);
643 End = std::end(MatchTable0);
648 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
650 if (MnemonicRange.first == MnemonicRange.second)
651 return Match_MnemonicFail;
653 for (
const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
656 FeatureBitsets[it->RequiredFeaturesIdx];
657 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
658 return Match_Success;
660 return Match_MissingFeature;
663bool SparcAsmParser::expandSET(
MCInst &Inst,
SMLoc IDLoc,
672 int64_t RawImmValue = IsImm ? MCValOp.
getImm() : 0;
675 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
677 "set: argument must be between -2147483648 and 4294967295");
682 int32_t ImmValue = RawImmValue;
686 bool IsEffectivelyImm13 =
687 IsImm && ((
is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
699 if (!IsEffectivelyImm13) {
720 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
723 if (IsEffectivelyImm13)
737bool SparcAsmParser::expandSETX(
MCInst &Inst,
SMLoc IDLoc,
746 bool IsImm = MCValOp.
isImm();
747 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
753 if (IsImm && isInt<13>(ImmValue)) {
778 if (IsImm && isUInt<32>(ImmValue))
809bool SparcAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
813 bool MatchingInlineAsm) {
818 switch (MatchResult) {
819 case Match_Success: {
826 if (expandSET(Inst, IDLoc, Instructions))
830 if (expandSETX(Inst, IDLoc, Instructions))
835 for (
const MCInst &
I : Instructions) {
841 case Match_MissingFeature:
843 "instruction requires a CPU feature not currently enabled");
845 case Match_InvalidOperand: {
846 SMLoc ErrorLoc = IDLoc;
849 return Error(IDLoc,
"too few operands for instruction");
852 if (ErrorLoc ==
SMLoc())
856 return Error(ErrorLoc,
"invalid operand for instruction");
858 case Match_MnemonicFail:
859 return Error(IDLoc,
"invalid instruction mnemonic");
866 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
867 return Error(StartLoc,
"invalid register name");
876 Reg = Sparc::NoRegister;
880 unsigned RegKind = SparcOperand::rk_None;
881 Reg = matchRegisterName(Tok, RegKind);
887 getLexer().UnLex(Tok);
903 MatchResultTy MS = mnemonicIsValid(
Name, 0);
907 case Match_MissingFeature:
908 return Error(NameLoc,
909 "instruction requires a CPU feature not currently enabled");
910 case Match_MnemonicFail:
911 return Error(NameLoc,
912 "invalid instruction mnemonic" +
913 SparcMnemonicSpellCheck(
Name, getAvailableFeatures(), 0));
919 Operands.push_back(SparcOperand::CreateToken(
Name, NameLoc));
927 if (!parseBranchModifiers(
Operands).isSuccess()) {
928 SMLoc Loc = getLexer().getLoc();
929 return Error(Loc,
"unexpected token");
933 SMLoc Loc = getLexer().getLoc();
934 return Error(Loc,
"unexpected token");
945 SMLoc Loc = getLexer().getLoc();
946 return Error(Loc,
"unexpected token");
951 SMLoc Loc = getLexer().getLoc();
952 return Error(Loc,
"unexpected token");
961 if (IDVal ==
".register") {
966 if (IDVal ==
".proc") {
980 std::unique_ptr<SparcOperand>
LHS;
981 if (!parseSparcAsmOperand(LHS).isSuccess())
986 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
990 if (!
LHS->isIntReg())
991 return Error(
LHS->getStartLoc(),
"invalid register kind for this operand");
999 std::unique_ptr<SparcOperand>
RHS;
1000 if (!parseSparcAsmOperand(RHS).isSuccess())
1003 if (
RHS->isReg() && !
RHS->isIntReg())
1005 "invalid register kind for this operand");
1009 ? SparcOperand::MorphToMEMri(
LHS->getReg(), std::move(RHS))
1015 Operands.push_back(SparcOperand::CreateMEMr(
LHS->getReg(), S, E));
1019template <
unsigned N>
1029 if (getParser().parseExpression(Expr))
1034 return Error(S,
"constant expression expected");
1036 if (!isUInt<N>(
CE->getValue()))
1037 return Error(S,
"immediate shift value out of range");
1039 Operands.push_back(SparcOperand::CreateImm(Expr, S, E));
1043template <SparcAsmParser::TailRelocKind Kind>
1050 case TailRelocKind::Load_GOT:
1054 case TailRelocKind::Add_TLS:
1066 case TailRelocKind::Load_TLS:
1076 case TailRelocKind::Call_TLS:
1097 return Error(getLoc(),
"expected valid identifier for operand modifier");
1102 return Error(getLoc(),
"invalid operand modifier");
1104 if (!MatchesKind(VK)) {
1106 getLexer().UnLex(Tok);
1112 return Error(getLoc(),
"expected '('");
1116 if (getParser().parseParenExpression(SubExpr, E))
1119 const MCExpr *Val = adjustPICRelocation(VK, SubExpr);
1120 Operands.push_back(SparcOperand::CreateTailRelocSym(Val, S, E));
1129 std::unique_ptr<SparcOperand>
Mask;
1130 if (parseSparcAsmOperand(Mask).isSuccess()) {
1131 if (!
Mask->isImm() || !
Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1132 ImmVal < 0 || ImmVal > 127)
1133 return Error(S,
"invalid membar mask number");
1137 SMLoc TagStart = getLexer().getLoc();
1140 .
Case(
"LoadLoad", 0x1)
1141 .
Case(
"StoreLoad", 0x2)
1142 .
Case(
"LoadStore", 0x4)
1143 .
Case(
"StoreStore", 0x8)
1144 .
Case(
"Lookaside", 0x10)
1145 .
Case(
"MemIssue", 0x20)
1152 return Error(TagStart,
"unknown membar tag");
1162 Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
1174 ParseStatus ParseExprStatus = parseExpression(ASIVal);
1176 return ParseExprStatus;
1178 if (!isUInt<8>(ASIVal))
1179 return Error(S,
"invalid ASI number, must be between 0 and 255");
1181 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1187 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1192 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1196 return Error(TagStart,
"unknown ASI tag");
1200 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1207 int64_t PrefetchVal = 0;
1212 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1214 return ParseExprStatus;
1216 if (!isUInt<8>(PrefetchVal))
1217 return Error(S,
"invalid prefetch number, must be between 0 and 31");
1219 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1223 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1227 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1231 return Error(TagStart,
"unknown prefetch tag");
1233 PrefetchVal = PrefetchTag->
Encoding;
1235 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1243 switch (getLexer().getKind()) {
1254 if (getParser().parseExpression(DestValue))
1257 bool IsPic = getContext().getObjectFileInfo()->isPositionIndependent();
1262 Operands.push_back(SparcOperand::CreateImm(DestExpr, S, E));
1279 Operands.push_back(SparcOperand::CreateToken(
"[",
1283 if (Mnemonic ==
"cas" || Mnemonic ==
"casl" || Mnemonic ==
"casa" ||
1284 Mnemonic ==
"casx" || Mnemonic ==
"casxl" || Mnemonic ==
"casxa") {
1297 Operands.push_back(SparcOperand::CreateReg(Reg, RegKind, S, E));
1309 Operands.push_back(SparcOperand::CreateToken(
"]",
1320 S,
"malformed ASI tag, must be a constant integer expression");
1331 if (OldMemOp.isMEMrr()) {
1332 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1333 return Error(S,
"invalid operand for instruction");
1336 OldMemOp.getMemBase(),
1338 OldMemOp.getStartLoc(),
1339 OldMemOp.getEndLoc()));
1346 Operands.push_back(SparcOperand::CreateToken(
"%asi", S));
1350 return Error(S,
"malformed ASI tag, must be %asi, a constant integer "
1351 "expression, or a named tag");
1362 std::unique_ptr<SparcOperand>
Op;
1364 Res = parseSparcAsmOperand(
Op, (Mnemonic ==
"call"));
1375SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &
Op,
1382 switch (getLexer().getKind()) {
1392 if (Reg == Sparc::ICC &&
Name ==
"xcc")
1393 Op = SparcOperand::CreateToken(
"%xcc", S);
1395 Op = SparcOperand::CreateReg(Reg, RegKind, S, E);
1398 if (matchSparcAsmModifiers(EVal, E)) {
1400 Op = SparcOperand::CreateImm(EVal, S, E);
1411 if (getParser().parseExpression(EVal, E))
1415 if (!EVal->evaluateAsAbsolute(Res)) {
1418 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1426 Op = SparcOperand::CreateImm(EVal, S, E);
1441 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
1442 Operands.push_back(SparcOperand::CreateToken(modName,
1450ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1451 AsmToken Tok = getLexer().getTok();
1453 if (!isPossibleExpression(Tok))
1456 return getParser().parseAbsoluteExpression(Val);
1460 unsigned &RegKind) {
1461 RegKind = SparcOperand::rk_None;
1463 return SP::NoRegister;
1477 if (Reg == SP::ASR4 &&
Name ==
"tick") {
1478 RegKind = SparcOperand::rk_Special;
1482 if (
MRI.getRegClass(SP::IntRegsRegClassID).contains(Reg)) {
1483 RegKind = SparcOperand::rk_IntReg;
1486 if (
MRI.getRegClass(SP::FPRegsRegClassID).contains(Reg)) {
1487 RegKind = SparcOperand::rk_FloatReg;
1490 if (
MRI.getRegClass(SP::CoprocRegsRegClassID).contains(Reg)) {
1491 RegKind = SparcOperand::rk_CoprocReg;
1496 if (
MRI.getRegClass(SP::IntPairRegClassID).contains(Reg)) {
1497 RegKind = SparcOperand::rk_IntReg;
1498 return MRI.getSubReg(Reg, SP::sub_even);
1502 if (
MRI.getRegClass(SP::DFPRegsRegClassID).contains(Reg)) {
1505 RegKind = SparcOperand::rk_FloatReg;
1508 RegKind = SparcOperand::rk_DoubleReg;
1514 assert(!
MRI.getRegClass(SP::QFPRegsRegClassID).contains(Reg));
1517 if (
MRI.getRegClass(SP::CoprocPairRegClassID).contains(Reg)) {
1518 RegKind = SparcOperand::rk_CoprocReg;
1519 return MRI.getSubReg(Reg, SP::sub_even);
1523 RegKind = SparcOperand::rk_Special;
1532 if (
Name.starts_with_insensitive(
"r") &&
1533 !
Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {
1534 RegKind = SparcOperand::rk_IntReg;
1538 if (
Name ==
"xcc") {
1540 RegKind = SparcOperand::rk_Special;
1546 if (
Name ==
"pcr") {
1547 RegKind = SparcOperand::rk_Special;
1550 if (
Name ==
"pic") {
1551 RegKind = SparcOperand::rk_Special;
1554 if (
Name ==
"dcr") {
1555 RegKind = SparcOperand::rk_Special;
1558 if (
Name ==
"gsr") {
1559 RegKind = SparcOperand::rk_Special;
1562 if (
Name ==
"set_softint") {
1563 RegKind = SparcOperand::rk_Special;
1566 if (
Name ==
"clear_softint") {
1567 RegKind = SparcOperand::rk_Special;
1570 if (
Name ==
"softint") {
1571 RegKind = SparcOperand::rk_Special;
1574 if (
Name ==
"tick_cmpr") {
1575 RegKind = SparcOperand::rk_Special;
1578 if (
Name ==
"stick" ||
Name ==
"sys_tick") {
1579 RegKind = SparcOperand::rk_Special;
1582 if (
Name ==
"stick_cmpr" ||
Name ==
"sys_tick_cmpr") {
1583 RegKind = SparcOperand::rk_Special;
1587 return SP::NoRegister;
1595 if (
const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1626 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1643bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
1654 Error(getLoc(),
"invalid operand modifier");
1682 EVal = adjustPICRelocation(VK, subExpr);
1686bool SparcAsmParser::isPossibleExpression(
const AsmToken &Token) {
1708 SparcOperand &
Op = (SparcOperand &)GOp;
1709 if (
Op.isFloatOrDoubleReg()) {
1713 if (!
Op.isFloatReg() || SparcOperand::MorphToDoubleReg(
Op))
1717 if (SparcOperand::MorphToQuadReg(
Op))
1722 if (
Op.isIntReg() &&
Kind == MCK_IntPair) {
1723 if (SparcOperand::MorphToIntPairReg(
Op))
1726 if (
Op.isCoprocReg() &&
Kind == MCK_CoprocPair) {
1727 if (SparcOperand::MorphToCoprocPairReg(
Op))
1730 return Match_InvalidOperand;
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static const MCPhysReg DoubleRegs[32]
static bool hasGOTReference(const MCExpr *Expr)
static const MCPhysReg IntRegs[32]
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.
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
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.
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 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.
@ 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 void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
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.
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.
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
static VariantKind parseVariantKind(StringRef name)
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)
@ 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()
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,...