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 isTPRelAddSymbol()
const {
252 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
254 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
258 bool isUImm1()
const {
return isUImm<1>(); }
259 bool isUImm2()
const {
return isUImm<2>(); }
260 bool isUImm2plus1()
const {
return isUImm<2, 1>(); }
261 bool isUImm3()
const {
return isUImm<3>(); }
262 bool isUImm4()
const {
return isUImm<4>(); }
263 bool isSImm5()
const {
return isSImm<5>(); }
264 bool isUImm5()
const {
return isUImm<5>(); }
265 bool isUImm6()
const {
return isUImm<6>(); }
266 bool isUImm7()
const {
return isUImm<7>(); }
267 bool isSImm8()
const {
return isSImm<8>(); }
268 bool isSImm8lsl1()
const {
return isSImm<8, 1>(); }
269 bool isSImm8lsl2()
const {
return isSImm<8, 2>(); }
270 bool isSImm8lsl3()
const {
return isSImm<8, 3>(); }
271 bool isUImm8()
const {
return isUImm<8>(); }
272 bool isSImm9lsl3()
const {
return isSImm<9, 3>(); }
273 bool isSImm10()
const {
return isSImm<10>(); }
274 bool isSImm10lsl2()
const {
return isSImm<10, 2>(); }
275 bool isSImm11lsl1()
const {
return isSImm<11, 1>(); }
276 bool isSImm12()
const {
return isSImm<12>(); }
278 bool isSImm12addlike()
const {
284 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
293 ? isInt<12>(Imm) && IsValidKind
294 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
298 bool isSImm12lu52id()
const {
304 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
316 ? isInt<12>(Imm) && IsValidKind
317 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
321 bool isUImm12()
const {
return isUImm<12>(); }
323 bool isUImm12ori()
const {
329 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
340 ? isUInt<12>(Imm) && IsValidKind
341 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
345 bool isSImm13()
const {
return isSImm<13>(); }
346 bool isUImm14()
const {
return isUImm<14>(); }
347 bool isUImm15()
const {
return isUImm<15>(); }
349 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
350 bool isSImm16()
const {
return isSImm<16>(); }
352 bool isSImm16lsl2()
const {
358 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
364 ? isShiftedInt<16, 2>(Imm) && IsValidKind
365 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
369 bool isSImm20()
const {
return isSImm<20>(); }
371 bool isSImm20pcalau12i()
const {
377 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
386 ? isInt<20>(Imm) && IsValidKind
387 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
391 bool isSImm20lu12iw()
const {
397 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
408 ? isInt<20>(Imm) && IsValidKind
409 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
413 bool isSImm20lu32id()
const {
419 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
432 ? isInt<20>(Imm) && IsValidKind
433 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
437 bool isSImm20pcaddu18i()
const {
443 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
448 ? isInt<20>(Imm) && IsValidKind
449 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
453 bool isSImm20pcaddi()
const {
459 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
466 ? isInt<20>(Imm) && IsValidKind
467 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
471 bool isSImm21lsl2()
const {
477 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
481 ? isShiftedInt<21, 2>(Imm) && IsValidKind
482 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
486 bool isSImm26Operand()
const {
492 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
498 ? isShiftedInt<26, 2>(Imm) && IsValidKind
499 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
503 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
504 bool isImm64()
const {
509 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
519 assert(Kind == KindTy::Register &&
"Invalid type access!");
523 const MCExpr *getImm()
const {
524 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
529 assert(Kind == KindTy::Token &&
"Invalid type access!");
542 case KindTy::Immediate:
545 case KindTy::Register:
549 OS <<
"'" << getToken() <<
"'";
554 static std::unique_ptr<LoongArchOperand> createToken(
StringRef Str,
SMLoc S) {
555 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
562 static std::unique_ptr<LoongArchOperand> createReg(
unsigned RegNo,
SMLoc S,
564 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
565 Op->Reg.RegNum = RegNo;
571 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val,
SMLoc S,
573 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
581 if (
auto CE = dyn_cast<MCConstantExpr>(Expr))
588 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
589 assert(
N == 1 &&
"Invalid number of operands!");
592 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
593 assert(
N == 1 &&
"Invalid number of operands!");
594 addExpr(Inst, getImm());
599#define GET_REGISTER_MATCHER
600#define GET_SUBTARGET_FEATURE_NAME
601#define GET_MATCHER_IMPLEMENTATION
602#define GET_MNEMONIC_SPELL_CHECKER
603#include "LoongArchGenAsmMatcher.inc"
606 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
607 return Reg - LoongArch::F0 + LoongArch::F0_64;
617 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
619 static_assert(LoongArch::F0 < LoongArch::F0_64,
620 "FPR matching must be updated");
621 if (RegNo == LoongArch::NoRegister)
624 return RegNo == LoongArch::NoRegister;
629 return Error(getLoc(),
"invalid register number");
638bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
643 Kind = RE->getKind();
644 Expr = RE->getSubExpr();
662 if (RegNo == LoongArch::NoRegister)
668 Operands.push_back(LoongArchOperand::createReg(RegNo, S,
E));
678 switch (getLexer().getKind()) {
690 if (getParser().parseExpression(Res,
E))
694 return parseOperandWithModifier(
Operands);
697 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
707 return Error(getLoc(),
"expected '%' for operand modifier");
712 return Error(getLoc(),
"expected valid identifier for operand modifier");
717 return Error(getLoc(),
"unrecognized operand modifier");
721 return Error(getLoc(),
"expected '('");
725 if (getParser().parseParenExpression(SubExpr,
E))
729 Operands.push_back(LoongArchOperand::createImm(ModExpr, S,
E));
738 return parseOperandWithModifier(
Operands);
744 if (getParser().parseIdentifier(Identifier))
749 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
753 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
759 if (!parseRegister(
Operands).isSuccess())
766 SMLoc ImmStart = getLoc();
767 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
770 return Error(ImmStart,
"optional integer offset must be 0");
782 MatchOperandParserImpl(
Operands, Mnemonic,
true);
788 if (parseRegister(
Operands).isSuccess() ||
793 return Error(getLoc(),
"unknown operand");
800 Operands.push_back(LoongArchOperand::createToken(
Name, NameLoc));
819 SMLoc Loc = getLexer().getLoc();
820 getParser().eatToEndOfStatement();
821 return Error(Loc,
"unexpected token");
830 for (LoongArchAsmParser::Inst &Inst : Insts) {
831 unsigned Opc = Inst.Opc;
838 case LoongArch::PCALAU12I:
839 case LoongArch::LU12I_W:
844 case LoongArch::ADDI_W:
845 case LoongArch::LD_W:
846 case LoongArch::LD_D: {
849 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addImm(0),
854 .addReg(LoongArch::R1)
861 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
865 case LoongArch::LU32I_D:
867 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
868 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
872 case LoongArch::LU52I_D:
874 MCInstBuilder(Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
877 case LoongArch::ADDI_D:
881 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
885 case LoongArch::ADD_D:
886 case LoongArch::LDX_D:
888 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
891 case LoongArch::JIRL:
893 .addReg(LoongArch::R1)
894 .addReg(LoongArch::R1)
902void LoongArchAsmParser::emitLoadAddressAbs(
MCInst &Inst,
SMLoc IDLoc,
918 Insts.push_back(LoongArchAsmParser::Inst(
920 Insts.push_back(LoongArchAsmParser::Inst(
924 Insts.push_back(LoongArchAsmParser::Inst(
926 Insts.push_back(LoongArchAsmParser::Inst(
930 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
933void LoongArchAsmParser::emitLoadAddressPcrel(
MCInst &Inst,
SMLoc IDLoc,
942 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
944 Insts.push_back(LoongArchAsmParser::Inst(
949 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
true);
952void LoongArchAsmParser::emitLoadAddressPcrelLarge(
MCInst &Inst,
SMLoc IDLoc,
966 Insts.push_back(LoongArchAsmParser::Inst(
968 Insts.push_back(LoongArchAsmParser::Inst(
970 Insts.push_back(LoongArchAsmParser::Inst(
972 Insts.push_back(LoongArchAsmParser::Inst(
974 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
976 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
979void LoongArchAsmParser::emitLoadAddressGot(
MCInst &Inst,
SMLoc IDLoc,
988 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
990 Insts.push_back(LoongArchAsmParser::Inst(
995 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
true);
998void LoongArchAsmParser::emitLoadAddressGotLarge(
MCInst &Inst,
SMLoc IDLoc,
1012 Insts.push_back(LoongArchAsmParser::Inst(
1014 Insts.push_back(LoongArchAsmParser::Inst(
1016 Insts.push_back(LoongArchAsmParser::Inst(
1018 Insts.push_back(LoongArchAsmParser::Inst(
1020 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1022 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1025void LoongArchAsmParser::emitLoadAddressTLSLE(
MCInst &Inst,
SMLoc IDLoc,
1035 Insts.push_back(LoongArchAsmParser::Inst(
1037 Insts.push_back(LoongArchAsmParser::Inst(
1040 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1043void LoongArchAsmParser::emitLoadAddressTLSIE(
MCInst &Inst,
SMLoc IDLoc,
1052 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1054 Insts.push_back(LoongArchAsmParser::Inst(
1056 Insts.push_back(LoongArchAsmParser::Inst(
1059 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1062void LoongArchAsmParser::emitLoadAddressTLSIELarge(
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::LDX_D));
1086 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1089void LoongArchAsmParser::emitLoadAddressTLSLD(
MCInst &Inst,
SMLoc IDLoc,
1098 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1100 Insts.push_back(LoongArchAsmParser::Inst(
1102 Insts.push_back(LoongArchAsmParser::Inst(
1105 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1108void LoongArchAsmParser::emitLoadAddressTLSLDLarge(
MCInst &Inst,
SMLoc IDLoc,
1122 Insts.push_back(LoongArchAsmParser::Inst(
1124 Insts.push_back(LoongArchAsmParser::Inst(
1126 Insts.push_back(LoongArchAsmParser::Inst(
1128 Insts.push_back(LoongArchAsmParser::Inst(
1130 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1132 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1135void LoongArchAsmParser::emitLoadAddressTLSGD(
MCInst &Inst,
SMLoc IDLoc,
1144 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1146 Insts.push_back(LoongArchAsmParser::Inst(
1148 Insts.push_back(LoongArchAsmParser::Inst(
1151 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1154void LoongArchAsmParser::emitLoadAddressTLSGDLarge(
MCInst &Inst,
SMLoc IDLoc,
1168 Insts.push_back(LoongArchAsmParser::Inst(
1170 Insts.push_back(LoongArchAsmParser::Inst(
1172 Insts.push_back(LoongArchAsmParser::Inst(
1174 Insts.push_back(LoongArchAsmParser::Inst(
1176 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1178 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1181void LoongArchAsmParser::emitLoadAddressTLSDescAbs(
MCInst &Inst,
SMLoc IDLoc,
1201 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1204 Insts.push_back(LoongArchAsmParser::Inst(
1206 Insts.push_back(LoongArchAsmParser::Inst(
1210 Insts.push_back(LoongArchAsmParser::Inst(
1212 Insts.push_back(LoongArchAsmParser::Inst(
1218 Insts.push_back(LoongArchAsmParser::Inst(
1221 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1224void LoongArchAsmParser::emitLoadAddressTLSDescPcrel(
MCInst &Inst,
SMLoc IDLoc,
1234 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1235 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1238 Insts.push_back(LoongArchAsmParser::Inst(
1240 Insts.push_back(LoongArchAsmParser::Inst(
1244 Insts.push_back(LoongArchAsmParser::Inst(
1247 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1250void LoongArchAsmParser::emitLoadAddressTLSDescPcrelLarge(
MCInst &Inst,
1267 Insts.push_back(LoongArchAsmParser::Inst(
1269 Insts.push_back(LoongArchAsmParser::Inst(
1271 Insts.push_back(LoongArchAsmParser::Inst(
1273 Insts.push_back(LoongArchAsmParser::Inst(
1275 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1276 Insts.push_back(LoongArchAsmParser::Inst(
1278 Insts.push_back(LoongArchAsmParser::Inst(
1281 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1284void LoongArchAsmParser::emitLoadImm(
MCInst &Inst,
SMLoc IDLoc,
1290 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1291 Imm = SignExtend64<32>(Imm);
1294 unsigned Opc = Inst.Opc;
1295 if (Opc == LoongArch::LU12I_W)
1300 MCInstBuilder(Opc).addReg(DestReg).addReg(SrcReg).addImm(Inst.Imm),
1306void LoongArchAsmParser::emitFuncCall36(
MCInst &Inst,
SMLoc IDLoc,
1317 unsigned ScratchReg =
1325 MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),
1329 .addReg(IsTailCall ? (
unsigned)LoongArch::R0 : ScratchReg)
1335bool LoongArchAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1342 case LoongArch::PseudoLA_ABS:
1343 case LoongArch::PseudoLA_ABS_LARGE:
1344 emitLoadAddressAbs(Inst, IDLoc, Out);
1346 case LoongArch::PseudoLA_PCREL:
1347 emitLoadAddressPcrel(Inst, IDLoc, Out);
1349 case LoongArch::PseudoLA_PCREL_LARGE:
1350 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1352 case LoongArch::PseudoLA_GOT:
1353 emitLoadAddressGot(Inst, IDLoc, Out);
1355 case LoongArch::PseudoLA_GOT_LARGE:
1356 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1358 case LoongArch::PseudoLA_TLS_LE:
1359 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1361 case LoongArch::PseudoLA_TLS_IE:
1362 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1364 case LoongArch::PseudoLA_TLS_IE_LARGE:
1365 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1367 case LoongArch::PseudoLA_TLS_LD:
1368 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1370 case LoongArch::PseudoLA_TLS_LD_LARGE:
1371 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1373 case LoongArch::PseudoLA_TLS_GD:
1374 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1376 case LoongArch::PseudoLA_TLS_GD_LARGE:
1377 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1379 case LoongArch::PseudoLA_TLS_DESC_ABS:
1380 case LoongArch::PseudoLA_TLS_DESC_ABS_LARGE:
1381 emitLoadAddressTLSDescAbs(Inst, IDLoc, Out);
1383 case LoongArch::PseudoLA_TLS_DESC_PC:
1384 emitLoadAddressTLSDescPcrel(Inst, IDLoc, Out);
1386 case LoongArch::PseudoLA_TLS_DESC_PC_LARGE:
1387 emitLoadAddressTLSDescPcrelLarge(Inst, IDLoc, Out);
1389 case LoongArch::PseudoLI_W:
1390 case LoongArch::PseudoLI_D:
1391 emitLoadImm(Inst, IDLoc, Out);
1393 case LoongArch::PseudoCALL36:
1394 emitFuncCall36(Inst, IDLoc, Out,
false);
1396 case LoongArch::PseudoTAIL36:
1397 emitFuncCall36(Inst, IDLoc, Out,
true);
1404unsigned LoongArchAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1408 if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) {
1412 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1413 return Match_RequiresAMORdDifferRkRj;
1416 case LoongArch::PseudoLA_TLS_DESC_ABS:
1417 case LoongArch::PseudoLA_TLS_DESC_ABS_LARGE:
1418 case LoongArch::PseudoLA_TLS_DESC_PC:
1419 case LoongArch::PseudoLA_TLS_DESC_PC_LARGE: {
1421 if (Rd != LoongArch::R4)
1422 return Match_RequiresLAORdR4;
1425 case LoongArch::PseudoLA_PCREL_LARGE:
1426 case LoongArch::PseudoLA_GOT_LARGE:
1427 case LoongArch::PseudoLA_TLS_IE_LARGE:
1428 case LoongArch::PseudoLA_TLS_LD_LARGE:
1429 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1433 return Match_RequiresLAORdDifferRj;
1436 case LoongArch::CSRXCHG:
1437 case LoongArch::GCSRXCHG: {
1439 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1440 return Match_RequiresOpnd2NotR0R1;
1441 return Match_Success;
1443 case LoongArch::BSTRINS_W:
1444 case LoongArch::BSTRINS_D:
1445 case LoongArch::BSTRPICK_W:
1446 case LoongArch::BSTRPICK_D: {
1449 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1453 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1457 return Match_RequiresMsbNotLessThanLsb;
1458 return Match_Success;
1462 return Match_Success;
1468 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1470 return Match_InvalidOperand;
1475 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1476 Kind == MCK_FPR64) {
1478 return Match_Success;
1481 return Match_InvalidOperand;
1484bool LoongArchAsmParser::generateImmOutOfRangeError(
1486 const Twine &Msg =
"immediate must be an integer in the range") {
1491bool LoongArchAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1495 bool MatchingInlineAsm) {
1505 return processInstruction(Inst, IDLoc,
Operands, Out);
1506 case Match_MissingFeature: {
1507 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1508 bool FirstFeature =
true;
1509 std::string Msg =
"instruction requires the following:";
1510 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1511 if (MissingFeatures[i]) {
1512 Msg += FirstFeature ?
" " :
", ";
1514 FirstFeature =
false;
1517 return Error(IDLoc, Msg);
1519 case Match_MnemonicFail: {
1520 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1521 std::string Suggestion = LoongArchMnemonicSpellCheck(
1522 ((LoongArchOperand &)*
Operands[0]).getToken(), FBS, 0);
1523 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1525 case Match_InvalidOperand: {
1526 SMLoc ErrorLoc = IDLoc;
1529 return Error(ErrorLoc,
"too few operands for instruction");
1532 if (ErrorLoc ==
SMLoc())
1535 return Error(ErrorLoc,
"invalid operand for instruction");
1542 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1543 SMLoc ErrorLoc = IDLoc;
1545 return Error(ErrorLoc,
"too few operands for instruction");
1551 case Match_RequiresMsbNotLessThanLsb: {
1553 return Error(ErrorStart,
"msb is less than lsb",
1556 case Match_RequiresOpnd2NotR0R1:
1557 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1558 case Match_RequiresAMORdDifferRkRj:
1560 "$rd must be different from both $rk and $rj");
1561 case Match_RequiresLAORdDifferRj:
1562 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1563 case Match_RequiresLAORdR4:
1564 return Error(
Operands[1]->getStartLoc(),
"$rd must be $r4");
1565 case Match_InvalidUImm1:
1568 case Match_InvalidUImm2:
1571 case Match_InvalidUImm2plus1:
1574 case Match_InvalidUImm3:
1577 case Match_InvalidUImm4:
1580 case Match_InvalidUImm5:
1583 case Match_InvalidUImm6:
1586 case Match_InvalidUImm7:
1589 case Match_InvalidUImm8:
1592 case Match_InvalidUImm12:
1595 case Match_InvalidUImm12ori:
1596 return generateImmOutOfRangeError(
1599 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1600 "integer in the range");
1601 case Match_InvalidUImm14:
1604 case Match_InvalidUImm15:
1607 case Match_InvalidSImm5:
1610 case Match_InvalidSImm8:
1613 case Match_InvalidSImm8lsl1:
1614 return generateImmOutOfRangeError(
1616 "immediate must be a multiple of 2 in the range");
1617 case Match_InvalidSImm8lsl2:
1618 return generateImmOutOfRangeError(
1620 "immediate must be a multiple of 4 in the range");
1621 case Match_InvalidSImm10:
1624 case Match_InvalidSImm8lsl3:
1625 return generateImmOutOfRangeError(
1627 "immediate must be a multiple of 8 in the range");
1628 case Match_InvalidSImm9lsl3:
1629 return generateImmOutOfRangeError(
1631 "immediate must be a multiple of 8 in the range");
1632 case Match_InvalidSImm10lsl2:
1633 return generateImmOutOfRangeError(
1635 "immediate must be a multiple of 4 in the range");
1636 case Match_InvalidSImm11lsl1:
1637 return generateImmOutOfRangeError(
1639 "immediate must be a multiple of 2 in the range");
1640 case Match_InvalidSImm12:
1643 case Match_InvalidSImm12addlike:
1644 return generateImmOutOfRangeError(
1647 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1649 case Match_InvalidSImm12lu52id:
1650 return generateImmOutOfRangeError(
1653 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1654 "integer in the range");
1655 case Match_InvalidSImm13:
1658 case Match_InvalidSImm14lsl2:
1659 return generateImmOutOfRangeError(
1661 "immediate must be a multiple of 4 in the range");
1662 case Match_InvalidSImm16:
1665 case Match_InvalidSImm16lsl2:
1666 return generateImmOutOfRangeError(
1668 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1670 case Match_InvalidSImm20:
1673 case Match_InvalidSImm20lu12iw:
1674 return generateImmOutOfRangeError(
1677 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1679 case Match_InvalidSImm20lu32id:
1680 return generateImmOutOfRangeError(
1683 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1684 "integer in the range");
1685 case Match_InvalidSImm20pcalau12i:
1686 return generateImmOutOfRangeError(
1689 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1691 case Match_InvalidSImm20pcaddu18i:
1692 return generateImmOutOfRangeError(
1695 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1697 case Match_InvalidSImm20pcaddi:
1698 return generateImmOutOfRangeError(
1701 "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
1703 case Match_InvalidSImm21lsl2:
1704 return generateImmOutOfRangeError(
1706 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1708 case Match_InvalidSImm26Operand:
1709 return generateImmOutOfRangeError(
1711 "operand must be a bare symbol name or an immediate must be a multiple "
1712 "of 4 in the range");
1713 case Match_InvalidImm32: {
1715 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1717 case Match_InvalidImm64: {
1719 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
1721 case Match_InvalidBareSymbol: {
1723 return Error(ErrorLoc,
"operand must be a bare symbol name");
1725 case Match_InvalidTPRelAddSymbol: {
1727 return Error(ErrorLoc,
"operand must be a symbol with %le_add_r modifier");
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_PCREL20_S2
@ VK_LoongArch_TLS_LD_HI20
@ VK_LoongArch_TLS_DESC_CALL
@ VK_LoongArch_TLS_DESC_PCREL20_S2
@ VK_LoongArch_GOT64_HI12
@ VK_LoongArch_PCALA_LO12
@ VK_LoongArch_TLS_DESC64_HI12
@ VK_LoongArch_TLS_LE_HI20_R
@ 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_GD_PCREL20_S2
@ 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_LE_LO12_R
@ VK_LoongArch_TLS_DESC_PC_LO12
@ VK_LoongArch_GOT64_LO20
@ VK_LoongArch_TLS_DESC64_LO20
@ VK_LoongArch_TLS_GD_PC_HI20
@ VK_LoongArch_TLS_LE_ADD_R
@ VK_LoongArch_TLS_DESC64_PC_HI12
@ VK_LoongArch_GOT64_PC_LO20
@ VK_LoongArch_PCALA64_HI12
@ VK_LoongArch_TLS_LD_PCREL20_S2
@ 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 MCAssembler *Asm, 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.
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,...