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 void emitLoadAddressTLSDescPcrelLarge(
MCInst &Inst,
SMLoc IDLoc,
136 enum LoongArchMatchResultTy {
138 Match_RequiresMsbNotLessThanLsb,
139 Match_RequiresOpnd2NotR0R1,
140 Match_RequiresAMORdDifferRkRj,
141 Match_RequiresLAORdDifferRj,
142 Match_RequiresLAORdR4,
143#define GET_OPERAND_DIAGNOSTIC_TYPES
144#include "LoongArchGenAsmMatcher.inc"
145#undef GET_OPERAND_DIAGNOSTIC_TYPES
148 static bool classifySymbolRef(
const MCExpr *Expr,
180 SMLoc StartLoc, EndLoc;
190 bool isToken()
const override {
return Kind == KindTy::Token; }
191 bool isReg()
const override {
return Kind == KindTy::Register; }
192 bool isImm()
const override {
return Kind == KindTy::Immediate; }
193 bool isMem()
const override {
return false; }
196 return Kind == KindTy::Register &&
197 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(
201 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
203 if (
auto *LE = dyn_cast<LoongArchMCExpr>(Expr)) {
208 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
209 Imm =
CE->getValue();
216 template <
unsigned N,
int P = 0>
bool isUImm()
const {
222 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
223 return IsConstantImm && isUInt<N>(Imm -
P) &&
227 template <
unsigned N,
unsigned S = 0>
bool isSImm()
const {
233 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
234 return IsConstantImm && isShiftedInt<N, S>(Imm) &&
238 bool isBareSymbol()
const {
242 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
244 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
248 bool isUImm1()
const {
return isUImm<1>(); }
249 bool isUImm2()
const {
return isUImm<2>(); }
250 bool isUImm2plus1()
const {
return isUImm<2, 1>(); }
251 bool isUImm3()
const {
return isUImm<3>(); }
252 bool isUImm4()
const {
return isUImm<4>(); }
253 bool isSImm5()
const {
return isSImm<5>(); }
254 bool isUImm5()
const {
return isUImm<5>(); }
255 bool isUImm6()
const {
return isUImm<6>(); }
256 bool isUImm7()
const {
return isUImm<7>(); }
257 bool isSImm8()
const {
return isSImm<8>(); }
258 bool isSImm8lsl1()
const {
return isSImm<8, 1>(); }
259 bool isSImm8lsl2()
const {
return isSImm<8, 2>(); }
260 bool isSImm8lsl3()
const {
return isSImm<8, 3>(); }
261 bool isUImm8()
const {
return isUImm<8>(); }
262 bool isSImm9lsl3()
const {
return isSImm<9, 3>(); }
263 bool isSImm10()
const {
return isSImm<10>(); }
264 bool isSImm10lsl2()
const {
return isSImm<10, 2>(); }
265 bool isSImm11lsl1()
const {
return isSImm<11, 1>(); }
266 bool isSImm12()
const {
return isSImm<12>(); }
268 bool isSImm12addlike()
const {
274 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
282 ? isInt<12>(Imm) && IsValidKind
283 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
287 bool isSImm12lu52id()
const {
293 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
305 ? isInt<12>(Imm) && IsValidKind
306 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
310 bool isUImm12()
const {
return isUImm<12>(); }
312 bool isUImm12ori()
const {
318 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
329 ? isUInt<12>(Imm) && IsValidKind
330 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
334 bool isSImm13()
const {
return isSImm<13>(); }
335 bool isUImm14()
const {
return isUImm<14>(); }
336 bool isUImm15()
const {
return isUImm<15>(); }
338 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
339 bool isSImm16()
const {
return isSImm<16>(); }
341 bool isSImm16lsl2()
const {
347 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
353 ? isShiftedInt<16, 2>(Imm) && IsValidKind
354 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
358 bool isSImm20()
const {
return isSImm<20>(); }
360 bool isSImm20pcalau12i()
const {
366 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
375 ? isInt<20>(Imm) && IsValidKind
376 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
380 bool isSImm20lu12iw()
const {
386 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
396 ? isInt<20>(Imm) && IsValidKind
397 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
401 bool isSImm20lu32id()
const {
407 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
420 ? isInt<20>(Imm) && IsValidKind
421 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
425 bool isSImm20pcaddu18i()
const {
431 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
436 ? isInt<20>(Imm) && IsValidKind
437 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
441 bool isSImm21lsl2()
const {
447 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
451 ? isShiftedInt<21, 2>(Imm) && IsValidKind
452 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
456 bool isSImm26Operand()
const {
462 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
468 ? isShiftedInt<26, 2>(Imm) && IsValidKind
469 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
473 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
474 bool isImm64()
const {
479 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
489 assert(Kind == KindTy::Register &&
"Invalid type access!");
493 const MCExpr *getImm()
const {
494 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
499 assert(Kind == KindTy::Token &&
"Invalid type access!");
512 case KindTy::Immediate:
515 case KindTy::Register:
519 OS <<
"'" << getToken() <<
"'";
524 static std::unique_ptr<LoongArchOperand> createToken(
StringRef Str,
SMLoc S) {
525 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
532 static std::unique_ptr<LoongArchOperand> createReg(
unsigned RegNo,
SMLoc S,
534 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
535 Op->Reg.RegNum = RegNo;
541 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val,
SMLoc S,
543 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
551 if (
auto CE = dyn_cast<MCConstantExpr>(Expr))
558 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
559 assert(
N == 1 &&
"Invalid number of operands!");
562 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
563 assert(
N == 1 &&
"Invalid number of operands!");
564 addExpr(Inst, getImm());
569#define GET_REGISTER_MATCHER
570#define GET_SUBTARGET_FEATURE_NAME
571#define GET_MATCHER_IMPLEMENTATION
572#define GET_MNEMONIC_SPELL_CHECKER
573#include "LoongArchGenAsmMatcher.inc"
576 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
577 return Reg - LoongArch::F0 + LoongArch::F0_64;
587 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
589 static_assert(LoongArch::F0 < LoongArch::F0_64,
590 "FPR matching must be updated");
591 if (RegNo == LoongArch::NoRegister)
594 return RegNo == LoongArch::NoRegister;
599 return Error(getLoc(),
"invalid register number");
608bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
613 Kind = RE->getKind();
614 Expr = RE->getSubExpr();
632 if (RegNo == LoongArch::NoRegister)
638 Operands.push_back(LoongArchOperand::createReg(RegNo, S,
E));
648 switch (getLexer().getKind()) {
660 if (getParser().parseExpression(Res,
E))
664 return parseOperandWithModifier(
Operands);
667 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
677 return Error(getLoc(),
"expected '%' for operand modifier");
682 return Error(getLoc(),
"expected valid identifier for operand modifier");
687 return Error(getLoc(),
"unrecognized operand modifier");
691 return Error(getLoc(),
"expected '('");
695 if (getParser().parseParenExpression(SubExpr,
E))
699 Operands.push_back(LoongArchOperand::createImm(ModExpr, S,
E));
708 return parseOperandWithModifier(
Operands);
714 if (getParser().parseIdentifier(Identifier))
719 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
723 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
729 if (!parseRegister(
Operands).isSuccess())
736 SMLoc ImmStart = getLoc();
737 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
740 return Error(ImmStart,
"optional integer offset must be 0");
752 MatchOperandParserImpl(
Operands, Mnemonic,
true);
758 if (parseRegister(
Operands).isSuccess() ||
763 return Error(getLoc(),
"unknown operand");
770 Operands.push_back(LoongArchOperand::createToken(
Name, NameLoc));
789 SMLoc Loc = getLexer().getLoc();
790 getParser().eatToEndOfStatement();
791 return Error(Loc,
"unexpected token");
800 for (LoongArchAsmParser::Inst &Inst : Insts) {
801 unsigned Opc = Inst.Opc;
808 case LoongArch::PCALAU12I:
809 case LoongArch::LU12I_W:
814 case LoongArch::ADDI_W:
815 case LoongArch::LD_W:
816 case LoongArch::LD_D: {
819 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addImm(0),
824 .addReg(LoongArch::R1)
831 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
835 case LoongArch::LU32I_D:
837 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
838 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
842 case LoongArch::LU52I_D:
844 MCInstBuilder(Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
847 case LoongArch::ADDI_D:
851 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
855 case LoongArch::ADD_D:
856 case LoongArch::LDX_D:
858 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
861 case LoongArch::JIRL:
863 .addReg(LoongArch::R1)
864 .addReg(LoongArch::R1)
872void LoongArchAsmParser::emitLoadAddressAbs(
MCInst &Inst,
SMLoc IDLoc,
888 Insts.push_back(LoongArchAsmParser::Inst(
890 Insts.push_back(LoongArchAsmParser::Inst(
894 Insts.push_back(LoongArchAsmParser::Inst(
896 Insts.push_back(LoongArchAsmParser::Inst(
900 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
903void LoongArchAsmParser::emitLoadAddressPcrel(
MCInst &Inst,
SMLoc IDLoc,
912 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
914 Insts.push_back(LoongArchAsmParser::Inst(
919 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
true);
922void LoongArchAsmParser::emitLoadAddressPcrelLarge(
MCInst &Inst,
SMLoc IDLoc,
936 Insts.push_back(LoongArchAsmParser::Inst(
938 Insts.push_back(LoongArchAsmParser::Inst(
940 Insts.push_back(LoongArchAsmParser::Inst(
942 Insts.push_back(LoongArchAsmParser::Inst(
944 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
946 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
949void LoongArchAsmParser::emitLoadAddressGot(
MCInst &Inst,
SMLoc IDLoc,
958 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
960 Insts.push_back(LoongArchAsmParser::Inst(
965 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
true);
968void LoongArchAsmParser::emitLoadAddressGotLarge(
MCInst &Inst,
SMLoc IDLoc,
982 Insts.push_back(LoongArchAsmParser::Inst(
984 Insts.push_back(LoongArchAsmParser::Inst(
986 Insts.push_back(LoongArchAsmParser::Inst(
988 Insts.push_back(LoongArchAsmParser::Inst(
990 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
992 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
995void LoongArchAsmParser::emitLoadAddressTLSLE(
MCInst &Inst,
SMLoc IDLoc,
1005 Insts.push_back(LoongArchAsmParser::Inst(
1007 Insts.push_back(LoongArchAsmParser::Inst(
1010 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1013void LoongArchAsmParser::emitLoadAddressTLSIE(
MCInst &Inst,
SMLoc IDLoc,
1022 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1024 Insts.push_back(LoongArchAsmParser::Inst(
1026 Insts.push_back(LoongArchAsmParser::Inst(
1029 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1032void LoongArchAsmParser::emitLoadAddressTLSIELarge(
MCInst &Inst,
SMLoc IDLoc,
1046 Insts.push_back(LoongArchAsmParser::Inst(
1048 Insts.push_back(LoongArchAsmParser::Inst(
1050 Insts.push_back(LoongArchAsmParser::Inst(
1052 Insts.push_back(LoongArchAsmParser::Inst(
1054 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1056 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1059void LoongArchAsmParser::emitLoadAddressTLSLD(
MCInst &Inst,
SMLoc IDLoc,
1068 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1070 Insts.push_back(LoongArchAsmParser::Inst(
1072 Insts.push_back(LoongArchAsmParser::Inst(
1075 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1078void LoongArchAsmParser::emitLoadAddressTLSLDLarge(
MCInst &Inst,
SMLoc IDLoc,
1092 Insts.push_back(LoongArchAsmParser::Inst(
1094 Insts.push_back(LoongArchAsmParser::Inst(
1096 Insts.push_back(LoongArchAsmParser::Inst(
1098 Insts.push_back(LoongArchAsmParser::Inst(
1100 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1102 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1105void LoongArchAsmParser::emitLoadAddressTLSGD(
MCInst &Inst,
SMLoc IDLoc,
1114 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1116 Insts.push_back(LoongArchAsmParser::Inst(
1118 Insts.push_back(LoongArchAsmParser::Inst(
1121 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1124void LoongArchAsmParser::emitLoadAddressTLSGDLarge(
MCInst &Inst,
SMLoc IDLoc,
1138 Insts.push_back(LoongArchAsmParser::Inst(
1140 Insts.push_back(LoongArchAsmParser::Inst(
1142 Insts.push_back(LoongArchAsmParser::Inst(
1144 Insts.push_back(LoongArchAsmParser::Inst(
1146 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1148 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1151void LoongArchAsmParser::emitLoadAddressTLSDescAbs(
MCInst &Inst,
SMLoc IDLoc,
1171 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1174 Insts.push_back(LoongArchAsmParser::Inst(
1176 Insts.push_back(LoongArchAsmParser::Inst(
1180 Insts.push_back(LoongArchAsmParser::Inst(
1182 Insts.push_back(LoongArchAsmParser::Inst(
1188 Insts.push_back(LoongArchAsmParser::Inst(
1191 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1194void LoongArchAsmParser::emitLoadAddressTLSDescPcrel(
MCInst &Inst,
SMLoc IDLoc,
1204 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1205 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1208 Insts.push_back(LoongArchAsmParser::Inst(
1210 Insts.push_back(LoongArchAsmParser::Inst(
1214 Insts.push_back(LoongArchAsmParser::Inst(
1217 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1220void LoongArchAsmParser::emitLoadAddressTLSDescPcrelLarge(
MCInst &Inst,
1237 Insts.push_back(LoongArchAsmParser::Inst(
1239 Insts.push_back(LoongArchAsmParser::Inst(
1241 Insts.push_back(LoongArchAsmParser::Inst(
1243 Insts.push_back(LoongArchAsmParser::Inst(
1245 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1246 Insts.push_back(LoongArchAsmParser::Inst(
1248 Insts.push_back(LoongArchAsmParser::Inst(
1251 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1254void LoongArchAsmParser::emitLoadImm(
MCInst &Inst,
SMLoc IDLoc,
1260 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1261 Imm = SignExtend64<32>(Imm);
1264 unsigned Opc = Inst.Opc;
1265 if (Opc == LoongArch::LU12I_W)
1270 MCInstBuilder(Opc).addReg(DestReg).addReg(SrcReg).addImm(Inst.Imm),
1276void LoongArchAsmParser::emitFuncCall36(
MCInst &Inst,
SMLoc IDLoc,
1287 unsigned ScratchReg =
1295 MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),
1299 .addReg(IsTailCall ? (
unsigned)LoongArch::R0 : ScratchReg)
1305bool LoongArchAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1312 case LoongArch::PseudoLA_ABS:
1313 case LoongArch::PseudoLA_ABS_LARGE:
1314 emitLoadAddressAbs(Inst, IDLoc, Out);
1316 case LoongArch::PseudoLA_PCREL:
1317 emitLoadAddressPcrel(Inst, IDLoc, Out);
1319 case LoongArch::PseudoLA_PCREL_LARGE:
1320 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1322 case LoongArch::PseudoLA_GOT:
1323 emitLoadAddressGot(Inst, IDLoc, Out);
1325 case LoongArch::PseudoLA_GOT_LARGE:
1326 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1328 case LoongArch::PseudoLA_TLS_LE:
1329 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1331 case LoongArch::PseudoLA_TLS_IE:
1332 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1334 case LoongArch::PseudoLA_TLS_IE_LARGE:
1335 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1337 case LoongArch::PseudoLA_TLS_LD:
1338 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1340 case LoongArch::PseudoLA_TLS_LD_LARGE:
1341 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1343 case LoongArch::PseudoLA_TLS_GD:
1344 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1346 case LoongArch::PseudoLA_TLS_GD_LARGE:
1347 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1349 case LoongArch::PseudoLA_TLS_DESC_ABS:
1350 case LoongArch::PseudoLA_TLS_DESC_ABS_LARGE:
1351 emitLoadAddressTLSDescAbs(Inst, IDLoc, Out);
1353 case LoongArch::PseudoLA_TLS_DESC_PC:
1354 emitLoadAddressTLSDescPcrel(Inst, IDLoc, Out);
1356 case LoongArch::PseudoLA_TLS_DESC_PC_LARGE:
1357 emitLoadAddressTLSDescPcrelLarge(Inst, IDLoc, Out);
1359 case LoongArch::PseudoLI_W:
1360 case LoongArch::PseudoLI_D:
1361 emitLoadImm(Inst, IDLoc, Out);
1363 case LoongArch::PseudoCALL36:
1364 emitFuncCall36(Inst, IDLoc, Out,
false);
1366 case LoongArch::PseudoTAIL36:
1367 emitFuncCall36(Inst, IDLoc, Out,
true);
1374unsigned LoongArchAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1378 if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) {
1382 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1383 return Match_RequiresAMORdDifferRkRj;
1386 case LoongArch::PseudoLA_TLS_DESC_ABS:
1387 case LoongArch::PseudoLA_TLS_DESC_ABS_LARGE:
1388 case LoongArch::PseudoLA_TLS_DESC_PC:
1389 case LoongArch::PseudoLA_TLS_DESC_PC_LARGE: {
1391 if (Rd != LoongArch::R4)
1392 return Match_RequiresLAORdR4;
1395 case LoongArch::PseudoLA_PCREL_LARGE:
1396 case LoongArch::PseudoLA_GOT_LARGE:
1397 case LoongArch::PseudoLA_TLS_IE_LARGE:
1398 case LoongArch::PseudoLA_TLS_LD_LARGE:
1399 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1403 return Match_RequiresLAORdDifferRj;
1406 case LoongArch::CSRXCHG:
1407 case LoongArch::GCSRXCHG: {
1409 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1410 return Match_RequiresOpnd2NotR0R1;
1411 return Match_Success;
1413 case LoongArch::BSTRINS_W:
1414 case LoongArch::BSTRINS_D:
1415 case LoongArch::BSTRPICK_W:
1416 case LoongArch::BSTRPICK_D: {
1419 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1423 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1427 return Match_RequiresMsbNotLessThanLsb;
1428 return Match_Success;
1432 return Match_Success;
1438 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1440 return Match_InvalidOperand;
1445 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1446 Kind == MCK_FPR64) {
1448 return Match_Success;
1451 return Match_InvalidOperand;
1454bool LoongArchAsmParser::generateImmOutOfRangeError(
1456 const Twine &Msg =
"immediate must be an integer in the range") {
1461bool LoongArchAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1465 bool MatchingInlineAsm) {
1475 return processInstruction(Inst, IDLoc,
Operands, Out);
1476 case Match_MissingFeature: {
1477 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1478 bool FirstFeature =
true;
1479 std::string
Msg =
"instruction requires the following:";
1480 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1481 if (MissingFeatures[i]) {
1482 Msg += FirstFeature ?
" " :
", ";
1484 FirstFeature =
false;
1487 return Error(IDLoc, Msg);
1489 case Match_MnemonicFail: {
1490 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1491 std::string Suggestion = LoongArchMnemonicSpellCheck(
1492 ((LoongArchOperand &)*
Operands[0]).getToken(), FBS, 0);
1493 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1495 case Match_InvalidOperand: {
1496 SMLoc ErrorLoc = IDLoc;
1499 return Error(ErrorLoc,
"too few operands for instruction");
1502 if (ErrorLoc ==
SMLoc())
1505 return Error(ErrorLoc,
"invalid operand for instruction");
1512 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1513 SMLoc ErrorLoc = IDLoc;
1515 return Error(ErrorLoc,
"too few operands for instruction");
1521 case Match_RequiresMsbNotLessThanLsb: {
1523 return Error(ErrorStart,
"msb is less than lsb",
1526 case Match_RequiresOpnd2NotR0R1:
1527 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1528 case Match_RequiresAMORdDifferRkRj:
1530 "$rd must be different from both $rk and $rj");
1531 case Match_RequiresLAORdDifferRj:
1532 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1533 case Match_RequiresLAORdR4:
1534 return Error(
Operands[1]->getStartLoc(),
"$rd must be $r4");
1535 case Match_InvalidUImm1:
1538 case Match_InvalidUImm2:
1541 case Match_InvalidUImm2plus1:
1544 case Match_InvalidUImm3:
1547 case Match_InvalidUImm4:
1550 case Match_InvalidUImm5:
1553 case Match_InvalidUImm6:
1556 case Match_InvalidUImm7:
1559 case Match_InvalidUImm8:
1562 case Match_InvalidUImm12:
1565 case Match_InvalidUImm12ori:
1566 return generateImmOutOfRangeError(
1569 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1570 "integer in the range");
1571 case Match_InvalidUImm14:
1574 case Match_InvalidUImm15:
1577 case Match_InvalidSImm5:
1580 case Match_InvalidSImm8:
1583 case Match_InvalidSImm8lsl1:
1584 return generateImmOutOfRangeError(
1586 "immediate must be a multiple of 2 in the range");
1587 case Match_InvalidSImm8lsl2:
1588 return generateImmOutOfRangeError(
1590 "immediate must be a multiple of 4 in the range");
1591 case Match_InvalidSImm10:
1594 case Match_InvalidSImm8lsl3:
1595 return generateImmOutOfRangeError(
1597 "immediate must be a multiple of 8 in the range");
1598 case Match_InvalidSImm9lsl3:
1599 return generateImmOutOfRangeError(
1601 "immediate must be a multiple of 8 in the range");
1602 case Match_InvalidSImm10lsl2:
1603 return generateImmOutOfRangeError(
1605 "immediate must be a multiple of 4 in the range");
1606 case Match_InvalidSImm11lsl1:
1607 return generateImmOutOfRangeError(
1609 "immediate must be a multiple of 2 in the range");
1610 case Match_InvalidSImm12:
1613 case Match_InvalidSImm12addlike:
1614 return generateImmOutOfRangeError(
1617 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1619 case Match_InvalidSImm12lu52id:
1620 return generateImmOutOfRangeError(
1623 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1624 "integer in the range");
1625 case Match_InvalidSImm13:
1628 case Match_InvalidSImm14lsl2:
1629 return generateImmOutOfRangeError(
1631 "immediate must be a multiple of 4 in the range");
1632 case Match_InvalidSImm16:
1635 case Match_InvalidSImm16lsl2:
1636 return generateImmOutOfRangeError(
1638 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1640 case Match_InvalidSImm20:
1643 case Match_InvalidSImm20lu12iw:
1644 return generateImmOutOfRangeError(
1647 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1649 case Match_InvalidSImm20lu32id:
1650 return generateImmOutOfRangeError(
1653 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1654 "integer in the range");
1655 case Match_InvalidSImm20pcalau12i:
1656 return generateImmOutOfRangeError(
1659 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1661 case Match_InvalidSImm20pcaddu18i:
1662 return generateImmOutOfRangeError(
1665 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1667 case Match_InvalidSImm21lsl2:
1668 return generateImmOutOfRangeError(
1670 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1672 case Match_InvalidSImm26Operand:
1673 return generateImmOutOfRangeError(
1675 "operand must be a bare symbol name or an immediate must be a multiple "
1676 "of 4 in the range");
1677 case Match_InvalidImm32: {
1679 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1681 case Match_InvalidImm64: {
1683 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
1685 case Match_InvalidBareSymbol: {
1687 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_TLS_DESC_CALL
@ VK_LoongArch_GOT64_HI12
@ VK_LoongArch_PCALA_LO12
@ VK_LoongArch_TLS_DESC64_HI12
@ VK_LoongArch_TLS_IE_HI20
@ VK_LoongArch_TLS_GD_HI20
@ VK_LoongArch_TLS_DESC_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_TLS_DESC_LD
@ VK_LoongArch_TLS_DESC64_PC_LO20
@ VK_LoongArch_TLS_DESC_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_TLS_DESC_PC_LO12
@ VK_LoongArch_GOT64_LO20
@ VK_LoongArch_TLS_DESC64_LO20
@ VK_LoongArch_TLS_GD_PC_HI20
@ VK_LoongArch_TLS_DESC64_PC_HI12
@ VK_LoongArch_GOT64_PC_LO20
@ VK_LoongArch_PCALA64_HI12
@ VK_LoongArch_TLS_DESC_PC_HI20
@ 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,...