58 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
63#define GET_ASSEMBLER_HEADER
64#include "SparcGenAsmMatcher.inc"
72 bool MatchingInlineAsm)
override;
74 SMLoc &EndLoc)
override;
76 SMLoc &EndLoc)
override;
82 unsigned Kind)
override;
89 template <TailRelocKind Kind>
100 parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
101 bool isCall =
false);
113 bool matchSparcAsmModifiers(
const MCExpr *&EVal,
SMLoc &EndLoc);
145 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
146 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
147 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
148 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
149 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
150 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
151 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
152 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
155 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
156 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
157 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
158 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
159 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
160 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
161 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
162 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
165 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
166 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
167 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
168 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
169 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
170 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
171 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
172 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
175 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
176 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
177 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
178 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
181 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
182 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
183 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
184 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
185 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
186 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
187 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
188 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
191 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
192 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
193 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
194 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
197 Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3,
198 Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7,
199 Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11,
200 Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
201 Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
202 Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
203 Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
204 Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
207 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
208 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
209 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
210 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
239 SMLoc StartLoc, EndLoc;
269 SparcOperand(KindTy K) :
Kind(
K) {}
271 bool isToken()
const override {
return Kind == k_Token; }
272 bool isReg()
const override {
return Kind == k_Register; }
273 bool isImm()
const override {
return Kind == k_Immediate; }
274 bool isMem()
const override {
return isMEMrr() || isMEMri(); }
275 bool isMEMrr()
const {
return Kind == k_MemoryReg; }
276 bool isMEMri()
const {
return Kind == k_MemoryImm; }
277 bool isMembarTag()
const {
return Kind == k_Immediate; }
278 bool isTailRelocSym()
const {
return Kind == k_Immediate; }
280 bool isCallTarget()
const {
285 return CE->getValue() % 4 == 0;
290 bool isShiftAmtImm5()
const {
295 return isUInt<5>(
CE->getValue());
300 bool isShiftAmtImm6()
const {
305 return isUInt<6>(
CE->getValue());
311 return (Kind == k_Register &&
Reg.Kind == rk_IntReg);
314 bool isFloatReg()
const {
315 return (Kind == k_Register &&
Reg.Kind == rk_FloatReg);
318 bool isFloatOrDoubleReg()
const {
319 return (Kind == k_Register && (
Reg.Kind == rk_FloatReg
320 ||
Reg.Kind == rk_DoubleReg));
323 bool isCoprocReg()
const {
324 return (Kind == k_Register &&
Reg.Kind == rk_CoprocReg);
328 assert(Kind == k_Token &&
"Invalid access!");
332 unsigned getReg()
const override {
333 assert((Kind == k_Register) &&
"Invalid access!");
337 const MCExpr *getImm()
const {
338 assert((Kind == k_Immediate) &&
"Invalid access!");
342 unsigned getMemBase()
const {
343 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) &&
"Invalid access!");
347 unsigned getMemOffsetReg()
const {
348 assert((Kind == k_MemoryReg) &&
"Invalid access!");
349 return Mem.OffsetReg;
352 const MCExpr *getMemOff()
const {
353 assert((Kind == k_MemoryImm) &&
"Invalid access!");
368 case k_Token:
OS <<
"Token: " << getToken() <<
"\n";
break;
369 case k_Register:
OS <<
"Reg: #" <<
getReg() <<
"\n";
break;
370 case k_Immediate:
OS <<
"Imm: " << getImm() <<
"\n";
break;
371 case k_MemoryReg:
OS <<
"Mem: " << getMemBase() <<
"+"
372 << getMemOffsetReg() <<
"\n";
break;
373 case k_MemoryImm:
assert(getMemOff() !=
nullptr);
374 OS <<
"Mem: " << getMemBase()
375 <<
"+" << *getMemOff()
380 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
381 assert(
N == 1 &&
"Invalid number of operands!");
385 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
386 assert(
N == 1 &&
"Invalid number of operands!");
387 const MCExpr *Expr = getImm();
391 void addShiftAmtImm5Operands(
MCInst &Inst,
unsigned N)
const {
392 assert(
N == 1 &&
"Invalid number of operands!");
393 addExpr(Inst, getImm());
395 void addShiftAmtImm6Operands(
MCInst &Inst,
unsigned N)
const {
396 assert(
N == 1 &&
"Invalid number of operands!");
397 addExpr(Inst, getImm());
404 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
410 void addMEMrrOperands(
MCInst &Inst,
unsigned N)
const {
411 assert(
N == 2 &&
"Invalid number of operands!");
415 assert(getMemOffsetReg() != 0 &&
"Invalid offset");
419 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
420 assert(
N == 2 &&
"Invalid number of operands!");
424 const MCExpr *Expr = getMemOff();
428 void addMembarTagOperands(
MCInst &Inst,
unsigned N)
const {
429 assert(
N == 1 &&
"Invalid number of operands!");
430 const MCExpr *Expr = getImm();
435 assert(
N == 1 &&
"Invalid number of operands!");
436 addExpr(Inst, getImm());
439 void addTailRelocSymOperands(
MCInst &Inst,
unsigned N)
const {
440 assert(
N == 1 &&
"Invalid number of operands!");
441 addExpr(Inst, getImm());
444 static std::unique_ptr<SparcOperand> CreateToken(
StringRef Str,
SMLoc S) {
445 auto Op = std::make_unique<SparcOperand>(k_Token);
446 Op->Tok.Data = Str.data();
447 Op->Tok.Length = Str.size();
453 static std::unique_ptr<SparcOperand> CreateReg(
unsigned RegNum,
unsigned Kind,
455 auto Op = std::make_unique<SparcOperand>(k_Register);
456 Op->Reg.RegNum = RegNum;
457 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
463 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
465 auto Op = std::make_unique<SparcOperand>(k_Immediate);
472 static bool MorphToIntPairReg(SparcOperand &Op) {
473 unsigned Reg =
Op.getReg();
475 unsigned regIdx = 32;
476 if (
Reg >= Sparc::G0 &&
Reg <= Sparc::G7)
477 regIdx =
Reg - Sparc::G0;
478 else if (
Reg >= Sparc::O0 &&
Reg <= Sparc::O7)
479 regIdx =
Reg - Sparc::O0 + 8;
480 else if (
Reg >= Sparc::L0 &&
Reg <= Sparc::L7)
481 regIdx =
Reg - Sparc::L0 + 16;
482 else if (
Reg >= Sparc::I0 &&
Reg <= Sparc::I7)
483 regIdx =
Reg - Sparc::I0 + 24;
484 if (regIdx % 2 || regIdx > 31)
487 Op.Reg.Kind = rk_IntPairReg;
491 static bool MorphToDoubleReg(SparcOperand &Op) {
492 unsigned Reg =
Op.getReg();
494 unsigned regIdx =
Reg - Sparc::F0;
495 if (regIdx % 2 || regIdx > 31)
498 Op.Reg.Kind = rk_DoubleReg;
502 static bool MorphToQuadReg(SparcOperand &Op) {
503 unsigned Reg =
Op.getReg();
505 switch (
Op.Reg.Kind) {
508 regIdx =
Reg - Sparc::F0;
509 if (regIdx % 4 || regIdx > 31)
514 regIdx =
Reg - Sparc::D0;
515 if (regIdx % 2 || regIdx > 31)
521 Op.Reg.Kind = rk_QuadReg;
525 static bool MorphToCoprocPairReg(SparcOperand &Op) {
526 unsigned Reg =
Op.getReg();
527 assert(
Op.Reg.Kind == rk_CoprocReg);
528 unsigned regIdx = 32;
529 if (
Reg >= Sparc::C0 &&
Reg <= Sparc::C31)
530 regIdx =
Reg - Sparc::C0;
531 if (regIdx % 2 || regIdx > 31)
534 Op.Reg.Kind = rk_CoprocPairReg;
538 static std::unique_ptr<SparcOperand>
539 MorphToMEMrr(
unsigned Base, std::unique_ptr<SparcOperand> Op) {
540 unsigned offsetReg =
Op->getReg();
541 Op->Kind = k_MemoryReg;
543 Op->Mem.OffsetReg = offsetReg;
544 Op->Mem.Off =
nullptr;
548 static std::unique_ptr<SparcOperand>
550 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
552 Op->Mem.OffsetReg = Sparc::G0;
553 Op->Mem.Off =
nullptr;
559 static std::unique_ptr<SparcOperand>
560 MorphToMEMri(
unsigned Base, std::unique_ptr<SparcOperand> Op) {
562 Op->Kind = k_MemoryImm;
564 Op->Mem.OffsetReg = 0;
572bool SparcAsmParser::expandSET(
MCInst &Inst,
SMLoc IDLoc,
581 int64_t RawImmValue = IsImm ? MCValOp.
getImm() : 0;
584 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
586 "set: argument must be between -2147483648 and 4294967295");
591 int32_t ImmValue = RawImmValue;
595 bool IsEffectivelyImm13 =
596 IsImm && ((
is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
608 if (!IsEffectivelyImm13) {
629 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
632 if (IsEffectivelyImm13)
646bool SparcAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
650 bool MatchingInlineAsm) {
655 switch (MatchResult) {
656 case Match_Success: {
663 if (expandSET(Inst, IDLoc, Instructions))
668 for (
const MCInst &
I : Instructions) {
674 case Match_MissingFeature:
676 "instruction requires a CPU feature not currently enabled");
678 case Match_InvalidOperand: {
679 SMLoc ErrorLoc = IDLoc;
682 return Error(IDLoc,
"too few operands for instruction");
685 if (ErrorLoc ==
SMLoc())
689 return Error(ErrorLoc,
"invalid operand for instruction");
691 case Match_MnemonicFail:
692 return Error(IDLoc,
"invalid instruction mnemonic");
700 return Error(StartLoc,
"invalid register name");
714 unsigned regKind = SparcOperand::rk_None;
715 if (matchRegisterName(Tok, RegNo, regKind)) {
720 getLexer().UnLex(Tok);
733 Operands.push_back(SparcOperand::CreateToken(
Name, NameLoc));
742 SMLoc Loc = getLexer().getLoc();
743 return Error(Loc,
"unexpected token");
747 SMLoc Loc = getLexer().getLoc();
748 return Error(Loc,
"unexpected token");
759 SMLoc Loc = getLexer().getLoc();
760 return Error(Loc,
"unexpected token");
765 SMLoc Loc = getLexer().getLoc();
766 return Error(Loc,
"unexpected token");
777 if (IDVal ==
".register") {
782 if (IDVal ==
".proc") {
797 std::unique_ptr<SparcOperand>
LHS;
803 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
807 if (!
LHS->isIntReg()) {
808 Error(
LHS->getStartLoc(),
"invalid register kind for this operand");
818 std::unique_ptr<SparcOperand>
RHS;
822 if (
RHS->isReg() && !
RHS->isIntReg()) {
823 Error(
RHS->getStartLoc(),
"invalid register kind for this operand");
829 ? SparcOperand::MorphToMEMri(
LHS->getReg(), std::move(RHS))
830 : SparcOperand::MorphToMEMrr(
LHS->getReg(), std::move(RHS)));
835 Operands.push_back(SparcOperand::CreateMEMr(
LHS->getReg(), S,
E));
849 if (getParser().parseExpression(Expr))
854 Error(S,
"constant expression expected");
858 if (!isUInt<N>(
CE->getValue())) {
859 Error(S,
"immediate shift value out of range");
863 Operands.push_back(SparcOperand::CreateImm(Expr, S,
E));
867template <SparcAsmParser::TailRelocKind Kind>
875 case TailRelocKind::Load_GOT:
879 case TailRelocKind::Add_TLS:
891 case TailRelocKind::Load_TLS:
901 case TailRelocKind::Call_TLS:
916 Error(getLoc(),
"expected '%' for operand modifier");
924 Error(getLoc(),
"expected valid identifier for operand modifier");
931 Error(getLoc(),
"invalid operand modifier");
935 if (!MatchesKind(VK)) {
937 getLexer().UnLex(Tok);
943 Error(getLoc(),
"expected '('");
949 if (getParser().parseParenExpression(SubExpr,
E)) {
953 const MCExpr *Val = adjustPICRelocation(VK, SubExpr);
954 Operands.push_back(SparcOperand::CreateImm(Val, S,
E));
963 std::unique_ptr<SparcOperand>
Mask;
965 if (!
Mask->isImm() || !
Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
966 ImmVal < 0 || ImmVal > 127) {
967 Error(S,
"invalid membar mask number");
973 SMLoc TagStart = getLexer().getLoc();
976 .
Case(
"LoadLoad", 0x1)
977 .
Case(
"StoreLoad", 0x2)
978 .
Case(
"LoadStore", 0x4)
979 .
Case(
"StoreStore", 0x8)
980 .
Case(
"Lookaside", 0x10)
981 .
Case(
"MemIssue", 0x20)
988 Error(TagStart,
"unknown membar tag");
1000 Operands.push_back(SparcOperand::CreateImm(EVal, S,
E));
1008 switch (getLexer().getKind()) {
1019 if (getParser().parseExpression(DestValue))
1022 bool IsPic = getContext().getObjectFileInfo()->isPositionIndependent();
1027 Operands.push_back(SparcOperand::CreateImm(DestExpr, S,
E));
1044 Operands.push_back(SparcOperand::CreateToken(
"[",
1048 if (Mnemonic ==
"cas" || Mnemonic ==
"casx" || Mnemonic ==
"casa") {
1056 if (!matchRegisterName(Parser.
getTok(), RegNo, RegKind))
1061 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S,
E));
1073 Operands.push_back(SparcOperand::CreateToken(
"]",
1079 std::unique_ptr<SparcOperand>
Op;
1080 ResTy = parseSparcAsmOperand(Op,
false);
1088 std::unique_ptr<SparcOperand>
Op;
1090 ResTy = parseSparcAsmOperand(Op, (Mnemonic ==
"call"));
1101SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
1108 switch (getLexer().getKind()) {
1115 if (matchRegisterName(Parser.
getTok(), RegNo, RegKind)) {
1121 Op = SparcOperand::CreateReg(RegNo, RegKind, S,
E);
1124 Op = SparcOperand::CreateToken(
"%psr", S);
1127 Op = SparcOperand::CreateToken(
"%fsr", S);
1130 Op = SparcOperand::CreateToken(
"%fq", S);
1133 Op = SparcOperand::CreateToken(
"%csr", S);
1136 Op = SparcOperand::CreateToken(
"%cq", S);
1139 Op = SparcOperand::CreateToken(
"%wim", S);
1142 Op = SparcOperand::CreateToken(
"%tbr", S);
1145 Op = SparcOperand::CreateToken(
"%pc", S);
1149 Op = SparcOperand::CreateToken(
"%xcc", S);
1151 Op = SparcOperand::CreateToken(
"%icc", S);
1156 if (matchSparcAsmModifiers(EVal,
E)) {
1158 Op = SparcOperand::CreateImm(EVal, S,
E);
1169 if (getParser().parseExpression(EVal,
E))
1173 if (!EVal->evaluateAsAbsolute(Res)) {
1176 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1184 Op = SparcOperand::CreateImm(EVal, S,
E);
1200 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
1201 Operands.push_back(SparcOperand::CreateToken(modName,
1210 unsigned &RegKind) {
1213 RegKind = SparcOperand::rk_None;
1218 if (
name.equals(
"fp")) {
1220 RegKind = SparcOperand::rk_IntReg;
1224 if (
name.equals(
"sp")) {
1226 RegKind = SparcOperand::rk_IntReg;
1230 if (
name.equals(
"y")) {
1232 RegKind = SparcOperand::rk_Special;
1236 if (
name.substr(0, 3).equals_insensitive(
"asr") &&
1237 !
name.substr(3).getAsInteger(10, intVal) && intVal > 0 && intVal < 32) {
1239 RegKind = SparcOperand::rk_Special;
1244 if (
name.equals(
"fprs")) {
1246 RegKind = SparcOperand::rk_Special;
1250 if (
name.equals(
"icc")) {
1252 RegKind = SparcOperand::rk_Special;
1256 if (
name.equals(
"psr")) {
1258 RegKind = SparcOperand::rk_Special;
1262 if (
name.equals(
"fsr")) {
1264 RegKind = SparcOperand::rk_Special;
1268 if (
name.equals(
"fq")) {
1270 RegKind = SparcOperand::rk_Special;
1274 if (
name.equals(
"csr")) {
1275 RegNo = Sparc::CPSR;
1276 RegKind = SparcOperand::rk_Special;
1280 if (
name.equals(
"cq")) {
1282 RegKind = SparcOperand::rk_Special;
1286 if (
name.equals(
"wim")) {
1288 RegKind = SparcOperand::rk_Special;
1292 if (
name.equals(
"tbr")) {
1294 RegKind = SparcOperand::rk_Special;
1298 if (
name.equals(
"xcc")) {
1301 RegKind = SparcOperand::rk_Special;
1306 if (
name.substr(0, 3).equals_insensitive(
"fcc") &&
1307 !
name.substr(3).getAsInteger(10, intVal) && intVal < 4) {
1309 RegNo = Sparc::FCC0 + intVal;
1310 RegKind = SparcOperand::rk_Special;
1315 if (
name.substr(0, 1).equals_insensitive(
"g") &&
1316 !
name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1318 RegKind = SparcOperand::rk_IntReg;
1322 if (
name.substr(0, 1).equals_insensitive(
"o") &&
1323 !
name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1325 RegKind = SparcOperand::rk_IntReg;
1328 if (
name.substr(0, 1).equals_insensitive(
"l") &&
1329 !
name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1331 RegKind = SparcOperand::rk_IntReg;
1334 if (
name.substr(0, 1).equals_insensitive(
"i") &&
1335 !
name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1337 RegKind = SparcOperand::rk_IntReg;
1341 if (
name.substr(0, 1).equals_insensitive(
"f") &&
1342 !
name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1344 RegKind = SparcOperand::rk_FloatReg;
1348 if (
name.substr(0, 1).equals_insensitive(
"f") &&
1349 !
name.substr(1, 2).getAsInteger(10, intVal) && intVal >= 32 &&
1350 intVal <= 62 && (intVal % 2 == 0)) {
1353 RegKind = SparcOperand::rk_DoubleReg;
1358 if (
name.substr(0, 1).equals_insensitive(
"r") &&
1359 !
name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1361 RegKind = SparcOperand::rk_IntReg;
1366 if (
name.substr(0, 1).equals_insensitive(
"c") &&
1367 !
name.substr(1).getAsInteger(10, intVal) && intVal < 32) {
1369 RegKind = SparcOperand::rk_CoprocReg;
1373 if (
name.equals(
"tpc")) {
1375 RegKind = SparcOperand::rk_Special;
1378 if (
name.equals(
"tnpc")) {
1379 RegNo = Sparc::TNPC;
1380 RegKind = SparcOperand::rk_Special;
1383 if (
name.equals(
"tstate")) {
1384 RegNo = Sparc::TSTATE;
1385 RegKind = SparcOperand::rk_Special;
1388 if (
name.equals(
"tt")) {
1390 RegKind = SparcOperand::rk_Special;
1393 if (
name.equals(
"tick")) {
1394 RegNo = Sparc::TICK;
1395 RegKind = SparcOperand::rk_Special;
1398 if (
name.equals(
"tba")) {
1400 RegKind = SparcOperand::rk_Special;
1403 if (
name.equals(
"pstate")) {
1404 RegNo = Sparc::PSTATE;
1405 RegKind = SparcOperand::rk_Special;
1408 if (
name.equals(
"tl")) {
1410 RegKind = SparcOperand::rk_Special;
1413 if (
name.equals(
"pil")) {
1415 RegKind = SparcOperand::rk_Special;
1418 if (
name.equals(
"cwp")) {
1420 RegKind = SparcOperand::rk_Special;
1423 if (
name.equals(
"cansave")) {
1424 RegNo = Sparc::CANSAVE;
1425 RegKind = SparcOperand::rk_Special;
1428 if (
name.equals(
"canrestore")) {
1429 RegNo = Sparc::CANRESTORE;
1430 RegKind = SparcOperand::rk_Special;
1433 if (
name.equals(
"cleanwin")) {
1434 RegNo = Sparc::CLEANWIN;
1435 RegKind = SparcOperand::rk_Special;
1438 if (
name.equals(
"otherwin")) {
1439 RegNo = Sparc::OTHERWIN;
1440 RegKind = SparcOperand::rk_Special;
1443 if (
name.equals(
"wstate")) {
1444 RegNo = Sparc::WSTATE;
1445 RegKind = SparcOperand::rk_Special;
1448 if (
name.equals(
"pc")) {
1450 RegKind = SparcOperand::rk_Special;
1462 if (
const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1493 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1510bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
1521 Error(getLoc(),
"invalid operand modifier");
1549 EVal = adjustPICRelocation(VK, subExpr);
1559#define GET_REGISTER_MATCHER
1560#define GET_MATCHER_IMPLEMENTATION
1561#include "SparcGenAsmMatcher.inc"
1565 SparcOperand &Op = (SparcOperand &)GOp;
1566 if (Op.isFloatOrDoubleReg()) {
1570 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1574 if (SparcOperand::MorphToQuadReg(Op))
1579 if (Op.isIntReg() && Kind == MCK_IntPair) {
1580 if (SparcOperand::MorphToIntPairReg(Op))
1583 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1584 if (SparcOperand::MorphToCoprocPairReg(Op))
1587 return Match_InvalidOperand;
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
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
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]
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static const MCPhysReg CoprocRegs[32]
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser()
static const MCPhysReg IntPairRegs[]
static const MCPhysReg QuadFPRegs[32]
static const MCPhysReg ASRRegs[32]
static const MCPhysReg FloatRegs[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
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.
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)
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual unsigned getReg() const =0
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 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.
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 bool ParseDirective(AsmToken DirectiveID)=0
ParseDirective - Parse a target specific assembler directive.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
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 ...
virtual OperandMatchResultTy tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
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(unsigned Reg)
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSparcTarget()
Target & getTheSparcV9Target()
Target & getTheSparcelTarget()
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...