LLVM: lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

43

44#include

45#include

46

47using namespace llvm;

48

49#define DEBUG_TYPE "riscv-asm-parser"

50

52 "Number of RISC-V Compressed instructions emitted");

53

56

57namespace llvm {

59}

60

61namespace {

62struct RISCVOperand;

63

64struct ParserOptionsSet {

65 bool IsPicEnabled;

66};

67

69

70

71 enum class VTypeState {

72 SeenNothingYet,

73 SeenSew,

74 SeenLmul,

75 SeenTailPolicy,

76 SeenMaskPolicy,

77 };

78

80

82 ParserOptionsSet ParserOptions;

83

84 SMLoc getLoc() const { return getParser().getTok().getLoc(); }

85 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }

86 bool isRVE() const { return getSTI().hasFeature(RISCV::FeatureStdExtE); }

87 bool enableExperimentalExtension() const {

88 return getSTI().hasFeature(RISCV::Experimental);

89 }

90

91 RISCVTargetStreamer &getTargetStreamer() {

92 assert(getParser().getStreamer().getTargetStreamer() &&

93 "do not have a target streamer");

94 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();

95 return static_cast<RISCVTargetStreamer &>(TS);

96 }

97

98 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,

99 unsigned Kind) override;

100

101 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,

103 const Twine &Msg);

104 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t Lower, int64_t Upper,

105 const Twine &Msg);

106

107 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

109 uint64_t &ErrorInfo,

110 bool MatchingInlineAsm) override;

111

113 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;

114 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

115 SMLoc &EndLoc) override;

116

117 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,

118 SMLoc NameLoc, OperandVector &Operands) override;

119

120 ParseStatus parseDirective(AsmToken DirectiveID) override;

121

122 bool parseVTypeToken(const AsmToken &Tok, VTypeState &State, unsigned &Sew,

123 unsigned &Lmul, bool &Fractional, bool &TailAgnostic,

124 bool &MaskAgnostic, bool &AltFmt);

125 bool generateVTypeError(SMLoc ErrorLoc);

126

127 bool generateXSfmmVTypeError(SMLoc ErrorLoc);

128

129

130 void emitToStreamer(MCStreamer &S, const MCInst &Inst);

131

132

133

134 void emitLoadImm(MCRegister DestReg, int64_t Value, MCStreamer &Out);

135

136

137

138 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,

140 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);

141

142

143 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

144

145

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

147

148

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

150

151

152

153 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

154

155

156

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

158

159

160 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,

161 MCStreamer &Out, bool HasTmpReg);

162

163

164 void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width,

165 SMLoc IDLoc, MCStreamer &Out);

166

167

168 void emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);

169

170

171

172

173

174 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);

175

176

177

178

179

180 bool checkPseudoTLSDESCCall(MCInst &Inst, OperandVector &Operands);

181

182

183 bool validateInstruction(MCInst &Inst, OperandVector &Operands);

184

185

186

187

188

189 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,

190 MCStreamer &Out);

191

192

193#define GET_ASSEMBLER_HEADER

194#include "RISCVGenAsmMatcher.inc"

195

220 return parseRegList(Operands, true);

221 }

222

223 ParseStatus parseRegReg(OperandVector &Operands);

224 ParseStatus parseXSfmmVType(OperandVector &Operands);

225 ParseStatus parseZcmpStackAdj(OperandVector &Operands,

226 bool ExpectNegative = false);

227 ParseStatus parseZcmpNegStackAdj(OperandVector &Operands) {

228 return parseZcmpStackAdj(Operands, true);

229 }

230

231 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);

232 bool parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E);

233 bool parseDataExpr(const MCExpr *&Res) override;

234

235 bool parseDirectiveOption();

236 bool parseDirectiveAttribute();

237 bool parseDirectiveInsn(SMLoc L);

238 bool parseDirectiveVariantCC();

239

240

241

242

243 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,

244 bool FromOptionDirective);

245

246 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {

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

248 MCSubtargetInfo &STI = copySTI();

249 setAvailableFeatures(

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

251 }

252 }

253

254 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {

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

256 MCSubtargetInfo &STI = copySTI();

257 setAvailableFeatures(

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

259 }

260 }

261

262 void pushFeatureBits() {

263 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&

264 "These two stacks must be kept synchronized");

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

266 ParserOptionsStack.push_back(ParserOptions);

267 }

268

269 bool popFeatureBits() {

270 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&

271 "These two stacks must be kept synchronized");

272 if (FeatureBitStack.empty())

273 return true;

274

275 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();

276 copySTI().setFeatureBits(FeatureBits);

277 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));

278

279 ParserOptions = ParserOptionsStack.pop_back_val();

280

281 return false;

282 }

283

284 std::unique_ptr defaultMaskRegOp() const;

285 std::unique_ptr defaultFRMArgOp() const;

286 std::unique_ptr defaultFRMArgLegacyOp() const;

287

288public:

289 enum RISCVMatchResultTy : unsigned {

290 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,

291#define GET_OPERAND_DIAGNOSTIC_TYPES

292#include "RISCVGenAsmMatcher.inc"

293#undef GET_OPERAND_DIAGNOSTIC_TYPES

294 };

295

296 static bool classifySymbolRef(const MCExpr *Expr, RISCV::Specifier &Kind);

297 static bool isSymbolDiff(const MCExpr *Expr);

298

299 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,

300 const MCInstrInfo &MII, const MCTargetOptions &Options)

301 : MCTargetAsmParser(Options, STI, MII) {

303

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

309

310 auto ABIName = StringRef(Options.ABIName);

311 if (ABIName.ends_with("f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {

312 errs() << "Hard-float 'f' ABI can't be used for a target that "

313 "doesn't support the F instruction set extension (ignoring "

314 "target-abi)\n";

315 } else if (ABIName.ends_with("d") &&

316 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {

317 errs() << "Hard-float 'd' ABI can't be used for a target that "

318 "doesn't support the D instruction set extension (ignoring "

319 "target-abi)\n";

320 }

321

322

323

325 ABIName);

326

329

331 getTargetStreamer().emitTargetAttributes(STI, false);

332 }

333};

334

335

336

338

339 enum class KindTy {

340 Token,

342 Expression,

343 FPImmediate,

344 SystemRegister,

345 VType,

346 FRM,

347 Fence,

348 RegList,

349 StackAdj,

351 } Kind;

352

353 struct RegOp {

354 MCRegister Reg;

355 bool IsGPRAsFPR;

356 };

357

358 struct ExprOp {

359 const MCExpr *Expr;

360 bool IsRV64;

361 };

362

363 struct FPImmOp {

364 uint64_t Val;

365 };

366

367 struct SysRegOp {

368 const char *Data;

369 unsigned Length;

370 unsigned Encoding;

371

372

373 };

374

375 struct VTypeOp {

376 unsigned Val;

377 };

378

379 struct FRMOp {

381 };

382

383 struct FenceOp {

384 unsigned Val;

385 };

386

387 struct RegListOp {

388 unsigned Encoding;

389 };

390

391 struct StackAdjOp {

392 unsigned Val;

393 };

394

395 struct RegRegOp {

396 MCRegister BaseReg;

397 MCRegister OffsetReg;

398 };

399

400 SMLoc StartLoc, EndLoc;

401 union {

402 StringRef Tok;

403 RegOp Reg;

404 ExprOp Expr;

405 FPImmOp FPImm;

406 SysRegOp SysReg;

407 VTypeOp VType;

408 FRMOp FRM;

409 FenceOp Fence;

410 RegListOp RegList;

411 StackAdjOp StackAdj;

413 };

414

415 RISCVOperand(KindTy K) : Kind(K) {}

416

417public:

418 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {

419 Kind = o.Kind;

420 StartLoc = o.StartLoc;

421 EndLoc = o.EndLoc;

422 switch (Kind) {

423 case KindTy::Register:

425 break;

426 case KindTy::Expression:

427 Expr = o.Expr;

428 break;

429 case KindTy::FPImmediate:

430 FPImm = o.FPImm;

431 break;

432 case KindTy::Token:

433 Tok = o.Tok;

434 break;

435 case KindTy::SystemRegister:

436 SysReg = o.SysReg;

437 break;

438 case KindTy::VType:

439 VType = o.VType;

440 break;

441 case KindTy::FRM:

442 FRM = o.FRM;

443 break;

444 case KindTy::Fence:

445 Fence = o.Fence;

446 break;

447 case KindTy::RegList:

448 RegList = o.RegList;

449 break;

450 case KindTy::StackAdj:

451 StackAdj = o.StackAdj;

452 break;

453 case KindTy::RegReg:

455 break;

456 }

457 }

458

459 bool isToken() const override { return Kind == KindTy::Token; }

460 bool isReg() const override { return Kind == KindTy::Register; }

461 bool isExpr() const { return Kind == KindTy::Expression; }

462 bool isV0Reg() const {

463 return Kind == KindTy::Register && Reg.Reg == RISCV::V0;

464 }

465 bool isAnyReg() const {

466 return Kind == KindTy::Register &&

467 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.Reg) ||

468 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg.Reg) ||

469 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg.Reg));

470 }

471 bool isAnyRegC() const {

472 return Kind == KindTy::Register &&

473 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(Reg.Reg) ||

474 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg.Reg));

475 }

476 bool isImm() const override { return isExpr(); }

477 bool isMem() const override { return false; }

478 bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }

479 bool isRegReg() const { return Kind == KindTy::RegReg; }

480 bool isRegList() const { return Kind == KindTy::RegList; }

481 bool isRegListS0() const {

482 return Kind == KindTy::RegList && RegList.Encoding != RISCVZC::RA;

483 }

484 bool isStackAdj() const { return Kind == KindTy::StackAdj; }

485

486 bool isGPR() const {

487 return Kind == KindTy::Register &&

488 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.Reg);

489 }

490

491 bool isGPRPair() const {

492 return Kind == KindTy::Register &&

493 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(Reg.Reg);

494 }

495

496 bool isGPRPairC() const {

497 return Kind == KindTy::Register &&

498 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(Reg.Reg);

499 }

500

501 bool isGPRPairNoX0() const {

502 return Kind == KindTy::Register &&

503 RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(

504 Reg.Reg);

505 }

506

507 bool isGPRF16() const {

508 return Kind == KindTy::Register &&

509 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(Reg.Reg);

510 }

511

512 bool isGPRF32() const {

513 return Kind == KindTy::Register &&

514 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(Reg.Reg);

515 }

516

517 bool isGPRAsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }

518 bool isGPRAsFPR16() const { return isGPRF16() && Reg.IsGPRAsFPR; }

519 bool isGPRAsFPR32() const { return isGPRF32() && Reg.IsGPRAsFPR; }

520 bool isGPRPairAsFPR64() const { return isGPRPair() && Reg.IsGPRAsFPR; }

521

522 static bool evaluateConstantExpr(const MCExpr *Expr, int64_t &Imm) {

524 Imm = CE->getValue();

525 return true;

526 }

527

528 return false;

529 }

530

531

532

533 template bool isBareSimmNLsb0() const {

534 if (!isExpr())

535 return false;

536

537 int64_t Imm;

538 if (evaluateConstantExpr(getExpr(), Imm))

539 return isShiftedInt<N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));

540

542 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

544 }

545

546

547

548 template bool isBareSimmN() const {

549 if (!isExpr())

550 return false;

551

552 int64_t Imm;

553 if (evaluateConstantExpr(getExpr(), Imm))

554 return isInt(fixImmediateForRV32(Imm, isRV64Expr()));

555

557 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

559 }

560

561

562

563 bool isBareSymbol() const {

564 int64_t Imm;

565

566 if (!isExpr() || evaluateConstantExpr(getExpr(), Imm))

567 return false;

568

570 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

572 }

573

574 bool isCallSymbol() const {

575 int64_t Imm;

576

577 if (!isExpr() || evaluateConstantExpr(getExpr(), Imm))

578 return false;

579

581 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

582 VK == ELF::R_RISCV_CALL_PLT;

583 }

584

585 bool isPseudoJumpSymbol() const {

586 int64_t Imm;

587

588 if (!isExpr() || evaluateConstantExpr(getExpr(), Imm))

589 return false;

590

592 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

593 VK == ELF::R_RISCV_CALL_PLT;

594 }

595

596 bool isTPRelAddSymbol() const {

597 int64_t Imm;

598

599 if (!isExpr() || evaluateConstantExpr(getExpr(), Imm))

600 return false;

601

603 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

604 VK == ELF::R_RISCV_TPREL_ADD;

605 }

606

607 bool isTLSDESCCallSymbol() const {

608 int64_t Imm;

609

610 if (!isExpr() || evaluateConstantExpr(getExpr(), Imm))

611 return false;

612

614 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

615 VK == ELF::R_RISCV_TLSDESC_CALL;

616 }

617

618 bool isCSRSystemRegister() const { return isSystemRegister(); }

619

620

621

622 bool isVTypeI10() const {

623 if (Kind == KindTy::VType)

624 return true;

625 return isUImm<10>();

626 }

627 bool isVTypeI11() const {

628 if (Kind == KindTy::VType)

629 return true;

630 return isUImm<11>();

631 }

632

633 bool isXSfmmVType() const {

635 }

636

637

638

639 bool isFenceArg() const { return Kind == KindTy::Fence; }

640

641

642 bool isFRMArg() const { return Kind == KindTy::FRM; }

643 bool isFRMArgLegacy() const { return Kind == KindTy::FRM; }

644 bool isRTZArg() const { return isFRMArg() && FRM.FRM == RISCVFPRndMode::RTZ; }

645

646

647 bool isLoadFPImm() const {

648 if (isExpr())

649 return isUImm5();

650 if (Kind != KindTy::FPImmediate)

651 return false;

653 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));

654

655

656 return Idx >= 0 && Idx != 1;

657 }

658

659 bool isImmXLenLI() const {

660 int64_t Imm;

661 if (!isExpr())

662 return false;

663

664

665 if (evaluateConstantExpr(getExpr(), Imm))

667

668 return RISCVAsmParser::isSymbolDiff(getExpr());

669 }

670

671 bool isImmXLenLI_Restricted() const {

672 int64_t Imm;

673 if (!isExpr())

674 return false;

675 bool IsConstantImm = evaluateConstantExpr(getExpr(), Imm);

676

677 return IsConstantImm &&

679 }

680

681 template bool isUImm() const {

682 int64_t Imm;

683 if (!isExpr())

684 return false;

685 bool IsConstantImm = evaluateConstantExpr(getExpr(), Imm);

686 return IsConstantImm && isUInt(Imm);

687 }

688

689 template <unsigned N, unsigned S> bool isUImmShifted() const {

690 int64_t Imm;

691 if (!isExpr())

692 return false;

693 bool IsConstantImm = evaluateConstantExpr(getExpr(), Imm);

695 }

696

697 template bool isUImmPred(Pred p) const {

698 int64_t Imm;

699 if (!isExpr())

700 return false;

701 bool IsConstantImm = evaluateConstantExpr(getExpr(), Imm);

702 return IsConstantImm && p(Imm);

703 }

704

705 bool isUImmLog2XLen() const {

706 if (isExpr() && isRV64Expr())

707 return isUImm<6>();

708 return isUImm<5>();

709 }

710

711 bool isUImmLog2XLenNonZero() const {

712 if (isExpr() && isRV64Expr())

713 return isUImmPred([](int64_t Imm) { return Imm != 0 && isUInt<6>(Imm); });

714 return isUImmPred([](int64_t Imm) { return Imm != 0 && isUInt<5>(Imm); });

715 }

716

717 bool isUImmLog2XLenHalf() const {

718 if (isExpr() && isRV64Expr())

719 return isUImm<5>();

720 return isUImm<4>();

721 }

722

723 bool isUImm1() const { return isUImm<1>(); }

724 bool isUImm2() const { return isUImm<2>(); }

725 bool isUImm3() const { return isUImm<3>(); }

726 bool isUImm4() const { return isUImm<4>(); }

727 bool isUImm5() const { return isUImm<5>(); }

728 bool isUImm6() const { return isUImm<6>(); }

729 bool isUImm7() const { return isUImm<7>(); }

730 bool isUImm8() const { return isUImm<8>(); }

731 bool isUImm9() const { return isUImm<9>(); }

732 bool isUImm10() const { return isUImm<10>(); }

733 bool isUImm11() const { return isUImm<11>(); }

734 bool isUImm16() const { return isUImm<16>(); }

735 bool isUImm20() const { return isUImm<20>(); }

736 bool isUImm32() const { return isUImm<32>(); }

737 bool isUImm48() const { return isUImm<48>(); }

738 bool isUImm64() const { return isUImm<64>(); }

739

740 bool isUImm5NonZero() const {

741 return isUImmPred([](int64_t Imm) { return Imm != 0 && isUInt<5>(Imm); });

742 }

743

744 bool isUImm5GT3() const {

745 return isUImmPred([](int64_t Imm) { return isUInt<5>(Imm) && Imm > 3; });

746 }

747

748 bool isUImm5Plus1() const {

749 return isUImmPred(

750 [](int64_t Imm) { return Imm > 0 && isUInt<5>(Imm - 1); });

751 }

752

753 bool isUImm5GE6Plus1() const {

754 return isUImmPred(

755 [](int64_t Imm) { return Imm >= 6 && isUInt<5>(Imm - 1); });

756 }

757

758 bool isUImm5Slist() const {

759 return isUImmPred([](int64_t Imm) {

760 return (Imm == 0) || (Imm == 1) || (Imm == 2) || (Imm == 4) ||

761 (Imm == 8) || (Imm == 16) || (Imm == 15) || (Imm == 31);

762 });

763 }

764

765 bool isUImm8GE32() const {

766 return isUImmPred([](int64_t Imm) { return isUInt<8>(Imm) && Imm >= 32; });

767 }

768

769 bool isRnumArg() const {

770 return isUImmPred(

771 [](int64_t Imm) { return Imm >= INT64_C(0) && Imm <= INT64_C(10); });

772 }

773

774 bool isRnumArg_0_7() const {

775 return isUImmPred(

776 [](int64_t Imm) { return Imm >= INT64_C(0) && Imm <= INT64_C(7); });

777 }

778

779 bool isRnumArg_1_10() const {

780 return isUImmPred(

781 [](int64_t Imm) { return Imm >= INT64_C(1) && Imm <= INT64_C(10); });

782 }

783

784 bool isRnumArg_2_14() const {

785 return isUImmPred(

786 [](int64_t Imm) { return Imm >= INT64_C(2) && Imm <= INT64_C(14); });

787 }

788

789 template bool isSImm() const {

790 int64_t Imm;

791 if (!isExpr())

792 return false;

793 bool IsConstantImm = evaluateConstantExpr(getExpr(), Imm);

794 return IsConstantImm && isInt(fixImmediateForRV32(Imm, isRV64Expr()));

795 }

796

797 template bool isSImmPred(Pred p) const {

798 int64_t Imm;

799 if (!isExpr())

800 return false;

801 bool IsConstantImm = evaluateConstantExpr(getExpr(), Imm);

802 return IsConstantImm && p(fixImmediateForRV32(Imm, isRV64Expr()));

803 }

804

805 bool isSImm5() const { return isSImm<5>(); }

806 bool isSImm6() const { return isSImm<6>(); }

807 bool isSImm10() const { return isSImm<10>(); }

808 bool isSImm11() const { return isSImm<11>(); }

809 bool isSImm12() const { return isSImm<12>(); }

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

811 bool isSImm26() const { return isSImm<26>(); }

812

813 bool isSImm5NonZero() const {

814 return isSImmPred([](int64_t Imm) { return Imm != 0 && isInt<5>(Imm); });

815 }

816

817 bool isSImm6NonZero() const {

818 return isSImmPred([](int64_t Imm) { return Imm != 0 && isInt<6>(Imm); });

819 }

820

821 bool isCLUIImm() const {

822 return isUImmPred([](int64_t Imm) {

823 return (isUInt<5>(Imm) && Imm != 0) || (Imm >= 0xfffe0 && Imm <= 0xfffff);

824 });

825 }

826

827 bool isUImm2Lsb0() const { return isUImmShifted<1, 1>(); }

828

829 bool isUImm5Lsb0() const { return isUImmShifted<4, 1>(); }

830

831 bool isUImm6Lsb0() const { return isUImmShifted<5, 1>(); }

832

833 bool isUImm7Lsb00() const { return isUImmShifted<5, 2>(); }

834

835 bool isUImm7Lsb000() const { return isUImmShifted<4, 3>(); }

836

837 bool isUImm8Lsb00() const { return isUImmShifted<6, 2>(); }

838

839 bool isUImm8Lsb000() const { return isUImmShifted<5, 3>(); }

840

841 bool isUImm9Lsb000() const { return isUImmShifted<6, 3>(); }

842

843 bool isUImm14Lsb00() const { return isUImmShifted<12, 2>(); }

844

845 bool isUImm10Lsb00NonZero() const {

846 return isUImmPred(

848 }

849

850

851

852 static int64_t fixImmediateForRV32(int64_t Imm, bool IsRV64Imm) {

854 return Imm;

856 }

857

858 bool isSImm12LO() const {

859 if (!isExpr())

860 return false;

861

862 int64_t Imm;

863 if (evaluateConstantExpr(getExpr(), Imm))

864 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));

865

867 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

869 VK == RISCV::S_TPREL_LO || VK == ELF::R_RISCV_TLSDESC_LOAD_LO12 ||

870 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);

871 }

872

873 bool isSImm12Lsb00000() const {

874 return isSImmPred([](int64_t Imm) { return isShiftedInt<7, 5>(Imm); });

875 }

876

877 bool isSImm10Lsb0000NonZero() const {

878 return isSImmPred(

880 }

881

882 bool isSImm16NonZero() const {

883 return isSImmPred([](int64_t Imm) { return Imm != 0 && isInt<16>(Imm); });

884 }

885

886 bool isUImm16NonZero() const {

887 return isUImmPred([](int64_t Imm) { return isUInt<16>(Imm) && Imm != 0; });

888 }

889

890 bool isSImm20LI() const {

891 if (!isExpr())

892 return false;

893

894 int64_t Imm;

895 if (evaluateConstantExpr(getExpr(), Imm))

896 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));

897

899 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

901 }

902

903 bool isSImm8Unsigned() const { return isSImm<8>() || isUImm<8>(); }

904 bool isSImm10Unsigned() const { return isSImm<10>() || isUImm<10>(); }

905

906 bool isUImm20LUI() const {

907 if (!isExpr())

908 return false;

909

910 int64_t Imm;

911 if (evaluateConstantExpr(getExpr(), Imm))

913

915 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

916 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);

917 }

918

919 bool isUImm20AUIPC() const {

920 if (!isExpr())

921 return false;

922

923 int64_t Imm;

924 if (evaluateConstantExpr(getExpr(), Imm))

926

928 return RISCVAsmParser::classifySymbolRef(getExpr(), VK) &&

929 (VK == ELF::R_RISCV_PCREL_HI20 || VK == ELF::R_RISCV_GOT_HI20 ||

930 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||

931 VK == ELF::R_RISCV_TLSDESC_HI20);

932 }

933

934 bool isImmZero() const {

935 return isUImmPred([](int64_t Imm) { return 0 == Imm; });

936 }

937

938 bool isImmThree() const {

939 return isUImmPred([](int64_t Imm) { return 3 == Imm; });

940 }

941

942 bool isImmFour() const {

943 return isUImmPred([](int64_t Imm) { return 4 == Imm; });

944 }

945

946 bool isImm5Zibi() const {

947 return isUImmPred(

948 [](int64_t Imm) { return (Imm != 0 && isUInt<5>(Imm)) || Imm == -1; });

949 }

950

951 bool isSImm5Plus1() const {

952 return isSImmPred(

954 }

955

956 bool isSImm18() const {

957 return isSImmPred([](int64_t Imm) { return isInt<18>(Imm); });

958 }

959

960 bool isSImm18Lsb0() const {

962 }

963

964 bool isSImm19Lsb00() const {

966 }

967

968 bool isSImm20Lsb000() const {

970 }

971

972 bool isSImm32Lsb0() const {

974 }

975

976

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

978

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

980

981

982 bool isRV64Expr() const {

983 assert(Kind == KindTy::Expression && "Invalid type access!");

984 return Expr.IsRV64;

985 }

986

987 MCRegister getReg() const override {

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

989 return Reg.Reg;

990 }

991

992 StringRef getSysReg() const {

993 assert(Kind == KindTy::SystemRegister && "Invalid type access!");

994 return StringRef(SysReg.Data, SysReg.Length);

995 }

996

997 const MCExpr *getExpr() const {

998 assert(Kind == KindTy::Expression && "Invalid type access!");

999 return Expr.Expr;

1000 }

1001

1002 uint64_t getFPConst() const {

1003 assert(Kind == KindTy::FPImmediate && "Invalid type access!");

1004 return FPImm.Val;

1005 }

1006

1007 StringRef getToken() const {

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

1009 return Tok;

1010 }

1011

1012 unsigned getVType() const {

1013 assert(Kind == KindTy::VType && "Invalid type access!");

1014 return VType.Val;

1015 }

1016

1018 assert(Kind == KindTy::FRM && "Invalid type access!");

1019 return FRM.FRM;

1020 }

1021

1022 unsigned getFence() const {

1023 assert(Kind == KindTy::Fence && "Invalid type access!");

1024 return Fence.Val;

1025 }

1026

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

1029 if (Reg)

1031 else

1032 return "noreg";

1033 };

1034

1035 switch (Kind) {

1036 case KindTy::Expression:

1037 OS << "<imm: ";

1039 OS << ' ' << (Expr.IsRV64 ? "rv64" : "rv32") << '>';

1040 break;

1041 case KindTy::FPImmediate:

1042 OS << "<fpimm: " << FPImm.Val << ">";

1043 break;

1044 case KindTy::Register:

1045 OS << "<reg: " << RegName(Reg.Reg) << " (" << Reg.Reg.id()

1046 << (Reg.IsGPRAsFPR ? ") GPRasFPR>" : ")>");

1047 break;

1048 case KindTy::Token:

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

1050 break;

1051 case KindTy::SystemRegister:

1052 OS << "<sysreg: " << getSysReg() << " (" << SysReg.Encoding << ")>";

1053 break;

1054 case KindTy::VType:

1055 OS << "<vtype: ";

1057 OS << '>';

1058 break;

1059 case KindTy::FRM:

1060 OS << "<frm: ";

1061 roundingModeToString(getFRM());

1062 OS << '>';

1063 break;

1064 case KindTy::Fence:

1065 OS << "<fence: ";

1066 OS << getFence();

1067 OS << '>';

1068 break;

1069 case KindTy::RegList:

1070 OS << "<reglist: ";

1072 OS << '>';

1073 break;

1074 case KindTy::StackAdj:

1075 OS << "<stackadj: ";

1076 OS << StackAdj.Val;

1077 OS << '>';

1078 break;

1079 case KindTy::RegReg:

1080 OS << "<RegReg: BaseReg " << RegName(RegReg.BaseReg) << " OffsetReg "

1082 break;

1083 }

1084 }

1085

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

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

1088 Op->Tok = Str;

1089 Op->StartLoc = S;

1090 Op->EndLoc = S;

1091 return Op;

1092 }

1093

1094 static std::unique_ptr

1095 createReg(MCRegister Reg, SMLoc S, SMLoc E, bool IsGPRAsFPR = false) {

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

1097 Op->Reg.Reg = Reg;

1098 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;

1099 Op->StartLoc = S;

1100 Op->EndLoc = E;

1101 return Op;

1102 }

1103

1104 static std::unique_ptr createExpr(const MCExpr *Val, SMLoc S,

1105 SMLoc E, bool IsRV64) {

1106 auto Op = std::make_unique(KindTy::Expression);

1107 Op->Expr.Expr = Val;

1108 Op->Expr.IsRV64 = IsRV64;

1109 Op->StartLoc = S;

1110 Op->EndLoc = E;

1111 return Op;

1112 }

1113

1114 static std::unique_ptr createFPImm(uint64_t Val, SMLoc S) {

1115 auto Op = std::make_unique(KindTy::FPImmediate);

1116 Op->FPImm.Val = Val;

1117 Op->StartLoc = S;

1118 Op->EndLoc = S;

1119 return Op;

1120 }

1121

1122 static std::unique_ptr createSysReg(StringRef Str, SMLoc S,

1123 unsigned Encoding) {

1124 auto Op = std::make_unique(KindTy::SystemRegister);

1125 Op->SysReg.Data = Str.data();

1126 Op->SysReg.Length = Str.size();

1128 Op->StartLoc = S;

1129 Op->EndLoc = S;

1130 return Op;

1131 }

1132

1133 static std::unique_ptr

1135 auto Op = std::make_unique(KindTy::FRM);

1136 Op->FRM.FRM = FRM;

1137 Op->StartLoc = S;

1138 Op->EndLoc = S;

1139 return Op;

1140 }

1141

1142 static std::unique_ptr createFenceArg(unsigned Val, SMLoc S) {

1143 auto Op = std::make_unique(KindTy::Fence);

1144 Op->Fence.Val = Val;

1145 Op->StartLoc = S;

1146 Op->EndLoc = S;

1147 return Op;

1148 }

1149

1150 static std::unique_ptr createVType(unsigned VTypeI, SMLoc S) {

1151 auto Op = std::make_unique(KindTy::VType);

1152 Op->VType.Val = VTypeI;

1153 Op->StartLoc = S;

1154 Op->EndLoc = S;

1155 return Op;

1156 }

1157

1158 static std::unique_ptr createRegList(unsigned RlistEncode,

1159 SMLoc S) {

1160 auto Op = std::make_unique(KindTy::RegList);

1162 Op->StartLoc = S;

1163 return Op;

1164 }

1165

1166 static std::unique_ptr

1167 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {

1168 auto Op = std::make_unique(KindTy::RegReg);

1170 Op->RegReg.OffsetReg = OffsetReg;

1171 Op->StartLoc = S;

1172 Op->EndLoc = S;

1173 return Op;

1174 }

1175

1176 static std::unique_ptr createStackAdj(unsigned StackAdj, SMLoc S) {

1177 auto Op = std::make_unique(KindTy::StackAdj);

1178 Op->StackAdj.Val = StackAdj;

1179 Op->StartLoc = S;

1180 return Op;

1181 }

1182

1183 static void addExpr(MCInst &Inst, const MCExpr *Expr, bool IsRV64Imm) {

1184 assert(Expr && "Expr shouldn't be null!");

1185 int64_t Imm = 0;

1186 bool IsConstant = evaluateConstantExpr(Expr, Imm);

1187

1188 if (IsConstant)

1191 else

1193 }

1194

1195

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

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

1199 }

1200

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

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

1203 addExpr(Inst, getExpr(), isRV64Expr());

1204 }

1205

1206 void addSImm8UnsignedOperands(MCInst &Inst, unsigned N) const {

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

1208 int64_t Imm;

1209 [[maybe_unused]] bool IsConstant = evaluateConstantExpr(getExpr(), Imm);

1212 }

1213

1214 void addSImm10UnsignedOperands(MCInst &Inst, unsigned N) const {

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

1216 int64_t Imm;

1217 [[maybe_unused]] bool IsConstant = evaluateConstantExpr(getExpr(), Imm);

1220 }

1221

1222 void addFPImmOperands(MCInst &Inst, unsigned N) const {

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

1224 if (isExpr()) {

1225 addExpr(Inst, getExpr(), isRV64Expr());

1226 return;

1227 }

1228

1230 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));

1232 }

1233

1234 void addFenceArgOperands(MCInst &Inst, unsigned N) const {

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

1237 }

1238

1239 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {

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

1242 }

1243

1244

1245

1246

1247 void addVTypeIOperands(MCInst &Inst, unsigned N) const {

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

1249 int64_t Imm = 0;

1250 if (Kind == KindTy::Expression) {

1251 [[maybe_unused]] bool IsConstantImm =

1252 evaluateConstantExpr(getExpr(), Imm);

1253 assert(IsConstantImm && "Invalid VTypeI Operand!");

1254 } else {

1255 Imm = getVType();

1256 }

1258 }

1259

1260 void addRegListOperands(MCInst &Inst, unsigned N) const {

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

1263 }

1264

1265 void addRegRegOperands(MCInst &Inst, unsigned N) const {

1266 assert(N == 2 && "Invalid number of operands!");

1269 }

1270

1271 void addStackAdjOperands(MCInst &Inst, unsigned N) const {

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

1274 }

1275

1276 void addFRMArgOperands(MCInst &Inst, unsigned N) const {

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

1279 }

1280};

1281}

1282

1283#define GET_REGISTER_MATCHER

1284#define GET_SUBTARGET_FEATURE_NAME

1285#define GET_MATCHER_IMPLEMENTATION

1286#define GET_MNEMONIC_SPELL_CHECKER

1287#include "RISCVGenAsmMatcher.inc"

1288

1290 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");

1291 return Reg - RISCV::F0_D + RISCV::F0_H;

1292}

1293

1295 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");

1296 return Reg - RISCV::F0_D + RISCV::F0_F;

1297}

1298

1300 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");

1301 return Reg - RISCV::F0_D + RISCV::F0_Q;

1302}

1303

1305 unsigned Kind) {

1306 unsigned RegClassID;

1307 if (Kind == MCK_VRM2)

1308 RegClassID = RISCV::VRM2RegClassID;

1309 else if (Kind == MCK_VRM4)

1310 RegClassID = RISCV::VRM4RegClassID;

1311 else if (Kind == MCK_VRM8)

1312 RegClassID = RISCV::VRM8RegClassID;

1313 else

1316 &RISCVMCRegisterClasses[RegClassID]);

1317}

1318

1319unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,

1320 unsigned Kind) {

1321 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);

1322 if (Op.isReg())

1323 return Match_InvalidOperand;

1324

1325 MCRegister Reg = Op.getReg();

1326 bool IsRegFPR64 =

1327 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg);

1328 bool IsRegFPR64C =

1329 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);

1330 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg);

1331

1332 if (IsRegFPR64 && Kind == MCK_FPR128) {

1334 return Match_Success;

1335 }

1336

1337

1338 if ((IsRegFPR64 && Kind == MCK_FPR32) ||

1339 (IsRegFPR64C && Kind == MCK_FPR32C)) {

1341 return Match_Success;

1342 }

1343

1344

1345 if (IsRegFPR64 && Kind == MCK_FPR16) {

1347 return Match_Success;

1348 }

1349 if (Kind == MCK_GPRAsFPR16 && Op.isGPRAsFPR()) {

1350 Op.Reg.Reg = Reg - RISCV::X0 + RISCV::X0_H;

1351 return Match_Success;

1352 }

1353 if (Kind == MCK_GPRAsFPR32 && Op.isGPRAsFPR()) {

1354 Op.Reg.Reg = Reg - RISCV::X0 + RISCV::X0_W;

1355 return Match_Success;

1356 }

1357

1358

1359

1360

1361

1362 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg) &&

1363 Kind == MCK_GPRF64AsFPR && STI->hasFeature(RISCV::FeatureStdExtZdinx) &&

1364 !isRV64())

1365 return Match_Success;

1366

1367

1368

1369 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {

1371 if (Op.Reg.Reg)

1372 return Match_InvalidOperand;

1373 return Match_Success;

1374 }

1375 return Match_InvalidOperand;

1376}

1377

1378bool RISCVAsmParser::generateImmOutOfRangeError(

1379 SMLoc ErrorLoc, int64_t Lower, int64_t Upper,

1380 const Twine &Msg = "immediate must be an integer in the range") {

1381 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");

1382}

1383

1384bool RISCVAsmParser::generateImmOutOfRangeError(

1386 const Twine &Msg = "immediate must be an integer in the range") {

1387 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();

1388 return generateImmOutOfRangeError(ErrorLoc, Lower, Upper, Msg);

1389}

1390

1391bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

1393 MCStreamer &Out,

1394 uint64_t &ErrorInfo,

1395 bool MatchingInlineAsm) {

1396 MCInst Inst;

1397 FeatureBitset MissingFeatures;

1398

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

1400 MatchingInlineAsm);

1401 switch (Result) {

1402 default:

1403 break;

1404 case Match_Success:

1405 if (validateInstruction(Inst, Operands))

1406 return true;

1407 return processInstruction(Inst, IDLoc, Operands, Out);

1408 case Match_MissingFeature: {

1409 assert(MissingFeatures.any() && "Unknown missing features!");

1410 bool FirstFeature = true;

1411 std::string Msg = "instruction requires the following:";

1412 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {

1413 if (MissingFeatures[i]) {

1414 Msg += FirstFeature ? " " : ", ";

1416 FirstFeature = false;

1417 }

1418 }

1419 return Error(IDLoc, Msg);

1420 }

1421 case Match_MnemonicFail: {

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

1423 std::string Suggestion = RISCVMnemonicSpellCheck(

1424 ((RISCVOperand &)*Operands[0]).getToken(), FBS, 0);

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

1426 }

1427 case Match_InvalidOperand: {

1428 SMLoc ErrorLoc = IDLoc;

1429 if (ErrorInfo != ~0ULL) {

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

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

1432

1433 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();

1434 if (ErrorLoc == SMLoc())

1435 ErrorLoc = IDLoc;

1436 }

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

1438 }

1439 }

1440

1441

1442

1443

1444 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {

1445 SMLoc ErrorLoc = IDLoc;

1446 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.size())

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

1448 }

1449

1450 switch (Result) {

1451 default:

1452 break;

1453 case Match_InvalidImmXLenLI:

1454 if (isRV64()) {

1455 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();

1456 return Error(ErrorLoc, "operand must be a constant 64-bit integer");

1457 }

1458 return generateImmOutOfRangeError(Operands, ErrorInfo,

1459 std::numeric_limits<int32_t>::min(),

1460 std::numeric_limits<uint32_t>::max());

1461 case Match_InvalidImmXLenLI_Restricted:

1462 if (isRV64()) {

1463 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();

1464 return Error(ErrorLoc, "operand either must be a constant 64-bit integer "

1465 "or a bare symbol name");

1466 }

1467 return generateImmOutOfRangeError(

1468 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),

1469 std::numeric_limits<uint32_t>::max(),

1470 "operand either must be a bare symbol name or an immediate integer in "

1471 "the range");

1472 case Match_InvalidUImmLog2XLen:

1473 if (isRV64())

1474 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);

1475 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);

1476 case Match_InvalidUImmLog2XLenNonZero:

1477 if (isRV64())

1478 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);

1479 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);

1480 case Match_InvalidUImm1:

1481 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);

1482 case Match_InvalidUImm2:

1483 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);

1484 case Match_InvalidUImm2Lsb0:

1485 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,

1486 "immediate must be one of");

1487 case Match_InvalidUImm3:

1488 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);

1489 case Match_InvalidUImm4:

1490 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);

1491 case Match_InvalidUImm5:

1492 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);

1493 case Match_InvalidUImm5NonZero:

1494 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);

1495 case Match_InvalidUImm5GT3:

1496 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);

1497 case Match_InvalidUImm5Plus1:

1498 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));

1499 case Match_InvalidUImm5GE6Plus1:

1500 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));

1501 case Match_InvalidUImm5Slist: {

1502 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();

1503 return Error(ErrorLoc,

1504 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");

1505 }

1506 case Match_InvalidUImm6:

1507 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);

1508 case Match_InvalidUImm7:

1509 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);

1510 case Match_InvalidUImm8:

1511 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);

1512 case Match_InvalidUImm8GE32:

1513 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);

1514 case Match_InvalidSImm5:

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

1516 (1 << 4) - 1);

1517 case Match_InvalidSImm5NonZero:

1518 return generateImmOutOfRangeError(

1519 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,

1520 "immediate must be non-zero in the range");

1521 case Match_InvalidSImm6:

1522 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),

1523 (1 << 5) - 1);

1524 case Match_InvalidSImm6NonZero:

1525 return generateImmOutOfRangeError(

1526 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,

1527 "immediate must be non-zero in the range");

1528 case Match_InvalidCLUIImm:

1529 return generateImmOutOfRangeError(

1530 Operands, ErrorInfo, 1, (1 << 5) - 1,

1531 "immediate must be in [0xfffe0, 0xfffff] or");

1532 case Match_InvalidUImm5Lsb0:

1533 return generateImmOutOfRangeError(

1534 Operands, ErrorInfo, 0, (1 << 5) - 2,

1535 "immediate must be a multiple of 2 bytes in the range");

1536 case Match_InvalidUImm6Lsb0:

1537 return generateImmOutOfRangeError(

1538 Operands, ErrorInfo, 0, (1 << 6) - 2,

1539 "immediate must be a multiple of 2 bytes in the range");

1540 case Match_InvalidUImm7Lsb00:

1541 return generateImmOutOfRangeError(

1542 Operands, ErrorInfo, 0, (1 << 7) - 4,

1543 "immediate must be a multiple of 4 bytes in the range");

1544 case Match_InvalidUImm8Lsb00:

1545 return generateImmOutOfRangeError(

1546 Operands, ErrorInfo, 0, (1 << 8) - 4,

1547 "immediate must be a multiple of 4 bytes in the range");

1548 case Match_InvalidUImm8Lsb000:

1549 return generateImmOutOfRangeError(

1550 Operands, ErrorInfo, 0, (1 << 8) - 8,

1551 "immediate must be a multiple of 8 bytes in the range");

1552 case Match_InvalidUImm9:

1553 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,

1554 "immediate offset must be in the range");

1555 case Match_InvalidBareSImm9Lsb0:

1556 return generateImmOutOfRangeError(

1557 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,

1558 "immediate must be a multiple of 2 bytes in the range");

1559 case Match_InvalidUImm9Lsb000:

1560 return generateImmOutOfRangeError(

1561 Operands, ErrorInfo, 0, (1 << 9) - 8,

1562 "immediate must be a multiple of 8 bytes in the range");

1563 case Match_InvalidSImm8Unsigned:

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

1565 (1 << 8) - 1);

1566 case Match_InvalidSImm10:

1567 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),

1568 (1 << 9) - 1);

1569 case Match_InvalidSImm10Unsigned:

1570 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),

1571 (1 << 10) - 1);

1572 case Match_InvalidUImm10Lsb00NonZero:

1573 return generateImmOutOfRangeError(

1574 Operands, ErrorInfo, 4, (1 << 10) - 4,

1575 "immediate must be a multiple of 4 bytes in the range");

1576 case Match_InvalidSImm10Lsb0000NonZero:

1577 return generateImmOutOfRangeError(

1578 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,

1579 "immediate must be a multiple of 16 bytes and non-zero in the range");

1580 case Match_InvalidSImm11:

1581 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),

1582 (1 << 10) - 1);

1583 case Match_InvalidBareSImm11Lsb0:

1584 return generateImmOutOfRangeError(

1585 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,

1586 "immediate must be a multiple of 2 bytes in the range");

1587 case Match_InvalidUImm10:

1588 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);

1589 case Match_InvalidUImm11:

1590 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);

1591 case Match_InvalidUImm14Lsb00:

1592 return generateImmOutOfRangeError(

1593 Operands, ErrorInfo, 0, (1 << 14) - 4,

1594 "immediate must be a multiple of 4 bytes in the range");

1595 case Match_InvalidUImm16NonZero:

1596 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);

1597 case Match_InvalidSImm12:

1598 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),

1599 (1 << 11) - 1);

1600 case Match_InvalidSImm12LO:

1601 return generateImmOutOfRangeError(

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

1603 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "

1604 "integer in the range");

1605 case Match_InvalidBareSImm12Lsb0:

1606 return generateImmOutOfRangeError(

1607 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,

1608 "immediate must be a multiple of 2 bytes in the range");

1609 case Match_InvalidSImm12Lsb00000:

1610 return generateImmOutOfRangeError(

1611 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,

1612 "immediate must be a multiple of 32 bytes in the range");

1613 case Match_InvalidBareSImm13Lsb0:

1614 return generateImmOutOfRangeError(

1615 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,

1616 "immediate must be a multiple of 2 bytes in the range");

1617 case Match_InvalidSImm16:

1618 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),

1619 (1 << 15) - 1);

1620 case Match_InvalidSImm16NonZero:

1621 return generateImmOutOfRangeError(

1622 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,

1623 "immediate must be non-zero in the range");

1624 case Match_InvalidSImm20LI:

1625 return generateImmOutOfRangeError(

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

1627 "operand must be a symbol with a %qc.abs20 specifier or an integer "

1628 " in the range");

1629 case Match_InvalidUImm20LUI:

1630 return generateImmOutOfRangeError(

1631 Operands, ErrorInfo, 0, (1 << 20) - 1,

1632 "operand must be a symbol with "

1633 "%hi/%tprel_hi specifier or an integer in "

1634 "the range");

1635 case Match_InvalidUImm20:

1636 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);

1637 case Match_InvalidUImm20AUIPC:

1638 return generateImmOutOfRangeError(

1639 Operands, ErrorInfo, 0, (1 << 20) - 1,

1640 "operand must be a symbol with a "

1641 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "

1642 "or "

1643 "an integer in the range");

1644 case Match_InvalidBareSImm21Lsb0:

1645 return generateImmOutOfRangeError(

1646 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,

1647 "immediate must be a multiple of 2 bytes in the range");

1648 case Match_InvalidCSRSystemRegister: {

1649 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,

1650 "operand must be a valid system register "

1651 "name or an integer in the range");

1652 }

1653 case Match_InvalidImm5Zibi:

1654 return generateImmOutOfRangeError(

1655 Operands, ErrorInfo, -1, (1 << 5) - 1,

1656 "immediate must be non-zero in the range");

1657 case Match_InvalidVTypeI: {

1658 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();

1659 return generateVTypeError(ErrorLoc);

1660 }

1661 case Match_InvalidSImm5Plus1: {

1662 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,

1663 (1 << 4),

1664 "immediate must be in the range");

1665 }

1666 case Match_InvalidSImm18:

1667 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),

1668 (1 << 17) - 1);

1669 case Match_InvalidSImm18Lsb0:

1670 return generateImmOutOfRangeError(

1671 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,

1672 "immediate must be a multiple of 2 bytes in the range");

1673 case Match_InvalidSImm19Lsb00:

1674 return generateImmOutOfRangeError(

1675 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,

1676 "immediate must be a multiple of 4 bytes in the range");

1677 case Match_InvalidSImm20Lsb000:

1678 return generateImmOutOfRangeError(

1679 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,

1680 "immediate must be a multiple of 8 bytes in the range");

1681 case Match_InvalidSImm26:

1682 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),

1683 (1 << 25) - 1);

1684

1685 case Match_InvalidBareSymbolQC_E_LI:

1686 [[fallthrough]];

1687

1688 case Match_InvalidBareSImm32:

1689 return generateImmOutOfRangeError(Operands, ErrorInfo,

1690 std::numeric_limits<int32_t>::min(),

1691 std::numeric_limits<uint32_t>::max());

1692 case Match_InvalidBareSImm32Lsb0:

1693 return generateImmOutOfRangeError(

1694 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),

1695 std::numeric_limits<int32_t>::max() - 1,

1696 "operand must be a multiple of 2 bytes in the range");

1697 case Match_InvalidRnumArg: {

1698 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);

1699 }

1700 case Match_InvalidStackAdj: {

1701 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();

1703 ErrorLoc,

1704 "stack adjustment is invalid for this instruction and register list");

1705 }

1706 }

1707

1708 if (const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {

1709 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();

1710 return Error(ErrorLoc, MatchDiag);

1711 }

1712

1714}

1715

1716

1717

1718

1719

1720MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name) const {

1722

1723

1724

1725 assert(!(Reg >= RISCV::F0_H && Reg <= RISCV::F31_H));

1726 assert(!(Reg >= RISCV::F0_F && Reg <= RISCV::F31_F));

1727 assert(!(Reg >= RISCV::F0_Q && Reg <= RISCV::F31_Q));

1728

1729 static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated");

1730 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");

1731 static_assert(RISCV::F0_D < RISCV::F0_Q, "FPR matching must be updated");

1732 if (Reg)

1734 if (isRVE() && Reg >= RISCV::X16 && Reg <= RISCV::X31)

1735 Reg = MCRegister();

1736 return Reg;

1737}

1738

1739bool RISCVAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,

1740 SMLoc &EndLoc) {

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

1742 return Error(StartLoc, "invalid register name");

1743 return false;

1744}

1745

1746ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

1747 SMLoc &EndLoc) {

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

1749 StartLoc = Tok.getLoc();

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

1752

1754 if (Reg)

1756

1757 getParser().Lex();

1759}

1760

1761ParseStatus RISCVAsmParser::parseRegister(OperandVector &Operands,

1762 bool AllowParens) {

1763 SMLoc FirstS = getLoc();

1764 bool HadParens = false;

1765 AsmToken LParen;

1766

1767

1768

1770 AsmToken Buf[2];

1771 size_t ReadCount = getLexer().peekTokens(Buf);

1772 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {

1773 HadParens = true;

1774 LParen = getParser().getTok();

1775 getParser().Lex();

1776 }

1777 }

1778

1779 switch (getLexer().getKind()) {

1780 default:

1781 if (HadParens)

1782 getLexer().UnLex(LParen);

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

1787

1788 if (Reg) {

1789 if (HadParens)

1790 getLexer().UnLex(LParen);

1792 }

1793 if (HadParens)

1794 Operands.push_back(RISCVOperand::createToken("(", FirstS));

1795 SMLoc S = getLoc();

1796 SMLoc E = getTok().getEndLoc();

1797 getLexer().Lex();

1798 Operands.push_back(RISCVOperand::createReg(Reg, S, E));

1799 }

1800

1801 if (HadParens) {

1802 getParser().Lex();

1803 Operands.push_back(RISCVOperand::createToken(")", getLoc()));

1804 }

1805

1807}

1808

1809ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(OperandVector &Operands) {

1810 SMLoc S = getLoc();

1811 SMLoc E;

1812 const MCExpr *Res;

1813

1814 switch (getLexer().getKind()) {

1815 default:

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

1826

1828 if (CE) {

1829 int64_t Imm = CE->getValue();

1831 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

1833 }

1834 }

1835

1836 break;

1837 }

1840 if (getParser().parseIdentifier(Identifier))

1842

1843 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);

1844 if (Opcode) {

1845 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&

1846 "Unexpected opcode");

1849 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

1851 }

1852

1853 break;

1854 }

1856 break;

1857 }

1858

1859 return generateImmOutOfRangeError(

1860 S, 0, 127,

1861 "opcode must be a valid opcode name or an immediate in the range");

1862}

1863

1864ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(OperandVector &Operands) {

1865 SMLoc S = getLoc();

1866 SMLoc E;

1867 const MCExpr *Res;

1868

1869 switch (getLexer().getKind()) {

1870 default:

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

1881

1883 if (CE) {

1884 int64_t Imm = CE->getValue();

1885 if (Imm >= 0 && Imm <= 2) {

1886 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

1888 }

1889 }

1890

1891 break;

1892 }

1895 if (getParser().parseIdentifier(Identifier))

1897

1898 unsigned Opcode;

1899 if (Identifier == "C0")

1900 Opcode = 0;

1901 else if (Identifier == "C1")

1902 Opcode = 1;

1903 else if (Identifier == "C2")

1904 Opcode = 2;

1905 else

1906 break;

1907

1910 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

1912 }

1914

1915 break;

1916 }

1917 }

1918

1919 return generateImmOutOfRangeError(

1920 S, 0, 2,

1921 "opcode must be a valid opcode name or an immediate in the range");

1922}

1923

1924ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {

1925 SMLoc S = getLoc();

1926 const MCExpr *Res;

1927

1928 auto SysRegFromConstantInt = [this](const MCExpr *E, SMLoc S) {

1930 int64_t Imm = CE->getValue();

1932 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);

1933

1934

1936 if (Reg.IsAltName || Reg.IsDeprecatedName)

1937 continue;

1939 return RISCVOperand::createSysReg(Reg.Name, S, Imm);

1940 }

1941

1942

1943 return RISCVOperand::createSysReg("", S, Imm);

1944 }

1945 }

1946 return std::unique_ptr();

1947 };

1948

1949 switch (getLexer().getKind()) {

1950 default:

1959 if (getParser().parseExpression(Res))

1961

1962 if (auto SysOpnd = SysRegFromConstantInt(Res, S)) {

1963 Operands.push_back(std::move(SysOpnd));

1965 }

1966

1967 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);

1968 }

1971 if (getParser().parseIdentifier(Identifier))

1973

1974 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);

1975

1976 if (SysReg) {

1977 if (SysReg->IsDeprecatedName) {

1978

1979 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);

1981 if (Reg.IsAltName || Reg.IsDeprecatedName)

1982 continue;

1983 Warning(S, "'" + Identifier + "' is a deprecated alias for '" +

1984 Reg.Name + "'");

1985 }

1986 }

1987

1988

1989 const auto &FeatureBits = getSTI().getFeatureBits();

1990 if (!SysReg->haveRequiredFeatures(FeatureBits)) {

1992 return SysReg->FeaturesRequired[Feature.Value];

1993 });

1994 auto ErrorMsg = std::string("system register '") + SysReg->Name + "' ";

1995 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {

1996 ErrorMsg += "is RV32 only";

1998 ErrorMsg += " and ";

1999 }

2001 ErrorMsg +=

2002 "requires '" + std::string(Feature->Key) + "' to be enabled";

2003 }

2004

2005 return Error(S, ErrorMsg);

2006 }

2008 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));

2010 }

2011

2012

2015

2016

2017 if (auto SysOpnd = SysRegFromConstantInt(Sym->getVariableValue(), S)) {

2018 Operands.push_back(std::move(SysOpnd));

2020 }

2021 }

2022

2023 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,

2024 "operand must be a valid system register "

2025 "name or an integer in the range");

2026 }

2028

2029 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);

2030 }

2031 }

2032

2034}

2035

2036ParseStatus RISCVAsmParser::parseFPImm(OperandVector &Operands) {

2037 SMLoc S = getLoc();

2038

2039

2041 StringRef Identifier = getTok().getIdentifier();

2042 if (Identifier.compare_insensitive("inf") == 0) {

2045 getTok().getEndLoc(), isRV64()));

2046 } else if (Identifier.compare_insensitive("nan") == 0) {

2049 getTok().getEndLoc(), isRV64()));

2050 } else if (Identifier.compare_insensitive("min") == 0) {

2053 getTok().getEndLoc(), isRV64()));

2054 } else {

2055 return TokError("invalid floating point literal");

2056 }

2057

2058 Lex();

2059

2061 }

2062

2063

2065

2066 const AsmToken &Tok = getTok();

2068 return TokError("invalid floating point immediate");

2069

2070

2071 APFloat RealVal(APFloat::IEEEdouble());

2072 auto StatusOrErr =

2073 RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero);

2074 if (errorToBool(StatusOrErr.takeError()))

2075 return TokError("invalid floating point representation");

2076

2077 if (IsNegative)

2078 RealVal.changeSign();

2079

2080 Operands.push_back(RISCVOperand::createFPImm(

2081 RealVal.bitcastToAPInt().getZExtValue(), S));

2082

2083 Lex();

2084

2086}

2087

2088ParseStatus RISCVAsmParser::parseExpression(OperandVector &Operands) {

2089 SMLoc S = getLoc();

2090 SMLoc E;

2091 const MCExpr *Res;

2092

2093 switch (getLexer().getKind()) {

2094 default:

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

2107 break;

2109 return parseOperandWithSpecifier(Operands);

2110 }

2111

2112 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

2114}

2115

2116ParseStatus RISCVAsmParser::parseOperandWithSpecifier(OperandVector &Operands) {

2117 SMLoc S = getLoc();

2118 SMLoc E;

2119

2120 if (parseToken(AsmToken::Percent, "expected '%' relocation specifier"))

2122 const MCExpr *Expr = nullptr;

2123 bool Failed = parseExprWithSpecifier(Expr, E);

2125 Operands.push_back(RISCVOperand::createExpr(Expr, S, E, isRV64()));

2127}

2128

2129bool RISCVAsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) {

2130 SMLoc Loc = getLoc();

2132 return TokError("expected '%' relocation specifier");

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

2135 if (!Spec)

2136 return TokError("invalid relocation specifier");

2137

2138 getParser().Lex();

2140 return true;

2141

2142 const MCExpr *SubExpr;

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

2144 return true;

2145

2147 return false;

2148}

2149

2150bool RISCVAsmParser::parseDataExpr(const MCExpr *&Res) {

2151 SMLoc E;

2153 return parseExprWithSpecifier(Res, E);

2154 return getParser().parseExpression(Res);

2155}

2156

2157ParseStatus RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {

2158 SMLoc S = getLoc();

2159 const MCExpr *Res;

2160

2163

2165 AsmToken Tok = getLexer().getTok();

2166

2167 if (getParser().parseIdentifier(Identifier))

2169

2171

2173

2177 getLexer().UnLex(Tok);

2179 }

2180 Res = V;

2181 } else

2183

2185 switch (getLexer().getKind()) {

2186 default:

2187 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

2191 getLexer().Lex();

2192 break;

2195 getLexer().Lex();

2196 break;

2197 }

2198

2199 const MCExpr *Expr;

2200 if (getParser().parseExpression(Expr, E))

2203 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

2205}

2206

2207ParseStatus RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {

2208 SMLoc S = getLoc();

2209 const MCExpr *Res;

2210

2213 std::string Identifier(getTok().getIdentifier());

2214

2215 if (getLexer().peekTok().is(AsmToken::At)) {

2216 Lex();

2217 Lex();

2218 StringRef PLT;

2219 SMLoc Loc = getLoc();

2220 if (getParser().parseIdentifier(PLT) || PLT != "plt")

2221 return Error(Loc, "@ (except the deprecated/ignored @plt) is disallowed");

2223

2225 } else {

2226 Lex();

2227 }

2228

2231

2235 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

2237}

2238

2239ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) {

2240 SMLoc S = getLoc();

2241 SMLoc E;

2242 const MCExpr *Res;

2243

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

2246

2247 if (Res->getKind() != MCExpr::ExprKind::SymbolRef)

2248 return Error(S, "operand must be a valid jump target");

2249

2251 Operands.push_back(RISCVOperand::createExpr(Res, S, E, isRV64()));

2253}

2254

2255ParseStatus RISCVAsmParser::parseJALOffset(OperandVector &Operands) {

2256

2257

2258

2259

2260

2261

2262

2263

2264

2268

2269 return parseExpression(Operands);

2270}

2271

2272bool RISCVAsmParser::parseVTypeToken(const AsmToken &Tok, VTypeState &State,

2273 unsigned &Sew, unsigned &Lmul,

2274 bool &Fractional, bool &TailAgnostic,

2275 bool &MaskAgnostic, bool &AltFmt) {

2277 return true;

2278

2280 if (State < VTypeState::SeenSew && Identifier.consume_front("e")) {

2281 if (Identifier.getAsInteger(10, Sew)) {

2282 if (Identifier == "16alt") {

2284 Sew = 16;

2285 } else if (Identifier == "8alt") {

2287 Sew = 8;

2288 } else {

2289 return true;

2290 }

2291 }

2293 return true;

2294

2295 State = VTypeState::SeenSew;

2296 return false;

2297 }

2298

2299 if (State < VTypeState::SeenLmul && Identifier.consume_front("m")) {

2300

2301

2302 if (Identifier == "a" || Identifier == "u") {

2304 State = VTypeState::SeenMaskPolicy;

2305 return false;

2306 }

2307

2308 Fractional = Identifier.consume_front("f");

2309 if (Identifier.getAsInteger(10, Lmul))

2310 return true;

2312 return true;

2313

2314 if (Fractional) {

2315 unsigned ELEN = STI->hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;

2316 unsigned MinLMUL = ELEN / 8;

2317 if (Lmul > MinLMUL)

2319 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +

2320 Twine(MinLMUL) + " is reserved");

2321 }

2322

2323 State = VTypeState::SeenLmul;

2324 return false;

2325 }

2326

2327 if (State < VTypeState::SeenTailPolicy && Identifier.starts_with("t")) {

2328 if (Identifier == "ta")

2329 TailAgnostic = true;

2330 else if (Identifier == "tu")

2331 TailAgnostic = false;

2332 else

2333 return true;

2334

2335 State = VTypeState::SeenTailPolicy;

2336 return false;

2337 }

2338

2339 if (State < VTypeState::SeenMaskPolicy && Identifier.starts_with("m")) {

2340 if (Identifier == "ma")

2341 MaskAgnostic = true;

2342 else if (Identifier == "mu")

2343 MaskAgnostic = false;

2344 else

2345 return true;

2346

2347 State = VTypeState::SeenMaskPolicy;

2348 return false;

2349 }

2350

2351 return true;

2352}

2353

2354ParseStatus RISCVAsmParser::parseVTypeI(OperandVector &Operands) {

2355 SMLoc S = getLoc();

2356

2357

2358 unsigned Sew = 8;

2359 unsigned Lmul = 1;

2360 bool Fractional = false;

2361 bool TailAgnostic = false;

2362 bool MaskAgnostic = false;

2363 bool AltFmt = false;

2364

2365 VTypeState State = VTypeState::SeenNothingYet;

2366 do {

2367 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,

2368 MaskAgnostic, AltFmt)) {

2369

2370 if (State == VTypeState::SeenNothingYet)

2372 break;

2373 }

2374

2375 getLexer().Lex();

2377

2379 State == VTypeState::SeenNothingYet)

2380 return generateVTypeError(S);

2381

2383 if (Fractional) {

2384 unsigned ELEN = STI->hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;

2385 unsigned MaxSEW = ELEN / Lmul;

2386

2387 if (MaxSEW >= 8 && Sew > MaxSEW)

2388 Warning(S, "use of vtype encodings with SEW > " + Twine(MaxSEW) +

2389 " and LMUL == mf" + Twine(Lmul) +

2390 " may not be compatible with all RVV implementations");

2391 }

2392

2393 unsigned VTypeI =

2395 Operands.push_back(RISCVOperand::createVType(VTypeI, S));

2397}

2398

2399bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {

2400 if (STI->hasFeature(RISCV::FeatureStdExtZvfbfa) ||

2401 STI->hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))

2403 ErrorLoc,

2404 "operand must be "

2405 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");

2407 ErrorLoc,

2408 "operand must be "

2409 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");

2410}

2411

2412ParseStatus RISCVAsmParser::parseXSfmmVType(OperandVector &Operands) {

2413 SMLoc S = getLoc();

2414

2415 unsigned Widen = 0;

2416 unsigned SEW = 0;

2417 bool AltFmt = false;

2419

2422

2423 Identifier = getTok().getIdentifier();

2424

2427

2428 if (Identifier.getAsInteger(10, SEW)) {

2429 if (Identifier != "16alt")

2431

2433 SEW = 16;

2434 }

2437

2438 Lex();

2439

2442

2445

2446 Identifier = getTok().getIdentifier();

2447

2454

2455 Lex();

2456

2458 Operands.push_back(RISCVOperand::createVType(

2461 }

2462

2464 return generateXSfmmVTypeError(S);

2465}

2466

2467bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {

2468 return Error(ErrorLoc, "operand must be e[8|16|16alt|32|64],w[1|2|4]");

2469}

2470

2471ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) {

2474

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

2476 if (Name.consume_back(".t"))

2477 return Error(getLoc(), "expected '.t' suffix");

2479

2480 if (Reg)

2482 if (Reg != RISCV::V0)

2484 SMLoc S = getLoc();

2485 SMLoc E = getTok().getEndLoc();

2486 getLexer().Lex();

2487 Operands.push_back(RISCVOperand::createReg(Reg, S, E));

2489}

2490

2491ParseStatus RISCVAsmParser::parseGPRAsFPR64(OperandVector &Operands) {

2492 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))

2494

2495 return parseGPRAsFPR(Operands);

2496}

2497

2498ParseStatus RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {

2501

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

2504

2505 if (Reg)

2507 SMLoc S = getLoc();

2508 SMLoc E = getTok().getEndLoc();

2509 getLexer().Lex();

2510 Operands.push_back(RISCVOperand::createReg(

2511 Reg, S, E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));

2513}

2514

2515ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(OperandVector &Operands) {

2516 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))

2518

2521

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

2524

2525 if (Reg)

2527

2528 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg))

2530

2531 if ((Reg - RISCV::X0) & 1) {

2532

2533

2534 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))

2535 return TokError("double precision floating point operands must use even "

2536 "numbered X register");

2538 }

2539

2540 SMLoc S = getLoc();

2541 SMLoc E = getTok().getEndLoc();

2542 getLexer().Lex();

2543

2544 const MCRegisterInfo *RI = getContext().getRegisterInfo();

2546 Reg, RISCV::sub_gpr_even,

2547 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);

2548 Operands.push_back(RISCVOperand::createReg(Pair, S, E, true));

2550}

2551

2552template

2553ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands) {

2554 return parseGPRPair(Operands, IsRV64);

2555}

2556

2557ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands,

2558 bool IsRV64Inst) {

2559

2560

2561

2562

2563

2564 if (!IsRV64Inst && isRV64())

2566

2569

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

2572

2573 if (Reg)

2575

2576 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg))

2578

2579 if ((Reg - RISCV::X0) & 1)

2580 return TokError("register must be even");

2581

2582 SMLoc S = getLoc();

2583 SMLoc E = getTok().getEndLoc();

2584 getLexer().Lex();

2585

2586 const MCRegisterInfo *RI = getContext().getRegisterInfo();

2588 Reg, RISCV::sub_gpr_even,

2589 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);

2590 Operands.push_back(RISCVOperand::createReg(Pair, S, E));

2592}

2593

2594ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) {

2596 return TokError(

2597 "operand must be a valid floating point rounding mode mnemonic");

2598

2599 StringRef Str = getLexer().getTok().getIdentifier();

2601

2603 return TokError(

2604 "operand must be a valid floating point rounding mode mnemonic");

2605

2606 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));

2607 Lex();

2609}

2610

2611ParseStatus RISCVAsmParser::parseFenceArg(OperandVector &Operands) {

2612 const AsmToken &Tok = getLexer().getTok();

2613

2616 goto ParseFail;

2617

2618 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));

2619 Lex();

2621 }

2622

2625

2626

2627

2628

2629 unsigned Imm = 0;

2630 bool Valid = true;

2631 char Prev = '\0';

2632 for (char c : Str) {

2633 switch (c) {

2634 default:

2636 break;

2637 case 'i':

2639 break;

2640 case 'o':

2642 break;

2643 case 'r':

2645 break;

2646 case 'w':

2648 break;

2649 }

2650

2651 if (c <= Prev) {

2653 break;

2654 }

2655 Prev = c;

2656 }

2657

2658 if (!Valid)

2659 goto ParseFail;

2660

2661 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));

2662 Lex();

2664 }

2665

2666ParseFail:

2667 return TokError("operand must be formed of letters selected in-order from "

2668 "'iorw' or be 0");

2669}

2670

2671ParseStatus RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {

2674 Operands.push_back(RISCVOperand::createToken("(", getLoc()));

2675

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

2677 return Error(getLoc(), "expected register");

2678

2681 Operands.push_back(RISCVOperand::createToken(")", getLoc()));

2682

2684}

2685

2686ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) {

2687

2688

2689

2690

2691

2692

2693

2694

2695

2696

2697

2698

2699

2700

2701

2702

2703

2704

2705 std::unique_ptr OptionalImmOp;

2706

2708

2709

2710

2711 int64_t ImmVal;

2712 SMLoc ImmStart = getLoc();

2713 if (getParser().parseIntToken(ImmVal,

2714 "expected '(' or optional integer offset"))

2716

2717

2718

2719 SMLoc ImmEnd = getLoc();

2720 OptionalImmOp =

2722 ImmStart, ImmEnd, isRV64());

2723 }

2724

2726 OptionalImmOp ? "expected '(' after optional integer offset"

2727 : "expected '(' or optional integer offset"))

2729

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

2731 return Error(getLoc(), "expected register");

2732

2735

2736

2737 if (OptionalImmOp && !OptionalImmOp->isImmZero())

2739 OptionalImmOp->getStartLoc(), "optional integer offset must be 0",

2740 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));

2741

2743}

2744

2745ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {

2746

2749

2750 SMLoc S = getLoc();

2751 StringRef OffsetRegName = getLexer().getTok().getIdentifier();

2753 if (!OffsetReg ||

2754 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(OffsetReg))

2755 return Error(getLoc(), "expected GPR register");

2756 getLexer().Lex();

2757

2758 if (parseToken(AsmToken::LParen, "expected '(' or invalid operand"))

2760

2762 return Error(getLoc(), "expected GPR register");

2763

2764 StringRef BaseRegName = getLexer().getTok().getIdentifier();

2766 if (!BaseReg ||

2767 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(BaseReg))

2768 return Error(getLoc(), "expected GPR register");

2769 getLexer().Lex();

2770

2773

2774 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));

2775

2777}

2778

2779

2780

2781

2782

2783

2784

2785

2786ParseStatus RISCVAsmParser::parseRegList(OperandVector &Operands,

2787 bool MustIncludeS0) {

2790

2791 SMLoc S = getLoc();

2792

2793 Lex();

2794

2795 bool UsesXRegs;

2796 MCRegister RegEnd;

2797 do {

2799 return Error(getLoc(), "invalid register");

2800

2801 StringRef RegName = getTok().getIdentifier();

2803 if (Reg)

2804 return Error(getLoc(), "invalid register");

2805

2806 if (!RegEnd) {

2807 UsesXRegs = RegName[0] == 'x';

2808 if (Reg != RISCV::X1)

2809 return Error(getLoc(), "register list must start from 'ra' or 'x1'");

2810 } else if (RegEnd == RISCV::X1) {

2811 if (Reg != RISCV::X8 || (UsesXRegs != (RegName[0] == 'x')))

2812 return Error(getLoc(), Twine("register must be '") +

2813 (UsesXRegs ? "x8" : "s0") + "'");

2814 } else if (RegEnd == RISCV::X9 && UsesXRegs) {

2815 if (Reg != RISCV::X18 || (RegName[0] != 'x'))

2816 return Error(getLoc(), "register must be 'x18'");

2817 } else {

2818 return Error(getLoc(), "too many register ranges");

2819 }

2820

2821 RegEnd = Reg;

2822

2823 Lex();

2824

2825 SMLoc MinusLoc = getLoc();

2827 if (RegEnd == RISCV::X1)

2828 return Error(MinusLoc, Twine("register '") + (UsesXRegs ? "x1" : "ra") +

2829 "' cannot start a multiple register range");

2830

2832 return Error(getLoc(), "invalid register");

2833

2834 StringRef RegName = getTok().getIdentifier();

2836 if (Reg)

2837 return Error(getLoc(), "invalid register");

2838

2839 if (RegEnd == RISCV::X8) {

2840 if ((Reg != RISCV::X9 &&

2842 (UsesXRegs != (RegName[0] == 'x'))) {

2843 if (UsesXRegs)

2844 return Error(getLoc(), "register must be 'x9'");

2845 return Error(getLoc(), "register must be in the range 's1' to 's11'");

2846 }

2847 } else if (RegEnd == RISCV::X18) {

2849 return Error(getLoc(),

2850 "register must be in the range 'x19' to 'x27'");

2851 } else

2853

2854 RegEnd = Reg;

2855

2856 Lex();

2857 }

2859

2862

2863 if (RegEnd == RISCV::X26)

2864 return Error(S, "invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "

2865 "x18-x26}' is not supported");

2866

2869

2870 if (MustIncludeS0 && Encode == RISCVZC::RA)

2871 return Error(S, "register list must include 's0' or 'x8'");

2872

2873 Operands.push_back(RISCVOperand::createRegList(Encode, S));

2874

2876}

2877

2878ParseStatus RISCVAsmParser::parseZcmpStackAdj(OperandVector &Operands,

2879 bool ExpectNegative) {

2880 SMLoc S = getLoc();

2882

2885

2887

2888 auto *RegListOp = static_cast<RISCVOperand *>(Operands.back().get());

2889 if (!RegListOp->isRegList())

2891

2892 unsigned RlistEncode = RegListOp->RegList.Encoding;

2893

2896 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||

2897 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {

2898 int64_t Lower = StackAdjBase;

2899 int64_t Upper = StackAdjBase + 48;

2900 if (ExpectNegative) {

2904 }

2905 return generateImmOutOfRangeError(S, Lower, Upper,

2906 "stack adjustment for register list must "

2907 "be a multiple of 16 bytes in the range");

2908 }

2909

2911 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));

2912 Lex();

2914}

2915

2916

2917

2918

2919bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {

2920

2921

2922 ParseStatus Result =

2923 MatchOperandParserImpl(Operands, Mnemonic, true);

2924 if (Result.isSuccess())

2925 return false;

2926 if (Result.isFailure())

2927 return true;

2928

2929

2930 if (parseRegister(Operands, true).isSuccess())

2931 return false;

2932

2933

2934 if (parseExpression(Operands).isSuccess()) {

2935

2937 return !parseMemOpBaseReg(Operands).isSuccess();

2938 return false;

2939 }

2940

2941

2942 Error(getLoc(), "unknown operand");

2943 return true;

2944}

2945

2946bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,

2947 StringRef Name, SMLoc NameLoc,

2949

2950

2951

2952

2953 const FeatureBitset &AvailableFeatures = getAvailableFeatures();

2955

2956

2957 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));

2958

2959

2961 getParser().Lex();

2962 return false;

2963 }

2964

2965

2966 if (parseOperand(Operands, Name))

2967 return true;

2968

2969

2971

2972 if (parseOperand(Operands, Name))

2973 return true;

2974 }

2975

2976 if (getParser().parseEOL("unexpected token")) {

2977 getParser().eatToEndOfStatement();

2978 return true;

2979 }

2980 return false;

2981}

2982

2983bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,

2987 Kind = RE->getSpecifier();

2988 Expr = RE->getSubExpr();

2989 }

2990

2991 MCValue Res;

2994 return false;

2995}

2996

2997bool RISCVAsmParser::isSymbolDiff(const MCExpr *Expr) {

2998 MCValue Res;

3002 }

3003 return false;

3004}

3005

3006ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {

3007 StringRef IDVal = DirectiveID.getString();

3008

3009 if (IDVal == ".option")

3010 return parseDirectiveOption();

3011 if (IDVal == ".attribute")

3012 return parseDirectiveAttribute();

3013 if (IDVal == ".insn")

3014 return parseDirectiveInsn(DirectiveID.getLoc());

3015 if (IDVal == ".variant_cc")

3016 return parseDirectiveVariantCC();

3017

3019}

3020

3021bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,

3022 bool FromOptionDirective) {

3025 clearFeatureBits(Feature.Value, Feature.Key);

3026

3028 Arch, true,

3029 true);

3030 if (!ParseResult) {

3031 std::string Buffer;

3032 raw_string_ostream OutputErrMsg(Buffer);

3033 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {

3034 OutputErrMsg << "invalid arch name '" << Arch << "', "

3035 << ErrMsg.getMessage();

3036 });

3037

3038 return Error(Loc, OutputErrMsg.str());

3039 }

3040 auto &ISAInfo = *ParseResult;

3041

3043 if (ISAInfo->hasExtension(Feature.Key))

3044 setFeatureBits(Feature.Value, Feature.Key);

3045

3046 if (FromOptionDirective) {

3047 if (ISAInfo->getXLen() == 32 && isRV64())

3048 return Error(Loc, "bad arch string switching from rv64 to rv32");

3049 else if (ISAInfo->getXLen() == 64 && !isRV64())

3050 return Error(Loc, "bad arch string switching from rv32 to rv64");

3051 }

3052

3053 if (ISAInfo->getXLen() == 32)

3054 clearFeatureBits(RISCV::Feature64Bit, "64bit");

3055 else if (ISAInfo->getXLen() == 64)

3056 setFeatureBits(RISCV::Feature64Bit, "64bit");

3057 else

3058 return Error(Loc, "bad arch string " + Arch);

3059

3060 Result = ISAInfo->toString();

3061 return false;

3062}

3063

3064bool RISCVAsmParser::parseDirectiveOption() {

3065 MCAsmParser &Parser = getParser();

3066

3067 AsmToken Tok = Parser.getTok();

3068

3069

3071 return true;

3072

3074

3075 if (Option == "push") {

3077 return true;

3078

3079 getTargetStreamer().emitDirectiveOptionPush();

3080 pushFeatureBits();

3081 return false;

3082 }

3083

3084 if (Option == "pop") {

3087 return true;

3088

3089 getTargetStreamer().emitDirectiveOptionPop();

3090 if (popFeatureBits())

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

3092

3093 return false;

3094 }

3095

3096 if (Option == "arch") {

3098 do {

3100 return true;

3101

3104 Type = RISCVOptionArchArgType::Plus;

3106 Type = RISCVOptionArchArgType::Minus;

3107 else if (Args.empty())

3109 "unexpected token, expected + or -");

3110 else

3111 Type = RISCVOptionArchArgType::Full;

3112

3115 "unexpected token, expected identifier");

3116

3119 Parser.Lex();

3120

3121 if (Type == RISCVOptionArchArgType::Full) {

3123 if (resetToArch(Arch, Loc, Result, true))

3124 return true;

3125

3126 Args.emplace_back(Type, Result);

3127 break;

3128 }

3129

3132 Loc, "extension version number parsing not currently implemented");

3133

3135 if (!enableExperimentalExtension() &&

3136 StringRef(Feature).starts_with("experimental-"))

3137 return Error(Loc, "unexpected experimental extensions");

3139 if (Ext == std::end(RISCVFeatureKV) || StringRef(Ext->Key) != Feature)

3140 return Error(Loc, "unknown extension feature");

3141

3143

3144 if (Type == RISCVOptionArchArgType::Plus) {

3145 FeatureBitset OldFeatureBits = STI->getFeatureBits();

3146

3147 setFeatureBits(Ext->Value, Ext->Key);

3149 if (!ParseResult) {

3150 copySTI().setFeatureBits(OldFeatureBits);

3151 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));

3152

3153 std::string Buffer;

3154 raw_string_ostream OutputErrMsg(Buffer);

3155 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {

3156 OutputErrMsg << ErrMsg.getMessage();

3157 });

3158

3159 return Error(Loc, OutputErrMsg.str());

3160 }

3161 } else {

3162 assert(Type == RISCVOptionArchArgType::Minus);

3163

3164

3165

3167 if (getSTI().hasFeature(Feature.Value) &&

3168 Feature.Implies.test(Ext->Value))

3169 return Error(Loc, Twine("can't disable ") + Ext->Key +

3170 " extension; " + Feature.Key +

3171 " extension requires " + Ext->Key +

3172 " extension");

3173 }

3174

3175 clearFeatureBits(Ext->Value, Ext->Key);

3176 }

3178

3180 return true;

3181

3182 getTargetStreamer().emitDirectiveOptionArch(Args);

3183 return false;

3184 }

3185

3186 if (Option == "exact") {

3188 return true;

3189

3190 getTargetStreamer().emitDirectiveOptionExact();

3191 setFeatureBits(RISCV::FeatureExactAssembly, "exact-asm");

3192 clearFeatureBits(RISCV::FeatureRelax, "relax");

3193 return false;

3194 }

3195

3196 if (Option == "noexact") {

3198 return true;

3199

3200 getTargetStreamer().emitDirectiveOptionNoExact();

3201 clearFeatureBits(RISCV::FeatureExactAssembly, "exact-asm");

3202 setFeatureBits(RISCV::FeatureRelax, "relax");

3203 return false;

3204 }

3205

3206 if (Option == "rvc") {

3208 return true;

3209

3210 getTargetStreamer().emitDirectiveOptionRVC();

3211 setFeatureBits(RISCV::FeatureStdExtC, "c");

3212 return false;

3213 }

3214

3215 if (Option == "norvc") {

3217 return true;

3218

3219 getTargetStreamer().emitDirectiveOptionNoRVC();

3220 clearFeatureBits(RISCV::FeatureStdExtC, "c");

3221 clearFeatureBits(RISCV::FeatureStdExtZca, "zca");

3222 return false;

3223 }

3224

3225 if (Option == "pic") {

3227 return true;

3228

3229 getTargetStreamer().emitDirectiveOptionPIC();

3230 ParserOptions.IsPicEnabled = true;

3231 return false;

3232 }

3233

3234 if (Option == "nopic") {

3236 return true;

3237

3238 getTargetStreamer().emitDirectiveOptionNoPIC();

3239 ParserOptions.IsPicEnabled = false;

3240 return false;

3241 }

3242

3243 if (Option == "relax") {

3245 return true;

3246

3247 getTargetStreamer().emitDirectiveOptionRelax();

3248 setFeatureBits(RISCV::FeatureRelax, "relax");

3249 return false;

3250 }

3251

3252 if (Option == "norelax") {

3254 return true;

3255

3256 getTargetStreamer().emitDirectiveOptionNoRelax();

3257 clearFeatureBits(RISCV::FeatureRelax, "relax");

3258 return false;

3259 }

3260

3261

3263 "unknown option, expected 'push', 'pop', "

3264 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "

3265 "'exact', or 'noexact'");

3267 return false;

3268}

3269

3270

3271

3272

3273bool RISCVAsmParser::parseDirectiveAttribute() {

3274 MCAsmParser &Parser = getParser();

3275 int64_t Tag;

3276 SMLoc TagLoc;

3280 std::optional Ret =

3282 if (!Ret)

3283 return Error(TagLoc, "attribute name not recognised: " + Name);

3284 Tag = *Ret;

3285 Parser.Lex();

3286 } else {

3287 const MCExpr *AttrExpr;

3288

3291 return true;

3292

3294 if (check(!CE, TagLoc, "expected numeric constant"))

3295 return true;

3296

3297 Tag = CE->getValue();

3298 }

3299

3301 return true;

3302

3303 StringRef StringValue;

3304 int64_t IntegerValue = 0;

3305 bool IsIntegerValue = true;

3306

3307

3308

3309 if (Tag % 2)

3310 IsIntegerValue = false;

3311

3312 SMLoc ValueExprLoc = Parser.getTok().getLoc();

3313 if (IsIntegerValue) {

3314 const MCExpr *ValueExpr;

3316 return true;

3317

3319 if (!CE)

3320 return Error(ValueExprLoc, "expected numeric constant");

3321 IntegerValue = CE->getValue();

3322 } else {

3324 return Error(Parser.getTok().getLoc(), "expected string constant");

3325

3327 Parser.Lex();

3328 }

3329

3331 return true;

3332

3333 if (IsIntegerValue)

3334 getTargetStreamer().emitAttribute(Tag, IntegerValue);

3336 getTargetStreamer().emitTextAttribute(Tag, StringValue);

3337 else {

3339 if (resetToArch(StringValue, ValueExprLoc, Result, false))

3340 return true;

3341

3342

3343 getTargetStreamer().emitTextAttribute(Tag, Result);

3344 }

3345

3346 return false;

3347}

3348

3351 .Cases({"r", "r4", "i", "b", "sb", "u", "j", "uj", "s"}, true)

3352 .Cases({"cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj"},

3353 STI.hasFeature(RISCV::FeatureStdExtZca))

3354 .Cases({"qc.eai", "qc.ei", "qc.eb", "qc.ej", "qc.es"},

3355 !STI.hasFeature(RISCV::Feature64Bit))

3357}

3358

3359

3360

3361

3362

3363bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {

3364 MCAsmParser &Parser = getParser();

3365

3366

3370

3371 std::optional<int64_t> Length;

3372 int64_t Value = 0;

3374 return true;

3378 return true;

3379

3381 return Error(ErrorLoc,

3382 "instruction lengths must be a non-zero multiple of two");

3383

3384

3386 return Error(ErrorLoc,

3387 "instruction lengths over 64 bits are not supported");

3388 }

3389

3390

3391

3392

3393 int64_t EncodingDerivedLength = ((Value & 0b11) == 0b11) ? 4 : 2;

3394

3396

3397

3398 if ((*Length <= 4) && (*Length != EncodingDerivedLength))

3399 return Error(ErrorLoc,

3400 "instruction length does not match the encoding");

3401

3403 return Error(ErrorLoc, "encoding value does not fit into instruction");

3404 } else {

3405 if (isUIntN(EncodingDerivedLength * 8, Value))

3406 return Error(ErrorLoc, "encoding value does not fit into instruction");

3407 }

3408

3409 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&

3410 (EncodingDerivedLength == 2))

3411 return Error(ErrorLoc, "compressed instructions are not allowed");

3412

3413 if (getParser().parseEOL("invalid operand for instruction")) {

3414 getParser().eatToEndOfStatement();

3415 return true;

3416 }

3417

3418 unsigned Opcode;

3421 case 2:

3422 Opcode = RISCV::Insn16;

3423 break;

3424 case 4:

3425 Opcode = RISCV::Insn32;

3426 break;

3427 case 6:

3428 Opcode = RISCV::Insn48;

3429 break;

3430 case 8:

3431 Opcode = RISCV::Insn64;

3432 break;

3433 default:

3435 }

3436 } else

3437 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;

3438

3439 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(Value));

3440 return false;

3441 }

3442

3444 return Error(ErrorLoc, "invalid instruction format");

3445

3446 std::string FormatName = (".insn_" + Format).str();

3447

3448 ParseInstructionInfo Info;

3450

3451 if (parseInstruction(Info, FormatName, L, Operands))

3452 return true;

3453

3454 unsigned Opcode;

3455 uint64_t ErrorInfo;

3456 return matchAndEmitInstruction(L, Opcode, Operands, Parser.getStreamer(),

3457 ErrorInfo,

3458 false);

3459}

3460

3461

3462

3463bool RISCVAsmParser::parseDirectiveVariantCC() {

3464 StringRef Name;

3465 if (getParser().parseIdentifier(Name))

3466 return TokError("expected symbol name");

3467 if (parseEOL())

3468 return true;

3469 getTargetStreamer().emitDirectiveVariantCC(

3470 *getContext().getOrCreateSymbol(Name));

3471 return false;

3472}

3473

3474void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {

3475 MCInst CInst;

3476 bool Res = false;

3477 const MCSubtargetInfo &STI = getSTI();

3478 if (!STI.hasFeature(RISCV::FeatureExactAssembly))

3480 if (Res)

3481 ++RISCVNumInstrsCompressed;

3483}

3484

3485void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value,

3486 MCStreamer &Out) {

3489

3490 for (MCInst &Inst : Seq) {

3491 emitToStreamer(Out, Inst);

3492 }

3493}

3494

3495void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,

3496 const MCExpr *Symbol,

3498 unsigned SecondOpcode, SMLoc IDLoc,

3499 MCStreamer &Out) {

3500

3501

3502

3504

3507

3509 emitToStreamer(Out,

3510 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));

3511

3514

3515 emitToStreamer(Out, MCInstBuilder(SecondOpcode)

3516 .addReg(DestReg)

3517 .addReg(TmpReg)

3518 .addExpr(RefToLinkTmpLabel));

3519}

3520

3521void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,

3522 MCStreamer &Out) {

3523

3524

3525

3526

3527

3528

3531 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_PCREL_HI20,

3532 RISCV::ADDI, IDLoc, Out);

3533}

3534

3535void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,

3536 MCStreamer &Out) {

3537

3538

3539

3540

3541

3542

3545 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;

3546 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_GOT_HI20,

3547 SecondOpcode, IDLoc, Out);

3548}

3549

3550void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,

3551 MCStreamer &Out) {

3552

3553

3554

3555

3556

3557

3558

3559 if (ParserOptions.IsPicEnabled)

3560 emitLoadGlobalAddress(Inst, IDLoc, Out);

3561 else

3562 emitLoadLocalAddress(Inst, IDLoc, Out);

3563}

3564

3565void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,

3566 MCStreamer &Out) {

3567

3568

3569

3570

3571

3572

3575 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;

3576 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,

3577 SecondOpcode, IDLoc, Out);

3578}

3579

3580void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,

3581 MCStreamer &Out) {

3582

3583

3584

3585

3586

3587

3590 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,

3591 RISCV::ADDI, IDLoc, Out);

3592}

3593

3594void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,

3595 SMLoc IDLoc, MCStreamer &Out,

3596 bool HasTmpReg) {

3597

3598

3599

3600

3601

3602

3603

3604 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;

3605 MCRegister DestReg = Inst.getOperand(DestRegOpIdx).getReg();

3606 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;

3608

3609

3610 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(TmpReg)) {

3611 const MCRegisterInfo *RI = getContext().getRegisterInfo();

3612 TmpReg = RI->getSubReg(TmpReg, RISCV::sub_gpr_even);

3613 }

3614

3616 emitAuipcInstPair(DestReg, TmpReg, Symbol, ELF::R_RISCV_PCREL_HI20, Opcode,

3617 IDLoc, Out);

3618}

3619

3620void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend,

3621 int64_t Width, SMLoc IDLoc,

3622 MCStreamer &Out) {

3623

3624

3625

3626

3627

3628

3629

3630 const MCOperand &DestReg = Inst.getOperand(0);

3631 const MCOperand &SourceReg = Inst.getOperand(1);

3632

3633 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;

3634 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;

3635

3636 assert(ShAmt > 0 && "Shift amount must be non-zero.");

3637

3638 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)

3641 .addImm(ShAmt));

3642

3643 emitToStreamer(Out, MCInstBuilder(SecondOpcode)

3646 .addImm(ShAmt));

3647}

3648

3649void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,

3650 MCStreamer &Out) {

3652

3653

3654

3655

3656 emitToStreamer(Out, MCInstBuilder(Opcode)

3660 .addReg(MCRegister())

3661 .setLoc(IDLoc));

3662 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)

3666 .setLoc(IDLoc));

3668

3669

3670

3671

3673 "The destination register should not be V0.");

3674 emitToStreamer(Out, MCInstBuilder(Opcode)

3679 .setLoc(IDLoc));

3680 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)

3683 .addReg(RISCV::V0)

3684 .setLoc(IDLoc));

3687

3688

3689

3690

3692 "The destination register should be V0.");

3694 "The temporary vector register should not be V0.");

3695 emitToStreamer(Out, MCInstBuilder(Opcode)

3699 .addReg(MCRegister())

3700 .setLoc(IDLoc));

3701 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)

3705 .setLoc(IDLoc));

3707

3708

3709

3710

3711

3713 "The temporary vector register should not be V0.");

3714 emitToStreamer(Out, MCInstBuilder(Opcode)

3718 .addReg(MCRegister())

3719 .setLoc(IDLoc));

3720 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)

3722 .addReg(RISCV::V0)

3724 .setLoc(IDLoc));

3725 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)

3728 .addReg(RISCV::V0)

3729 .setLoc(IDLoc));

3730 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)

3734 .setLoc(IDLoc));

3735 }

3736}

3737

3738bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,

3740 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction");

3743 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();

3744 return Error(ErrorLoc, "the second input operand must be tp/x4 when using "

3745 "%tprel_add specifier");

3746 }

3747

3748 return false;

3749}

3750

3751bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,

3753 assert(Inst.getOpcode() == RISCV::PseudoTLSDESCCall && "Invalid instruction");

3756 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();

3757 return Error(ErrorLoc, "the output operand must be t0/x5 when using "

3758 "%tlsdesc_call specifier");

3759 }

3760

3761 return false;

3762}

3763

3764std::unique_ptr RISCVAsmParser::defaultMaskRegOp() const {

3765 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());

3766}

3767

3768std::unique_ptr RISCVAsmParser::defaultFRMArgOp() const {

3769 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,

3770 llvm::SMLoc());

3771}

3772

3773std::unique_ptr RISCVAsmParser::defaultFRMArgLegacyOp() const {

3774 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,

3775 llvm::SMLoc());

3776}

3777

3778bool RISCVAsmParser::validateInstruction(MCInst &Inst,

3780 unsigned Opcode = Inst.getOpcode();

3781

3782 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||

3783 Opcode == RISCV::PseudoVMSGE_VX_M_T) {

3786 if (DestReg == TempReg) {

3787 SMLoc Loc = Operands.back()->getStartLoc();

3788 return Error(Loc, "the temporary vector register cannot be the same as "

3789 "the destination register");

3790 }

3791 }

3792

3793 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||

3794 Opcode == RISCV::TH_LWD) {

3798

3799 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {

3800 SMLoc Loc = Operands[1]->getStartLoc();

3801 return Error(Loc, "rs1, rd1, and rd2 cannot overlap");

3802 }

3803 }

3804

3805 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {

3808 if (Rd1 == Rd2) {

3809 SMLoc Loc = Operands[1]->getStartLoc();

3810 return Error(Loc, "rs1 and rs2 must be different");

3811 }

3812 }

3813

3814 const MCInstrDesc &MCID = MII.get(Opcode);

3816 return false;

3817

3818 if (Opcode == RISCV::SF_VC_V_XVW || Opcode == RISCV::SF_VC_V_IVW ||

3819 Opcode == RISCV::SF_VC_V_FVW || Opcode == RISCV::SF_VC_V_VVW) {

3820

3822 SMLoc VCIXDstLoc = Operands[2]->getStartLoc();

3825 if (VCIXDst == VCIXRs1)

3826 return Error(VCIXDstLoc, "the destination vector register group cannot"

3827 " overlap the source vector register group");

3828 }

3831 if (VCIXDst == VCIXRs2)

3832 return Error(VCIXDstLoc, "the destination vector register group cannot"

3833 " overlap the source vector register group");

3834 }

3835 return false;

3836 }

3837

3839 unsigned Offset = 0;

3841 if (TiedOp == 0)

3843

3844

3845 SMLoc Loc = Operands[1]->getStartLoc();

3848 if (DestReg == CheckReg)

3849 return Error(Loc, "the destination vector register group cannot overlap"

3850 " the source vector register group");

3851 }

3854 if (DestReg == CheckReg)

3855 return Error(Loc, "the destination vector register group cannot overlap"

3856 " the source vector register group");

3857 }

3859

3860

3861 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||

3862 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||

3863 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||

3864 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||

3865 Opcode == RISCV::VMERGE_VXM)

3866 return Error(Loc, "the destination vector register group cannot be V0");

3867

3868

3869

3870

3871

3873 assert((CheckReg == RISCV::V0 || !CheckReg) &&

3874 "Unexpected register for mask operand");

3875

3876 if (DestReg == CheckReg)

3877 return Error(Loc, "the destination vector register group cannot overlap"

3878 " the mask register");

3879 }

3880 return false;

3881}

3882

3883bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,

3885 MCStreamer &Out) {

3887

3889 default:

3890 break;

3891 case RISCV::PseudoC_ADDI_NOP: {

3893 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));

3894 else

3895 emitToStreamer(

3897 return false;

3898 }

3899 case RISCV::PseudoLLAImm:

3900 case RISCV::PseudoLAImm:

3901 case RISCV::PseudoLI: {

3903 const MCOperand &Op1 = Inst.getOperand(1);

3905

3906

3907 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)

3908 .addReg(Reg)

3909 .addReg(RISCV::X0)

3910 .addExpr(Op1.getExpr()));

3911 return false;

3912 }

3914

3915

3916

3917 if (!isRV64())

3919 emitLoadImm(Reg, Imm, Out);

3920 return false;

3921 }

3922 case RISCV::PseudoLLA:

3923 emitLoadLocalAddress(Inst, IDLoc, Out);

3924 return false;

3925 case RISCV::PseudoLGA:

3926 emitLoadGlobalAddress(Inst, IDLoc, Out);

3927 return false;

3928 case RISCV::PseudoLA:

3929 emitLoadAddress(Inst, IDLoc, Out);

3930 return false;

3931 case RISCV::PseudoLA_TLS_IE:

3932 emitLoadTLSIEAddress(Inst, IDLoc, Out);

3933 return false;

3934 case RISCV::PseudoLA_TLS_GD:

3935 emitLoadTLSGDAddress(Inst, IDLoc, Out);

3936 return false;

3937 case RISCV::PseudoLB:

3938 case RISCV::PseudoQC_E_LB:

3939 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, false);

3940 return false;

3941 case RISCV::PseudoLBU:

3942 case RISCV::PseudoQC_E_LBU:

3943 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, false);

3944 return false;

3945 case RISCV::PseudoLH:

3946 case RISCV::PseudoQC_E_LH:

3947 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, false);

3948 return false;

3949 case RISCV::PseudoLHU:

3950 case RISCV::PseudoQC_E_LHU:

3951 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, false);

3952 return false;

3953 case RISCV::PseudoLW:

3954 case RISCV::PseudoQC_E_LW:

3955 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, false);

3956 return false;

3957 case RISCV::PseudoLWU:

3958 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, false);

3959 return false;

3960 case RISCV::PseudoLD:

3961 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, false);

3962 return false;

3963 case RISCV::PseudoLD_RV32:

3964 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out, false);

3965 return false;

3966 case RISCV::PseudoFLH:

3967 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, true);

3968 return false;

3969 case RISCV::PseudoFLW:

3970 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, true);

3971 return false;

3972 case RISCV::PseudoFLD:

3973 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, true);

3974 return false;

3975 case RISCV::PseudoFLQ:

3976 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out, true);

3977 return false;

3978 case RISCV::PseudoSB:

3979 case RISCV::PseudoQC_E_SB:

3980 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, true);

3981 return false;

3982 case RISCV::PseudoSH:

3983 case RISCV::PseudoQC_E_SH:

3984 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, true);

3985 return false;

3986 case RISCV::PseudoSW:

3987 case RISCV::PseudoQC_E_SW:

3988 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, true);

3989 return false;

3990 case RISCV::PseudoSD:

3991 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, true);

3992 return false;

3993 case RISCV::PseudoSD_RV32:

3994 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out, true);

3995 return false;

3996 case RISCV::PseudoFSH:

3997 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, true);

3998 return false;

3999 case RISCV::PseudoFSW:

4000 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, true);

4001 return false;

4002 case RISCV::PseudoFSD:

4003 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, true);

4004 return false;

4005 case RISCV::PseudoFSQ:

4006 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out, true);

4007 return false;

4008 case RISCV::PseudoAddTPRel:

4009 if (checkPseudoAddTPRel(Inst, Operands))

4010 return true;

4011 break;

4012 case RISCV::PseudoTLSDESCCall:

4013 if (checkPseudoTLSDESCCall(Inst, Operands))

4014 return true;

4015 break;

4016 case RISCV::PseudoSEXT_B:

4017 emitPseudoExtend(Inst, true, 8, IDLoc, Out);

4018 return false;

4019 case RISCV::PseudoSEXT_H:

4020 emitPseudoExtend(Inst, true, 16, IDLoc, Out);

4021 return false;

4022 case RISCV::PseudoZEXT_H:

4023 emitPseudoExtend(Inst, false, 16, IDLoc, Out);

4024 return false;

4025 case RISCV::PseudoZEXT_W:

4026 emitPseudoExtend(Inst, false, 32, IDLoc, Out);

4027 return false;

4028 case RISCV::PseudoVMSGEU_VX:

4029 case RISCV::PseudoVMSGEU_VX_M:

4030 case RISCV::PseudoVMSGEU_VX_M_T:

4031 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);

4032 return false;

4033 case RISCV::PseudoVMSGE_VX:

4034 case RISCV::PseudoVMSGE_VX_M:

4035 case RISCV::PseudoVMSGE_VX_M_T:

4036 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);

4037 return false;

4038 case RISCV::PseudoVMSGE_VI:

4039 case RISCV::PseudoVMSLT_VI: {

4040

4041

4043 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI

4044 : RISCV::VMSLE_VI;

4045 emitToStreamer(Out, MCInstBuilder(Opc)

4048 .addImm(Imm - 1)

4050 .setLoc(IDLoc));

4051 return false;

4052 }

4053 case RISCV::PseudoVMSGEU_VI:

4054 case RISCV::PseudoVMSLTU_VI: {

4056

4057

4058

4059

4060 if (Imm == 0) {

4061 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI

4062 ? RISCV::VMSEQ_VV

4063 : RISCV::VMSNE_VV;

4064 emitToStreamer(Out, MCInstBuilder(Opc)

4069 .setLoc(IDLoc));

4070 } else {

4071

4072 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI

4073 ? RISCV::VMSGTU_VI

4074 : RISCV::VMSLEU_VI;

4075 emitToStreamer(Out, MCInstBuilder(Opc)

4078 .addImm(Imm - 1)

4080 .setLoc(IDLoc));

4081 }

4082

4083 return false;

4084 }

4085 case RISCV::PseudoCV_ELW:

4086 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out, false);

4087 return false;

4088 }

4089

4090 emitToStreamer(Out, Inst);

4091 return false;

4092}

4093

static MCRegister MatchRegisterName(StringRef Name)

static const char * getSubtargetFeatureName(uint64_t Val)

static SDValue Widen(SelectionDAG *CurDAG, SDValue N)

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)

static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)

static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)

static MCRegister MatchRegisterAltName(StringRef Name)

Maps from the set of all alternative registernames to a register number.

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

Analysis containing CSE Info

static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)

#define LLVM_EXTERNAL_VISIBILITY

Promote Memory to Register

static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)

static bool isReg(const MCInst &MI, unsigned OpNo)

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)

Definition RISCVAsmParser.cpp:3349

static MCRegister convertFPR64ToFPR128(MCRegister Reg)

Definition RISCVAsmParser.cpp:1299

static MCRegister convertFPR64ToFPR32(MCRegister Reg)

Definition RISCVAsmParser.cpp:1294

static cl::opt< bool > AddBuildAttributes("riscv-add-build-attributes", cl::init(false))

static MCRegister convertFPR64ToFPR16(MCRegister Reg)

Definition RISCVAsmParser.cpp:1289

LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()

Definition RISCVAsmParser.cpp:4095

static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)

Definition RISCVAsmParser.cpp:1304

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file implements the SmallBitVector class.

This file defines the SmallVector class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

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

LLVM_ABI SMLoc getLoc() const

int64_t getIntVal() const

bool isNot(TokenKind K) const

StringRef getString() const

Get the string for the current token, this includes all characters (for example, the quotes on string...

StringRef getStringContents() const

Get the contents of a string token (without quotes).

bool is(TokenKind K) const

LLVM_ABI SMLoc getEndLoc() const

StringRef getIdentifier() const

Get the identifier string for the current token, which should be an identifier or a string.

Encoding

Size and signedness of expression operations' operands.

constexpr size_t size() const

void printExpr(raw_ostream &, const MCExpr &) const

const AsmToken & getTok()

virtual void Initialize(MCAsmParser &Parser)

Initialize the extension for parsing using the given Parser.

virtual void eatToEndOfStatement()=0

Skip to the end of the current statement, for error recovery.

virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0

Parse an arbitrary expression.

const AsmToken & getTok() const

Get the current AsmToken from the stream.

virtual bool parseIdentifier(StringRef &Res)=0

Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.

bool parseOptionalToken(AsmToken::TokenKind T)

Attempt to parse and consume token, returning true on success.

virtual const AsmToken & Lex()=0

Get the next AsmToken in the stream, possibly handling file inclusion first.

virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0

virtual bool parseAbsoluteExpression(int64_t &Res)=0

Parse an expression which must evaluate to an absolute value.

MCStreamer & getStreamer()

static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

const MCObjectFileInfo * getObjectFileInfo() const

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.

unsigned getNumOperands() const

unsigned getOpcode() const

void addOperand(const MCOperand Op)

const MCOperand & getOperand(unsigned i) const

int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const

Returns the value of the specified operand constraint if it is present.

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

bool isPositionIndependent() const

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.

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const

Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.

MCRegister getSubReg(MCRegister Reg, unsigned Idx) const

Returns the physical register number of sub-register "Index" for physical register RegNo.

Wrapper class representing physical registers. Should be passed by value.

static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())

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.

Generic base class for all target subtargets.

bool hasFeature(unsigned Feature) const

const Triple & getTargetTriple() const

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

bool isVariable() const

isVariable - Check if this is a variable symbol.

const MCExpr * getVariableValue() const

Get the expression of the variable symbol.

MCTargetAsmParser - Generic interface to target specific assembly parsers.

const MCSymbol * getAddSym() const

uint32_t getSpecifier() const

const MCSymbol * getSubSym() const

Ternary parse status returned by various parse* methods.

static constexpr StatusTy Failure

static constexpr StatusTy Success

static constexpr StatusTy NoMatch

static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)

static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)

static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)

Parse RISC-V ISA info from arch string.

static const char * getRegisterName(MCRegister Reg)

static SMLoc getFromPointer(const char *Ptr)

constexpr const char * getPointer() const

void push_back(const T &Elt)

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

char back() const

back - Get the last character in the string.

A switch()-like statement whose cases are string literals.

StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

uint16_t StackAdjustment(const RuntimeFunction &RF)

StackAdjustment - calculated stack adjustment in words.

LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)

MCExpr const & getExpr(MCExpr const &Expr)

ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)

LLVM_ABI const TagNameMap & getRISCVAttributeTags()

static RoundingMode stringToRoundingMode(StringRef Str)

llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits)

int getLoadFPImm(APFloat FPImm)

getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.

void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)

bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)

static VLMUL encodeLMUL(unsigned LMUL, bool Fractional)

LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)

static bool isValidLMUL(unsigned LMUL, bool Fractional)

static bool isValidSEW(unsigned SEW)

LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)

static bool isValidXSfmmVType(unsigned VTypeI)

LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)

unsigned encodeRegList(MCRegister EndReg, bool IsRVE=false)

static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64)

void printRegList(unsigned RlistEncode, raw_ostream &OS)

Specifier parseSpecifierName(StringRef name)

@ CE

Windows NT (Windows on ARM)

@ Valid

The data is already valid.

initializer< Ty > init(const Ty &Val)

Context & getContext() const

BaseReg

Stack frame base register. Bit 0 of FREInfo.Info.

This is an optimization pass for GlobalISel generic memory operations.

bool errorToBool(Error Err)

Helper for converting an Error to a bool.

FunctionAddr VTableAddr Value

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

static bool isMem(const MachineInstr &MI, unsigned Op)

LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")

getToken - This function extracts one token from source, ignoring any leading characters that appear ...

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

void handleAllErrors(Error E, HandlerTs &&... Handlers)

Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...

testing::Matcher< const detail::ErrorHolder & > Failed()

Target & getTheRISCV32Target()

constexpr bool isUIntN(unsigned N, uint64_t x)

Checks if an unsigned integer fits into the given (dynamic) bit width.

Target & getTheRISCV64beTarget()

SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

bool isDigit(char C)

Checks if character C is one of the 10 decimal digits.

constexpr bool isUInt(uint64_t x)

Checks if an unsigned integer fits into the given bit width.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

auto lower_bound(R &&Range, T &&Value)

Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...

DWARFExpression::Operation Op

Target & getTheRISCV64Target()

constexpr bool isShiftedInt(int64_t x)

Checks if a signed integer is an N bit number shifted left by S.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

constexpr int64_t SignExtend64(uint64_t x)

Sign-extend the number in the bottom B bits of X to a 64-bit integer.

const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]

constexpr bool isShiftedUInt(uint64_t x)

Checks if a unsigned integer is an N bit number shifted left by S.

Target & getTheRISCV32beTarget()

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...

Used to provide key value pairs for feature and CPU bit flags.