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();
100 if (!(getSTI().hasFeature(Feature))) {
102 setAvailableFeatures(
107 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
108 if (getSTI().hasFeature(Feature)) {
109 MCSubtargetInfo &STI = copySTI();
110 setAvailableFeatures(
115 void pushFeatureBits() {
116 FeatureBitStack.push_back(getSTI().getFeatureBits());
119 bool popFeatureBits() {
120 if (FeatureBitStack.empty())
123 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
124 copySTI().setFeatureBits(FeatureBits);
125 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
132 void emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
133 const MCExpr *Symbol, SmallVectorImpl<Inst> &Insts,
134 SMLoc IDLoc, MCStreamer &Out,
bool RelaxHint =
false);
137 void emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
140 void emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
142 void emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
145 void emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
147 void emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
150 void emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
153 void emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
155 void emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
158 void emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
160 void emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
163 void emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
165 void emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
168 void emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
170 void emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
173 void emitLoadImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
176 void emitFuncCall(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
bool IsTailCall,
180 enum LoongArchMatchResultTy {
181 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
182 Match_RequiresMsbNotLessThanLsb,
183 Match_RequiresOpnd2NotR0R1,
184 Match_RequiresAMORdDifferRkRj,
185 Match_RequiresLAORdDifferRj,
186 Match_RequiresLAORdR4,
187#define GET_OPERAND_DIAGNOSTIC_TYPES
188#include "LoongArchGenAsmMatcher.inc"
189#undef GET_OPERAND_DIAGNOSTIC_TYPES
192 static bool classifySymbolRef(
const MCExpr *Expr,
195 LoongArchAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
196 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
197 : MCTargetAsmParser(
Options, STI, MII) {
204 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
224 SMLoc StartLoc, EndLoc;
232 LoongArchOperand(KindTy K) : MCParsedAsmOperand(), Kind(
K) {}
234 bool isToken()
const override {
return Kind == KindTy::Token; }
235 bool isReg()
const override {
return Kind == KindTy::Register; }
236 bool isImm()
const override {
return Kind == KindTy::Immediate; }
237 bool isMem()
const override {
return false; }
238 void setReg(MCRegister PhysReg) {
Reg.RegNum = PhysReg; }
240 return Kind == KindTy::Register &&
241 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(
245 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
248 VK =
LE->getSpecifier();
253 Imm =
CE->getValue();
260 template <
unsigned N,
int P = 0>
bool isUImm()
const {
266 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
271 template <
unsigned N,
unsigned S = 0>
bool isSImm()
const {
277 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
282 bool isBareSymbol()
const {
286 if (!isImm() || evaluateConstantImm(
getImm(), Imm, VK))
288 return LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
292 bool isTPRelAddSymbol()
const {
296 if (!isImm() || evaluateConstantImm(
getImm(), Imm, VK))
298 return LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
299 VK == ELF::R_LARCH_TLS_LE_ADD_R;
302 bool isUImm1()
const {
return isUImm<1>(); }
303 bool isUImm2()
const {
return isUImm<2>(); }
304 bool isUImm2plus1()
const {
return isUImm<2, 1>(); }
305 bool isUImm3()
const {
return isUImm<3>(); }
306 bool isUImm4()
const {
return isUImm<4>(); }
307 bool isSImm5()
const {
return isSImm<5>(); }
308 bool isUImm5()
const {
return isUImm<5>(); }
309 bool isUImm6()
const {
return isUImm<6>(); }
310 bool isUImm7()
const {
return isUImm<7>(); }
311 bool isSImm8()
const {
return isSImm<8>(); }
312 bool isSImm8lsl1()
const {
return isSImm<8, 1>(); }
313 bool isSImm8lsl2()
const {
return isSImm<8, 2>(); }
314 bool isSImm8lsl3()
const {
return isSImm<8, 3>(); }
315 bool isUImm8()
const {
return isUImm<8>(); }
316 bool isSImm9lsl3()
const {
return isSImm<9, 3>(); }
317 bool isSImm10()
const {
return isSImm<10>(); }
318 bool isSImm10lsl2()
const {
return isSImm<10, 2>(); }
319 bool isSImm11lsl1()
const {
return isSImm<11, 1>(); }
320 bool isSImm12()
const {
return isSImm<12>(); }
322 bool isSImm12addlike()
const {
328 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
331 VK == ELF::R_LARCH_GOT_PC_LO12 || VK == ELF::R_LARCH_TLS_IE_PC_LO12 ||
332 VK == ELF::R_LARCH_TLS_LE_LO12_R || VK == ELF::R_LARCH_TLS_DESC_LD ||
333 VK == ELF::R_LARCH_TLS_DESC_PC_LO12 || VK == ELF::R_LARCH_PCADD_LO12 ||
334 VK == ELF::R_LARCH_GOT_PCADD_LO12 ||
335 VK == ELF::R_LARCH_TLS_IE_PCADD_LO12 ||
336 VK == ELF::R_LARCH_TLS_LD_PCADD_LO12 ||
337 VK == ELF::R_LARCH_TLS_GD_PCADD_LO12 ||
338 VK == ELF::R_LARCH_TLS_DESC_PCADD_LO12;
341 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
345 bool isSImm12lu52id()
const {
351 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
354 VK == ELF::R_LARCH_PCALA64_HI12 || VK == ELF::R_LARCH_GOT64_HI12 ||
355 VK == ELF::R_LARCH_GOT64_PC_HI12 || VK == ELF::R_LARCH_TLS_LE64_HI12 ||
356 VK == ELF::R_LARCH_TLS_IE64_HI12 ||
357 VK == ELF::R_LARCH_TLS_IE64_PC_HI12 ||
358 VK == ELF::R_LARCH_TLS_DESC64_HI12 ||
359 VK == ELF::R_LARCH_TLS_DESC64_PC_HI12;
362 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
366 bool isUImm12()
const {
return isUImm<12>(); }
368 bool isUImm12ori()
const {
374 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
377 VK == ELF::R_LARCH_PCALA_LO12 || VK == ELF::R_LARCH_GOT_LO12 ||
378 VK == ELF::R_LARCH_GOT_PC_LO12 || VK == ELF::R_LARCH_TLS_LE_LO12 ||
379 VK == ELF::R_LARCH_TLS_IE_LO12 || VK == ELF::R_LARCH_TLS_IE_PC_LO12 ||
380 VK == ELF::R_LARCH_TLS_DESC_LO12;
383 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
387 bool isSImm13()
const {
return isSImm<13>(); }
388 bool isUImm14()
const {
return isUImm<14>(); }
389 bool isUImm15()
const {
return isUImm<15>(); }
391 bool isSImm14lsl2()
const {
return isSImm<14, 2>(); }
392 bool isSImm16()
const {
return isSImm<16>(); }
394 bool isSImm16lsl2()
const {
400 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
403 VK == ELF::R_LARCH_PCALA_LO12 || VK == ELF::R_LARCH_TLS_DESC_CALL;
406 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
410 bool isSImm20()
const {
return isSImm<20>(); }
412 bool isSImm20pcalau12i()
const {
418 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
421 VK == ELF::R_LARCH_GOT_PC_HI20 || VK == ELF::R_LARCH_TLS_IE_PC_HI20 ||
422 VK == ELF::R_LARCH_TLS_LD_PC_HI20 ||
423 VK == ELF::R_LARCH_TLS_GD_PC_HI20 ||
424 VK == ELF::R_LARCH_TLS_DESC_PC_HI20;
427 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
431 bool isSImm20lu12iw()
const {
437 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
440 VK == ELF::R_LARCH_GOT_HI20 || VK == ELF::R_LARCH_TLS_GD_HI20 ||
441 VK == ELF::R_LARCH_TLS_LD_HI20 || VK == ELF::R_LARCH_TLS_IE_HI20 ||
442 VK == ELF::R_LARCH_TLS_LE_HI20 || VK == ELF::R_LARCH_TLS_LE_HI20_R ||
443 VK == ELF::R_LARCH_TLS_DESC_HI20;
446 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
450 bool isSImm20lu32id()
const {
456 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
459 VK == ELF::R_LARCH_PCALA64_LO20 || VK == ELF::R_LARCH_GOT64_LO20 ||
460 VK == ELF::R_LARCH_GOT64_PC_LO20 || VK == ELF::R_LARCH_TLS_IE64_LO20 ||
461 VK == ELF::R_LARCH_TLS_IE64_PC_LO20 ||
462 VK == ELF::R_LARCH_TLS_LE64_LO20 ||
463 VK == ELF::R_LARCH_TLS_DESC64_PC_LO20 ||
464 VK == ELF::R_LARCH_TLS_DESC64_LO20;
468 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
472 bool isSImm20pcaddu12i()
const {
478 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
481 VK == ELF::R_LARCH_PCADD_HI20 || VK == ELF::R_LARCH_GOT_PCADD_HI20 ||
482 VK == ELF::R_LARCH_TLS_IE_PCADD_HI20 ||
483 VK == ELF::R_LARCH_TLS_LD_PCADD_HI20 ||
484 VK == ELF::R_LARCH_TLS_GD_PCADD_HI20 ||
485 VK == ELF::R_LARCH_TLS_DESC_PCADD_HI20;
489 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
493 bool isSImm20pcaddu18i()
const {
499 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
505 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
509 bool isSImm20pcaddi()
const {
515 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
517 VK == ELF::R_LARCH_PCREL20_S2 ||
518 VK == ELF::R_LARCH_TLS_LD_PCREL20_S2 ||
519 VK == ELF::R_LARCH_TLS_GD_PCREL20_S2 ||
520 VK == ELF::R_LARCH_TLS_DESC_PCREL20_S2;
523 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
527 bool isSImm21lsl2()
const {
533 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
537 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
541 bool isSImm26Operand()
const {
547 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
551 : LoongArchAsmParser::classifySymbolRef(
getImm(), VK) &&
555 bool isImm32()
const {
return isSImm<32>() || isUImm<32>(); }
556 bool isImm64()
const {
561 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm, VK);
566 SMLoc getStartLoc()
const override {
return StartLoc; }
568 SMLoc getEndLoc()
const override {
return EndLoc; }
570 MCRegister
getReg()
const override {
571 assert(Kind == KindTy::Register &&
"Invalid type access!");
575 const MCExpr *
getImm()
const {
576 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
581 assert(Kind == KindTy::Token &&
"Invalid type access!");
585 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
594 case KindTy::Immediate:
597 case KindTy::Register:
606 static std::unique_ptr<LoongArchOperand> createToken(StringRef Str, SMLoc S) {
607 auto Op = std::make_unique<LoongArchOperand>(KindTy::Token);
614 static std::unique_ptr<LoongArchOperand> createReg(MCRegister
Reg, SMLoc S,
616 auto Op = std::make_unique<LoongArchOperand>(KindTy::Register);
617 Op->Reg.RegNum =
Reg;
623 static std::unique_ptr<LoongArchOperand> createImm(
const MCExpr *Val, SMLoc S,
625 auto Op = std::make_unique<LoongArchOperand>(KindTy::Immediate);
632 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
640 void addRegOperands(MCInst &Inst,
unsigned N)
const {
641 assert(
N == 1 &&
"Invalid number of operands!");
644 void addImmOperands(MCInst &Inst,
unsigned N)
const {
645 assert(
N == 1 &&
"Invalid number of operands!");
651#define GET_REGISTER_MATCHER
652#define GET_SUBTARGET_FEATURE_NAME
653#define GET_MATCHER_IMPLEMENTATION
654#define GET_MNEMONIC_SPELL_CHECKER
655#include "LoongArchGenAsmMatcher.inc"
658 assert(
Reg >= LoongArch::F0 &&
Reg <= LoongArch::F31 &&
"Invalid register");
659 return Reg - LoongArch::F0 + LoongArch::F0_64;
669 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));
671 static_assert(LoongArch::F0 < LoongArch::F0_64,
672 "FPR matching must be updated");
673 if (RegNo == LoongArch::NoRegister)
676 return RegNo == LoongArch::NoRegister;
681 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
682 return Error(getLoc(),
"invalid register name");
684 if (!LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].
contains(
Reg) &&
685 !LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg))
686 return Error(getLoc(),
"invalid register name");
691ParseStatus LoongArchAsmParser::tryParseRegister(MCRegister &
Reg,
694 const AsmToken &Tok = getParser().getTok();
710bool LoongArchAsmParser::classifySymbolRef(
const MCExpr *Expr,
715 Kind = RE->getSpecifier();
716 Expr = RE->getSubExpr();
725ParseStatus LoongArchAsmParser::parseRegister(
OperandVector &Operands) {
731 StringRef
Name = getLexer().getTok().getIdentifier();
734 if (RegNo == LoongArch::NoRegister)
740 Operands.
push_back(LoongArchOperand::createReg(RegNo, S,
E));
745ParseStatus LoongArchAsmParser::parseImmediate(
OperandVector &Operands) {
750 switch (getLexer().getKind()) {
762 if (getParser().parseExpression(Res,
E))
766 return parseOperandWithModifier(Operands);
769 Operands.
push_back(LoongArchOperand::createImm(Res, S,
E));
774LoongArchAsmParser::parseOperandWithModifier(
OperandVector &Operands) {
779 return Error(getLoc(),
"expected '%' for operand modifier");
784 return Error(getLoc(),
"expected valid identifier for operand modifier");
785 StringRef
Identifier = getParser().getTok().getIdentifier();
788 return Error(getLoc(),
"invalid relocation specifier");
792 return Error(getLoc(),
"expected '('");
795 const MCExpr *SubExpr;
796 if (getParser().parseParenExpression(SubExpr,
E))
800 Operands.
push_back(LoongArchOperand::createImm(ModExpr, S,
E));
804ParseStatus LoongArchAsmParser::parseSImm26Operand(
OperandVector &Operands) {
809 return parseOperandWithModifier(Operands);
815 if (getParser().parseIdentifier(Identifier))
822 Operands.
push_back(LoongArchOperand::createImm(Res, S,
E));
826ParseStatus LoongArchAsmParser::parseAtomicMemOp(
OperandVector &Operands) {
828 if (!parseRegister(Operands).isSuccess())
835 SMLoc ImmStart = getLoc();
836 if (getParser().parseIntToken(ImmVal,
"expected optional integer offset"))
839 return Error(ImmStart,
"optional integer offset must be 0");
846bool LoongArchAsmParser::parseOperand(
OperandVector &Operands,
847 StringRef Mnemonic) {
851 MatchOperandParserImpl(Operands, Mnemonic,
true);
857 if (parseRegister(Operands).isSuccess() ||
862 return Error(getLoc(),
"unknown operand");
865bool LoongArchAsmParser::parseInstruction(ParseInstructionInfo &
Info,
866 StringRef Name, SMLoc NameLoc,
869 Operands.
push_back(LoongArchOperand::createToken(Name, NameLoc));
876 if (parseOperand(Operands, Name))
881 if (parseOperand(Operands, Name))
888 SMLoc Loc = getLexer().getLoc();
889 getParser().eatToEndOfStatement();
890 return Error(Loc,
"unexpected token");
893void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
894 const MCExpr *Symbol,
895 SmallVectorImpl<Inst> &Insts,
896 SMLoc IDLoc, MCStreamer &Out,
900 for (LoongArchAsmParser::Inst &Inst : Insts) {
901 unsigned Opc = Inst.Opc;
903 const LoongArchMCExpr *
LE =
908 case LoongArch::PCADDU12I:
912 case LoongArch::PCALAU12I:
913 case LoongArch::LU12I_W:
918 case LoongArch::ADDI_W:
919 case LoongArch::LD_W:
920 case LoongArch::LD_D: {
923 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addImm(0),
926 }
else if (VK == ELF::R_LARCH_TLS_DESC_LD) {
928 .addReg(LoongArch::R1)
933 }
else if (VK == ELF::R_LARCH_PCADD_LO12 ||
934 VK == ELF::R_LARCH_GOT_PCADD_LO12 ||
935 VK == ELF::R_LARCH_TLS_IE_PCADD_LO12 ||
936 VK == ELF::R_LARCH_TLS_LD_PCADD_LO12 ||
937 VK == ELF::R_LARCH_TLS_GD_PCADD_LO12 ||
938 VK == ELF::R_LARCH_TLS_DESC_PCADD_LO12) {
940 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addExpr(
942 VK, Ctx, RelaxHint)),
947 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
951 case LoongArch::LU32I_D:
953 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
954 .addReg(DestReg == TmpReg ? DestReg : TmpReg)
958 case LoongArch::LU52I_D:
960 MCInstBuilder(
Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),
963 case LoongArch::ADDI_D:
967 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)
971 case LoongArch::ADD_D:
972 case LoongArch::LDX_D:
974 MCInstBuilder(
Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),
977 case LoongArch::JIRL:
979 .addReg(LoongArch::R1)
980 .addReg(LoongArch::R1)
988void LoongArchAsmParser::emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc,
1007 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_MARK_LA));
1009 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_ABS_LO12));
1013 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_ABS64_LO20));
1015 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_ABS64_HI12));
1018 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1021void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc,
1036 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1037 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1039 has32S() ? ELF::R_LARCH_PCALA_HI20 : ELF::R_LARCH_PCADD_HI20;
1041 has32S() ? ELF::R_LARCH_PCALA_LO12 : ELF::R_LARCH_PCADD_LO12;
1043 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1044 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
1046 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1050void LoongArchAsmParser::emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc,
1065 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));
1067 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_PCALA_LO12));
1069 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_PCALA64_LO20));
1071 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_PCALA64_HI12));
1072 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1074 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1077void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,
1083 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1084 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1086 has32S() ? ELF::R_LARCH_GOT_PC_HI20 : ELF::R_LARCH_GOT_PCADD_HI20;
1088 has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_GOT_PCADD_LO12;
1090 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1104 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_GOT_HI20));
1106 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1109 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1110 ELF::R_LARCH_GOT64_LO20));
1111 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1112 ELF::R_LARCH_GOT64_HI12));
1114 Insts.push_back(LoongArchAsmParser::Inst(LD));
1115 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1126 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1127 Insts.push_back(LoongArchAsmParser::Inst(LD, LDRel));
1129 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1133void LoongArchAsmParser::emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc,
1148 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));
1150 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1152 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1154 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1155 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1157 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1160void LoongArchAsmParser::emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc,
1171 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LE_HI20));
1173 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_LE_LO12));
1175 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1178void LoongArchAsmParser::emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc,
1184 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1185 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1187 has32S() ? ELF::R_LARCH_TLS_IE_PC_HI20 : ELF::R_LARCH_TLS_IE_PCADD_HI20;
1189 has32S() ? ELF::R_LARCH_TLS_IE_PC_LO12 : ELF::R_LARCH_TLS_IE_PCADD_LO12;
1191 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1205 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_IE_HI20));
1207 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_IE_LO12));
1210 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1211 ELF::R_LARCH_TLS_IE64_LO20));
1212 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1213 ELF::R_LARCH_TLS_IE64_HI12));
1215 Insts.push_back(LoongArchAsmParser::Inst(LD));
1216 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1228 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1229 Insts.push_back(LoongArchAsmParser::Inst(LD, LDRel));
1231 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1235void LoongArchAsmParser::emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc,
1249 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1250 ELF::R_LARCH_TLS_IE_PC_HI20));
1252 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_TLS_IE_PC_LO12));
1253 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1254 ELF::R_LARCH_TLS_IE64_PC_LO20));
1255 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1256 ELF::R_LARCH_TLS_IE64_PC_HI12));
1257 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));
1259 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1262void LoongArchAsmParser::emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc,
1268 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1269 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1271 has32S() ? ELF::R_LARCH_TLS_LD_PC_HI20 : ELF::R_LARCH_TLS_LD_PCADD_HI20;
1273 has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_TLS_LD_PCADD_LO12;
1275 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1287 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LD_HI20));
1289 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1292 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1293 ELF::R_LARCH_GOT64_LO20));
1294 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1295 ELF::R_LARCH_GOT64_HI12));
1297 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1309 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1310 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
1312 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1316void LoongArchAsmParser::emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc,
1330 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1331 ELF::R_LARCH_TLS_LD_PC_HI20));
1333 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1335 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1337 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1338 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1340 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1343void LoongArchAsmParser::emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc,
1349 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1350 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1352 has32S() ? ELF::R_LARCH_TLS_GD_PC_HI20 : ELF::R_LARCH_TLS_GD_PCADD_HI20;
1354 has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_TLS_GD_PCADD_LO12;
1356 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1368 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_GD_HI20));
1370 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));
1373 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1374 ELF::R_LARCH_GOT64_LO20));
1375 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1376 ELF::R_LARCH_GOT64_HI12));
1378 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1390 Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1391 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
1393 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1397void LoongArchAsmParser::emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc,
1411 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1412 ELF::R_LARCH_TLS_GD_PC_HI20));
1414 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));
1416 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));
1418 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));
1419 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1421 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1424void LoongArchAsmParser::emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc,
1429 unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
1430 unsigned ADDI =
is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1431 unsigned LD =
is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
1432 unsigned PCAIRel = has32S() ? ELF::R_LARCH_TLS_DESC_PC_HI20
1433 : ELF::R_LARCH_TLS_DESC_PCADD_HI20;
1434 unsigned ADDIRel = has32S() ? ELF::R_LARCH_TLS_DESC_PC_LO12
1435 : ELF::R_LARCH_TLS_DESC_PCADD_LO12;
1438 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
1453 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU12I_W,
1454 ELF::R_LARCH_TLS_DESC_HI20));
1456 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_DESC_LO12));
1459 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1460 ELF::R_LARCH_TLS_DESC64_LO20));
1461 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1462 ELF::R_LARCH_TLS_DESC64_HI12));
1465 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
1467 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1469 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
1485 Insts.
push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
1486 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
1487 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
1489 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1491 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
1495void LoongArchAsmParser::emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc,
1511 Insts.
push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
1512 ELF::R_LARCH_TLS_DESC_PC_HI20));
1513 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADDI_D,
1514 ELF::R_LARCH_TLS_DESC_PC_LO12));
1515 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU32I_D,
1516 ELF::R_LARCH_TLS_DESC64_PC_LO20));
1517 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU52I_D,
1518 ELF::R_LARCH_TLS_DESC64_PC_HI12));
1519 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));
1521 LoongArchAsmParser::Inst(LoongArch::LD_D, ELF::R_LARCH_TLS_DESC_LD));
1523 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
1525 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);
1528void LoongArchAsmParser::emitLoadImm(MCInst &Inst, SMLoc IDLoc,
1532 MCRegister SrcReg = LoongArch::R0;
1534 if (Inst.
getOpcode() == LoongArch::PseudoLI_W)
1539 case LoongArch::LU12I_W:
1541 MCInstBuilder(Inst.Opc).addReg(DestReg).addImm(Inst.Imm), getSTI());
1543 case LoongArch::ADDI_W:
1544 case LoongArch::ORI:
1545 case LoongArch::LU32I_D:
1546 case LoongArch::LU52I_D:
1548 MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1552 case LoongArch::BSTRINS_D:
1557 .addImm(Inst.Imm >> 32)
1558 .addImm(Inst.Imm & 0xFF),
1568void LoongArchAsmParser::emitFuncCall(MCInst &Inst, SMLoc IDLoc,
1569 MCStreamer &Out,
bool IsTailCall,
1590 MCRegister ScratchReg =
1592 unsigned PCAI = IsCall36 ? LoongArch::PCADDU18I : LoongArch::PCADDU12I;
1593 unsigned Rel = IsCall36 ? ELF::R_LARCH_CALL36 : ELF::R_LARCH_CALL30;
1596 const LoongArchMCExpr *
LE =
1599 Out.
emitInstruction(MCInstBuilder(PCAI).addReg(ScratchReg).addExpr(LE),
1602 MCInstBuilder(LoongArch::JIRL)
1603 .addReg(IsTailCall ? MCRegister(LoongArch::R0) : ScratchReg)
1609bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1616 case LoongArch::PseudoLA_ABS:
1617 case LoongArch::PseudoLA_ABS_LARGE:
1618 emitLoadAddressAbs(Inst, IDLoc, Out);
1620 case LoongArch::PseudoLA_PCREL:
1621 emitLoadAddressPcrel(Inst, IDLoc, Out);
1623 case LoongArch::PseudoLA_PCREL_LARGE:
1624 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);
1626 case LoongArch::PseudoLA_GOT:
1627 emitLoadAddressGot(Inst, IDLoc, Out);
1629 case LoongArch::PseudoLA_GOT_LARGE:
1630 emitLoadAddressGotLarge(Inst, IDLoc, Out);
1632 case LoongArch::PseudoLA_TLS_LE:
1633 emitLoadAddressTLSLE(Inst, IDLoc, Out);
1635 case LoongArch::PseudoLA_TLS_IE:
1636 emitLoadAddressTLSIE(Inst, IDLoc, Out);
1638 case LoongArch::PseudoLA_TLS_IE_LARGE:
1639 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);
1641 case LoongArch::PseudoLA_TLS_LD:
1642 emitLoadAddressTLSLD(Inst, IDLoc, Out);
1644 case LoongArch::PseudoLA_TLS_LD_LARGE:
1645 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);
1647 case LoongArch::PseudoLA_TLS_GD:
1648 emitLoadAddressTLSGD(Inst, IDLoc, Out);
1650 case LoongArch::PseudoLA_TLS_GD_LARGE:
1651 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);
1653 case LoongArch::PseudoLA_TLS_DESC:
1654 emitLoadAddressTLSDesc(Inst, IDLoc, Out);
1656 case LoongArch::PseudoLA_TLS_DESC_LARGE:
1657 emitLoadAddressTLSDescLarge(Inst, IDLoc, Out);
1659 case LoongArch::PseudoLI_W:
1660 case LoongArch::PseudoLI_D:
1661 emitLoadImm(Inst, IDLoc, Out);
1663 case LoongArch::PseudoCALL:
1664 emitFuncCall(Inst, IDLoc, Out,
false,
1667 case LoongArch::PseudoCALL30:
1668 emitFuncCall(Inst, IDLoc, Out,
false,
false);
1670 case LoongArch::PseudoCALL36:
1671 emitFuncCall(Inst, IDLoc, Out,
false,
true);
1673 case LoongArch::PseudoTAIL:
1674 emitFuncCall(Inst, IDLoc, Out,
true,
is64Bit());
1676 case LoongArch::PseudoTAIL30:
1677 emitFuncCall(Inst, IDLoc, Out,
true,
false);
1679 case LoongArch::PseudoTAIL36:
1680 emitFuncCall(Inst, IDLoc, Out,
true,
true);
1687unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1689 const MCInstrDesc &MCID = MII.
get(
Opc);
1697 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)
1698 return Match_RequiresAMORdDifferRkRj;
1701 case LoongArch::PseudoLA_TLS_DESC:
1702 case LoongArch::PseudoLA_TLS_DESC_LARGE: {
1704 if (Rd != LoongArch::R4)
1705 return Match_RequiresLAORdR4;
1708 case LoongArch::PseudoLA_PCREL_LARGE:
1709 case LoongArch::PseudoLA_GOT_LARGE:
1710 case LoongArch::PseudoLA_TLS_IE_LARGE:
1711 case LoongArch::PseudoLA_TLS_LD_LARGE:
1712 case LoongArch::PseudoLA_TLS_GD_LARGE: {
1716 return Match_RequiresLAORdDifferRj;
1719 case LoongArch::CSRXCHG:
1720 case LoongArch::GCSRXCHG: {
1722 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)
1723 return Match_RequiresOpnd2NotR0R1;
1724 return Match_Success;
1726 case LoongArch::BSTRINS_W:
1727 case LoongArch::BSTRINS_D:
1728 case LoongArch::BSTRPICK_W:
1729 case LoongArch::BSTRPICK_D: {
1732 (
Opc == LoongArch::BSTRINS_W ||
Opc == LoongArch::BSTRINS_D)
1736 (
Opc == LoongArch::BSTRINS_W ||
Opc == LoongArch::BSTRINS_D)
1740 return Match_RequiresMsbNotLessThanLsb;
1741 return Match_Success;
1745 return Match_Success;
1749LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1751 LoongArchOperand &
Op =
static_cast<LoongArchOperand &
>(AsmOp);
1753 return Match_InvalidOperand;
1755 MCRegister
Reg =
Op.getReg();
1758 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].
contains(
Reg) &&
1759 Kind == MCK_FPR64) {
1761 return Match_Success;
1764 if (Kind == MCK_GPRNoR0R1 && (
Reg == LoongArch::R0 ||
Reg == LoongArch::R1))
1765 return Match_RequiresOpnd2NotR0R1;
1767 return Match_InvalidOperand;
1770bool LoongArchAsmParser::generateImmOutOfRangeError(
1772 const Twine &Msg =
"immediate must be an integer in the range") {
1773 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
1774 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1777bool LoongArchAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1780 uint64_t &ErrorInfo,
1781 bool MatchingInlineAsm) {
1783 FeatureBitset MissingFeatures;
1785 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1791 return processInstruction(Inst, IDLoc, Operands, Out);
1792 case Match_MissingFeature: {
1793 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1794 bool FirstFeature =
true;
1795 std::string Msg =
"instruction requires the following:";
1796 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1797 if (MissingFeatures[i]) {
1798 Msg += FirstFeature ?
" " :
", ";
1800 FirstFeature =
false;
1803 return Error(IDLoc, Msg);
1805 case Match_MnemonicFail: {
1806 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1807 std::string Suggestion = LoongArchMnemonicSpellCheck(
1808 ((LoongArchOperand &)*Operands[0]).
getToken(), FBS, 0);
1809 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1811 case Match_InvalidOperand: {
1812 SMLoc ErrorLoc = IDLoc;
1813 if (ErrorInfo != ~0ULL) {
1814 if (ErrorInfo >= Operands.
size())
1815 return Error(ErrorLoc,
"too few operands for instruction");
1817 ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
1818 if (ErrorLoc == SMLoc())
1821 return Error(ErrorLoc,
"invalid operand for instruction");
1828 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1829 SMLoc ErrorLoc = IDLoc;
1830 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1831 return Error(ErrorLoc,
"too few operands for instruction");
1837 case Match_RequiresMsbNotLessThanLsb: {
1838 SMLoc ErrorStart = Operands[3]->getStartLoc();
1839 return Error(ErrorStart,
"msb is less than lsb",
1840 SMRange(ErrorStart, Operands[4]->getEndLoc()));
1842 case Match_RequiresOpnd2NotR0R1:
1843 return Error(Operands[2]->getStartLoc(),
"must not be $r0 or $r1");
1844 case Match_RequiresAMORdDifferRkRj:
1845 return Error(Operands[1]->getStartLoc(),
1846 "$rd must be different from both $rk and $rj");
1847 case Match_RequiresLAORdDifferRj:
1848 return Error(Operands[1]->getStartLoc(),
"$rd must be different from $rj");
1849 case Match_RequiresLAORdR4:
1850 return Error(Operands[1]->getStartLoc(),
"$rd must be $r4");
1851 case Match_InvalidUImm1:
1852 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1854 case Match_InvalidUImm2:
1855 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1857 case Match_InvalidUImm2plus1:
1858 return generateImmOutOfRangeError(Operands, ErrorInfo, 1,
1860 case Match_InvalidUImm3:
1861 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1863 case Match_InvalidUImm4:
1864 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1866 case Match_InvalidUImm5:
1867 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1869 case Match_InvalidUImm6:
1870 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1872 case Match_InvalidUImm7:
1873 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1875 case Match_InvalidUImm8:
1876 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1878 case Match_InvalidUImm12:
1879 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1881 case Match_InvalidUImm12ori:
1882 return generateImmOutOfRangeError(
1883 Operands, ErrorInfo, 0,
1885 "operand must be a symbol with modifier (e.g. %abs_lo12) or an "
1886 "integer in the range");
1887 case Match_InvalidUImm14:
1888 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1890 case Match_InvalidUImm15:
1891 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,
1893 case Match_InvalidSImm5:
1894 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1896 case Match_InvalidSImm8:
1897 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1899 case Match_InvalidSImm8lsl1:
1900 return generateImmOutOfRangeError(
1901 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1902 "immediate must be a multiple of 2 in the range");
1903 case Match_InvalidSImm8lsl2:
1904 return generateImmOutOfRangeError(
1905 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 4,
1906 "immediate must be a multiple of 4 in the range");
1907 case Match_InvalidSImm10:
1908 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1910 case Match_InvalidSImm8lsl3:
1911 return generateImmOutOfRangeError(
1912 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 8,
1913 "immediate must be a multiple of 8 in the range");
1914 case Match_InvalidSImm9lsl3:
1915 return generateImmOutOfRangeError(
1916 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 8,
1917 "immediate must be a multiple of 8 in the range");
1918 case Match_InvalidSImm10lsl2:
1919 return generateImmOutOfRangeError(
1920 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 4,
1921 "immediate must be a multiple of 4 in the range");
1922 case Match_InvalidSImm11lsl1:
1923 return generateImmOutOfRangeError(
1924 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1925 "immediate must be a multiple of 2 in the range");
1926 case Match_InvalidSImm12:
1927 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1929 case Match_InvalidSImm12addlike:
1930 return generateImmOutOfRangeError(
1931 Operands, ErrorInfo, -(1 << 11),
1933 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "
1935 case Match_InvalidSImm12lu52id:
1936 return generateImmOutOfRangeError(
1937 Operands, ErrorInfo, -(1 << 11),
1939 "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
1940 "integer in the range");
1941 case Match_InvalidSImm13:
1942 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 12),
1944 case Match_InvalidSImm14lsl2:
1945 return generateImmOutOfRangeError(
1946 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 4,
1947 "immediate must be a multiple of 4 in the range");
1948 case Match_InvalidSImm16:
1949 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1951 case Match_InvalidSImm16lsl2:
1952 return generateImmOutOfRangeError(
1953 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 4,
1954 "operand must be a symbol with modifier (e.g. %b16) or an integer "
1956 case Match_InvalidSImm20:
1957 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 19),
1959 case Match_InvalidSImm20lu12iw:
1960 return generateImmOutOfRangeError(
1961 Operands, ErrorInfo, -(1 << 19),
1963 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "
1965 case Match_InvalidSImm20lu32id:
1966 return generateImmOutOfRangeError(
1967 Operands, ErrorInfo, -(1 << 19),
1969 "operand must be a symbol with modifier (e.g. %abs64_lo20) or an "
1970 "integer in the range");
1971 case Match_InvalidSImm20pcalau12i:
1972 return generateImmOutOfRangeError(
1973 Operands, ErrorInfo, -(1 << 19),
1975 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
1977 case Match_InvalidSImm20pcaddu12i:
1978 return generateImmOutOfRangeError(
1979 Operands, ErrorInfo, -(1 << 19),
1981 "operand must be a symbol with modifier (e.g. %call30 or %pcadd_hi20) "
1982 "or an integer in the range");
1983 case Match_InvalidSImm20pcaddu18i:
1984 return generateImmOutOfRangeError(
1985 Operands, ErrorInfo, -(1 << 19),
1987 "operand must be a symbol with modifier (e.g. %call36) or an integer "
1989 case Match_InvalidSImm20pcaddi:
1990 return generateImmOutOfRangeError(
1991 Operands, ErrorInfo, -(1 << 19),
1993 "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
1995 case Match_InvalidSImm21lsl2:
1996 return generateImmOutOfRangeError(
1997 Operands, ErrorInfo, -(1 << 22), (1 << 22) - 4,
1998 "operand must be a symbol with modifier (e.g. %b21) or an integer "
2000 case Match_InvalidSImm26Operand:
2001 return generateImmOutOfRangeError(
2002 Operands, ErrorInfo, -(1 << 27), (1 << 27) - 4,
2003 "operand must be a bare symbol name or an immediate must be a multiple "
2004 "of 4 in the range");
2005 case Match_InvalidImm32: {
2006 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
2007 return Error(ErrorLoc,
"operand must be a 32 bit immediate");
2009 case Match_InvalidImm64: {
2010 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
2011 return Error(ErrorLoc,
"operand must be a 64 bit immediate");
2013 case Match_InvalidBareSymbol: {
2014 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
2015 return Error(ErrorLoc,
"operand must be a bare symbol name");
2017 case Match_InvalidTPRelAddSymbol: {
2018 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();
2019 return Error(ErrorLoc,
"operand must be a symbol with %le_add_r modifier");
2025bool LoongArchAsmParser::parseDirectiveOption() {
2026 MCAsmParser &Parser = getParser();
2028 AsmToken Tok = Parser.
getTok();
2036 if (Option ==
"push") {
2040 getTargetStreamer().emitDirectiveOptionPush();
2045 if (Option ==
"pop") {
2050 getTargetStreamer().emitDirectiveOptionPop();
2051 if (popFeatureBits())
2052 return Error(StartLoc,
".option pop with no .option push");
2057 if (Option ==
"relax") {
2061 getTargetStreamer().emitDirectiveOptionRelax();
2062 setFeatureBits(LoongArch::FeatureRelax,
"relax");
2066 if (Option ==
"norelax") {
2070 getTargetStreamer().emitDirectiveOptionNoRelax();
2071 clearFeatureBits(LoongArch::FeatureRelax,
"relax");
2077 "unknown option, expected 'push', 'pop', 'relax' or 'norelax'");
2082ParseStatus LoongArchAsmParser::parseDirective(AsmToken DirectiveID) {
2083 if (DirectiveID.
getString() ==
".option")
2084 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_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")
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 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
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,...