29#define DEBUG_TYPE "loongarch-asm-parser"
48 SMLoc &EndLoc)
override;
56 bool MatchingInlineAsm)
override;
61 unsigned Kind)
override;
73#define GET_ASSEMBLER_HEADER
74#include "LoongArchGenAsmMatcher.inc"
125 enum LoongArchMatchResultTy {
127 Match_RequiresMsbNotLessThanLsb,
128 Match_RequiresOpnd2NotR0R1,
129 Match_RequiresAMORdDifferRkRj,
130 Match_RequiresLAORdDifferRj,
131#define GET_OPERAND_DIAGNOSTIC_TYPES
132#include "LoongArchGenAsmMatcher.inc"
133#undef GET_OPERAND_DIAGNOSTIC_TYPES
136 static bool classifySymbolRef(
const MCExpr *Expr,
168 SMLoc StartLoc, EndLoc;
178 bool isToken()
const override {
return Kind == KindTy::Token; }
179 bool isReg()
const override {
return Kind == KindTy::Register; }
180 bool isImm()
const override {
return Kind == KindTy::Immediate; }
181 bool isMem()
const override {
return false; }
184 return Kind == KindTy::Register &&
185 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(
189 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
191 if (
auto *LE = dyn_cast<LoongArchMCExpr>(Expr)) {
196 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
197 Imm =
CE->getValue();
204 template <
unsigned N,
int P = 0>
bool isUImm()
const {
210 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
211 return IsConstantImm && isUInt<N>(Imm -
P) &&
215 template <
unsigned N,
unsigned S = 0>
bool isSImm()
const {
221 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
222 return IsConstantImm && isShiftedInt<N, S>(Imm) &&
226 bool isBareSymbol()
const {
230 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
232 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
236 bool isUImm1()
const {
return isUImm<1>(); }
237 bool isUImm2()
const {
return isUImm<2>(); }
238 bool isUImm2plus1()
const {
return isUImm<2, 1>(); }
239 bool isUImm3()
const {
return isUImm<3>(); }
240 bool isUImm4()
const {
return isUImm<4>(); }
241 bool isSImm5()
const {
return isSImm<5>(); }
242 bool isUImm5()
const {
return isUImm<5>(); }
243 bool isUImm6()
const {
return isUImm<6>(); }
244 bool isUImm7()
const {
return isUImm<7>(); }
245 bool isSImm8()
const {
return isSImm<8>(); }
246 bool isSImm8lsl1()
const {
return isSImm<8, 1>(); }
247 bool isSImm8lsl2()
const {
return isSImm<8, 2>(); }
248 bool isSImm8lsl3()
const {
return isSImm<8, 3>(); }
249 bool isUImm8()
const {
return isUImm<8>(); }
250 bool isSImm9lsl3()
const {
return isSImm<9, 3>(); }
251 bool isSImm10()
const {
return isSImm<10>(); }
252 bool isSImm10lsl2()
const {
return isSImm<10, 2>(); }
253 bool isSImm11lsl1()
const {
return isSImm<11, 1>(); }
254 bool isSImm12()
const {
return isSImm<12>(); }
256 bool isSImm12addlike()
const {
262 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
268 ? isInt<12>(Imm) && IsValidKind
269 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
273 bool isSImm12lu52id()
const {
279 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
289 ? isInt<12>(Imm) && IsValidKind
290 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
294 bool isUImm12()
const {
return isUImm<12>(); }
296 bool isUImm12ori()
const {
302 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
312 ? isUInt<12>(Imm) && IsValidKind
313 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
317 bool isSImm13()
const {
return isSImm<13>(); }
318 bool isUImm14()
const {
return isUImm<14>(); }
319 bool isUImm15()
const {
return isUImm<15>(); }
321 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
322 bool isSImm16()
const {
return isSImm<16>(); }
324 bool isSImm16lsl2()
const {
330 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
335 ? isShiftedInt<16, 2>(Imm) && IsValidKind
336 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
340 bool isSImm20()
const {
return isSImm<20>(); }
342 bool isSImm20pcalau12i()
const {
348 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
356 ? isInt<20>(Imm) && IsValidKind
357 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
361 bool isSImm20lu12iw()
const {
367 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
376 ? isInt<20>(Imm) && IsValidKind
377 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
381 bool isSImm20lu32id()
const {
387 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
398 ? isInt<20>(Imm) && IsValidKind
399 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
403 bool isSImm21lsl2()
const {
409 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
413 ? isShiftedInt<21, 2>(Imm) && IsValidKind
414 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
418 bool isSImm26Operand()
const {
424 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
430 ? isShiftedInt<26, 2>(Imm) && IsValidKind
431 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
435 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
442 unsigned getReg()
const override {
443 assert(Kind == KindTy::Register &&
"Invalid type access!");
444 return Reg.RegNum.id();
447 const MCExpr *getImm()
const {
448 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
453 assert(Kind == KindTy::Token &&
"Invalid type access!");
466 case KindTy::Immediate:
469 case KindTy::Register:
473 OS <<
"'" << getToken() <<
"'";
478 static std::unique_ptr<LoongArchOperand> createToken(
StringRef Str,
SMLoc S) {
479 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
486 static std::unique_ptr<LoongArchOperand> createReg(
unsigned RegNo,
SMLoc S,
488 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
489 Op->Reg.RegNum = RegNo;
495 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val,
SMLoc S,
497 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
505 if (
auto CE = dyn_cast<MCConstantExpr>(Expr))
512 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
513 assert(
N == 1 &&
"Invalid number of operands!");
516 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
517 assert(
N == 1 &&
"Invalid number of operands!");
518 addExpr(Inst, getImm());
523#define GET_REGISTER_MATCHER
524#define GET_SUBTARGET_FEATURE_NAME
525#define GET_MATCHER_IMPLEMENTATION
526#define GET_MNEMONIC_SPELL_CHECKER
527#include "LoongArchGenAsmMatcher.inc"
530 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
531 return Reg - LoongArch::F0 + LoongArch::F0_64;
541 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
543 static_assert(LoongArch::F0 < LoongArch::F0_64,
544 "FPR matching must be updated");
545 if (RegNo == LoongArch::NoRegister)
548 return RegNo == LoongArch::NoRegister;
553 return Error(getLoc(),
"invalid register number");
562bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
567 Kind = RE->getKind();
568 Expr = RE->getSubExpr();
586 if (RegNo == LoongArch::NoRegister)
592 Operands.push_back(LoongArchOperand::createReg(RegNo, S,
E));
602 switch (getLexer().getKind()) {
614 if (getParser().parseExpression(Res,
E))
618 return parseOperandWithModifier(
Operands);
621 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
631 return Error(getLoc(),
"expected '%' for operand modifier");
636 return Error(getLoc(),
"expected valid identifier for operand modifier");
641 return Error(getLoc(),
"unrecognized operand modifier");
645 return Error(getLoc(),
"expected '('");
649 if (getParser().parseParenExpression(SubExpr,
E))
653 Operands.push_back(LoongArchOperand::createImm(ModExpr, S,
E));
662 return parseOperandWithModifier(
Operands);
668 if (getParser().parseIdentifier(Identifier))
673 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
677 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
683 if (!parseRegister(
Operands).isSuccess())
690 SMLoc ImmStart = getLoc();
691 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
694 return Error(ImmStart,
"optional integer offset must be 0");
706 MatchOperandParserImpl(
Operands, Mnemonic,
true);
712 if (parseRegister(
Operands).isSuccess() ||
717 return Error(getLoc(),
"unknown operand");
724 Operands.push_back(LoongArchOperand::createToken(
Name, NameLoc));
743 SMLoc Loc = getLexer().getLoc();
744 getParser().eatToEndOfStatement();
745 return Error(Loc,
"unexpected token");
753 for (LoongArchAsmParser::Inst &Inst : Insts) {
754 unsigned Opc = Inst.Opc;
760 case LoongArch::PCALAU12I:
761 case LoongArch::LU12I_W:
766 case LoongArch::ADDI_W:
767 case LoongArch::LD_W:
768 case LoongArch::LD_D: {
771 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addImm(0),
776 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
780 case LoongArch::LU32I_D:
782 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
783 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
787 case LoongArch::LU52I_D:
789 MCInstBuilder(Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
792 case LoongArch::ADDI_D:
796 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
800 case LoongArch::ADD_D:
801 case LoongArch::LDX_D:
803 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
810void LoongArchAsmParser::emitLoadAddressAbs(
MCInst &Inst,
SMLoc IDLoc,
826 Insts.push_back(LoongArchAsmParser::Inst(
828 Insts.push_back(LoongArchAsmParser::Inst(
832 Insts.push_back(LoongArchAsmParser::Inst(
834 Insts.push_back(LoongArchAsmParser::Inst(
838 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
841void LoongArchAsmParser::emitLoadAddressPcrel(
MCInst &Inst,
SMLoc IDLoc,
850 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
852 Insts.push_back(LoongArchAsmParser::Inst(
857 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
860void LoongArchAsmParser::emitLoadAddressPcrelLarge(
MCInst &Inst,
SMLoc IDLoc,
874 Insts.push_back(LoongArchAsmParser::Inst(
876 Insts.push_back(LoongArchAsmParser::Inst(
878 Insts.push_back(LoongArchAsmParser::Inst(
880 Insts.push_back(LoongArchAsmParser::Inst(
882 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
884 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
887void LoongArchAsmParser::emitLoadAddressGot(
MCInst &Inst,
SMLoc IDLoc,
896 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
898 Insts.push_back(LoongArchAsmParser::Inst(
903 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
906void LoongArchAsmParser::emitLoadAddressGotLarge(
MCInst &Inst,
SMLoc IDLoc,
920 Insts.push_back(LoongArchAsmParser::Inst(
922 Insts.push_back(LoongArchAsmParser::Inst(
924 Insts.push_back(LoongArchAsmParser::Inst(
926 Insts.push_back(LoongArchAsmParser::Inst(
928 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
930 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
933void LoongArchAsmParser::emitLoadAddressTLSLE(
MCInst &Inst,
SMLoc IDLoc,
943 Insts.push_back(LoongArchAsmParser::Inst(
945 Insts.push_back(LoongArchAsmParser::Inst(
948 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
951void LoongArchAsmParser::emitLoadAddressTLSIE(
MCInst &Inst,
SMLoc IDLoc,
960 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
962 Insts.push_back(LoongArchAsmParser::Inst(
964 Insts.push_back(LoongArchAsmParser::Inst(
967 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
970void LoongArchAsmParser::emitLoadAddressTLSIELarge(
MCInst &Inst,
SMLoc IDLoc,
984 Insts.push_back(LoongArchAsmParser::Inst(
986 Insts.push_back(LoongArchAsmParser::Inst(
988 Insts.push_back(LoongArchAsmParser::Inst(
990 Insts.push_back(LoongArchAsmParser::Inst(
992 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
994 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
997void LoongArchAsmParser::emitLoadAddressTLSLD(
MCInst &Inst,
SMLoc IDLoc,
1006 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1008 Insts.push_back(LoongArchAsmParser::Inst(
1010 Insts.push_back(LoongArchAsmParser::Inst(
1013 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1016void LoongArchAsmParser::emitLoadAddressTLSLDLarge(
MCInst &Inst,
SMLoc IDLoc,
1030 Insts.push_back(LoongArchAsmParser::Inst(
1032 Insts.push_back(LoongArchAsmParser::Inst(
1034 Insts.push_back(LoongArchAsmParser::Inst(
1036 Insts.push_back(LoongArchAsmParser::Inst(
1038 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1040 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1043void LoongArchAsmParser::emitLoadAddressTLSGD(
MCInst &Inst,
SMLoc IDLoc,
1052 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1054 Insts.push_back(LoongArchAsmParser::Inst(
1056 Insts.push_back(LoongArchAsmParser::Inst(
1059 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1062void LoongArchAsmParser::emitLoadAddressTLSGDLarge(
MCInst &Inst,
SMLoc IDLoc,
1076 Insts.push_back(LoongArchAsmParser::Inst(
1078 Insts.push_back(LoongArchAsmParser::Inst(
1080 Insts.push_back(LoongArchAsmParser::Inst(
1082 Insts.push_back(LoongArchAsmParser::Inst(
1084 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1086 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1089void LoongArchAsmParser::emitLoadImm(
MCInst &Inst,
SMLoc IDLoc,
1095 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1096 Imm = SignExtend64<32>(Imm);
1099 unsigned Opc = Inst.Opc;
1100 if (Opc == LoongArch::LU12I_W)
1105 MCInstBuilder(Opc).addReg(DestReg).addReg(SrcReg).addImm(Inst.Imm),
1111bool LoongArchAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1118 case LoongArch::PseudoLA_ABS:
1119 case LoongArch::PseudoLA_ABS_LARGE:
1120 emitLoadAddressAbs(Inst, IDLoc, Out);
1122 case LoongArch::PseudoLA_PCREL:
1123 emitLoadAddressPcrel(Inst, IDLoc, Out);
1125 case LoongArch::PseudoLA_PCREL_LARGE:
1126 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1128 case LoongArch::PseudoLA_GOT:
1129 emitLoadAddressGot(Inst, IDLoc, Out);
1131 case LoongArch::PseudoLA_GOT_LARGE:
1132 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1134 case LoongArch::PseudoLA_TLS_LE:
1135 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1137 case LoongArch::PseudoLA_TLS_IE:
1138 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1140 case LoongArch::PseudoLA_TLS_IE_LARGE:
1141 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1143 case LoongArch::PseudoLA_TLS_LD:
1144 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1146 case LoongArch::PseudoLA_TLS_LD_LARGE:
1147 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1149 case LoongArch::PseudoLA_TLS_GD:
1150 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1152 case LoongArch::PseudoLA_TLS_GD_LARGE:
1153 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1155 case LoongArch::PseudoLI_W:
1156 case LoongArch::PseudoLI_D:
1157 emitLoadImm(Inst, IDLoc, Out);
1164unsigned LoongArchAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1168 if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) {
1172 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1173 return Match_RequiresAMORdDifferRkRj;
1176 case LoongArch::PseudoLA_PCREL_LARGE:
1177 case LoongArch::PseudoLA_GOT_LARGE:
1178 case LoongArch::PseudoLA_TLS_IE_LARGE:
1179 case LoongArch::PseudoLA_TLS_LD_LARGE:
1180 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1184 return Match_RequiresLAORdDifferRj;
1187 case LoongArch::CSRXCHG:
1188 case LoongArch::GCSRXCHG: {
1190 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1191 return Match_RequiresOpnd2NotR0R1;
1192 return Match_Success;
1194 case LoongArch::BSTRINS_W:
1195 case LoongArch::BSTRINS_D:
1196 case LoongArch::BSTRPICK_W:
1197 case LoongArch::BSTRPICK_D: {
1200 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1204 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1208 return Match_RequiresMsbNotLessThanLsb;
1209 return Match_Success;
1213 return Match_Success;
1219 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1221 return Match_InvalidOperand;
1226 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1227 Kind == MCK_FPR64) {
1229 return Match_Success;
1232 return Match_InvalidOperand;
1235bool LoongArchAsmParser::generateImmOutOfRangeError(
1237 const Twine &Msg =
"immediate must be an integer in the range") {
1242bool LoongArchAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &
Opcode,
1246 bool MatchingInlineAsm) {
1256 return processInstruction(Inst, IDLoc,
Operands, Out);
1257 case Match_MissingFeature: {
1258 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1259 bool FirstFeature =
true;
1260 std::string
Msg =
"instruction requires the following:";
1261 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1262 if (MissingFeatures[i]) {
1263 Msg += FirstFeature ?
" " :
", ";
1265 FirstFeature =
false;
1268 return Error(IDLoc, Msg);
1270 case Match_MnemonicFail: {
1271 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1272 std::string Suggestion = LoongArchMnemonicSpellCheck(
1273 ((LoongArchOperand &)*
Operands[0]).getToken(), FBS, 0);
1274 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1276 case Match_InvalidOperand: {
1277 SMLoc ErrorLoc = IDLoc;
1280 return Error(ErrorLoc,
"too few operands for instruction");
1283 if (ErrorLoc ==
SMLoc())
1286 return Error(ErrorLoc,
"invalid operand for instruction");
1293 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1294 SMLoc ErrorLoc = IDLoc;
1296 return Error(ErrorLoc,
"too few operands for instruction");
1302 case Match_RequiresMsbNotLessThanLsb: {
1304 return Error(ErrorStart,
"msb is less than lsb",
1307 case Match_RequiresOpnd2NotR0R1:
1308 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1309 case Match_RequiresAMORdDifferRkRj:
1311 "$rd must be different from both $rk and $rj");
1312 case Match_RequiresLAORdDifferRj:
1313 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1314 case Match_InvalidUImm1:
1317 case Match_InvalidUImm2:
1320 case Match_InvalidUImm2plus1:
1323 case Match_InvalidUImm3:
1326 case Match_InvalidUImm4:
1329 case Match_InvalidUImm5:
1332 case Match_InvalidUImm6:
1335 case Match_InvalidUImm7:
1338 case Match_InvalidUImm8:
1341 case Match_InvalidUImm12:
1344 case Match_InvalidUImm12ori:
1345 return generateImmOutOfRangeError(
1348 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1349 "integer in the range");
1350 case Match_InvalidUImm14:
1353 case Match_InvalidUImm15:
1356 case Match_InvalidSImm5:
1359 case Match_InvalidSImm8:
1362 case Match_InvalidSImm8lsl1:
1363 return generateImmOutOfRangeError(
1365 "immediate must be a multiple of 2 in the range");
1366 case Match_InvalidSImm8lsl2:
1367 return generateImmOutOfRangeError(
1369 "immediate must be a multiple of 4 in the range");
1370 case Match_InvalidSImm10:
1373 case Match_InvalidSImm8lsl3:
1374 return generateImmOutOfRangeError(
1376 "immediate must be a multiple of 8 in the range");
1377 case Match_InvalidSImm9lsl3:
1378 return generateImmOutOfRangeError(
1380 "immediate must be a multiple of 8 in the range");
1381 case Match_InvalidSImm10lsl2:
1382 return generateImmOutOfRangeError(
1384 "immediate must be a multiple of 4 in the range");
1385 case Match_InvalidSImm11lsl1:
1386 return generateImmOutOfRangeError(
1388 "immediate must be a multiple of 2 in the range");
1389 case Match_InvalidSImm12:
1392 case Match_InvalidSImm12addlike:
1393 return generateImmOutOfRangeError(
1396 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1398 case Match_InvalidSImm12lu52id:
1399 return generateImmOutOfRangeError(
1402 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1403 "integer in the range");
1404 case Match_InvalidSImm13:
1407 case Match_InvalidSImm14lsl2:
1408 return generateImmOutOfRangeError(
1410 "immediate must be a multiple of 4 in the range");
1411 case Match_InvalidSImm16:
1414 case Match_InvalidSImm16lsl2:
1415 return generateImmOutOfRangeError(
1417 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1419 case Match_InvalidSImm20:
1422 case Match_InvalidSImm20lu12iw:
1423 return generateImmOutOfRangeError(
1426 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1428 case Match_InvalidSImm20lu32id:
1429 return generateImmOutOfRangeError(
1432 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1433 "integer in the range");
1434 case Match_InvalidSImm20pcalau12i:
1435 return generateImmOutOfRangeError(
1438 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1440 case Match_InvalidSImm21lsl2:
1441 return generateImmOutOfRangeError(
1443 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1445 case Match_InvalidSImm26Operand:
1446 return generateImmOutOfRangeError(
1448 "operand must be a bare symbol name or an immediate must be a multiple "
1449 "of 4 in the range");
1450 case Match_InvalidImm32: {
1452 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1454 case Match_InvalidBareSymbol: {
1456 return Error(ErrorLoc,
"operand must be a bare symbol name");
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchRegisterName(StringRef Name)
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool matchRegisterNameHelper(MCRegister &RegNo, StringRef Name)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchAsmParser()
static MCRegister convertFPR32ToFPR64(MCRegister Reg)
mir Rename Register Operands
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
static bool is64Bit(const char *name)
static constexpr uint32_t Opcode
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
static const char * getRegisterName(MCRegister Reg)
static const LoongArchMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
static VariantKind getVariantKindForName(StringRef name)
@ VK_LoongArch_PCALA_HI20
@ VK_LoongArch_TLS_LD_PC_HI20
@ VK_LoongArch_TLS_LE64_HI12
@ VK_LoongArch_TLS_LD_HI20
@ VK_LoongArch_GOT64_HI12
@ VK_LoongArch_PCALA_LO12
@ VK_LoongArch_TLS_IE_HI20
@ VK_LoongArch_TLS_GD_HI20
@ VK_LoongArch_ABS64_HI12
@ VK_LoongArch_TLS_LE_LO12
@ VK_LoongArch_TLS_IE64_HI12
@ VK_LoongArch_GOT_PC_HI20
@ VK_LoongArch_TLS_IE64_PC_LO20
@ VK_LoongArch_TLS_IE64_LO20
@ VK_LoongArch_TLS_IE_PC_LO12
@ VK_LoongArch_GOT64_PC_HI12
@ VK_LoongArch_TLS_IE_PC_HI20
@ VK_LoongArch_TLS_LE64_LO20
@ VK_LoongArch_PCALA64_LO20
@ VK_LoongArch_TLS_IE_LO12
@ VK_LoongArch_GOT_PC_LO12
@ VK_LoongArch_TLS_LE_HI20
@ VK_LoongArch_GOT64_LO20
@ VK_LoongArch_TLS_GD_PC_HI20
@ VK_LoongArch_GOT64_PC_LO20
@ VK_LoongArch_PCALA64_HI12
@ VK_LoongArch_TLS_IE64_PC_HI12
@ VK_LoongArch_ABS64_LO20
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Interface to description of machine instruction set.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual unsigned getReg() const =0
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
This represents an "assembler immediate".
uint32_t getRefKind() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const CustomOperand< const MCSubtargetInfo & > Msg[]
InstSeq generateInstSeq(int64_t Val)
SmallVector< Inst, 4 > InstSeq
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheLoongArch64Target()
Target & getTheLoongArch32Target()
DWARFExpression::Operation Op
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...