33#define DEBUG_TYPE "loongarch-asm-parser"
39 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
40 bool is64Bit()
const {
return getSTI().hasFeature(LoongArch::Feature64Bit); }
41 bool has32S()
const {
return getSTI().hasFeature(LoongArch::Feature32S); }
43 assert(getParser().getStreamer().getTargetStreamer() &&
44 "do not have a target streamer");
59 SMLoc &EndLoc)
override;
64 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
67 bool MatchingInlineAsm)
override;
69 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
72 unsigned Kind)
override;
86#define GET_ASSEMBLER_HEADER
87#include "LoongArchGenAsmMatcher.inc"
97 bool parseDirectiveOption();
98 bool parseDirectiveDtpRelWord();
99 bool parseDirectiveDtpRelDWord();
102 if (!(getSTI().hasFeature(Feature))) {
104 setAvailableFeatures(
109 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
110 if (getSTI().hasFeature(Feature)) {
111 MCSubtargetInfo &STI = copySTI();
112 setAvailableFeatures(
117 void pushFeatureBits() {
118 FeatureBitStack.push_back(getSTI().getFeatureBits());
121 bool popFeatureBits() {
122 if (FeatureBitStack.empty())
125 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
126 copySTI().setFeatureBits(FeatureBits);
127 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
134 void emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
135 const MCExpr *Symbol, SmallVectorImpl<Inst> &Insts,
136 SMLoc IDLoc, MCStreamer &Out,
bool RelaxHint =
false);
139 void emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
142 void emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
144 void emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
147 void emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
149 void emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
152 void emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
155 void emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
157 void emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
160 void emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
162 void emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
165 void emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
167 void emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
170 void emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
172 void emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
175 void emitLoadImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
178 void emitFuncCall(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
bool IsTailCall,
182 enum LoongArchMatchResultTy {
183 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
184 Match_RequiresMsbNotLessThanLsb,
185 Match_RequiresOpnd2NotR0R1,
186 Match_RequiresAMORdDifferRkRj,
187 Match_RequiresLAORdDifferRj,
188 Match_RequiresLAORdR4,
189#define GET_OPERAND_DIAGNOSTIC_TYPES
190#include "LoongArchGenAsmMatcher.inc"
191#undef GET_OPERAND_DIAGNOSTIC_TYPES
194 static bool classifySymbolRef(
const MCExpr *Expr,
197 LoongArchAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
198 const MCInstrInfo &MII)
199 : MCTargetAsmParser(STI, MII) {
206 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
226 SMLoc StartLoc, EndLoc;
234 LoongArchOperand(KindTy K) : MCParsedAsmOperand(), Kind(
K) {}
236 bool isToken()
const override {
return Kind == KindTy::Token; }
237 bool isReg()
const override {
return Kind == KindTy::Register; }
238 bool isImm()
const override {
return Kind == KindTy::Immediate; }
239 bool isMem()
const override {
return false; }
240 void setReg(MCRegister PhysReg) {
Reg.RegNum = PhysReg; }
242 return Kind == KindTy::Register &&
243 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(
247 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
250 VK =
LE->getSpecifier();
255 Imm =
CE->getValue();
262 template <
unsigned N,
int P = 0>
bool isUImm()
const {
268 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
273 template <
unsigned N,
unsigned S = 0>
bool isSImm()
const {
279 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
284 bool isBareSymbol()
const {
288 if (!isImm() || evaluateConstantImm(
getImm(), Imm, VK))
290 return LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
294 bool isTPRelAddSymbol()
const {
298 if (!isImm() || evaluateConstantImm(
getImm(), Imm, VK))
300 return LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
301 VK == ELF::R_LARCH_TLS_LE_ADD_R;
304 bool isUImm1()
const {
return isUImm<1>(); }
305 bool isUImm2()
const {
return isUImm<2>(); }
306 bool isUImm2plus1()
const {
return isUImm<2, 1>(); }
307 bool isUImm3()
const {
return isUImm<3>(); }
308 bool isUImm4()
const {
return isUImm<4>(); }
309 bool isSImm5()
const {
return isSImm<5>(); }
310 bool isUImm5()
const {
return isUImm<5>(); }
311 bool isUImm6()
const {
return isUImm<6>(); }
312 bool isUImm7()
const {
return isUImm<7>(); }
313 bool isSImm8()
const {
return isSImm<8>(); }
314 bool isSImm8lsl1()
const {
return isSImm<8, 1>(); }
315 bool isSImm8lsl2()
const {
return isSImm<8, 2>(); }
316 bool isSImm8lsl3()
const {
return isSImm<8, 3>(); }
317 bool isUImm8()
const {
return isUImm<8>(); }
318 bool isSImm9lsl3()
const {
return isSImm<9, 3>(); }
319 bool isSImm10()
const {
return isSImm<10>(); }
320 bool isSImm10lsl2()
const {
return isSImm<10, 2>(); }
321 bool isSImm11lsl1()
const {
return isSImm<11, 1>(); }
322 bool isSImm12()
const {
return isSImm<12>(); }
324 bool isSImm12addlike()
const {
330 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
333 VK == ELF::R_LARCH_GOT_PC_LO12 || VK == ELF::R_LARCH_TLS_IE_PC_LO12 ||
334 VK == ELF::R_LARCH_TLS_LE_LO12_R || VK == ELF::R_LARCH_TLS_DESC_LD ||
335 VK == ELF::R_LARCH_TLS_DESC_PC_LO12 || VK == ELF::R_LARCH_PCADD_LO12 ||
336 VK == ELF::R_LARCH_GOT_PCADD_LO12 ||
337 VK == ELF::R_LARCH_TLS_IE_PCADD_LO12 ||
338 VK == ELF::R_LARCH_TLS_LD_PCADD_LO12 ||
339 VK == ELF::R_LARCH_TLS_GD_PCADD_LO12 ||
340 VK == ELF::R_LARCH_TLS_DESC_PCADD_LO12;
343 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
347 bool isSImm12lu52id()
const {
353 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
356 VK == ELF::R_LARCH_PCALA64_HI12 || VK == ELF::R_LARCH_GOT64_HI12 ||
357 VK == ELF::R_LARCH_GOT64_PC_HI12 || VK == ELF::R_LARCH_TLS_LE64_HI12 ||
358 VK == ELF::R_LARCH_TLS_IE64_HI12 ||
359 VK == ELF::R_LARCH_TLS_IE64_PC_HI12 ||
360 VK == ELF::R_LARCH_TLS_DESC64_HI12 ||
361 VK == ELF::R_LARCH_TLS_DESC64_PC_HI12;
364 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
368 bool isUImm12()
const {
return isUImm<12>(); }
370 bool isUImm12ori()
const {
376 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
379 VK == ELF::R_LARCH_PCALA_LO12 || VK == ELF::R_LARCH_GOT_LO12 ||
380 VK == ELF::R_LARCH_GOT_PC_LO12 || VK == ELF::R_LARCH_TLS_LE_LO12 ||
381 VK == ELF::R_LARCH_TLS_IE_LO12 || VK == ELF::R_LARCH_TLS_IE_PC_LO12 ||
382 VK == ELF::R_LARCH_TLS_DESC_LO12;
385 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
389 bool isSImm13()
const {
return isSImm<13>(); }
390 bool isUImm14()
const {
return isUImm<14>(); }
391 bool isUImm15()
const {
return isUImm<15>(); }
393 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
394 bool isSImm16()
const {
return isSImm<16>(); }
396 bool isSImm16lsl2()
const {
402 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
405 VK == ELF::R_LARCH_PCALA_LO12 || VK == ELF::R_LARCH_TLS_DESC_CALL;
408 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
412 bool isSImm20()
const {
return isSImm<20>(); }
414 bool isSImm20pcalau12i()
const {
420 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
423 VK == ELF::R_LARCH_GOT_PC_HI20 || VK == ELF::R_LARCH_TLS_IE_PC_HI20 ||
424 VK == ELF::R_LARCH_TLS_LD_PC_HI20 ||
425 VK == ELF::R_LARCH_TLS_GD_PC_HI20 ||
426 VK == ELF::R_LARCH_TLS_DESC_PC_HI20;
429 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
433 bool isSImm20lu12iw()
const {
439 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
442 VK == ELF::R_LARCH_GOT_HI20 || VK == ELF::R_LARCH_TLS_GD_HI20 ||
443 VK == ELF::R_LARCH_TLS_LD_HI20 || VK == ELF::R_LARCH_TLS_IE_HI20 ||
444 VK == ELF::R_LARCH_TLS_LE_HI20 || VK == ELF::R_LARCH_TLS_LE_HI20_R ||
445 VK == ELF::R_LARCH_TLS_DESC_HI20;
448 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
452 bool isSImm20lu32id()
const {
458 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
461 VK == ELF::R_LARCH_PCALA64_LO20 || VK == ELF::R_LARCH_GOT64_LO20 ||
462 VK == ELF::R_LARCH_GOT64_PC_LO20 || VK == ELF::R_LARCH_TLS_IE64_LO20 ||
463 VK == ELF::R_LARCH_TLS_IE64_PC_LO20 ||
464 VK == ELF::R_LARCH_TLS_LE64_LO20 ||
465 VK == ELF::R_LARCH_TLS_DESC64_PC_LO20 ||
466 VK == ELF::R_LARCH_TLS_DESC64_LO20;
470 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
474 bool isSImm20pcaddu12i()
const {
480 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
483 VK == ELF::R_LARCH_PCADD_HI20 || VK == ELF::R_LARCH_GOT_PCADD_HI20 ||
484 VK == ELF::R_LARCH_TLS_IE_PCADD_HI20 ||
485 VK == ELF::R_LARCH_TLS_LD_PCADD_HI20 ||
486 VK == ELF::R_LARCH_TLS_GD_PCADD_HI20 ||
487 VK == ELF::R_LARCH_TLS_DESC_PCADD_HI20;
491 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
495 bool isSImm20pcaddu18i()
const {
501 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
507 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
511 bool isSImm20pcaddi()
const {
517 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
519 VK == ELF::R_LARCH_PCREL20_S2 ||
520 VK == ELF::R_LARCH_TLS_LD_PCREL20_S2 ||
521 VK == ELF::R_LARCH_TLS_GD_PCREL20_S2 ||
522 VK == ELF::R_LARCH_TLS_DESC_PCREL20_S2;
525 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
529 bool isSImm21lsl2()
const {
535 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
539 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
543 bool isSImm26Operand()
const {
549 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
553 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
557 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
558 bool isImm64()
const {
563 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
568 SMLoc getStartLoc()
const override {
return StartLoc; }
570 SMLoc getEndLoc()
const override {
return EndLoc; }
572 MCRegister
getReg()
const override {
573 assert(Kind == KindTy::Register &&
"Invalid type access!");
577 const MCExpr *
getImm()
const {
578 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
583 assert(Kind == KindTy::Token &&
"Invalid type access!");
587 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
596 case KindTy::Immediate:
599 case KindTy::Register:
608 static std::unique_ptr<LoongArchOperand> createToken(StringRef Str, SMLoc S) {
609 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
616 static std::unique_ptr<LoongArchOperand> createReg(MCRegister
Reg, SMLoc S,
618 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
619 Op->Reg.RegNum =
Reg;
625 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val, SMLoc S,
627 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
634 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
642 void addRegOperands(MCInst &Inst,
unsigned N)
const {
643 assert(
N == 1 &&
"Invalid number of operands!");
646 void addImmOperands(MCInst &Inst,
unsigned N)
const {
647 assert(
N == 1 &&
"Invalid number of operands!");
653#define GET_REGISTER_MATCHER
654#define GET_SUBTARGET_FEATURE_NAME
655#define GET_MATCHER_IMPLEMENTATION
656#define GET_MNEMONIC_SPELL_CHECKER
657#include "LoongArchGenAsmMatcher.inc"
660 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
661 return Reg - LoongArch::F0 + LoongArch::F0_64;
671 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
673 static_assert(LoongArch::F0 < LoongArch::F0_64,
674 "FPR matching must be updated");
675 if (RegNo == LoongArch::NoRegister)
678 return RegNo == LoongArch::NoRegister;
683 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
684 return Error(getLoc(),
"invalid register name");
686 if (!LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].
contains(
Reg) &&
687 !LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg))
688 return Error(getLoc(),
"invalid register name");
693ParseStatus LoongArchAsmParser::tryParseRegister(MCRegister &
Reg,
696 const AsmToken &Tok = getParser().getTok();
712bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
717 Kind = RE->getSpecifier();
718 Expr = RE->getSubExpr();
727ParseStatus LoongArchAsmParser::parseRegister(
OperandVector &Operands) {
733 StringRef
Name = getLexer().getTok().getIdentifier();
736 if (RegNo == LoongArch::NoRegister)
742 Operands.
push_back(LoongArchOperand::createReg(RegNo, S,
E));
747ParseStatus LoongArchAsmParser::parseImmediate(
OperandVector &Operands) {
752 switch (getLexer().getKind()) {
764 if (getParser().parseExpression(Res,
E))
768 return parseOperandWithModifier(Operands);
771 Operands.
push_back(LoongArchOperand::createImm(Res, S,
E));
776LoongArchAsmParser::parseOperandWithModifier(
OperandVector &Operands) {
781 return Error(getLoc(),
"expected '%' for operand modifier");
786 return Error(getLoc(),
"expected valid identifier for operand modifier");
787 StringRef
Identifier = getParser().getTok().getIdentifier();
790 return Error(getLoc(),
"invalid relocation specifier");
794 return Error(getLoc(),
"expected '('");
797 const MCExpr *SubExpr;
798 if (getParser().parseParenExpression(SubExpr,
E))
802 Operands.
push_back(LoongArchOperand::createImm(ModExpr, S,
E));
806ParseStatus LoongArchAsmParser::parseSImm26Operand(
OperandVector &Operands) {
811 return parseOperandWithModifier(Operands);
817 if (getParser().parseIdentifier(Identifier))
824 Operands.
push_back(LoongArchOperand::createImm(Res, S,
E));
828ParseStatus LoongArchAsmParser::parseAtomicMemOp(
OperandVector &Operands) {
830 if (!parseRegister(Operands).isSuccess())
837 SMLoc ImmStart = getLoc();
838 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
841 return Error(ImmStart,
"optional integer offset must be 0");
848bool LoongArchAsmParser::parseOperand(
OperandVector &Operands,
849 StringRef Mnemonic) {
853 MatchOperandParserImpl(Operands, Mnemonic,
true);
859 if (parseRegister(Operands).isSuccess() ||
864 return Error(getLoc(),
"unknown operand");
867bool LoongArchAsmParser::parseInstruction(ParseInstructionInfo &Info,
868 StringRef Name, SMLoc NameLoc,
871 Operands.
push_back(LoongArchOperand::createToken(Name, NameLoc));
878 if (parseOperand(Operands, Name))
883 if (parseOperand(Operands, Name))
890 SMLoc Loc = getLexer().getLoc();
891 getParser().eatToEndOfStatement();
892 return Error(Loc,
"unexpected token");
895void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
896 const MCExpr *Symbol,
897 SmallVectorImpl<Inst> &Insts,
898 SMLoc IDLoc, MCStreamer &Out,
902 for (LoongArchAsmParser::Inst &Inst : Insts) {
903 unsigned Opc = Inst.Opc;
905 const LoongArchMCExpr *
LE =
910 case LoongArch::PCADDU12I:
914 case LoongArch::PCALAU12I:
915 case LoongArch::LU12I_W:
920 case LoongArch::ADDI_W:
921 case LoongArch::LD_W:
922 case LoongArch::LD_D: {
925 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addImm(0),
928 }
else if (VK == ELF::R_LARCH_TLS_DESC_LD) {
930 .addReg(LoongArch::R1)
935 }
else if (VK == ELF::R_LARCH_PCADD_LO12 ||
936 VK == ELF::R_LARCH_GOT_PCADD_LO12 ||
937 VK == ELF::R_LARCH_TLS_IE_PCADD_LO12 ||
938 VK == ELF::R_LARCH_TLS_LD_PCADD_LO12 ||
939 VK == ELF::R_LARCH_TLS_GD_PCADD_LO12 ||
940 VK == ELF::R_LARCH_TLS_DESC_PCADD_LO12) {
942 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addExpr(
944 VK, Ctx, RelaxHint)),
949 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
953 case LoongArch::LU32I_D:
955 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
956 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
960 case LoongArch::LU52I_D:
962 MCInstBuilder(
Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
965 case LoongArch::ADDI_D:
969 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
973 case LoongArch::ADD_D:
974 case LoongArch::LDX_D:
976 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
979 case LoongArch::JIRL:
981 .addReg(LoongArch::R1)
982 .addReg(LoongArch::R1)
990void LoongArchAsmParser::emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc,
1009 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_MARK_LA));
1011 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_ABS_LO12));
1015 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_ABS64_LO20));
1017 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_ABS64_HI12));
1020 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1023void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc,
1038 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1039 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1041 has32S() ? ELF::R_LARCH_PCALA_HI20 : ELF::R_LARCH_PCADD_HI20;
1043 has32S() ? ELF::R_LARCH_PCALA_LO12 : ELF::R_LARCH_PCADD_LO12;
1045 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1046 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
1048 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1052void LoongArchAsmParser::emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc,
1067 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));
1069 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_PCALA_LO12));
1071 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_PCALA64_LO20));
1073 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_PCALA64_HI12));
1074 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1076 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1079void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,
1085 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1086 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1088 has32S() ? ELF::R_LARCH_GOT_PC_HI20 : ELF::R_LARCH_GOT_PCADD_HI20;
1090 has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_GOT_PCADD_LO12;
1092 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1106 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_GOT_HI20));
1108 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1111 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1112 ELF::R_LARCH_GOT64_LO20));
1113 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1114 ELF::R_LARCH_GOT64_HI12));
1116 Insts.push_back(LoongArchAsmParser::Inst(LD));
1117 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1128 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1129 Insts.push_back(LoongArchAsmParser::Inst(LD, LDRel));
1131 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1135void LoongArchAsmParser::emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc,
1150 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));
1152 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1154 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1156 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1157 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1159 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1162void LoongArchAsmParser::emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc,
1173 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LE_HI20));
1175 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_LE_LO12));
1177 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1180void LoongArchAsmParser::emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc,
1186 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1187 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1189 has32S() ? ELF::R_LARCH_TLS_IE_PC_HI20 : ELF::R_LARCH_TLS_IE_PCADD_HI20;
1191 has32S() ? ELF::R_LARCH_TLS_IE_PC_LO12 : ELF::R_LARCH_TLS_IE_PCADD_LO12;
1193 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1207 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_IE_HI20));
1209 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_IE_LO12));
1212 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1213 ELF::R_LARCH_TLS_IE64_LO20));
1214 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1215 ELF::R_LARCH_TLS_IE64_HI12));
1217 Insts.push_back(LoongArchAsmParser::Inst(LD));
1218 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1230 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1231 Insts.push_back(LoongArchAsmParser::Inst(LD, LDRel));
1233 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1237void LoongArchAsmParser::emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc,
1251 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1252 ELF::R_LARCH_TLS_IE_PC_HI20));
1254 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_TLS_IE_PC_LO12));
1255 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1256 ELF::R_LARCH_TLS_IE64_PC_LO20));
1257 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1258 ELF::R_LARCH_TLS_IE64_PC_HI12));
1259 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1261 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1264void LoongArchAsmParser::emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc,
1270 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1271 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1273 has32S() ? ELF::R_LARCH_TLS_LD_PC_HI20 : ELF::R_LARCH_TLS_LD_PCADD_HI20;
1275 has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_TLS_LD_PCADD_LO12;
1277 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1289 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LD_HI20));
1291 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1294 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1295 ELF::R_LARCH_GOT64_LO20));
1296 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1297 ELF::R_LARCH_GOT64_HI12));
1299 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1311 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1312 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
1314 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1318void LoongArchAsmParser::emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc,
1332 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1333 ELF::R_LARCH_TLS_LD_PC_HI20));
1335 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1337 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1339 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1340 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1342 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1345void LoongArchAsmParser::emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc,
1351 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1352 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1354 has32S() ? ELF::R_LARCH_TLS_GD_PC_HI20 : ELF::R_LARCH_TLS_GD_PCADD_HI20;
1356 has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_TLS_GD_PCADD_LO12;
1358 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1370 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_GD_HI20));
1372 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1375 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1376 ELF::R_LARCH_GOT64_LO20));
1377 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1378 ELF::R_LARCH_GOT64_HI12));
1380 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1392 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1393 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
1395 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1399void LoongArchAsmParser::emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc,
1413 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1414 ELF::R_LARCH_TLS_GD_PC_HI20));
1416 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1418 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1420 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1421 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1423 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1426void LoongArchAsmParser::emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc,
1431 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1432 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1433 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1434 unsigned PCAIRel = has32S() ? ELF::R_LARCH_TLS_DESC_PC_HI20
1435 : ELF::R_LARCH_TLS_DESC_PCADD_HI20;
1436 unsigned ADDIRel = has32S() ? ELF::R_LARCH_TLS_DESC_PC_LO12
1437 : ELF::R_LARCH_TLS_DESC_PCADD_LO12;
1440 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1455 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU12I_W,
1456 ELF::R_LARCH_TLS_DESC_HI20));
1458 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_DESC_LO12));
1461 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1462 ELF::R_LARCH_TLS_DESC64_LO20));
1463 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1464 ELF::R_LARCH_TLS_DESC64_HI12));
1467 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
1469 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1471 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1487 Insts.
push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1488 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
1489 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
1491 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1493 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1497void LoongArchAsmParser::emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc,
1513 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1514 ELF::R_LARCH_TLS_DESC_PC_HI20));
1515 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADDI_D,
1516 ELF::R_LARCH_TLS_DESC_PC_LO12));
1517 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1518 ELF::R_LARCH_TLS_DESC64_PC_LO20));
1519 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1520 ELF::R_LARCH_TLS_DESC64_PC_HI12));
1521 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1523 LoongArchAsmParser::Inst(LoongArch::LD_D, ELF::R_LARCH_TLS_DESC_LD));
1525 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1527 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1530void LoongArchAsmParser::emitLoadImm(MCInst &Inst, SMLoc IDLoc,
1534 MCRegister SrcReg = LoongArch::R0;
1536 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1541 case LoongArch::LU12I_W:
1543 MCInstBuilder(Inst.Opc).addReg(DestReg).addImm(Inst.Imm), getSTI());
1545 case LoongArch::ADDI_W:
1546 case LoongArch::ORI:
1547 case LoongArch::LU32I_D:
1548 case LoongArch::LU52I_D:
1550 MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1554 case LoongArch::BSTRINS_D:
1559 .addImm(Inst.Imm >> 32)
1560 .addImm(Inst.Imm & 0xFF),
1570void LoongArchAsmParser::emitFuncCall(MCInst &Inst, SMLoc IDLoc,
1571 MCStreamer &Out,
bool IsTailCall,
1592 MCRegister ScratchReg =
1594 unsigned PCAI = IsCall36 ? LoongArch::PCADDU18I : LoongArch::PCADDU12I;
1595 unsigned Rel = IsCall36 ? ELF::R_LARCH_CALL36 : ELF::R_LARCH_CALL30;
1598 const LoongArchMCExpr *
LE =
1601 Out.
emitInstruction(MCInstBuilder(PCAI).addReg(ScratchReg).addExpr(LE),
1604 MCInstBuilder(LoongArch::JIRL)
1605 .addReg(IsTailCall ? MCRegister(LoongArch::R0) : ScratchReg)
1611bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1618 case LoongArch::PseudoLA_ABS:
1619 case LoongArch::PseudoLA_ABS_LARGE:
1620 emitLoadAddressAbs(Inst, IDLoc, Out);
1622 case LoongArch::PseudoLA_PCREL:
1623 emitLoadAddressPcrel(Inst, IDLoc, Out);
1625 case LoongArch::PseudoLA_PCREL_LARGE:
1626 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1628 case LoongArch::PseudoLA_GOT:
1629 emitLoadAddressGot(Inst, IDLoc, Out);
1631 case LoongArch::PseudoLA_GOT_LARGE:
1632 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1634 case LoongArch::PseudoLA_TLS_LE:
1635 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1637 case LoongArch::PseudoLA_TLS_IE:
1638 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1640 case LoongArch::PseudoLA_TLS_IE_LARGE:
1641 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1643 case LoongArch::PseudoLA_TLS_LD:
1644 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1646 case LoongArch::PseudoLA_TLS_LD_LARGE:
1647 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1649 case LoongArch::PseudoLA_TLS_GD:
1650 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1652 case LoongArch::PseudoLA_TLS_GD_LARGE:
1653 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1655 case LoongArch::PseudoLA_TLS_DESC:
1656 emitLoadAddressTLSDesc(Inst, IDLoc, Out);
1658 case LoongArch::PseudoLA_TLS_DESC_LARGE:
1659 emitLoadAddressTLSDescLarge(Inst, IDLoc, Out);
1661 case LoongArch::PseudoLI_W:
1662 case LoongArch::PseudoLI_D:
1663 emitLoadImm(Inst, IDLoc, Out);
1665 case LoongArch::PseudoCALL:
1666 emitFuncCall(Inst, IDLoc, Out,
false,
1669 case LoongArch::PseudoCALL30:
1670 emitFuncCall(Inst, IDLoc, Out,
false,
false);
1672 case LoongArch::PseudoCALL36:
1673 emitFuncCall(Inst, IDLoc, Out,
false,
true);
1675 case LoongArch::PseudoTAIL:
1676 emitFuncCall(Inst, IDLoc, Out,
true,
is64Bit());
1678 case LoongArch::PseudoTAIL30:
1679 emitFuncCall(Inst, IDLoc, Out,
true,
false);
1681 case LoongArch::PseudoTAIL36:
1682 emitFuncCall(Inst, IDLoc, Out,
true,
true);
1689unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1691 const MCInstrDesc &MCID = MII.
get(
Opc);
1699 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1700 return Match_RequiresAMORdDifferRkRj;
1703 case LoongArch::PseudoLA_TLS_DESC:
1704 case LoongArch::PseudoLA_TLS_DESC_LARGE: {
1706 if (Rd != LoongArch::R4)
1707 return Match_RequiresLAORdR4;
1710 case LoongArch::PseudoLA_PCREL_LARGE:
1711 case LoongArch::PseudoLA_GOT_LARGE:
1712 case LoongArch::PseudoLA_TLS_IE_LARGE:
1713 case LoongArch::PseudoLA_TLS_LD_LARGE:
1714 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1718 return Match_RequiresLAORdDifferRj;
1721 case LoongArch::CSRXCHG:
1722 case LoongArch::GCSRXCHG: {
1724 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1725 return Match_RequiresOpnd2NotR0R1;
1726 return Match_Success;
1728 case LoongArch::BSTRINS_W:
1729 case LoongArch::BSTRINS_D:
1730 case LoongArch::BSTRPICK_W:
1731 case LoongArch::BSTRPICK_D: {
1734 (
Opc == LoongArch::BSTRINS_W ||
Opc == LoongArch::BSTRINS_D)
1738 (
Opc == LoongArch::BSTRINS_W ||
Opc == LoongArch::BSTRINS_D)
1742 return Match_RequiresMsbNotLessThanLsb;
1743 return Match_Success;
1747 return Match_Success;
1751LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1753 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1755 return Match_InvalidOperand;
1757 MCRegister
Reg =
Op.getReg();
1760 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1761 Kind == MCK_FPR64) {
1763 return Match_Success;
1766 if (Kind == MCK_GPRNoR0R1 && (
Reg == LoongArch::R0 ||
Reg == LoongArch::R1))
1767 return Match_RequiresOpnd2NotR0R1;
1769 return Match_InvalidOperand;
1772bool LoongArchAsmParser::generateImmOutOfRangeError(
1774 const Twine &Msg =
"immediate must be an integer in the range") {
1775 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
1776 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1779bool LoongArchAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1782 uint64_t &ErrorInfo,
1783 bool MatchingInlineAsm) {
1785 FeatureBitset MissingFeatures;
1787 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1793 return processInstruction(Inst, IDLoc, Operands, Out);
1794 case Match_MissingFeature: {
1795 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1796 bool FirstFeature =
true;
1797 std::string Msg =
"instruction requires the following:";
1798 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1799 if (MissingFeatures[i]) {
1800 Msg += FirstFeature ?
" " :
", ";
1802 FirstFeature =
false;
1805 return Error(IDLoc, Msg);
1807 case Match_MnemonicFail: {
1808 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1809 std::string Suggestion = LoongArchMnemonicSpellCheck(
1810 ((LoongArchOperand &)*Operands[0]).
getToken(), FBS, 0);
1811 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1813 case Match_InvalidOperand: {
1814 SMLoc ErrorLoc = IDLoc;
1815 if (ErrorInfo != ~0ULL) {
1816 if (ErrorInfo >= Operands.
size())
1817 return Error(ErrorLoc,
"too few operands for instruction");
1819 ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
1820 if (ErrorLoc == SMLoc())
1823 return Error(ErrorLoc,
"invalid operand for instruction");
1830 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1831 SMLoc ErrorLoc = IDLoc;
1832 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1833 return Error(ErrorLoc,
"too few operands for instruction");
1839 case Match_RequiresMsbNotLessThanLsb: {
1840 SMLoc ErrorStart = Operands[3]->getStartLoc();
1841 return Error(ErrorStart,
"msb is less than lsb",
1842 SMRange(ErrorStart, Operands[4]->getEndLoc()));
1844 case Match_RequiresOpnd2NotR0R1:
1845 return Error(Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1846 case Match_RequiresAMORdDifferRkRj:
1847 return Error(Operands[1]->getStartLoc(),
1848 "$rd must be different from both $rk and $rj");
1849 case Match_RequiresLAORdDifferRj:
1850 return Error(Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1851 case Match_RequiresLAORdR4:
1852 return Error(Operands[1]->getStartLoc(),
"$rd must be $r4");
1853 case Match_InvalidUImm1:
1854 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1856 case Match_InvalidUImm2:
1857 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1859 case Match_InvalidUImm2plus1:
1860 return generateImmOutOfRangeError(Operands, ErrorInfo, 1,
1862 case Match_InvalidUImm3:
1863 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1865 case Match_InvalidUImm4:
1866 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1868 case Match_InvalidUImm5:
1869 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1871 case Match_InvalidUImm6:
1872 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1874 case Match_InvalidUImm7:
1875 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1877 case Match_InvalidUImm8:
1878 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1880 case Match_InvalidUImm12:
1881 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1883 case Match_InvalidUImm12ori:
1884 return generateImmOutOfRangeError(
1885 Operands, ErrorInfo, 0,
1887 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1888 "integer in the range");
1889 case Match_InvalidUImm14:
1890 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1892 case Match_InvalidUImm15:
1893 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1895 case Match_InvalidSImm5:
1896 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1898 case Match_InvalidSImm8:
1899 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1901 case Match_InvalidSImm8lsl1:
1902 return generateImmOutOfRangeError(
1903 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1904 "immediate must be a multiple of 2 in the range");
1905 case Match_InvalidSImm8lsl2:
1906 return generateImmOutOfRangeError(
1907 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 4,
1908 "immediate must be a multiple of 4 in the range");
1909 case Match_InvalidSImm10:
1910 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1912 case Match_InvalidSImm8lsl3:
1913 return generateImmOutOfRangeError(
1914 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 8,
1915 "immediate must be a multiple of 8 in the range");
1916 case Match_InvalidSImm9lsl3:
1917 return generateImmOutOfRangeError(
1918 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 8,
1919 "immediate must be a multiple of 8 in the range");
1920 case Match_InvalidSImm10lsl2:
1921 return generateImmOutOfRangeError(
1922 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 4,
1923 "immediate must be a multiple of 4 in the range");
1924 case Match_InvalidSImm11lsl1:
1925 return generateImmOutOfRangeError(
1926 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1927 "immediate must be a multiple of 2 in the range");
1928 case Match_InvalidSImm12:
1929 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1931 case Match_InvalidSImm12addlike:
1932 return generateImmOutOfRangeError(
1933 Operands, ErrorInfo, -(1 << 11),
1935 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1937 case Match_InvalidSImm12lu52id:
1938 return generateImmOutOfRangeError(
1939 Operands, ErrorInfo, -(1 << 11),
1941 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1942 "integer in the range");
1943 case Match_InvalidSImm13:
1944 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 12),
1946 case Match_InvalidSImm14lsl2:
1947 return generateImmOutOfRangeError(
1948 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 4,
1949 "immediate must be a multiple of 4 in the range");
1950 case Match_InvalidSImm16:
1951 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1953 case Match_InvalidSImm16lsl2:
1954 return generateImmOutOfRangeError(
1955 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 4,
1956 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1958 case Match_InvalidSImm20:
1959 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 19),
1961 case Match_InvalidSImm20lu12iw:
1962 return generateImmOutOfRangeError(
1963 Operands, ErrorInfo, -(1 << 19),
1965 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1967 case Match_InvalidSImm20lu32id:
1968 return generateImmOutOfRangeError(
1969 Operands, ErrorInfo, -(1 << 19),
1971 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1972 "integer in the range");
1973 case Match_InvalidSImm20pcalau12i:
1974 return generateImmOutOfRangeError(
1975 Operands, ErrorInfo, -(1 << 19),
1977 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1979 case Match_InvalidSImm20pcaddu12i:
1980 return generateImmOutOfRangeError(
1981 Operands, ErrorInfo, -(1 << 19),
1983 "operand must be a symbol with modifier (e.g. %call30 or %pcadd_hi20) "
1984 "or an integer in the range");
1985 case Match_InvalidSImm20pcaddu18i:
1986 return generateImmOutOfRangeError(
1987 Operands, ErrorInfo, -(1 << 19),
1989 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1991 case Match_InvalidSImm20pcaddi:
1992 return generateImmOutOfRangeError(
1993 Operands, ErrorInfo, -(1 << 19),
1995 "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
1997 case Match_InvalidSImm21lsl2:
1998 return generateImmOutOfRangeError(
1999 Operands, ErrorInfo, -(1 << 22), (1 << 22) - 4,
2000 "operand must be a symbol with modifier (e.g. %b21) or an integer "
2002 case Match_InvalidSImm26Operand:
2003 return generateImmOutOfRangeError(
2004 Operands, ErrorInfo, -(1 << 27), (1 << 27) - 4,
2005 "operand must be a bare symbol name or an immediate must be a multiple "
2006 "of 4 in the range");
2007 case Match_InvalidImm32: {
2008 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
2009 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
2011 case Match_InvalidImm64: {
2012 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
2013 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
2015 case Match_InvalidBareSymbol: {
2016 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
2017 return Error(ErrorLoc,
"operand must be a bare symbol name");
2019 case Match_InvalidTPRelAddSymbol: {
2020 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
2021 return Error(ErrorLoc,
"operand must be a symbol with %le_add_r modifier");
2027bool LoongArchAsmParser::parseDirectiveOption() {
2028 MCAsmParser &Parser = getParser();
2030 AsmToken Tok = Parser.
getTok();
2038 if (Option ==
"push") {
2042 getTargetStreamer().emitDirectiveOptionPush();
2047 if (Option ==
"pop") {
2052 getTargetStreamer().emitDirectiveOptionPop();
2053 if (popFeatureBits())
2054 return Error(StartLoc,
".option pop with no .option push");
2059 if (Option ==
"relax") {
2063 getTargetStreamer().emitDirectiveOptionRelax();
2064 setFeatureBits(LoongArch::FeatureRelax,
"relax");
2068 if (Option ==
"norelax") {
2072 getTargetStreamer().emitDirectiveOptionNoRelax();
2073 clearFeatureBits(LoongArch::FeatureRelax,
"relax");
2079 "unknown option, expected 'push', 'pop', 'relax' or 'norelax'");
2084bool LoongArchAsmParser::parseDirectiveDtpRelWord() {
2085 const MCExpr *
Value;
2086 if (getParser().parseExpression(
Value))
2088 getTargetStreamer().emitDTPRel32Value(
Value);
2092bool LoongArchAsmParser::parseDirectiveDtpRelDWord() {
2093 const MCExpr *
Value;
2094 if (getParser().parseExpression(
Value))
2096 getTargetStreamer().emitDTPRel64Value(
Value);
2100ParseStatus LoongArchAsmParser::parseDirective(AsmToken DirectiveID) {
2101 if (DirectiveID.
getString() ==
".option")
2102 return parseDirectiveOption();
2104 if (DirectiveID.
getString() ==
".dtprelword")
2105 return parseDirectiveDtpRelWord();
2107 if (DirectiveID.
getString() ==
".dtpreldword")
2108 return parseDirectiveDtpRelDWord();
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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")
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
static MCRegister convertFPR32ToFPR64(MCRegister Reg)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
#define LLVM_EXTERNAL_VISIBILITY
static bool matchRegisterNameHelper(MCRegister &RegNo, StringRef Name)
static MCRegister convertFPR32ToFPR64(MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchAsmParser()
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
static bool is64Bit(const char *name)
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
constexpr size_t size() const
static const char * getRegisterName(MCRegister Reg)
static const LoongArchMCExpr * create(const MCExpr *Expr, uint16_t S, MCContext &Ctx, bool Hint=false)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) 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
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.
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.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
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, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Target specific streamer interface.
MCStreamer & getStreamer()
uint32_t getSpecifier() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#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)
uint16_t parseSpecifier(StringRef name)
@ CE
Windows NT (Windows on ARM)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheLoongArch64Target()
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Target & getTheLoongArch32Target()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...