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,
963 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_MARK_LA));
965 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_ABS_LO12));
969 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_ABS64_LO20));
971 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_ABS64_HI12));
974 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
977void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc,
986 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
989 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));
990 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_PCALA_LO12));
992 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
996void LoongArchAsmParser::emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc,
1011 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));
1013 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_PCALA_LO12));
1015 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_PCALA64_LO20));
1017 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_PCALA64_HI12));
1018 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1020 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1023void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,
1029 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1031 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1045 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_GOT_HI20));
1047 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1050 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1051 ELF::R_LARCH_GOT64_LO20));
1052 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1053 ELF::R_LARCH_GOT64_HI12));
1055 Insts.push_back(LoongArchAsmParser::Inst(LD));
1056 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1063 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));
1064 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_GOT_PC_LO12));
1066 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1070void LoongArchAsmParser::emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc,
1085 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));
1087 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1089 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1091 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1092 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1094 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1097void LoongArchAsmParser::emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc,
1108 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LE_HI20));
1110 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_LE_LO12));
1112 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1115void LoongArchAsmParser::emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc,
1121 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1123 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1137 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_IE_HI20));
1139 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_IE_LO12));
1142 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1143 ELF::R_LARCH_TLS_IE64_LO20));
1144 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1145 ELF::R_LARCH_TLS_IE64_HI12));
1147 Insts.push_back(LoongArchAsmParser::Inst(LD));
1148 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1155 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1156 ELF::R_LARCH_TLS_IE_PC_HI20));
1157 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_IE_PC_LO12));
1159 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1163void LoongArchAsmParser::emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc,
1177 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1178 ELF::R_LARCH_TLS_IE_PC_HI20));
1180 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_TLS_IE_PC_LO12));
1181 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1182 ELF::R_LARCH_TLS_IE64_PC_LO20));
1183 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1184 ELF::R_LARCH_TLS_IE64_PC_HI12));
1185 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1187 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1190void LoongArchAsmParser::emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc,
1196 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1198 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1210 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LD_HI20));
1212 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1215 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1216 ELF::R_LARCH_GOT64_LO20));
1217 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1218 ELF::R_LARCH_GOT64_HI12));
1220 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1227 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1228 ELF::R_LARCH_TLS_LD_PC_HI20));
1229 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_GOT_PC_LO12));
1231 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1235void LoongArchAsmParser::emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc,
1249 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1250 ELF::R_LARCH_TLS_LD_PC_HI20));
1252 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1254 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1256 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1257 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1259 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1262void LoongArchAsmParser::emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc,
1268 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1270 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1282 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_GD_HI20));
1284 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1287 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1288 ELF::R_LARCH_GOT64_LO20));
1289 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1290 ELF::R_LARCH_GOT64_HI12));
1292 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1299 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1300 ELF::R_LARCH_TLS_GD_PC_HI20));
1301 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_GOT_PC_LO12));
1303 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1307void LoongArchAsmParser::emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc,
1321 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1322 ELF::R_LARCH_TLS_GD_PC_HI20));
1324 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1326 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1328 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1329 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1331 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1334void LoongArchAsmParser::emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc,
1339 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1340 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1343 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1358 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU12I_W,
1359 ELF::R_LARCH_TLS_DESC_HI20));
1361 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_DESC_LO12));
1364 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1365 ELF::R_LARCH_TLS_DESC64_LO20));
1366 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1367 ELF::R_LARCH_TLS_DESC64_HI12));
1370 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
1372 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1374 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1383 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1384 ELF::R_LARCH_TLS_DESC_PC_HI20));
1386 LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_TLS_DESC_PC_LO12));
1387 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
1389 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1391 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1395void LoongArchAsmParser::emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc,
1411 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1412 ELF::R_LARCH_TLS_DESC_PC_HI20));
1413 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADDI_D,
1414 ELF::R_LARCH_TLS_DESC_PC_LO12));
1415 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1416 ELF::R_LARCH_TLS_DESC64_PC_LO20));
1417 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1418 ELF::R_LARCH_TLS_DESC64_PC_HI12));
1419 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1421 LoongArchAsmParser::Inst(LoongArch::LD_D, ELF::R_LARCH_TLS_DESC_LD));
1423 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1425 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1428void LoongArchAsmParser::emitLoadImm(MCInst &Inst, SMLoc IDLoc,
1432 MCRegister SrcReg = LoongArch::R0;
1434 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1439 case LoongArch::LU12I_W:
1441 MCInstBuilder(Inst.Opc).addReg(DestReg).addImm(Inst.Imm), getSTI());
1443 case LoongArch::ADDI_W:
1444 case LoongArch::ORI:
1445 case LoongArch::LU32I_D:
1446 case LoongArch::LU52I_D:
1448 MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1452 case LoongArch::BSTRINS_D:
1457 .addImm(Inst.Imm >> 32)
1458 .addImm(Inst.Imm & 0xFF),
1468void LoongArchAsmParser::emitFuncCall36(MCInst &Inst, SMLoc IDLoc,
1469 MCStreamer &Out,
bool IsTailCall) {
1479 MCRegister ScratchReg =
1484 Sym, ELF::R_LARCH_CALL36,
getContext(),
true);
1487 MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),
1490 MCInstBuilder(LoongArch::JIRL)
1491 .addReg(IsTailCall ? MCRegister(LoongArch::R0) : ScratchReg)
1497bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1504 case LoongArch::PseudoLA_ABS:
1505 case LoongArch::PseudoLA_ABS_LARGE:
1506 emitLoadAddressAbs(Inst, IDLoc, Out);
1508 case LoongArch::PseudoLA_PCREL:
1509 emitLoadAddressPcrel(Inst, IDLoc, Out);
1511 case LoongArch::PseudoLA_PCREL_LARGE:
1512 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1514 case LoongArch::PseudoLA_GOT:
1515 emitLoadAddressGot(Inst, IDLoc, Out);
1517 case LoongArch::PseudoLA_GOT_LARGE:
1518 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1520 case LoongArch::PseudoLA_TLS_LE:
1521 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1523 case LoongArch::PseudoLA_TLS_IE:
1524 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1526 case LoongArch::PseudoLA_TLS_IE_LARGE:
1527 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1529 case LoongArch::PseudoLA_TLS_LD:
1530 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1532 case LoongArch::PseudoLA_TLS_LD_LARGE:
1533 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1535 case LoongArch::PseudoLA_TLS_GD:
1536 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1538 case LoongArch::PseudoLA_TLS_GD_LARGE:
1539 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1541 case LoongArch::PseudoLA_TLS_DESC:
1542 emitLoadAddressTLSDesc(Inst, IDLoc, Out);
1544 case LoongArch::PseudoLA_TLS_DESC_LARGE:
1545 emitLoadAddressTLSDescLarge(Inst, IDLoc, Out);
1547 case LoongArch::PseudoLI_W:
1548 case LoongArch::PseudoLI_D:
1549 emitLoadImm(Inst, IDLoc, Out);
1551 case LoongArch::PseudoCALL36:
1552 emitFuncCall36(Inst, IDLoc, Out,
false);
1554 case LoongArch::PseudoTAIL36:
1555 emitFuncCall36(Inst, IDLoc, Out,
true);
1562unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1564 const MCInstrDesc &MCID = MII.
get(
Opc);
1572 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1573 return Match_RequiresAMORdDifferRkRj;
1576 case LoongArch::PseudoLA_TLS_DESC:
1577 case LoongArch::PseudoLA_TLS_DESC_LARGE: {
1579 if (Rd != LoongArch::R4)
1580 return Match_RequiresLAORdR4;
1583 case LoongArch::PseudoLA_PCREL_LARGE:
1584 case LoongArch::PseudoLA_GOT_LARGE:
1585 case LoongArch::PseudoLA_TLS_IE_LARGE:
1586 case LoongArch::PseudoLA_TLS_LD_LARGE:
1587 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1591 return Match_RequiresLAORdDifferRj;
1594 case LoongArch::CSRXCHG:
1595 case LoongArch::GCSRXCHG: {
1597 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1598 return Match_RequiresOpnd2NotR0R1;
1599 return Match_Success;
1601 case LoongArch::BSTRINS_W:
1602 case LoongArch::BSTRINS_D:
1603 case LoongArch::BSTRPICK_W:
1604 case LoongArch::BSTRPICK_D: {
1607 (
Opc == LoongArch::BSTRINS_W ||
Opc == LoongArch::BSTRINS_D)
1611 (
Opc == LoongArch::BSTRINS_W ||
Opc == LoongArch::BSTRINS_D)
1615 return Match_RequiresMsbNotLessThanLsb;
1616 return Match_Success;
1620 return Match_Success;
1624LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1626 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1628 return Match_InvalidOperand;
1630 MCRegister
Reg =
Op.getReg();
1633 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1634 Kind == MCK_FPR64) {
1636 return Match_Success;
1639 if (Kind == MCK_GPRNoR0R1 && (
Reg == LoongArch::R0 ||
Reg == LoongArch::R1))
1640 return Match_RequiresOpnd2NotR0R1;
1642 return Match_InvalidOperand;
1645bool LoongArchAsmParser::generateImmOutOfRangeError(
1647 const Twine &Msg =
"immediate must be an integer in the range") {
1648 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1649 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1652bool LoongArchAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1655 uint64_t &ErrorInfo,
1656 bool MatchingInlineAsm) {
1658 FeatureBitset MissingFeatures;
1660 auto Result = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
1666 return processInstruction(Inst, IDLoc,
Operands, Out);
1667 case Match_MissingFeature: {
1668 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1669 bool FirstFeature =
true;
1670 std::string Msg =
"instruction requires the following:";
1671 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1672 if (MissingFeatures[i]) {
1673 Msg += FirstFeature ?
" " :
", ";
1675 FirstFeature =
false;
1678 return Error(IDLoc, Msg);
1680 case Match_MnemonicFail: {
1681 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1682 std::string Suggestion = LoongArchMnemonicSpellCheck(
1684 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1686 case Match_InvalidOperand: {
1687 SMLoc ErrorLoc = IDLoc;
1688 if (ErrorInfo != ~0ULL) {
1690 return Error(ErrorLoc,
"too few operands for instruction");
1692 ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1693 if (ErrorLoc == SMLoc())
1696 return Error(ErrorLoc,
"invalid operand for instruction");
1703 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1704 SMLoc ErrorLoc = IDLoc;
1705 if (ErrorInfo != ~0ULL && ErrorInfo >=
Operands.size())
1706 return Error(ErrorLoc,
"too few operands for instruction");
1712 case Match_RequiresMsbNotLessThanLsb: {
1713 SMLoc ErrorStart =
Operands[3]->getStartLoc();
1714 return Error(ErrorStart,
"msb is less than lsb",
1715 SMRange(ErrorStart,
Operands[4]->getEndLoc()));
1717 case Match_RequiresOpnd2NotR0R1:
1718 return Error(
Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1719 case Match_RequiresAMORdDifferRkRj:
1721 "$rd must be different from both $rk and $rj");
1722 case Match_RequiresLAORdDifferRj:
1723 return Error(
Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1724 case Match_RequiresLAORdR4:
1725 return Error(
Operands[1]->getStartLoc(),
"$rd must be $r4");
1726 case Match_InvalidUImm1:
1727 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1729 case Match_InvalidUImm2:
1730 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1732 case Match_InvalidUImm2plus1:
1733 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1,
1735 case Match_InvalidUImm3:
1736 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1738 case Match_InvalidUImm4:
1739 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1741 case Match_InvalidUImm5:
1742 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1744 case Match_InvalidUImm6:
1745 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1747 case Match_InvalidUImm7:
1748 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1750 case Match_InvalidUImm8:
1751 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1753 case Match_InvalidUImm12:
1754 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1756 case Match_InvalidUImm12ori:
1757 return generateImmOutOfRangeError(
1760 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1761 "integer in the range");
1762 case Match_InvalidUImm14:
1763 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1765 case Match_InvalidUImm15:
1766 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0,
1768 case Match_InvalidSImm5:
1769 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 4),
1771 case Match_InvalidSImm8:
1772 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 7),
1774 case Match_InvalidSImm8lsl1:
1775 return generateImmOutOfRangeError(
1776 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1777 "immediate must be a multiple of 2 in the range");
1778 case Match_InvalidSImm8lsl2:
1779 return generateImmOutOfRangeError(
1780 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 4,
1781 "immediate must be a multiple of 4 in the range");
1782 case Match_InvalidSImm10:
1783 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9),
1785 case Match_InvalidSImm8lsl3:
1786 return generateImmOutOfRangeError(
1787 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 8,
1788 "immediate must be a multiple of 8 in the range");
1789 case Match_InvalidSImm9lsl3:
1790 return generateImmOutOfRangeError(
1791 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 8,
1792 "immediate must be a multiple of 8 in the range");
1793 case Match_InvalidSImm10lsl2:
1794 return generateImmOutOfRangeError(
1795 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 4,
1796 "immediate must be a multiple of 4 in the range");
1797 case Match_InvalidSImm11lsl1:
1798 return generateImmOutOfRangeError(
1799 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1800 "immediate must be a multiple of 2 in the range");
1801 case Match_InvalidSImm12:
1802 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11),
1804 case Match_InvalidSImm12addlike:
1805 return generateImmOutOfRangeError(
1808 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1810 case Match_InvalidSImm12lu52id:
1811 return generateImmOutOfRangeError(
1814 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1815 "integer in the range");
1816 case Match_InvalidSImm13:
1817 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 12),
1819 case Match_InvalidSImm14lsl2:
1820 return generateImmOutOfRangeError(
1821 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 4,
1822 "immediate must be a multiple of 4 in the range");
1823 case Match_InvalidSImm16:
1824 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 15),
1826 case Match_InvalidSImm16lsl2:
1827 return generateImmOutOfRangeError(
1828 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 4,
1829 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1831 case Match_InvalidSImm20:
1832 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 19),
1834 case Match_InvalidSImm20lu12iw:
1835 return generateImmOutOfRangeError(
1838 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1840 case Match_InvalidSImm20lu32id:
1841 return generateImmOutOfRangeError(
1844 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1845 "integer in the range");
1846 case Match_InvalidSImm20pcalau12i:
1847 return generateImmOutOfRangeError(
1850 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1852 case Match_InvalidSImm20pcaddu18i:
1853 return generateImmOutOfRangeError(
1856 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1858 case Match_InvalidSImm20pcaddi:
1859 return generateImmOutOfRangeError(
1862 "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
1864 case Match_InvalidSImm21lsl2:
1865 return generateImmOutOfRangeError(
1866 Operands, ErrorInfo, -(1 << 22), (1 << 22) - 4,
1867 "operand must be a symbol with modifier (e.g. %b21) or an integer "
1869 case Match_InvalidSImm26Operand:
1870 return generateImmOutOfRangeError(
1871 Operands, ErrorInfo, -(1 << 27), (1 << 27) - 4,
1872 "operand must be a bare symbol name or an immediate must be a multiple "
1873 "of 4 in the range");
1874 case Match_InvalidImm32: {
1875 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1876 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
1878 case Match_InvalidImm64: {
1879 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1880 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
1882 case Match_InvalidBareSymbol: {
1883 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1884 return Error(ErrorLoc,
"operand must be a bare symbol name");
1886 case Match_InvalidTPRelAddSymbol: {
1887 SMLoc ErrorLoc = ((LoongArchOperand &)*
Operands[ErrorInfo]).getStartLoc();
1888 return Error(ErrorLoc,
"operand must be a symbol with %le_add_r modifier");
1894bool LoongArchAsmParser::parseDirectiveOption() {
1895 MCAsmParser &Parser = getParser();
1897 AsmToken Tok = Parser.
getTok();
1905 if (Option ==
"push") {
1909 getTargetStreamer().emitDirectiveOptionPush();
1914 if (Option ==
"pop") {
1919 getTargetStreamer().emitDirectiveOptionPop();
1920 if (popFeatureBits())
1921 return Error(StartLoc,
".option pop with no .option push");
1926 if (Option ==
"relax") {
1930 getTargetStreamer().emitDirectiveOptionRelax();
1931 setFeatureBits(LoongArch::FeatureRelax,
"relax");
1935 if (Option ==
"norelax") {
1939 getTargetStreamer().emitDirectiveOptionNoRelax();
1940 clearFeatureBits(LoongArch::FeatureRelax,
"relax");
1946 "unknown option, expected 'push', 'pop', 'relax' or 'norelax'");
1951ParseStatus LoongArchAsmParser::parseDirective(AsmToken DirectiveID) {
1952 if (DirectiveID.
getString() ==
".option")
1953 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,...