31#define DEBUG_TYPE "loongarch-asm-parser"
41 "do not have a target streamer");
58 SMLoc &EndLoc)
override;
66 bool MatchingInlineAsm)
override;
71 unsigned Kind)
override;
85#define GET_ASSEMBLER_HEADER
86#include "LoongArchGenAsmMatcher.inc"
96 bool parseDirectiveOption();
99 if (!(
getSTI().hasFeature(Feature))) {
107 if (
getSTI().hasFeature(Feature)) {
114 void pushFeatureBits() {
118 bool popFeatureBits() {
119 if (FeatureBitStack.
empty())
179 enum LoongArchMatchResultTy {
181 Match_RequiresMsbNotLessThanLsb,
182 Match_RequiresOpnd2NotR0R1,
183 Match_RequiresAMORdDifferRkRj,
184 Match_RequiresLAORdDifferRj,
185 Match_RequiresLAORdR4,
186#define GET_OPERAND_DIAGNOSTIC_TYPES
187#include "LoongArchGenAsmMatcher.inc"
188#undef GET_OPERAND_DIAGNOSTIC_TYPES
191 static bool classifySymbolRef(
const MCExpr *Expr,
223 SMLoc StartLoc, EndLoc;
233 bool isToken()
const override {
return Kind == KindTy::Token; }
234 bool isReg()
const override {
return Kind == KindTy::Register; }
235 bool isImm()
const override {
return Kind == KindTy::Immediate; }
236 bool isMem()
const override {
return false; }
239 return Kind == KindTy::Register &&
240 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(
244 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
246 if (
auto *LE = dyn_cast<LoongArchMCExpr>(Expr)) {
251 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
252 Imm =
CE->getValue();
259 template <
unsigned N,
int P = 0>
bool isUImm()
const {
265 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
266 return IsConstantImm && isUInt<N>(Imm -
P) &&
270 template <
unsigned N,
unsigned S = 0>
bool isSImm()
const {
276 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
277 return IsConstantImm && isShiftedInt<N, S>(Imm) &&
281 bool isBareSymbol()
const {
285 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
287 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
291 bool isTPRelAddSymbol()
const {
295 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
297 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
301 bool isUImm1()
const {
return isUImm<1>(); }
302 bool isUImm2()
const {
return isUImm<2>(); }
303 bool isUImm2plus1()
const {
return isUImm<2, 1>(); }
304 bool isUImm3()
const {
return isUImm<3>(); }
305 bool isUImm4()
const {
return isUImm<4>(); }
306 bool isSImm5()
const {
return isSImm<5>(); }
307 bool isUImm5()
const {
return isUImm<5>(); }
308 bool isUImm6()
const {
return isUImm<6>(); }
309 bool isUImm7()
const {
return isUImm<7>(); }
310 bool isSImm8()
const {
return isSImm<8>(); }
311 bool isSImm8lsl1()
const {
return isSImm<8, 1>(); }
312 bool isSImm8lsl2()
const {
return isSImm<8, 2>(); }
313 bool isSImm8lsl3()
const {
return isSImm<8, 3>(); }
314 bool isUImm8()
const {
return isUImm<8>(); }
315 bool isSImm9lsl3()
const {
return isSImm<9, 3>(); }
316 bool isSImm10()
const {
return isSImm<10>(); }
317 bool isSImm10lsl2()
const {
return isSImm<10, 2>(); }
318 bool isSImm11lsl1()
const {
return isSImm<11, 1>(); }
319 bool isSImm12()
const {
return isSImm<12>(); }
321 bool isSImm12addlike()
const {
327 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
336 ? isInt<12>(Imm) && IsValidKind
337 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
341 bool isSImm12lu52id()
const {
347 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
359 ? isInt<12>(Imm) && IsValidKind
360 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
364 bool isUImm12()
const {
return isUImm<12>(); }
366 bool isUImm12ori()
const {
372 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
383 ? isUInt<12>(Imm) && IsValidKind
384 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
388 bool isSImm13()
const {
return isSImm<13>(); }
389 bool isUImm14()
const {
return isUImm<14>(); }
390 bool isUImm15()
const {
return isUImm<15>(); }
392 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
393 bool isSImm16()
const {
return isSImm<16>(); }
395 bool isSImm16lsl2()
const {
401 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
407 ? isShiftedInt<16, 2>(Imm) && IsValidKind
408 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
412 bool isSImm20()
const {
return isSImm<20>(); }
414 bool isSImm20pcalau12i()
const {
420 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
429 ? isInt<20>(Imm) && IsValidKind
430 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
434 bool isSImm20lu12iw()
const {
440 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
451 ? isInt<20>(Imm) && IsValidKind
452 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
456 bool isSImm20lu32id()
const {
462 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
475 ? isInt<20>(Imm) && IsValidKind
476 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
480 bool isSImm20pcaddu18i()
const {
486 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
491 ? isInt<20>(Imm) && IsValidKind
492 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
496 bool isSImm20pcaddi()
const {
502 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
509 ? isInt<20>(Imm) && IsValidKind
510 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
514 bool isSImm21lsl2()
const {
520 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
524 ? isShiftedInt<21, 2>(Imm) && IsValidKind
525 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
529 bool isSImm26Operand()
const {
535 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
541 ? isShiftedInt<26, 2>(Imm) && IsValidKind
542 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
546 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
547 bool isImm64()
const {
552 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
562 assert(Kind == KindTy::Register &&
"Invalid type access!");
566 const MCExpr *getImm()
const {
567 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
572 assert(Kind == KindTy::Token &&
"Invalid type access!");
585 case KindTy::Immediate:
588 case KindTy::Register:
592 OS <<
"'" << getToken() <<
"'";
597 static std::unique_ptr<LoongArchOperand> createToken(
StringRef Str,
SMLoc S) {
598 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
607 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
608 Op->Reg.RegNum =
Reg;
614 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val,
SMLoc S,
616 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
624 if (
auto CE = dyn_cast<MCConstantExpr>(Expr))
631 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
632 assert(
N == 1 &&
"Invalid number of operands!");
635 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
636 assert(
N == 1 &&
"Invalid number of operands!");
637 addExpr(Inst, getImm());
642#define GET_REGISTER_MATCHER
643#define GET_SUBTARGET_FEATURE_NAME
644#define GET_MATCHER_IMPLEMENTATION
645#define GET_MNEMONIC_SPELL_CHECKER
646#include "LoongArchGenAsmMatcher.inc"
649 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
650 return Reg - LoongArch::F0 + LoongArch::F0_64;
660 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
662 static_assert(LoongArch::F0 < LoongArch::F0_64,
663 "FPR matching must be updated");
664 if (RegNo == LoongArch::NoRegister)
667 return RegNo == LoongArch::NoRegister;
672 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
673 return Error(getLoc(),
"invalid register name");
675 if (!LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].
contains(
Reg) &&
676 !LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg))
677 return Error(getLoc(),
"invalid register name");
685 const AsmToken &Tok = getParser().getTok();
701bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
706 Kind = RE->getKind();
707 Expr = RE->getSubExpr();
725 if (RegNo == LoongArch::NoRegister)
731 Operands.push_back(LoongArchOperand::createReg(RegNo, S,
E));
741 switch (getLexer().getKind()) {
753 if (getParser().parseExpression(Res,
E))
757 return parseOperandWithModifier(
Operands);
760 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
770 return Error(getLoc(),
"expected '%' for operand modifier");
775 return Error(getLoc(),
"expected valid identifier for operand modifier");
780 return Error(getLoc(),
"unrecognized operand modifier");
784 return Error(getLoc(),
"expected '('");
788 if (getParser().parseParenExpression(SubExpr,
E))
792 Operands.push_back(LoongArchOperand::createImm(ModExpr, S,
E));
801 return parseOperandWithModifier(
Operands);
807 if (getParser().parseIdentifier(Identifier))
812 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
816 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
822 if (!parseRegister(
Operands).isSuccess())
829 SMLoc ImmStart = getLoc();
830 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
833 return Error(ImmStart,
"optional integer offset must be 0");
845 MatchOperandParserImpl(
Operands, Mnemonic,
true);
851 if (parseRegister(
Operands).isSuccess() ||
856 return Error(getLoc(),
"unknown operand");
863 Operands.push_back(LoongArchOperand::createToken(
Name, NameLoc));
882 SMLoc Loc = getLexer().getLoc();
883 getParser().eatToEndOfStatement();
884 return Error(Loc,
"unexpected token");
893 for (LoongArchAsmParser::Inst &Inst : Insts) {
894 unsigned Opc = Inst.Opc;
901 case LoongArch::PCALAU12I:
902 case LoongArch::LU12I_W:
907 case LoongArch::ADDI_W:
908 case LoongArch::LD_W:
909 case LoongArch::LD_D: {
912 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addImm(0),
917 .addReg(LoongArch::R1)
924 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
928 case LoongArch::LU32I_D:
930 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
931 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
935 case LoongArch::LU52I_D:
937 MCInstBuilder(Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
940 case LoongArch::ADDI_D:
944 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
948 case LoongArch::ADD_D:
949 case LoongArch::LDX_D:
951 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
954 case LoongArch::JIRL:
956 .addReg(LoongArch::R1)
957 .addReg(LoongArch::R1)
965void LoongArchAsmParser::emitLoadAddressAbs(
MCInst &Inst,
SMLoc IDLoc,
981 Insts.push_back(LoongArchAsmParser::Inst(
983 Insts.push_back(LoongArchAsmParser::Inst(
987 Insts.push_back(LoongArchAsmParser::Inst(
989 Insts.push_back(LoongArchAsmParser::Inst(
993 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
996void LoongArchAsmParser::emitLoadAddressPcrel(
MCInst &Inst,
SMLoc IDLoc,
1005 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1007 Insts.push_back(LoongArchAsmParser::Inst(
1012 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1016void LoongArchAsmParser::emitLoadAddressPcrelLarge(
MCInst &Inst,
SMLoc IDLoc,
1030 Insts.push_back(LoongArchAsmParser::Inst(
1032 Insts.push_back(LoongArchAsmParser::Inst(
1034 Insts.push_back(LoongArchAsmParser::Inst(
1036 Insts.push_back(LoongArchAsmParser::Inst(
1038 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1040 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1043void LoongArchAsmParser::emitLoadAddressGot(
MCInst &Inst,
SMLoc IDLoc,
1049 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1051 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1064 Insts.push_back(LoongArchAsmParser::Inst(
1066 Insts.push_back(LoongArchAsmParser::Inst(
1070 Insts.push_back(LoongArchAsmParser::Inst(
1072 Insts.push_back(LoongArchAsmParser::Inst(
1075 Insts.push_back(LoongArchAsmParser::Inst(LD));
1076 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1082 Insts.push_back(LoongArchAsmParser::Inst(
1087 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1091void LoongArchAsmParser::emitLoadAddressGotLarge(
MCInst &Inst,
SMLoc IDLoc,
1105 Insts.push_back(LoongArchAsmParser::Inst(
1107 Insts.push_back(LoongArchAsmParser::Inst(
1109 Insts.push_back(LoongArchAsmParser::Inst(
1111 Insts.push_back(LoongArchAsmParser::Inst(
1113 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1115 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1118void LoongArchAsmParser::emitLoadAddressTLSLE(
MCInst &Inst,
SMLoc IDLoc,
1128 Insts.push_back(LoongArchAsmParser::Inst(
1130 Insts.push_back(LoongArchAsmParser::Inst(
1133 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1136void LoongArchAsmParser::emitLoadAddressTLSIE(
MCInst &Inst,
SMLoc IDLoc,
1142 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1144 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1157 Insts.push_back(LoongArchAsmParser::Inst(
1159 Insts.push_back(LoongArchAsmParser::Inst(
1163 Insts.push_back(LoongArchAsmParser::Inst(
1165 Insts.push_back(LoongArchAsmParser::Inst(
1168 Insts.push_back(LoongArchAsmParser::Inst(LD));
1169 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1176 Insts.push_back(LoongArchAsmParser::Inst(
1178 Insts.push_back(LoongArchAsmParser::Inst(
1181 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1185void LoongArchAsmParser::emitLoadAddressTLSIELarge(
MCInst &Inst,
SMLoc IDLoc,
1199 Insts.push_back(LoongArchAsmParser::Inst(
1201 Insts.push_back(LoongArchAsmParser::Inst(
1203 Insts.push_back(LoongArchAsmParser::Inst(
1205 Insts.push_back(LoongArchAsmParser::Inst(
1207 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1209 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1212void LoongArchAsmParser::emitLoadAddressTLSLD(
MCInst &Inst,
SMLoc IDLoc,
1218 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1220 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1231 Insts.push_back(LoongArchAsmParser::Inst(
1233 Insts.push_back(LoongArchAsmParser::Inst(
1237 Insts.push_back(LoongArchAsmParser::Inst(
1239 Insts.push_back(LoongArchAsmParser::Inst(
1242 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1249 Insts.push_back(LoongArchAsmParser::Inst(
1251 Insts.push_back(LoongArchAsmParser::Inst(
1254 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1258void LoongArchAsmParser::emitLoadAddressTLSLDLarge(
MCInst &Inst,
SMLoc IDLoc,
1272 Insts.push_back(LoongArchAsmParser::Inst(
1274 Insts.push_back(LoongArchAsmParser::Inst(
1276 Insts.push_back(LoongArchAsmParser::Inst(
1278 Insts.push_back(LoongArchAsmParser::Inst(
1280 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1282 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1285void LoongArchAsmParser::emitLoadAddressTLSGD(
MCInst &Inst,
SMLoc IDLoc,
1291 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1293 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1304 Insts.push_back(LoongArchAsmParser::Inst(
1306 Insts.push_back(LoongArchAsmParser::Inst(
1310 Insts.push_back(LoongArchAsmParser::Inst(
1312 Insts.push_back(LoongArchAsmParser::Inst(
1315 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1322 Insts.push_back(LoongArchAsmParser::Inst(
1324 Insts.push_back(LoongArchAsmParser::Inst(
1327 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1331void LoongArchAsmParser::emitLoadAddressTLSGDLarge(
MCInst &Inst,
SMLoc IDLoc,
1345 Insts.push_back(LoongArchAsmParser::Inst(
1347 Insts.push_back(LoongArchAsmParser::Inst(
1349 Insts.push_back(LoongArchAsmParser::Inst(
1351 Insts.push_back(LoongArchAsmParser::Inst(
1353 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1355 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1358void LoongArchAsmParser::emitLoadAddressTLSDesc(
MCInst &Inst,
SMLoc IDLoc,
1363 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1364 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1367 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1382 Insts.push_back(LoongArchAsmParser::Inst(
1384 Insts.push_back(LoongArchAsmParser::Inst(
1388 Insts.push_back(LoongArchAsmParser::Inst(
1390 Insts.push_back(LoongArchAsmParser::Inst(
1394 Insts.push_back(LoongArchAsmParser::Inst(
1396 Insts.push_back(LoongArchAsmParser::Inst(
1399 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1408 Insts.push_back(LoongArchAsmParser::Inst(
1410 Insts.push_back(LoongArchAsmParser::Inst(
1414 Insts.push_back(LoongArchAsmParser::Inst(
1417 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1421void LoongArchAsmParser::emitLoadAddressTLSDescLarge(
MCInst &Inst,
SMLoc IDLoc,
1437 Insts.push_back(LoongArchAsmParser::Inst(
1439 Insts.push_back(LoongArchAsmParser::Inst(
1441 Insts.push_back(LoongArchAsmParser::Inst(
1443 Insts.push_back(LoongArchAsmParser::Inst(
1445 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1446 Insts.push_back(LoongArchAsmParser::Inst(
1448 Insts.push_back(LoongArchAsmParser::Inst(
1451 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1454void LoongArchAsmParser::emitLoadImm(
MCInst &Inst,
SMLoc IDLoc,
1460 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1461 Imm = SignExtend64<32>(Imm);
1465 case LoongArch::LU12I_W:
1469 case LoongArch::ADDI_W:
1470 case LoongArch::ORI:
1471 case LoongArch::LU32I_D:
1472 case LoongArch::LU52I_D:
1478 case LoongArch::BSTRINS_D:
1484 .
addImm(Inst.Imm & 0xFF),
1494void LoongArchAsmParser::emitFuncCall36(
MCInst &Inst,
SMLoc IDLoc,
1511 getContext(),
true);
1514 MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),
1518 .addReg(IsTailCall ?
MCRegister(LoongArch::R0) : ScratchReg)
1524bool LoongArchAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1531 case LoongArch::PseudoLA_ABS:
1532 case LoongArch::PseudoLA_ABS_LARGE:
1533 emitLoadAddressAbs(Inst, IDLoc, Out);
1535 case LoongArch::PseudoLA_PCREL:
1536 emitLoadAddressPcrel(Inst, IDLoc, Out);
1538 case LoongArch::PseudoLA_PCREL_LARGE:
1539 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1541 case LoongArch::PseudoLA_GOT:
1542 emitLoadAddressGot(Inst, IDLoc, Out);
1544 case LoongArch::PseudoLA_GOT_LARGE:
1545 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1547 case LoongArch::PseudoLA_TLS_LE:
1548 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1550 case LoongArch::PseudoLA_TLS_IE:
1551 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1553 case LoongArch::PseudoLA_TLS_IE_LARGE:
1554 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1556 case LoongArch::PseudoLA_TLS_LD:
1557 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1559 case LoongArch::PseudoLA_TLS_LD_LARGE:
1560 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1562 case LoongArch::PseudoLA_TLS_GD:
1563 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1565 case LoongArch::PseudoLA_TLS_GD_LARGE:
1566 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1568 case LoongArch::PseudoLA_TLS_DESC:
1569 emitLoadAddressTLSDesc(Inst, IDLoc, Out);
1571 case LoongArch::PseudoLA_TLS_DESC_LARGE:
1572 emitLoadAddressTLSDescLarge(Inst, IDLoc, Out);
1574 case LoongArch::PseudoLI_W:
1575 case LoongArch::PseudoLI_D:
1576 emitLoadImm(Inst, IDLoc, Out);
1578 case LoongArch::PseudoCALL36:
1579 emitFuncCall36(Inst, IDLoc, Out,
false);
1581 case LoongArch::PseudoTAIL36:
1582 emitFuncCall36(Inst, IDLoc, Out,
true);
1589unsigned LoongArchAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1599 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1600 return Match_RequiresAMORdDifferRkRj;
1603 case LoongArch::PseudoLA_TLS_DESC:
1604 case LoongArch::PseudoLA_TLS_DESC_LARGE: {
1606 if (Rd != LoongArch::R4)
1607 return Match_RequiresLAORdR4;
1610 case LoongArch::PseudoLA_PCREL_LARGE:
1611 case LoongArch::PseudoLA_GOT_LARGE:
1612 case LoongArch::PseudoLA_TLS_IE_LARGE:
1613 case LoongArch::PseudoLA_TLS_LD_LARGE:
1614 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1618 return Match_RequiresLAORdDifferRj;
1621 case LoongArch::CSRXCHG:
1622 case LoongArch::GCSRXCHG: {
1624 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1625 return Match_RequiresOpnd2NotR0R1;
1626 return Match_Success;
1628 case LoongArch::BSTRINS_W:
1629 case LoongArch::BSTRINS_D:
1630 case LoongArch::BSTRPICK_W:
1631 case LoongArch::BSTRPICK_D: {
1634 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1638 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1642 return Match_RequiresMsbNotLessThanLsb;
1643 return Match_Success;
1647 return Match_Success;
1653 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1655 return Match_InvalidOperand;
1660 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1661 Kind == MCK_FPR64) {
1663 return Match_Success;
1666 return Match_InvalidOperand;
1669bool LoongArchAsmParser::generateImmOutOfRangeError(
1671 const Twine &Msg =
"immediate must be an integer in the range") {
1676bool LoongArchAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1680 bool MatchingInlineAsm) {
1690 return processInstruction(Inst, IDLoc,
Operands, Out);
1691 case Match_MissingFeature: {
1692 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1693 bool FirstFeature =
true;
1694 std::string Msg =
"instruction requires the following:";
1695 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1696 if (MissingFeatures[i]) {
1697 Msg += FirstFeature ?
" " :
", ";
1699 FirstFeature =
false;
1702 return Error(IDLoc, Msg);
1704 case Match_MnemonicFail: {
1705 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1706 std::string Suggestion = LoongArchMnemonicSpellCheck(
1707 ((LoongArchOperand &)*
Operands[0]).getToken(), FBS, 0);
1708 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1710 case Match_InvalidOperand: {
1711 SMLoc ErrorLoc = IDLoc;
1714 return Error(ErrorLoc,
"too few operands for instruction");
1717 if (ErrorLoc ==
SMLoc())
1720 return Error(ErrorLoc,
"invalid operand for instruction");
1727 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1728 SMLoc ErrorLoc = IDLoc;
1730 return Error(ErrorLoc,
"too few operands for instruction");
1736 case Match_RequiresMsbNotLessThanLsb: {
1738 return Error(ErrorStart,
"msb is less than lsb",
1741 case Match_RequiresOpnd2NotR0R1:
1742 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1743 case Match_RequiresAMORdDifferRkRj:
1745 "$rd must be different from both $rk and $rj");
1746 case Match_RequiresLAORdDifferRj:
1747 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1748 case Match_RequiresLAORdR4:
1749 return Error(
Operands[1]->getStartLoc(),
"$rd must be $r4");
1750 case Match_InvalidUImm1:
1753 case Match_InvalidUImm2:
1756 case Match_InvalidUImm2plus1:
1759 case Match_InvalidUImm3:
1762 case Match_InvalidUImm4:
1765 case Match_InvalidUImm5:
1768 case Match_InvalidUImm6:
1771 case Match_InvalidUImm7:
1774 case Match_InvalidUImm8:
1777 case Match_InvalidUImm12:
1780 case Match_InvalidUImm12ori:
1781 return generateImmOutOfRangeError(
1784 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1785 "integer in the range");
1786 case Match_InvalidUImm14:
1789 case Match_InvalidUImm15:
1792 case Match_InvalidSImm5:
1795 case Match_InvalidSImm8:
1798 case Match_InvalidSImm8lsl1:
1799 return generateImmOutOfRangeError(
1801 "immediate must be a multiple of 2 in the range");
1802 case Match_InvalidSImm8lsl2:
1803 return generateImmOutOfRangeError(
1805 "immediate must be a multiple of 4 in the range");
1806 case Match_InvalidSImm10:
1809 case Match_InvalidSImm8lsl3:
1810 return generateImmOutOfRangeError(
1812 "immediate must be a multiple of 8 in the range");
1813 case Match_InvalidSImm9lsl3:
1814 return generateImmOutOfRangeError(
1816 "immediate must be a multiple of 8 in the range");
1817 case Match_InvalidSImm10lsl2:
1818 return generateImmOutOfRangeError(
1820 "immediate must be a multiple of 4 in the range");
1821 case Match_InvalidSImm11lsl1:
1822 return generateImmOutOfRangeError(
1824 "immediate must be a multiple of 2 in the range");
1825 case Match_InvalidSImm12:
1828 case Match_InvalidSImm12addlike:
1829 return generateImmOutOfRangeError(
1832 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1834 case Match_InvalidSImm12lu52id:
1835 return generateImmOutOfRangeError(
1838 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1839 "integer in the range");
1840 case Match_InvalidSImm13:
1843 case Match_InvalidSImm14lsl2:
1844 return generateImmOutOfRangeError(
1846 "immediate must be a multiple of 4 in the range");
1847 case Match_InvalidSImm16:
1850 case Match_InvalidSImm16lsl2:
1851 return generateImmOutOfRangeError(
1853 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1855 case Match_InvalidSImm20:
1858 case Match_InvalidSImm20lu12iw:
1859 return generateImmOutOfRangeError(
1862 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1864 case Match_InvalidSImm20lu32id:
1865 return generateImmOutOfRangeError(
1868 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1869 "integer in the range");
1870 case Match_InvalidSImm20pcalau12i:
1871 return generateImmOutOfRangeError(
1874 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1876 case Match_InvalidSImm20pcaddu18i:
1877 return generateImmOutOfRangeError(
1880 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1882 case Match_InvalidSImm20pcaddi:
1883 return generateImmOutOfRangeError(
1886 "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
1888 case Match_InvalidSImm21lsl2:
1889 return generateImmOutOfRangeError(
1891 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1893 case Match_InvalidSImm26Operand:
1894 return generateImmOutOfRangeError(
1896 "operand must be a bare symbol name or an immediate must be a multiple "
1897 "of 4 in the range");
1898 case Match_InvalidImm32: {
1900 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1902 case Match_InvalidImm64: {
1904 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
1906 case Match_InvalidBareSymbol: {
1908 return Error(ErrorLoc,
"operand must be a bare symbol name");
1910 case Match_InvalidTPRelAddSymbol: {
1912 return Error(ErrorLoc,
"operand must be a symbol with %le_add_r modifier");
1918bool LoongArchAsmParser::parseDirectiveOption() {
1929 if (Option ==
"push") {
1933 getTargetStreamer().emitDirectiveOptionPush();
1938 if (Option ==
"pop") {
1943 getTargetStreamer().emitDirectiveOptionPop();
1944 if (popFeatureBits())
1945 return Error(StartLoc,
".option pop with no .option push");
1950 if (Option ==
"relax") {
1954 getTargetStreamer().emitDirectiveOptionRelax();
1955 setFeatureBits(LoongArch::FeatureRelax,
"relax");
1959 if (Option ==
"norelax") {
1963 getTargetStreamer().emitDirectiveOptionNoRelax();
1964 clearFeatureBits(LoongArch::FeatureRelax,
"relax");
1970 "unknown option, expected 'push', 'pop', 'relax' or 'norelax'");
1976 if (DirectiveID.
getString() ==
".option")
1977 return parseDirectiveOption();
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)
Target independent representation for an assembler token.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
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)
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
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.
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
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
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
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.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
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.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
@ 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
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
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 unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
Target specific streamer interface.
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...
void push_back(const T &Elt)
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.
static bool isAMCAS(uint64_t TSFlags)
static bool isSubjectToAMORdConstraint(uint64_t TSFlags)
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,...