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);
134 bool expandSET(MCInst &Inst, SMLoc IDLoc,
135 SmallVectorImpl<MCInst> &Instructions);
137 bool expandSETSW(MCInst &Inst, SMLoc IDLoc,
138 SmallVectorImpl<MCInst> &Instructions);
140 bool expandSETX(MCInst &Inst, SMLoc IDLoc,
141 SmallVectorImpl<MCInst> &Instructions);
143 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
146 SparcAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
147 const MCInstrInfo &MII)
148 : MCTargetAsmParser(sti, MII), Parser(parser),
150 Parser.addAliasForDirective(
".half",
".2byte");
151 Parser.addAliasForDirective(
".uahalf",
".2byte");
152 Parser.addAliasForDirective(
".word",
".4byte");
153 Parser.addAliasForDirective(
".uaword",
".4byte");
154 Parser.addAliasForDirective(
".nword",
is64Bit() ?
".8byte" :
".4byte");
156 Parser.addAliasForDirective(
".xword",
".8byte");
159 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
166 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
167 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
168 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
169 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
170 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
171 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
172 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
173 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
176 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
177 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
178 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
179 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
180 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
181 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
182 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
183 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
186 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
187 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
188 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
189 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
192 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
193 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
194 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
195 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
198 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
199 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
200 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
201 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
233 SMLoc StartLoc, EndLoc;
251 MCRegister OffsetReg;
265 SparcOperand(KindTy K) : Kind(
K) {}
267 bool isToken()
const override {
return Kind == k_Token; }
268 bool isReg()
const override {
return Kind == k_Register; }
269 bool isImm()
const override {
return Kind == k_Immediate; }
270 bool isMem()
const override {
return isMEMrr() || isMEMri(); }
271 bool isMEMrr()
const {
return Kind == k_MemoryReg; }
272 bool isMEMri()
const {
return Kind == k_MemoryImm; }
273 bool isMembarTag()
const {
return Kind == k_Immediate; }
274 bool isASITag()
const {
return Kind == k_ASITag; }
275 bool isPrefetchTag()
const {
return Kind == k_PrefetchTag; }
276 bool isTailRelocSym()
const {
return Kind == k_TailRelocSym; }
278 bool isCallTarget()
const {
283 return CE->getValue() % 4 == 0;
288 bool isShiftAmtImm5()
const {
298 bool isShiftAmtImm6()
const {
309 return (Kind == k_Register &&
Reg.Kind == rk_IntReg);
312 bool isFloatReg()
const {
313 return (Kind == k_Register &&
Reg.Kind == rk_FloatReg);
316 bool isFloatOrDoubleReg()
const {
317 return (Kind == k_Register && (
Reg.Kind == rk_FloatReg
318 ||
Reg.Kind == rk_DoubleReg));
321 bool isCoprocReg()
const {
322 return (Kind == k_Register &&
Reg.Kind == rk_CoprocReg);
326 assert(Kind == k_Token &&
"Invalid access!");
327 return StringRef(Tok.Data, Tok.Length);
330 MCRegister
getReg()
const override {
331 assert((Kind == k_Register) &&
"Invalid access!");
335 const MCExpr *
getImm()
const {
336 assert((Kind == k_Immediate) &&
"Invalid access!");
340 MCRegister getMemBase()
const {
341 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) &&
"Invalid access!");
345 MCRegister getMemOffsetReg()
const {
346 assert((Kind == k_MemoryReg) &&
"Invalid access!");
347 return Mem.OffsetReg;
350 const MCExpr *getMemOff()
const {
351 assert((Kind == k_MemoryImm) &&
"Invalid access!");
355 unsigned getASITag()
const {
356 assert((Kind == k_ASITag) &&
"Invalid access!");
360 unsigned getPrefetchTag()
const {
361 assert((Kind == k_PrefetchTag) &&
"Invalid access!");
365 const MCExpr *getTailRelocSym()
const {
366 assert((Kind == k_TailRelocSym) &&
"Invalid access!");
371 SMLoc getStartLoc()
const override {
375 SMLoc getEndLoc()
const override {
379 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
381 case k_Token: OS <<
"Token: " <<
getToken() <<
"\n";
break;
383 OS <<
"Reg: #" <<
getReg().
id() <<
"\n";
385 case k_Immediate: OS <<
"Imm: " <<
getImm() <<
"\n";
break;
387 OS <<
"Mem: " << getMemBase().id() <<
"+" << getMemOffsetReg().id()
390 case k_MemoryImm:
assert(getMemOff() !=
nullptr);
391 OS <<
"Mem: " << getMemBase().id() <<
"+";
396 OS <<
"ASI tag: " << getASITag() <<
"\n";
399 OS <<
"Prefetch tag: " << getPrefetchTag() <<
"\n";
402 OS <<
"TailReloc: " << getTailRelocSym() <<
"\n";
407 void addRegOperands(MCInst &Inst,
unsigned N)
const {
408 assert(
N == 1 &&
"Invalid number of operands!");
412 void addImmOperands(MCInst &Inst,
unsigned N)
const {
413 assert(
N == 1 &&
"Invalid number of operands!");
414 const MCExpr *Expr =
getImm();
418 void addShiftAmtImm5Operands(MCInst &Inst,
unsigned N)
const {
419 assert(
N == 1 &&
"Invalid number of operands!");
422 void addShiftAmtImm6Operands(MCInst &Inst,
unsigned N)
const {
423 assert(
N == 1 &&
"Invalid number of operands!");
427 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const{
437 void addMEMrrOperands(MCInst &Inst,
unsigned N)
const {
438 assert(
N == 2 &&
"Invalid number of operands!");
446 void addMEMriOperands(MCInst &Inst,
unsigned N)
const {
447 assert(
N == 2 &&
"Invalid number of operands!");
451 const MCExpr *Expr = getMemOff();
455 void addASITagOperands(MCInst &Inst,
unsigned N)
const {
456 assert(
N == 1 &&
"Invalid number of operands!");
460 void addPrefetchTagOperands(MCInst &Inst,
unsigned N)
const {
461 assert(
N == 1 &&
"Invalid number of operands!");
465 void addMembarTagOperands(MCInst &Inst,
unsigned N)
const {
466 assert(
N == 1 &&
"Invalid number of operands!");
467 const MCExpr *Expr =
getImm();
472 assert(
N == 1 &&
"Invalid number of operands!");
476 void addTailRelocSymOperands(MCInst &Inst,
unsigned N)
const {
477 assert(
N == 1 &&
"Invalid number of operands!");
478 addExpr(Inst, getTailRelocSym());
481 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
482 auto Op = std::make_unique<SparcOperand>(k_Token);
483 Op->Tok.Data = Str.data();
484 Op->Tok.Length = Str.size();
490 static std::unique_ptr<SparcOperand> CreateReg(MCRegister
Reg,
unsigned Kind,
492 auto Op = std::make_unique<SparcOperand>(k_Register);
494 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
500 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val, SMLoc S,
502 auto Op = std::make_unique<SparcOperand>(k_Immediate);
509 static std::unique_ptr<SparcOperand> CreateASITag(
unsigned Val, SMLoc S,
511 auto Op = std::make_unique<SparcOperand>(k_ASITag);
518 static std::unique_ptr<SparcOperand> CreatePrefetchTag(
unsigned Val, SMLoc S,
520 auto Op = std::make_unique<SparcOperand>(k_PrefetchTag);
527 static std::unique_ptr<SparcOperand> CreateTailRelocSym(
const MCExpr *Val,
529 auto Op = std::make_unique<SparcOperand>(k_TailRelocSym);
536 static bool MorphToIntPairReg(SparcOperand &
Op) {
537 MCRegister
Reg =
Op.getReg();
539 unsigned regIdx = 32;
540 if (
Reg >= Sparc::G0 &&
Reg <= Sparc::G7)
541 regIdx =
Reg - Sparc::G0;
542 else if (
Reg >= Sparc::O0 &&
Reg <= Sparc::O7)
543 regIdx =
Reg - Sparc::O0 + 8;
544 else if (
Reg >= Sparc::L0 &&
Reg <= Sparc::L7)
545 regIdx =
Reg - Sparc::L0 + 16;
546 else if (
Reg >= Sparc::I0 &&
Reg <= Sparc::I7)
547 regIdx =
Reg - Sparc::I0 + 24;
548 if (regIdx % 2 || regIdx > 31)
551 Op.Reg.Kind = rk_IntPairReg;
555 static bool MorphToDoubleReg(SparcOperand &
Op) {
556 MCRegister
Reg =
Op.getReg();
558 unsigned regIdx =
Reg - Sparc::F0;
559 if (regIdx % 2 || regIdx > 31)
562 Op.Reg.Kind = rk_DoubleReg;
566 static bool MorphToQuadReg(SparcOperand &
Op) {
567 MCRegister
Reg =
Op.getReg();
569 switch (
Op.Reg.Kind) {
572 regIdx =
Reg - Sparc::F0;
573 if (regIdx % 4 || regIdx > 31)
578 regIdx =
Reg - Sparc::D0;
579 if (regIdx % 2 || regIdx > 31)
585 Op.Reg.Kind = rk_QuadReg;
589 static bool MorphToCoprocPairReg(SparcOperand &
Op) {
590 MCRegister
Reg =
Op.getReg();
591 assert(
Op.Reg.Kind == rk_CoprocReg);
592 unsigned regIdx = 32;
593 if (
Reg >= Sparc::C0 &&
Reg <= Sparc::C31)
594 regIdx =
Reg - Sparc::C0;
595 if (regIdx % 2 || regIdx > 31)
598 Op.Reg.Kind = rk_CoprocPairReg;
602 static std::unique_ptr<SparcOperand>
603 MorphToMEMrr(MCRegister
Base, std::unique_ptr<SparcOperand>
Op) {
604 MCRegister offsetReg =
Op->getReg();
605 Op->Kind = k_MemoryReg;
607 Op->Mem.OffsetReg = offsetReg;
608 Op->Mem.Off =
nullptr;
612 static std::unique_ptr<SparcOperand> CreateMEMr(MCRegister
Base, SMLoc S,
614 auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
616 Op->Mem.OffsetReg = Sparc::G0;
617 Op->Mem.Off =
nullptr;
623 static std::unique_ptr<SparcOperand>
624 MorphToMEMri(MCRegister
Base, std::unique_ptr<SparcOperand>
Op) {
625 const MCExpr *
Imm =
Op->getImm();
626 Op->Kind = k_MemoryImm;
628 Op->Mem.OffsetReg = MCRegister();
636#define GET_MATCHER_IMPLEMENTATION
637#define GET_REGISTER_MATCHER
638#define GET_MNEMONIC_SPELL_CHECKER
639#include "SparcGenAsmMatcher.inc"
643SparcAsmParser::MatchResultTy
644SparcAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
649 const MatchEntry *Start, *End;
654 Start = std::begin(MatchTable0);
655 End = std::end(MatchTable0);
660 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
662 if (MnemonicRange.first == MnemonicRange.second)
663 return Match_MnemonicFail;
665 for (
const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
668 FeatureBitsets[it->RequiredFeaturesIdx];
669 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
670 return Match_Success;
672 return Match_MissingFeature;
675bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
676 SmallVectorImpl<MCInst> &Instructions) {
684 int64_t RawImmValue = IsImm ? MCValOp.
getImm() : 0;
687 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
689 "set: argument must be between -2147483648 and 4294967295");
694 int32_t ImmValue = RawImmValue;
698 bool IsEffectivelyImm13 =
699 IsImm && ((
is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
700 const MCExpr *ValExpr;
711 if (!IsEffectivelyImm13) {
713 const MCExpr *Expr = adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr);
732 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
735 if (IsEffectivelyImm13)
738 Expr = adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
749bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,
750 SmallVectorImpl<MCInst> &Instructions) {
758 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
762 bool IsSmallImm = IsImm &&
isInt<13>(ImmValue);
763 bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);
769 "set: argument must be between -2147483648 and 2147483647");
776 MCInstBuilder(SP::SETHIi)
778 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
784 if (!NoLowBitsImm || IsSmallImm) {
786 IsSmallImm ? ValExpr : adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
791 .addReg(PrevReg.getReg())
800 if (!IsImm || ImmValue < 0) {
811bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
812 SmallVectorImpl<MCInst> &Instructions) {
820 bool IsImm = MCValOp.
isImm();
821 int64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
840 MCInstBuilder(SP::SETHIi)
842 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
845 MCInstBuilder(SP::ORri)
848 .addExpr(adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr)));
878 .addReg(MCRegOp.
getReg()));
883bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
887 bool MatchingInlineAsm) {
890 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
892 switch (MatchResult) {
893 case Match_Success: {
900 if (expandSET(Inst, IDLoc, Instructions))
904 if (expandSETSW(Inst, IDLoc, Instructions))
908 if (expandSETX(Inst, IDLoc, Instructions))
913 for (
const MCInst &
I : Instructions) {
919 case Match_MissingFeature:
921 "instruction requires a CPU feature not currently enabled");
923 case Match_InvalidOperand: {
924 SMLoc ErrorLoc = IDLoc;
925 if (ErrorInfo != ~0ULL) {
926 if (ErrorInfo >= Operands.
size())
927 return Error(IDLoc,
"too few operands for instruction");
929 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
930 if (ErrorLoc == SMLoc())
934 return Error(ErrorLoc,
"invalid operand for instruction");
936 case Match_MnemonicFail:
937 return Error(IDLoc,
"invalid instruction mnemonic");
942bool SparcAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
944 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
945 return Error(StartLoc,
"invalid register name");
949ParseStatus SparcAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
951 const AsmToken &Tok = Parser.
getTok();
954 Reg = Sparc::NoRegister;
958 unsigned RegKind = SparcOperand::rk_None;
959 Reg = matchRegisterName(Tok, RegKind);
965 getLexer().UnLex(Tok);
969bool SparcAsmParser::parseInstruction(ParseInstructionInfo &Info,
970 StringRef Name, SMLoc NameLoc,
981 MatchResultTy MS = mnemonicIsValid(Name, 0);
985 case Match_MissingFeature:
986 return Error(NameLoc,
987 "instruction requires a CPU feature not currently enabled");
988 case Match_MnemonicFail:
989 return Error(NameLoc,
990 "invalid instruction mnemonic" +
991 SparcMnemonicSpellCheck(Name, getAvailableFeatures(), 0));
997 Operands.
push_back(SparcOperand::CreateToken(Name, NameLoc));
1005 if (!parseBranchModifiers(Operands).isSuccess()) {
1006 SMLoc Loc = getLexer().getLoc();
1007 return Error(Loc,
"unexpected token");
1010 if (!parseOperand(Operands, Name).isSuccess()) {
1011 SMLoc Loc = getLexer().getLoc();
1012 return Error(Loc,
"unexpected token");
1022 if (!parseOperand(Operands, Name).isSuccess()) {
1023 SMLoc Loc = getLexer().getLoc();
1024 return Error(Loc,
"unexpected token");
1029 SMLoc Loc = getLexer().getLoc();
1030 return Error(Loc,
"unexpected token");
1036ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {
1037 StringRef IDVal = DirectiveID.
getString();
1039 if (IDVal ==
".register") {
1044 if (IDVal ==
".proc") {
1050 if (IDVal ==
".seg") {
1056 uint32_t Subsection = 0;
1057 const MCObjectFileInfo *MCOFI =
getContext().getObjectFileInfo();
1058 if (Name ==
"text") {
1060 }
else if (Name ==
"data" || Name ==
"data1") {
1062 Subsection =
Name ==
"data1" ? 1 : 0;
1063 }
else if (Name ==
"bss") {
1066 return Error(DirectiveID.
getLoc(),
"unknown segment type");
1068 getStreamer().switchSection(Section, Subsection);
1076ParseStatus SparcAsmParser::parseMEMOperand(
OperandVector &Operands) {
1079 std::unique_ptr<SparcOperand>
LHS;
1080 if (!parseSparcAsmOperand(
LHS).isSuccess())
1085 Operands.
push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(
LHS)));
1089 if (!
LHS->isIntReg())
1090 return Error(
LHS->getStartLoc(),
"invalid register kind for this operand");
1092 AsmToken Tok = getLexer().getTok();
1098 std::unique_ptr<SparcOperand>
RHS;
1099 if (!parseSparcAsmOperand(
RHS).isSuccess())
1102 if (
RHS->isReg() && !
RHS->isIntReg())
1104 "invalid register kind for this operand");
1108 ? SparcOperand::MorphToMEMri(
LHS->getReg(), std::move(
RHS))
1109 : SparcOperand::MorphToMEMrr(
LHS->getReg(), std::move(
RHS)));
1114 Operands.
push_back(SparcOperand::CreateMEMr(
LHS->getReg(), S,
E));
1118template <
unsigned N>
1119ParseStatus SparcAsmParser::parseShiftAmtImm(
OperandVector &Operands) {
1128 if (getParser().parseExpression(Expr))
1133 return Error(S,
"constant expression expected");
1136 return Error(S,
"immediate shift value out of range");
1138 Operands.
push_back(SparcOperand::CreateImm(Expr, S,
E));
1142template <SparcAsmParser::TailRelocKind Kind>
1143ParseStatus SparcAsmParser::parseTailRelocSym(
OperandVector &Operands) {
1147 auto MatchesKind = [](uint16_t RelType) ->
bool {
1149 case TailRelocKind::Load_GOT:
1152 return RelType == ELF::R_SPARC_GOTDATA_OP;
1153 case TailRelocKind::Add_TLS:
1157 case ELF::R_SPARC_TLS_GD_ADD:
1158 case ELF::R_SPARC_TLS_IE_ADD:
1159 case ELF::R_SPARC_TLS_LDM_ADD:
1160 case ELF::R_SPARC_TLS_LDO_ADD:
1165 case TailRelocKind::Load_TLS:
1169 case ELF::R_SPARC_TLS_IE_LD:
1170 case ELF::R_SPARC_TLS_IE_LDX:
1175 case TailRelocKind::Call_TLS:
1179 case ELF::R_SPARC_TLS_GD_CALL:
1180 case ELF::R_SPARC_TLS_LDM_CALL:
1192 const AsmToken Tok = Parser.
getTok();
1196 return Error(getLoc(),
"expected valid identifier for operand modifier");
1198 StringRef
Name = getParser().getTok().getIdentifier();
1201 return Error(getLoc(),
"invalid relocation specifier");
1203 if (!MatchesKind(RelType)) {
1205 getLexer().UnLex(Tok);
1211 return Error(getLoc(),
"expected '('");
1214 const MCExpr *SubExpr;
1215 if (getParser().parseParenExpression(SubExpr,
E))
1218 const MCExpr *Val = adjustPICRelocation(RelType, SubExpr);
1219 Operands.
push_back(SparcOperand::CreateTailRelocSym(Val, S,
E));
1223ParseStatus SparcAsmParser::parseMembarTag(
OperandVector &Operands) {
1228 std::unique_ptr<SparcOperand>
Mask;
1229 if (parseSparcAsmOperand(Mask).isSuccess()) {
1230 if (!
Mask->isImm() || !
Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
1231 ImmVal < 0 || ImmVal > 127)
1232 return Error(S,
"invalid membar mask number");
1236 SMLoc TagStart = getLexer().getLoc();
1238 unsigned MaskVal = StringSwitch<unsigned>(Parser.
getTok().
getString())
1239 .Case(
"LoadLoad", 0x1)
1240 .Case(
"StoreLoad", 0x2)
1241 .Case(
"LoadStore", 0x4)
1242 .Case(
"StoreStore", 0x8)
1243 .Case(
"Lookaside", 0x10)
1244 .Case(
"MemIssue", 0x20)
1251 return Error(TagStart,
"unknown membar tag");
1261 Operands.
push_back(SparcOperand::CreateImm(EVal, S,
E));
1265ParseStatus SparcAsmParser::parseASITag(
OperandVector &Operands) {
1273 ParseStatus ParseExprStatus = parseExpression(ASIVal);
1275 return ParseExprStatus;
1278 return Error(S,
"invalid ASI number, must be between 0 and 255");
1280 Operands.
push_back(SparcOperand::CreateASITag(ASIVal, S,
E));
1286 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1289 const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName);
1291 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1295 return Error(TagStart,
"unknown ASI tag");
1299 Operands.
push_back(SparcOperand::CreateASITag(ASIVal, S,
E));
1303ParseStatus SparcAsmParser::parsePrefetchTag(
OperandVector &Operands) {
1306 int64_t PrefetchVal = 0;
1311 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1313 return ParseExprStatus;
1316 return Error(S,
"invalid prefetch number, must be between 0 and 31");
1318 Operands.
push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S,
E));
1322 SMLoc TagStart = getLexer().peekTok(
false).getLoc();
1325 const SparcPrefetchTag::PrefetchTag *PrefetchTag =
1326 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1330 return Error(TagStart,
"unknown prefetch tag");
1332 PrefetchVal = PrefetchTag->
Encoding;
1334 Operands.
push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S,
E));
1338ParseStatus SparcAsmParser::parseCallTarget(
OperandVector &Operands) {
1342 switch (getLexer().getKind()) {
1352 const MCExpr *DestValue;
1353 if (getParser().parseExpression(DestValue))
1356 Operands.
push_back(SparcOperand::CreateImm(DestValue, S,
E));
1360ParseStatus SparcAsmParser::parseOperand(
OperandVector &Operands,
1361 StringRef Mnemonic) {
1363 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
1373 Operands.
push_back(SparcOperand::CreateToken(
"[",
1377 if (Mnemonic ==
"cas" || Mnemonic ==
"casl" || Mnemonic ==
"casa" ||
1378 Mnemonic ==
"casx" || Mnemonic ==
"casxl" || Mnemonic ==
"casxa") {
1385 MCRegister
Reg = matchRegisterName(Parser.
getTok(), RegKind);
1391 Operands.
push_back(SparcOperand::CreateReg(
Reg, RegKind, S,
E));
1394 Res = parseMEMOperand(Operands);
1403 Operands.
push_back(SparcOperand::CreateToken(
"]",
1414 S,
"malformed ASI tag, must be a constant integer expression");
1417 const AsmToken Tok = Parser.
getTok();
1424 SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.
size() - 2];
1425 if (OldMemOp.isMEMrr()) {
1426 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1427 return Error(S,
"invalid operand for instruction");
1429 Operands[Operands.
size() - 2] = SparcOperand::MorphToMEMri(
1430 OldMemOp.getMemBase(),
1432 OldMemOp.getStartLoc(),
1433 OldMemOp.getEndLoc()));
1440 Operands.
push_back(SparcOperand::CreateToken(
"%asi", S));
1444 return Error(S,
"malformed ASI tag, must be %asi, a constant integer "
1445 "expression, or a named tag");
1452 return parseASITag(Operands);
1456 std::unique_ptr<SparcOperand>
Op;
1458 Res = parseSparcAsmOperand(
Op);
1469SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &
Op) {
1475 switch (getLexer().getKind()) {
1481 if (MCRegister
Reg = matchRegisterName(Parser.
getTok(), RegKind)) {
1489 if (
Reg == Sparc::ICC && Name ==
"xcc")
1490 Op = SparcOperand::CreateToken(
"%xcc", S);
1492 Op = SparcOperand::CreateReg(
Reg, RegKind, S,
E);
1495 if (matchSparcAsmModifiers(EVal,
E)) {
1497 Op = SparcOperand::CreateImm(EVal, S,
E);
1508 if (getParser().parseExpression(EVal,
E))
1511 Op = SparcOperand::CreateImm(EVal, S,
E);
1517ParseStatus SparcAsmParser::parseBranchModifiers(
OperandVector &Operands) {
1526 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
1527 Operands.
push_back(SparcOperand::CreateToken(modName,
1535ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1536 AsmToken Tok = getLexer().getTok();
1538 if (!isPossibleExpression(Tok))
1541 return getParser().parseAbsoluteExpression(Val);
1544MCRegister SparcAsmParser::matchRegisterName(
const AsmToken &Tok,
1545 unsigned &RegKind) {
1546 RegKind = SparcOperand::rk_None;
1548 return SP::NoRegister;
1562 if (
Reg == SP::ASR4 && Name ==
"tick") {
1563 RegKind = SparcOperand::rk_Special;
1568 RegKind = SparcOperand::rk_IntReg;
1572 RegKind = SparcOperand::rk_FloatReg;
1576 RegKind = SparcOperand::rk_CoprocReg;
1582 RegKind = SparcOperand::rk_IntReg;
1589 if (MCRegister SubReg = MRI.
getSubReg(
Reg, SP::sub_even)) {
1590 RegKind = SparcOperand::rk_FloatReg;
1593 RegKind = SparcOperand::rk_DoubleReg;
1603 RegKind = SparcOperand::rk_CoprocReg;
1608 RegKind = SparcOperand::rk_Special;
1617 if (
Name.starts_with_insensitive(
"r") &&
1618 !
Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {
1619 RegKind = SparcOperand::rk_IntReg;
1623 if (Name ==
"xcc" || Name ==
"ncc") {
1625 RegKind = SparcOperand::rk_Special;
1631 if (Name ==
"pcr") {
1632 RegKind = SparcOperand::rk_Special;
1635 if (Name ==
"pic") {
1636 RegKind = SparcOperand::rk_Special;
1639 if (Name ==
"dcr") {
1640 RegKind = SparcOperand::rk_Special;
1643 if (Name ==
"gsr") {
1644 RegKind = SparcOperand::rk_Special;
1647 if (Name ==
"set_softint") {
1648 RegKind = SparcOperand::rk_Special;
1651 if (Name ==
"clear_softint") {
1652 RegKind = SparcOperand::rk_Special;
1655 if (Name ==
"softint") {
1656 RegKind = SparcOperand::rk_Special;
1659 if (Name ==
"tick_cmpr") {
1660 RegKind = SparcOperand::rk_Special;
1663 if (Name ==
"stick" || Name ==
"sys_tick") {
1664 RegKind = SparcOperand::rk_Special;
1667 if (Name ==
"stick_cmpr" || Name ==
"sys_tick_cmpr") {
1668 RegKind = SparcOperand::rk_Special;
1672 return SP::NoRegister;
1706const MCSpecifierExpr *
1707SparcAsmParser::adjustPICRelocation(uint16_t RelType,
const MCExpr *subExpr) {
1713 if (
getContext().getObjectFileInfo()->isPositionIndependent()) {
1716 case ELF::R_SPARC_LO10:
1720 case ELF::R_SPARC_HI22:
1730bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
1732 AsmToken Tok = Parser.
getTok();
1741 Error(getLoc(),
"invalid relocation specifier");
1744 case ELF::R_SPARC_GOTDATA_OP:
1745 case ELF::R_SPARC_TLS_GD_ADD:
1746 case ELF::R_SPARC_TLS_GD_CALL:
1747 case ELF::R_SPARC_TLS_IE_ADD:
1748 case ELF::R_SPARC_TLS_IE_LD:
1749 case ELF::R_SPARC_TLS_IE_LDX:
1750 case ELF::R_SPARC_TLS_LDM_ADD:
1751 case ELF::R_SPARC_TLS_LDM_CALL:
1752 case ELF::R_SPARC_TLS_LDO_ADD:
1765 const MCExpr *subExpr;
1769 EVal = adjustPICRelocation(VK, subExpr);
1773bool SparcAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
1774 SMLoc Loc = getLoc();
1776 return TokError(
"expected '%' relocation specifier");
1779 return TokError(
"invalid relocation specifier");
1785 const MCExpr *SubExpr;
1792bool SparcAsmParser::parseDataExpr(
const MCExpr *&Res) {
1795 return parseExprWithSpecifier(Res, EndLoc);
1799bool SparcAsmParser::isPossibleExpression(
const AsmToken &Token) {
1820unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1822 SparcOperand &
Op = (SparcOperand &)GOp;
1823 if (
Op.isFloatOrDoubleReg()) {
1827 if (!
Op.isFloatReg() || SparcOperand::MorphToDoubleReg(
Op))
1831 if (SparcOperand::MorphToQuadReg(
Op))
1836 if (
Op.isIntReg() && Kind == MCK_IntPair) {
1837 if (SparcOperand::MorphToIntPairReg(
Op))
1840 if (
Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1841 if (SparcOperand::MorphToCoprocPairReg(
Op))
1844 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.
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)
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)
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,...