LLVM: lib/Target/M68k/AsmParser/M68kAsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

13

20

21#include

22

23#define DEBUG_TYPE "m68k-asm-parser"

24

25using namespace llvm;

26

28 "m68k-register-prefix-optional", cl::Hidden,

29 cl::desc("Enable specifying registers without the % prefix"),

31

32namespace {

33

37

38#define GET_ASSEMBLER_HEADER

39#include "M68kGenAsmMatcher.inc"

40

41

48

49

50 void eatComma();

51

52 bool isExpr();

56

57public:

62 MRI = getContext().getRegisterInfo();

63

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

65 }

66

67 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,

68 unsigned Kind) override;

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

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

71 SMLoc &EndLoc) override;

72 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,

74 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

76 uint64_t &ErrorInfo,

77 bool MatchingInlineAsm) override;

78};

79

80struct M68kMemOp {

81 enum class Kind {

82 Addr,

83 RegMask,

85 RegIndirect,

86 RegPostIncrement,

87 RegPreDecrement,

88 RegIndirectDisplacement,

89 RegIndirectDisplacementIndex,

90 };

91

92

93

94

95

96

97

98

99

100

101

102

103 Kind Op;

104 MCRegister OuterReg;

105 MCRegister InnerReg;

106 const MCExpr *OuterDisp;

107 const MCExpr *InnerDisp;

108 uint8_t Size : 4;

109 uint8_t Scale : 4;

110 const MCExpr *Expr;

111 uint16_t RegMask;

112

113 M68kMemOp() {}

114 M68kMemOp(Kind Op) : Op(Op) {}

115

116 void print(raw_ostream &OS) const;

117};

118

119

121 typedef MCParsedAsmOperand Base;

122

123 enum class KindTy {

125 Token,

127 MemOp,

128 };

129

130 KindTy Kind;

131 SMLoc Start, End;

132 union {

133 StringRef Token;

134 const MCExpr *Expr;

135 M68kMemOp MemOp;

136 };

137

138 template bool isAddrN() const;

139

140public:

141 M68kOperand(KindTy Kind, SMLoc Start, SMLoc End)

142 : Base(), Kind(Kind), Start(Start), End(End) {}

143

144 SMLoc getStartLoc() const override { return Start; }

145 SMLoc getEndLoc() const override { return End; }

146

147 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;

148

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

150 bool isMemOp() const { return Kind == KindTy::MemOp; }

151

152 static void addExpr(MCInst &Inst, const MCExpr *Expr);

153

154

155 bool isReg() const override;

156 bool isAReg() const;

157 bool isDReg() const;

158 bool isFPDReg() const;

159 bool isFPCReg() const;

160 MCRegister getReg() const override;

161 void addRegOperands(MCInst &Inst, unsigned N) const;

162

163 static std::unique_ptr createMemOp(M68kMemOp MemOp, SMLoc Start,

164 SMLoc End);

165

166

167 bool isToken() const override;

169 static std::unique_ptr createToken(StringRef Token, SMLoc Start,

170 SMLoc End);

171

172

173 bool isImm() const override;

174 void addImmOperands(MCInst &Inst, unsigned N) const;

175

176 static std::unique_ptr createImm(const MCExpr *Expr, SMLoc Start,

177 SMLoc End);

178

179

180 bool isTrapImm() const;

181

182 bool isBkptImm() const;

183

184

185 bool isMoveMask() const;

186 void addMoveMaskOperands(MCInst &Inst, unsigned N) const;

187

188

189 bool isAddr() const;

190 bool isAddr8() const { return isAddrN<8>(); }

191 bool isAddr16() const { return isAddrN<16>(); }

192 bool isAddr32() const { return isAddrN<32>(); }

193 void addAddrOperands(MCInst &Inst, unsigned N) const;

194

195

196 bool isARI() const;

197 void addARIOperands(MCInst &Inst, unsigned N) const;

198

199

200 bool isARID() const;

201 void addARIDOperands(MCInst &Inst, unsigned N) const;

202

203

204 bool isARII() const;

205 void addARIIOperands(MCInst &Inst, unsigned N) const;

206

207

208 bool isARIPD() const;

209 void addARIPDOperands(MCInst &Inst, unsigned N) const;

210

211

212 bool isARIPI() const;

213 void addARIPIOperands(MCInst &Inst, unsigned N) const;

214

215

216 bool isPCD() const;

217 void addPCDOperands(MCInst &Inst, unsigned N) const;

218

219

220 bool isPCI() const;

221 void addPCIOperands(MCInst &Inst, unsigned N) const;

222};

223

224}

225

229

230#define GET_REGISTER_MATCHER

231#define GET_MATCHER_IMPLEMENTATION

232#include "M68kGenAsmMatcher.inc"

233

235 static unsigned RegistersByIndex[] = {

236 M68k::D0, M68k::D1, M68k::D2, M68k::D3, M68k::D4, M68k::D5,

237 M68k::D6, M68k::D7, M68k::A0, M68k::A1, M68k::A2, M68k::A3,

238 M68k::A4, M68k::A5, M68k::A6, M68k::SP, M68k::FP0, M68k::FP1,

239 M68k::FP2, M68k::FP3, M68k::FP4, M68k::FP5, M68k::FP6, M68k::FP7};

240 assert(RegisterIndex <=

241 sizeof(RegistersByIndex) / sizeof(RegistersByIndex[0]));

242 return RegistersByIndex[RegisterIndex];

243}

244

249 return Register - M68k::A0 + 8;

251 return Register - M68k::FP0 + 16;

252

254 case M68k::SP:

255

256 return 15;

257

258

259 case M68k::PC:

260 case M68k::CCR:

261 case M68k::SR:

262 case M68k::FPC:

263 case M68k::FPS:

264 case M68k::FPIAR:

265 return UINT_MAX;

266

267 default:

269 }

270}

271

272void M68kMemOp::print(raw_ostream &OS) const {

273 switch (Op) {

274 case Kind::Addr:

275 OS << OuterDisp;

276 break;

277 case Kind::RegMask:

278 OS << "RegMask(" << format("%04x", RegMask) << ")";

279 break;

280 case Kind::Reg:

281 OS << '%' << OuterReg;

282 break;

283 case Kind::RegIndirect:

284 OS << "(%" << OuterReg << ')';

285 break;

286 case Kind::RegPostIncrement:

287 OS << "(%" << OuterReg << ")+";

288 break;

289 case Kind::RegPreDecrement:

290 OS << "-(%" << OuterReg << ")";

291 break;

292 case Kind::RegIndirectDisplacement:

293 OS << OuterDisp << "(%" << OuterReg << ")";

294 break;

295 case Kind::RegIndirectDisplacementIndex:

296 OS << OuterDisp << "(%" << OuterReg << ", " << InnerReg << "." << Size

297 << ", " << InnerDisp << ")";

298 break;

299 }

300}

301

302void M68kOperand::addExpr(MCInst &Inst, const MCExpr *Expr) {

305 return;

306 }

307

309}

310

311

312bool M68kOperand::isReg() const {

313 return Kind == KindTy::MemOp && MemOp.Op == M68kMemOp::Kind::Reg;

314}

315

316MCRegister M68kOperand::getReg() const {

318 return MemOp.OuterReg;

319}

320

321void M68kOperand::addRegOperands(MCInst &Inst, unsigned N) const {

323 assert((N == 1) && "can only handle one register operand");

324

326}

327

328std::unique_ptr M68kOperand::createMemOp(M68kMemOp MemOp,

329 SMLoc Start, SMLoc End) {

330 auto Op = std::make_unique(KindTy::MemOp, Start, End);

331 Op->MemOp = MemOp;

332 return Op;

333}

334

335

336bool M68kOperand::isToken() const { return Kind == KindTy::Token; }

337StringRef M68kOperand::getToken() const {

339 return Token;

340}

341

342std::unique_ptr M68kOperand::createToken(StringRef Token,

343 SMLoc Start, SMLoc End) {

344 auto Op = std::make_unique(KindTy::Token, Start, End);

345 Op->Token = Token;

346 return Op;

347}

348

349

350bool M68kOperand::isImm() const { return Kind == KindTy::Imm; }

351void M68kOperand::addImmOperands(MCInst &Inst, unsigned N) const {

352 assert(isImm() && "wrong operand kind");

353 assert((N == 1) && "can only handle one register operand");

354

355 M68kOperand::addExpr(Inst, Expr);

356}

357

358std::unique_ptr M68kOperand::createImm(const MCExpr *Expr,

359 SMLoc Start, SMLoc End) {

360 auto Op = std::make_unique(KindTy::Imm, Start, End);

361 Op->Expr = Expr;

362 return Op;

363}

364

365bool M68kOperand::isTrapImm() const {

367 if (!isImm() || !Expr->evaluateAsAbsolute(Value))

368 return false;

369

371}

372

373bool M68kOperand::isBkptImm() const {

375 if (!isImm() || !Expr->evaluateAsAbsolute(Value))

376 return false;

377

379}

380

381

382bool M68kOperand::isMoveMask() const {

383 if (!isMemOp())

384 return false;

385

386 if (MemOp.Op == M68kMemOp::Kind::RegMask)

387 return true;

388

389 if (MemOp.Op != M68kMemOp::Kind::Reg)

390 return false;

391

392

393

395}

396

397void M68kOperand::addMoveMaskOperands(MCInst &Inst, unsigned N) const {

398 assert(isMoveMask() && "wrong operand kind");

399 assert((N == 1) && "can only handle one immediate operand");

400

401 uint16_t MoveMask = MemOp.RegMask;

402 if (MemOp.Op == M68kMemOp::Kind::Reg)

404

406}

407

408

409bool M68kOperand::isAddr() const {

410 return isMemOp() && MemOp.Op == M68kMemOp::Kind::Addr;

411}

412

413

414template bool M68kOperand::isAddrN() const {

415 if (isAddr()) {

416 int64_t Res;

417 if (MemOp.OuterDisp->evaluateAsAbsolute(Res))

419 return true;

420 }

421 return false;

422}

423void M68kOperand::addAddrOperands(MCInst &Inst, unsigned N) const {

424 M68kOperand::addExpr(Inst, MemOp.OuterDisp);

425}

426

427

428bool M68kOperand::isARI() const {

429 return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegIndirect &&

430 M68k::AR32RegClass.contains(MemOp.OuterReg);

431}

432void M68kOperand::addARIOperands(MCInst &Inst, unsigned N) const {

434}

435

436

437bool M68kOperand::isARID() const {

438 return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacement &&

439 M68k::AR32RegClass.contains(MemOp.OuterReg);

440}

441void M68kOperand::addARIDOperands(MCInst &Inst, unsigned N) const {

442 M68kOperand::addExpr(Inst, MemOp.OuterDisp);

444}

445

446

447bool M68kOperand::isARII() const {

448 return isMemOp() &&

449 MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacementIndex &&

450 M68k::AR32RegClass.contains(MemOp.OuterReg);

451}

452void M68kOperand::addARIIOperands(MCInst &Inst, unsigned N) const {

453 M68kOperand::addExpr(Inst, MemOp.OuterDisp);

456}

457

458

459bool M68kOperand::isARIPD() const {

460 return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegPreDecrement &&

461 M68k::AR32RegClass.contains(MemOp.OuterReg);

462}

463void M68kOperand::addARIPDOperands(MCInst &Inst, unsigned N) const {

465}

466

467

468bool M68kOperand::isARIPI() const {

469 return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegPostIncrement &&

470 M68k::AR32RegClass.contains(MemOp.OuterReg);

471}

472void M68kOperand::addARIPIOperands(MCInst &Inst, unsigned N) const {

474}

475

476

477bool M68kOperand::isPCD() const {

478 return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacement &&

479 MemOp.OuterReg == M68k::PC;

480}

481void M68kOperand::addPCDOperands(MCInst &Inst, unsigned N) const {

482 M68kOperand::addExpr(Inst, MemOp.OuterDisp);

483}

484

485

486bool M68kOperand::isPCI() const {

487 return isMemOp() &&

488 MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacementIndex &&

489 MemOp.OuterReg == M68k::PC;

490}

491void M68kOperand::addPCIOperands(MCInst &Inst, unsigned N) const {

492 M68kOperand::addExpr(Inst, MemOp.OuterDisp);

494}

495

497 bool SP, bool FPDR = false,

498 bool FPCR = false) {

499 switch (RegNo) {

500 case M68k::A0:

501 case M68k::A1:

502 case M68k::A2:

503 case M68k::A3:

504 case M68k::A4:

505 case M68k::A5:

506 case M68k::A6:

507 return Address;

508

509 case M68k::SP:

510 return SP;

511

512 case M68k::D0:

513 case M68k::D1:

514 case M68k::D2:

515 case M68k::D3:

516 case M68k::D4:

517 case M68k::D5:

518 case M68k::D6:

519 case M68k::D7:

521

522 case M68k::SR:

523 case M68k::CCR:

524 return false;

525

526 case M68k::FP0:

527 case M68k::FP1:

528 case M68k::FP2:

529 case M68k::FP3:

530 case M68k::FP4:

531 case M68k::FP5:

532 case M68k::FP6:

533 case M68k::FP7:

534 return FPDR;

535

536 case M68k::FPC:

537 case M68k::FPS:

538 case M68k::FPIAR:

539 return FPCR;

540

541 default:

543 return false;

544 }

545}

546

547bool M68kOperand::isAReg() const {

549 false,

550 true, true);

551}

552

553bool M68kOperand::isDReg() const {

555 true,

556 false, false);

557}

558

559bool M68kOperand::isFPDReg() const {

561 false,

562 false, false,

563 true);

564}

565

566bool M68kOperand::isFPCReg() const {

568 false,

569 false, false,

570 false, true);

571}

572

573unsigned M68kAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,

574 unsigned Kind) {

575 M68kOperand &Operand = (M68kOperand &)Op;

576

577 switch (Kind) {

578 case MCK_XR16:

579 case MCK_SPILL:

580 if (Operand.isReg() &&

582 return Match_Success;

583 }

584 break;

585

586 case MCK_AR16:

587 case MCK_AR32:

588 if (Operand.isReg() &&

590 return Match_Success;

591 }

592 break;

593

594 case MCK_AR32_NOSP:

595 if (Operand.isReg() &&

597 return Match_Success;

598 }

599 break;

600

601 case MCK_DR8:

602 case MCK_DR16:

603 case MCK_DR32:

604 if (Operand.isReg() &&

606 return Match_Success;

607 }

608 break;

609

610 case MCK_AR16_TC:

611 if (Operand.isReg() &&

612 ((Operand.getReg() == M68k::A0) || (Operand.getReg() == M68k::A1))) {

613 return Match_Success;

614 }

615 break;

616

617 case MCK_DR16_TC:

618 if (Operand.isReg() &&

619 ((Operand.getReg() == M68k::D0) || (Operand.getReg() == M68k::D1))) {

620 return Match_Success;

621 }

622 break;

623

624 case MCK_XR16_TC:

625 if (Operand.isReg() &&

626 ((Operand.getReg() == M68k::D0) || (Operand.getReg() == M68k::D1) ||

627 (Operand.getReg() == M68k::A0) || (Operand.getReg() == M68k::A1))) {

628 return Match_Success;

629 }

630 break;

631 }

632

633 return Match_InvalidOperand;

634}

635

636bool M68kAsmParser::parseRegisterName(MCRegister &RegNo, SMLoc Loc,

637 StringRef RegisterName) {

638 auto RegisterNameLower = RegisterName.lower();

639

640

641 if (RegisterNameLower == "ccr") {

642 RegNo = M68k::CCR;

643 return true;

644 } else if (RegisterNameLower == "sr") {

645 RegNo = M68k::SR;

646 return true;

647 }

648

649

650 if (RegisterNameLower.size() == 2) {

651

652 switch (RegisterNameLower[0]) {

653 case 'd':

654 case 'a': {

655 if (isdigit(RegisterNameLower[1])) {

656 unsigned IndexOffset = (RegisterNameLower[0] == 'a') ? 8 : 0;

657 unsigned RegIndex = (unsigned)(RegisterNameLower[1] - '0');

658 if (RegIndex < 8) {

660 return true;

661 }

662 }

663 break;

664 }

665

666 case 's':

667 if (RegisterNameLower[1] == 'p') {

668 RegNo = M68k::SP;

669 return true;

670 } else if (RegisterNameLower[1] == 'r') {

671 RegNo = M68k::SR;

672 return true;

673 }

674 break;

675

676 case 'p':

677 if (RegisterNameLower[1] == 'c') {

678 RegNo = M68k::PC;

679 return true;

680 }

681 break;

682 }

683 } else if (StringRef(RegisterNameLower).starts_with("fp") &&

684 RegisterNameLower.size() > 2) {

685 auto RegIndex = unsigned(RegisterNameLower[2] - '0');

686 if (RegIndex < 8 && RegisterNameLower.size() == 3) {

687

689 return true;

690 } else {

691

692 RegNo = StringSwitch(RegisterNameLower)

693 .Cases({"fpc", "fpcr"}, M68k::FPC)

694 .Cases({"fps", "fpsr"}, M68k::FPS)

695 .Cases({"fpi", "fpiar"}, M68k::FPIAR)

696 .Default(M68k::NoRegister);

697 assert(RegNo != M68k::NoRegister &&

698 "Unrecognized FP control register name");

699 return true;

700 }

701 }

702

703 return false;

704}

705

706ParseStatus M68kAsmParser::parseRegister(MCRegister &RegNo) {

707 bool HasPercent = false;

708 AsmToken PercentToken;

709

711

713 HasPercent = true;

714 PercentToken = Lex();

717 }

718

720 if (HasPercent) {

721 getLexer().UnLex(PercentToken);

722 }

724 }

725

727 if (!parseRegisterName(RegNo, Parser.getLexer().getLoc(), RegisterName)) {

728 if (HasPercent) {

729 getLexer().UnLex(PercentToken);

730 }

732 }

733

734 Parser.Lex();

736}

737

738bool M68kAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,

739 SMLoc &EndLoc) {

740 ParseStatus Result = tryParseRegister(Reg, StartLoc, EndLoc);

741 if (Result.isSuccess())

742 return Error(StartLoc, "expected register");

743

744 return false;

745}

746

747ParseStatus M68kAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

748 SMLoc &EndLoc) {

749 StartLoc = getLexer().getLoc();

750 ParseStatus Result = parseRegister(Reg);

751 EndLoc = getLexer().getLoc();

753}

754

755bool M68kAsmParser::isExpr() {

759 return true;

762

763 default:

764 return false;

765 }

766}

767

768ParseStatus M68kAsmParser::parseImm(OperandVector &Operands) {

771 SMLoc Start = getLexer().getLoc();

772 Parser.Lex();

773

774 SMLoc End;

775 const MCExpr *Expr;

776

777 if (getParser().parseExpression(Expr, End))

779

780 Operands.push_back(M68kOperand::createImm(Expr, Start, End));

782}

783

784ParseStatus M68kAsmParser::parseMemOp(OperandVector &Operands) {

785 SMLoc Start = getLexer().getLoc();

786 bool IsPD = false;

787 M68kMemOp MemOp;

788

789

790 ParseStatus Result = parseRegOrMoveMask(Operands);

791 if (Result.isNoMatch())

793

794

795 bool HasDisplacement = false;

797 IsPD = true;

798 Parser.Lex();

799 } else if (isExpr()) {

802 HasDisplacement = true;

803 }

804

806 if (HasDisplacement) {

807 MemOp.Op = M68kMemOp::Kind::Addr;

809 M68kOperand::createMemOp(MemOp, Start, getLexer().getLoc()));

811 }

812 if (IsPD)

813 return Error(getLexer().getLoc(), "expected (");

814

816 }

817 Parser.Lex();

818

819

820 if (!HasDisplacement && isExpr()) {

823 HasDisplacement = true;

824

825

827 MemOp.Op = M68kMemOp::Kind::Addr;

829 M68kOperand::createMemOp(MemOp, Start, getLexer().getLoc()));

831 }

832

833 Parser.Lex();

834 }

835

836 Result = parseRegister(MemOp.OuterReg);

837 if (Result.isFailure())

839

840 if (Result.isSuccess())

841 return Error(getLexer().getLoc(), "expected register");

842

843

846 Parser.Lex();

847

848 Result = parseRegister(MemOp.InnerReg);

849 if (Result.isFailure())

851

852 if (Result.isNoMatch())

853 return Error(getLexer().getLoc(), "expected register");

854

855

856 MemOp.Size = 4;

857 MemOp.Scale = 1;

860 }

861

863 return Error(getLexer().getLoc(), "expected )");

864 Parser.Lex();

865

866 bool IsPI = false;

868 Parser.Lex();

869 IsPI = true;

870 }

871

872 SMLoc End = getLexer().getLoc();

873

874 unsigned OpCount = IsPD + IsPI + (HasIndex || HasDisplacement);

875 if (OpCount > 1)

876 return Error(Start, "only one of post-increment, pre-decrement or "

877 "displacement can be used");

878

879 if (IsPD) {

880 MemOp.Op = M68kMemOp::Kind::RegPreDecrement;

881 } else if (IsPI) {

882 MemOp.Op = M68kMemOp::Kind::RegPostIncrement;

883 } else if (HasIndex) {

884 MemOp.Op = M68kMemOp::Kind::RegIndirectDisplacementIndex;

885 } else if (HasDisplacement) {

886 MemOp.Op = M68kMemOp::Kind::RegIndirectDisplacement;

887 } else {

888 MemOp.Op = M68kMemOp::Kind::RegIndirect;

889 }

890

891 Operands.push_back(M68kOperand::createMemOp(MemOp, Start, End));

893}

894

895ParseStatus M68kAsmParser::parseRegOrMoveMask(OperandVector &Operands) {

896 SMLoc Start = getLexer().getLoc();

897 M68kMemOp MemOp(M68kMemOp::Kind::RegMask);

898 MemOp.RegMask = 0;

899

900 for (;;) {

901 bool IsFirstRegister =

902 (MemOp.Op == M68kMemOp::Kind::RegMask) && (MemOp.RegMask == 0);

903

904 MCRegister FirstRegister;

905 ParseStatus Result = parseRegister(FirstRegister);

906 if (IsFirstRegister && Result.isNoMatch())

908 if (Result.isSuccess())

909 return Error(getLexer().getLoc(), "expected start register");

910

911 MCRegister LastRegister = FirstRegister;

913 Result = parseRegister(LastRegister);

914 if (Result.isSuccess())

915 return Error(getLexer().getLoc(), "expected end register");

916 }

917

918 unsigned FirstRegisterIndex = getRegisterIndex(FirstRegister);

920

921 uint16_t NumNewBits = LastRegisterIndex - FirstRegisterIndex + 1;

922 uint16_t NewMaskBits = ((1 << NumNewBits) - 1) << FirstRegisterIndex;

923

924 if (IsFirstRegister && (FirstRegister == LastRegister)) {

925

926

927 MemOp.Op = M68kMemOp::Kind::Reg;

928 MemOp.OuterReg = FirstRegister;

929 } else {

930 if (MemOp.Op == M68kMemOp::Kind::Reg) {

931

932

933 MemOp.Op = M68kMemOp::Kind::RegMask;

935

936 if (MemOp.RegMask == 0)

937 return Error(getLexer().getLoc(),

938 "special registers cannot be used in register masks");

939 }

940

941 if ((FirstRegisterIndex >= 16) || (LastRegisterIndex >= 16))

942 return Error(getLexer().getLoc(),

943 "special registers cannot be used in register masks");

944

945 if (NewMaskBits & MemOp.RegMask)

946 return Error(getLexer().getLoc(), "conflicting masked registers");

947

948 MemOp.RegMask |= NewMaskBits;

949 }

950

952 break;

953 }

954

956 M68kOperand::createMemOp(MemOp, Start, getLexer().getLoc()));

958}

959

960void M68kAsmParser::eatComma() {

962 Parser.Lex();

963 }

964}

965

966bool M68kAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,

968 SMLoc Start = getLexer().getLoc();

969 Operands.push_back(M68kOperand::createToken(Name, Start, Start));

970

971 bool First = true;

974 eatComma();

975 } else {

977 }

978

979 ParseStatus MatchResult = MatchOperandParserImpl(Operands, Name);

981 continue;

982

983

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

986 return Error(Loc, "unexpected token parsing operands");

987 }

988

989

990 Parser.Lex();

991 return false;

992}

993

994bool M68kAsmParser::invalidOperand(SMLoc Loc, OperandVector const &Operands,

995 uint64_t const &ErrorInfo) {

996 SMLoc ErrorLoc = Loc;

997 char const *Diag = 0;

998

999 if (ErrorInfo != ~0U) {

1000 if (ErrorInfo >= Operands.size()) {

1001 Diag = "too few operands for instruction.";

1002 } else {

1003 auto const &Op = (M68kOperand const &)*Operands[ErrorInfo];

1004 if (Op.getStartLoc() != SMLoc()) {

1005 ErrorLoc = Op.getStartLoc();

1006 }

1007 }

1008 }

1009

1010 if (!Diag) {

1011 Diag = "invalid operand for instruction";

1012 }

1013

1014 return Error(ErrorLoc, Diag);

1015}

1016

1017bool M68kAsmParser::missingFeature(SMLoc Loc, uint64_t const &ErrorInfo) {

1018 return Error(Loc, "instruction requires a CPU feature not currently enabled");

1019}

1020

1021bool M68kAsmParser::emit(MCInst &Inst, SMLoc Loc, MCStreamer &Out) const {

1024

1025 return false;

1026}

1027

1028bool M68kAsmParser::matchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,

1030 MCStreamer &Out,

1031 uint64_t &ErrorInfo,

1032 bool MatchingInlineAsm) {

1033 MCInst Inst;

1034 unsigned MatchResult =

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

1036

1037 switch (MatchResult) {

1038 case Match_Success:

1039 return emit(Inst, Loc, Out);

1040 case Match_MissingFeature:

1041 return missingFeature(Loc, ErrorInfo);

1042 case Match_InvalidOperand:

1043 return invalidOperand(Loc, Operands, ErrorInfo);

1044 case Match_MnemonicFail:

1045 return Error(Loc, "invalid instruction");

1046 default:

1047 return true;

1048 }

1049}

1050

1051void M68kOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {

1052 switch (Kind) {

1053 case KindTy::Invalid:

1054 OS << "invalid";

1055 break;

1056

1057 case KindTy::Token:

1058 OS << "token '" << Token << "'";

1059 break;

1060

1061 case KindTy::Imm: {

1063 Expr->evaluateAsAbsolute(Value);

1064 OS << "immediate " << Value;

1065 break;

1066 }

1067

1068 case KindTy::MemOp:

1069 MemOp.print(OS);

1070 break;

1071 }

1072}

unsigned const MachineRegisterInfo * MRI

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

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

Analysis containing CSE Info

#define LLVM_EXTERNAL_VISIBILITY

static bool checkRegisterClass(unsigned RegNo, bool Data, bool Address, bool SP, bool FPDR=false, bool FPCR=false)

Definition M68kAsmParser.cpp:496

static cl::opt< bool > RegisterPrefixOptional("m68k-register-prefix-optional", cl::Hidden, cl::desc("Enable specifying registers without the % prefix"), cl::init(false))

LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kAsmParser()

Definition M68kAsmParser.cpp:226

static unsigned getRegisterByIndex(unsigned RegisterIndex)

Definition M68kAsmParser.cpp:234

static unsigned getRegisterIndex(unsigned Register)

Definition M68kAsmParser.cpp:245

This file contains the M68k implementation of the TargetInstrInfo class.

This file contains the declarations of the M68k MCAsmInfo properties.

This file contains the M68k implementation of the TargetRegisterInfo class.

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

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

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

SMLoc getLoc() const

Get the current source location.

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

bool is(TokenKind K) const

TokenKind getKind() const

Base class for user error types.

virtual void Initialize(MCAsmParser &Parser)

Initialize the extension for parsing using the given Parser.

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.

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 const AsmToken & Lex()=0

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

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

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.

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.

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.

const FeatureBitset & getFeatureBits() const

MCTargetAsmParser - Generic interface to target specific assembly parsers.

Ternary parse status returned by various parse* methods.

static constexpr StatusTy Failure

constexpr bool isSuccess() const

static constexpr StatusTy Success

static constexpr StatusTy NoMatch

Wrapper class representing virtual and physical registers.

Represents a location in source code.

void push_back(const T &Elt)

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

LLVM_ABI std::string lower() const

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.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

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.

SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector

LLVM_ABI raw_ostream & dbgs()

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

constexpr bool isUInt(uint64_t x)

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

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

DWARFExpression::Operation Op

Target & getTheM68kTarget()

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