63 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
68#define GET_ASSEMBLER_HEADER
69#include "SparcGenAsmMatcher.inc"
74 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
77 bool MatchingInlineAsm)
override;
80 SMLoc &EndLoc)
override;
86 unsigned Kind)
override;
97 template <TailRelocKind Kind>
106 ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand);
117 bool isPossibleExpression(
const AsmToken &Token);
120 MatchResultTy mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
125 bool matchSparcAsmModifiers(
const MCExpr *&EVal,
SMLoc &EndLoc);
131 bool expandSET(MCInst &Inst, SMLoc IDLoc,
132 SmallVectorImpl<MCInst> &Instructions);
134 bool expandSETSW(MCInst &Inst, SMLoc IDLoc,
135 SmallVectorImpl<MCInst> &Instructions);
137 bool expandSETX(MCInst &Inst, SMLoc IDLoc,
138 SmallVectorImpl<MCInst> &Instructions);
140 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
143 SparcAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
144 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
145 : MCTargetAsmParser(
Options, sti, MII), Parser(parser),
147 Parser.addAliasForDirective(
".half",
".2byte");
148 Parser.addAliasForDirective(
".uahalf",
".2byte");
149 Parser.addAliasForDirective(
".word",
".4byte");
150 Parser.addAliasForDirective(
".uaword",
".4byte");
151 Parser.addAliasForDirective(
".nword",
is64Bit() ?
".8byte" :
".4byte");
153 Parser.addAliasForDirective(
".xword",
".8byte");
156 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
163 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
164 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
165 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
166 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
167 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
168 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
169 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
170 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
173 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
174 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
175 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
176 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
177 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
178 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
179 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
180 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
183 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
184 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
185 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
186 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
189 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
190 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
191 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
192 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
195 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
196 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
197 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
198 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
230 SMLoc StartLoc, EndLoc;
248 MCRegister OffsetReg;
262 SparcOperand(KindTy K) : Kind(
K) {}
264 bool isToken()
const override {
return Kind == k_Token; }
265 bool isReg()
const override {
return Kind == k_Register; }
266 bool isImm()
const override {
return Kind == k_Immediate; }
267 bool isMem()
const override {
return isMEMrr() || isMEMri(); }
268 bool isMEMrr()
const {
return Kind == k_MemoryReg; }
269 bool isMEMri()
const {
return Kind == k_MemoryImm; }
270 bool isMembarTag()
const {
return Kind == k_Immediate; }
271 bool isASITag()
const {
return Kind == k_ASITag; }
272 bool isPrefetchTag()
const {
return Kind == k_PrefetchTag; }
273 bool isTailRelocSym()
const {
return Kind == k_TailRelocSym; }
275 bool isCallTarget()
const {
280 return CE->getValue() % 4 == 0;
285 bool isShiftAmtImm5()
const {
295 bool isShiftAmtImm6()
const {
306 return (Kind == k_Register &&
Reg.Kind == rk_IntReg);
309 bool isFloatReg()
const {
310 return (Kind == k_Register &&
Reg.Kind == rk_FloatReg);
313 bool isFloatOrDoubleReg()
const {
314 return (Kind == k_Register && (
Reg.Kind == rk_FloatReg
315 ||
Reg.Kind == rk_DoubleReg));
318 bool isCoprocReg()
const {
319 return (Kind == k_Register &&
Reg.Kind == rk_CoprocReg);
323 assert(Kind == k_Token &&
"Invalid access!");
324 return StringRef(Tok.Data, Tok.Length);
327 MCRegister
getReg()
const override {
328 assert((Kind == k_Register) &&
"Invalid access!");
332 const MCExpr *
getImm()
const {
333 assert((Kind == k_Immediate) &&
"Invalid access!");
337 MCRegister getMemBase()
const {
338 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) &&
"Invalid access!");
342 MCRegister getMemOffsetReg()
const {
343 assert((Kind == k_MemoryReg) &&
"Invalid access!");
344 return Mem.OffsetReg;
347 const MCExpr *getMemOff()
const {
348 assert((Kind == k_MemoryImm) &&
"Invalid access!");
352 unsigned getASITag()
const {
353 assert((Kind == k_ASITag) &&
"Invalid access!");
357 unsigned getPrefetchTag()
const {
358 assert((Kind == k_PrefetchTag) &&
"Invalid access!");
362 const MCExpr *getTailRelocSym()
const {
363 assert((Kind == k_TailRelocSym) &&
"Invalid access!");
368 SMLoc getStartLoc()
const override {
372 SMLoc getEndLoc()
const override {
376 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
378 case k_Token: OS <<
"Token: " <<
getToken() <<
"\n";
break;
380 OS <<
"Reg: #" <<
getReg().id() <<
"\n";
382 case k_Immediate: OS <<
"Imm: " <<
getImm() <<
"\n";
break;
384 OS <<
"Mem: " << getMemBase().id() <<
"+" << getMemOffsetReg().id()
387 case k_MemoryImm:
assert(getMemOff() !=
nullptr);
388 OS <<
"Mem: " << getMemBase().id() <<
"+";
393 OS <<
"ASI tag: " << getASITag() <<
"\n";
396 OS <<
"Prefetch tag: " << getPrefetchTag() <<
"\n";
399 OS <<
"TailReloc: " << getTailRelocSym() <<
"\n";
404 void addRegOperands(MCInst &Inst,
unsigned N)
const {
405 assert(
N == 1 &&
"Invalid number of operands!");
409 void addImmOperands(MCInst &Inst,
unsigned N)
const {
410 assert(
N == 1 &&
"Invalid number of operands!");
411 const MCExpr *Expr =
getImm();
415 void addShiftAmtImm5Operands(MCInst &Inst,
unsigned N)
const {
416 assert(
N == 1 &&
"Invalid number of operands!");
419 void addShiftAmtImm6Operands(MCInst &Inst,
unsigned N)
const {
420 assert(
N == 1 &&
"Invalid number of operands!");
424 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const{
434 void addMEMrrOperands(MCInst &Inst,
unsigned N)
const {
435 assert(
N == 2 &&
"Invalid number of operands!");
443 void addMEMriOperands(MCInst &Inst,
unsigned N)
const {
444 assert(
N == 2 &&
"Invalid number of operands!");
448 const MCExpr *Expr = getMemOff();
452 void addASITagOperands(MCInst &Inst,
unsigned N)
const {
453 assert(
N == 1 &&
"Invalid number of operands!");
457 void addPrefetchTagOperands(MCInst &Inst,
unsigned N)
const {
458 assert(
N == 1 &&
"Invalid number of operands!");
462 void addMembarTagOperands(MCInst &Inst,
unsigned N)
const {
463 assert(
N == 1 &&
"Invalid number of operands!");
464 const MCExpr *Expr =
getImm();
469 assert(
N == 1 &&
"Invalid number of operands!");
473 void addTailRelocSymOperands(MCInst &Inst,
unsigned N)
const {
474 assert(
N == 1 &&
"Invalid number of operands!");
475 addExpr(Inst, getTailRelocSym());
478 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
479 auto Op = std::make_unique<SparcOperand>(k_Token);
480 Op->Tok.Data = Str.data();
481 Op->Tok.Length = Str.size();
487 static std::unique_ptr<SparcOperand> CreateReg(MCRegister
Reg,
unsigned Kind,
489 auto Op = std::make_unique<SparcOperand>(k_Register);
491 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
497 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val, SMLoc S,
499 auto Op = std::make_unique<SparcOperand>(k_Immediate);
506 static std::unique_ptr<SparcOperand> CreateASITag(
unsigned Val, SMLoc S,
508 auto Op = std::make_unique<SparcOperand>(k_ASITag);
515 static std::unique_ptr<SparcOperand> CreatePrefetchTag(
unsigned Val, SMLoc S,
517 auto Op = std::make_unique<SparcOperand>(k_PrefetchTag);
524 static std::unique_ptr<SparcOperand> CreateTailRelocSym(
const MCExpr *Val,
526 auto Op = std::make_unique<SparcOperand>(k_TailRelocSym);
533 static bool MorphToIntPairReg(SparcOperand &
Op) {
534 MCRegister
Reg =
Op.getReg();
536 unsigned regIdx = 32;
537 if (
Reg >= Sparc::G0 &&
Reg <= Sparc::G7)
538 regIdx =
Reg - Sparc::G0;
539 else if (
Reg >= Sparc::O0 &&
Reg <= Sparc::O7)
540 regIdx =
Reg - Sparc::O0 + 8;
541 else if (
Reg >= Sparc::L0 &&
Reg <= Sparc::L7)
542 regIdx =
Reg - Sparc::L0 + 16;
543 else if (
Reg >= Sparc::I0 &&
Reg <= Sparc::I7)
544 regIdx =
Reg - Sparc::I0 + 24;
545 if (regIdx % 2 || regIdx > 31)
548 Op.Reg.Kind = rk_IntPairReg;
552 static bool MorphToDoubleReg(SparcOperand &
Op) {
553 MCRegister
Reg =
Op.getReg();
555 unsigned regIdx =
Reg - Sparc::F0;
556 if (regIdx % 2 || regIdx > 31)
559 Op.Reg.Kind = rk_DoubleReg;
563 static bool MorphToQuadReg(SparcOperand &
Op) {
564 MCRegister
Reg =
Op.getReg();
566 switch (
Op.Reg.Kind) {
569 regIdx =
Reg - Sparc::F0;
570 if (regIdx % 4 || regIdx > 31)
575 regIdx =
Reg - Sparc::D0;
576 if (regIdx % 2 || regIdx > 31)
582 Op.Reg.Kind = rk_QuadReg;
586 static bool MorphToCoprocPairReg(SparcOperand &
Op) {
587 MCRegister
Reg =
Op.getReg();
588 assert(
Op.Reg.Kind == rk_CoprocReg);
589 unsigned regIdx = 32;
590 if (
Reg >= Sparc::C0 &&
Reg <= Sparc::C31)
591 regIdx =
Reg - Sparc::C0;
592 if (regIdx % 2 || regIdx > 31)
595 Op.Reg.Kind = rk_CoprocPairReg;
599 static std::unique_ptr<SparcOperand>
600 MorphToMEMrr(MCRegister
Base, std::unique_ptr<SparcOperand>
Op) {
601 MCRegister offsetReg =
Op->getReg();
602 Op->Kind = k_MemoryReg;
604 Op->Mem.OffsetReg = offsetReg;
605 Op->Mem.Off =
nullptr;
609 static std::unique_ptr<SparcOperand> CreateMEMr(MCRegister
Base, SMLoc S,
611 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
613 Op->Mem.OffsetReg = Sparc::G0;
614 Op->Mem.Off =
nullptr;
620 static std::unique_ptr<SparcOperand>
621 MorphToMEMri(MCRegister
Base, std::unique_ptr<SparcOperand>
Op) {
622 const MCExpr *
Imm =
Op->getImm();
623 Op->Kind = k_MemoryImm;
625 Op->Mem.OffsetReg = MCRegister();
633#define GET_MATCHER_IMPLEMENTATION
634#define GET_REGISTER_MATCHER
635#define GET_MNEMONIC_SPELL_CHECKER
636#include "SparcGenAsmMatcher.inc"
640SparcAsmParser::MatchResultTy
641SparcAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
646 const MatchEntry *Start, *End;
651 Start = std::begin(MatchTable0);
652 End = std::end(MatchTable0);
657 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
659 if (MnemonicRange.first == MnemonicRange.second)
660 return Match_MnemonicFail;
662 for (
const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
665 FeatureBitsets[it->RequiredFeaturesIdx];
666 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
667 return Match_Success;
669 return Match_MissingFeature;
672bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
673 SmallVectorImpl<MCInst> &Instructions) {
681 int64_t RawImmValue = IsImm ? MCValOp.
getImm() : 0;
684 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
686 "set: argument must be between -2147483648 and 4294967295");
691 int32_t ImmValue = RawImmValue;
695 bool IsEffectivelyImm13 =
696 IsImm && ((
is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
697 const MCExpr *ValExpr;
708 if (!IsEffectivelyImm13) {
710 const MCExpr *Expr = adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr);
729 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
732 if (IsEffectivelyImm13)
735 Expr = adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
746bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,
747 SmallVectorImpl<MCInst> &Instructions) {
755 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
759 bool IsSmallImm = IsImm &&
isInt<13>(ImmValue);
760 bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);
766 "set: argument must be between -2147483648 and 2147483647");
773 MCInstBuilder(SP::SETHIi)
775 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
781 if (!NoLowBitsImm || IsSmallImm) {
783 IsSmallImm ? ValExpr : adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
788 .addReg(PrevReg.getReg())
797 if (!IsImm || ImmValue < 0) {
808bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
809 SmallVectorImpl<MCInst> &Instructions) {
817 bool IsImm = MCValOp.
isImm();
818 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
837 MCInstBuilder(SP::SETHIi)
839 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
842 MCInstBuilder(SP::ORri)
845 .addExpr(adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr)));
875 .addReg(MCRegOp.
getReg()));
880bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
884 bool MatchingInlineAsm) {
887 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
889 switch (MatchResult) {
890 case Match_Success: {
897 if (expandSET(Inst, IDLoc, Instructions))
901 if (expandSETSW(Inst, IDLoc, Instructions))
905 if (expandSETX(Inst, IDLoc, Instructions))
910 for (
const MCInst &
I : Instructions) {
916 case Match_MissingFeature:
918 "instruction requires a CPU feature not currently enabled");
920 case Match_InvalidOperand: {
921 SMLoc ErrorLoc = IDLoc;
922 if (ErrorInfo != ~0ULL) {
923 if (ErrorInfo >= Operands.
size())
924 return Error(IDLoc,
"too few operands for instruction");
926 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
927 if (ErrorLoc == SMLoc())
931 return Error(ErrorLoc,
"invalid operand for instruction");
933 case Match_MnemonicFail:
934 return Error(IDLoc,
"invalid instruction mnemonic");
939bool SparcAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
941 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
942 return Error(StartLoc,
"invalid register name");
946ParseStatus SparcAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
948 const AsmToken &Tok = Parser.
getTok();
951 Reg = Sparc::NoRegister;
955 unsigned RegKind = SparcOperand::rk_None;
956 Reg = matchRegisterName(Tok, RegKind);
962 getLexer().UnLex(Tok);
966bool SparcAsmParser::parseInstruction(ParseInstructionInfo &
Info,
967 StringRef Name, SMLoc NameLoc,
978 MatchResultTy MS = mnemonicIsValid(Name, 0);
982 case Match_MissingFeature:
983 return Error(NameLoc,
984 "instruction requires a CPU feature not currently enabled");
985 case Match_MnemonicFail:
986 return Error(NameLoc,
987 "invalid instruction mnemonic" +
988 SparcMnemonicSpellCheck(Name, getAvailableFeatures(), 0));
994 Operands.
push_back(SparcOperand::CreateToken(Name, NameLoc));
1002 if (!parseBranchModifiers(Operands).isSuccess()) {
1003 SMLoc Loc = getLexer().getLoc();
1004 return Error(Loc,
"unexpected token");
1007 if (!parseOperand(Operands, Name).isSuccess()) {
1008 SMLoc Loc = getLexer().getLoc();
1009 return Error(Loc,
"unexpected token");
1019 if (!parseOperand(Operands, Name).isSuccess()) {
1020 SMLoc Loc = getLexer().getLoc();
1021 return Error(Loc,
"unexpected token");
1026 SMLoc Loc = getLexer().getLoc();
1027 return Error(Loc,
"unexpected token");
1033ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {
1034 StringRef IDVal = DirectiveID.
getString();
1036 if (IDVal ==
".register") {
1041 if (IDVal ==
".proc") {
1052ParseStatus SparcAsmParser::parseMEMOperand(
OperandVector &Operands) {
1055 std::unique_ptr<SparcOperand>
LHS;
1056 if (!parseSparcAsmOperand(
LHS).isSuccess())
1061 Operands.
push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(
LHS)));
1065 if (!
LHS->isIntReg())
1066 return Error(
LHS->getStartLoc(),
"invalid register kind for this operand");
1068 AsmToken Tok = getLexer().getTok();
1074 std::unique_ptr<SparcOperand>
RHS;
1075 if (!parseSparcAsmOperand(
RHS).isSuccess())
1078 if (
RHS->isReg() && !
RHS->isIntReg())
1080 "invalid register kind for this operand");
1084 ? SparcOperand::MorphToMEMri(
LHS->getReg(), std::move(
RHS))
1085 : SparcOperand::MorphToMEMrr(
LHS->getReg(), std::move(
RHS)));
1090 Operands.
push_back(SparcOperand::CreateMEMr(
LHS->getReg(), S,
E));
1094template <
unsigned N>
1095ParseStatus SparcAsmParser::parseShiftAmtImm(
OperandVector &Operands) {
1104 if (getParser().parseExpression(Expr))
1109 return Error(S,
"constant expression expected");
1112 return Error(S,
"immediate shift value out of range");
1114 Operands.
push_back(SparcOperand::CreateImm(Expr, S,
E));
1118template <SparcAsmParser::TailRelocKind Kind>
1119ParseStatus SparcAsmParser::parseTailRelocSym(
OperandVector &Operands) {
1123 auto MatchesKind = [](uint16_t RelType) ->
bool {
1125 case TailRelocKind::Load_GOT:
1128 return RelType == ELF::R_SPARC_GOTDATA_OP;
1129 case TailRelocKind::Add_TLS:
1133 case ELF::R_SPARC_TLS_GD_ADD:
1134 case ELF::R_SPARC_TLS_IE_ADD:
1135 case ELF::R_SPARC_TLS_LDM_ADD:
1136 case ELF::R_SPARC_TLS_LDO_ADD:
1141 case TailRelocKind::Load_TLS:
1145 case ELF::R_SPARC_TLS_IE_LD:
1146 case ELF::R_SPARC_TLS_IE_LDX:
1151 case TailRelocKind::Call_TLS:
1155 case ELF::R_SPARC_TLS_GD_CALL:
1156 case ELF::R_SPARC_TLS_LDM_CALL:
1168 const AsmToken Tok = Parser.
getTok();
1172 return Error(getLoc(),
"expected valid identifier for operand modifier");
1174 StringRef
Name = getParser().getTok().getIdentifier();
1177 return Error(getLoc(),
"invalid relocation specifier");
1179 if (!MatchesKind(RelType)) {
1181 getLexer().UnLex(Tok);
1187 return Error(getLoc(),
"expected '('");
1190 const MCExpr *SubExpr;
1191 if (getParser().parseParenExpression(SubExpr,
E))
1194 const MCExpr *Val = adjustPICRelocation(RelType, SubExpr);
1195 Operands.
push_back(SparcOperand::CreateTailRelocSym(Val, S,
E));
1199ParseStatus SparcAsmParser::parseMembarTag(
OperandVector &Operands) {
1204 std::unique_ptr<SparcOperand>
Mask;
1205 if (parseSparcAsmOperand(Mask).isSuccess()) {
1206 if (!
Mask->isImm() || !
Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1207 ImmVal < 0 || ImmVal > 127)
1208 return Error(S,
"invalid membar mask number");
1212 SMLoc TagStart = getLexer().getLoc();
1214 unsigned MaskVal = StringSwitch<unsigned>(Parser.
getTok().
getString())
1215 .Case(
"LoadLoad", 0x1)
1216 .Case(
"StoreLoad", 0x2)
1217 .Case(
"LoadStore", 0x4)
1218 .Case(
"StoreStore", 0x8)
1219 .Case(
"Lookaside", 0x10)
1220 .Case(
"MemIssue", 0x20)
1227 return Error(TagStart,
"unknown membar tag");
1237 Operands.
push_back(SparcOperand::CreateImm(EVal, S,
E));
1241ParseStatus SparcAsmParser::parseASITag(
OperandVector &Operands) {
1249 ParseStatus ParseExprStatus = parseExpression(ASIVal);
1251 return ParseExprStatus;
1254 return Error(S,
"invalid ASI number, must be between 0 and 255");
1256 Operands.
push_back(SparcOperand::CreateASITag(ASIVal, S,
E));
1262 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1265 const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName);
1267 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1271 return Error(TagStart,
"unknown ASI tag");
1275 Operands.
push_back(SparcOperand::CreateASITag(ASIVal, S,
E));
1279ParseStatus SparcAsmParser::parsePrefetchTag(
OperandVector &Operands) {
1282 int64_t PrefetchVal = 0;
1287 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1289 return ParseExprStatus;
1292 return Error(S,
"invalid prefetch number, must be between 0 and 31");
1294 Operands.
push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S,
E));
1298 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1301 const SparcPrefetchTag::PrefetchTag *PrefetchTag =
1302 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1306 return Error(TagStart,
"unknown prefetch tag");
1308 PrefetchVal = PrefetchTag->
Encoding;
1310 Operands.
push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S,
E));
1314ParseStatus SparcAsmParser::parseCallTarget(
OperandVector &Operands) {
1318 switch (getLexer().getKind()) {
1328 const MCExpr *DestValue;
1329 if (getParser().parseExpression(DestValue))
1332 Operands.
push_back(SparcOperand::CreateImm(DestValue, S,
E));
1336ParseStatus SparcAsmParser::parseOperand(
OperandVector &Operands,
1337 StringRef Mnemonic) {
1339 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
1349 Operands.
push_back(SparcOperand::CreateToken(
"[",
1353 if (Mnemonic ==
"cas" || Mnemonic ==
"casl" || Mnemonic ==
"casa" ||
1354 Mnemonic ==
"casx" || Mnemonic ==
"casxl" || Mnemonic ==
"casxa") {
1361 MCRegister
Reg = matchRegisterName(Parser.
getTok(), RegKind);
1367 Operands.
push_back(SparcOperand::CreateReg(
Reg, RegKind, S,
E));
1370 Res = parseMEMOperand(Operands);
1379 Operands.
push_back(SparcOperand::CreateToken(
"]",
1390 S,
"malformed ASI tag, must be a constant integer expression");
1393 const AsmToken Tok = Parser.
getTok();
1400 SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.
size() - 2];
1401 if (OldMemOp.isMEMrr()) {
1402 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1403 return Error(S,
"invalid operand for instruction");
1405 Operands[Operands.
size() - 2] = SparcOperand::MorphToMEMri(
1406 OldMemOp.getMemBase(),
1408 OldMemOp.getStartLoc(),
1409 OldMemOp.getEndLoc()));
1416 Operands.
push_back(SparcOperand::CreateToken(
"%asi", S));
1420 return Error(S,
"malformed ASI tag, must be %asi, a constant integer "
1421 "expression, or a named tag");
1428 return parseASITag(Operands);
1432 std::unique_ptr<SparcOperand>
Op;
1434 Res = parseSparcAsmOperand(
Op);
1445SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &
Op) {
1451 switch (getLexer().getKind()) {
1457 if (MCRegister
Reg = matchRegisterName(Parser.
getTok(), RegKind)) {
1461 if (
Reg == Sparc::ICC && Name ==
"xcc")
1462 Op = SparcOperand::CreateToken(
"%xcc", S);
1464 Op = SparcOperand::CreateReg(
Reg, RegKind, S,
E);
1467 if (matchSparcAsmModifiers(EVal,
E)) {
1469 Op = SparcOperand::CreateImm(EVal, S,
E);
1480 if (getParser().parseExpression(EVal,
E))
1483 Op = SparcOperand::CreateImm(EVal, S,
E);
1489ParseStatus SparcAsmParser::parseBranchModifiers(
OperandVector &Operands) {
1498 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
1499 Operands.
push_back(SparcOperand::CreateToken(modName,
1507ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1508 AsmToken Tok = getLexer().getTok();
1510 if (!isPossibleExpression(Tok))
1513 return getParser().parseAbsoluteExpression(Val);
1516MCRegister SparcAsmParser::matchRegisterName(
const AsmToken &Tok,
1517 unsigned &RegKind) {
1518 RegKind = SparcOperand::rk_None;
1520 return SP::NoRegister;
1534 if (
Reg == SP::ASR4 && Name ==
"tick") {
1535 RegKind = SparcOperand::rk_Special;
1539 if (
MRI.getRegClass(SP::IntRegsRegClassID).contains(
Reg)) {
1540 RegKind = SparcOperand::rk_IntReg;
1543 if (
MRI.getRegClass(SP::FPRegsRegClassID).contains(
Reg)) {
1544 RegKind = SparcOperand::rk_FloatReg;
1547 if (
MRI.getRegClass(SP::CoprocRegsRegClassID).contains(
Reg)) {
1548 RegKind = SparcOperand::rk_CoprocReg;
1553 if (
MRI.getRegClass(SP::IntPairRegClassID).contains(
Reg)) {
1554 RegKind = SparcOperand::rk_IntReg;
1555 return MRI.getSubReg(
Reg, SP::sub_even);
1559 if (
MRI.getRegClass(SP::DFPRegsRegClassID).contains(
Reg)) {
1561 if (MCRegister
SubReg =
MRI.getSubReg(
Reg, SP::sub_even)) {
1562 RegKind = SparcOperand::rk_FloatReg;
1565 RegKind = SparcOperand::rk_DoubleReg;
1571 assert(!
MRI.getRegClass(SP::QFPRegsRegClassID).contains(
Reg));
1574 if (
MRI.getRegClass(SP::CoprocPairRegClassID).contains(
Reg)) {
1575 RegKind = SparcOperand::rk_CoprocReg;
1576 return MRI.getSubReg(
Reg, SP::sub_even);
1580 RegKind = SparcOperand::rk_Special;
1589 if (
Name.starts_with_insensitive(
"r") &&
1590 !
Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {
1591 RegKind = SparcOperand::rk_IntReg;
1595 if (Name ==
"xcc") {
1597 RegKind = SparcOperand::rk_Special;
1603 if (Name ==
"pcr") {
1604 RegKind = SparcOperand::rk_Special;
1607 if (Name ==
"pic") {
1608 RegKind = SparcOperand::rk_Special;
1611 if (Name ==
"dcr") {
1612 RegKind = SparcOperand::rk_Special;
1615 if (Name ==
"gsr") {
1616 RegKind = SparcOperand::rk_Special;
1619 if (Name ==
"set_softint") {
1620 RegKind = SparcOperand::rk_Special;
1623 if (Name ==
"clear_softint") {
1624 RegKind = SparcOperand::rk_Special;
1627 if (Name ==
"softint") {
1628 RegKind = SparcOperand::rk_Special;
1631 if (Name ==
"tick_cmpr") {
1632 RegKind = SparcOperand::rk_Special;
1635 if (Name ==
"stick" || Name ==
"sys_tick") {
1636 RegKind = SparcOperand::rk_Special;
1639 if (Name ==
"stick_cmpr" || Name ==
"sys_tick_cmpr") {
1640 RegKind = SparcOperand::rk_Special;
1644 return SP::NoRegister;
1678const MCSpecifierExpr *
1679SparcAsmParser::adjustPICRelocation(uint16_t RelType,
const MCExpr *subExpr) {
1685 if (
getContext().getObjectFileInfo()->isPositionIndependent()) {
1688 case ELF::R_SPARC_LO10:
1692 case ELF::R_SPARC_HI22:
1702bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
1704 AsmToken Tok = Parser.
getTok();
1713 Error(getLoc(),
"invalid relocation specifier");
1716 case ELF::R_SPARC_GOTDATA_OP:
1717 case ELF::R_SPARC_TLS_GD_ADD:
1718 case ELF::R_SPARC_TLS_GD_CALL:
1719 case ELF::R_SPARC_TLS_IE_ADD:
1720 case ELF::R_SPARC_TLS_IE_LD:
1721 case ELF::R_SPARC_TLS_IE_LDX:
1722 case ELF::R_SPARC_TLS_LDM_ADD:
1723 case ELF::R_SPARC_TLS_LDM_CALL:
1724 case ELF::R_SPARC_TLS_LDO_ADD:
1737 const MCExpr *subExpr;
1741 EVal = adjustPICRelocation(VK, subExpr);
1745bool SparcAsmParser::isPossibleExpression(
const AsmToken &Token) {
1766unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1768 SparcOperand &
Op = (SparcOperand &)GOp;
1769 if (
Op.isFloatOrDoubleReg()) {
1773 if (!
Op.isFloatReg() || SparcOperand::MorphToDoubleReg(
Op))
1777 if (SparcOperand::MorphToQuadReg(
Op))
1782 if (
Op.isIntReg() && Kind == MCK_IntPair) {
1783 if (SparcOperand::MorphToIntPairReg(
Op))
1786 if (
Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1787 if (SparcOperand::MorphToCoprocPairReg(
Op))
1790 return Match_InvalidOperand;
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info, bool IsDynamicVGPRChainCall=false)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
loop data Loop Data Prefetch
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file defines the SmallVector class.
static const MCPhysReg DoubleRegs[32]
static bool hasGOTReference(const MCExpr *Expr)
static const MCPhysReg IntRegs[32]
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser()
static const MCPhysReg IntPairRegs[]
static const MCPhysReg QuadFPRegs[32]
static const MCPhysReg CoprocPairRegs[]
static bool is64Bit(const char *name)
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
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.
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
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.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Extension point for target-specific MCExpr subclasses with a relocation specifier,...
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
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.
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
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
bool isIntReg(MCRegister Reg)
MCExpr const & getExpr(MCExpr const &Expr)
uint16_t parseSpecifier(StringRef name)
@ CE
Windows NT (Windows on ARM)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Target & getTheSparcTarget()
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
Target & getTheSparcV9Target()
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Target & getTheSparcelTarget()
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...