LLVM: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

38#include

39#include

40#include

41#include

42

43using namespace llvm;

44

45

46

47namespace llvm {

49

50 using namespace SP;

51

52}

53}

54

55namespace {

56

57class SparcOperand;

58

62

63 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };

64

65

66

67

68#define GET_ASSEMBLER_HEADER

69#include "SparcGenAsmMatcher.inc"

70

71

72

73

74 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

77 bool MatchingInlineAsm) override;

80 SMLoc &EndLoc) override;

84

86 unsigned Kind) override;

87

88

90

92

94

96

97 template

99

101

103

105

106 ParseStatus parseSparcAsmOperand(std::unique_ptr &Operand);

107

109

110 ParseStatus parseExpression(int64_t &Val);

111

112

114 const MCExpr *subExpr);

115

116

117 bool isPossibleExpression(const AsmToken &Token);

118

119

120 MatchResultTy mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);

121

122

123 MCRegister matchRegisterName(const AsmToken &Tok, unsigned &RegKind);

124

125 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);

126

128 return getSTI().getTargetTriple().getArch() == Triple::sparcv9;

129 }

130

131 bool expandSET(MCInst &Inst, SMLoc IDLoc,

132 SmallVectorImpl &Instructions);

133

134 bool expandSETSW(MCInst &Inst, SMLoc IDLoc,

135 SmallVectorImpl &Instructions);

136

137 bool expandSETX(MCInst &Inst, SMLoc IDLoc,

138 SmallVectorImpl &Instructions);

139

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

141

142public:

143 SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,

144 const MCInstrInfo &MII, const MCTargetOptions &Options)

145 : MCTargetAsmParser(Options, sti, MII), Parser(parser),

146 MRI(*Parser.getContext().getRegisterInfo()) {

147 Parser.addAliasForDirective(".half", ".2byte");

148 Parser.addAliasForDirective(".uahalf", ".2byte");

149 Parser.addAliasForDirective(".word", ".4byte");

150 Parser.addAliasForDirective(".uaword", ".4byte");

151 Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");

153 Parser.addAliasForDirective(".xword", ".8byte");

154

155

156 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));

157 }

158};

159

160}

161

163 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,

164 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,

165 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,

166 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,

167 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,

168 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,

169 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,

170 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };

171

173 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,

174 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,

175 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,

176 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,

177 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,

178 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,

179 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,

180 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };

181

183 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,

184 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,

185 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,

186 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };

187

189 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,

190 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,

191 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,

192 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};

193

195 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,

196 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,

197 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,

198 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};

199

200namespace {

201

202

203

205public:

206 enum RegisterKind {

207 rk_None,

208 rk_IntReg,

209 rk_IntPairReg,

210 rk_FloatReg,

211 rk_DoubleReg,

212 rk_QuadReg,

213 rk_CoprocReg,

214 rk_CoprocPairReg,

215 rk_Special,

216 };

217

218private:

219 enum KindTy {

220 k_Token,

221 k_Register,

222 k_Immediate,

223 k_MemoryReg,

224 k_MemoryImm,

225 k_ASITag,

226 k_PrefetchTag,

227 k_TailRelocSym,

228 } Kind;

229

230 SMLoc StartLoc, EndLoc;

231

232 struct Token {

233 const char *Data;

234 unsigned Length;

235 };

236

237 struct RegOp {

238 MCRegister Reg;

239 RegisterKind Kind;

240 };

241

242 struct ImmOp {

243 const MCExpr *Val;

244 };

245

246 struct MemOp {

247 MCRegister Base;

248 MCRegister OffsetReg;

249 const MCExpr *Off;

250 };

251

252 union {

253 struct Token Tok;

254 struct RegOp Reg;

255 struct ImmOp Imm;

256 struct MemOp Mem;

257 unsigned ASI;

259 };

260

261public:

262 SparcOperand(KindTy K) : Kind(K) {}

263

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

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

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

267 bool isMem() const override { return isMEMrr() || isMEMri(); }

268 bool isMEMrr() const { return Kind == k_MemoryReg; }

269 bool isMEMri() const { return Kind == k_MemoryImm; }

270 bool isMembarTag() const { return Kind == k_Immediate; }

271 bool isASITag() const { return Kind == k_ASITag; }

272 bool isPrefetchTag() const { return Kind == k_PrefetchTag; }

273 bool isTailRelocSym() const { return Kind == k_TailRelocSym; }

274

275 bool isCallTarget() const {

276 if (!isImm())

277 return false;

278

280 return CE->getValue() % 4 == 0;

281

282 return true;

283 }

284

285 bool isShiftAmtImm5() const {

286 if (!isImm())

287 return false;

288

291

292 return false;

293 }

294

295 bool isShiftAmtImm6() const {

296 if (!isImm())

297 return false;

298

301

302 return false;

303 }

304

306 return (Kind == k_Register && Reg.Kind == rk_IntReg);

307 }

308

309 bool isFloatReg() const {

310 return (Kind == k_Register && Reg.Kind == rk_FloatReg);

311 }

312

313 bool isFloatOrDoubleReg() const {

314 return (Kind == k_Register && (Reg.Kind == rk_FloatReg

315 || Reg.Kind == rk_DoubleReg));

316 }

317

318 bool isCoprocReg() const {

319 return (Kind == k_Register && Reg.Kind == rk_CoprocReg);

320 }

321

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

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

325 }

326

327 MCRegister getReg() const override {

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

329 return Reg.Reg;

330 }

331

332 const MCExpr *getImm() const {

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

334 return Imm.Val;

335 }

336

337 MCRegister getMemBase() const {

338 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");

339 return Mem.Base;

340 }

341

342 MCRegister getMemOffsetReg() const {

343 assert((Kind == k_MemoryReg) && "Invalid access!");

344 return Mem.OffsetReg;

345 }

346

347 const MCExpr *getMemOff() const {

348 assert((Kind == k_MemoryImm) && "Invalid access!");

349 return Mem.Off;

350 }

351

352 unsigned getASITag() const {

353 assert((Kind == k_ASITag) && "Invalid access!");

354 return ASI;

355 }

356

357 unsigned getPrefetchTag() const {

358 assert((Kind == k_PrefetchTag) && "Invalid access!");

360 }

361

362 const MCExpr *getTailRelocSym() const {

363 assert((Kind == k_TailRelocSym) && "Invalid access!");

364 return Imm.Val;

365 }

366

367

368 SMLoc getStartLoc() const override {

369 return StartLoc;

370 }

371

372 SMLoc getEndLoc() const override {

373 return EndLoc;

374 }

375

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

377 switch (Kind) {

378 case k_Token: OS << "Token: " << getToken() << "\n"; break;

379 case k_Register:

380 OS << "Reg: #" << getReg().id() << "\n";

381 break;

382 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;

383 case k_MemoryReg:

384 OS << "Mem: " << getMemBase().id() << "+" << getMemOffsetReg().id()

385 << "\n";

386 break;

387 case k_MemoryImm: assert(getMemOff() != nullptr);

388 OS << "Mem: " << getMemBase().id() << "+";

390 OS << "\n";

391 break;

392 case k_ASITag:

393 OS << "ASI tag: " << getASITag() << "\n";

394 break;

395 case k_PrefetchTag:

396 OS << "Prefetch tag: " << getPrefetchTag() << "\n";

397 break;

398 case k_TailRelocSym:

399 OS << "TailReloc: " << getTailRelocSym() << "\n";

400 break;

401 }

402 }

403

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

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

407 }

408

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

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

411 const MCExpr *Expr = getImm();

412 addExpr(Inst, Expr);

413 }

414

415 void addShiftAmtImm5Operands(MCInst &Inst, unsigned N) const {

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

417 addExpr(Inst, getImm());

418 }

419 void addShiftAmtImm6Operands(MCInst &Inst, unsigned N) const {

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

421 addExpr(Inst, getImm());

422 }

423

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

425

426 if (!Expr)

430 else

432 }

433

434 void addMEMrrOperands(MCInst &Inst, unsigned N) const {

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

436

438

439 assert(getMemOffsetReg().isValid() && "Invalid offset");

441 }

442

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

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

445

447

448 const MCExpr *Expr = getMemOff();

449 addExpr(Inst, Expr);

450 }

451

452 void addASITagOperands(MCInst &Inst, unsigned N) const {

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

455 }

456

457 void addPrefetchTagOperands(MCInst &Inst, unsigned N) const {

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

460 }

461

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

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

464 const MCExpr *Expr = getImm();

465 addExpr(Inst, Expr);

466 }

467

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

470 addExpr(Inst, getImm());

471 }

472

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

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

475 addExpr(Inst, getTailRelocSym());

476 }

477

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

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

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

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

482 Op->StartLoc = S;

483 Op->EndLoc = S;

484 return Op;

485 }

486

487 static std::unique_ptr CreateReg(MCRegister Reg, unsigned Kind,

488 SMLoc S, SMLoc E) {

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

490 Op->Reg.Reg = Reg;

491 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;

492 Op->StartLoc = S;

493 Op->EndLoc = E;

494 return Op;

495 }

496

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

498 SMLoc E) {

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

500 Op->Imm.Val = Val;

501 Op->StartLoc = S;

502 Op->EndLoc = E;

503 return Op;

504 }

505

506 static std::unique_ptr CreateASITag(unsigned Val, SMLoc S,

507 SMLoc E) {

508 auto Op = std::make_unique(k_ASITag);

509 Op->ASI = Val;

510 Op->StartLoc = S;

511 Op->EndLoc = E;

512 return Op;

513 }

514

515 static std::unique_ptr CreatePrefetchTag(unsigned Val, SMLoc S,

516 SMLoc E) {

517 auto Op = std::make_unique(k_PrefetchTag);

518 Op->Prefetch = Val;

519 Op->StartLoc = S;

520 Op->EndLoc = E;

521 return Op;

522 }

523

524 static std::unique_ptr CreateTailRelocSym(const MCExpr *Val,

525 SMLoc S, SMLoc E) {

526 auto Op = std::make_unique(k_TailRelocSym);

527 Op->Imm.Val = Val;

528 Op->StartLoc = S;

529 Op->EndLoc = E;

530 return Op;

531 }

532

533 static bool MorphToIntPairReg(SparcOperand &Op) {

534 MCRegister Reg = Op.getReg();

535 assert(Op.Reg.Kind == rk_IntReg);

536 unsigned regIdx = 32;

537 if (Reg >= Sparc::G0 && Reg <= Sparc::G7)

538 regIdx = Reg - Sparc::G0;

539 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)

540 regIdx = Reg - Sparc::O0 + 8;

541 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)

542 regIdx = Reg - Sparc::L0 + 16;

543 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)

544 regIdx = Reg - Sparc::I0 + 24;

545 if (regIdx % 2 || regIdx > 31)

546 return false;

548 Op.Reg.Kind = rk_IntPairReg;

549 return true;

550 }

551

552 static bool MorphToDoubleReg(SparcOperand &Op) {

553 MCRegister Reg = Op.getReg();

554 assert(Op.Reg.Kind == rk_FloatReg);

555 unsigned regIdx = Reg - Sparc::F0;

556 if (regIdx % 2 || regIdx > 31)

557 return false;

559 Op.Reg.Kind = rk_DoubleReg;

560 return true;

561 }

562

563 static bool MorphToQuadReg(SparcOperand &Op) {

564 MCRegister Reg = Op.getReg();

565 unsigned regIdx = 0;

566 switch (Op.Reg.Kind) {

568 case rk_FloatReg:

569 regIdx = Reg - Sparc::F0;

570 if (regIdx % 4 || regIdx > 31)

571 return false;

573 break;

574 case rk_DoubleReg:

575 regIdx = Reg - Sparc::D0;

576 if (regIdx % 2 || regIdx > 31)

577 return false;

579 break;

580 }

581 Op.Reg.Reg = Reg;

582 Op.Reg.Kind = rk_QuadReg;

583 return true;

584 }

585

586 static bool MorphToCoprocPairReg(SparcOperand &Op) {

587 MCRegister Reg = Op.getReg();

588 assert(Op.Reg.Kind == rk_CoprocReg);

589 unsigned regIdx = 32;

590 if (Reg >= Sparc::C0 && Reg <= Sparc::C31)

591 regIdx = Reg - Sparc::C0;

592 if (regIdx % 2 || regIdx > 31)

593 return false;

595 Op.Reg.Kind = rk_CoprocPairReg;

596 return true;

597 }

598

599 static std::unique_ptr

600 MorphToMEMrr(MCRegister Base, std::unique_ptr Op) {

601 MCRegister offsetReg = Op->getReg();

602 Op->Kind = k_MemoryReg;

604 Op->Mem.OffsetReg = offsetReg;

605 Op->Mem.Off = nullptr;

606 return Op;

607 }

608

609 static std::unique_ptr CreateMEMr(MCRegister Base, SMLoc S,

610 SMLoc E) {

611 auto Op = std::make_unique(k_MemoryReg);

613 Op->Mem.OffsetReg = Sparc::G0;

614 Op->Mem.Off = nullptr;

615 Op->StartLoc = S;

616 Op->EndLoc = E;

617 return Op;

618 }

619

620 static std::unique_ptr

621 MorphToMEMri(MCRegister Base, std::unique_ptr Op) {

622 const MCExpr *Imm = Op->getImm();

623 Op->Kind = k_MemoryImm;

625 Op->Mem.OffsetReg = MCRegister();

626 Op->Mem.Off = Imm;

627 return Op;

628 }

629};

630

631}

632

633#define GET_MATCHER_IMPLEMENTATION

634#define GET_REGISTER_MATCHER

635#define GET_MNEMONIC_SPELL_CHECKER

636#include "SparcGenAsmMatcher.inc"

637

638

639

640SparcAsmParser::MatchResultTy

641SparcAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {

642

644

645

646 const MatchEntry *Start, *End;

647 switch (VariantID) {

648 default:

650 case 0:

651 Start = std::begin(MatchTable0);

652 End = std::end(MatchTable0);

653 break;

654 }

655

656

657 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());

658

659 if (MnemonicRange.first == MnemonicRange.second)

660 return Match_MnemonicFail;

661

662 for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;

663 it != ie; ++it) {

665 FeatureBitsets[it->RequiredFeaturesIdx];

666 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)

667 return Match_Success;

668 }

669 return Match_MissingFeature;

670}

671

672bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,

673 SmallVectorImpl &Instructions) {

674 MCOperand MCRegOp = Inst.getOperand(0);

675 MCOperand MCValOp = Inst.getOperand(1);

678

679

681 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;

682

683

684 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {

685 return Error(IDLoc,

686 "set: argument must be between -2147483648 and 4294967295");

687 }

688

689

690

691 int32_t ImmValue = RawImmValue;

692

693

694

695 bool IsEffectivelyImm13 =

696 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);

697 const MCExpr *ValExpr;

698 if (IsImm)

700 else

701 ValExpr = MCValOp.getExpr();

702

704

705

706

707

708 if (!IsEffectivelyImm13) {

709 MCInst TmpInst;

710 const MCExpr *Expr = adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr);

711 TmpInst.setLoc(IDLoc);

716 PrevReg = MCRegOp;

717 }

718

719

720

721

722

723

724

725

726

727

728

729 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {

730 MCInst TmpInst;

731 const MCExpr *Expr;

732 if (IsEffectivelyImm13)

733 Expr = ValExpr;

734 else

735 Expr = adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);

736 TmpInst.setLoc(IDLoc);

742 }

743 return false;

744}

745

746bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,

747 SmallVectorImpl &Instructions) {

748 MCOperand MCRegOp = Inst.getOperand(0);

749 MCOperand MCValOp = Inst.getOperand(1);

752

753

755 int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;

758

759 bool IsSmallImm = IsImm && isInt<13>(ImmValue);

760 bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);

761

763

765 return Error(IDLoc,

766 "set: argument must be between -2147483648 and 2147483647");

767 }

768

769

770 if (!IsSmallImm) {

771

773 MCInstBuilder(SP::SETHIi)

774 .addReg(MCRegOp.getReg())

775 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));

776

777 PrevReg = MCRegOp;

778 }

779

780

781 if (!NoLowBitsImm || IsSmallImm) {

782 const MCExpr *Expr =

783 IsSmallImm ? ValExpr : adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);

784

785

786 Instructions.push_back(MCInstBuilder(SP::ORri)

787 .addReg(MCRegOp.getReg())

788 .addReg(PrevReg.getReg())

789 .addExpr(Expr));

790

791

792 if (IsSmallImm)

793 return false;

794 }

795

796

797 if (!IsImm || ImmValue < 0) {

798

799 Instructions.push_back(MCInstBuilder(SP::SRArr)

800 .addReg(MCRegOp.getReg())

801 .addReg(MCRegOp.getReg())

802 .addReg(Sparc::G0));

803 }

804

805 return false;

806}

807

808bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,

809 SmallVectorImpl &Instructions) {

810 MCOperand MCRegOp = Inst.getOperand(0);

811 MCOperand MCValOp = Inst.getOperand(1);

812 MCOperand MCTmpOp = Inst.getOperand(2);

815

816

817 bool IsImm = MCValOp.isImm();

818 int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;

819

822

823

824 if (IsImm && isInt<13>(ImmValue)) {

825

826 Instructions.push_back(MCInstBuilder(SP::ORri)

827 .addReg(MCRegOp.getReg())

828 .addReg(Sparc::G0)

829 .addExpr(ValExpr));

830 return false;

831 }

832

833

834

835

837 MCInstBuilder(SP::SETHIi)

838 .addReg(MCRegOp.getReg())

839 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));

840

842 MCInstBuilder(SP::ORri)

843 .addReg(MCRegOp.getReg())

844 .addReg(MCRegOp.getReg())

845 .addExpr(adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr)));

846

847

848

850 return false;

851

852

853

854

855

856 Instructions.push_back(MCInstBuilder(SP::SETHIi)

857 .addReg(MCTmpOp.getReg())

859 ValExpr, ELF::R_SPARC_HH22, getContext())));

860

861 Instructions.push_back(MCInstBuilder(SP::ORri)

862 .addReg(MCTmpOp.getReg())

863 .addReg(MCTmpOp.getReg())

865 ValExpr, ELF::R_SPARC_HM10, getContext())));

866

867 Instructions.push_back(MCInstBuilder(SP::SLLXri)

868 .addReg(MCTmpOp.getReg())

869 .addReg(MCTmpOp.getReg())

870 .addImm(32));

871

872 Instructions.push_back(MCInstBuilder(SP::ORrr)

873 .addReg(MCRegOp.getReg())

874 .addReg(MCTmpOp.getReg())

875 .addReg(MCRegOp.getReg()));

876

877 return false;

878}

879

880bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

882 MCStreamer &Out,

883 uint64_t &ErrorInfo,

884 bool MatchingInlineAsm) {

885 MCInst Inst;

887 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,

888 MatchingInlineAsm);

889 switch (MatchResult) {

890 case Match_Success: {

892 default:

895 break;

896 case SP::SET:

897 if (expandSET(Inst, IDLoc, Instructions))

898 return true;

899 break;

900 case SP::SETSW:

901 if (expandSETSW(Inst, IDLoc, Instructions))

902 return true;

903 break;

904 case SP::SETX:

905 if (expandSETX(Inst, IDLoc, Instructions))

906 return true;

907 break;

908 }

909

910 for (const MCInst &I : Instructions) {

912 }

913 return false;

914 }

915

916 case Match_MissingFeature:

917 return Error(IDLoc,

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

919

920 case Match_InvalidOperand: {

921 SMLoc ErrorLoc = IDLoc;

922 if (ErrorInfo != ~0ULL) {

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

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

925

926 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();

927 if (ErrorLoc == SMLoc())

928 ErrorLoc = IDLoc;

929 }

930

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

932 }

933 case Match_MnemonicFail:

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

935 }

937}

938

939bool SparcAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,

940 SMLoc &EndLoc) {

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

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

943 return false;

944}

945

946ParseStatus SparcAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

947 SMLoc &EndLoc) {

948 const AsmToken &Tok = Parser.getTok();

949 StartLoc = Tok.getLoc();

951 Reg = Sparc::NoRegister;

954 Parser.Lex();

955 unsigned RegKind = SparcOperand::rk_None;

956 Reg = matchRegisterName(Tok, RegKind);

957 if (Reg) {

958 Parser.Lex();

960 }

961

962 getLexer().UnLex(Tok);

964}

965

966bool SparcAsmParser::parseInstruction(ParseInstructionInfo &Info,

967 StringRef Name, SMLoc NameLoc,

969

970

971

972

973

974

975

976

977

978 MatchResultTy MS = mnemonicIsValid(Name, 0);

979 switch (MS) {

980 case Match_Success:

981 break;

982 case Match_MissingFeature:

983 return Error(NameLoc,

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

985 case Match_MnemonicFail:

986 return Error(NameLoc,

987 "invalid instruction mnemonic" +

988 SparcMnemonicSpellCheck(Name, getAvailableFeatures(), 0));

989 default:

991 }

992

993

994 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));

995

996

998

1000

1002 if (!parseBranchModifiers(Operands).isSuccess()) {

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

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

1005 }

1006 }

1007 if (!parseOperand(Operands, Name).isSuccess()) {

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

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

1010 }

1011

1014

1016 }

1017 Parser.Lex();

1018

1019 if (!parseOperand(Operands, Name).isSuccess()) {

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

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

1022 }

1023 }

1024 }

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

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

1028 }

1029 Parser.Lex();

1030 return false;

1031}

1032

1033ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {

1034 StringRef IDVal = DirectiveID.getString();

1035

1036 if (IDVal == ".register") {

1037

1040 }

1041 if (IDVal == ".proc") {

1042

1043

1046 }

1047

1048

1050}

1051

1052ParseStatus SparcAsmParser::parseMEMOperand(OperandVector &Operands) {

1053 SMLoc S, E;

1054

1055 std::unique_ptr LHS;

1056 if (!parseSparcAsmOperand(LHS).isSuccess())

1058

1059

1060 if (LHS->isImm()) {

1061 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));

1063 }

1064

1065 if (LHS->isIntReg())

1066 return Error(LHS->getStartLoc(), "invalid register kind for this operand");

1067

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

1069

1070

1073

1074 std::unique_ptr RHS;

1075 if (!parseSparcAsmOperand(RHS).isSuccess())

1077

1078 if (RHS->isReg() && RHS->isIntReg())

1079 return Error(RHS->getStartLoc(),

1080 "invalid register kind for this operand");

1081

1083 RHS->isImm()

1084 ? SparcOperand::MorphToMEMri(LHS->getReg(), std::move(RHS))

1085 : SparcOperand::MorphToMEMrr(LHS->getReg(), std::move(RHS)));

1086

1088 }

1089

1090 Operands.push_back(SparcOperand::CreateMEMr(LHS->getReg(), S, E));

1092}

1093

1094template

1095ParseStatus SparcAsmParser::parseShiftAmtImm(OperandVector &Operands) {

1098

1099

1102

1103 const MCExpr *Expr;

1104 if (getParser().parseExpression(Expr))

1106

1108 if (!CE)

1109 return Error(S, "constant expression expected");

1110

1112 return Error(S, "immediate shift value out of range");

1113

1114 Operands.push_back(SparcOperand::CreateImm(Expr, S, E));

1116}

1117

1118template <SparcAsmParser::TailRelocKind Kind>

1119ParseStatus SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {

1120 SMLoc S = getLoc();

1122

1123 auto MatchesKind = [](uint16_t RelType) -> bool {

1124 switch (Kind) {

1125 case TailRelocKind::Load_GOT:

1126

1127

1128 return RelType == ELF::R_SPARC_GOTDATA_OP;

1129 case TailRelocKind::Add_TLS:

1130

1131

1132 switch (RelType) {

1133 case ELF::R_SPARC_TLS_GD_ADD:

1134 case ELF::R_SPARC_TLS_IE_ADD:

1135 case ELF::R_SPARC_TLS_LDM_ADD:

1136 case ELF::R_SPARC_TLS_LDO_ADD:

1137 return true;

1138 default:

1139 return false;

1140 }

1141 case TailRelocKind::Load_TLS:

1142

1143

1144 switch (RelType) {

1145 case ELF::R_SPARC_TLS_IE_LD:

1146 case ELF::R_SPARC_TLS_IE_LDX:

1147 return true;

1148 default:

1149 return false;

1150 }

1151 case TailRelocKind::Call_TLS:

1152

1153

1154 switch (RelType) {

1155 case ELF::R_SPARC_TLS_GD_CALL:

1156 case ELF::R_SPARC_TLS_LDM_CALL:

1157 return true;

1158 default:

1159 return false;

1160 }

1161 }

1162 llvm_unreachable("Unhandled SparcAsmParser::TailRelocKind enum");

1163 };

1164

1167

1168 const AsmToken Tok = Parser.getTok();

1169 getParser().Lex();

1170

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

1173

1174 StringRef Name = getParser().getTok().getIdentifier();

1176 if (RelType == 0)

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

1178

1179 if (!MatchesKind(RelType)) {

1180

1181 getLexer().UnLex(Tok);

1183 }

1184

1185 Parser.Lex();

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

1188

1189 getParser().Lex();

1190 const MCExpr *SubExpr;

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

1193

1194 const MCExpr *Val = adjustPICRelocation(RelType, SubExpr);

1195 Operands.push_back(SparcOperand::CreateTailRelocSym(Val, S, E));

1197}

1198

1199ParseStatus SparcAsmParser::parseMembarTag(OperandVector &Operands) {

1201 const MCExpr *EVal;

1202 int64_t ImmVal = 0;

1203

1204 std::unique_ptr Mask;

1205 if (parseSparcAsmOperand(Mask).isSuccess()) {

1206 if (Mask->isImm() || Mask->getImm()->evaluateAsAbsolute(ImmVal) ||

1207 ImmVal < 0 || ImmVal > 127)

1208 return Error(S, "invalid membar mask number");

1209 }

1210

1212 SMLoc TagStart = getLexer().getLoc();

1213 Parser.Lex();

1214 unsigned MaskVal = StringSwitch(Parser.getTok().getString())

1215 .Case("LoadLoad", 0x1)

1216 .Case("StoreLoad", 0x2)

1217 .Case("LoadStore", 0x4)

1218 .Case("StoreStore", 0x8)

1219 .Case("Lookaside", 0x10)

1220 .Case("MemIssue", 0x20)

1221 .Case("Sync", 0x40)

1222 .Default(0);

1223

1224 Parser.Lex();

1225

1226 if (!MaskVal)

1227 return Error(TagStart, "unknown membar tag");

1228

1229 ImmVal |= MaskVal;

1230

1232 Parser.Lex();

1233 }

1234

1237 Operands.push_back(SparcOperand::CreateImm(EVal, S, E));

1239}

1240

1241ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) {

1244 int64_t ASIVal = 0;

1245

1247

1248

1249 ParseStatus ParseExprStatus = parseExpression(ASIVal);

1250 if (!ParseExprStatus.isSuccess())

1251 return ParseExprStatus;

1252

1254 return Error(S, "invalid ASI number, must be between 0 and 255");

1255

1256 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));

1258 }

1259

1260

1261

1262 SMLoc TagStart = getLexer().peekTok(false).getLoc();

1263 Parser.Lex();

1265 const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName);

1266 if (!ASITag)

1267 ASITag = SparcASITag::lookupASITagByAltName(ASIName);

1268 Parser.Lex();

1269

1270 if (!ASITag)

1271 return Error(TagStart, "unknown ASI tag");

1272

1274

1275 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));

1277}

1278

1279ParseStatus SparcAsmParser::parsePrefetchTag(OperandVector &Operands) {

1282 int64_t PrefetchVal = 0;

1283

1285

1286

1287 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);

1288 if (!ParseExprStatus.isSuccess())

1289 return ParseExprStatus;

1290

1292 return Error(S, "invalid prefetch number, must be between 0 and 31");

1293

1294 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));

1296 }

1297

1298 SMLoc TagStart = getLexer().peekTok(false).getLoc();

1299 Parser.Lex();

1300 const StringRef PrefetchName = Parser.getTok().getString();

1301 const SparcPrefetchTag::PrefetchTag *PrefetchTag =

1302 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);

1303 Parser.Lex();

1304

1305 if (!PrefetchTag)

1306 return Error(TagStart, "unknown prefetch tag");

1307

1308 PrefetchVal = PrefetchTag->Encoding;

1309

1310 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));

1312}

1313

1314ParseStatus SparcAsmParser::parseCallTarget(OperandVector &Operands) {

1317

1318 switch (getLexer().getKind()) {

1319 default:

1325 break;

1326 }

1327

1328 const MCExpr *DestValue;

1329 if (getParser().parseExpression(DestValue))

1331

1332 Operands.push_back(SparcOperand::CreateImm(DestValue, S, E));

1334}

1335

1336ParseStatus SparcAsmParser::parseOperand(OperandVector &Operands,

1337 StringRef Mnemonic) {

1338

1339 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);

1340

1341

1342

1343

1345 return Res;

1346

1348

1349 Operands.push_back(SparcOperand::CreateToken("[",

1351 Parser.Lex();

1352

1353 if (Mnemonic == "cas" || Mnemonic == "casl" || Mnemonic == "casa" ||

1354 Mnemonic == "casx" || Mnemonic == "casxl" || Mnemonic == "casxa") {

1358 Parser.Lex();

1359

1360 unsigned RegKind;

1361 MCRegister Reg = matchRegisterName(Parser.getTok(), RegKind);

1362 if (Reg)

1364

1365 Parser.Lex();

1367 Operands.push_back(SparcOperand::CreateReg(Reg, RegKind, S, E));

1369 } else {

1370 Res = parseMEMOperand(Operands);

1371 }

1372

1374 return Res;

1375

1378

1379 Operands.push_back(SparcOperand::CreateToken("]",

1381 Parser.Lex();

1382

1383

1384

1385

1390 S, "malformed ASI tag, must be a constant integer expression");

1391

1392 Parser.Lex();

1393 const AsmToken Tok = Parser.getTok();

1395

1396

1397

1398

1399

1400 SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.size() - 2];

1401 if (OldMemOp.isMEMrr()) {

1402 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {

1403 return Error(S, "invalid operand for instruction");

1404 }

1405 Operands[Operands.size() - 2] = SparcOperand::MorphToMEMri(

1406 OldMemOp.getMemBase(),

1408 OldMemOp.getStartLoc(),

1409 OldMemOp.getEndLoc()));

1410 }

1411 Parser.Lex();

1412

1413

1414

1415

1416 Operands.push_back(SparcOperand::CreateToken("%asi", S));

1418 }

1419

1420 return Error(S, "malformed ASI tag, must be %asi, a constant integer "

1421 "expression, or a named tag");

1422 }

1423

1424

1425

1428 return parseASITag(Operands);

1430 }

1431

1432 std::unique_ptr Op;

1433

1434 Res = parseSparcAsmOperand(Op);

1437

1438

1440

1442}

1443

1444ParseStatus

1445SparcAsmParser::parseSparcAsmOperand(std::unique_ptr &Op) {

1448 const MCExpr *EVal;

1449

1450 Op = nullptr;

1451 switch (getLexer().getKind()) {

1452 default: break;

1453

1455 Parser.Lex();

1456 unsigned RegKind;

1457 if (MCRegister Reg = matchRegisterName(Parser.getTok(), RegKind)) {

1459 Parser.Lex();

1461 if (Reg == Sparc::ICC && Name == "xcc")

1462 Op = SparcOperand::CreateToken("%xcc", S);

1463 else

1464 Op = SparcOperand::CreateReg(Reg, RegKind, S, E);

1465 break;

1466 }

1467 if (matchSparcAsmModifiers(EVal, E)) {

1469 Op = SparcOperand::CreateImm(EVal, S, E);

1470 }

1471 break;

1472 }

1473

1480 if (getParser().parseExpression(EVal, E))

1481 break;

1482

1483 Op = SparcOperand::CreateImm(EVal, S, E);

1484 break;

1485 }

1487}

1488

1489ParseStatus SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {

1490

1491

1493 Parser.Lex();

1494

1498 if (modName == "a" || modName == "pn" || modName == "pt") {

1499 Operands.push_back(SparcOperand::CreateToken(modName,

1501 Parser.Lex();

1502 }

1503 }

1505}

1506

1507ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {

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

1509

1510 if (!isPossibleExpression(Tok))

1512

1513 return getParser().parseAbsoluteExpression(Val);

1514}

1515

1516MCRegister SparcAsmParser::matchRegisterName(const AsmToken &Tok,

1517 unsigned &RegKind) {

1518 RegKind = SparcOperand::rk_None;

1520 return SP::NoRegister;

1521

1524 if (Reg)

1526

1527 if (Reg) {

1528

1529

1530

1531

1532

1533

1534 if (Reg == SP::ASR4 && Name == "tick") {

1535 RegKind = SparcOperand::rk_Special;

1536 return SP::TICK;

1537 }

1538

1539 if (MRI.getRegClass(SP::IntRegsRegClassID).contains(Reg)) {

1540 RegKind = SparcOperand::rk_IntReg;

1541 return Reg;

1542 }

1543 if (MRI.getRegClass(SP::FPRegsRegClassID).contains(Reg)) {

1544 RegKind = SparcOperand::rk_FloatReg;

1545 return Reg;

1546 }

1547 if (MRI.getRegClass(SP::CoprocRegsRegClassID).contains(Reg)) {

1548 RegKind = SparcOperand::rk_CoprocReg;

1549 return Reg;

1550 }

1551

1552

1553 if (MRI.getRegClass(SP::IntPairRegClassID).contains(Reg)) {

1554 RegKind = SparcOperand::rk_IntReg;

1555 return MRI.getSubReg(Reg, SP::sub_even);

1556 }

1557

1558

1559 if (MRI.getRegClass(SP::DFPRegsRegClassID).contains(Reg)) {

1560

1561 if (MCRegister SubReg = MRI.getSubReg(Reg, SP::sub_even)) {

1562 RegKind = SparcOperand::rk_FloatReg;

1564 }

1565 RegKind = SparcOperand::rk_DoubleReg;

1566 return Reg;

1567 }

1568

1569

1570

1571 assert(MRI.getRegClass(SP::QFPRegsRegClassID).contains(Reg));

1572

1573

1574 if (MRI.getRegClass(SP::CoprocPairRegClassID).contains(Reg)) {

1575 RegKind = SparcOperand::rk_CoprocReg;

1576 return MRI.getSubReg(Reg, SP::sub_even);

1577 }

1578

1579

1580 RegKind = SparcOperand::rk_Special;

1581 return Reg;

1582 }

1583

1584

1585

1586

1587

1588 int64_t RegNo = 0;

1589 if (Name.starts_with_insensitive("r") &&

1590 Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {

1591 RegKind = SparcOperand::rk_IntReg;

1593 }

1594

1595 if (Name == "xcc") {

1596

1597 RegKind = SparcOperand::rk_Special;

1598 return SP::ICC;

1599 }

1600

1601

1602

1603 if (Name == "pcr") {

1604 RegKind = SparcOperand::rk_Special;

1605 return SP::ASR16;

1606 }

1607 if (Name == "pic") {

1608 RegKind = SparcOperand::rk_Special;

1609 return SP::ASR17;

1610 }

1611 if (Name == "dcr") {

1612 RegKind = SparcOperand::rk_Special;

1613 return SP::ASR18;

1614 }

1615 if (Name == "gsr") {

1616 RegKind = SparcOperand::rk_Special;

1617 return SP::ASR19;

1618 }

1619 if (Name == "set_softint") {

1620 RegKind = SparcOperand::rk_Special;

1621 return SP::ASR20;

1622 }

1623 if (Name == "clear_softint") {

1624 RegKind = SparcOperand::rk_Special;

1625 return SP::ASR21;

1626 }

1627 if (Name == "softint") {

1628 RegKind = SparcOperand::rk_Special;

1629 return SP::ASR22;

1630 }

1631 if (Name == "tick_cmpr") {

1632 RegKind = SparcOperand::rk_Special;

1633 return SP::ASR23;

1634 }

1635 if (Name == "stick" || Name == "sys_tick") {

1636 RegKind = SparcOperand::rk_Special;

1637 return SP::ASR24;

1638 }

1639 if (Name == "stick_cmpr" || Name == "sys_tick_cmpr") {

1640 RegKind = SparcOperand::rk_Special;

1641 return SP::ASR25;

1642 }

1643

1644 return SP::NoRegister;

1645}

1646

1647

1648

1650 switch (Expr->getKind()) {

1654 break;

1655

1657 break;

1658

1662 }

1663

1666 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");

1667 }

1668

1671

1674 }

1675 return false;

1676}

1677

1678const MCSpecifierExpr *

1679SparcAsmParser::adjustPICRelocation(uint16_t RelType, const MCExpr *subExpr) {

1680

1681

1682

1683

1684

1685 if (getContext().getObjectFileInfo()->isPositionIndependent()) {

1686 switch (RelType) {

1687 default: break;

1688 case ELF::R_SPARC_LO10:

1689 RelType =

1690 hasGOTReference(subExpr) ? ELF::R_SPARC_PC10 : ELF::R_SPARC_GOT10;

1691 break;

1692 case ELF::R_SPARC_HI22:

1693 RelType =

1694 hasGOTReference(subExpr) ? ELF::R_SPARC_PC22 : ELF::R_SPARC_GOT22;

1695 break;

1696 }

1697 }

1698

1700}

1701

1702bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,

1703 SMLoc &EndLoc) {

1704 AsmToken Tok = Parser.getTok();

1706 return false;

1707

1709

1711 switch (VK) {

1712 case 0:

1713 Error(getLoc(), "invalid relocation specifier");

1714 return false;

1715

1716 case ELF::R_SPARC_GOTDATA_OP:

1717 case ELF::R_SPARC_TLS_GD_ADD:

1718 case ELF::R_SPARC_TLS_GD_CALL:

1719 case ELF::R_SPARC_TLS_IE_ADD:

1720 case ELF::R_SPARC_TLS_IE_LD:

1721 case ELF::R_SPARC_TLS_IE_LDX:

1722 case ELF::R_SPARC_TLS_LDM_ADD:

1723 case ELF::R_SPARC_TLS_LDM_CALL:

1724 case ELF::R_SPARC_TLS_LDO_ADD:

1725

1726 return false;

1727

1728 default:

1729 break;

1730 }

1731

1732 Parser.Lex();

1734 return false;

1735

1736 Parser.Lex();

1737 const MCExpr *subExpr;

1739 return false;

1740

1741 EVal = adjustPICRelocation(VK, subExpr);

1742 return true;

1743}

1744

1745bool SparcAsmParser::isPossibleExpression(const AsmToken &Token) {

1746 switch (Token.getKind()) {

1753 return true;

1754 default:

1755 return false;

1756 }

1757}

1758

1765

1766unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,

1767 unsigned Kind) {

1768 SparcOperand &Op = (SparcOperand &)GOp;

1769 if (Op.isFloatOrDoubleReg()) {

1770 switch (Kind) {

1771 default: break;

1772 case MCK_DFPRegs:

1773 if (Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))

1775 break;

1776 case MCK_QFPRegs:

1777 if (SparcOperand::MorphToQuadReg(Op))

1779 break;

1780 }

1781 }

1782 if (Op.isIntReg() && Kind == MCK_IntPair) {

1783 if (SparcOperand::MorphToIntPairReg(Op))

1785 }

1786 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {

1787 if (SparcOperand::MorphToCoprocPairReg(Op))

1789 }

1790 return Match_InvalidOperand;

1791}

unsigned const MachineRegisterInfo * MRI

static MCRegister MatchRegisterName(StringRef Name)

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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

static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info, bool IsDynamicVGPRChainCall=false)

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

#define LLVM_EXTERNAL_VISIBILITY

loop data Loop Data Prefetch

static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)

static bool isReg(const MCInst &MI, unsigned OpNo)

static bool isValid(const char C)

Returns true if C is a valid mangled character: <0-9a-zA-Z_>.

This file defines the SmallVector class.

static const MCPhysReg DoubleRegs[32]

Definition SparcAsmParser.cpp:172

static bool hasGOTReference(const MCExpr *Expr)

Definition SparcAsmParser.cpp:1649

static const MCPhysReg IntRegs[32]

Definition SparcAsmParser.cpp:162

LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser()

Definition SparcAsmParser.cpp:1760

static const MCPhysReg IntPairRegs[]

Definition SparcAsmParser.cpp:188

static const MCPhysReg QuadFPRegs[32]

Definition SparcAsmParser.cpp:182

static const MCPhysReg CoprocPairRegs[]

Definition SparcAsmParser.cpp:194

static bool is64Bit(const char *name)

Target independent representation for an assembler token.

LLVM_ABI SMLoc getLoc() const

StringRef getString() const

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

bool is(TokenKind K) const

TokenKind getKind() const

LLVM_ABI SMLoc getEndLoc() const

Base class for user error types.

Container class for subtarget features.

void printExpr(raw_ostream &, const MCExpr &) const

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

virtual void eatToEndOfStatement()=0

Skip to the end of the current statement, for error recovery.

const AsmToken & getTok() const

Get the current AsmToken from the stream.

virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0

Parse an arbitrary expression, assuming that an initial '(' has already been consumed.

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.

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.

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

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.

@ Specifier

Expression with a relocation specifier.

@ Binary

Binary expressions.

unsigned getOpcode() const

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

const MCOperand & getOperand(unsigned i) 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...

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

constexpr unsigned id() const

Extension point for target-specific MCExpr subclasses with a relocation specifier,...

static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())

Streaming machine code generation interface.

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

Emit the given Instruction into the current section.

Represent a reference to a symbol from inside an expression.

const MCSymbol & getSymbol() const

StringRef getName() const

getName - Get the symbol name.

MCTargetAsmParser - Generic interface to target specific assembly parsers.

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

void push_back(const T &Elt)

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

#define llvm_unreachable(msg)

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

constexpr std::underlying_type_t< E > Mask()

Get a bitmask with 1s in all places up to the high-order bit of E's largest value.

@ C

The default llvm calling convention, compatible with C.

bool isIntReg(MCRegister Reg)

MCExpr const & getExpr(MCExpr const &Expr)

Definition SparcAsmParser.cpp:48

uint16_t parseSpecifier(StringRef name)

@ CE

Windows NT (Windows on ARM)

Context & getContext() const

This is an optimization pass for GlobalISel generic memory operations.

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.

Target & getTheSparcTarget()

SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

constexpr bool isUInt(uint64_t x)

Checks if an unsigned integer fits into the given bit width.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

Target & getTheSparcV9Target()

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

Target & getTheSparcelTarget()

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