LLVM: lib/Target/VE/AsmParser/VEAsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

12#include "VE.h"

29#include

30

31using namespace llvm;

32

33#define DEBUG_TYPE "ve-asmparser"

34

35namespace {

36

37class VEOperand;

38

41

42

43

44

45#define GET_ASSEMBLER_HEADER

46#include "VEGenAsmMatcher.inc"

47

48

49

50

54 bool MatchingInlineAsm) override;

58 SMLoc &EndLoc) override;

62

64 unsigned Kind) override;

65

66

73 ParseStatus parseVEAsmOperand(std::unique_ptr &Operand);

74

75

76 const MCExpr *extractModifierFromExpr(const MCExpr *E,

78 const MCExpr *fixupVariantKind(const MCExpr *E);

79 bool parseExpression(const MCExpr *&EVal);

80

81

84

85 bool parseLiteralValues(unsigned Size, SMLoc L);

86

87public:

91

93 }

94};

95

96}

97

99 VE::SW0, VE::SW1, VE::SW2, VE::SW3, VE::SW4, VE::SW5, VE::SW6,

100 VE::SW7, VE::SW8, VE::SW9, VE::SW10, VE::SW11, VE::SW12, VE::SW13,

101 VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,

102 VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,

103 VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,

104 VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,

105 VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,

106 VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,

107 VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,

108 VE::SW63};

109

111 VE::SF0, VE::SF1, VE::SF2, VE::SF3, VE::SF4, VE::SF5, VE::SF6,

112 VE::SF7, VE::SF8, VE::SF9, VE::SF10, VE::SF11, VE::SF12, VE::SF13,

113 VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,

114 VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,

115 VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,

116 VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,

117 VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,

118 VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,

119 VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,

120 VE::SF63};

121

123 VE::Q0, VE::Q1, VE::Q2, VE::Q3, VE::Q4, VE::Q5, VE::Q6, VE::Q7,

124 VE::Q8, VE::Q9, VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15,

125 VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,

126 VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};

127

129 VE::VMP4, VE::VMP5, VE::VMP6, VE::VMP7};

130

132 VE::USRCC, VE::PSW, VE::SAR, VE::NoRegister,

133 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,

134 VE::PMCR0, VE::PMCR1, VE::PMCR2, VE::PMCR3,

135 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister,

136 VE::PMC0, VE::PMC1, VE::PMC2, VE::PMC3,

137 VE::PMC4, VE::PMC5, VE::PMC6, VE::PMC7,

138 VE::PMC8, VE::PMC9, VE::PMC10, VE::PMC11,

139 VE::PMC12, VE::PMC13, VE::PMC14};

140

141namespace {

142

143

144

146private:

147 enum KindTy {

148 k_Token,

149 k_Register,

150 k_Immediate,

151

152 k_MemoryRegRegImm,

153 k_MemoryRegImmImm,

154 k_MemoryZeroRegImm,

155 k_MemoryZeroImmImm,

156

157 k_MemoryRegImm,

158 k_MemoryZeroImm,

159

160 k_CCOp,

161 k_RDOp,

162 k_MImmOp,

164

165 SMLoc StartLoc, EndLoc;

166

167 struct Token {

168 const char *Data;

170 };

171

172 struct RegOp {

173 unsigned RegNum;

174 };

175

176 struct ImmOp {

178 };

179

181 unsigned Base;

182 unsigned IndexReg;

185 };

186

187 struct CCOp {

188 unsigned CCVal;

189 };

190

191 struct RDOp {

192 unsigned RDVal;

193 };

194

195 struct MImmOp {

197 bool M0Flag;

198 };

199

200 union {

201 struct Token Tok;

202 struct RegOp Reg;

203 struct ImmOp Imm;

204 struct MemOp Mem;

205 struct CCOp CC;

206 struct RDOp RD;

207 struct MImmOp MImm;

208 };

209

210public:

211 VEOperand(KindTy K) : Kind(K) {}

212

213 bool isToken() const override { return Kind == k_Token; }

214 bool isReg() const override { return Kind == k_Register; }

215 bool isImm() const override { return Kind == k_Immediate; }

216 bool isMem() const override {

217 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||

218 isMEMzi();

219 }

220 bool isMEMrri() const { return Kind == k_MemoryRegRegImm; }

221 bool isMEMrii() const { return Kind == k_MemoryRegImmImm; }

222 bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; }

223 bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; }

224 bool isMEMri() const { return Kind == k_MemoryRegImm; }

225 bool isMEMzi() const { return Kind == k_MemoryZeroImm; }

226 bool isCCOp() const { return Kind == k_CCOp; }

227 bool isRDOp() const { return Kind == k_RDOp; }

230 return false;

231

232

233 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

234 int64_t Value = ConstExpr->getValue();

235 return Value == 0;

236 }

237 return false;

238 }

239 bool isUImm0to2() {

241 return false;

242

243

244 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

245 int64_t Value = ConstExpr->getValue();

247 }

248 return false;

249 }

250 bool isUImm1() {

252 return false;

253

254

255 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

256 int64_t Value = ConstExpr->getValue();

257 return isUInt<1>(Value);

258 }

259 return false;

260 }

261 bool isUImm2() {

263 return false;

264

265

266 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

267 int64_t Value = ConstExpr->getValue();

268 return isUInt<2>(Value);

269 }

270 return false;

271 }

272 bool isUImm3() {

274 return false;

275

276

277 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

278 int64_t Value = ConstExpr->getValue();

279 return isUInt<3>(Value);

280 }

281 return false;

282 }

283 bool isUImm4() {

285 return false;

286

287

288 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

289 int64_t Value = ConstExpr->getValue();

290 return isUInt<4>(Value);

291 }

292 return false;

293 }

294 bool isUImm6() {

296 return false;

297

298

299 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

300 int64_t Value = ConstExpr->getValue();

301 return isUInt<6>(Value);

302 }

303 return false;

304 }

305 bool isUImm7() {

307 return false;

308

309

310 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

311 int64_t Value = ConstExpr->getValue();

312 return isUInt<7>(Value);

313 }

314 return false;

315 }

316 bool isSImm7() {

318 return false;

319

320

321 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {

322 int64_t Value = ConstExpr->getValue();

323 return isInt<7>(Value);

324 }

325 return false;

326 }

327 bool isMImm() const {

328 if (Kind != k_MImmOp)

329 return false;

330

331

332 if (const auto *ConstExpr = dyn_cast(MImm.Val)) {

333 int64_t Value = ConstExpr->getValue();

334 return isUInt<6>(Value);

335 }

336 return false;

337 }

338

340 assert(Kind == k_Token && "Invalid access!");

341 return StringRef(Tok.Data, Tok.Length);

342 }

343

345 assert((Kind == k_Register) && "Invalid access!");

346 return Reg.RegNum;

347 }

348

349 const MCExpr *getImm() const {

350 assert((Kind == k_Immediate) && "Invalid access!");

351 return Imm.Val;

352 }

353

354 unsigned getMemBase() const {

355 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||

356 Kind == k_MemoryRegImm) &&

357 "Invalid access!");

358 return Mem.Base;

359 }

360

361 unsigned getMemIndexReg() const {

362 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) &&

363 "Invalid access!");

364 return Mem.IndexReg;

365 }

366

367 const MCExpr *getMemIndex() const {

368 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) &&

369 "Invalid access!");

370 return Mem.Index;

371 }

372

373 const MCExpr *getMemOffset() const {

374 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||

375 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||

376 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&

377 "Invalid access!");

378 return Mem.Offset;

379 }

380

381 void setMemOffset(const MCExpr *off) {

382 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||

383 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||

384 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&

385 "Invalid access!");

386 Mem.Offset = off;

387 }

388

389 unsigned getCCVal() const {

390 assert((Kind == k_CCOp) && "Invalid access!");

391 return CC.CCVal;

392 }

393

394 unsigned getRDVal() const {

395 assert((Kind == k_RDOp) && "Invalid access!");

396 return RD.RDVal;

397 }

398

399 const MCExpr *getMImmVal() const {

400 assert((Kind == k_MImmOp) && "Invalid access!");

401 return MImm.Val;

402 }

403 bool getM0Flag() const {

404 assert((Kind == k_MImmOp) && "Invalid access!");

405 return MImm.M0Flag;

406 }

407

408

410

412

414 switch (Kind) {

415 case k_Token:

416 OS << "Token: " << getToken() << "\n";

417 break;

418 case k_Register:

419 OS << "Reg: #" << getReg() << "\n";

420 break;

421 case k_Immediate:

422 OS << "Imm: " << getImm() << "\n";

423 break;

424 case k_MemoryRegRegImm:

425 assert(getMemOffset() != nullptr);

426 OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+"

427 << *getMemOffset() << "\n";

428 break;

429 case k_MemoryRegImmImm:

430 assert(getMemIndex() != nullptr && getMemOffset() != nullptr);

431 OS << "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+"

432 << *getMemOffset() << "\n";

433 break;

434 case k_MemoryZeroRegImm:

435 assert(getMemOffset() != nullptr);

436 OS << "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n";

437 break;

438 case k_MemoryZeroImmImm:

439 assert(getMemIndex() != nullptr && getMemOffset() != nullptr);

440 OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n";

441 break;

442 case k_MemoryRegImm:

443 assert(getMemOffset() != nullptr);

444 OS << "Mem: #" << getMemBase() << "+" << *getMemOffset() << "\n";

445 break;

446 case k_MemoryZeroImm:

447 assert(getMemOffset() != nullptr);

448 OS << "Mem: 0+" << *getMemOffset() << "\n";

449 break;

450 case k_CCOp:

451 OS << "CCOp: " << getCCVal() << "\n";

452 break;

453 case k_RDOp:

454 OS << "RDOp: " << getRDVal() << "\n";

455 break;

456 case k_MImmOp:

457 OS << "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n";

458 break;

459 }

460 }

461

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

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

465 }

466

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

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

469 const MCExpr *Expr = getImm();

470 addExpr(Inst, Expr);

471 }

472

473 void addZeroOperands(MCInst &Inst, unsigned N) const {

474 addImmOperands(Inst, N);

475 }

476

477 void addUImm0to2Operands(MCInst &Inst, unsigned N) const {

478 addImmOperands(Inst, N);

479 }

480

481 void addUImm1Operands(MCInst &Inst, unsigned N) const {

482 addImmOperands(Inst, N);

483 }

484

485 void addUImm2Operands(MCInst &Inst, unsigned N) const {

486 addImmOperands(Inst, N);

487 }

488

489 void addUImm3Operands(MCInst &Inst, unsigned N) const {

490 addImmOperands(Inst, N);

491 }

492

493 void addUImm4Operands(MCInst &Inst, unsigned N) const {

494 addImmOperands(Inst, N);

495 }

496

497 void addUImm6Operands(MCInst &Inst, unsigned N) const {

498 addImmOperands(Inst, N);

499 }

500

501 void addUImm7Operands(MCInst &Inst, unsigned N) const {

502 addImmOperands(Inst, N);

503 }

504

505 void addSImm7Operands(MCInst &Inst, unsigned N) const {

506 addImmOperands(Inst, N);

507 }

508

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

510

511 if (!Expr)

513 else if (const auto *CE = dyn_cast(Expr))

515 else

517 }

518

519 void addMEMrriOperands(MCInst &Inst, unsigned N) const {

520 assert(N == 3 && "Invalid number of operands!");

521

524 addExpr(Inst, getMemOffset());

525 }

526

527 void addMEMriiOperands(MCInst &Inst, unsigned N) const {

528 assert(N == 3 && "Invalid number of operands!");

529

531 addExpr(Inst, getMemIndex());

532 addExpr(Inst, getMemOffset());

533 }

534

535 void addMEMzriOperands(MCInst &Inst, unsigned N) const {

536 assert(N == 3 && "Invalid number of operands!");

537

540 addExpr(Inst, getMemOffset());

541 }

542

543 void addMEMziiOperands(MCInst &Inst, unsigned N) const {

544 assert(N == 3 && "Invalid number of operands!");

545

547 addExpr(Inst, getMemIndex());

548 addExpr(Inst, getMemOffset());

549 }

550

551 void addMEMriOperands(MCInst &Inst, unsigned N) const {

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

553

555 addExpr(Inst, getMemOffset());

556 }

557

558 void addMEMziOperands(MCInst &Inst, unsigned N) const {

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

560

562 addExpr(Inst, getMemOffset());

563 }

564

565 void addCCOpOperands(MCInst &Inst, unsigned N) const {

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

567

569 }

570

571 void addRDOpOperands(MCInst &Inst, unsigned N) const {

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

573

575 }

576

577 void addMImmOperands(MCInst &Inst, unsigned N) const {

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

579 const auto *ConstExpr = dyn_cast(getMImmVal());

580 assert(ConstExpr && "Null operands!");

581 int64_t Value = ConstExpr->getValue();

582 if (getM0Flag())

585 }

586

587 static std::unique_ptr CreateToken(StringRef Str, SMLoc S) {

588 auto Op = std::make_unique(k_Token);

589 Op->Tok.Data = Str.data();

590 Op->Tok.Length = Str.size();

591 Op->StartLoc = S;

592 Op->EndLoc = S;

593 return Op;

594 }

595

596 static std::unique_ptr CreateReg(unsigned RegNum, SMLoc S,

598 auto Op = std::make_unique(k_Register);

599 Op->Reg.RegNum = RegNum;

600 Op->StartLoc = S;

601 Op->EndLoc = E;

602 return Op;

603 }

604

605 static std::unique_ptr CreateImm(const MCExpr *Val, SMLoc S,

607 auto Op = std::make_unique(k_Immediate);

608 Op->Imm.Val = Val;

609 Op->StartLoc = S;

610 Op->EndLoc = E;

611 return Op;

612 }

613

614 static std::unique_ptr CreateCCOp(unsigned CCVal, SMLoc S,

616 auto Op = std::make_unique(k_CCOp);

617 Op->CC.CCVal = CCVal;

618 Op->StartLoc = S;

619 Op->EndLoc = E;

620 return Op;

621 }

622

623 static std::unique_ptr CreateRDOp(unsigned RDVal, SMLoc S,

625 auto Op = std::make_unique(k_RDOp);

626 Op->RD.RDVal = RDVal;

627 Op->StartLoc = S;

628 Op->EndLoc = E;

629 return Op;

630 }

631

632 static std::unique_ptr CreateMImm(const MCExpr *Val, bool Flag,

634 auto Op = std::make_unique(k_MImmOp);

635 Op->MImm.Val = Val;

636 Op->MImm.M0Flag = Flag;

637 Op->StartLoc = S;

638 Op->EndLoc = E;

639 return Op;

640 }

641

642 static bool MorphToI32Reg(VEOperand &Op) {

643 unsigned Reg = Op.getReg();

644 unsigned regIdx = Reg - VE::SX0;

645 if (regIdx > 63)

646 return false;

648 return true;

649 }

650

651 static bool MorphToF32Reg(VEOperand &Op) {

652 unsigned Reg = Op.getReg();

653 unsigned regIdx = Reg - VE::SX0;

654 if (regIdx > 63)

655 return false;

657 return true;

658 }

659

660 static bool MorphToF128Reg(VEOperand &Op) {

661 unsigned Reg = Op.getReg();

662 unsigned regIdx = Reg - VE::SX0;

663 if (regIdx % 2 || regIdx > 63)

664 return false;

665 Op.Reg.RegNum = F128Regs[regIdx / 2];

666 return true;

667 }

668

669 static bool MorphToVM512Reg(VEOperand &Op) {

670 unsigned Reg = Op.getReg();

671 unsigned regIdx = Reg - VE::VM0;

672 if (regIdx % 2 || regIdx > 15)

673 return false;

675 return true;

676 }

677

678 static bool MorphToMISCReg(VEOperand &Op) {

679 const auto *ConstExpr = dyn_cast(Op.getImm());

680 if (!ConstExpr)

681 return false;

682 unsigned regIdx = ConstExpr->getValue();

683 if (regIdx > 31 || MISCRegs[regIdx] == VE::NoRegister)

684 return false;

685 Op.Kind = k_Register;

687 return true;

688 }

689

690 static std::unique_ptr

691 MorphToMEMri(unsigned Base, std::unique_ptr Op) {

693 Op->Kind = k_MemoryRegImm;

695 Op->Mem.IndexReg = 0;

696 Op->Mem.Index = nullptr;

697 Op->Mem.Offset = Imm;

698 return Op;

699 }

700

701 static std::unique_ptr

702 MorphToMEMzi(std::unique_ptr Op) {

704 Op->Kind = k_MemoryZeroImm;

705 Op->Mem.Base = 0;

706 Op->Mem.IndexReg = 0;

707 Op->Mem.Index = nullptr;

708 Op->Mem.Offset = Imm;

709 return Op;

710 }

711

712 static std::unique_ptr

713 MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr Op) {

715 Op->Kind = k_MemoryRegRegImm;

717 Op->Mem.IndexReg = Index;

718 Op->Mem.Index = nullptr;

719 Op->Mem.Offset = Imm;

720 return Op;

721 }

722

723 static std::unique_ptr

725 std::unique_ptr Op) {

727 Op->Kind = k_MemoryRegImmImm;

729 Op->Mem.IndexReg = 0;

731 Op->Mem.Offset = Imm;

732 return Op;

733 }

734

735 static std::unique_ptr

736 MorphToMEMzri(unsigned Index, std::unique_ptr Op) {

738 Op->Kind = k_MemoryZeroRegImm;

739 Op->Mem.Base = 0;

740 Op->Mem.IndexReg = Index;

741 Op->Mem.Index = nullptr;

742 Op->Mem.Offset = Imm;

743 return Op;

744 }

745

746 static std::unique_ptr

747 MorphToMEMzii(const MCExpr *Index, std::unique_ptr Op) {

749 Op->Kind = k_MemoryZeroImmImm;

750 Op->Mem.Base = 0;

751 Op->Mem.IndexReg = 0;

753 Op->Mem.Offset = Imm;

754 return Op;

755 }

756};

757

758}

759

760bool VEAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

763 bool MatchingInlineAsm) {

765 unsigned MatchResult =

766 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);

767 switch (MatchResult) {

768 case Match_Success:

771 return false;

772

773 case Match_MissingFeature:

774 return Error(IDLoc,

775 "instruction requires a CPU feature not currently enabled");

776

777 case Match_InvalidOperand: {

778 SMLoc ErrorLoc = IDLoc;

781 return Error(IDLoc, "too few operands for instruction");

782

784 if (ErrorLoc == SMLoc())

785 ErrorLoc = IDLoc;

786 }

787

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

789 }

790 case Match_MnemonicFail:

791 return Error(IDLoc, "invalid instruction mnemonic");

792 }

794}

795

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

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

800 return false;

801}

802

803

804

807

808 int RegNum = matchFn(Name);

809

810

811

812 if (RegNum == VE::NoRegister) {

813 RegNum = matchFn(Name.lower());

814 }

815

816 return RegNum;

817}

818

819

820

822

823

824

826

830 StartLoc = Tok.getLoc();

832 Reg = VE::NoRegister;

835 Parser.Lex();

836

838 if (Reg == VE::NoRegister)

840

841 if (Reg != VE::NoRegister) {

842 Parser.Lex();

844 }

845

846 getLexer().UnLex(Tok);

848}

849

851 bool IntegerCC, bool OmitCC, SMLoc NameLoc,

853

854

858

859

863

864 Name = Name.slice(0, Prefix);

865 Operands->push_back(VEOperand::CreateToken(Name, NameLoc));

866

869 Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc));

870

871 if (!SuffixStr.empty())

872 Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc));

873 } else {

874 Operands->push_back(VEOperand::CreateToken(Name, NameLoc));

875 }

877}

878

881

882

885

887 Name = Name.slice(0, Prefix);

888

889 Operands->push_back(VEOperand::CreateToken(Name, NameLoc));

890 SMLoc SuffixLoc =

894

897 } else {

898 Operands->push_back(VEOperand::CreateToken(Name, NameLoc));

899 }

901}

902

903

904

907

909

910 if (Name[0] == 'b') {

911

912 size_t Start = 1;

913 size_t Next = Name.find('.');

914

915 if (Name.size() > 1 && Name[1] == 'r')

916 Start = 2;

917

918 bool ICC = true;

919 if (Next + 1 < Name.size() &&

920 (Name[Next + 1] == 'd' || Name[Next + 1] == 's'))

921 ICC = false;

923 } else if (Name.starts_with("cmov.l.") || Name.starts_with("cmov.w.") ||

924 Name.starts_with("cmov.d.") || Name.starts_with("cmov.s.")) {

925 bool ICC = Name[5] == 'l' || Name[5] == 'w';

927 } else if (Name.starts_with("cvt.w.d.sx") || Name.starts_with("cvt.w.d.zx") ||

928 Name.starts_with("cvt.w.s.sx") || Name.starts_with("cvt.w.s.zx")) {

930 } else if (Name.starts_with("cvt.l.d")) {

932 } else if (Name.starts_with("vcvt.w.d.sx") ||

933 Name.starts_with("vcvt.w.d.zx") ||

934 Name.starts_with("vcvt.w.s.sx") ||

935 Name.starts_with("vcvt.w.s.zx")) {

937 } else if (Name.starts_with("vcvt.l.d")) {

939 } else if (Name.starts_with("pvcvt.w.s.lo") ||

940 Name.starts_with("pvcvt.w.s.up")) {

942 } else if (Name.starts_with("pvcvt.w.s")) {

944 } else if (Name.starts_with("vfmk.l.") || Name.starts_with("vfmk.w.") ||

945 Name.starts_with("vfmk.d.") || Name.starts_with("vfmk.s.")) {

946 bool ICC = Name[5] == 'l' || Name[5] == 'w' ? true : false;

948 } else if (Name.starts_with("pvfmk.w.lo.") ||

949 Name.starts_with("pvfmk.w.up.") ||

950 Name.starts_with("pvfmk.s.lo.") ||

951 Name.starts_with("pvfmk.s.up.")) {

952 bool ICC = Name[6] == 'l' || Name[6] == 'w' ? true : false;

954 } else {

955 Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc));

956 }

957

958 return Mnemonic;

959}

960

963 unsigned VariantID);

964

967

968

970

971

972

973

975

977

978 if (!parseOperand(Operands, Mnemonic).isSuccess()) {

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

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

981 }

982

984 Parser.Lex();

985

986 if (!parseOperand(Operands, Mnemonic).isSuccess()) {

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

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

989 }

990 }

991 }

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

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

995 }

996 Parser.Lex();

997 return false;

998}

999

1002

1003

1004

1005

1006

1007

1008 if (IDVal == ".word")

1009 return parseLiteralValues(4, DirectiveID.getLoc());

1010

1011

1012 if (IDVal == ".long")

1013 return parseLiteralValues(8, DirectiveID.getLoc());

1014

1015

1016 if (IDVal == ".llong")

1017 return parseLiteralValues(8, DirectiveID.getLoc());

1018

1019

1021}

1022

1023

1024

1025

1026

1027bool VEAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {

1028 auto parseOne = [&]() -> bool {

1030 if (getParser().parseExpression(Value))

1031 return true;

1032 getParser().getStreamer().emitValue(Value, Size, L);

1033 return false;

1034 };

1035 return (parseMany(parseOne));

1036}

1037

1038

1039

1040

1041

1042

1043

1045VEAsmParser::extractModifierFromExpr(const MCExpr *E,

1047 MCContext &Context = getParser().getContext();

1049

1050 switch (E->getKind()) {

1053 return nullptr;

1054

1057

1058 switch (SRE->getKind()) {

1060

1062 break;

1065 break;

1068 break;

1071 break;

1074 break;

1077 break;

1080 break;

1083 break;

1086 break;

1089 break;

1092 break;

1095 break;

1098 break;

1101 break;

1104 break;

1105 default:

1106 return nullptr;

1107 }

1108

1110 }

1111

1113 const MCUnaryExpr *UE = cast(E);

1114 const MCExpr *Sub = extractModifierFromExpr(UE->getSubExpr(), Variant);

1115 if (!Sub)

1116 return nullptr;

1118 }

1119

1123 const MCExpr *LHS = extractModifierFromExpr(BE->getLHS(), LHSVariant);

1124 const MCExpr *RHS = extractModifierFromExpr(BE->getRHS(), RHSVariant);

1125

1127 return nullptr;

1128

1129 if (LHS)

1131 if (RHS)

1133

1138 else if (LHSVariant == RHSVariant)

1140 else

1141 return nullptr;

1142

1144 }

1145 }

1146

1148}

1149

1150const MCExpr *VEAsmParser::fixupVariantKind(const MCExpr *E) {

1151 MCContext &Context = getParser().getContext();

1152

1153 switch (E->getKind()) {

1157 return E;

1158

1160 const MCUnaryExpr *UE = cast(E);

1163 return E;

1165 }

1166

1172 return E;

1174 }

1175 }

1176

1178}

1179

1180

1181

1182bool VEAsmParser::parseExpression(const MCExpr *&EVal) {

1183

1184 if (getParser().parseExpression(EVal))

1185 return true;

1186

1187

1188 EVal = fixupVariantKind(EVal);

1190 const MCExpr *E = extractModifierFromExpr(EVal, Variant);

1191 if (E)

1193

1194 return false;

1195}

1196

1202

1203

1204

1205

1206

1207

1208

1209

1210

1211 std::unique_ptr Offset;

1212 switch (getLexer().getKind()) {

1213 default:

1215

1221 if (!parseExpression(EVal))

1222 Offset = VEOperand::CreateImm(EVal, S, E);

1223 else

1225 break;

1226 }

1227

1229

1232 break;

1233 }

1234

1235 switch (getLexer().getKind()) {

1236 default:

1238

1240 Operands.push_back(VEOperand::MorphToMEMzii(

1243

1245 Parser.Lex();

1246 break;

1247 }

1248

1249 const MCExpr *IndexValue = nullptr;

1251

1252 switch (getLexer().getKind()) {

1253 default:

1254 if (parseRegister(IndexReg, S, E))

1256 break;

1257

1261 if (getParser().parseExpression(IndexValue, E))

1263 break;

1264

1266

1268 break;

1269 }

1270

1271 switch (getLexer().getKind()) {

1272 default:

1274

1276 Parser.Lex();

1278 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset))

1279 : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset)));

1281

1283 Parser.Lex();

1284 break;

1285 }

1286

1288 if (parseRegister(BaseReg, S, E))

1290

1293

1294 Parser.Lex();

1296 IndexValue

1297 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset))

1298 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset)));

1299

1301}

1302

1308

1309

1310

1311

1312

1313

1314

1315

1316

1318 std::unique_ptr Offset;

1319 switch (getLexer().getKind()) {

1320 default:

1322

1328 if (!parseExpression(EVal))

1329 Offset = VEOperand::CreateImm(EVal, S, E);

1330 else

1332 break;

1333 }

1334

1336 if (parseRegister(BaseReg, S, E))

1340 break;

1341

1343

1346 break;

1347 }

1348

1349 switch (getLexer().getKind()) {

1350 default:

1352

1355 Operands.push_back(BaseReg != VE::NoRegister

1356 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))

1357 : VEOperand::MorphToMEMzi(std::move(Offset)));

1359

1361 if (BaseReg != VE::NoRegister)

1363 Parser.Lex();

1364 break;

1365 }

1366

1367 switch (getLexer().getKind()) {

1368 default:

1369 if (parseRegister(BaseReg, S, E))

1371 break;

1372

1374 Parser.Lex();

1375 if (parseRegister(BaseReg, S, E))

1377 break;

1378

1380 break;

1381 }

1382

1385

1386 Parser.Lex();

1387 Operands.push_back(BaseReg != VE::NoRegister

1388 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))

1389 : VEOperand::MorphToMEMzi(std::move(Offset)));

1390

1392}

1393

1396

1397

1401

1402 Parser.Lex();

1403

1408 getLexer().UnLex(Tok1);

1410 }

1411

1414 getLexer().UnLex(Tok2);

1415 getLexer().UnLex(Tok1);

1417 }

1418 Parser.Lex();

1419

1422 if (Suffix != "1" && Suffix != "0") {

1423 getLexer().UnLex(Tok3);

1424 getLexer().UnLex(Tok2);

1425 getLexer().UnLex(Tok1);

1427 }

1428 Parser.Lex();

1431 VEOperand::CreateMImm(EVal, Suffix == "0", Tok1.getLoc(), EndLoc));

1433}

1434

1439

1440

1441

1442

1444 return Res;

1445

1446 switch (getLexer().getKind()) {

1448

1450 Parser.Lex();

1451

1454 if (!tryParseRegister(Reg1, S1, E1).isSuccess()) {

1455 getLexer().UnLex(Tok1);

1457 }

1458

1461 Parser.Lex();

1462

1465 if (!tryParseRegister(Reg2, S2, E2).isSuccess())

1467

1470

1472 Operands.push_back(VEOperand::CreateReg(Reg1, S1, E1));

1473 Operands.push_back(VEOperand::CreateReg(Reg2, S2, E2));

1476 Parser.Lex();

1477 break;

1478 }

1479 default: {

1480 std::unique_ptr Op;

1481 Res = parseVEAsmOperand(Op);

1484

1485

1487

1489 break;

1490

1491

1492 std::unique_ptr Op1 = VEOperand::CreateToken(

1494 Parser.Lex();

1495

1496 std::unique_ptr Op2;

1497 Res = parseVEAsmOperand(Op2);

1500

1503

1504 Operands.push_back(std::move(Op1));

1505 Operands.push_back(std::move(Op2));

1508 Parser.Lex();

1509 break;

1510 }

1511 }

1512

1514}

1515

1516ParseStatus VEAsmParser::parseVEAsmOperand(std::unique_ptr &Op) {

1521

1522 Op = nullptr;

1523 switch (getLexer().getKind()) {

1524 default:

1525 break;

1526

1529 if (tryParseRegister(Reg, S, E).isSuccess())

1530 Op = VEOperand::CreateReg(Reg, S, E);

1531 break;

1532 }

1537 if (!parseExpression(EVal))

1538 Op = VEOperand::CreateImm(EVal, S, E);

1539 break;

1540 }

1542}

1543

1544

1547}

1548

1549#define GET_REGISTER_MATCHER

1550#define GET_MATCHER_IMPLEMENTATION

1551#include "VEGenAsmMatcher.inc"

1552

1553unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,

1554 unsigned Kind) {

1555 VEOperand &Op = (VEOperand &)GOp;

1556

1557

1558

1559

1560 switch (Kind) {

1561 default:

1562 break;

1563 case MCK_F32:

1564 if (Op.isReg() && VEOperand::MorphToF32Reg(Op))

1566 break;

1567 case MCK_I32:

1568 if (Op.isReg() && VEOperand::MorphToI32Reg(Op))

1570 break;

1571 case MCK_F128:

1572 if (Op.isReg() && VEOperand::MorphToF128Reg(Op))

1574 break;

1575 case MCK_VM512:

1576 if (Op.isReg() && VEOperand::MorphToVM512Reg(Op))

1578 break;

1579 case MCK_MISC:

1580 if (Op.isImm() && VEOperand::MorphToMISCReg(Op))

1582 break;

1583 }

1584 return Match_InvalidOperand;

1585}

static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Analysis containing CSE Info

#define LLVM_EXTERNAL_VISIBILITY

static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)

mir Rename Register Operands

const SmallVectorImpl< MachineOperand > & Cond

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallVector class.

static const MCPhysReg MISCRegs[31]

static MCRegister MatchRegisterAltName(StringRef Name)

Maps from the set of all alternative registernames to a register number.

static const MCPhysReg F128Regs[32]

static MCRegister MatchRegisterName(StringRef Name)

Maps from the set of all register names to a register number.

static const MCPhysReg F32Regs[64]

static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)

static StringRef parseCC(StringRef Name, unsigned Prefix, unsigned Suffix, bool IntegerCC, bool OmitCC, SMLoc NameLoc, OperandVector *Operands)

static const MCPhysReg VM512Regs[8]

LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser()

static const MCPhysReg I32Regs[64]

static StringRef parseRD(StringRef Name, unsigned Prefix, SMLoc NameLoc, OperandVector *Operands)

static bool isMImm(SDValue V)

Target independent representation for an assembler token.

StringRef getString() const

Get the string for the current token, this includes all characters (for example, the quotes on string...

bool is(TokenKind K) const

StringRef getIdentifier() const

Get the identifier string for the current token, which should be an identifier or a string.

This class represents an Operation in the Expression.

Base class for user error types.

Lightweight error class with error context and mandatory checking.

Container class for subtarget features.

Generic assembler parser interface, for use by target specific assembly parsers.

const AsmToken & getTok() const

Get the current AsmToken from the stream.

virtual const AsmToken & Lex()=0

Get the next AsmToken in the stream, possibly handling file inclusion first.

Binary assembler expressions.

const MCExpr * getLHS() const

Get the left-hand side expression of the binary operator.

const MCExpr * getRHS() const

Get the right-hand side expression of the binary operator.

Opcode getOpcode() const

Get the kind of this binary expression.

static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

Base class for the full range of assembler expressions which are needed for parsing.

@ Unary

Unary expressions.

@ Constant

Constant expressions.

@ SymbolRef

References to labels and assigned expressions.

@ Target

Target specific expression.

@ Binary

Binary expressions.

Instances of this class represent a single low-level machine instruction.

void addOperand(const MCOperand Op)

Interface to description of machine instruction set.

static MCOperand createExpr(const MCExpr *Val)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.

virtual SMLoc getStartLoc() const =0

getStartLoc - Get the location of the first token of this operand.

virtual bool isReg() const =0

isReg - Is this a register operand?

virtual bool isMem() const =0

isMem - Is this a memory operand?

virtual MCRegister getReg() const =0

virtual void print(raw_ostream &OS) const =0

print - Print a debug representation of the operand to the given stream.

virtual bool isToken() const =0

isToken - Is this a token operand?

virtual bool isImm() const =0

isImm - Is this an immediate operand?

virtual SMLoc getEndLoc() const =0

getEndLoc - Get the location of the last token of this operand.

Wrapper class representing physical registers. Should be passed by value.

Streaming machine code generation interface.

virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)

Emit the given Instruction into the current section.

Generic base class for all target subtargets.

Represent a reference to a symbol from inside an expression.

const MCSymbol & getSymbol() const

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)

VariantKind getKind() const

MCTargetAsmParser - Generic interface to target specific assembly parsers.

virtual ParseStatus parseDirective(AsmToken DirectiveID)

Parses a target-specific assembler directive.

virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0

Parse one assembly instruction.

virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0

virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0

tryParseRegister - parse one register if possible

virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0

Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...

void setAvailableFeatures(const FeatureBitset &Value)

const MCSubtargetInfo & getSTI() const

virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)

Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...

Unary assembler expressions.

Opcode getOpcode() const

Get the kind of this unary expression.

static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())

const MCExpr * getSubExpr() const

Get the child of this unary expression.

Ternary parse status returned by various parse* methods.

constexpr bool isFailure() const

static constexpr StatusTy Failure

constexpr bool isSuccess() const

static constexpr StatusTy Success

static constexpr StatusTy NoMatch

Represents a location in source code.

static SMLoc getFromPointer(const char *Ptr)

constexpr const char * getPointer() const

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

std::string lower() const

static const VEMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)

LLVM Value Representation.

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant

Alias for the std::variant specialization base class of DbgVariable.

Flag

These should be considered private to the implementation of the MCInstrDesc class.

@ CE

Windows NT (Windows on ARM)

This is an optimization pass for GlobalISel generic memory operations.

Target & getTheVETarget()

static VECC::CondCode stringToVEFCondCode(StringRef S)

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

DWARFExpression::Operation Op

RoundingMode

Rounding mode.

static VERD::RoundingMode stringToVERD(StringRef S)

static VECC::CondCode stringToVEICondCode(StringRef S)

RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...