64 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
69#define GET_ASSEMBLER_HEADER
70#include "SparcGenAsmMatcher.inc"
75 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
78 bool MatchingInlineAsm)
override;
81 SMLoc &EndLoc)
override;
85 bool parseExprWithSpecifier(
const MCExpr *&Res,
SMLoc &
E);
86 bool parseDataExpr(
const MCExpr *&Res)
override;
89 unsigned Kind)
override;
100 template <TailRelocKind Kind>
109 ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand);
120 bool isPossibleExpression(
const AsmToken &Token);
123 MatchResultTy mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
128 bool matchSparcAsmModifiers(
const MCExpr *&EVal,
SMLoc &EndLoc);
130 bool is64Bit()
const {
return getSTI().getTargetTriple().isSPARC64(); }
132 bool expandSET(MCInst &Inst, SMLoc IDLoc,
133 SmallVectorImpl<MCInst> &Instructions);
135 bool expandSETSW(MCInst &Inst, SMLoc IDLoc,
136 SmallVectorImpl<MCInst> &Instructions);
138 bool expandSETX(MCInst &Inst, SMLoc IDLoc,
139 SmallVectorImpl<MCInst> &Instructions);
141 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
144 SparcAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
145 const MCInstrInfo &MII)
146 : MCTargetAsmParser(sti, MII), Parser(parser),
148 Parser.addAliasForDirective(
".half",
".2byte");
149 Parser.addAliasForDirective(
".uahalf",
".2byte");
150 Parser.addAliasForDirective(
".word",
".4byte");
151 Parser.addAliasForDirective(
".uaword",
".4byte");
152 Parser.addAliasForDirective(
".nword",
is64Bit() ?
".8byte" :
".4byte");
154 Parser.addAliasForDirective(
".xword",
".8byte");
157 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
164 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
165 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
166 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
167 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
168 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
169 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
170 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
171 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
174 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
175 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
176 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
177 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
178 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
179 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
180 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
181 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
184 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
185 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
186 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
187 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
190 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
191 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
192 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
193 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
196 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
197 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
198 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
199 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
231 SMLoc StartLoc, EndLoc;
249 MCRegister OffsetReg;
263 SparcOperand(KindTy K) : Kind(
K) {}
265 bool isToken()
const override {
return Kind == k_Token; }
266 bool isReg()
const override {
return Kind == k_Register; }
267 bool isImm()
const override {
return Kind == k_Immediate; }
268 bool isMem()
const override {
return isMEMrr() || isMEMri(); }
269 bool isMEMrr()
const {
return Kind == k_MemoryReg; }
270 bool isMEMri()
const {
return Kind == k_MemoryImm; }
271 bool isMembarTag()
const {
return Kind == k_Immediate; }
272 bool isASITag()
const {
return Kind == k_ASITag; }
273 bool isPrefetchTag()
const {
return Kind == k_PrefetchTag; }
274 bool isTailRelocSym()
const {
return Kind == k_TailRelocSym; }
276 bool isCallTarget()
const {
281 return CE->getValue() % 4 == 0;
286 bool isShiftAmtImm5()
const {
296 bool isShiftAmtImm6()
const {
307 return (Kind == k_Register &&
Reg.Kind == rk_IntReg);
310 bool isFloatReg()
const {
311 return (Kind == k_Register &&
Reg.Kind == rk_FloatReg);
314 bool isFloatOrDoubleReg()
const {
315 return (Kind == k_Register && (
Reg.Kind == rk_FloatReg
316 ||
Reg.Kind == rk_DoubleReg));
319 bool isCoprocReg()
const {
320 return (Kind == k_Register &&
Reg.Kind == rk_CoprocReg);
324 assert(Kind == k_Token &&
"Invalid access!");
325 return StringRef(Tok.Data, Tok.Length);
328 MCRegister
getReg()
const override {
329 assert((Kind == k_Register) &&
"Invalid access!");
333 const MCExpr *
getImm()
const {
334 assert((Kind == k_Immediate) &&
"Invalid access!");
338 MCRegister getMemBase()
const {
339 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) &&
"Invalid access!");
343 MCRegister getMemOffsetReg()
const {
344 assert((Kind == k_MemoryReg) &&
"Invalid access!");
345 return Mem.OffsetReg;
348 const MCExpr *getMemOff()
const {
349 assert((Kind == k_MemoryImm) &&
"Invalid access!");
353 unsigned getASITag()
const {
354 assert((Kind == k_ASITag) &&
"Invalid access!");
358 unsigned getPrefetchTag()
const {
359 assert((Kind == k_PrefetchTag) &&
"Invalid access!");
363 const MCExpr *getTailRelocSym()
const {
364 assert((Kind == k_TailRelocSym) &&
"Invalid access!");
369 SMLoc getStartLoc()
const override {
373 SMLoc getEndLoc()
const override {
377 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
379 case k_Token: OS <<
"Token: " <<
getToken() <<
"\n";
break;
381 OS <<
"Reg: #" <<
getReg().
id() <<
"\n";
383 case k_Immediate: OS <<
"Imm: " <<
getImm() <<
"\n";
break;
385 OS <<
"Mem: " << getMemBase().id() <<
"+" << getMemOffsetReg().id()
388 case k_MemoryImm:
assert(getMemOff() !=
nullptr);
389 OS <<
"Mem: " << getMemBase().id() <<
"+";
394 OS <<
"ASI tag: " << getASITag() <<
"\n";
397 OS <<
"Prefetch tag: " << getPrefetchTag() <<
"\n";
400 OS <<
"TailReloc: " << getTailRelocSym() <<
"\n";
405 void addRegOperands(MCInst &Inst,
unsigned N)
const {
406 assert(
N == 1 &&
"Invalid number of operands!");
410 void addImmOperands(MCInst &Inst,
unsigned N)
const {
411 assert(
N == 1 &&
"Invalid number of operands!");
412 const MCExpr *Expr =
getImm();
416 void addShiftAmtImm5Operands(MCInst &Inst,
unsigned N)
const {
417 assert(
N == 1 &&
"Invalid number of operands!");
420 void addShiftAmtImm6Operands(MCInst &Inst,
unsigned N)
const {
421 assert(
N == 1 &&
"Invalid number of operands!");
425 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const{
435 void addMEMrrOperands(MCInst &Inst,
unsigned N)
const {
436 assert(
N == 2 &&
"Invalid number of operands!");
444 void addMEMriOperands(MCInst &Inst,
unsigned N)
const {
445 assert(
N == 2 &&
"Invalid number of operands!");
449 const MCExpr *Expr = getMemOff();
453 void addASITagOperands(MCInst &Inst,
unsigned N)
const {
454 assert(
N == 1 &&
"Invalid number of operands!");
458 void addPrefetchTagOperands(MCInst &Inst,
unsigned N)
const {
459 assert(
N == 1 &&
"Invalid number of operands!");
463 void addMembarTagOperands(MCInst &Inst,
unsigned N)
const {
464 assert(
N == 1 &&
"Invalid number of operands!");
465 const MCExpr *Expr =
getImm();
470 assert(
N == 1 &&
"Invalid number of operands!");
474 void addTailRelocSymOperands(MCInst &Inst,
unsigned N)
const {
475 assert(
N == 1 &&
"Invalid number of operands!");
476 addExpr(Inst, getTailRelocSym());
479 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
480 auto Op = std::make_unique<SparcOperand>(k_Token);
481 Op->Tok.Data = Str.data();
482 Op->Tok.Length = Str.size();
488 static std::unique_ptr<SparcOperand> CreateReg(MCRegister
Reg,
unsigned Kind,
490 auto Op = std::make_unique<SparcOperand>(k_Register);
492 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
498 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val, SMLoc S,
500 auto Op = std::make_unique<SparcOperand>(k_Immediate);
507 static std::unique_ptr<SparcOperand> CreateASITag(
unsigned Val, SMLoc S,
509 auto Op = std::make_unique<SparcOperand>(k_ASITag);
516 static std::unique_ptr<SparcOperand> CreatePrefetchTag(
unsigned Val, SMLoc S,
518 auto Op = std::make_unique<SparcOperand>(k_PrefetchTag);
525 static std::unique_ptr<SparcOperand> CreateTailRelocSym(
const MCExpr *Val,
527 auto Op = std::make_unique<SparcOperand>(k_TailRelocSym);
534 static bool MorphToIntPairReg(SparcOperand &
Op) {
535 MCRegister
Reg =
Op.getReg();
537 unsigned regIdx = 32;
538 if (
Reg >= Sparc::G0 &&
Reg <= Sparc::G7)
539 regIdx =
Reg - Sparc::G0;
540 else if (
Reg >= Sparc::O0 &&
Reg <= Sparc::O7)
541 regIdx =
Reg - Sparc::O0 + 8;
542 else if (
Reg >= Sparc::L0 &&
Reg <= Sparc::L7)
543 regIdx =
Reg - Sparc::L0 + 16;
544 else if (
Reg >= Sparc::I0 &&
Reg <= Sparc::I7)
545 regIdx =
Reg - Sparc::I0 + 24;
546 if (regIdx % 2 || regIdx > 31)
549 Op.Reg.Kind = rk_IntPairReg;
553 static bool MorphToDoubleReg(SparcOperand &
Op) {
554 MCRegister
Reg =
Op.getReg();
556 unsigned regIdx =
Reg - Sparc::F0;
557 if (regIdx % 2 || regIdx > 31)
560 Op.Reg.Kind = rk_DoubleReg;
564 static bool MorphToQuadReg(SparcOperand &
Op) {
565 MCRegister
Reg =
Op.getReg();
567 switch (
Op.Reg.Kind) {
570 regIdx =
Reg - Sparc::F0;
571 if (regIdx % 4 || regIdx > 31)
576 regIdx =
Reg - Sparc::D0;
577 if (regIdx % 2 || regIdx > 31)
583 Op.Reg.Kind = rk_QuadReg;
587 static bool MorphToCoprocPairReg(SparcOperand &
Op) {
588 MCRegister
Reg =
Op.getReg();
589 assert(
Op.Reg.Kind == rk_CoprocReg);
590 unsigned regIdx = 32;
591 if (
Reg >= Sparc::C0 &&
Reg <= Sparc::C31)
592 regIdx =
Reg - Sparc::C0;
593 if (regIdx % 2 || regIdx > 31)
596 Op.Reg.Kind = rk_CoprocPairReg;
600 static std::unique_ptr<SparcOperand>
601 MorphToMEMrr(MCRegister
Base, std::unique_ptr<SparcOperand>
Op) {
602 MCRegister offsetReg =
Op->getReg();
603 Op->Kind = k_MemoryReg;
605 Op->Mem.OffsetReg = offsetReg;
606 Op->Mem.Off =
nullptr;
610 static std::unique_ptr<SparcOperand> CreateMEMr(MCRegister
Base, SMLoc S,
612 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
614 Op->Mem.OffsetReg = Sparc::G0;
615 Op->Mem.Off =
nullptr;
621 static std::unique_ptr<SparcOperand>
622 MorphToMEMri(MCRegister
Base, std::unique_ptr<SparcOperand>
Op) {
623 const MCExpr *
Imm =
Op->getImm();
624 Op->Kind = k_MemoryImm;
626 Op->Mem.OffsetReg = MCRegister();
634#define GET_MATCHER_IMPLEMENTATION
635#define GET_REGISTER_MATCHER
636#define GET_MNEMONIC_SPELL_CHECKER
637#include "SparcGenAsmMatcher.inc"
641SparcAsmParser::MatchResultTy
642SparcAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
647 const MatchEntry *Start, *End;
652 Start = std::begin(MatchTable0);
653 End = std::end(MatchTable0);
658 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
660 if (MnemonicRange.first == MnemonicRange.second)
661 return Match_MnemonicFail;
663 for (
const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
666 FeatureBitsets[it->RequiredFeaturesIdx];
667 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
668 return Match_Success;
670 return Match_MissingFeature;
673bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
674 SmallVectorImpl<MCInst> &Instructions) {
682 int64_t RawImmValue = IsImm ? MCValOp.
getImm() : 0;
685 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
687 "set: argument must be between -2147483648 and 4294967295");
692 int32_t ImmValue = RawImmValue;
696 bool IsEffectivelyImm13 =
697 IsImm && ((
is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
698 const MCExpr *ValExpr;
709 if (!IsEffectivelyImm13) {
711 const MCExpr *Expr = adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr);
730 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
733 if (IsEffectivelyImm13)
736 Expr = adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
747bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,
748 SmallVectorImpl<MCInst> &Instructions) {
756 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
760 bool IsSmallImm = IsImm &&
isInt<13>(ImmValue);
761 bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);
767 "set: argument must be between -2147483648 and 2147483647");
774 MCInstBuilder(SP::SETHIi)
776 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
782 if (!NoLowBitsImm || IsSmallImm) {
784 IsSmallImm ? ValExpr : adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
789 .addReg(PrevReg.getReg())
798 if (!IsImm || ImmValue < 0) {
809bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
810 SmallVectorImpl<MCInst> &Instructions) {
818 bool IsImm = MCValOp.
isImm();
819 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
838 MCInstBuilder(SP::SETHIi)
840 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
843 MCInstBuilder(SP::ORri)
846 .addExpr(adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr)));
876 .addReg(MCRegOp.
getReg()));
881bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
885 bool MatchingInlineAsm) {
888 unsigned MatchResult = MatchInstructionImpl(
Operands, Inst, ErrorInfo,
890 switch (MatchResult) {
891 case Match_Success: {
898 if (expandSET(Inst, IDLoc, Instructions))
902 if (expandSETSW(Inst, IDLoc, Instructions))
906 if (expandSETX(Inst, IDLoc, Instructions))
911 for (
const MCInst &
I : Instructions) {
912 Out.emitInstruction(
I, getSTI());
917 case Match_MissingFeature:
919 "instruction requires a CPU feature not currently enabled");
921 case Match_InvalidOperand: {
922 SMLoc ErrorLoc = IDLoc;
923 if (ErrorInfo != ~0ULL) {
925 return Error(IDLoc,
"too few operands for instruction");
927 ErrorLoc = ((SparcOperand &)*
Operands[ErrorInfo]).getStartLoc();
928 if (ErrorLoc == SMLoc())
932 return Error(ErrorLoc,
"invalid operand for instruction");
934 case Match_MnemonicFail:
935 return Error(IDLoc,
"invalid instruction mnemonic");
940bool SparcAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
942 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
943 return Error(StartLoc,
"invalid register name");
947ParseStatus SparcAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
949 const AsmToken &Tok = Parser.
getTok();
952 Reg = Sparc::NoRegister;
956 unsigned RegKind = SparcOperand::rk_None;
963 getLexer().UnLex(Tok);
967bool SparcAsmParser::parseInstruction(ParseInstructionInfo &Info,
968 StringRef Name, SMLoc NameLoc,
979 MatchResultTy MS = mnemonicIsValid(Name, 0);
983 case Match_MissingFeature:
984 return Error(NameLoc,
985 "instruction requires a CPU feature not currently enabled");
986 case Match_MnemonicFail:
987 return Error(NameLoc,
988 "invalid instruction mnemonic" +
989 SparcMnemonicSpellCheck(Name, getAvailableFeatures(), 0));
995 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
1003 if (!parseBranchModifiers(
Operands).isSuccess()) {
1004 SMLoc Loc = getLexer().getLoc();
1005 return Error(Loc,
"unexpected token");
1008 if (!parseOperand(
Operands, Name).isSuccess()) {
1009 SMLoc Loc = getLexer().getLoc();
1010 return Error(Loc,
"unexpected token");
1020 if (!parseOperand(
Operands, Name).isSuccess()) {
1021 SMLoc Loc = getLexer().getLoc();
1022 return Error(Loc,
"unexpected token");
1027 SMLoc Loc = getLexer().getLoc();
1028 return Error(Loc,
"unexpected token");
1034ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {
1035 StringRef IDVal = DirectiveID.
getString();
1037 if (IDVal ==
".register") {
1042 if (IDVal ==
".proc") {
1048 if (IDVal ==
".seg") {
1054 uint32_t Subsection = 0;
1055 const MCObjectFileInfo *MCOFI =
getContext().getObjectFileInfo();
1056 if (Name ==
"text") {
1058 }
else if (Name ==
"data" || Name ==
"data1") {
1060 Subsection =
Name ==
"data1" ? 1 : 0;
1061 }
else if (Name ==
"bss") {
1064 return Error(DirectiveID.
getLoc(),
"unknown segment type");
1066 getStreamer().switchSection(Section, Subsection);
1077 std::unique_ptr<SparcOperand>
LHS;
1078 if (!parseSparcAsmOperand(
LHS).isSuccess())
1083 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(
LHS)));
1087 if (!
LHS->isIntReg())
1088 return Error(
LHS->getStartLoc(),
"invalid register kind for this operand");
1090 AsmToken Tok = getLexer().getTok();
1096 std::unique_ptr<SparcOperand>
RHS;
1097 if (!parseSparcAsmOperand(
RHS).isSuccess())
1100 if (
RHS->isReg() && !
RHS->isIntReg())
1102 "invalid register kind for this operand");
1106 ? SparcOperand::MorphToMEMri(
LHS->getReg(), std::move(
RHS))
1107 : SparcOperand::MorphToMEMrr(
LHS->getReg(), std::move(
RHS)));
1112 Operands.push_back(SparcOperand::CreateMEMr(
LHS->getReg(), S,
E));
1116template <
unsigned N>
1126 if (getParser().parseExpression(Expr))
1131 return Error(S,
"constant expression expected");
1134 return Error(S,
"immediate shift value out of range");
1136 Operands.push_back(SparcOperand::CreateImm(Expr, S,
E));
1140template <SparcAsmParser::TailRelocKind Kind>
1145 auto MatchesKind = [](uint16_t RelType) ->
bool {
1147 case TailRelocKind::Load_GOT:
1150 return RelType == ELF::R_SPARC_GOTDATA_OP;
1151 case TailRelocKind::Add_TLS:
1155 case ELF::R_SPARC_TLS_GD_ADD:
1156 case ELF::R_SPARC_TLS_IE_ADD:
1157 case ELF::R_SPARC_TLS_LDM_ADD:
1158 case ELF::R_SPARC_TLS_LDO_ADD:
1163 case TailRelocKind::Load_TLS:
1167 case ELF::R_SPARC_TLS_IE_LD:
1168 case ELF::R_SPARC_TLS_IE_LDX:
1173 case TailRelocKind::Call_TLS:
1177 case ELF::R_SPARC_TLS_GD_CALL:
1178 case ELF::R_SPARC_TLS_LDM_CALL:
1190 const AsmToken Tok = Parser.
getTok();
1194 return Error(getLoc(),
"expected valid identifier for operand modifier");
1196 StringRef
Name = getParser().getTok().getIdentifier();
1199 return Error(getLoc(),
"invalid relocation specifier");
1201 if (!MatchesKind(RelType)) {
1203 getLexer().UnLex(Tok);
1209 return Error(getLoc(),
"expected '('");
1212 const MCExpr *SubExpr;
1213 if (getParser().parseParenExpression(SubExpr,
E))
1216 const MCExpr *Val = adjustPICRelocation(RelType, SubExpr);
1217 Operands.push_back(SparcOperand::CreateTailRelocSym(Val, S,
E));
1226 std::unique_ptr<SparcOperand>
Mask;
1227 if (parseSparcAsmOperand(Mask).isSuccess()) {
1228 if (!
Mask->isImm() || !
Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1229 ImmVal < 0 || ImmVal > 127)
1230 return Error(S,
"invalid membar mask number");
1234 SMLoc TagStart = getLexer().getLoc();
1236 unsigned MaskVal = StringSwitch<unsigned>(Parser.
getTok().
getString())
1237 .Case(
"LoadLoad", 0x1)
1238 .Case(
"StoreLoad", 0x2)
1239 .Case(
"LoadStore", 0x4)
1240 .Case(
"StoreStore", 0x8)
1241 .Case(
"Lookaside", 0x10)
1242 .Case(
"MemIssue", 0x20)
1249 return Error(TagStart,
"unknown membar tag");
1259 Operands.push_back(SparcOperand::CreateImm(EVal, S,
E));
1271 ParseStatus ParseExprStatus = parseExpression(ASIVal);
1273 return ParseExprStatus;
1276 return Error(S,
"invalid ASI number, must be between 0 and 255");
1278 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S,
E));
1284 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1287 const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName);
1289 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1293 return Error(TagStart,
"unknown ASI tag");
1297 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S,
E));
1304 int64_t PrefetchVal = 0;
1309 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1311 return ParseExprStatus;
1314 return Error(S,
"invalid prefetch number, must be between 0 and 31");
1316 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S,
E));
1320 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1323 const SparcPrefetchTag::PrefetchTag *PrefetchTag =
1324 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1328 return Error(TagStart,
"unknown prefetch tag");
1330 PrefetchVal = PrefetchTag->
Encoding;
1332 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S,
E));
1340 switch (getLexer().getKind()) {
1350 const MCExpr *DestValue;
1351 if (getParser().parseExpression(DestValue))
1354 Operands.push_back(SparcOperand::CreateImm(DestValue, S,
E));
1359 StringRef Mnemonic) {
1361 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic);
1371 Operands.push_back(SparcOperand::CreateToken(
"[",
1375 if (Mnemonic ==
"cas" || Mnemonic ==
"casl" || Mnemonic ==
"casa" ||
1376 Mnemonic ==
"casx" || Mnemonic ==
"casxl" || Mnemonic ==
"casxa") {
1389 Operands.push_back(SparcOperand::CreateReg(
Reg, RegKind, S,
E));
1401 Operands.push_back(SparcOperand::CreateToken(
"]",
1412 S,
"malformed ASI tag, must be a constant integer expression");
1415 const AsmToken Tok = Parser.
getTok();
1423 if (OldMemOp.isMEMrr()) {
1424 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1425 return Error(S,
"invalid operand for instruction");
1428 OldMemOp.getMemBase(),
1430 OldMemOp.getStartLoc(),
1431 OldMemOp.getEndLoc()));
1438 Operands.push_back(SparcOperand::CreateToken(
"%asi", S));
1442 return Error(S,
"malformed ASI tag, must be %asi, a constant integer "
1443 "expression, or a named tag");
1454 std::unique_ptr<SparcOperand>
Op;
1456 Res = parseSparcAsmOperand(
Op);
1467SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &
Op) {
1473 switch (getLexer().getKind()) {
1487 if (
Reg == Sparc::ICC && Name ==
"xcc")
1488 Op = SparcOperand::CreateToken(
"%xcc", S);
1490 Op = SparcOperand::CreateReg(
Reg, RegKind, S,
E);
1493 if (matchSparcAsmModifiers(EVal,
E)) {
1495 Op = SparcOperand::CreateImm(EVal, S,
E);
1507 if (getParser().parseExpression(EVal,
E))
1510 Op = SparcOperand::CreateImm(EVal, S,
E);
1525 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
1526 Operands.push_back(SparcOperand::CreateToken(modName,
1534ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1535 AsmToken Tok = getLexer().getTok();
1537 if (!isPossibleExpression(Tok))
1540 return getParser().parseAbsoluteExpression(Val);
1543MCRegister SparcAsmParser::matchRegisterName(
const AsmToken &Tok,
1544 unsigned &RegKind) {
1545 RegKind = SparcOperand::rk_None;
1547 return SP::NoRegister;
1561 if (
Reg == SP::ASR4 && Name ==
"tick") {
1562 RegKind = SparcOperand::rk_Special;
1567 RegKind = SparcOperand::rk_IntReg;
1571 RegKind = SparcOperand::rk_FloatReg;
1575 RegKind = SparcOperand::rk_CoprocReg;
1581 RegKind = SparcOperand::rk_IntReg;
1588 if (MCRegister SubReg = MRI.
getSubReg(
Reg, SP::sub_even)) {
1589 RegKind = SparcOperand::rk_FloatReg;
1592 RegKind = SparcOperand::rk_DoubleReg;
1602 RegKind = SparcOperand::rk_CoprocReg;
1607 RegKind = SparcOperand::rk_Special;
1616 if (
Name.starts_with_insensitive(
"r") &&
1617 !
Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo <= 31) {
1618 RegKind = SparcOperand::rk_IntReg;
1622 if (Name ==
"xcc" || Name ==
"ncc") {
1624 RegKind = SparcOperand::rk_Special;
1630 if (Name ==
"pcr") {
1631 RegKind = SparcOperand::rk_Special;
1634 if (Name ==
"pic") {
1635 RegKind = SparcOperand::rk_Special;
1638 if (Name ==
"dcr") {
1639 RegKind = SparcOperand::rk_Special;
1642 if (Name ==
"gsr") {
1643 RegKind = SparcOperand::rk_Special;
1646 if (Name ==
"set_softint") {
1647 RegKind = SparcOperand::rk_Special;
1650 if (Name ==
"clear_softint") {
1651 RegKind = SparcOperand::rk_Special;
1654 if (Name ==
"softint") {
1655 RegKind = SparcOperand::rk_Special;
1658 if (Name ==
"tick_cmpr") {
1659 RegKind = SparcOperand::rk_Special;
1662 if (Name ==
"stick" || Name ==
"sys_tick") {
1663 RegKind = SparcOperand::rk_Special;
1666 if (Name ==
"stick_cmpr" || Name ==
"sys_tick_cmpr") {
1667 RegKind = SparcOperand::rk_Special;
1671 return SP::NoRegister;
1705const MCSpecifierExpr *
1706SparcAsmParser::adjustPICRelocation(uint16_t RelType,
const MCExpr *subExpr) {
1712 if (
getContext().getObjectFileInfo()->isPositionIndependent()) {
1715 case ELF::R_SPARC_LO10:
1719 case ELF::R_SPARC_HI22:
1729bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
1731 AsmToken Tok = Parser.
getTok();
1740 Error(getLoc(),
"invalid relocation specifier");
1743 case ELF::R_SPARC_GOTDATA_OP:
1744 case ELF::R_SPARC_TLS_GD_ADD:
1745 case ELF::R_SPARC_TLS_GD_CALL:
1746 case ELF::R_SPARC_TLS_IE_ADD:
1747 case ELF::R_SPARC_TLS_IE_LD:
1748 case ELF::R_SPARC_TLS_IE_LDX:
1749 case ELF::R_SPARC_TLS_LDM_ADD:
1750 case ELF::R_SPARC_TLS_LDM_CALL:
1751 case ELF::R_SPARC_TLS_LDO_ADD:
1764 const MCExpr *subExpr;
1768 EVal = adjustPICRelocation(VK, subExpr);
1772bool SparcAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
1773 SMLoc Loc = getLoc();
1775 return TokError(
"expected '%' relocation specifier");
1778 return TokError(
"invalid relocation specifier");
1784 const MCExpr *SubExpr;
1791bool SparcAsmParser::parseDataExpr(
const MCExpr *&Res) {
1794 return parseExprWithSpecifier(Res, EndLoc);
1798bool SparcAsmParser::isPossibleExpression(
const AsmToken &Token) {
1819unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1821 SparcOperand &
Op = (SparcOperand &)GOp;
1822 if (
Op.isFloatOrDoubleReg()) {
1826 if (!
Op.isFloatReg() || SparcOperand::MorphToDoubleReg(
Op))
1830 if (SparcOperand::MorphToQuadReg(
Op))
1835 if (
Op.isIntReg() && Kind == MCK_IntPair) {
1836 if (SparcOperand::MorphToIntPairReg(
Op))
1839 if (
Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1840 if (SparcOperand::MorphToCoprocPairReg(
Op))
1843 return Match_InvalidOperand;
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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")
#define LLVM_EXTERNAL_VISIBILITY
loop data Loop Data Prefetch
static MCRegister 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_>.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
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.
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
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
MCSection * getBSSSection() const
MCSection * getTextSection() const
MCSection * getDataSection() 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.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
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.
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
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.
bool isIntReg(MCRegister Reg)
MCExpr const & getExpr(MCExpr const &Expr)
MCRegister matchRegisterName(StringRef Name, const MCRegisterInfo &MRI, unsigned RegClassID, unsigned AltIdx)
Match a symbolic name in RegClassID, or return an invalid register.
uint16_t parseSpecifier(StringRef name)
uint16_t parseDataSpecifier(StringRef name)
@ CE
Windows NT (Windows on ARM)
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,...