29#define DEBUG_TYPE "loongarch-asm-parser"
47 SMLoc &EndLoc)
override;
49 SMLoc &EndLoc)
override;
59 bool MatchingInlineAsm)
override;
64 unsigned Kind)
override;
75#define GET_ASSEMBLER_HEADER
76#include "LoongArchGenAsmMatcher.inc"
127 enum LoongArchMatchResultTy {
129 Match_RequiresMsbNotLessThanLsb,
130 Match_RequiresOpnd2NotR0R1,
131 Match_RequiresAMORdDifferRkRj,
132 Match_RequiresLAORdDifferRj,
133#define GET_OPERAND_DIAGNOSTIC_TYPES
134#include "LoongArchGenAsmMatcher.inc"
135#undef GET_OPERAND_DIAGNOSTIC_TYPES
138 static bool classifySymbolRef(
const MCExpr *Expr,
170 SMLoc StartLoc, EndLoc;
180 bool isToken()
const override {
return Kind == KindTy::Token; }
181 bool isReg()
const override {
return Kind == KindTy::Register; }
182 bool isImm()
const override {
return Kind == KindTy::Immediate; }
183 bool isMem()
const override {
return false; }
186 return Kind == KindTy::Register &&
187 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(
191 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
193 if (
auto *LE = dyn_cast<LoongArchMCExpr>(Expr)) {
198 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
199 Imm =
CE->getValue();
206 template <
unsigned N,
int P = 0>
bool isUImm()
const {
212 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
213 return IsConstantImm && isUInt<N>(Imm -
P) &&
217 template <
unsigned N,
unsigned S = 0>
bool isSImm()
const {
223 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
224 return IsConstantImm && isShiftedInt<N, S>(Imm) &&
228 bool isBareSymbol()
const {
232 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
234 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
238 bool isUImm2()
const {
return isUImm<2>(); }
239 bool isUImm2plus1()
const {
return isUImm<2, 1>(); }
240 bool isUImm3()
const {
return isUImm<3>(); }
241 bool isUImm5()
const {
return isUImm<5>(); }
242 bool isUImm6()
const {
return isUImm<6>(); }
243 bool isUImm8()
const {
return isUImm<8>(); }
244 bool isSImm12()
const {
return isSImm<12>(); }
246 bool isSImm12addlike()
const {
252 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
258 ? isInt<12>(Imm) && IsValidKind
259 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
263 bool isSImm12lu52id()
const {
269 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
279 ? isInt<12>(Imm) && IsValidKind
280 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
284 bool isUImm12()
const {
return isUImm<12>(); }
286 bool isUImm12ori()
const {
292 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
302 ? isUInt<12>(Imm) && IsValidKind
303 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
307 bool isUImm14()
const {
return isUImm<14>(); }
308 bool isUImm15()
const {
return isUImm<15>(); }
310 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
311 bool isSImm16()
const {
return isSImm<16>(); }
313 bool isSImm16lsl2()
const {
319 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
324 ? isShiftedInt<16, 2>(Imm) && IsValidKind
325 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
329 bool isSImm20()
const {
return isSImm<20>(); }
331 bool isSImm20pcalau12i()
const {
337 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
345 ? isInt<20>(Imm) && IsValidKind
346 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
350 bool isSImm20lu12iw()
const {
356 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
365 ? isInt<20>(Imm) && IsValidKind
366 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
370 bool isSImm20lu32id()
const {
376 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
387 ? isInt<20>(Imm) && IsValidKind
388 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
392 bool isSImm21lsl2()
const {
398 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
402 ? isShiftedInt<21, 2>(Imm) && IsValidKind
403 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
407 bool isSImm26Operand()
const {
413 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
419 ? isShiftedInt<26, 2>(Imm) && IsValidKind
420 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
424 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
431 unsigned getReg()
const override {
432 assert(Kind == KindTy::Register &&
"Invalid type access!");
433 return Reg.RegNum.id();
436 const MCExpr *getImm()
const {
437 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
442 assert(Kind == KindTy::Token &&
"Invalid type access!");
455 case KindTy::Immediate:
458 case KindTy::Register:
462 OS <<
"'" << getToken() <<
"'";
467 static std::unique_ptr<LoongArchOperand> createToken(
StringRef Str,
SMLoc S) {
468 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
475 static std::unique_ptr<LoongArchOperand> createReg(
unsigned RegNo,
SMLoc S,
477 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
478 Op->Reg.RegNum = RegNo;
484 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val,
SMLoc S,
486 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
494 if (
auto CE = dyn_cast<MCConstantExpr>(Expr))
501 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
502 assert(
N == 1 &&
"Invalid number of operands!");
505 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
506 assert(
N == 1 &&
"Invalid number of operands!");
507 addExpr(Inst, getImm());
512#define GET_REGISTER_MATCHER
513#define GET_SUBTARGET_FEATURE_NAME
514#define GET_MATCHER_IMPLEMENTATION
515#define GET_MNEMONIC_SPELL_CHECKER
516#include "LoongArchGenAsmMatcher.inc"
519 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
520 return Reg - LoongArch::F0 + LoongArch::F0_64;
530 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
532 static_assert(LoongArch::F0 < LoongArch::F0_64,
533 "FPR matching must be updated");
534 if (RegNo == LoongArch::NoRegister)
537 return RegNo == LoongArch::NoRegister;
540bool LoongArchAsmParser::parseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
542 return Error(getLoc(),
"invalid register number");
551bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
556 Kind = RE->getKind();
557 Expr = RE->getSubExpr();
579 if (RegNo == LoongArch::NoRegister)
585 Operands.push_back(LoongArchOperand::createReg(RegNo, S,
E));
596 switch (getLexer().getKind()) {
608 if (getParser().parseExpression(Res,
E))
612 return parseOperandWithModifier(
Operands);
615 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
625 Error(getLoc(),
"expected '%' for operand modifier");
632 Error(getLoc(),
"expected valid identifier for operand modifier");
639 Error(getLoc(),
"unrecognized operand modifier");
645 Error(getLoc(),
"expected '('");
651 if (getParser().parseParenExpression(SubExpr,
E)) {
656 Operands.push_back(LoongArchOperand::createImm(ModExpr, S,
E));
666 return parseOperandWithModifier(
Operands);
672 if (getParser().parseIdentifier(Identifier))
677 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
681 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
696 SMLoc ImmStart = getLoc();
697 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
700 Error(ImmStart,
"optional integer offset must be 0");
714 MatchOperandParserImpl(
Operands, Mnemonic,
true);
725 Error(getLoc(),
"unknown operand");
733 Operands.push_back(LoongArchOperand::createToken(
Name, NameLoc));
752 SMLoc Loc = getLexer().getLoc();
753 getParser().eatToEndOfStatement();
754 return Error(Loc,
"unexpected token");
762 for (LoongArchAsmParser::Inst &Inst : Insts) {
763 unsigned Opc = Inst.Opc;
769 case LoongArch::PCALAU12I:
770 case LoongArch::LU12I_W:
775 case LoongArch::ADDI_W:
776 case LoongArch::LD_W:
777 case LoongArch::LD_D: {
780 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addImm(0),
785 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
789 case LoongArch::LU32I_D:
791 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
792 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
796 case LoongArch::LU52I_D:
798 MCInstBuilder(Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
801 case LoongArch::ADDI_D:
805 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
809 case LoongArch::ADD_D:
810 case LoongArch::LDX_D:
812 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
819void LoongArchAsmParser::emitLoadAddressAbs(
MCInst &Inst,
SMLoc IDLoc,
835 Insts.push_back(LoongArchAsmParser::Inst(
837 Insts.push_back(LoongArchAsmParser::Inst(
841 Insts.push_back(LoongArchAsmParser::Inst(
843 Insts.push_back(LoongArchAsmParser::Inst(
847 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
850void LoongArchAsmParser::emitLoadAddressPcrel(
MCInst &Inst,
SMLoc IDLoc,
859 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
861 Insts.push_back(LoongArchAsmParser::Inst(
866 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
869void LoongArchAsmParser::emitLoadAddressPcrelLarge(
MCInst &Inst,
SMLoc IDLoc,
883 Insts.push_back(LoongArchAsmParser::Inst(
885 Insts.push_back(LoongArchAsmParser::Inst(
887 Insts.push_back(LoongArchAsmParser::Inst(
889 Insts.push_back(LoongArchAsmParser::Inst(
891 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
893 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
896void LoongArchAsmParser::emitLoadAddressGot(
MCInst &Inst,
SMLoc IDLoc,
905 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
907 Insts.push_back(LoongArchAsmParser::Inst(
912 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
915void LoongArchAsmParser::emitLoadAddressGotLarge(
MCInst &Inst,
SMLoc IDLoc,
929 Insts.push_back(LoongArchAsmParser::Inst(
931 Insts.push_back(LoongArchAsmParser::Inst(
933 Insts.push_back(LoongArchAsmParser::Inst(
935 Insts.push_back(LoongArchAsmParser::Inst(
937 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
939 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
942void LoongArchAsmParser::emitLoadAddressTLSLE(
MCInst &Inst,
SMLoc IDLoc,
952 Insts.push_back(LoongArchAsmParser::Inst(
954 Insts.push_back(LoongArchAsmParser::Inst(
957 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
960void LoongArchAsmParser::emitLoadAddressTLSIE(
MCInst &Inst,
SMLoc IDLoc,
969 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
971 Insts.push_back(LoongArchAsmParser::Inst(
973 Insts.push_back(LoongArchAsmParser::Inst(
976 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
979void LoongArchAsmParser::emitLoadAddressTLSIELarge(
MCInst &Inst,
SMLoc IDLoc,
993 Insts.push_back(LoongArchAsmParser::Inst(
995 Insts.push_back(LoongArchAsmParser::Inst(
997 Insts.push_back(LoongArchAsmParser::Inst(
999 Insts.push_back(LoongArchAsmParser::Inst(
1001 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1003 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1006void LoongArchAsmParser::emitLoadAddressTLSLD(
MCInst &Inst,
SMLoc IDLoc,
1015 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1017 Insts.push_back(LoongArchAsmParser::Inst(
1019 Insts.push_back(LoongArchAsmParser::Inst(
1022 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1025void LoongArchAsmParser::emitLoadAddressTLSLDLarge(
MCInst &Inst,
SMLoc IDLoc,
1039 Insts.push_back(LoongArchAsmParser::Inst(
1041 Insts.push_back(LoongArchAsmParser::Inst(
1043 Insts.push_back(LoongArchAsmParser::Inst(
1045 Insts.push_back(LoongArchAsmParser::Inst(
1047 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1049 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1052void LoongArchAsmParser::emitLoadAddressTLSGD(
MCInst &Inst,
SMLoc IDLoc,
1061 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1063 Insts.push_back(LoongArchAsmParser::Inst(
1065 Insts.push_back(LoongArchAsmParser::Inst(
1068 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1071void LoongArchAsmParser::emitLoadAddressTLSGDLarge(
MCInst &Inst,
SMLoc IDLoc,
1085 Insts.push_back(LoongArchAsmParser::Inst(
1087 Insts.push_back(LoongArchAsmParser::Inst(
1089 Insts.push_back(LoongArchAsmParser::Inst(
1091 Insts.push_back(LoongArchAsmParser::Inst(
1093 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1095 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1098void LoongArchAsmParser::emitLoadImm(
MCInst &Inst,
SMLoc IDLoc,
1104 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1105 Imm = SignExtend64<32>(Imm);
1108 unsigned Opc = Inst.Opc;
1109 if (Opc == LoongArch::LU12I_W)
1114 MCInstBuilder(Opc).addReg(DestReg).addReg(SrcReg).addImm(Inst.Imm),
1120bool LoongArchAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1127 case LoongArch::PseudoLA_ABS:
1128 case LoongArch::PseudoLA_ABS_LARGE:
1129 emitLoadAddressAbs(Inst, IDLoc, Out);
1131 case LoongArch::PseudoLA_PCREL:
1132 emitLoadAddressPcrel(Inst, IDLoc, Out);
1134 case LoongArch::PseudoLA_PCREL_LARGE:
1135 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1137 case LoongArch::PseudoLA_GOT:
1138 emitLoadAddressGot(Inst, IDLoc, Out);
1140 case LoongArch::PseudoLA_GOT_LARGE:
1141 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1143 case LoongArch::PseudoLA_TLS_LE:
1144 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1146 case LoongArch::PseudoLA_TLS_IE:
1147 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1149 case LoongArch::PseudoLA_TLS_IE_LARGE:
1150 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1152 case LoongArch::PseudoLA_TLS_LD:
1153 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1155 case LoongArch::PseudoLA_TLS_LD_LARGE:
1156 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1158 case LoongArch::PseudoLA_TLS_GD:
1159 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1161 case LoongArch::PseudoLA_TLS_GD_LARGE:
1162 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1164 case LoongArch::PseudoLI_W:
1165 case LoongArch::PseudoLI_D:
1166 emitLoadImm(Inst, IDLoc, Out);
1173unsigned LoongArchAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1177 if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) {
1181 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1182 return Match_RequiresAMORdDifferRkRj;
1185 case LoongArch::PseudoLA_PCREL_LARGE:
1186 case LoongArch::PseudoLA_GOT_LARGE:
1187 case LoongArch::PseudoLA_TLS_IE_LARGE:
1188 case LoongArch::PseudoLA_TLS_LD_LARGE:
1189 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1193 return Match_RequiresLAORdDifferRj;
1196 case LoongArch::CSRXCHG: {
1198 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1199 return Match_RequiresOpnd2NotR0R1;
1200 return Match_Success;
1202 case LoongArch::BSTRINS_W:
1203 case LoongArch::BSTRINS_D:
1204 case LoongArch::BSTRPICK_W:
1205 case LoongArch::BSTRPICK_D: {
1208 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1212 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
1216 return Match_RequiresMsbNotLessThanLsb;
1217 return Match_Success;
1221 return Match_Success;
1227 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1229 return Match_InvalidOperand;
1234 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1235 Kind == MCK_FPR64) {
1237 return Match_Success;
1240 return Match_InvalidOperand;
1243bool LoongArchAsmParser::generateImmOutOfRangeError(
1245 Twine Msg =
"immediate must be an integer in the range") {
1250bool LoongArchAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1254 bool MatchingInlineAsm) {
1264 return processInstruction(Inst, IDLoc,
Operands, Out);
1265 case Match_MissingFeature: {
1266 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1267 bool FirstFeature =
true;
1268 std::string
Msg =
"instruction requires the following:";
1269 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1270 if (MissingFeatures[i]) {
1271 Msg += FirstFeature ?
" " :
", ";
1273 FirstFeature =
false;
1276 return Error(IDLoc, Msg);
1278 case Match_MnemonicFail: {
1279 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1280 std::string Suggestion = LoongArchMnemonicSpellCheck(
1281 ((LoongArchOperand &)*
Operands[0]).getToken(), FBS, 0);
1282 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1284 case Match_InvalidOperand: {
1285 SMLoc ErrorLoc = IDLoc;
1288 return Error(ErrorLoc,
"too few operands for instruction");
1291 if (ErrorLoc ==
SMLoc())
1294 return Error(ErrorLoc,
"invalid operand for instruction");
1301 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1302 SMLoc ErrorLoc = IDLoc;
1304 return Error(ErrorLoc,
"too few operands for instruction");
1310 case Match_RequiresMsbNotLessThanLsb: {
1312 return Error(ErrorStart,
"msb is less than lsb",
1315 case Match_RequiresOpnd2NotR0R1:
1316 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1317 case Match_RequiresAMORdDifferRkRj:
1319 "$rd must be different from both $rk and $rj");
1320 case Match_RequiresLAORdDifferRj:
1321 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1322 case Match_InvalidUImm2:
1325 case Match_InvalidUImm2plus1:
1328 case Match_InvalidUImm3:
1331 case Match_InvalidUImm5:
1334 case Match_InvalidUImm6:
1337 case Match_InvalidUImm12:
1340 case Match_InvalidUImm12ori:
1341 return generateImmOutOfRangeError(
1344 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1345 "integer in the range");
1346 case Match_InvalidUImm15:
1349 case Match_InvalidSImm12:
1352 case Match_InvalidSImm12addlike:
1353 return generateImmOutOfRangeError(
1356 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1358 case Match_InvalidSImm12lu52id:
1359 return generateImmOutOfRangeError(
1362 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1363 "integer in the range");
1364 case Match_InvalidSImm14lsl2:
1365 return generateImmOutOfRangeError(
1367 "immediate must be a multiple of 4 in the range");
1368 case Match_InvalidSImm16:
1371 case Match_InvalidSImm16lsl2:
1372 return generateImmOutOfRangeError(
1374 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1376 case Match_InvalidSImm20:
1379 case Match_InvalidSImm20lu12iw:
1380 return generateImmOutOfRangeError(
1383 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1385 case Match_InvalidSImm20lu32id:
1386 return generateImmOutOfRangeError(
1389 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1390 "integer in the range");
1391 case Match_InvalidSImm20pcalau12i:
1392 return generateImmOutOfRangeError(
1395 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1397 case Match_InvalidSImm21lsl2:
1398 return generateImmOutOfRangeError(
1400 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1402 case Match_InvalidSImm26Operand:
1403 return generateImmOutOfRangeError(
1405 "operand must be a bare symbol name or an immediate must be a multiple "
1406 "of 4 in the range");
1407 case Match_InvalidImm32: {
1409 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1411 case Match_InvalidBareSymbol: {
1413 return Error(ErrorLoc,
"operand must be a bare symbol name");
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchRegisterName(StringRef Name)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static unsigned 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.
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 const LoongArchMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
static VariantKind getVariantKindForName(StringRef name)
@ VK_LoongArch_PCALA_HI20
@ VK_LoongArch_TLS_LD_PC_HI20
@ VK_LoongArch_TLS_LE64_HI12
@ VK_LoongArch_TLS_LD_HI20
@ VK_LoongArch_GOT64_HI12
@ VK_LoongArch_PCALA_LO12
@ VK_LoongArch_TLS_IE_HI20
@ VK_LoongArch_TLS_GD_HI20
@ VK_LoongArch_ABS64_HI12
@ VK_LoongArch_TLS_LE_LO12
@ VK_LoongArch_TLS_IE64_HI12
@ VK_LoongArch_GOT_PC_HI20
@ VK_LoongArch_TLS_IE64_PC_LO20
@ VK_LoongArch_TLS_IE64_LO20
@ VK_LoongArch_TLS_IE_PC_LO12
@ VK_LoongArch_GOT64_PC_HI12
@ VK_LoongArch_TLS_IE_PC_HI20
@ VK_LoongArch_TLS_LE64_LO20
@ VK_LoongArch_PCALA64_LO20
@ VK_LoongArch_TLS_IE_LO12
@ VK_LoongArch_GOT_PC_LO12
@ VK_LoongArch_TLS_LE_HI20
@ VK_LoongArch_GOT64_LO20
@ VK_LoongArch_TLS_GD_PC_HI20
@ VK_LoongArch_GOT64_PC_LO20
@ VK_LoongArch_PCALA64_HI12
@ VK_LoongArch_TLS_IE64_PC_HI12
@ VK_LoongArch_ABS64_LO20
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Interface to description of machine instruction set.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual unsigned getReg() const =0
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 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.
virtual bool ParseDirective(AsmToken DirectiveID)=0
ParseDirective - Parse a target specific assembler directive.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
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 ...
virtual OperandMatchResultTy tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
This represents an "assembler immediate".
uint32_t getRefKind() const
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const CustomOperand< const MCSubtargetInfo & > Msg[]
InstSeq generateInstSeq(int64_t Val)
SmallVector< Inst, 4 > InstSeq
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheLoongArch64Target()
Target & getTheLoongArch32Target()
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...