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"
129 enum LoongArchMatchResultTy {
131 Match_RequiresMsbNotLessThanLsb,
132 Match_RequiresOpnd2NotR0R1,
133 Match_RequiresAMORdDifferRkRj,
134 Match_RequiresLAORdDifferRj,
135#define GET_OPERAND_DIAGNOSTIC_TYPES
136#include "LoongArchGenAsmMatcher.inc"
137#undef GET_OPERAND_DIAGNOSTIC_TYPES
140 static bool classifySymbolRef(
const MCExpr *Expr,
172 SMLoc StartLoc, EndLoc;
182 bool isToken()
const override {
return Kind == KindTy::Token; }
183 bool isReg()
const override {
return Kind == KindTy::Register; }
184 bool isImm()
const override {
return Kind == KindTy::Immediate; }
185 bool isMem()
const override {
return false; }
188 return Kind == KindTy::Register &&
189 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(
193 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
195 if (
auto *LE = dyn_cast<LoongArchMCExpr>(Expr)) {
200 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
201 Imm =
CE->getValue();
208 template <
unsigned N,
int P = 0>
bool isUImm()
const {
214 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
215 return IsConstantImm && isUInt<N>(Imm -
P) &&
219 template <
unsigned N,
unsigned S = 0>
bool isSImm()
const {
225 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
226 return IsConstantImm && isShiftedInt<N, S>(Imm) &&
230 bool isBareSymbol()
const {
234 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
236 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
240 bool isUImm1()
const {
return isUImm<1>(); }
241 bool isUImm2()
const {
return isUImm<2>(); }
242 bool isUImm2plus1()
const {
return isUImm<2, 1>(); }
243 bool isUImm3()
const {
return isUImm<3>(); }
244 bool isUImm4()
const {
return isUImm<4>(); }
245 bool isSImm5()
const {
return isSImm<5>(); }
246 bool isUImm5()
const {
return isUImm<5>(); }
247 bool isUImm6()
const {
return isUImm<6>(); }
248 bool isUImm7()
const {
return isUImm<7>(); }
249 bool isSImm8()
const {
return isSImm<8>(); }
250 bool isSImm8lsl1()
const {
return isSImm<8, 1>(); }
251 bool isSImm8lsl2()
const {
return isSImm<8, 2>(); }
252 bool isSImm8lsl3()
const {
return isSImm<8, 3>(); }
253 bool isUImm8()
const {
return isUImm<8>(); }
254 bool isSImm9lsl3()
const {
return isSImm<9, 3>(); }
255 bool isSImm10()
const {
return isSImm<10>(); }
256 bool isSImm10lsl2()
const {
return isSImm<10, 2>(); }
257 bool isSImm11lsl1()
const {
return isSImm<11, 1>(); }
258 bool isSImm12()
const {
return isSImm<12>(); }
260 bool isSImm12addlike()
const {
266 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
272 ? isInt<12>(Imm) && IsValidKind
273 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
277 bool isSImm12lu52id()
const {
283 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
293 ? isInt<12>(Imm) && IsValidKind
294 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
298 bool isUImm12()
const {
return isUImm<12>(); }
300 bool isUImm12ori()
const {
306 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
316 ? isUInt<12>(Imm) && IsValidKind
317 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
321 bool isSImm13()
const {
return isSImm<13>(); }
322 bool isUImm14()
const {
return isUImm<14>(); }
323 bool isUImm15()
const {
return isUImm<15>(); }
325 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
326 bool isSImm16()
const {
return isSImm<16>(); }
328 bool isSImm16lsl2()
const {
334 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
339 ? isShiftedInt<16, 2>(Imm) && IsValidKind
340 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
344 bool isSImm20()
const {
return isSImm<20>(); }
346 bool isSImm20pcalau12i()
const {
352 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
360 ? isInt<20>(Imm) && IsValidKind
361 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
365 bool isSImm20lu12iw()
const {
371 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
380 ? isInt<20>(Imm) && IsValidKind
381 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
385 bool isSImm20lu32id()
const {
391 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
402 ? isInt<20>(Imm) && IsValidKind
403 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
407 bool isSImm20pcaddu18i()
const {
413 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
418 ? isInt<20>(Imm) && IsValidKind
419 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
423 bool isSImm21lsl2()
const {
429 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
433 ? isShiftedInt<21, 2>(Imm) && IsValidKind
434 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
438 bool isSImm26Operand()
const {
444 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
450 ? isShiftedInt<26, 2>(Imm) && IsValidKind
451 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
455 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
456 bool isImm64()
const {
461 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
471 assert(Kind == KindTy::Register &&
"Invalid type access!");
475 const MCExpr *getImm()
const {
476 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
481 assert(Kind == KindTy::Token &&
"Invalid type access!");
494 case KindTy::Immediate:
497 case KindTy::Register:
501 OS <<
"'" << getToken() <<
"'";
506 static std::unique_ptr<LoongArchOperand> createToken(
StringRef Str,
SMLoc S) {
507 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
514 static std::unique_ptr<LoongArchOperand> createReg(
unsigned RegNo,
SMLoc S,
516 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
517 Op->Reg.RegNum = RegNo;
523 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val,
SMLoc S,
525 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
533 if (
auto CE = dyn_cast<MCConstantExpr>(Expr))
540 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
541 assert(
N == 1 &&
"Invalid number of operands!");
544 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
545 assert(
N == 1 &&
"Invalid number of operands!");
546 addExpr(Inst, getImm());
551#define GET_REGISTER_MATCHER
552#define GET_SUBTARGET_FEATURE_NAME
553#define GET_MATCHER_IMPLEMENTATION
554#define GET_MNEMONIC_SPELL_CHECKER
555#include "LoongArchGenAsmMatcher.inc"
558 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
559 return Reg - LoongArch::F0 + LoongArch::F0_64;
569 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
571 static_assert(LoongArch::F0 < LoongArch::F0_64,
572 "FPR matching must be updated");
573 if (RegNo == LoongArch::NoRegister)
576 return RegNo == LoongArch::NoRegister;
581 return Error(getLoc(),
"invalid register number");
590bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
595 Kind = RE->getKind();
596 Expr = RE->getSubExpr();
614 if (RegNo == LoongArch::NoRegister)
620 Operands.push_back(LoongArchOperand::createReg(RegNo, S,
E));
630 switch (getLexer().getKind()) {
642 if (getParser().parseExpression(Res,
E))
646 return parseOperandWithModifier(
Operands);
649 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
659 return Error(getLoc(),
"expected '%' for operand modifier");
664 return Error(getLoc(),
"expected valid identifier for operand modifier");
669 return Error(getLoc(),
"unrecognized operand modifier");
673 return Error(getLoc(),
"expected '('");
677 if (getParser().parseParenExpression(SubExpr,
E))
681 Operands.push_back(LoongArchOperand::createImm(ModExpr, S,
E));
690 return parseOperandWithModifier(
Operands);
696 if (getParser().parseIdentifier(Identifier))
701 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
705 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
711 if (!parseRegister(
Operands).isSuccess())
718 SMLoc ImmStart = getLoc();
719 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
722 return Error(ImmStart,
"optional integer offset must be 0");
734 MatchOperandParserImpl(
Operands, Mnemonic,
true);
740 if (parseRegister(
Operands).isSuccess() ||
745 return Error(getLoc(),
"unknown operand");
752 Operands.push_back(LoongArchOperand::createToken(
Name, NameLoc));
771 SMLoc Loc = getLexer().getLoc();
772 getParser().eatToEndOfStatement();
773 return Error(Loc,
"unexpected token");
782 for (LoongArchAsmParser::Inst &Inst : Insts) {
783 unsigned Opc = Inst.Opc;
790 case LoongArch::PCALAU12I:
791 case LoongArch::LU12I_W:
796 case LoongArch::ADDI_W:
797 case LoongArch::LD_W:
798 case LoongArch::LD_D: {
801 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addImm(0),
806 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
810 case LoongArch::LU32I_D:
812 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
813 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
817 case LoongArch::LU52I_D:
819 MCInstBuilder(Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
822 case LoongArch::ADDI_D:
826 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
830 case LoongArch::ADD_D:
831 case LoongArch::LDX_D:
833 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
840void LoongArchAsmParser::emitLoadAddressAbs(
MCInst &Inst,
SMLoc IDLoc,
856 Insts.push_back(LoongArchAsmParser::Inst(
858 Insts.push_back(LoongArchAsmParser::Inst(
862 Insts.push_back(LoongArchAsmParser::Inst(
864 Insts.push_back(LoongArchAsmParser::Inst(
868 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
871void LoongArchAsmParser::emitLoadAddressPcrel(
MCInst &Inst,
SMLoc IDLoc,
880 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
882 Insts.push_back(LoongArchAsmParser::Inst(
887 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
true);
890void LoongArchAsmParser::emitLoadAddressPcrelLarge(
MCInst &Inst,
SMLoc IDLoc,
904 Insts.push_back(LoongArchAsmParser::Inst(
906 Insts.push_back(LoongArchAsmParser::Inst(
908 Insts.push_back(LoongArchAsmParser::Inst(
910 Insts.push_back(LoongArchAsmParser::Inst(
912 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
914 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
917void LoongArchAsmParser::emitLoadAddressGot(
MCInst &Inst,
SMLoc IDLoc,
926 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
928 Insts.push_back(LoongArchAsmParser::Inst(
933 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
true);
936void LoongArchAsmParser::emitLoadAddressGotLarge(
MCInst &Inst,
SMLoc IDLoc,
950 Insts.push_back(LoongArchAsmParser::Inst(
952 Insts.push_back(LoongArchAsmParser::Inst(
954 Insts.push_back(LoongArchAsmParser::Inst(
956 Insts.push_back(LoongArchAsmParser::Inst(
958 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
960 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
963void LoongArchAsmParser::emitLoadAddressTLSLE(
MCInst &Inst,
SMLoc IDLoc,
973 Insts.push_back(LoongArchAsmParser::Inst(
975 Insts.push_back(LoongArchAsmParser::Inst(
978 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
981void LoongArchAsmParser::emitLoadAddressTLSIE(
MCInst &Inst,
SMLoc IDLoc,
990 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
992 Insts.push_back(LoongArchAsmParser::Inst(
994 Insts.push_back(LoongArchAsmParser::Inst(
997 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1000void LoongArchAsmParser::emitLoadAddressTLSIELarge(
MCInst &Inst,
SMLoc IDLoc,
1014 Insts.push_back(LoongArchAsmParser::Inst(
1016 Insts.push_back(LoongArchAsmParser::Inst(
1018 Insts.push_back(LoongArchAsmParser::Inst(
1020 Insts.push_back(LoongArchAsmParser::Inst(
1022 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1024 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1027void LoongArchAsmParser::emitLoadAddressTLSLD(
MCInst &Inst,
SMLoc IDLoc,
1036 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1038 Insts.push_back(LoongArchAsmParser::Inst(
1040 Insts.push_back(LoongArchAsmParser::Inst(
1043 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1046void LoongArchAsmParser::emitLoadAddressTLSLDLarge(
MCInst &Inst,
SMLoc IDLoc,
1060 Insts.push_back(LoongArchAsmParser::Inst(
1062 Insts.push_back(LoongArchAsmParser::Inst(
1064 Insts.push_back(LoongArchAsmParser::Inst(
1066 Insts.push_back(LoongArchAsmParser::Inst(
1068 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1070 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1073void LoongArchAsmParser::emitLoadAddressTLSGD(
MCInst &Inst,
SMLoc IDLoc,
1082 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1084 Insts.push_back(LoongArchAsmParser::Inst(
1086 Insts.push_back(LoongArchAsmParser::Inst(
1089 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1092void LoongArchAsmParser::emitLoadAddressTLSGDLarge(
MCInst &Inst,
SMLoc IDLoc,
1106 Insts.push_back(LoongArchAsmParser::Inst(
1108 Insts.push_back(LoongArchAsmParser::Inst(
1110 Insts.push_back(LoongArchAsmParser::Inst(
1112 Insts.push_back(LoongArchAsmParser::Inst(
1114 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1116 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1119void LoongArchAsmParser::emitLoadImm(
MCInst &Inst,
SMLoc IDLoc,
1125 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1126 Imm = SignExtend64<32>(Imm);
1129 unsigned Opc = Inst.Opc;
1130 if (Opc == LoongArch::LU12I_W)
1135 MCInstBuilder(Opc).addReg(DestReg).addReg(SrcReg).addImm(Inst.Imm),
1141void LoongArchAsmParser::emitFuncCall36(
MCInst &Inst,
SMLoc IDLoc,
1152 unsigned ScratchReg =
1160 MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),
1164 .addReg(IsTailCall ? (
unsigned)LoongArch::R0 : ScratchReg)
1170bool LoongArchAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1177 case LoongArch::PseudoLA_ABS:
1178 case LoongArch::PseudoLA_ABS_LARGE:
1179 emitLoadAddressAbs(Inst, IDLoc, Out);
1181 case LoongArch::PseudoLA_PCREL:
1182 emitLoadAddressPcrel(Inst, IDLoc, Out);
1184 case LoongArch::PseudoLA_PCREL_LARGE:
1185 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1187 case LoongArch::PseudoLA_GOT:
1188 emitLoadAddressGot(Inst, IDLoc, Out);
1190 case LoongArch::PseudoLA_GOT_LARGE:
1191 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1193 case LoongArch::PseudoLA_TLS_LE:
1194 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1196 case LoongArch::PseudoLA_TLS_IE:
1197 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1199 case LoongArch::PseudoLA_TLS_IE_LARGE:
1200 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1202 case LoongArch::PseudoLA_TLS_LD:
1203 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1205 case LoongArch::PseudoLA_TLS_LD_LARGE:
1206 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1208 case LoongArch::PseudoLA_TLS_GD:
1209 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1211 case LoongArch::PseudoLA_TLS_GD_LARGE:
1212 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1214 case LoongArch::PseudoLI_W:
1215 case LoongArch::PseudoLI_D:
1216 emitLoadImm(Inst, IDLoc, Out);
1218 case LoongArch::PseudoCALL36:
1219 emitFuncCall36(Inst, IDLoc, Out,
false);
1221 case LoongArch::PseudoTAIL36:
1222 emitFuncCall36(Inst, IDLoc, Out,
true);
1229unsigned LoongArchAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1233 if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) {
1237 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1238 return Match_RequiresAMORdDifferRkRj;
1241 case LoongArch::PseudoLA_PCREL_LARGE:
1242 case LoongArch::PseudoLA_GOT_LARGE:
1243 case LoongArch::PseudoLA_TLS_IE_LARGE:
1244 case LoongArch::PseudoLA_TLS_LD_LARGE:
1245 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1249 return Match_RequiresLAORdDifferRj;
1252 case LoongArch::CSRXCHG:
1253 case LoongArch::GCSRXCHG: {
1255 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1256 return Match_RequiresOpnd2NotR0R1;
1257 return Match_Success;
1259 case LoongArch::BSTRINS_W:
1260 case LoongArch::BSTRINS_D:
1261 case LoongArch::BSTRPICK_W:
1262 case LoongArch::BSTRPICK_D: {
1265 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1269 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1273 return Match_RequiresMsbNotLessThanLsb;
1274 return Match_Success;
1278 return Match_Success;
1284 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1286 return Match_InvalidOperand;
1291 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1292 Kind == MCK_FPR64) {
1294 return Match_Success;
1297 return Match_InvalidOperand;
1300bool LoongArchAsmParser::generateImmOutOfRangeError(
1302 const Twine &Msg =
"immediate must be an integer in the range") {
1307bool LoongArchAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1311 bool MatchingInlineAsm) {
1321 return processInstruction(Inst, IDLoc,
Operands, Out);
1322 case Match_MissingFeature: {
1323 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1324 bool FirstFeature =
true;
1325 std::string
Msg =
"instruction requires the following:";
1326 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1327 if (MissingFeatures[i]) {
1328 Msg += FirstFeature ?
" " :
", ";
1330 FirstFeature =
false;
1333 return Error(IDLoc, Msg);
1335 case Match_MnemonicFail: {
1336 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1337 std::string Suggestion = LoongArchMnemonicSpellCheck(
1338 ((LoongArchOperand &)*
Operands[0]).getToken(), FBS, 0);
1339 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1341 case Match_InvalidOperand: {
1342 SMLoc ErrorLoc = IDLoc;
1345 return Error(ErrorLoc,
"too few operands for instruction");
1348 if (ErrorLoc ==
SMLoc())
1351 return Error(ErrorLoc,
"invalid operand for instruction");
1358 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1359 SMLoc ErrorLoc = IDLoc;
1361 return Error(ErrorLoc,
"too few operands for instruction");
1367 case Match_RequiresMsbNotLessThanLsb: {
1369 return Error(ErrorStart,
"msb is less than lsb",
1372 case Match_RequiresOpnd2NotR0R1:
1373 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1374 case Match_RequiresAMORdDifferRkRj:
1376 "$rd must be different from both $rk and $rj");
1377 case Match_RequiresLAORdDifferRj:
1378 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1379 case Match_InvalidUImm1:
1382 case Match_InvalidUImm2:
1385 case Match_InvalidUImm2plus1:
1388 case Match_InvalidUImm3:
1391 case Match_InvalidUImm4:
1394 case Match_InvalidUImm5:
1397 case Match_InvalidUImm6:
1400 case Match_InvalidUImm7:
1403 case Match_InvalidUImm8:
1406 case Match_InvalidUImm12:
1409 case Match_InvalidUImm12ori:
1410 return generateImmOutOfRangeError(
1413 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1414 "integer in the range");
1415 case Match_InvalidUImm14:
1418 case Match_InvalidUImm15:
1421 case Match_InvalidSImm5:
1424 case Match_InvalidSImm8:
1427 case Match_InvalidSImm8lsl1:
1428 return generateImmOutOfRangeError(
1430 "immediate must be a multiple of 2 in the range");
1431 case Match_InvalidSImm8lsl2:
1432 return generateImmOutOfRangeError(
1434 "immediate must be a multiple of 4 in the range");
1435 case Match_InvalidSImm10:
1438 case Match_InvalidSImm8lsl3:
1439 return generateImmOutOfRangeError(
1441 "immediate must be a multiple of 8 in the range");
1442 case Match_InvalidSImm9lsl3:
1443 return generateImmOutOfRangeError(
1445 "immediate must be a multiple of 8 in the range");
1446 case Match_InvalidSImm10lsl2:
1447 return generateImmOutOfRangeError(
1449 "immediate must be a multiple of 4 in the range");
1450 case Match_InvalidSImm11lsl1:
1451 return generateImmOutOfRangeError(
1453 "immediate must be a multiple of 2 in the range");
1454 case Match_InvalidSImm12:
1457 case Match_InvalidSImm12addlike:
1458 return generateImmOutOfRangeError(
1461 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1463 case Match_InvalidSImm12lu52id:
1464 return generateImmOutOfRangeError(
1467 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1468 "integer in the range");
1469 case Match_InvalidSImm13:
1472 case Match_InvalidSImm14lsl2:
1473 return generateImmOutOfRangeError(
1475 "immediate must be a multiple of 4 in the range");
1476 case Match_InvalidSImm16:
1479 case Match_InvalidSImm16lsl2:
1480 return generateImmOutOfRangeError(
1482 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1484 case Match_InvalidSImm20:
1487 case Match_InvalidSImm20lu12iw:
1488 return generateImmOutOfRangeError(
1491 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1493 case Match_InvalidSImm20lu32id:
1494 return generateImmOutOfRangeError(
1497 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1498 "integer in the range");
1499 case Match_InvalidSImm20pcalau12i:
1500 return generateImmOutOfRangeError(
1503 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1505 case Match_InvalidSImm20pcaddu18i:
1506 return generateImmOutOfRangeError(
1509 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1511 case Match_InvalidSImm21lsl2:
1512 return generateImmOutOfRangeError(
1514 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1516 case Match_InvalidSImm26Operand:
1517 return generateImmOutOfRangeError(
1519 "operand must be a bare symbol name or an immediate must be a multiple "
1520 "of 4 in the range");
1521 case Match_InvalidImm32: {
1523 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1525 case Match_InvalidImm64: {
1527 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
1529 case Match_InvalidBareSymbol: {
1531 return Error(ErrorLoc,
"operand must be a bare symbol name");
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
static MCRegister 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)
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 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
static const LoongArchMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx, bool Hint=false)
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 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 MCRegister getReg() const =0
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,...