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,
true);
1015void LoongArchAsmParser::emitLoadAddressPcrelLarge(
MCInst &Inst,
SMLoc IDLoc,
1029 Insts.push_back(LoongArchAsmParser::Inst(
1031 Insts.push_back(LoongArchAsmParser::Inst(
1033 Insts.push_back(LoongArchAsmParser::Inst(
1035 Insts.push_back(LoongArchAsmParser::Inst(
1037 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1039 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1042void LoongArchAsmParser::emitLoadAddressGot(
MCInst &Inst,
SMLoc IDLoc,
1048 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1050 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1063 Insts.push_back(LoongArchAsmParser::Inst(
1065 Insts.push_back(LoongArchAsmParser::Inst(
1069 Insts.push_back(LoongArchAsmParser::Inst(
1071 Insts.push_back(LoongArchAsmParser::Inst(
1074 Insts.push_back(LoongArchAsmParser::Inst(LD));
1075 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1081 Insts.push_back(LoongArchAsmParser::Inst(
1086 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
true);
1089void LoongArchAsmParser::emitLoadAddressGotLarge(
MCInst &Inst,
SMLoc IDLoc,
1103 Insts.push_back(LoongArchAsmParser::Inst(
1105 Insts.push_back(LoongArchAsmParser::Inst(
1107 Insts.push_back(LoongArchAsmParser::Inst(
1109 Insts.push_back(LoongArchAsmParser::Inst(
1111 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1113 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1116void LoongArchAsmParser::emitLoadAddressTLSLE(
MCInst &Inst,
SMLoc IDLoc,
1126 Insts.push_back(LoongArchAsmParser::Inst(
1128 Insts.push_back(LoongArchAsmParser::Inst(
1131 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1134void LoongArchAsmParser::emitLoadAddressTLSIE(
MCInst &Inst,
SMLoc IDLoc,
1140 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1142 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1155 Insts.push_back(LoongArchAsmParser::Inst(
1157 Insts.push_back(LoongArchAsmParser::Inst(
1161 Insts.push_back(LoongArchAsmParser::Inst(
1163 Insts.push_back(LoongArchAsmParser::Inst(
1166 Insts.push_back(LoongArchAsmParser::Inst(LD));
1167 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1174 Insts.push_back(LoongArchAsmParser::Inst(
1176 Insts.push_back(LoongArchAsmParser::Inst(
1179 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1182void LoongArchAsmParser::emitLoadAddressTLSIELarge(
MCInst &Inst,
SMLoc IDLoc,
1196 Insts.push_back(LoongArchAsmParser::Inst(
1198 Insts.push_back(LoongArchAsmParser::Inst(
1200 Insts.push_back(LoongArchAsmParser::Inst(
1202 Insts.push_back(LoongArchAsmParser::Inst(
1204 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1206 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1209void LoongArchAsmParser::emitLoadAddressTLSLD(
MCInst &Inst,
SMLoc IDLoc,
1215 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1217 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1228 Insts.push_back(LoongArchAsmParser::Inst(
1230 Insts.push_back(LoongArchAsmParser::Inst(
1234 Insts.push_back(LoongArchAsmParser::Inst(
1236 Insts.push_back(LoongArchAsmParser::Inst(
1239 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1246 Insts.push_back(LoongArchAsmParser::Inst(
1248 Insts.push_back(LoongArchAsmParser::Inst(
1251 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1254void LoongArchAsmParser::emitLoadAddressTLSLDLarge(
MCInst &Inst,
SMLoc IDLoc,
1268 Insts.push_back(LoongArchAsmParser::Inst(
1270 Insts.push_back(LoongArchAsmParser::Inst(
1272 Insts.push_back(LoongArchAsmParser::Inst(
1274 Insts.push_back(LoongArchAsmParser::Inst(
1276 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1278 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1281void LoongArchAsmParser::emitLoadAddressTLSGD(
MCInst &Inst,
SMLoc IDLoc,
1287 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1289 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1300 Insts.push_back(LoongArchAsmParser::Inst(
1302 Insts.push_back(LoongArchAsmParser::Inst(
1306 Insts.push_back(LoongArchAsmParser::Inst(
1308 Insts.push_back(LoongArchAsmParser::Inst(
1311 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1318 Insts.push_back(LoongArchAsmParser::Inst(
1320 Insts.push_back(LoongArchAsmParser::Inst(
1323 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1326void LoongArchAsmParser::emitLoadAddressTLSGDLarge(
MCInst &Inst,
SMLoc IDLoc,
1340 Insts.push_back(LoongArchAsmParser::Inst(
1342 Insts.push_back(LoongArchAsmParser::Inst(
1344 Insts.push_back(LoongArchAsmParser::Inst(
1346 Insts.push_back(LoongArchAsmParser::Inst(
1348 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1350 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1353void LoongArchAsmParser::emitLoadAddressTLSDesc(
MCInst &Inst,
SMLoc IDLoc,
1358 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1359 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1362 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1377 Insts.push_back(LoongArchAsmParser::Inst(
1379 Insts.push_back(LoongArchAsmParser::Inst(
1383 Insts.push_back(LoongArchAsmParser::Inst(
1385 Insts.push_back(LoongArchAsmParser::Inst(
1389 Insts.push_back(LoongArchAsmParser::Inst(
1391 Insts.push_back(LoongArchAsmParser::Inst(
1394 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1403 Insts.push_back(LoongArchAsmParser::Inst(
1405 Insts.push_back(LoongArchAsmParser::Inst(
1409 Insts.push_back(LoongArchAsmParser::Inst(
1412 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1415void LoongArchAsmParser::emitLoadAddressTLSDescLarge(
MCInst &Inst,
SMLoc IDLoc,
1431 Insts.push_back(LoongArchAsmParser::Inst(
1433 Insts.push_back(LoongArchAsmParser::Inst(
1435 Insts.push_back(LoongArchAsmParser::Inst(
1437 Insts.push_back(LoongArchAsmParser::Inst(
1439 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1440 Insts.push_back(LoongArchAsmParser::Inst(
1442 Insts.push_back(LoongArchAsmParser::Inst(
1445 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1448void LoongArchAsmParser::emitLoadImm(
MCInst &Inst,
SMLoc IDLoc,
1454 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1455 Imm = SignExtend64<32>(Imm);
1459 case LoongArch::LU12I_W:
1463 case LoongArch::ADDI_W:
1464 case LoongArch::ORI:
1465 case LoongArch::LU32I_D:
1466 case LoongArch::LU52I_D:
1472 case LoongArch::BSTRINS_D:
1478 .
addImm(Inst.Imm & 0xFF),
1488void LoongArchAsmParser::emitFuncCall36(
MCInst &Inst,
SMLoc IDLoc,
1507 MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),
1511 .addReg(IsTailCall ?
MCRegister(LoongArch::R0) : ScratchReg)
1517bool LoongArchAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1524 case LoongArch::PseudoLA_ABS:
1525 case LoongArch::PseudoLA_ABS_LARGE:
1526 emitLoadAddressAbs(Inst, IDLoc, Out);
1528 case LoongArch::PseudoLA_PCREL:
1529 emitLoadAddressPcrel(Inst, IDLoc, Out);
1531 case LoongArch::PseudoLA_PCREL_LARGE:
1532 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1534 case LoongArch::PseudoLA_GOT:
1535 emitLoadAddressGot(Inst, IDLoc, Out);
1537 case LoongArch::PseudoLA_GOT_LARGE:
1538 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1540 case LoongArch::PseudoLA_TLS_LE:
1541 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1543 case LoongArch::PseudoLA_TLS_IE:
1544 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1546 case LoongArch::PseudoLA_TLS_IE_LARGE:
1547 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1549 case LoongArch::PseudoLA_TLS_LD:
1550 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1552 case LoongArch::PseudoLA_TLS_LD_LARGE:
1553 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1555 case LoongArch::PseudoLA_TLS_GD:
1556 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1558 case LoongArch::PseudoLA_TLS_GD_LARGE:
1559 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1561 case LoongArch::PseudoLA_TLS_DESC:
1562 emitLoadAddressTLSDesc(Inst, IDLoc, Out);
1564 case LoongArch::PseudoLA_TLS_DESC_LARGE:
1565 emitLoadAddressTLSDescLarge(Inst, IDLoc, Out);
1567 case LoongArch::PseudoLI_W:
1568 case LoongArch::PseudoLI_D:
1569 emitLoadImm(Inst, IDLoc, Out);
1571 case LoongArch::PseudoCALL36:
1572 emitFuncCall36(Inst, IDLoc, Out,
false);
1574 case LoongArch::PseudoTAIL36:
1575 emitFuncCall36(Inst, IDLoc, Out,
true);
1582unsigned LoongArchAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1592 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1593 return Match_RequiresAMORdDifferRkRj;
1596 case LoongArch::PseudoLA_TLS_DESC:
1597 case LoongArch::PseudoLA_TLS_DESC_LARGE: {
1599 if (Rd != LoongArch::R4)
1600 return Match_RequiresLAORdR4;
1603 case LoongArch::PseudoLA_PCREL_LARGE:
1604 case LoongArch::PseudoLA_GOT_LARGE:
1605 case LoongArch::PseudoLA_TLS_IE_LARGE:
1606 case LoongArch::PseudoLA_TLS_LD_LARGE:
1607 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1611 return Match_RequiresLAORdDifferRj;
1614 case LoongArch::CSRXCHG:
1615 case LoongArch::GCSRXCHG: {
1617 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1618 return Match_RequiresOpnd2NotR0R1;
1619 return Match_Success;
1621 case LoongArch::BSTRINS_W:
1622 case LoongArch::BSTRINS_D:
1623 case LoongArch::BSTRPICK_W:
1624 case LoongArch::BSTRPICK_D: {
1627 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1631 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1635 return Match_RequiresMsbNotLessThanLsb;
1636 return Match_Success;
1640 return Match_Success;
1646 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1648 return Match_InvalidOperand;
1653 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1654 Kind == MCK_FPR64) {
1656 return Match_Success;
1659 return Match_InvalidOperand;
1662bool LoongArchAsmParser::generateImmOutOfRangeError(
1664 const Twine &Msg =
"immediate must be an integer in the range") {
1669bool LoongArchAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1673 bool MatchingInlineAsm) {
1683 return processInstruction(Inst, IDLoc,
Operands, Out);
1684 case Match_MissingFeature: {
1685 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1686 bool FirstFeature =
true;
1687 std::string Msg =
"instruction requires the following:";
1688 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1689 if (MissingFeatures[i]) {
1690 Msg += FirstFeature ?
" " :
", ";
1692 FirstFeature =
false;
1695 return Error(IDLoc, Msg);
1697 case Match_MnemonicFail: {
1698 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1699 std::string Suggestion = LoongArchMnemonicSpellCheck(
1700 ((LoongArchOperand &)*
Operands[0]).getToken(), FBS, 0);
1701 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1703 case Match_InvalidOperand: {
1704 SMLoc ErrorLoc = IDLoc;
1707 return Error(ErrorLoc,
"too few operands for instruction");
1710 if (ErrorLoc ==
SMLoc())
1713 return Error(ErrorLoc,
"invalid operand for instruction");
1720 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1721 SMLoc ErrorLoc = IDLoc;
1723 return Error(ErrorLoc,
"too few operands for instruction");
1729 case Match_RequiresMsbNotLessThanLsb: {
1731 return Error(ErrorStart,
"msb is less than lsb",
1734 case Match_RequiresOpnd2NotR0R1:
1735 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1736 case Match_RequiresAMORdDifferRkRj:
1738 "$rd must be different from both $rk and $rj");
1739 case Match_RequiresLAORdDifferRj:
1740 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1741 case Match_RequiresLAORdR4:
1742 return Error(
Operands[1]->getStartLoc(),
"$rd must be $r4");
1743 case Match_InvalidUImm1:
1746 case Match_InvalidUImm2:
1749 case Match_InvalidUImm2plus1:
1752 case Match_InvalidUImm3:
1755 case Match_InvalidUImm4:
1758 case Match_InvalidUImm5:
1761 case Match_InvalidUImm6:
1764 case Match_InvalidUImm7:
1767 case Match_InvalidUImm8:
1770 case Match_InvalidUImm12:
1773 case Match_InvalidUImm12ori:
1774 return generateImmOutOfRangeError(
1777 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1778 "integer in the range");
1779 case Match_InvalidUImm14:
1782 case Match_InvalidUImm15:
1785 case Match_InvalidSImm5:
1788 case Match_InvalidSImm8:
1791 case Match_InvalidSImm8lsl1:
1792 return generateImmOutOfRangeError(
1794 "immediate must be a multiple of 2 in the range");
1795 case Match_InvalidSImm8lsl2:
1796 return generateImmOutOfRangeError(
1798 "immediate must be a multiple of 4 in the range");
1799 case Match_InvalidSImm10:
1802 case Match_InvalidSImm8lsl3:
1803 return generateImmOutOfRangeError(
1805 "immediate must be a multiple of 8 in the range");
1806 case Match_InvalidSImm9lsl3:
1807 return generateImmOutOfRangeError(
1809 "immediate must be a multiple of 8 in the range");
1810 case Match_InvalidSImm10lsl2:
1811 return generateImmOutOfRangeError(
1813 "immediate must be a multiple of 4 in the range");
1814 case Match_InvalidSImm11lsl1:
1815 return generateImmOutOfRangeError(
1817 "immediate must be a multiple of 2 in the range");
1818 case Match_InvalidSImm12:
1821 case Match_InvalidSImm12addlike:
1822 return generateImmOutOfRangeError(
1825 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1827 case Match_InvalidSImm12lu52id:
1828 return generateImmOutOfRangeError(
1831 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1832 "integer in the range");
1833 case Match_InvalidSImm13:
1836 case Match_InvalidSImm14lsl2:
1837 return generateImmOutOfRangeError(
1839 "immediate must be a multiple of 4 in the range");
1840 case Match_InvalidSImm16:
1843 case Match_InvalidSImm16lsl2:
1844 return generateImmOutOfRangeError(
1846 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1848 case Match_InvalidSImm20:
1851 case Match_InvalidSImm20lu12iw:
1852 return generateImmOutOfRangeError(
1855 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1857 case Match_InvalidSImm20lu32id:
1858 return generateImmOutOfRangeError(
1861 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1862 "integer in the range");
1863 case Match_InvalidSImm20pcalau12i:
1864 return generateImmOutOfRangeError(
1867 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1869 case Match_InvalidSImm20pcaddu18i:
1870 return generateImmOutOfRangeError(
1873 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1875 case Match_InvalidSImm20pcaddi:
1876 return generateImmOutOfRangeError(
1879 "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
1881 case Match_InvalidSImm21lsl2:
1882 return generateImmOutOfRangeError(
1884 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1886 case Match_InvalidSImm26Operand:
1887 return generateImmOutOfRangeError(
1889 "operand must be a bare symbol name or an immediate must be a multiple "
1890 "of 4 in the range");
1891 case Match_InvalidImm32: {
1893 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1895 case Match_InvalidImm64: {
1897 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
1899 case Match_InvalidBareSymbol: {
1901 return Error(ErrorLoc,
"operand must be a bare symbol name");
1903 case Match_InvalidTPRelAddSymbol: {
1905 return Error(ErrorLoc,
"operand must be a symbol with %le_add_r modifier");
1911bool LoongArchAsmParser::parseDirectiveOption() {
1922 if (Option ==
"push") {
1926 getTargetStreamer().emitDirectiveOptionPush();
1931 if (Option ==
"pop") {
1936 getTargetStreamer().emitDirectiveOptionPop();
1937 if (popFeatureBits())
1938 return Error(StartLoc,
".option pop with no .option push");
1943 if (Option ==
"relax") {
1947 getTargetStreamer().emitDirectiveOptionRelax();
1948 setFeatureBits(LoongArch::FeatureRelax,
"relax");
1952 if (Option ==
"norelax") {
1956 getTargetStreamer().emitDirectiveOptionNoRelax();
1957 clearFeatureBits(LoongArch::FeatureRelax,
"relax");
1963 "unknown option, expected 'push', 'pop', 'relax' or 'norelax'");
1969 if (DirectiveID.
getString() ==
".option")
1970 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,...