LLVM: lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

30

31using namespace llvm;

32

33#define DEBUG_TYPE "xtensa-asm-parser"

34

36

39

40 enum XtensaRegisterType { Xtensa_Generic, Xtensa_SR, Xtensa_UR };

42

46 }

47

52 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

55 bool MatchingInlineAsm) override;

57 unsigned Kind) override;

58

61

62

63#define GET_ASSEMBLER_HEADER

64#include "XtensaGenAsmMatcher.inc"

65

68 parseRegister(OperandVector &Operands, bool AllowParens = false,

69 XtensaRegisterType SR = Xtensa_Generic,

72 bool

74 XtensaRegisterType SR = Xtensa_Generic,

79 SMLoc &EndLoc) override {

81 }

82

83 ParseStatus parsePCRelTarget(OperandVector &Operands);

84 bool parseLiteralDirective(SMLoc L);

85

86public:

89#define GET_OPERAND_DIAGNOSTIC_TYPES

90#include "XtensaGenAsmMatcher.inc"

91#undef GET_OPERAND_DIAGNOSTIC_TYPES

92 };

93

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

99 }

100

104};

105

106

107static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {

109 int64_t Value = CE->getValue();

110 return Value >= MinValue && Value <= MaxValue;

111 }

112 return false;

113}

114

116

122

126

130

132 union {

136 };

137

139

140public:

142 Kind = o.Kind;

145 switch (Kind) {

147 Reg = o.Reg;

148 break;

150 Imm = o.Imm;

151 break;

153 Tok = o.Tok;

154 break;

155 }

156 }

157

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

162

163 bool isImm(int64_t MinValue, int64_t MaxValue) const {

165 }

166

168

170 return isImm(-32768, 32512) &&

172 }

173

175

176

178

180 return isImm(0, 60) &&

182 }

183

185

187 return isImm(0, 510) &&

189 }

190

192 return isImm(0, 1020) &&

194 }

195

197 return isImm(0, 32760) &&

199 }

200

202

204

206

208

210

212

213

215

217

219 return isImm(-64, -4) &&

221 }

222

225 return false;

227 int64_t Value = CE->getValue();

229 case -1:

230 case 1:

231 case 2:

232 case 3:

233 case 4:

234 case 5:

235 case 6:

236 case 7:

237 case 8:

238 case 10:

239 case 12:

240 case 16:

241 case 32:

242 case 64:

243 case 128:

244 case 256:

245 return true;

246 default:

247 return false;

248 }

249 }

250 return false;

251 }

252

255 return false;

257 int64_t Value = CE->getValue();

259 case 32768:

260 case 65536:

261 case 2:

262 case 3:

263 case 4:

264 case 5:

265 case 6:

266 case 7:

267 case 8:

268 case 10:

269 case 12:

270 case 16:

271 case 32:

272 case 64:

273 case 128:

274 case 256:

275 return true;

276 default:

277 return false;

278 }

279 }

280 return false;

281 }

282

284

285

287

289

292 return Reg.RegNum;

293 }

294

297 return Imm.Val;

298 }

299

304

306 switch (Kind) {

309 break;

311 OS << "<register x";

312 OS << getReg() << ">";

313 break;

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

316 break;

317 }

318 }

319

321 auto Op = std::make_unique(Token);

322 Op->Tok = Str;

323 Op->StartLoc = S;

324 Op->EndLoc = S;

325 return Op;

326 }

327

328 static std::unique_ptr createReg(unsigned RegNo, SMLoc S,

330 auto Op = std::make_unique(Register);

331 Op->Reg.RegNum = RegNo;

332 Op->StartLoc = S;

333 Op->EndLoc = E;

334 return Op;

335 }

336

339 auto Op = std::make_unique(Immediate);

340 Op->Imm.Val = Val;

341 Op->StartLoc = S;

342 Op->EndLoc = E;

343 return Op;

344 }

345

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

348 int64_t Imm = 0;

349 bool IsConstant = false;

350

352 IsConstant = true;

353 Imm = CE->getValue();

354 }

355

356 if (IsConstant)

358 else

360 }

361

362

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

366 }

367

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

371 }

372};

373

374#define GET_REGISTER_MATCHER

375#define GET_MATCHER_IMPLEMENTATION

376#include "XtensaGenAsmMatcher.inc"

377

378unsigned XtensaAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,

379 unsigned Kind) {

381}

382

387 if (ErrorLoc == SMLoc())

388 return Loc;

389 return ErrorLoc;

390 }

391 return Loc;

392}

393

394bool XtensaAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,

398 const unsigned Opcode = Inst.getOpcode();

399 switch (Opcode) {

400 case Xtensa::L32R: {

401 const MCSymbolRefExpr *OpExpr =

402 static_cast<const MCSymbolRefExpr *>(Inst.getOperand(1).getExpr());

404 break;

405 }

406 case Xtensa::MOVI: {

407 XtensaTargetStreamer &TS = this->getTargetStreamer();

408

409

412 int32_t Imm = ImmOp64;

414 XtensaTargetStreamer &TS = this->getTargetStreamer();

415 MCInst TmpInst;

416 TmpInst.setLoc(IDLoc);

425 Inst = TmpInst;

426 }

427 } else {

428 MCInst TmpInst;

429 TmpInst.setLoc(IDLoc);

437 Inst = TmpInst;

439 }

440 break;

441 }

442 default:

443 break;

444 }

445

446 return true;

447}

448

449bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

453 bool MatchingInlineAsm) {

454 MCInst Inst;

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

457

458 switch (Result) {

459 default:

460 break;

462 processInstruction(Inst, IDLoc, Out, STI);

465 return false;

467 return Error(IDLoc, "instruction use requires an option to be enabled");

469 return Error(IDLoc, "unrecognized instruction mnemonic");

471 SMLoc ErrorLoc = IDLoc;

472 if (ErrorInfo != ~0U) {

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

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

475

476 ErrorLoc = ((XtensaOperand &)*Operands[ErrorInfo]).getStartLoc();

477 if (ErrorLoc == SMLoc())

478 ErrorLoc = IDLoc;

479 }

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

481 }

482 case Match_InvalidImm8:

484 "expected immediate in range [-128, 127]");

485 case Match_InvalidImm8_sh8:

487 "expected immediate in range [-32768, 32512], first 8 bits "

488 "should be zero");

489 case Match_InvalidB4const:

491 "expected b4const immediate");

492 case Match_InvalidB4constu:

494 "expected b4constu immediate");

495 case Match_InvalidImm12:

497 "expected immediate in range [-2048, 2047]");

498 case Match_InvalidImm12m:

500 "expected immediate in range [-2048, 2047]");

501 case Match_InvalidImm1_16:

503 "expected immediate in range [1, 16]");

504 case Match_InvalidImm1n_15:

506 "expected immediate in range [-1, 15] except 0");

507 case Match_InvalidImm32n_95:

509 "expected immediate in range [-32, 95]");

510 case Match_InvalidImm64n_4n:

512 "expected immediate in range [-64, -4]");

513 case Match_InvalidImm8n_7:

515 "expected immediate in range [-8, 7]");

516 case Match_InvalidShimm1_31:

518 "expected immediate in range [1, 31]");

519 case Match_InvalidUimm4:

521 "expected immediate in range [0, 15]");

522 case Match_InvalidUimm5:

524 "expected immediate in range [0, 31]");

525 case Match_InvalidOffset8m8:

527 "expected immediate in range [0, 255]");

528 case Match_InvalidOffset8m16:

530 "expected immediate in range [0, 510], first bit "

531 "should be zero");

532 case Match_InvalidOffset8m32:

534 "expected immediate in range [0, 1020], first 2 bits "

535 "should be zero");

536 case Match_InvalidOffset4m32:

538 "expected immediate in range [0, 60], first 2 bits "

539 "should be zero");

540 case Match_Invalidentry_imm12:

542 "expected immediate in range [0, 32760], first 3 bits "

543 "should be zero");

544 case Match_Invalidimm7_22:

546 "expected immediate in range [7, 22]");

547 }

548

550}

551

553 MCAsmParser &Parser = getParser();

555

557

558

559 const MCExpr *Expr = nullptr;

560 if (Parser.parseExpression(Expr)) {

561

563 }

564

565

566 if (Expr->getKind() == MCExpr::ExprKind::Constant)

567 return Error(getLoc(), "unknown operand");

568

571}

572

576 StartLoc = Tok.getLoc();

578 Reg = Xtensa::NoRegister;

580

583 return false;

584 }

585

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

587}

588

590 bool AllowParens,

591 XtensaRegisterType RegType,

593 SMLoc FirstS = getLoc();

594 bool HadParens = false;

595 AsmToken Buf[2];

597

598

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

602 if (Buf[0].getKind() == AsmToken::Integer && RegType == Xtensa_Generic)

604 HadParens = true;

606 }

607 }

608

609 MCRegister RegNo = 0;

610

611 switch (getLexer().getKind()) {

612 default:

615 if (RegType == Xtensa_Generic)

617

618

619

620

621 if (RegType == Xtensa_UR) {

624 } else {

627 }

628 break;

632 if (RegNo == 0)

634 break;

635 }

636

637 if (RegNo == 0) {

638 if (HadParens)

641 }

642

645

646 if (HadParens)

648 SMLoc S = getLoc();

652

653 if (HadParens) {

656 }

657

659}

660

662 SMLoc S = getLoc();

663 SMLoc E;

664 const MCExpr *Res;

665

666 switch (getLexer().getKind()) {

667 default:

675 if (getParser().parseExpression(Res))

677 break;

680 if (getParser().parseIdentifier(Identifier))

682

685 break;

686 }

688 return parseOperandWithModifier(Operands);

689 }

690

694}

695

698}

699

700

701

702

704 XtensaRegisterType RegType,

706

707

708 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);

710 return false;

711

712

713

714

716 return true;

717

718

719 if (parseRegister(Operands, true, RegType, RAType).isSuccess())

720 return false;

721

722

723 if (parseImmediate(Operands).isSuccess())

724 return false;

725

726

727 return Error(getLoc(), "unknown operand");

728}

729

737

738 if ((Name.size() > 4) && Name[3] == '.') {

739

740

741

742

744

747

748 if (RegNo == 0)

750

752 return Error(NameLoc, "invalid register name");

753

754

755 if (parseOperand(Operands, Name))

756 return true;

757

758 SMLoc S = getLoc();

761 } else {

762

764

765

766 if (parseOperand(Operands, Name))

767 return true;

768

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

773 }

774

775

776 if (parseOperand(Operands, Name, Name[1] == 's' ? Xtensa_SR : Xtensa_UR,

777 RAType))

778 return true;

779 }

780

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

785 }

786

787 getParser().Lex();

788 return false;

789}

790

794 if (Name.starts_with("wsr") || Name.starts_with("rsr") ||

795 Name.starts_with("xsr") || Name.starts_with("rur") ||

796 Name.starts_with("wur")) {

797 return ParseInstructionWithSR(Info, Name, NameLoc, Operands);

798 }

799

800

802

803

805 return false;

806

807

808 if (parseOperand(Operands, Name))

809 return true;

810

811

813 if (parseOperand(Operands, Name))

814 return true;

815

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

820 }

821

822 getParser().Lex();

823 return false;

824}

825

826bool XtensaAsmParser::parseLiteralDirective(SMLoc L) {

827 MCAsmParser &Parser = getParser();

828 const MCExpr *Value;

830 XtensaTargetStreamer &TS = this->getTargetStreamer();

831

832 if (Parser.parseExpression(Value))

833 return true;

834

836

837 if (!SE)

838 return Error(LiteralLoc, "literal label must be a symbol");

839

840 if (Parser.parseComma())

841 return true;

842

845 return Error(OpcodeLoc, "expected value");

846

847 if (Parser.parseExpression(Value))

848 return true;

849

851 return true;

852

854

856

857 return false;

858}

859

861 StringRef IDVal = DirectiveID.getString();

863

864 if (IDVal == ".literal_position") {

865 XtensaTargetStreamer &TS = this->getTargetStreamer();

868 }

869

870 if (IDVal == ".literal") {

871 return parseLiteralDirective(Loc);

872 }

873

875}

876

877

static MCRegister MatchRegisterName(StringRef Name)

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

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< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Analysis containing CSE Info

#define LLVM_EXTERNAL_VISIBILITY

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

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

bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)

static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue)

Definition XtensaAsmParser.cpp:107

LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser()

Definition XtensaAsmParser.cpp:878

static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)

Definition XtensaAsmParser.cpp:383

XtensaAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options)

Definition XtensaAsmParser.cpp:94

bool hasWindowed() const

Definition XtensaAsmParser.cpp:101

XtensaMatchResultTy

Definition XtensaAsmParser.cpp:87

@ Match_Dummy

Definition XtensaAsmParser.cpp:88

SMLoc getLoc() const

Get the current source location.

void UnLex(AsmToken const &Token)

const AsmToken & getTok() const

Get the current (last) lexed token.

const AsmToken & Lex()

Consume the next token from the input stream and return it.

LLVM_ABI size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)

Look ahead an arbitrary number of tokens.

Target independent representation for an assembler token.

LLVM_ABI SMLoc getLoc() const

int64_t getIntVal() const

StringRef getString() const

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

LLVM_ABI SMLoc getEndLoc() 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.

This class is intended to be used as a base class for asm properties and features specific to the tar...

void printExpr(raw_ostream &, const MCExpr &) const

bool parseOptionalToken(AsmToken::TokenKind T)

MCAsmParser & getParser()

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

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

MCStreamer & getStreamer()

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

LLVM_ABI MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

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

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

unsigned getOpcode() const

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

const MCOperand & getOperand(unsigned i) const

Interface to description of machine instruction set.

static MCOperand createExpr(const MCExpr *Val)

void setExpr(const MCExpr *Val)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

const MCExpr * getExpr() const

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

MCParsedAsmOperand()=default

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.

MCTargetStreamer * getTargetStreamer()

Generic base class for all target subtargets.

const FeatureBitset & getFeatureBits() const

const MCSymbol & getSymbol() const

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

StringRef getName() const

getName - Get the symbol name.

@ FIRST_TARGET_MATCH_RESULT_TY

MCTargetAsmParser(MCTargetOptions const &, const MCSubtargetInfo &STI, const MCInstrInfo &MII)

void setAvailableFeatures(const FeatureBitset &Value)

const MCSubtargetInfo & getSTI() const

const MCSubtargetInfo * STI

Current STI.

Target specific streamer interface.

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.

LLVM Value Representation.

virtual void emitLiteralPosition()=0

virtual void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, bool SwitchLiteralSection, SMLoc L=SMLoc())=0

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

MCExpr const & getExpr(MCExpr const &Expr)

bool checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits, RegisterAccessType RA)

MCRegister getUserRegister(unsigned Code, const MCRegisterInfo &MRI)

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

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.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

Target & getTheXtensaTarget()

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

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

const MCExpr * Val

Definition XtensaAsmParser.cpp:128

unsigned RegNum

Definition XtensaAsmParser.cpp:124

SMLoc EndLoc

Definition XtensaAsmParser.cpp:131

bool isImm12() const

Definition XtensaAsmParser.cpp:174

bool isOffset4m32() const

Definition XtensaAsmParser.cpp:179

bool isOffset8m16() const

Definition XtensaAsmParser.cpp:186

ImmOp Imm

Definition XtensaAsmParser.cpp:135

static std::unique_ptr< XtensaOperand > createToken(StringRef Str, SMLoc S)

Definition XtensaAsmParser.cpp:320

bool isImm8_sh8() const

Definition XtensaAsmParser.cpp:169

void addRegOperands(MCInst &Inst, unsigned N) const

Definition XtensaAsmParser.cpp:363

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

Definition XtensaAsmParser.cpp:346

void addImmOperands(MCInst &Inst, unsigned N) const

Definition XtensaAsmParser.cpp:368

StringRef getToken() const

Definition XtensaAsmParser.cpp:300

enum XtensaOperand::KindTy Kind

bool isMem() const override

isMem - Is this a memory operand?

Definition XtensaAsmParser.cpp:161

StringRef Tok

Definition XtensaAsmParser.cpp:133

bool isImm16_31() const

Definition XtensaAsmParser.cpp:209

bool isImm8n_7() const

Definition XtensaAsmParser.cpp:205

bool isToken() const override

isToken - Is this a token operand?

Definition XtensaAsmParser.cpp:158

bool isImm1n_15() const

Definition XtensaAsmParser.cpp:214

MCRegister getReg() const override

Definition XtensaAsmParser.cpp:290

SMLoc getStartLoc() const override

getStartLoc - Gets location of the first token of this operand

Definition XtensaAsmParser.cpp:286

bool isImm8() const

Definition XtensaAsmParser.cpp:167

bool isImm(int64_t MinValue, int64_t MaxValue) const

Definition XtensaAsmParser.cpp:163

RegOp Reg

Definition XtensaAsmParser.cpp:134

bool isImm12m() const

Definition XtensaAsmParser.cpp:177

bool isReg() const override

isReg - Is this a register operand?

Definition XtensaAsmParser.cpp:159

XtensaOperand(KindTy K)

Definition XtensaAsmParser.cpp:138

bool isB4constu() const

Definition XtensaAsmParser.cpp:253

bool isImm64n_4n() const

Definition XtensaAsmParser.cpp:218

bool isImm() const override

isImm - Is this an immediate operand?

Definition XtensaAsmParser.cpp:160

bool isUimm4() const

Definition XtensaAsmParser.cpp:201

bool isentry_imm12() const

Definition XtensaAsmParser.cpp:196

static std::unique_ptr< XtensaOperand > createReg(unsigned RegNo, SMLoc S, SMLoc E)

Definition XtensaAsmParser.cpp:328

SMLoc StartLoc

Definition XtensaAsmParser.cpp:131

bool isimm7_22() const

Definition XtensaAsmParser.cpp:283

SMLoc getEndLoc() const override

getEndLoc - Gets location of the last token of this operand

Definition XtensaAsmParser.cpp:288

bool isImm32n_95() const

Definition XtensaAsmParser.cpp:216

const MCExpr * getImm() const

Definition XtensaAsmParser.cpp:295

bool isUimm5() const

Definition XtensaAsmParser.cpp:203

bool isOffset8m8() const

Definition XtensaAsmParser.cpp:184

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

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

Definition XtensaAsmParser.cpp:305

KindTy

Definition XtensaAsmParser.cpp:117

@ Token

Definition XtensaAsmParser.cpp:118

@ Immediate

Definition XtensaAsmParser.cpp:120

@ Register

Definition XtensaAsmParser.cpp:119

XtensaOperand(const XtensaOperand &o)

Definition XtensaAsmParser.cpp:141

bool isImm1_16() const

Definition XtensaAsmParser.cpp:211

bool isB4const() const

Definition XtensaAsmParser.cpp:223

static std::unique_ptr< XtensaOperand > createImm(const MCExpr *Val, SMLoc S, SMLoc E)

Definition XtensaAsmParser.cpp:337

bool isOffset8m32() const

Definition XtensaAsmParser.cpp:191

bool isShimm1_31() const

Definition XtensaAsmParser.cpp:207

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