LLVM: lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

30

31using namespace llvm;

32

33#define DEBUG_TYPE "loongarch-asm-parser"

34

35namespace {

38

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");

46 }

47

48 struct Inst {

49 unsigned Opc;

52 };

54

55

58 SMLoc &EndLoc) override;

59

62

63 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

66 bool MatchingInlineAsm) override;

67

68 unsigned checkTargetMatchPredicate(MCInst &Inst) override;

69

71 unsigned Kind) override;

72

74

77 const Twine &Msg);

78

79

80

83

84

85#define GET_ASSEMBLER_HEADER

86#include "LoongArchGenAsmMatcher.inc"

87

93

95

96 bool parseDirectiveOption();

97

99 if (!(getSTI().hasFeature(Feature))) {

101 setAvailableFeatures(

102 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));

103 }

104 }

105

106 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {

107 if (getSTI().hasFeature(Feature)) {

108 MCSubtargetInfo &STI = copySTI();

109 setAvailableFeatures(

110 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));

111 }

112 }

113

114 void pushFeatureBits() {

115 FeatureBitStack.push_back(getSTI().getFeatureBits());

116 }

117

118 bool popFeatureBits() {

119 if (FeatureBitStack.empty())

120 return true;

121

122 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();

123 copySTI().setFeatureBits(FeatureBits);

124 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));

125

126 return false;

127 }

128

129

130

131 void emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,

132 const MCExpr *Symbol, SmallVectorImpl &Insts,

133 SMLoc IDLoc, MCStreamer &Out, bool RelaxHint = false);

134

135

136 void emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

137

138

139 void emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

140

141 void emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

142

143

144 void emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

145

146 void emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

147

148

149 void emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

150

151

152 void emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

153

154 void emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

155

156

157 void emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

158

159 void emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

160

161

162 void emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

163

164 void emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

165

166

167 void emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

168

169 void emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

170

171

172 void emitLoadImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

173

174

175 void emitFuncCall36(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,

176 bool IsTailCall);

177

178public:

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

189 };

190

191 static bool classifySymbolRef(const MCExpr *Expr,

193

194 LoongArchAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,

195 const MCInstrInfo &MII, const MCTargetOptions &Options)

196 : MCTargetAsmParser(Options, STI, MII) {

201

202

203 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));

204 }

205};

206

207

209 enum class KindTy {

210 Token,

212 Immediate,

213 } Kind;

214

215 struct RegOp {

216 MCRegister RegNum;

217 };

218

219 struct ImmOp {

220 const MCExpr *Val;

221 };

222

223 SMLoc StartLoc, EndLoc;

224 union {

225 StringRef Tok;

226 struct RegOp Reg;

227 struct ImmOp Imm;

228 };

229

230public:

231 LoongArchOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}

232

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; }

238 bool isGPR() const {

239 return Kind == KindTy::Register &&

240 LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(

241 Reg.RegNum);

242 }

243

244 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,

247 VK = LE->getSpecifier();

248 return false;

249 }

250

252 Imm = CE->getValue();

253 return true;

254 }

255

256 return false;

257 }

258

259 template <unsigned N, int P = 0> bool isUImm() const {

260 if (!isImm())

261 return false;

262

263 int64_t Imm;

265 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

266 return IsConstantImm && isUInt(Imm - P) &&

268 }

269

270 template <unsigned N, unsigned S = 0> bool isSImm() const {

271 if (!isImm())

272 return false;

273

274 int64_t Imm;

276 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

279 }

280

281 bool isBareSymbol() const {

282 int64_t Imm;

284

285 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))

286 return false;

287 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

289 }

290

291 bool isTPRelAddSymbol() const {

292 int64_t Imm;

294

295 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))

296 return false;

297 return LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

298 VK == ELF::R_LARCH_TLS_LE_ADD_R;

299 }

300

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>(); }

320

321 bool isSImm12addlike() const {

322 if (!isImm())

323 return false;

324

325 int64_t Imm;

327 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

328 bool IsValidKind =

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;

333 return IsConstantImm

335 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

336 IsValidKind;

337 }

338

339 bool isSImm12lu52id() const {

340 if (!isImm())

341 return false;

342

343 int64_t Imm;

345 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

346 bool IsValidKind =

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;

354 return IsConstantImm

356 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

357 IsValidKind;

358 }

359

360 bool isUImm12() const { return isUImm<12>(); }

361

362 bool isUImm12ori() const {

363 if (!isImm())

364 return false;

365

366 int64_t Imm;

368 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

369 bool IsValidKind =

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;

375 return IsConstantImm

377 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

378 IsValidKind;

379 }

380

381 bool isSImm13() const { return isSImm<13>(); }

382 bool isUImm14() const { return isUImm<14>(); }

383 bool isUImm15() const { return isUImm<15>(); }

384

385 bool isSImm14lsl2() const { return isSImm<14, 2>(); }

386 bool isSImm16() const { return isSImm<16>(); }

387

388 bool isSImm16lsl2() const {

389 if (!isImm())

390 return false;

391

392 int64_t Imm;

394 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

395 bool IsValidKind =

397 VK == ELF::R_LARCH_PCALA_LO12 || VK == ELF::R_LARCH_TLS_DESC_CALL;

398 return IsConstantImm

400 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

401 IsValidKind;

402 }

403

404 bool isSImm20() const { return isSImm<20>(); }

405

406 bool isSImm20pcalau12i() const {

407 if (!isImm())

408 return false;

409

410 int64_t Imm;

412 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

413 bool IsValidKind =

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;

419 return IsConstantImm

421 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

422 IsValidKind;

423 }

424

425 bool isSImm20lu12iw() const {

426 if (!isImm())

427 return false;

428

429 int64_t Imm;

431 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

432 bool IsValidKind =

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;

438 return IsConstantImm

440 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

441 IsValidKind;

442 }

443

444 bool isSImm20lu32id() const {

445 if (!isImm())

446 return false;

447

448 int64_t Imm;

450 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

451 bool IsValidKind =

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;

459

460 return IsConstantImm

462 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

463 IsValidKind;

464 }

465

466 bool isSImm20pcaddu18i() const {

467 if (!isImm())

468 return false;

469

470 int64_t Imm;

472 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

473 bool IsValidKind =

475

476 return IsConstantImm

478 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

479 IsValidKind;

480 }

481

482 bool isSImm20pcaddi() const {

483 if (!isImm())

484 return false;

485

486 int64_t Imm;

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;

494 return IsConstantImm

496 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

497 IsValidKind;

498 }

499

500 bool isSImm21lsl2() const {

501 if (!isImm())

502 return false;

503

504 int64_t Imm;

506 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

508 return IsConstantImm

510 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

511 IsValidKind;

512 }

513

514 bool isSImm26Operand() const {

515 if (!isImm())

516 return false;

517

518 int64_t Imm;

520 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

522 return IsConstantImm

524 : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&

525 IsValidKind;

526 }

527

528 bool isImm32() const { return isSImm<32>() || isUImm<32>(); }

529 bool isImm64() const {

530 if (!isImm())

531 return false;

532 int64_t Imm;

534 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);

536 }

537

538

539 SMLoc getStartLoc() const override { return StartLoc; }

540

541 SMLoc getEndLoc() const override { return EndLoc; }

542

543 MCRegister getReg() const override {

544 assert(Kind == KindTy::Register && "Invalid type access!");

545 return Reg.RegNum;

546 }

547

548 const MCExpr *getImm() const {

549 assert(Kind == KindTy::Immediate && "Invalid type access!");

550 return Imm.Val;

551 }

552

554 assert(Kind == KindTy::Token && "Invalid type access!");

555 return Tok;

556 }

557

558 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {

562 else

563 return "noreg";

564 };

565

566 switch (Kind) {

567 case KindTy::Immediate:

569 break;

570 case KindTy::Register:

572 break;

573 case KindTy::Token:

574 OS << "'" << getToken() << "'";

575 break;

576 }

577 }

578

579 static std::unique_ptr createToken(StringRef Str, SMLoc S) {

580 auto Op = std::make_unique(KindTy::Token);

581 Op->Tok = Str;

582 Op->StartLoc = S;

583 Op->EndLoc = S;

584 return Op;

585 }

586

587 static std::unique_ptr createReg(MCRegister Reg, SMLoc S,

588 SMLoc E) {

589 auto Op = std::make_unique(KindTy::Register);

590 Op->Reg.RegNum = Reg;

591 Op->StartLoc = S;

592 Op->EndLoc = E;

593 return Op;

594 }

595

596 static std::unique_ptr createImm(const MCExpr *Val, SMLoc S,

597 SMLoc E) {

598 auto Op = std::make_unique(KindTy::Immediate);

599 Op->Imm.Val = Val;

600 Op->StartLoc = S;

601 Op->EndLoc = E;

602 return Op;

603 }

604

605 void addExpr(MCInst &Inst, const MCExpr *Expr) const {

608 else

610 }

611

612

613 void addRegOperands(MCInst &Inst, unsigned N) const {

614 assert(N == 1 && "Invalid number of operands!");

616 }

617 void addImmOperands(MCInst &Inst, unsigned N) const {

618 assert(N == 1 && "Invalid number of operands!");

619 addExpr(Inst, getImm());

620 }

621};

622}

623

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"

629

631 assert(Reg >= LoongArch::F0 && Reg <= LoongArch::F31 && "Invalid register");

632 return Reg - LoongArch::F0 + LoongArch::F0_64;

633}

634

635

636

637

640

641

642 assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64));

643

644 static_assert(LoongArch::F0 < LoongArch::F0_64,

645 "FPR matching must be updated");

646 if (RegNo == LoongArch::NoRegister)

648

649 return RegNo == LoongArch::NoRegister;

650}

651

652bool LoongArchAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,

654 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())

655 return Error(getLoc(), "invalid register name");

656

657 if (!LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains(Reg) &&

658 !LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].contains(Reg))

659 return Error(getLoc(), "invalid register name");

660

661 return false;

662}

663

664ParseStatus LoongArchAsmParser::tryParseRegister(MCRegister &Reg,

665 SMLoc &StartLoc,

666 SMLoc &EndLoc) {

667 const AsmToken &Tok = getParser().getTok();

668 StartLoc = Tok.getLoc();

670

674

678

679 getParser().Lex();

681}

682

683bool LoongArchAsmParser::classifySymbolRef(const MCExpr *Expr,

686

688 Kind = RE->getSpecifier();

689 Expr = RE->getSubExpr();

690 }

691

692 MCValue Res;

695 return false;

696}

697

698ParseStatus LoongArchAsmParser::parseRegister(OperandVector &Operands) {

703

704 StringRef Name = getLexer().getTok().getIdentifier();

705 MCRegister RegNo;

707 if (RegNo == LoongArch::NoRegister)

709

710 SMLoc S = getLoc();

712 getLexer().Lex();

713 Operands.push_back(LoongArchOperand::createReg(RegNo, S, E));

714

716}

717

718ParseStatus LoongArchAsmParser::parseImmediate(OperandVector &Operands) {

719 SMLoc S = getLoc();

720 SMLoc E;

721 const MCExpr *Res;

722

723 switch (getLexer().getKind()) {

724 default:

735 if (getParser().parseExpression(Res, E))

737 break;

739 return parseOperandWithModifier(Operands);

740 }

741

742 Operands.push_back(LoongArchOperand::createImm(Res, S, E));

744}

745

746ParseStatus

747LoongArchAsmParser::parseOperandWithModifier(OperandVector &Operands) {

748 SMLoc S = getLoc();

749 SMLoc E;

750

752 return Error(getLoc(), "expected '%' for operand modifier");

753

754 getParser().Lex();

755

757 return Error(getLoc(), "expected valid identifier for operand modifier");

758 StringRef Identifier = getParser().getTok().getIdentifier();

761 return Error(getLoc(), "invalid relocation specifier");

762

763 getParser().Lex();

765 return Error(getLoc(), "expected '('");

766 getParser().Lex();

767

768 const MCExpr *SubExpr;

769 if (getParser().parseParenExpression(SubExpr, E))

771

773 Operands.push_back(LoongArchOperand::createImm(ModExpr, S, E));

775}

776

777ParseStatus LoongArchAsmParser::parseSImm26Operand(OperandVector &Operands) {

778 SMLoc S = getLoc();

779 const MCExpr *Res;

780

782 return parseOperandWithModifier(Operands);

783

786

788 if (getParser().parseIdentifier(Identifier))

790

792

795 Operands.push_back(LoongArchOperand::createImm(Res, S, E));

797}

798

799ParseStatus LoongArchAsmParser::parseAtomicMemOp(OperandVector &Operands) {

800

801 if (!parseRegister(Operands).isSuccess())

803

804

805

807 int64_t ImmVal;

808 SMLoc ImmStart = getLoc();

809 if (getParser().parseIntToken(ImmVal, "expected optional integer offset"))

811 if (ImmVal)

812 return Error(ImmStart, "optional integer offset must be 0");

813 }

814

816}

817

818

819bool LoongArchAsmParser::parseOperand(OperandVector &Operands,

820 StringRef Mnemonic) {

821

822

824 MatchOperandParserImpl(Operands, Mnemonic, true);

825 if (Result.isSuccess())

826 return false;

827 if (Result.isFailure())

828 return true;

829

830 if (parseRegister(Operands).isSuccess() ||

832 return false;

833

834

835 return Error(getLoc(), "unknown operand");

836}

837

838bool LoongArchAsmParser::parseInstruction(ParseInstructionInfo &Info,

839 StringRef Name, SMLoc NameLoc,

841

842 Operands.push_back(LoongArchOperand::createToken(Name, NameLoc));

843

844

846 return false;

847

848

849 if (parseOperand(Operands, Name))

850 return true;

851

852

854 if (parseOperand(Operands, Name))

855 return true;

856

857

859 return false;

860

861 SMLoc Loc = getLexer().getLoc();

862 getParser().eatToEndOfStatement();

863 return Error(Loc, "unexpected token");

864}

865

866void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,

867 const MCExpr *Symbol,

868 SmallVectorImpl &Insts,

869 SMLoc IDLoc, MCStreamer &Out,

870 bool RelaxHint) {

872 for (LoongArchAsmParser::Inst &Inst : Insts) {

873 unsigned Opc = Inst.Opc;

875 const LoongArchMCExpr *LE =

877 switch (Opc) {

878 default:

880 case LoongArch::PCALAU12I:

881 case LoongArch::LU12I_W:

883 getSTI());

884 break;

885 case LoongArch::ORI:

886 case LoongArch::ADDI_W:

887 case LoongArch::LD_W:

888 case LoongArch::LD_D: {

891 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addImm(0),

892 getSTI());

893 continue;

894 } else if (VK == ELF::R_LARCH_TLS_DESC_LD) {

896 .addReg(LoongArch::R1)

897 .addReg(DestReg)

898 .addExpr(LE),

899 getSTI());

900 continue;

901 }

903 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),

904 getSTI());

905 break;

906 }

907 case LoongArch::LU32I_D:

909 .addReg(DestReg == TmpReg ? DestReg : TmpReg)

910 .addReg(DestReg == TmpReg ? DestReg : TmpReg)

911 .addExpr(LE),

912 getSTI());

913 break;

914 case LoongArch::LU52I_D:

916 MCInstBuilder(Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE),

917 getSTI());

918 break;

919 case LoongArch::ADDI_D:

921 MCInstBuilder(Opc)

922 .addReg(TmpReg)

923 .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0)

924 .addExpr(LE),

925 getSTI());

926 break;

927 case LoongArch::ADD_D:

928 case LoongArch::LDX_D:

930 MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg),

931 getSTI());

932 break;

933 case LoongArch::JIRL:

935 .addReg(LoongArch::R1)

936 .addReg(LoongArch::R1)

937 .addExpr(LE),

938 getSTI());

939 break;

940 }

941 }

942}

943

944void LoongArchAsmParser::emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc,

945 MCStreamer &Out) {

946

947

948

949

950

951

952

953

955 const MCExpr *Symbol = Inst.getOpcode() == LoongArch::PseudoLA_ABS

958 InstSeq Insts;

959

960

961

963 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_MARK_LA));

964 Insts.push_back(

965 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_ABS_LO12));

966

968 Insts.push_back(

969 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_ABS64_LO20));

970 Insts.push_back(

971 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_ABS64_HI12));

972 }

973

974 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);

975}

976

977void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc,

978 MCStreamer &Out) {

979

980

981

982

985 InstSeq Insts;

986 unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;

987

988 Insts.push_back(

989 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));

990 Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_PCALA_LO12));

991

992 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,

993 true);

994}

995

996void LoongArchAsmParser::emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc,

997 MCStreamer &Out) {

998

999

1000

1001

1002

1003

1004

1008 InstSeq Insts;

1009

1011 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));

1012 Insts.push_back(

1013 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_PCALA_LO12));

1014 Insts.push_back(

1015 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_PCALA64_LO20));

1016 Insts.push_back(

1017 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_PCALA64_HI12));

1018 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));

1019

1020 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);

1021}

1022

1023void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,

1024 MCStreamer &Out) {

1025

1028 InstSeq Insts;

1029 unsigned LD = is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;

1030

1031 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044 Insts.push_back(

1045 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_GOT_HI20));

1046 Insts.push_back(

1047 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));

1048

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));

1054 }

1055 Insts.push_back(LoongArchAsmParser::Inst(LD));

1056 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);

1057 return;

1058 }

1059

1060

1061

1062 Insts.push_back(

1063 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));

1064 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_GOT_PC_LO12));

1065

1066 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,

1067 true);

1068}

1069

1070void LoongArchAsmParser::emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc,

1071 MCStreamer &Out) {

1072

1073

1074

1075

1076

1077

1078

1082 InstSeq Insts;

1083

1085 LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));

1086 Insts.push_back(

1087 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));

1088 Insts.push_back(

1089 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));

1090 Insts.push_back(

1091 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));

1092 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D));

1093

1094 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);

1095}

1096

1097void LoongArchAsmParser::emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc,

1098 MCStreamer &Out) {

1099

1100

1101

1102

1105 InstSeq Insts;

1106

1108 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LE_HI20));

1109 Insts.push_back(

1110 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_LE_LO12));

1111

1112 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);

1113}

1114

1115void LoongArchAsmParser::emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc,

1116 MCStreamer &Out) {

1117

1120 InstSeq Insts;

1121 unsigned LD = is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;

1122

1123 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {

1124

1125

1126

1127

1128

1129

1130

1131

1132

1133

1134

1135

1136 Insts.push_back(

1137 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_IE_HI20));

1138 Insts.push_back(

1139 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_IE_LO12));

1140

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));

1146 }

1147 Insts.push_back(LoongArchAsmParser::Inst(LD));

1148 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);

1149 return;

1150 }

1151

1152

1153

1154

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));

1158

1159 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,

1160 true);

1161}

1162

1163void LoongArchAsmParser::emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc,

1164 MCStreamer &Out) {

1165

1166

1167

1168

1169

1170

1171

1175 InstSeq Insts;

1176

1177 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,

1178 ELF::R_LARCH_TLS_IE_PC_HI20));

1179 Insts.push_back(

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));

1186

1187 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);

1188}

1189

1190void LoongArchAsmParser::emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc,

1191 MCStreamer &Out) {

1192

1195 InstSeq Insts;

1196 unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;

1197

1198 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {

1199

1200

1201

1202

1203

1204

1205

1206

1207

1208

1209 Insts.push_back(

1210 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_LD_HI20));

1211 Insts.push_back(

1212 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));

1213

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));

1219 }

1220 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);

1221 return;

1222 }

1223

1224

1225

1226

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));

1230

1231 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,

1232 true);

1233}

1234

1235void LoongArchAsmParser::emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc,

1236 MCStreamer &Out) {

1237

1238

1239

1240

1241

1242

1243

1247 InstSeq Insts;

1248

1249 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,

1250 ELF::R_LARCH_TLS_LD_PC_HI20));

1251 Insts.push_back(

1252 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));

1253 Insts.push_back(

1254 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));

1255 Insts.push_back(

1256 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));

1257 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));

1258

1259 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);

1260}

1261

1262void LoongArchAsmParser::emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc,

1263 MCStreamer &Out) {

1264

1267 InstSeq Insts;

1268 unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;

1269

1270 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {

1271

1272

1273

1274

1275

1276

1277

1278

1279

1280

1281 Insts.push_back(

1282 LoongArchAsmParser::Inst(LoongArch::LU12I_W, ELF::R_LARCH_TLS_GD_HI20));

1283 Insts.push_back(

1284 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_GOT_LO12));

1285

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));

1291 }

1292 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);

1293 return;

1294 }

1295

1296

1297

1298

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));

1302

1303 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,

1304 true);

1305}

1306

1307void LoongArchAsmParser::emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc,

1308 MCStreamer &Out) {

1309

1310

1311

1312

1313

1314

1315

1319 InstSeq Insts;

1320

1321 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,

1322 ELF::R_LARCH_TLS_GD_PC_HI20));

1323 Insts.push_back(

1324 LoongArchAsmParser::Inst(LoongArch::ADDI_D, ELF::R_LARCH_GOT_PC_LO12));

1325 Insts.push_back(

1326 LoongArchAsmParser::Inst(LoongArch::LU32I_D, ELF::R_LARCH_GOT64_PC_LO20));

1327 Insts.push_back(

1328 LoongArchAsmParser::Inst(LoongArch::LU52I_D, ELF::R_LARCH_GOT64_PC_HI12));

1329 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D));

1330

1331 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);

1332}

1333

1334void LoongArchAsmParser::emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc,

1335 MCStreamer &Out) {

1336

1339 unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;

1340 unsigned LD = is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;

1341 InstSeq Insts;

1342

1343 if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {

1344

1345

1346

1347

1348

1349

1350

1351

1352

1353

1354

1355

1356

1357

1358 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LU12I_W,

1359 ELF::R_LARCH_TLS_DESC_HI20));

1360 Insts.push_back(

1361 LoongArchAsmParser::Inst(LoongArch::ORI, ELF::R_LARCH_TLS_DESC_LO12));

1362

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));

1368 }

1369

1370 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));

1371 Insts.push_back(

1372 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));

1373

1374 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);

1375 return;

1376 }

1377

1378

1379

1380

1381

1382

1383 Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,

1384 ELF::R_LARCH_TLS_DESC_PC_HI20));

1385 Insts.push_back(

1386 LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_TLS_DESC_PC_LO12));

1387 Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));

1388 Insts.push_back(

1389 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));

1390

1391 emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,

1392 true);

1393}

1394

1395void LoongArchAsmParser::emitLoadAddressTLSDescLarge(MCInst &Inst, SMLoc IDLoc,

1396 MCStreamer &Out) {

1397

1398

1399

1400

1401

1402

1403

1404

1405

1409 InstSeq Insts;

1410

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));

1420 Insts.push_back(

1421 LoongArchAsmParser::Inst(LoongArch::LD_D, ELF::R_LARCH_TLS_DESC_LD));

1422 Insts.push_back(

1423 LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));

1424

1425 emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out);

1426}

1427

1428void LoongArchAsmParser::emitLoadImm(MCInst &Inst, SMLoc IDLoc,

1429 MCStreamer &Out) {

1432 MCRegister SrcReg = LoongArch::R0;

1433

1434 if (Inst.getOpcode() == LoongArch::PseudoLI_W)

1436

1438 switch (Inst.Opc) {

1439 case LoongArch::LU12I_W:

1441 MCInstBuilder(Inst.Opc).addReg(DestReg).addImm(Inst.Imm), getSTI());

1442 break;

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(

1449 Inst.Imm),

1450 getSTI());

1451 break;

1452 case LoongArch::BSTRINS_D:

1454 .addReg(DestReg)

1455 .addReg(SrcReg)

1456 .addReg(SrcReg)

1457 .addImm(Inst.Imm >> 32)

1458 .addImm(Inst.Imm & 0xFF),

1459 getSTI());

1460 break;

1461 default:

1462 llvm_unreachable("unexpected opcode generated by LoongArchMatInt");

1463 }

1464 SrcReg = DestReg;

1465 }

1466}

1467

1468void LoongArchAsmParser::emitFuncCall36(MCInst &Inst, SMLoc IDLoc,

1469 MCStreamer &Out, bool IsTailCall) {

1470

1471

1472

1473

1474

1475

1476

1477

1478

1479 MCRegister ScratchReg =

1480 IsTailCall ? Inst.getOperand(0).getReg() : MCRegister(LoongArch::R1);

1481 const MCExpr *Sym =

1484 Sym, ELF::R_LARCH_CALL36, getContext(), true);

1485

1487 MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),

1488 getSTI());

1490 MCInstBuilder(LoongArch::JIRL)

1491 .addReg(IsTailCall ? MCRegister(LoongArch::R0) : ScratchReg)

1492 .addReg(ScratchReg)

1493 .addImm(0),

1494 getSTI());

1495}

1496

1497bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,

1499 MCStreamer &Out) {

1502 default:

1503 break;

1504 case LoongArch::PseudoLA_ABS:

1505 case LoongArch::PseudoLA_ABS_LARGE:

1506 emitLoadAddressAbs(Inst, IDLoc, Out);

1507 return false;

1508 case LoongArch::PseudoLA_PCREL:

1509 emitLoadAddressPcrel(Inst, IDLoc, Out);

1510 return false;

1511 case LoongArch::PseudoLA_PCREL_LARGE:

1512 emitLoadAddressPcrelLarge(Inst, IDLoc, Out);

1513 return false;

1514 case LoongArch::PseudoLA_GOT:

1515 emitLoadAddressGot(Inst, IDLoc, Out);

1516 return false;

1517 case LoongArch::PseudoLA_GOT_LARGE:

1518 emitLoadAddressGotLarge(Inst, IDLoc, Out);

1519 return false;

1520 case LoongArch::PseudoLA_TLS_LE:

1521 emitLoadAddressTLSLE(Inst, IDLoc, Out);

1522 return false;

1523 case LoongArch::PseudoLA_TLS_IE:

1524 emitLoadAddressTLSIE(Inst, IDLoc, Out);

1525 return false;

1526 case LoongArch::PseudoLA_TLS_IE_LARGE:

1527 emitLoadAddressTLSIELarge(Inst, IDLoc, Out);

1528 return false;

1529 case LoongArch::PseudoLA_TLS_LD:

1530 emitLoadAddressTLSLD(Inst, IDLoc, Out);

1531 return false;

1532 case LoongArch::PseudoLA_TLS_LD_LARGE:

1533 emitLoadAddressTLSLDLarge(Inst, IDLoc, Out);

1534 return false;

1535 case LoongArch::PseudoLA_TLS_GD:

1536 emitLoadAddressTLSGD(Inst, IDLoc, Out);

1537 return false;

1538 case LoongArch::PseudoLA_TLS_GD_LARGE:

1539 emitLoadAddressTLSGDLarge(Inst, IDLoc, Out);

1540 return false;

1541 case LoongArch::PseudoLA_TLS_DESC:

1542 emitLoadAddressTLSDesc(Inst, IDLoc, Out);

1543 return false;

1544 case LoongArch::PseudoLA_TLS_DESC_LARGE:

1545 emitLoadAddressTLSDescLarge(Inst, IDLoc, Out);

1546 return false;

1547 case LoongArch::PseudoLI_W:

1548 case LoongArch::PseudoLI_D:

1549 emitLoadImm(Inst, IDLoc, Out);

1550 return false;

1551 case LoongArch::PseudoCALL36:

1552 emitFuncCall36(Inst, IDLoc, Out, false);

1553 return false;

1554 case LoongArch::PseudoTAIL36:

1555 emitFuncCall36(Inst, IDLoc, Out, true);

1556 return false;

1557 }

1559 return false;

1560}

1561

1562unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {

1564 const MCInstrDesc &MCID = MII.get(Opc);

1565 switch (Opc) {

1566 default:

1572 if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0)

1573 return Match_RequiresAMORdDifferRkRj;

1574 }

1575 break;

1576 case LoongArch::PseudoLA_TLS_DESC:

1577 case LoongArch::PseudoLA_TLS_DESC_LARGE: {

1579 if (Rd != LoongArch::R4)

1580 return Match_RequiresLAORdR4;

1581 break;

1582 }

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: {

1590 if (Rd == Rj)

1591 return Match_RequiresLAORdDifferRj;

1592 break;

1593 }

1594 case LoongArch::CSRXCHG:

1595 case LoongArch::GCSRXCHG: {

1597 if (Rj == LoongArch::R0 || Rj == LoongArch::R1)

1598 return Match_RequiresOpnd2NotR0R1;

1599 return Match_Success;

1600 }

1601 case LoongArch::BSTRINS_W:

1602 case LoongArch::BSTRINS_D:

1603 case LoongArch::BSTRPICK_W:

1604 case LoongArch::BSTRPICK_D: {

1606 const signed Msb =

1607 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)

1610 const signed Lsb =

1611 (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)

1614 if (Msb < Lsb)

1615 return Match_RequiresMsbNotLessThanLsb;

1616 return Match_Success;

1617 }

1618 }

1619

1620 return Match_Success;

1621}

1622

1623unsigned

1624LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,

1625 unsigned Kind) {

1626 LoongArchOperand &Op = static_cast<LoongArchOperand &>(AsmOp);

1627 if (Op.isReg())

1628 return Match_InvalidOperand;

1629

1630 MCRegister Reg = Op.getReg();

1631

1632

1633 if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].contains(Reg) &&

1634 Kind == MCK_FPR64) {

1636 return Match_Success;

1637 }

1638

1639 if (Kind == MCK_GPRNoR0R1 && (Reg == LoongArch::R0 || Reg == LoongArch::R1))

1640 return Match_RequiresOpnd2NotR0R1;

1641

1642 return Match_InvalidOperand;

1643}

1644

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) + "]");

1650}

1651

1652bool LoongArchAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

1654 MCStreamer &Out,

1655 uint64_t &ErrorInfo,

1656 bool MatchingInlineAsm) {

1657 MCInst Inst;

1658 FeatureBitset MissingFeatures;

1659

1660 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,

1661 MatchingInlineAsm);

1662 switch (Result) {

1663 default:

1664 break;

1665 case Match_Success:

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;

1676 }

1677 }

1678 return Error(IDLoc, Msg);

1679 }

1680 case Match_MnemonicFail: {

1681 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());

1682 std::string Suggestion = LoongArchMnemonicSpellCheck(

1683 ((LoongArchOperand &)*Operands[0]).getToken(), FBS, 0);

1684 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);

1685 }

1686 case Match_InvalidOperand: {

1687 SMLoc ErrorLoc = IDLoc;

1688 if (ErrorInfo != ~0ULL) {

1689 if (ErrorInfo >= Operands.size())

1690 return Error(ErrorLoc, "too few operands for instruction");

1691

1692 ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();

1693 if (ErrorLoc == SMLoc())

1694 ErrorLoc = IDLoc;

1695 }

1696 return Error(ErrorLoc, "invalid operand for instruction");

1697 }

1698 }

1699

1700

1701

1702

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");

1707 }

1708

1709 switch (Result) {

1710 default:

1711 break;

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()));

1716 }

1717 case Match_RequiresOpnd2NotR0R1:

1718 return Error(Operands[2]->getStartLoc(), "must not be r0orr0 or r0orr1");

1719 case Match_RequiresAMORdDifferRkRj:

1720 return Error(Operands[1]->getStartLoc(),

1721 "$rd must be different from both rkandrk and rkandrj");

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,

1728 (1 << 1) - 1);

1729 case Match_InvalidUImm2:

1730 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1731 (1 << 2) - 1);

1732 case Match_InvalidUImm2plus1:

1733 return generateImmOutOfRangeError(Operands, ErrorInfo, 1,

1734 (1 << 2));

1735 case Match_InvalidUImm3:

1736 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1737 (1 << 3) - 1);

1738 case Match_InvalidUImm4:

1739 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1740 (1 << 4) - 1);

1741 case Match_InvalidUImm5:

1742 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1743 (1 << 5) - 1);

1744 case Match_InvalidUImm6:

1745 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1746 (1 << 6) - 1);

1747 case Match_InvalidUImm7:

1748 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1749 (1 << 7) - 1);

1750 case Match_InvalidUImm8:

1751 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1752 (1 << 8) - 1);

1753 case Match_InvalidUImm12:

1754 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1755 (1 << 12) - 1);

1756 case Match_InvalidUImm12ori:

1757 return generateImmOutOfRangeError(

1758 Operands, ErrorInfo, 0,

1759 (1 << 12) - 1,

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,

1764 (1 << 14) - 1);

1765 case Match_InvalidUImm15:

1766 return generateImmOutOfRangeError(Operands, ErrorInfo, 0,

1767 (1 << 15) - 1);

1768 case Match_InvalidSImm5:

1769 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),

1770 (1 << 4) - 1);

1771 case Match_InvalidSImm8:

1772 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),

1773 (1 << 7) - 1);

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),

1784 (1 << 9) - 1);

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),

1803 (1 << 11) - 1);

1804 case Match_InvalidSImm12addlike:

1805 return generateImmOutOfRangeError(

1806 Operands, ErrorInfo, -(1 << 11),

1807 (1 << 11) - 1,

1808 "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer "

1809 "in the range");

1810 case Match_InvalidSImm12lu52id:

1811 return generateImmOutOfRangeError(

1812 Operands, ErrorInfo, -(1 << 11),

1813 (1 << 11) - 1,

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),

1818 (1 << 12) - 1);

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),

1825 (1 << 15) - 1);

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 "

1830 "in the range");

1831 case Match_InvalidSImm20:

1832 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 19),

1833 (1 << 19) - 1);

1834 case Match_InvalidSImm20lu12iw:

1835 return generateImmOutOfRangeError(

1836 Operands, ErrorInfo, -(1 << 19),

1837 (1 << 19) - 1,

1838 "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer "

1839 "in the range");

1840 case Match_InvalidSImm20lu32id:

1841 return generateImmOutOfRangeError(

1842 Operands, ErrorInfo, -(1 << 19),

1843 (1 << 19) - 1,

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(

1848 Operands, ErrorInfo, -(1 << 19),

1849 (1 << 19) - 1,

1850 "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "

1851 "in the range");

1852 case Match_InvalidSImm20pcaddu18i:

1853 return generateImmOutOfRangeError(

1854 Operands, ErrorInfo, -(1 << 19),

1855 (1 << 19) - 1,

1856 "operand must be a symbol with modifier (e.g. %call36) or an integer "

1857 "in the range");

1858 case Match_InvalidSImm20pcaddi:

1859 return generateImmOutOfRangeError(

1860 Operands, ErrorInfo, -(1 << 19),

1861 (1 << 19) - 1,

1862 "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "

1863 "in the range");

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 "

1868 "in the range");

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");

1877 }

1878 case Match_InvalidImm64: {

1879 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();

1880 return Error(ErrorLoc, "operand must be a 64 bit immediate");

1881 }

1882 case Match_InvalidBareSymbol: {

1883 SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc();

1884 return Error(ErrorLoc, "operand must be a bare symbol name");

1885 }

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");

1889 }

1890 }

1892}

1893

1894bool LoongArchAsmParser::parseDirectiveOption() {

1895 MCAsmParser &Parser = getParser();

1896

1897 AsmToken Tok = Parser.getTok();

1898

1899

1901 return true;

1902

1904

1905 if (Option == "push") {

1907 return true;

1908

1909 getTargetStreamer().emitDirectiveOptionPush();

1910 pushFeatureBits();

1911 return false;

1912 }

1913

1914 if (Option == "pop") {

1917 return true;

1918

1919 getTargetStreamer().emitDirectiveOptionPop();

1920 if (popFeatureBits())

1921 return Error(StartLoc, ".option pop with no .option push");

1922

1923 return false;

1924 }

1925

1926 if (Option == "relax") {

1928 return true;

1929

1930 getTargetStreamer().emitDirectiveOptionRelax();

1931 setFeatureBits(LoongArch::FeatureRelax, "relax");

1932 return false;

1933 }

1934

1935 if (Option == "norelax") {

1937 return true;

1938

1939 getTargetStreamer().emitDirectiveOptionNoRelax();

1940 clearFeatureBits(LoongArch::FeatureRelax, "relax");

1941 return false;

1942 }

1943

1944

1946 "unknown option, expected 'push', 'pop', 'relax' or 'norelax'");

1948 return false;

1949}

1950

1951ParseStatus LoongArchAsmParser::parseDirective(AsmToken DirectiveID) {

1952 if (DirectiveID.getString() == ".option")

1953 return parseDirectiveOption();

1954

1956}

1957

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)

Definition LoongArchAsmParser.cpp:638

static MCRegister convertFPR32ToFPR64(MCRegister Reg)

Definition LoongArchAsmParser.cpp:630

LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchAsmParser()

Definition LoongArchAsmParser.cpp:1959

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 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 - 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,...