33#define DEBUG_TYPE "loongarch-asm-parser"
39 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
40 bool is64Bit()
const {
return getSTI().hasFeature(LoongArch::Feature64Bit); }
42 assert(getParser().getStreamer().getTargetStreamer() &&
43 "do not have a target streamer");
58 SMLoc &EndLoc)
override;
63 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
66 bool MatchingInlineAsm)
override;
68 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
71 unsigned Kind)
override;
85#define GET_ASSEMBLER_HEADER
86#include "LoongArchGenAsmMatcher.inc"
96 bool parseDirectiveOption();
99 if (!(getSTI().hasFeature(Feature))) {
101 setAvailableFeatures(
106 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
107 if (getSTI().hasFeature(Feature)) {
108 MCSubtargetInfo &STI = copySTI();
109 setAvailableFeatures(
114 void pushFeatureBits() {
115 FeatureBitStack.push_back(getSTI().getFeatureBits());
118 bool popFeatureBits() {
119 if (FeatureBitStack.empty())
122 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
123 copySTI().setFeatureBits(FeatureBits);
124 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
131 void emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
132 const MCExpr *Symbol, SmallVectorImpl<Inst> &Insts,
133 SMLoc IDLoc, MCStreamer &Out,
bool RelaxHint =
false);
136 void emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
139 void emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
141 void emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
144 void emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
146 void emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
149 void emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
152 void emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
154 void emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
157 void emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
159 void emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
162 void emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
164 void emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
167 void emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
169 void emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
172 void emitLoadImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
175 void emitFuncCall36(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
179 enum LoongArchMatchResultTy {
180 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
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,
194 LoongArchAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
195 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
196 : MCTargetAsmParser(
Options, STI, MII) {
203 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
223 SMLoc StartLoc, EndLoc;
231 LoongArchOperand(KindTy K) : MCParsedAsmOperand(), Kind(
K) {}
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; }
237 void setReg(MCRegister PhysReg) {
Reg.RegNum = PhysReg; }
239 return Kind == KindTy::Register &&
240 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(
244 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
247 VK =
LE->getSpecifier();
252 Imm =
CE->getValue();
259 template <
unsigned N,
int P = 0>
bool isUImm()
const {
265 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
270 template <
unsigned N,
unsigned S = 0>
bool isSImm()
const {
276 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
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) &&
298 VK == ELF::R_LARCH_TLS_LE_ADD_R;
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);
330 VK == ELF::R_LARCH_GOT_PC_LO12 || VK == ELF::R_LARCH_TLS_IE_PC_LO12 ||
331 VK == ELF::R_LARCH_TLS_LE_LO12_R ||
332 VK == ELF::R_LARCH_TLS_DESC_PC_LO12 || VK == ELF::R_LARCH_TLS_DESC_LD;
335 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
339 bool isSImm12lu52id()
const {
345 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
348 VK == ELF::R_LARCH_PCALA64_HI12 || VK == ELF::R_LARCH_GOT64_HI12 ||
349 VK == ELF::R_LARCH_GOT64_PC_HI12 || VK == ELF::R_LARCH_TLS_LE64_HI12 ||
350 VK == ELF::R_LARCH_TLS_IE64_HI12 ||
351 VK == ELF::R_LARCH_TLS_IE64_PC_HI12 ||
352 VK == ELF::R_LARCH_TLS_DESC64_HI12 ||
353 VK == ELF::R_LARCH_TLS_DESC64_PC_HI12;
356 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
360 bool isUImm12()
const {
return isUImm<12>(); }
362 bool isUImm12ori()
const {
368 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
371 VK == ELF::R_LARCH_PCALA_LO12 || VK == ELF::R_LARCH_GOT_LO12 ||
372 VK == ELF::R_LARCH_GOT_PC_LO12 || VK == ELF::R_LARCH_TLS_LE_LO12 ||
373 VK == ELF::R_LARCH_TLS_IE_LO12 || VK == ELF::R_LARCH_TLS_IE_PC_LO12 ||
374 VK == ELF::R_LARCH_TLS_DESC_LO12;
377 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
381 bool isSImm13()
const {
return isSImm<13>(); }
382 bool isUImm14()
const {
return isUImm<14>(); }
383 bool isUImm15()
const {
return isUImm<15>(); }
385 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
386 bool isSImm16()
const {
return isSImm<16>(); }
388 bool isSImm16lsl2()
const {
394 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
397 VK == ELF::R_LARCH_PCALA_LO12 || VK == ELF::R_LARCH_TLS_DESC_CALL;
400 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
404 bool isSImm20()
const {
return isSImm<20>(); }
406 bool isSImm20pcalau12i()
const {
412 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
415 VK == ELF::R_LARCH_GOT_PC_HI20 || VK == ELF::R_LARCH_TLS_IE_PC_HI20 ||
416 VK == ELF::R_LARCH_TLS_LD_PC_HI20 ||
417 VK == ELF::R_LARCH_TLS_GD_PC_HI20 ||
418 VK == ELF::R_LARCH_TLS_DESC_PC_HI20;
421 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
425 bool isSImm20lu12iw()
const {
431 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
434 VK == ELF::R_LARCH_GOT_HI20 || VK == ELF::R_LARCH_TLS_GD_HI20 ||
435 VK == ELF::R_LARCH_TLS_LD_HI20 || VK == ELF::R_LARCH_TLS_IE_HI20 ||
436 VK == ELF::R_LARCH_TLS_LE_HI20 || VK == ELF::R_LARCH_TLS_LE_HI20_R ||
437 VK == ELF::R_LARCH_TLS_DESC_HI20;
440 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
444 bool isSImm20lu32id()
const {
450 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
453 VK == ELF::R_LARCH_PCALA64_LO20 || VK == ELF::R_LARCH_GOT64_LO20 ||
454 VK == ELF::R_LARCH_GOT64_PC_LO20 || VK == ELF::R_LARCH_TLS_IE64_LO20 ||
455 VK == ELF::R_LARCH_TLS_IE64_PC_LO20 ||
456 VK == ELF::R_LARCH_TLS_LE64_LO20 ||
457 VK == ELF::R_LARCH_TLS_DESC64_PC_LO20 ||
458 VK == ELF::R_LARCH_TLS_DESC64_LO20;
462 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
466 bool isSImm20pcaddu18i()
const {
472 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
478 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
482 bool isSImm20pcaddi()
const {
488 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
490 VK == ELF::R_LARCH_PCREL20_S2 ||
491 VK == ELF::R_LARCH_TLS_LD_PCREL20_S2 ||
492 VK == ELF::R_LARCH_TLS_GD_PCREL20_S2 ||
493 VK == ELF::R_LARCH_TLS_DESC_PCREL20_S2;
496 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
500 bool isSImm21lsl2()
const {
506 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
510 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
514 bool isSImm26Operand()
const {
520 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
524 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
528 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
529 bool isImm64()
const {
534 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
539 SMLoc getStartLoc()
const override {
return StartLoc; }
541 SMLoc getEndLoc()
const override {
return EndLoc; }
543 MCRegister
getReg()
const override {
544 assert(Kind == KindTy::Register &&
"Invalid type access!");
548 const MCExpr *
getImm()
const {
549 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
554 assert(Kind == KindTy::Token &&
"Invalid type access!");
558 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
567 case KindTy::Immediate:
570 case KindTy::Register:
579 static std::unique_ptr<LoongArchOperand> createToken(StringRef Str, SMLoc S) {
580 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
587 static std::unique_ptr<LoongArchOperand> createReg(MCRegister
Reg, SMLoc S,
589 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
590 Op->Reg.RegNum =
Reg;
596 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val, SMLoc S,
598 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
605 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
613 void addRegOperands(MCInst &Inst,
unsigned N)
const {
614 assert(
N == 1 &&
"Invalid number of operands!");
617 void addImmOperands(MCInst &Inst,
unsigned N)
const {
618 assert(
N == 1 &&
"Invalid number of operands!");
624#define GET_REGISTER_MATCHER
625#define GET_SUBTARGET_FEATURE_NAME
626#define GET_MATCHER_IMPLEMENTATION
627#define GET_MNEMONIC_SPELL_CHECKER
628#include "LoongArchGenAsmMatcher.inc"
631 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
632 return Reg - LoongArch::F0 + LoongArch::F0_64;
642 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
644 static_assert(LoongArch::F0 < LoongArch::F0_64,
645 "FPR matching must be updated");
646 if (RegNo == LoongArch::NoRegister)
649 return RegNo == LoongArch::NoRegister;
654 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
655 return Error(getLoc(),
"invalid register name");
657 if (!LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].
contains(
Reg) &&
658 !LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg))
659 return Error(getLoc(),
"invalid register name");
664ParseStatus LoongArchAsmParser::tryParseRegister(MCRegister &
Reg,
667 const AsmToken &Tok = getParser().getTok();
683bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
688 Kind = RE->getSpecifier();
689 Expr = RE->getSubExpr();
704 StringRef
Name = getLexer().getTok().getIdentifier();
707 if (RegNo == LoongArch::NoRegister)
713 Operands.push_back(LoongArchOperand::createReg(RegNo, S,
E));
723 switch (getLexer().getKind()) {
735 if (getParser().parseExpression(Res,
E))
739 return parseOperandWithModifier(
Operands);
742 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
752 return Error(getLoc(),
"expected '%' for operand modifier");
757 return Error(getLoc(),
"expected valid identifier for operand modifier");
758 StringRef
Identifier = getParser().getTok().getIdentifier();
761 return Error(getLoc(),
"invalid relocation specifier");
765 return Error(getLoc(),
"expected '('");
768 const MCExpr *SubExpr;
769 if (getParser().parseParenExpression(SubExpr,
E))
773 Operands.push_back(LoongArchOperand::createImm(ModExpr, S,
E));
782 return parseOperandWithModifier(
Operands);
788 if (getParser().parseIdentifier(Identifier))
795 Operands.push_back(LoongArchOperand::createImm(Res, S,
E));
801 if (!parseRegister(
Operands).isSuccess())
808 SMLoc ImmStart = getLoc();
809 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
812 return Error(ImmStart,
"optional integer offset must be 0");
820 StringRef Mnemonic) {
824 MatchOperandParserImpl(
Operands, Mnemonic,
true);
830 if (parseRegister(
Operands).isSuccess() ||
835 return Error(getLoc(),
"unknown operand");
838bool LoongArchAsmParser::parseInstruction(ParseInstructionInfo &
Info,
839 StringRef Name, SMLoc NameLoc,
842 Operands.push_back(LoongArchOperand::createToken(Name, NameLoc));
861 SMLoc Loc = getLexer().getLoc();
862 getParser().eatToEndOfStatement();
863 return Error(Loc,
"unexpected token");
866void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
867 const MCExpr *Symbol,
868 SmallVectorImpl<Inst> &Insts,
869 SMLoc IDLoc, MCStreamer &Out,
872 for (LoongArchAsmParser::Inst &Inst : Insts) {
873 unsigned Opc = Inst.Opc;
875 const LoongArchMCExpr *
LE =
880 case LoongArch::PCALAU12I:
881 case LoongArch::LU12I_W:
886 case LoongArch::ADDI_W:
887 case LoongArch::LD_W:
888 case LoongArch::LD_D: {
891 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addImm(0),
894 }
else if (VK == ELF::R_LARCH_TLS_DESC_LD) {
896 .addReg(LoongArch::R1)
903 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
907 case LoongArch::LU32I_D:
909 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
910 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
914 case LoongArch::LU52I_D:
916 MCInstBuilder(
Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
919 case LoongArch::ADDI_D:
923 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
927 case LoongArch::ADD_D:
928 case LoongArch::LDX_D:
930 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
933 case LoongArch::JIRL:
935 .addReg(LoongArch::R1)
936 .addReg(LoongArch::R1)
944void LoongArchAsmParser::emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc,
961 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_ABS_HI20));
963 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_ABS_LO12));
967 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_ABS64_LO20));
969 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_ABS64_HI12));
972 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
975void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc,
984 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
987 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));
988 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_PCALA_LO12));
990 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
994void LoongArchAsmParser::emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc,
1009 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));
1011 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_PCALA_LO12));
1013 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_PCALA64_LO20));
1015 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_PCALA64_HI12));
1016 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1018 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1021void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,
1027 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1029 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1043 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_GOT_HI20));
1045 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1048 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1049 ELF::R_LARCH_GOT64_LO20));
1050 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1051 ELF::R_LARCH_GOT64_HI12));
1053 Insts.push_back(LoongArchAsmParser::Inst(LD));
1054 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1061 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));
1062 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_GOT_PC_LO12));
1064 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1068void LoongArchAsmParser::emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc,
1083 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));
1085 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1087 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1089 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1090 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1092 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1095void LoongArchAsmParser::emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc,
1106 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LE_HI20));
1108 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_LE_LO12));
1110 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1113void LoongArchAsmParser::emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc,
1119 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1121 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1135 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_IE_HI20));
1137 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_IE_LO12));
1140 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1141 ELF::R_LARCH_TLS_IE64_LO20));
1142 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1143 ELF::R_LARCH_TLS_IE64_HI12));
1145 Insts.push_back(LoongArchAsmParser::Inst(LD));
1146 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1153 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1154 ELF::R_LARCH_TLS_IE_PC_HI20));
1155 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_IE_PC_LO12));
1157 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1161void LoongArchAsmParser::emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc,
1175 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1176 ELF::R_LARCH_TLS_IE_PC_HI20));
1178 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_TLS_IE_PC_LO12));
1179 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1180 ELF::R_LARCH_TLS_IE64_PC_LO20));
1181 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1182 ELF::R_LARCH_TLS_IE64_PC_HI12));
1183 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1185 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1188void LoongArchAsmParser::emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc,
1194 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1196 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1208 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LD_HI20));
1210 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1213 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1214 ELF::R_LARCH_GOT64_LO20));
1215 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1216 ELF::R_LARCH_GOT64_HI12));
1218 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1225 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1226 ELF::R_LARCH_TLS_LD_PC_HI20));
1227 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_GOT_PC_LO12));
1229 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1233void LoongArchAsmParser::emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc,
1247 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1248 ELF::R_LARCH_TLS_LD_PC_HI20));
1250 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1252 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1254 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1255 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1257 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1260void LoongArchAsmParser::emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc,
1266 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1268 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1280 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_GD_HI20));
1282 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1285 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1286 ELF::R_LARCH_GOT64_LO20));
1287 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1288 ELF::R_LARCH_GOT64_HI12));
1290 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1297 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1298 ELF::R_LARCH_TLS_GD_PC_HI20));
1299 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_GOT_PC_LO12));
1301 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1305void LoongArchAsmParser::emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc,
1319 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1320 ELF::R_LARCH_TLS_GD_PC_HI20));
1322 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1324 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1326 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1327 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1329 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1332void LoongArchAsmParser::emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc,
1337 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1338 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1341 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1356 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU12I_W,
1357 ELF::R_LARCH_TLS_DESC_HI20));
1359 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_DESC_LO12));
1362 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1363 ELF::R_LARCH_TLS_DESC64_LO20));
1364 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1365 ELF::R_LARCH_TLS_DESC64_HI12));
1368 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
1370 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1372 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1381 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1382 ELF::R_LARCH_TLS_DESC_PC_HI20));
1384 LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_TLS_DESC_PC_LO12));
1385 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
1387 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1389 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1393void LoongArchAsmParser::emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc,
1409 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1410 ELF::R_LARCH_TLS_DESC_PC_HI20));
1411 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADDI_D,
1412 ELF::R_LARCH_TLS_DESC_PC_LO12));
1413 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1414 ELF::R_LARCH_TLS_DESC64_PC_LO20));
1415 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1416 ELF::R_LARCH_TLS_DESC64_PC_HI12));
1417 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1419 LoongArchAsmParser::Inst(LoongArch::LD_D, ELF::R_LARCH_TLS_DESC_LD));
1421 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1423 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1426void LoongArchAsmParser::emitLoadImm(MCInst &Inst, SMLoc IDLoc,
1430 MCRegister SrcReg = LoongArch::R0;
1432 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1437 case LoongArch::LU12I_W:
1439 MCInstBuilder(Inst.Opc).addReg(DestReg).addImm(Inst.Imm), getSTI());
1441 case LoongArch::ADDI_W:
1442 case LoongArch::ORI:
1443 case LoongArch::LU32I_D:
1444 case LoongArch::LU52I_D:
1446 MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1450 case LoongArch::BSTRINS_D:
1455 .addImm(Inst.Imm >> 32)
1456 .addImm(Inst.Imm & 0xFF),
1466void LoongArchAsmParser::emitFuncCall36(MCInst &Inst, SMLoc IDLoc,
1467 MCStreamer &Out,
bool IsTailCall) {
1477 MCRegister ScratchReg =
1482 Sym, ELF::R_LARCH_CALL36,
getContext(),
true);
1485 MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),
1488 MCInstBuilder(LoongArch::JIRL)
1489 .addReg(IsTailCall ? MCRegister(LoongArch::R0) : ScratchReg)
1495bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1502 case LoongArch::PseudoLA_ABS:
1503 case LoongArch::PseudoLA_ABS_LARGE:
1504 emitLoadAddressAbs(Inst, IDLoc, Out);
1506 case LoongArch::PseudoLA_PCREL:
1507 emitLoadAddressPcrel(Inst, IDLoc, Out);
1509 case LoongArch::PseudoLA_PCREL_LARGE:
1510 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1512 case LoongArch::PseudoLA_GOT:
1513 emitLoadAddressGot(Inst, IDLoc, Out);
1515 case LoongArch::PseudoLA_GOT_LARGE:
1516 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1518 case LoongArch::PseudoLA_TLS_LE:
1519 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1521 case LoongArch::PseudoLA_TLS_IE:
1522 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1524 case LoongArch::PseudoLA_TLS_IE_LARGE:
1525 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1527 case LoongArch::PseudoLA_TLS_LD:
1528 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1530 case LoongArch::PseudoLA_TLS_LD_LARGE:
1531 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1533 case LoongArch::PseudoLA_TLS_GD:
1534 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1536 case LoongArch::PseudoLA_TLS_GD_LARGE:
1537 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1539 case LoongArch::PseudoLA_TLS_DESC:
1540 emitLoadAddressTLSDesc(Inst, IDLoc, Out);
1542 case LoongArch::PseudoLA_TLS_DESC_LARGE:
1543 emitLoadAddressTLSDescLarge(Inst, IDLoc, Out);
1545 case LoongArch::PseudoLI_W:
1546 case LoongArch::PseudoLI_D:
1547 emitLoadImm(Inst, IDLoc, Out);
1549 case LoongArch::PseudoCALL36:
1550 emitFuncCall36(Inst, IDLoc, Out,
false);
1552 case LoongArch::PseudoTAIL36:
1553 emitFuncCall36(Inst, IDLoc, Out,
true);
1560unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1562 const MCInstrDesc &MCID = MII.
get(
Opc);
1570 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1571 return Match_RequiresAMORdDifferRkRj;
1574 case LoongArch::PseudoLA_TLS_DESC:
1575 case LoongArch::PseudoLA_TLS_DESC_LARGE: {
1577 if (Rd != LoongArch::R4)
1578 return Match_RequiresLAORdR4;
1581 case LoongArch::PseudoLA_PCREL_LARGE:
1582 case LoongArch::PseudoLA_GOT_LARGE:
1583 case LoongArch::PseudoLA_TLS_IE_LARGE:
1584 case LoongArch::PseudoLA_TLS_LD_LARGE:
1585 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1589 return Match_RequiresLAORdDifferRj;
1592 case LoongArch::CSRXCHG:
1593 case LoongArch::GCSRXCHG: {
1595 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1596 return Match_RequiresOpnd2NotR0R1;
1597 return Match_Success;
1599 case LoongArch::BSTRINS_W:
1600 case LoongArch::BSTRINS_D:
1601 case LoongArch::BSTRPICK_W:
1602 case LoongArch::BSTRPICK_D: {
1605 (
Opc == LoongArch::BSTRINS_W ||
Opc == LoongArch::BSTRINS_D)
1609 (
Opc == LoongArch::BSTRINS_W ||
Opc == LoongArch::BSTRINS_D)
1613 return Match_RequiresMsbNotLessThanLsb;
1614 return Match_Success;
1618 return Match_Success;
1622LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1624 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1626 return Match_InvalidOperand;
1628 MCRegister
Reg =
Op.getReg();
1631 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1632 Kind == MCK_FPR64) {
1634 return Match_Success;
1637 if (Kind == MCK_GPRNoR0R1 && (
Reg == LoongArch::R0 ||
Reg == LoongArch::R1))
1638 return Match_RequiresOpnd2NotR0R1;
1640 return Match_InvalidOperand;
1643bool LoongArchAsmParser::generateImmOutOfRangeError(
1645 const Twine &Msg =
"immediate must be an integer in the range") {
1646 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1647 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1650bool LoongArchAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1653 uint64_t &ErrorInfo,
1654 bool MatchingInlineAsm) {
1656 FeatureBitset MissingFeatures;
1658 auto Result = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
1664 return processInstruction(Inst, IDLoc,
Operands, Out);
1665 case Match_MissingFeature: {
1666 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1667 bool FirstFeature =
true;
1668 std::string Msg =
"instruction requires the following:";
1669 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1670 if (MissingFeatures[i]) {
1671 Msg += FirstFeature ?
" " :
", ";
1673 FirstFeature =
false;
1676 return Error(IDLoc, Msg);
1678 case Match_MnemonicFail: {
1679 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1680 std::string Suggestion = LoongArchMnemonicSpellCheck(
1682 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1684 case Match_InvalidOperand: {
1685 SMLoc ErrorLoc = IDLoc;
1686 if (ErrorInfo != ~0ULL) {
1688 return Error(ErrorLoc,
"too few operands for instruction");
1690 ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1691 if (ErrorLoc == SMLoc())
1694 return Error(ErrorLoc,
"invalid operand for instruction");
1701 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1702 SMLoc ErrorLoc = IDLoc;
1703 if (ErrorInfo != ~0ULL && ErrorInfo >=
Operands.size())
1704 return Error(ErrorLoc,
"too few operands for instruction");
1710 case Match_RequiresMsbNotLessThanLsb: {
1711 SMLoc ErrorStart =
Operands[3]->getStartLoc();
1712 return Error(ErrorStart,
"msb is less than lsb",
1713 SMRange(ErrorStart,
Operands[4]->getEndLoc()));
1715 case Match_RequiresOpnd2NotR0R1:
1716 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1717 case Match_RequiresAMORdDifferRkRj:
1719 "$rd must be different from both $rk and $rj");
1720 case Match_RequiresLAORdDifferRj:
1721 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1722 case Match_RequiresLAORdR4:
1723 return Error(
Operands[1]->getStartLoc(),
"$rd must be $r4");
1724 case Match_InvalidUImm1:
1725 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1727 case Match_InvalidUImm2:
1728 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1730 case Match_InvalidUImm2plus1:
1731 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1,
1733 case Match_InvalidUImm3:
1734 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1736 case Match_InvalidUImm4:
1737 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1739 case Match_InvalidUImm5:
1740 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1742 case Match_InvalidUImm6:
1743 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1745 case Match_InvalidUImm7:
1746 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1748 case Match_InvalidUImm8:
1749 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1751 case Match_InvalidUImm12:
1752 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1754 case Match_InvalidUImm12ori:
1755 return generateImmOutOfRangeError(
1758 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1759 "integer in the range");
1760 case Match_InvalidUImm14:
1761 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1763 case Match_InvalidUImm15:
1764 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1766 case Match_InvalidSImm5:
1767 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 4),
1769 case Match_InvalidSImm8:
1770 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 7),
1772 case Match_InvalidSImm8lsl1:
1773 return generateImmOutOfRangeError(
1774 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1775 "immediate must be a multiple of 2 in the range");
1776 case Match_InvalidSImm8lsl2:
1777 return generateImmOutOfRangeError(
1778 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 4,
1779 "immediate must be a multiple of 4 in the range");
1780 case Match_InvalidSImm10:
1781 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9),
1783 case Match_InvalidSImm8lsl3:
1784 return generateImmOutOfRangeError(
1785 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 8,
1786 "immediate must be a multiple of 8 in the range");
1787 case Match_InvalidSImm9lsl3:
1788 return generateImmOutOfRangeError(
1789 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 8,
1790 "immediate must be a multiple of 8 in the range");
1791 case Match_InvalidSImm10lsl2:
1792 return generateImmOutOfRangeError(
1793 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 4,
1794 "immediate must be a multiple of 4 in the range");
1795 case Match_InvalidSImm11lsl1:
1796 return generateImmOutOfRangeError(
1797 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1798 "immediate must be a multiple of 2 in the range");
1799 case Match_InvalidSImm12:
1800 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11),
1802 case Match_InvalidSImm12addlike:
1803 return generateImmOutOfRangeError(
1806 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1808 case Match_InvalidSImm12lu52id:
1809 return generateImmOutOfRangeError(
1812 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1813 "integer in the range");
1814 case Match_InvalidSImm13:
1815 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 12),
1817 case Match_InvalidSImm14lsl2:
1818 return generateImmOutOfRangeError(
1819 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 4,
1820 "immediate must be a multiple of 4 in the range");
1821 case Match_InvalidSImm16:
1822 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 15),
1824 case Match_InvalidSImm16lsl2:
1825 return generateImmOutOfRangeError(
1826 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 4,
1827 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1829 case Match_InvalidSImm20:
1830 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 19),
1832 case Match_InvalidSImm20lu12iw:
1833 return generateImmOutOfRangeError(
1836 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1838 case Match_InvalidSImm20lu32id:
1839 return generateImmOutOfRangeError(
1842 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1843 "integer in the range");
1844 case Match_InvalidSImm20pcalau12i:
1845 return generateImmOutOfRangeError(
1848 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1850 case Match_InvalidSImm20pcaddu18i:
1851 return generateImmOutOfRangeError(
1854 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1856 case Match_InvalidSImm20pcaddi:
1857 return generateImmOutOfRangeError(
1860 "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
1862 case Match_InvalidSImm21lsl2:
1863 return generateImmOutOfRangeError(
1864 Operands, ErrorInfo, -(1 << 22), (1 << 22) - 4,
1865 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1867 case Match_InvalidSImm26Operand:
1868 return generateImmOutOfRangeError(
1869 Operands, ErrorInfo, -(1 << 27), (1 << 27) - 4,
1870 "operand must be a bare symbol name or an immediate must be a multiple "
1871 "of 4 in the range");
1872 case Match_InvalidImm32: {
1873 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1874 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1876 case Match_InvalidImm64: {
1877 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1878 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
1880 case Match_InvalidBareSymbol: {
1881 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1882 return Error(ErrorLoc,
"operand must be a bare symbol name");
1884 case Match_InvalidTPRelAddSymbol: {
1885 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1886 return Error(ErrorLoc,
"operand must be a symbol with %le_add_r modifier");
1892bool LoongArchAsmParser::parseDirectiveOption() {
1893 MCAsmParser &Parser = getParser();
1895 AsmToken Tok = Parser.
getTok();
1903 if (Option ==
"push") {
1907 getTargetStreamer().emitDirectiveOptionPush();
1912 if (Option ==
"pop") {
1917 getTargetStreamer().emitDirectiveOptionPop();
1918 if (popFeatureBits())
1919 return Error(StartLoc,
".option pop with no .option push");
1924 if (Option ==
"relax") {
1928 getTargetStreamer().emitDirectiveOptionRelax();
1929 setFeatureBits(LoongArch::FeatureRelax,
"relax");
1933 if (Option ==
"norelax") {
1937 getTargetStreamer().emitDirectiveOptionNoRelax();
1938 clearFeatureBits(LoongArch::FeatureRelax,
"relax");
1944 "unknown option, expected 'push', 'pop', 'relax' or 'norelax'");
1949ParseStatus LoongArchAsmParser::parseDirective(AsmToken DirectiveID) {
1950 if (DirectiveID.
getString() ==
".option")
1951 return parseDirectiveOption();
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")
Analysis containing CSE Info
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
static MCRegister convertFPR32ToFPR64(MCRegister Reg)
#define LLVM_EXTERNAL_VISIBILITY
static bool matchRegisterNameHelper(MCRegister &RegNo, StringRef Name)
static MCRegister convertFPR32ToFPR64(MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchAsmParser()
mir Rename Register Operands
Promote Memory to Register
static unsigned 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")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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 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.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
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, 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.
StringRef - 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()
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,...