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;
93 template <TailRelocKind Kind>
102 ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
103 bool isCall =
false);
115 bool matchSparcAsmModifiers(
const MCExpr *&EVal,
SMLoc &EndLoc);
150 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
151 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
152 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
153 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
154 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
155 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
156 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
157 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
160 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
161 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
162 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
163 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
164 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
165 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
166 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
167 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
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 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
187 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
188 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
189 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
190 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
191 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
192 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
193 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
196 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
197 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
198 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
199 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
202 Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3,
203 Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7,
204 Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11,
205 Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
206 Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
207 Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
208 Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
209 Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
212 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
213 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
214 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
215 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
245 SMLoc StartLoc, EndLoc;
276 SparcOperand(KindTy K) :
Kind(
K) {}
278 bool isToken()
const override {
return Kind == k_Token; }
279 bool isReg()
const override {
return Kind == k_Register; }
280 bool isImm()
const override {
return Kind == k_Immediate; }
281 bool isMem()
const override {
return isMEMrr() || isMEMri(); }
282 bool isMEMrr()
const {
return Kind == k_MemoryReg; }
283 bool isMEMri()
const {
return Kind == k_MemoryImm; }
284 bool isMembarTag()
const {
return Kind == k_Immediate; }
285 bool isASITag()
const {
return Kind == k_ASITag; }
286 bool isTailRelocSym()
const {
return Kind == k_Immediate; }
288 bool isCallTarget()
const {
293 return CE->getValue() % 4 == 0;
298 bool isShiftAmtImm5()
const {
303 return isUInt<5>(
CE->getValue());
308 bool isShiftAmtImm6()
const {
313 return isUInt<6>(
CE->getValue());
319 return (Kind == k_Register &&
Reg.Kind == rk_IntReg);
322 bool isFloatReg()
const {
323 return (Kind == k_Register &&
Reg.Kind == rk_FloatReg);
326 bool isFloatOrDoubleReg()
const {
327 return (Kind == k_Register && (
Reg.Kind == rk_FloatReg
328 ||
Reg.Kind == rk_DoubleReg));
331 bool isCoprocReg()
const {
332 return (Kind == k_Register &&
Reg.Kind == rk_CoprocReg);
336 assert(Kind == k_Token &&
"Invalid access!");
340 unsigned getReg()
const override {
341 assert((Kind == k_Register) &&
"Invalid access!");
345 const MCExpr *getImm()
const {
346 assert((Kind == k_Immediate) &&
"Invalid access!");
350 unsigned getMemBase()
const {
351 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) &&
"Invalid access!");
355 unsigned getMemOffsetReg()
const {
356 assert((Kind == k_MemoryReg) &&
"Invalid access!");
357 return Mem.OffsetReg;
360 const MCExpr *getMemOff()
const {
361 assert((Kind == k_MemoryImm) &&
"Invalid access!");
365 unsigned getASITag()
const {
366 assert((Kind == k_ASITag) &&
"Invalid access!");
381 case k_Token:
OS <<
"Token: " << getToken() <<
"\n";
break;
382 case k_Register:
OS <<
"Reg: #" <<
getReg() <<
"\n";
break;
383 case k_Immediate:
OS <<
"Imm: " << getImm() <<
"\n";
break;
384 case k_MemoryReg:
OS <<
"Mem: " << getMemBase() <<
"+"
385 << getMemOffsetReg() <<
"\n";
break;
386 case k_MemoryImm:
assert(getMemOff() !=
nullptr);
387 OS <<
"Mem: " << getMemBase()
388 <<
"+" << *getMemOff()
391 OS <<
"ASI tag: " << getASITag() <<
"\n";
396 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
397 assert(
N == 1 &&
"Invalid number of operands!");
401 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
402 assert(
N == 1 &&
"Invalid number of operands!");
403 const MCExpr *Expr = getImm();
407 void addShiftAmtImm5Operands(
MCInst &Inst,
unsigned N)
const {
408 assert(
N == 1 &&
"Invalid number of operands!");
409 addExpr(Inst, getImm());
411 void addShiftAmtImm6Operands(
MCInst &Inst,
unsigned N)
const {
412 assert(
N == 1 &&
"Invalid number of operands!");
413 addExpr(Inst, getImm());
420 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
426 void addMEMrrOperands(
MCInst &Inst,
unsigned N)
const {
427 assert(
N == 2 &&
"Invalid number of operands!");
431 assert(getMemOffsetReg() != 0 &&
"Invalid offset");
435 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
436 assert(
N == 2 &&
"Invalid number of operands!");
440 const MCExpr *Expr = getMemOff();
444 void addASITagOperands(
MCInst &Inst,
unsigned N)
const {
445 assert(
N == 1 &&
"Invalid number of operands!");
449 void addMembarTagOperands(
MCInst &Inst,
unsigned N)
const {
450 assert(
N == 1 &&
"Invalid number of operands!");
451 const MCExpr *Expr = getImm();
456 assert(
N == 1 &&
"Invalid number of operands!");
457 addExpr(Inst, getImm());
460 void addTailRelocSymOperands(
MCInst &Inst,
unsigned N)
const {
461 assert(
N == 1 &&
"Invalid number of operands!");
462 addExpr(Inst, getImm());
465 static std::unique_ptr<SparcOperand> CreateToken(
StringRef Str,
SMLoc S) {
466 auto Op = std::make_unique<SparcOperand>(k_Token);
467 Op->Tok.Data = Str.data();
468 Op->Tok.Length = Str.size();
474 static std::unique_ptr<SparcOperand> CreateReg(
unsigned RegNum,
unsigned Kind,
476 auto Op = std::make_unique<SparcOperand>(k_Register);
477 Op->Reg.RegNum = RegNum;
478 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
484 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
486 auto Op = std::make_unique<SparcOperand>(k_Immediate);
493 static std::unique_ptr<SparcOperand> CreateASITag(
unsigned Val,
SMLoc S,
495 auto Op = std::make_unique<SparcOperand>(k_ASITag);
502 static bool MorphToIntPairReg(SparcOperand &
Op) {
503 unsigned Reg =
Op.getReg();
505 unsigned regIdx = 32;
506 if (
Reg >= Sparc::G0 &&
Reg <= Sparc::G7)
507 regIdx =
Reg - Sparc::G0;
508 else if (
Reg >= Sparc::O0 &&
Reg <= Sparc::O7)
509 regIdx =
Reg - Sparc::O0 + 8;
510 else if (
Reg >= Sparc::L0 &&
Reg <= Sparc::L7)
511 regIdx =
Reg - Sparc::L0 + 16;
512 else if (
Reg >= Sparc::I0 &&
Reg <= Sparc::I7)
513 regIdx =
Reg - Sparc::I0 + 24;
514 if (regIdx % 2 || regIdx > 31)
517 Op.Reg.Kind = rk_IntPairReg;
521 static bool MorphToDoubleReg(SparcOperand &
Op) {
522 unsigned Reg =
Op.getReg();
524 unsigned regIdx =
Reg - Sparc::F0;
525 if (regIdx % 2 || regIdx > 31)
528 Op.Reg.Kind = rk_DoubleReg;
532 static bool MorphToQuadReg(SparcOperand &
Op) {
533 unsigned Reg =
Op.getReg();
535 switch (
Op.Reg.Kind) {
538 regIdx =
Reg - Sparc::F0;
539 if (regIdx % 4 || regIdx > 31)
544 regIdx =
Reg - Sparc::D0;
545 if (regIdx % 2 || regIdx > 31)
551 Op.Reg.Kind = rk_QuadReg;
555 static bool MorphToCoprocPairReg(SparcOperand &
Op) {
556 unsigned Reg =
Op.getReg();
557 assert(
Op.Reg.Kind == rk_CoprocReg);
558 unsigned regIdx = 32;
559 if (
Reg >= Sparc::C0 &&
Reg <= Sparc::C31)
560 regIdx =
Reg - Sparc::C0;
561 if (regIdx % 2 || regIdx > 31)
564 Op.Reg.Kind = rk_CoprocPairReg;
568 static std::unique_ptr<SparcOperand>
569 MorphToMEMrr(
unsigned Base, std::unique_ptr<SparcOperand>
Op) {
570 unsigned offsetReg =
Op->getReg();
571 Op->Kind = k_MemoryReg;
573 Op->Mem.OffsetReg = offsetReg;
574 Op->Mem.Off =
nullptr;
578 static std::unique_ptr<SparcOperand>
580 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
582 Op->Mem.OffsetReg = Sparc::G0;
583 Op->Mem.Off =
nullptr;
589 static std::unique_ptr<SparcOperand>
590 MorphToMEMri(
unsigned Base, std::unique_ptr<SparcOperand>
Op) {
592 Op->Kind = k_MemoryImm;
594 Op->Mem.OffsetReg = 0;
602bool SparcAsmParser::expandSET(
MCInst &Inst,
SMLoc IDLoc,
611 int64_t RawImmValue = IsImm ? MCValOp.
getImm() : 0;
614 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
616 "set: argument must be between -2147483648 and 4294967295");
621 int32_t ImmValue = RawImmValue;
625 bool IsEffectivelyImm13 =
626 IsImm && ((
is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
638 if (!IsEffectivelyImm13) {
659 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
662 if (IsEffectivelyImm13)
676bool SparcAsmParser::expandSETX(
MCInst &Inst,
SMLoc IDLoc,
685 bool IsImm = MCValOp.
isImm();
686 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
692 if (IsImm && isInt<13>(ImmValue)) {
717 if (IsImm && isUInt<32>(ImmValue))
748bool SparcAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &
Opcode,
752 bool MatchingInlineAsm) {
757 switch (MatchResult) {
758 case Match_Success: {
765 if (expandSET(Inst, IDLoc, Instructions))
769 if (expandSETX(Inst, IDLoc, Instructions))
774 for (
const MCInst &
I : Instructions) {
780 case Match_MissingFeature:
782 "instruction requires a CPU feature not currently enabled");
784 case Match_InvalidOperand: {
785 SMLoc ErrorLoc = IDLoc;
788 return Error(IDLoc,
"too few operands for instruction");
791 if (ErrorLoc ==
SMLoc())
795 return Error(ErrorLoc,
"invalid operand for instruction");
797 case Match_MnemonicFail:
798 return Error(IDLoc,
"invalid instruction mnemonic");
805 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
806 return Error(StartLoc,
"invalid register name");
815 Reg = Sparc::NoRegister;
819 unsigned regKind = SparcOperand::rk_None;
820 if (matchRegisterName(Tok, Reg, regKind)) {
825 getLexer().UnLex(Tok);
838 Operands.push_back(SparcOperand::CreateToken(
Name, NameLoc));
846 if (!parseBranchModifiers(
Operands).isSuccess()) {
847 SMLoc Loc = getLexer().getLoc();
848 return Error(Loc,
"unexpected token");
852 SMLoc Loc = getLexer().getLoc();
853 return Error(Loc,
"unexpected token");
864 SMLoc Loc = getLexer().getLoc();
865 return Error(Loc,
"unexpected token");
870 SMLoc Loc = getLexer().getLoc();
871 return Error(Loc,
"unexpected token");
880 if (IDVal ==
".register") {
885 if (IDVal ==
".proc") {
899 std::unique_ptr<SparcOperand>
LHS;
900 if (!parseSparcAsmOperand(LHS).isSuccess())
905 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
909 if (!
LHS->isIntReg())
910 return Error(
LHS->getStartLoc(),
"invalid register kind for this operand");
918 std::unique_ptr<SparcOperand>
RHS;
919 if (!parseSparcAsmOperand(RHS).isSuccess())
922 if (
RHS->isReg() && !
RHS->isIntReg())
924 "invalid register kind for this operand");
928 ? SparcOperand::MorphToMEMri(
LHS->getReg(), std::move(RHS))
934 Operands.push_back(SparcOperand::CreateMEMr(
LHS->getReg(), S,
E));
948 if (getParser().parseExpression(Expr))
953 return Error(S,
"constant expression expected");
955 if (!isUInt<N>(
CE->getValue()))
956 return Error(S,
"immediate shift value out of range");
958 Operands.push_back(SparcOperand::CreateImm(Expr, S,
E));
962template <SparcAsmParser::TailRelocKind Kind>
969 case TailRelocKind::Load_GOT:
973 case TailRelocKind::Add_TLS:
985 case TailRelocKind::Load_TLS:
995 case TailRelocKind::Call_TLS:
1010 return Error(getLoc(),
"expected '%' for operand modifier");
1016 return Error(getLoc(),
"expected valid identifier for operand modifier");
1021 return Error(getLoc(),
"invalid operand modifier");
1023 if (!MatchesKind(VK)) {
1025 getLexer().UnLex(Tok);
1031 return Error(getLoc(),
"expected '('");
1035 if (getParser().parseParenExpression(SubExpr,
E))
1038 const MCExpr *Val = adjustPICRelocation(VK, SubExpr);
1039 Operands.push_back(SparcOperand::CreateImm(Val, S,
E));
1048 std::unique_ptr<SparcOperand>
Mask;
1049 if (parseSparcAsmOperand(Mask).isSuccess()) {
1050 if (!
Mask->isImm() || !
Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1051 ImmVal < 0 || ImmVal > 127)
1052 return Error(S,
"invalid membar mask number");
1056 SMLoc TagStart = getLexer().getLoc();
1059 .
Case(
"LoadLoad", 0x1)
1060 .
Case(
"StoreLoad", 0x2)
1061 .
Case(
"LoadStore", 0x4)
1062 .
Case(
"StoreStore", 0x8)
1063 .
Case(
"Lookaside", 0x10)
1064 .
Case(
"MemIssue", 0x20)
1071 return Error(TagStart,
"unknown membar tag");
1081 Operands.push_back(SparcOperand::CreateImm(EVal, S,
E));
1093 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1096 auto ASITag = SparcASITag::lookupASITagByName(ASIName);
1098 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1102 return Error(TagStart,
"unknown ASI tag");
1104 ASIVal = ASITag->Encoding;
1105 }
else if (!getParser().parseAbsoluteExpression(ASIVal)) {
1106 if (!isUInt<8>(ASIVal))
1107 return Error(S,
"invalid ASI number, must be between 0 and 255");
1111 ?
"malformed ASI tag, must be %asi, a constant integer "
1112 "expression, or a named tag"
1113 :
"malformed ASI tag, must be a constant integer expression");
1116 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S,
E));
1124 switch (getLexer().getKind()) {
1135 if (getParser().parseExpression(DestValue))
1138 bool IsPic = getContext().getObjectFileInfo()->isPositionIndependent();
1143 Operands.push_back(SparcOperand::CreateImm(DestExpr, S,
E));
1160 Operands.push_back(SparcOperand::CreateToken(
"[",
1164 if (Mnemonic ==
"cas" || Mnemonic ==
"casl" || Mnemonic ==
"casa" ||
1165 Mnemonic ==
"casx" || Mnemonic ==
"casxl" || Mnemonic ==
"casxa") {
1173 if (!matchRegisterName(Parser.
getTok(), RegNo, RegKind))
1178 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S,
E));
1190 Operands.push_back(SparcOperand::CreateToken(
"]",
1208 if (OldMemOp.isMEMrr()) {
1209 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1210 return Error(S,
"invalid operand for instruction");
1213 OldMemOp.getMemBase(),
1215 OldMemOp.getStartLoc(),
1216 OldMemOp.getEndLoc()));
1223 Operands.push_back(SparcOperand::CreateToken(
"%asi", S));
1227 return Error(S,
"malformed ASI tag, must be %asi, a constant integer "
1228 "expression, or a named tag");
1239 std::unique_ptr<SparcOperand>
Op;
1241 Res = parseSparcAsmOperand(
Op, (Mnemonic ==
"call"));
1252SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &
Op,
1259 switch (getLexer().getKind()) {
1266 if (matchRegisterName(Parser.
getTok(), Reg, RegKind)) {
1270 if (Reg == Sparc::ICC &&
Name ==
"xcc")
1271 Op = SparcOperand::CreateToken(
"%xcc", S);
1273 Op = SparcOperand::CreateReg(Reg, RegKind, S,
E);
1276 if (matchSparcAsmModifiers(EVal,
E)) {
1278 Op = SparcOperand::CreateImm(EVal, S,
E);
1289 if (getParser().parseExpression(EVal,
E))
1293 if (!EVal->evaluateAsAbsolute(Res)) {
1296 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1304 Op = SparcOperand::CreateImm(EVal, S,
E);
1319 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
1320 Operands.push_back(SparcOperand::CreateToken(modName,
1329 unsigned &RegKind) {
1332 RegKind = SparcOperand::rk_None;
1337 if (
name.equals(
"fp")) {
1339 RegKind = SparcOperand::rk_IntReg;
1343 if (
name.equals(
"sp")) {
1345 RegKind = SparcOperand::rk_IntReg;
1349 if (
name.equals(
"y")) {
1351 RegKind = SparcOperand::rk_Special;
1355 if (
name.substr(0, 3).equals_insensitive(
"asr") &&
1356 !
name.substr(3).getAsInteger(10, intVal) && intVal > 0 && intVal < 32) {
1358 RegKind = SparcOperand::rk_Special;
1362 if (
name.equals(
"fprs")) {
1363 RegNo = Sparc::ASR6;
1364 RegKind = SparcOperand::rk_Special;
1368 if (
name.equals(
"icc")) {
1370 RegKind = SparcOperand::rk_Special;
1374 if (
name.equals(
"psr")) {
1376 RegKind = SparcOperand::rk_Special;
1380 if (
name.equals(
"fsr")) {
1382 RegKind = SparcOperand::rk_Special;
1386 if (
name.equals(
"fq")) {
1388 RegKind = SparcOperand::rk_Special;
1392 if (
name.equals(
"csr")) {
1393 RegNo = Sparc::CPSR;
1394 RegKind = SparcOperand::rk_Special;
1398 if (
name.equals(
"cq")) {
1400 RegKind = SparcOperand::rk_Special;
1404 if (
name.equals(
"wim")) {
1406 RegKind = SparcOperand::rk_Special;
1410 if (
name.equals(
"tbr")) {
1412 RegKind = SparcOperand::rk_Special;
1416 if (
name.equals(
"xcc")) {
1419 RegKind = SparcOperand::rk_Special;
1424 if (
name.substr(0, 3).equals_insensitive(
"fcc") &&
1425 !
name.substr(3).getAsInteger(10, intVal) && intVal < 4) {
1427 RegNo = Sparc::FCC0 + intVal;
1428 RegKind = SparcOperand::rk_Special;
1433 if (
name.substr(0, 1).equals_insensitive(
"g") &&
1434 !
name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1436 RegKind = SparcOperand::rk_IntReg;
1440 if (
name.substr(0, 1).equals_insensitive(
"o") &&
1441 !
name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1443 RegKind = SparcOperand::rk_IntReg;
1446 if (
name.substr(0, 1).equals_insensitive(
"l") &&
1447 !
name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1449 RegKind = SparcOperand::rk_IntReg;
1452 if (
name.substr(0, 1).equals_insensitive(
"i") &&
1453 !
name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1455 RegKind = SparcOperand::rk_IntReg;
1459 if (
name.substr(0, 1).equals_insensitive(
"f") &&
1460 !
name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1462 RegKind = SparcOperand::rk_FloatReg;
1466 if (
name.substr(0, 1).equals_insensitive(
"f") &&
1467 !
name.substr(1, 2).getAsInteger(10, intVal) && intVal >= 32 &&
1468 intVal <= 62 && (intVal % 2 == 0)) {
1471 RegKind = SparcOperand::rk_DoubleReg;
1476 if (
name.substr(0, 1).equals_insensitive(
"r") &&
1477 !
name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1479 RegKind = SparcOperand::rk_IntReg;
1484 if (
name.substr(0, 1).equals_insensitive(
"c") &&
1485 !
name.substr(1).getAsInteger(10, intVal) && intVal < 32) {
1487 RegKind = SparcOperand::rk_CoprocReg;
1491 if (
name.equals(
"tpc")) {
1493 RegKind = SparcOperand::rk_Special;
1496 if (
name.equals(
"tnpc")) {
1497 RegNo = Sparc::TNPC;
1498 RegKind = SparcOperand::rk_Special;
1501 if (
name.equals(
"tstate")) {
1502 RegNo = Sparc::TSTATE;
1503 RegKind = SparcOperand::rk_Special;
1506 if (
name.equals(
"tt")) {
1508 RegKind = SparcOperand::rk_Special;
1511 if (
name.equals(
"tick")) {
1512 RegNo = Sparc::TICK;
1513 RegKind = SparcOperand::rk_Special;
1516 if (
name.equals(
"tba")) {
1518 RegKind = SparcOperand::rk_Special;
1521 if (
name.equals(
"pstate")) {
1522 RegNo = Sparc::PSTATE;
1523 RegKind = SparcOperand::rk_Special;
1526 if (
name.equals(
"tl")) {
1528 RegKind = SparcOperand::rk_Special;
1531 if (
name.equals(
"pil")) {
1533 RegKind = SparcOperand::rk_Special;
1536 if (
name.equals(
"cwp")) {
1538 RegKind = SparcOperand::rk_Special;
1541 if (
name.equals(
"cansave")) {
1542 RegNo = Sparc::CANSAVE;
1543 RegKind = SparcOperand::rk_Special;
1546 if (
name.equals(
"canrestore")) {
1547 RegNo = Sparc::CANRESTORE;
1548 RegKind = SparcOperand::rk_Special;
1551 if (
name.equals(
"cleanwin")) {
1552 RegNo = Sparc::CLEANWIN;
1553 RegKind = SparcOperand::rk_Special;
1556 if (
name.equals(
"otherwin")) {
1557 RegNo = Sparc::OTHERWIN;
1558 RegKind = SparcOperand::rk_Special;
1561 if (
name.equals(
"wstate")) {
1562 RegNo = Sparc::WSTATE;
1563 RegKind = SparcOperand::rk_Special;
1566 if (
name.equals(
"pc")) {
1567 RegNo = Sparc::ASR5;
1568 RegKind = SparcOperand::rk_Special;
1571 if (
name.equals(
"asi")) {
1572 RegNo = Sparc::ASR3;
1573 RegKind = SparcOperand::rk_Special;
1576 if (
name.equals(
"ccr")) {
1577 RegNo = Sparc::ASR2;
1578 RegKind = SparcOperand::rk_Special;
1581 if (
name.equals(
"gl")) {
1583 RegKind = SparcOperand::rk_Special;
1586 if (
name.equals(
"ver")) {
1588 RegKind = SparcOperand::rk_Special;
1594 if (
name.equals(
"pcr")) {
1595 RegNo = Sparc::ASR16;
1596 RegKind = SparcOperand::rk_Special;
1599 if (
name.equals(
"pic")) {
1600 RegNo = Sparc::ASR17;
1601 RegKind = SparcOperand::rk_Special;
1604 if (
name.equals(
"dcr")) {
1605 RegNo = Sparc::ASR18;
1606 RegKind = SparcOperand::rk_Special;
1609 if (
name.equals(
"gsr")) {
1610 RegNo = Sparc::ASR19;
1611 RegKind = SparcOperand::rk_Special;
1614 if (
name.equals(
"softint")) {
1615 RegNo = Sparc::ASR22;
1616 RegKind = SparcOperand::rk_Special;
1619 if (
name.equals(
"tick_cmpr")) {
1620 RegNo = Sparc::ASR23;
1621 RegKind = SparcOperand::rk_Special;
1624 if (
name.equals(
"stick") ||
name.equals(
"sys_tick")) {
1625 RegNo = Sparc::ASR24;
1626 RegKind = SparcOperand::rk_Special;
1629 if (
name.equals(
"stick_cmpr") ||
name.equals(
"sys_tick_cmpr")) {
1630 RegNo = Sparc::ASR25;
1631 RegKind = SparcOperand::rk_Special;
1643 if (
const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1674 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1691bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
1702 Error(getLoc(),
"invalid operand modifier");
1730 EVal = adjustPICRelocation(VK, subExpr);
1740#define GET_REGISTER_MATCHER
1741#define GET_MATCHER_IMPLEMENTATION
1742#include "SparcGenAsmMatcher.inc"
1746 SparcOperand &
Op = (SparcOperand &)GOp;
1747 if (
Op.isFloatOrDoubleReg()) {
1751 if (!
Op.isFloatReg() || SparcOperand::MorphToDoubleReg(
Op))
1755 if (SparcOperand::MorphToQuadReg(
Op))
1760 if (
Op.isIntReg() && Kind == MCK_IntPair) {
1761 if (SparcOperand::MorphToIntPairReg(
Op))
1764 if (
Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1765 if (SparcOperand::MorphToCoprocPairReg(
Op))
1768 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
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]
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)
static constexpr uint32_t Opcode
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 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 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.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...