62 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
67#define GET_ASSEMBLER_HEADER
68#include "SparcGenAsmMatcher.inc"
76 bool MatchingInlineAsm)
override;
79 SMLoc &EndLoc)
override;
85 unsigned Kind)
override;
96 template <TailRelocKind Kind>
105 ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
106 bool isCall =
false);
117 bool isPossibleExpression(
const AsmToken &Token);
120 MatchResultTy mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
125 bool matchSparcAsmModifiers(
const MCExpr *&EVal,
SMLoc &EndLoc);
143 MRI(*Parser.getContext().getRegisterInfo()) {
160 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
161 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
162 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
163 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
164 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
165 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
166 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
167 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
170 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
171 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
172 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
173 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
174 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
175 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
176 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
177 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
180 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
181 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
182 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
183 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
186 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
187 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
188 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
189 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
192 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
193 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
194 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
195 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_Immediate; }
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!");
369 case k_Token:
OS <<
"Token: " << getToken() <<
"\n";
break;
370 case k_Register:
OS <<
"Reg: #" <<
getReg() <<
"\n";
break;
371 case k_Immediate:
OS <<
"Imm: " << getImm() <<
"\n";
break;
372 case k_MemoryReg:
OS <<
"Mem: " << getMemBase() <<
"+"
373 << getMemOffsetReg() <<
"\n";
break;
374 case k_MemoryImm:
assert(getMemOff() !=
nullptr);
375 OS <<
"Mem: " << getMemBase()
376 <<
"+" << *getMemOff()
379 OS <<
"ASI tag: " << getASITag() <<
"\n";
382 OS <<
"Prefetch tag: " << getPrefetchTag() <<
"\n";
387 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
388 assert(
N == 1 &&
"Invalid number of operands!");
392 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
393 assert(
N == 1 &&
"Invalid number of operands!");
394 const MCExpr *Expr = getImm();
398 void addShiftAmtImm5Operands(
MCInst &Inst,
unsigned N)
const {
399 assert(
N == 1 &&
"Invalid number of operands!");
400 addExpr(Inst, getImm());
402 void addShiftAmtImm6Operands(
MCInst &Inst,
unsigned N)
const {
403 assert(
N == 1 &&
"Invalid number of operands!");
404 addExpr(Inst, getImm());
411 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
417 void addMEMrrOperands(
MCInst &Inst,
unsigned N)
const {
418 assert(
N == 2 &&
"Invalid number of operands!");
422 assert(getMemOffsetReg() != 0 &&
"Invalid offset");
426 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
427 assert(
N == 2 &&
"Invalid number of operands!");
431 const MCExpr *Expr = getMemOff();
435 void addASITagOperands(
MCInst &Inst,
unsigned N)
const {
436 assert(
N == 1 &&
"Invalid number of operands!");
440 void addPrefetchTagOperands(
MCInst &Inst,
unsigned N)
const {
441 assert(
N == 1 &&
"Invalid number of operands!");
445 void addMembarTagOperands(
MCInst &Inst,
unsigned N)
const {
446 assert(
N == 1 &&
"Invalid number of operands!");
447 const MCExpr *Expr = getImm();
452 assert(
N == 1 &&
"Invalid number of operands!");
453 addExpr(Inst, getImm());
456 void addTailRelocSymOperands(
MCInst &Inst,
unsigned N)
const {
457 assert(
N == 1 &&
"Invalid number of operands!");
458 addExpr(Inst, getImm());
461 static std::unique_ptr<SparcOperand> CreateToken(
StringRef Str,
SMLoc S) {
462 auto Op = std::make_unique<SparcOperand>(k_Token);
463 Op->Tok.Data = Str.data();
464 Op->Tok.Length = Str.size();
470 static std::unique_ptr<SparcOperand> CreateReg(
unsigned RegNum,
unsigned Kind,
472 auto Op = std::make_unique<SparcOperand>(k_Register);
473 Op->Reg.RegNum = RegNum;
474 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
480 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
482 auto Op = std::make_unique<SparcOperand>(k_Immediate);
489 static std::unique_ptr<SparcOperand> CreateASITag(
unsigned Val,
SMLoc S,
491 auto Op = std::make_unique<SparcOperand>(k_ASITag);
498 static std::unique_ptr<SparcOperand> CreatePrefetchTag(
unsigned Val,
SMLoc S,
500 auto Op = std::make_unique<SparcOperand>(k_PrefetchTag);
507 static bool MorphToIntPairReg(SparcOperand &
Op) {
508 unsigned Reg =
Op.getReg();
510 unsigned regIdx = 32;
511 if (
Reg >= Sparc::G0 &&
Reg <= Sparc::G7)
512 regIdx =
Reg - Sparc::G0;
513 else if (
Reg >= Sparc::O0 &&
Reg <= Sparc::O7)
514 regIdx =
Reg - Sparc::O0 + 8;
515 else if (
Reg >= Sparc::L0 &&
Reg <= Sparc::L7)
516 regIdx =
Reg - Sparc::L0 + 16;
517 else if (
Reg >= Sparc::I0 &&
Reg <= Sparc::I7)
518 regIdx =
Reg - Sparc::I0 + 24;
519 if (regIdx % 2 || regIdx > 31)
522 Op.Reg.Kind = rk_IntPairReg;
526 static bool MorphToDoubleReg(SparcOperand &
Op) {
527 unsigned Reg =
Op.getReg();
529 unsigned regIdx =
Reg - Sparc::F0;
530 if (regIdx % 2 || regIdx > 31)
533 Op.Reg.Kind = rk_DoubleReg;
537 static bool MorphToQuadReg(SparcOperand &
Op) {
538 unsigned Reg =
Op.getReg();
540 switch (
Op.Reg.Kind) {
543 regIdx =
Reg - Sparc::F0;
544 if (regIdx % 4 || regIdx > 31)
549 regIdx =
Reg - Sparc::D0;
550 if (regIdx % 2 || regIdx > 31)
556 Op.Reg.Kind = rk_QuadReg;
560 static bool MorphToCoprocPairReg(SparcOperand &
Op) {
561 unsigned Reg =
Op.getReg();
562 assert(
Op.Reg.Kind == rk_CoprocReg);
563 unsigned regIdx = 32;
564 if (
Reg >= Sparc::C0 &&
Reg <= Sparc::C31)
565 regIdx =
Reg - Sparc::C0;
566 if (regIdx % 2 || regIdx > 31)
569 Op.Reg.Kind = rk_CoprocPairReg;
573 static std::unique_ptr<SparcOperand>
574 MorphToMEMrr(
unsigned Base, std::unique_ptr<SparcOperand>
Op) {
575 unsigned offsetReg =
Op->getReg();
576 Op->Kind = k_MemoryReg;
578 Op->Mem.OffsetReg = offsetReg;
579 Op->Mem.Off =
nullptr;
583 static std::unique_ptr<SparcOperand>
585 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
587 Op->Mem.OffsetReg = Sparc::G0;
588 Op->Mem.Off =
nullptr;
594 static std::unique_ptr<SparcOperand>
595 MorphToMEMri(
unsigned Base, std::unique_ptr<SparcOperand>
Op) {
597 Op->Kind = k_MemoryImm;
599 Op->Mem.OffsetReg = 0;
607#define GET_MATCHER_IMPLEMENTATION
608#define GET_REGISTER_MATCHER
609#define GET_MNEMONIC_SPELL_CHECKER
610#include "SparcGenAsmMatcher.inc"
614SparcAsmParser::MatchResultTy
615SparcAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
620 const MatchEntry *Start, *
End;
625 Start = std::begin(MatchTable0);
626 End = std::end(MatchTable0);
631 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
633 if (MnemonicRange.first == MnemonicRange.second)
634 return Match_MnemonicFail;
636 for (
const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
639 FeatureBitsets[it->RequiredFeaturesIdx];
640 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
641 return Match_Success;
643 return Match_MissingFeature;
646bool SparcAsmParser::expandSET(
MCInst &Inst,
SMLoc IDLoc,
655 int64_t RawImmValue = IsImm ? MCValOp.
getImm() : 0;
658 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
660 "set: argument must be between -2147483648 and 4294967295");
665 int32_t ImmValue = RawImmValue;
669 bool IsEffectivelyImm13 =
670 IsImm && ((
is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
682 if (!IsEffectivelyImm13) {
703 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
706 if (IsEffectivelyImm13)
720bool SparcAsmParser::expandSETX(
MCInst &Inst,
SMLoc IDLoc,
729 bool IsImm = MCValOp.
isImm();
730 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
736 if (IsImm && isInt<13>(ImmValue)) {
761 if (IsImm && isUInt<32>(ImmValue))
792bool SparcAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
796 bool MatchingInlineAsm) {
801 switch (MatchResult) {
802 case Match_Success: {
809 if (expandSET(Inst, IDLoc, Instructions))
813 if (expandSETX(Inst, IDLoc, Instructions))
818 for (
const MCInst &
I : Instructions) {
824 case Match_MissingFeature:
826 "instruction requires a CPU feature not currently enabled");
828 case Match_InvalidOperand: {
829 SMLoc ErrorLoc = IDLoc;
832 return Error(IDLoc,
"too few operands for instruction");
835 if (ErrorLoc ==
SMLoc())
839 return Error(ErrorLoc,
"invalid operand for instruction");
841 case Match_MnemonicFail:
842 return Error(IDLoc,
"invalid instruction mnemonic");
849 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
850 return Error(StartLoc,
"invalid register name");
859 Reg = Sparc::NoRegister;
863 unsigned RegKind = SparcOperand::rk_None;
864 Reg = matchRegisterName(Tok, RegKind);
870 getLexer().UnLex(Tok);
886 MatchResultTy MS = mnemonicIsValid(
Name, 0);
890 case Match_MissingFeature:
891 return Error(NameLoc,
892 "instruction requires a CPU feature not currently enabled");
893 case Match_MnemonicFail:
894 return Error(NameLoc,
895 "invalid instruction mnemonic" +
896 SparcMnemonicSpellCheck(
Name, getAvailableFeatures(), 0));
902 Operands.push_back(SparcOperand::CreateToken(
Name, NameLoc));
910 if (!parseBranchModifiers(
Operands).isSuccess()) {
911 SMLoc Loc = getLexer().getLoc();
912 return Error(Loc,
"unexpected token");
916 SMLoc Loc = getLexer().getLoc();
917 return Error(Loc,
"unexpected token");
928 SMLoc Loc = getLexer().getLoc();
929 return Error(Loc,
"unexpected token");
934 SMLoc Loc = getLexer().getLoc();
935 return Error(Loc,
"unexpected token");
944 if (IDVal ==
".register") {
949 if (IDVal ==
".proc") {
963 std::unique_ptr<SparcOperand>
LHS;
964 if (!parseSparcAsmOperand(LHS).isSuccess())
969 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
973 if (!
LHS->isIntReg())
974 return Error(
LHS->getStartLoc(),
"invalid register kind for this operand");
982 std::unique_ptr<SparcOperand>
RHS;
983 if (!parseSparcAsmOperand(RHS).isSuccess())
986 if (
RHS->isReg() && !
RHS->isIntReg())
988 "invalid register kind for this operand");
992 ? SparcOperand::MorphToMEMri(
LHS->getReg(), std::move(RHS))
998 Operands.push_back(SparcOperand::CreateMEMr(
LHS->getReg(), S, E));
1002template <
unsigned N>
1012 if (getParser().parseExpression(Expr))
1017 return Error(S,
"constant expression expected");
1019 if (!isUInt<N>(
CE->getValue()))
1020 return Error(S,
"immediate shift value out of range");
1022 Operands.push_back(SparcOperand::CreateImm(Expr, S, E));
1026template <SparcAsmParser::TailRelocKind Kind>
1033 case TailRelocKind::Load_GOT:
1037 case TailRelocKind::Add_TLS:
1049 case TailRelocKind::Load_TLS:
1059 case TailRelocKind::Call_TLS:
1074 return Error(getLoc(),
"expected '%' for operand modifier");
1080 return Error(getLoc(),
"expected valid identifier for operand modifier");
1085 return Error(getLoc(),
"invalid operand modifier");
1087 if (!MatchesKind(VK)) {
1089 getLexer().UnLex(Tok);
1095 return Error(getLoc(),
"expected '('");
1099 if (getParser().parseParenExpression(SubExpr, E))
1102 const MCExpr *Val = adjustPICRelocation(VK, SubExpr);
1103 Operands.push_back(SparcOperand::CreateImm(Val, S, E));
1112 std::unique_ptr<SparcOperand>
Mask;
1113 if (parseSparcAsmOperand(Mask).isSuccess()) {
1114 if (!
Mask->isImm() || !
Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1115 ImmVal < 0 || ImmVal > 127)
1116 return Error(S,
"invalid membar mask number");
1120 SMLoc TagStart = getLexer().getLoc();
1123 .
Case(
"LoadLoad", 0x1)
1124 .
Case(
"StoreLoad", 0x2)
1125 .
Case(
"LoadStore", 0x4)
1126 .
Case(
"StoreStore", 0x8)
1127 .
Case(
"Lookaside", 0x10)
1128 .
Case(
"MemIssue", 0x20)
1135 return Error(TagStart,
"unknown membar tag");
1145 Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
1157 ParseStatus ParseExprStatus = parseExpression(ASIVal);
1159 return ParseExprStatus;
1161 if (!isUInt<8>(ASIVal))
1162 return Error(S,
"invalid ASI number, must be between 0 and 255");
1164 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1170 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1175 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1179 return Error(TagStart,
"unknown ASI tag");
1183 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1190 int64_t PrefetchVal = 0;
1195 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1197 return ParseExprStatus;
1199 if (!isUInt<8>(PrefetchVal))
1200 return Error(S,
"invalid prefetch number, must be between 0 and 31");
1202 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1206 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1210 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1214 return Error(TagStart,
"unknown prefetch tag");
1216 PrefetchVal = PrefetchTag->
Encoding;
1218 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1226 switch (getLexer().getKind()) {
1237 if (getParser().parseExpression(DestValue))
1240 bool IsPic = getContext().getObjectFileInfo()->isPositionIndependent();
1245 Operands.push_back(SparcOperand::CreateImm(DestExpr, S, E));
1262 Operands.push_back(SparcOperand::CreateToken(
"[",
1266 if (Mnemonic ==
"cas" || Mnemonic ==
"casl" || Mnemonic ==
"casa" ||
1267 Mnemonic ==
"casx" || Mnemonic ==
"casxl" || Mnemonic ==
"casxa") {
1280 Operands.push_back(SparcOperand::CreateReg(Reg, RegKind, S, E));
1292 Operands.push_back(SparcOperand::CreateToken(
"]",
1303 S,
"malformed ASI tag, must be a constant integer expression");
1314 if (OldMemOp.isMEMrr()) {
1315 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1316 return Error(S,
"invalid operand for instruction");
1319 OldMemOp.getMemBase(),
1321 OldMemOp.getStartLoc(),
1322 OldMemOp.getEndLoc()));
1329 Operands.push_back(SparcOperand::CreateToken(
"%asi", S));
1333 return Error(S,
"malformed ASI tag, must be %asi, a constant integer "
1334 "expression, or a named tag");
1345 std::unique_ptr<SparcOperand>
Op;
1347 Res = parseSparcAsmOperand(
Op, (Mnemonic ==
"call"));
1358SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &
Op,
1365 switch (getLexer().getKind()) {
1375 if (Reg == Sparc::ICC &&
Name ==
"xcc")
1376 Op = SparcOperand::CreateToken(
"%xcc", S);
1378 Op = SparcOperand::CreateReg(Reg, RegKind, S, E);
1381 if (matchSparcAsmModifiers(EVal, E)) {
1383 Op = SparcOperand::CreateImm(EVal, S, E);
1394 if (getParser().parseExpression(EVal, E))
1398 if (!EVal->evaluateAsAbsolute(Res)) {
1401 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1409 Op = SparcOperand::CreateImm(EVal, S, E);
1424 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
1425 Operands.push_back(SparcOperand::CreateToken(modName,
1433ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1434 AsmToken Tok = getLexer().getTok();
1436 if (!isPossibleExpression(Tok))
1439 return getParser().parseAbsoluteExpression(Val);
1443 unsigned &RegKind) {
1444 RegKind = SparcOperand::rk_None;
1446 return SP::NoRegister;
1460 if (Reg == SP::ASR4 &&
Name ==
"tick") {
1461 RegKind = SparcOperand::rk_Special;
1465 if (
MRI.getRegClass(SP::IntRegsRegClassID).contains(Reg)) {
1466 RegKind = SparcOperand::rk_IntReg;
1469 if (
MRI.getRegClass(SP::FPRegsRegClassID).contains(Reg)) {
1470 RegKind = SparcOperand::rk_FloatReg;
1473 if (
MRI.getRegClass(SP::CoprocRegsRegClassID).contains(Reg)) {
1474 RegKind = SparcOperand::rk_CoprocReg;
1479 if (
MRI.getRegClass(SP::IntPairRegClassID).contains(Reg)) {
1480 RegKind = SparcOperand::rk_IntReg;
1481 return MRI.getSubReg(Reg, SP::sub_even);
1485 if (
MRI.getRegClass(SP::DFPRegsRegClassID).contains(Reg)) {
1488 RegKind = SparcOperand::rk_FloatReg;
1491 RegKind = SparcOperand::rk_DoubleReg;
1497 assert(!
MRI.getRegClass(SP::QFPRegsRegClassID).contains(Reg));
1500 if (
MRI.getRegClass(SP::CoprocPairRegClassID).contains(Reg)) {
1501 RegKind = SparcOperand::rk_CoprocReg;
1502 return MRI.getSubReg(Reg, SP::sub_even);
1506 RegKind = SparcOperand::rk_Special;
1515 if (
Name.starts_with_insensitive(
"r") &&
1516 !
Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {
1517 RegKind = SparcOperand::rk_IntReg;
1521 if (
Name ==
"xcc") {
1523 RegKind = SparcOperand::rk_Special;
1529 if (
Name ==
"pcr") {
1530 RegKind = SparcOperand::rk_Special;
1533 if (
Name ==
"pic") {
1534 RegKind = SparcOperand::rk_Special;
1537 if (
Name ==
"dcr") {
1538 RegKind = SparcOperand::rk_Special;
1541 if (
Name ==
"gsr") {
1542 RegKind = SparcOperand::rk_Special;
1545 if (
Name ==
"set_softint") {
1546 RegKind = SparcOperand::rk_Special;
1549 if (
Name ==
"clear_softint") {
1550 RegKind = SparcOperand::rk_Special;
1553 if (
Name ==
"softint") {
1554 RegKind = SparcOperand::rk_Special;
1557 if (
Name ==
"tick_cmpr") {
1558 RegKind = SparcOperand::rk_Special;
1561 if (
Name ==
"stick" ||
Name ==
"sys_tick") {
1562 RegKind = SparcOperand::rk_Special;
1565 if (
Name ==
"stick_cmpr" ||
Name ==
"sys_tick_cmpr") {
1566 RegKind = SparcOperand::rk_Special;
1570 return SP::NoRegister;
1578 if (
const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1609 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1626bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
1637 Error(getLoc(),
"invalid operand modifier");
1665 EVal = adjustPICRelocation(VK, subExpr);
1669bool SparcAsmParser::isPossibleExpression(
const AsmToken &Token) {
1691 SparcOperand &
Op = (SparcOperand &)GOp;
1692 if (
Op.isFloatOrDoubleReg()) {
1696 if (!
Op.isFloatReg() || SparcOperand::MorphToDoubleReg(
Op))
1700 if (SparcOperand::MorphToQuadReg(
Op))
1705 if (
Op.isIntReg() &&
Kind == MCK_IntPair) {
1706 if (SparcOperand::MorphToIntPairReg(
Op))
1709 if (
Op.isCoprocReg() &&
Kind == MCK_CoprocPair) {
1710 if (SparcOperand::MorphToCoprocPairReg(
Op))
1713 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(unsigned 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 createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned 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 parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
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...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
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.
MCExpr const & getExpr(MCExpr const &Expr)
bool isIntReg(unsigned Reg)
@ 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,...