LLVM: lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

14

30

31#define DEBUG_TYPE "msp430-asm-parser"

32

33using namespace llvm;

34

35namespace {

36

37

41

42 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

45 bool MatchingInlineAsm) override;

46

49 SMLoc &EndLoc) override;

50

53

55 bool ParseDirectiveRefSym(AsmToken DirectiveID);

56

58 unsigned Kind) override;

59

62

64

65 bool ParseLiteralValues(unsigned Size, SMLoc L);

66

67 MCAsmParser &getParser() const { return Parser; }

69

70

71

72

73#define GET_ASSEMBLER_HEADER

74#include "MSP430GenAsmMatcher.inc"

75

76

77

78public:

83 MRI = getContext().getRegisterInfo();

84

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

86 }

87};

88

89

91 typedef MCParsedAsmOperand Base;

92

93 enum KindTy {

94 k_Imm,

95 k_Reg,

96 k_Tok,

97 k_Mem,

98 k_IndReg,

99 k_PostIndReg

100 } Kind;

101

102 struct Memory {

103 MCRegister Reg;

104 const MCExpr *Offset;

105 };

106 union {

107 const MCExpr *Imm;

108 MCRegister Reg;

109 StringRef Tok;

110 Memory Mem;

111 };

112

113 SMLoc Start, End;

114

115public:

116 MSP430Operand(StringRef Tok, SMLoc const &S)

117 : Kind(k_Tok), Tok(Tok), Start(S), End(S) {}

118 MSP430Operand(KindTy Kind, MCRegister Reg, SMLoc const &S, SMLoc const &E)

119 : Kind(Kind), Reg(Reg), Start(S), End(E) {}

120 MSP430Operand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E)

121 : Kind(k_Imm), Imm(Imm), Start(S), End(E) {}

122 MSP430Operand(MCRegister Reg, MCExpr const *Expr, SMLoc const &S,

123 SMLoc const &E)

124 : Kind(k_Mem), Mem({Reg, Expr}), Start(S), End(E) {}

125

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

127 assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&

128 "Unexpected operand kind");

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

130

132 }

133

134 void addExprOperand(MCInst &Inst, const MCExpr *Expr) const {

135

136 if (!Expr)

140 else

142 }

143

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

145 assert(Kind == k_Imm && "Unexpected operand kind");

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

147

148 addExprOperand(Inst, Imm);

149 }

150

151 void addMemOperands(MCInst &Inst, unsigned N) const {

152 assert(Kind == k_Mem && "Unexpected operand kind");

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

154

156 addExprOperand(Inst, Mem.Offset);

157 }

158

159 bool isReg() const override { return Kind == k_Reg; }

160 bool isImm() const override { return Kind == k_Imm; }

161 bool isToken() const override { return Kind == k_Tok; }

162 bool isMem() const override { return Kind == k_Mem; }

163 bool isIndReg() const { return Kind == k_IndReg; }

164 bool isPostIndReg() const { return Kind == k_PostIndReg; }

165

166 bool isCGImm() const {

167 if (Kind != k_Imm)

168 return false;

169

170 int64_t Val;

171 if (Imm->evaluateAsAbsolute(Val))

172 return false;

173

174 if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)

175 return true;

176

177 return false;

178 }

179

181 assert(Kind == k_Tok && "Invalid access!");

182 return Tok;

183 }

184

185 MCRegister getReg() const override {

186 assert(Kind == k_Reg && "Invalid access!");

187 return Reg;

188 }

189

190 void setReg(MCRegister RegNo) {

191 assert(Kind == k_Reg && "Invalid access!");

192 Reg = RegNo;

193 }

194

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

196 return std::make_unique(Str, S);

197 }

198

199 static std::unique_ptr CreateReg(MCRegister Reg, SMLoc S,

200 SMLoc E) {

201 return std::make_unique(k_Reg, Reg, S, E);

202 }

203

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

205 SMLoc E) {

206 return std::make_unique(Val, S, E);

207 }

208

209 static std::unique_ptr

210 CreateMem(MCRegister Reg, const MCExpr *Val, SMLoc S, SMLoc E) {

211 return std::make_unique(Reg, Val, S, E);

212 }

213

214 static std::unique_ptr CreateIndReg(MCRegister Reg, SMLoc S,

215 SMLoc E) {

216 return std::make_unique(k_IndReg, Reg, S, E);

217 }

218

219 static std::unique_ptr CreatePostIndReg(MCRegister Reg,

220 SMLoc S, SMLoc E) {

221 return std::make_unique(k_PostIndReg, Reg, S, E);

222 }

223

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

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

226

227 void print(raw_ostream &O, const MCAsmInfo &MAI) const override {

228 switch (Kind) {

229 case k_Tok:

230 O << "Token " << Tok;

231 break;

232 case k_Reg:

233 O << "Register " << Reg.id();

234 break;

235 case k_Imm:

236 O << "Immediate ";

238 break;

239 case k_Mem:

240 O << "Memory ";

242 break;

243 case k_IndReg:

244 O << "RegInd " << Reg.id();

245 break;

246 case k_PostIndReg:

247 O << "PostInc " << Reg.id();

248 break;

249 }

250 }

251};

252}

253

254bool MSP430AsmParser::matchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,

258 bool MatchingInlineAsm) {

259 MCInst Inst;

260 unsigned MatchResult =

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

262

263 switch (MatchResult) {

264 case Match_Success:

267 return false;

268 case Match_MnemonicFail:

269 return Error(Loc, "invalid instruction mnemonic");

270 case Match_InvalidOperand: {

271 SMLoc ErrorLoc = Loc;

272 if (ErrorInfo != ~0U) {

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

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

275

276 ErrorLoc = ((MSP430Operand &)*Operands[ErrorInfo]).getStartLoc();

277 if (ErrorLoc == SMLoc())

278 ErrorLoc = Loc;

279 }

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

281 }

282 default:

283 return true;

284 }

285}

286

287

290

293 ParseStatus Res = tryParseRegister(Reg, StartLoc, EndLoc);

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

297 return false;

299 return true;

300

302}

303

304ParseStatus MSP430AsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

305 SMLoc &EndLoc) {

307 auto Name = getLexer().getTok().getIdentifier().lower();

309 if (Reg == MSP430::NoRegister) {

311 if (Reg == MSP430::NoRegister)

313 }

314

315 AsmToken const &T = getParser().getTok();

316 StartLoc = T.getLoc();

317 EndLoc = T.getEndLoc();

318 getLexer().Lex();

319

321 }

322

324}

325

326bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info,

327 StringRef Name, SMLoc NameLoc,

329 if (Name.starts_with_insensitive("j"))

330 return true;

331

332 auto CC = Name.drop_front().lower();

334 if (CC == "ne" || CC == "nz")

336 else if (CC == "eq" || CC == "z")

338 else if (CC == "lo" || CC == "nc")

340 else if (CC == "hs" || CC == "c")

342 else if (CC == "n")

344 else if (CC == "ge")

346 else if (CC == "l")

348 else if (CC == "mp")

350 else

351 return Error(NameLoc, "unknown instruction");

352

354 Operands.push_back(MSP430Operand::CreateToken("jmp", NameLoc));

355 else {

356 Operands.push_back(MSP430Operand::CreateToken("j", NameLoc));

358 Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc()));

359 }

360

361

363

364 const MCExpr *Val;

365 SMLoc ExprLoc = getLexer().getLoc();

366 if (getParser().parseExpression(Val))

367 return Error(ExprLoc, "expected expression operand");

368

369 int64_t Res;

370 if (Val->evaluateAsAbsolute(Res))

371 if (Res < -512 || Res > 511)

372 return Error(ExprLoc, "invalid jump offset");

373

374 Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc,

375 getLexer().getLoc()));

376

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

379 getParser().eatToEndOfStatement();

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

381 }

382

383 getParser().Lex();

384 return false;

385}

386

387bool MSP430AsmParser::parseInstruction(ParseInstructionInfo &Info,

388 StringRef Name, SMLoc NameLoc,

390

391 if (Name.ends_with_insensitive(".w"))

393

394 if (!parseJccInstruction(Info, Name, NameLoc, Operands))

395 return false;

396

397

398 Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc));

399

400

402 return false;

403

404

405 if (ParseOperand(Operands))

406 return true;

407

408

409 if (parseOptionalToken(AsmToken::Comma) && ParseOperand(Operands))

410 return true;

411

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

414 getParser().eatToEndOfStatement();

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

416 }

417

418 getParser().Lex();

419 return false;

420}

421

422bool MSP430AsmParser::ParseDirectiveRefSym(AsmToken DirectiveID) {

423 StringRef Name;

424 if (getParser().parseIdentifier(Name))

425 return TokError("expected identifier in directive");

426

428 getStreamer().emitSymbolAttribute(Sym, MCSA_Global);

429 return parseEOL();

430}

431

432ParseStatus MSP430AsmParser::parseDirective(AsmToken DirectiveID) {

434 if (IDVal.lower() == ".long")

435 return ParseLiteralValues(4, DirectiveID.getLoc());

436 if (IDVal.lower() == ".word" || IDVal.lower() == ".short")

437 return ParseLiteralValues(2, DirectiveID.getLoc());

438 if (IDVal.lower() == ".byte")

439 return ParseLiteralValues(1, DirectiveID.getLoc());

440 if (IDVal.lower() == ".refsym")

441 return ParseDirectiveRefSym(DirectiveID);

443}

444

445bool MSP430AsmParser::ParseOperand(OperandVector &Operands) {

446 switch (getLexer().getKind()) {

447 default: return true;

449

450 MCRegister RegNo;

451 SMLoc StartLoc, EndLoc;

452 if (!parseRegister(RegNo, StartLoc, EndLoc)) {

453 Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));

454 return false;

455 }

456 [[fallthrough]];

457 }

461 SMLoc StartLoc = getParser().getTok().getLoc();

462 const MCExpr *Val;

463

464 if (!getParser().parseExpression(Val)) {

465 MCRegister RegNo = MSP430::PC;

466 SMLoc EndLoc = getParser().getTok().getLoc();

467

469 SMLoc RegStartLoc;

470 if (parseRegister(RegNo, RegStartLoc, EndLoc))

471 return true;

472 EndLoc = getParser().getTok().getEndLoc();

474 return true;

475 }

476 Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,

477 EndLoc));

478 return false;

479 }

480 return true;

481 }

483

484 SMLoc StartLoc = getParser().getTok().getLoc();

485 getLexer().Lex();

486 const MCExpr *Val;

487 if (!getParser().parseExpression(Val)) {

488 SMLoc EndLoc = getParser().getTok().getLoc();

489 Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,

490 EndLoc));

491 return false;

492 }

493 return true;

494 }

496

497 SMLoc StartLoc = getParser().getTok().getLoc();

498 getLexer().Lex();

499 MCRegister RegNo;

500 SMLoc RegStartLoc, EndLoc;

501 if (parseRegister(RegNo, RegStartLoc, EndLoc))

502 return true;

504 Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));

505 return false;

506 }

507 if (Operands.size() > 1)

508 Operands.push_back(MSP430Operand::CreateMem(RegNo,

510 else

511 Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));

512 return false;

513 }

515

516 SMLoc StartLoc = getParser().getTok().getLoc();

517 getLexer().Lex();

518 const MCExpr *Val;

519 if (!getParser().parseExpression(Val)) {

520 SMLoc EndLoc = getParser().getTok().getLoc();

521 Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));

522 return false;

523 }

524 return true;

525 }

526}

527

528bool MSP430AsmParser::ParseLiteralValues(unsigned Size, SMLoc L) {

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

530 const MCExpr *Value;

531 if (getParser().parseExpression(Value))

532 return true;

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

534 return false;

535 };

536 return (parseMany(parseOne));

537}

538

543

544#define GET_REGISTER_MATCHER

545#define GET_MATCHER_IMPLEMENTATION

546#include "MSP430GenAsmMatcher.inc"

547

549 switch (Reg.id()) {

550 default:

552 case MSP430::PC: return MSP430::PCB;

553 case MSP430::SP: return MSP430::SPB;

554 case MSP430::SR: return MSP430::SRB;

555 case MSP430::CG: return MSP430::CGB;

556 case MSP430::R4: return MSP430::R4B;

557 case MSP430::R5: return MSP430::R5B;

558 case MSP430::R6: return MSP430::R6B;

559 case MSP430::R7: return MSP430::R7B;

560 case MSP430::R8: return MSP430::R8B;

561 case MSP430::R9: return MSP430::R9B;

562 case MSP430::R10: return MSP430::R10B;

563 case MSP430::R11: return MSP430::R11B;

564 case MSP430::R12: return MSP430::R12B;

565 case MSP430::R13: return MSP430::R13B;

566 case MSP430::R14: return MSP430::R14B;

567 case MSP430::R15: return MSP430::R15B;

568 }

569}

570

571unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,

572 unsigned Kind) {

573 MSP430Operand &Op = static_cast<MSP430Operand &>(AsmOp);

574

575 if (Op.isReg())

576 return Match_InvalidOperand;

577

578 MCRegister Reg = Op.getReg();

579 bool isGR16 =

580 MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg);

581

582 if (isGR16 && (Kind == MCK_GR8)) {

584 return Match_Success;

585 }

586

587 return Match_InvalidOperand;

588}

unsigned const MachineRegisterInfo * MRI

static MCRegister MatchRegisterName(StringRef Name)

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

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

This file implements a class to represent arbitrary precision integral constant values and operations...

static MCRegister MatchRegisterAltName(StringRef Name)

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

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

Analysis containing CSE Info

#define LLVM_EXTERNAL_VISIBILITY

LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430AsmParser()

Definition MSP430AsmParser.cpp:540

static MCRegister convertGR16ToGR8(MCRegister Reg)

Definition MSP430AsmParser.cpp:548

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

Target independent representation for an assembler token.

LLVM_ABI SMLoc getLoc() const

StringRef getIdentifier() const

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

Base class for user error types.

void printExpr(raw_ostream &, const MCExpr &) const

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.

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

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.

constexpr bool isFailure() const

static constexpr StatusTy Failure

constexpr bool isSuccess() const

static constexpr StatusTy Success

static constexpr StatusTy NoMatch

constexpr bool isNoMatch() const

constexpr unsigned id() const

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

#define llvm_unreachable(msg)

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

CondCode

ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...

@ CE

Windows NT (Windows on ARM)

Context & getContext() const

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)

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 & getTheMSP430Target()

SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector

DWARFExpression::Operation Op

@ MCSA_Global

.type _foo, @gnu_unique_object

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