33#define DEBUG_TYPE "xtensa-asm-parser"
50 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
53 bool MatchingInlineAsm)
override;
55 unsigned Kind)
override;
61#define GET_ASSEMBLER_HEADER
62#include "XtensaGenAsmMatcher.inc"
73 SMLoc &EndLoc)
override {
77 bool parseLiteralDirective(
SMLoc L);
82#define GET_OPERAND_DIAGNOSTIC_TYPES
83#include "XtensaGenAsmMatcher.inc"
84#undef GET_OPERAND_DIAGNOSTIC_TYPES
95static bool inRange(
const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
96 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
97 int64_t
Value = CE->getValue();
149 bool isMem()
const override {
return false; }
151 bool isImm(int64_t MinValue, int64_t MaxValue)
const {
158 return isImm(-32768, 32512) &&
159 ((cast<MCConstantExpr>(
getImm())->getValue() & 0xFF) == 0);
168 return isImm(0, 60) &&
169 ((cast<MCConstantExpr>(
getImm())->getValue() & 0x3) == 0);
175 return isImm(0, 510) &&
176 ((cast<MCConstantExpr>(
getImm())->getValue() & 0x1) == 0);
180 return isImm(0, 1020) &&
181 ((cast<MCConstantExpr>(
getImm())->getValue() & 0x3) == 0);
204 if (
auto *CE = dyn_cast<MCConstantExpr>(
getImm())) {
205 int64_t
Value = CE->getValue();
234 if (
auto *CE = dyn_cast<MCConstantExpr>(
getImm())) {
235 int64_t
Value = CE->getValue();
297 auto Op = std::make_unique<XtensaOperand>(
Token);
306 auto Op = std::make_unique<XtensaOperand>(
Register);
307 Op->Reg.RegNum = RegNo;
315 auto Op = std::make_unique<XtensaOperand>(
Immediate);
323 assert(Expr &&
"Expr shouldn't be null!");
325 bool IsConstant =
false;
327 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
329 Imm = CE->getValue();
340 assert(
N == 1 &&
"Invalid number of operands!");
345 assert(
N == 1 &&
"Invalid number of operands!");
350#define GET_REGISTER_MATCHER
351#define GET_MATCHER_IMPLEMENTATION
352#include "XtensaGenAsmMatcher.inc"
363 if (ErrorLoc ==
SMLoc())
370bool XtensaAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
374 const unsigned Opcode = Inst.
getOpcode();
390 int32_t
Imm = ImmOp64;
391 if (!isInt<12>(Imm)) {
433bool XtensaAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
437 bool MatchingInlineAsm) {
446 processInstruction(Inst, IDLoc, Out,
STI);
451 return Error(IDLoc,
"instruction use requires an option to be enabled");
453 return Error(IDLoc,
"unrecognized instruction mnemonic");
455 SMLoc ErrorLoc = IDLoc;
458 return Error(ErrorLoc,
"too few operands for instruction");
461 if (ErrorLoc ==
SMLoc())
464 return Error(ErrorLoc,
"invalid operand for instruction");
466 case Match_InvalidImm8:
468 "expected immediate in range [-128, 127]");
469 case Match_InvalidImm8_sh8:
471 "expected immediate in range [-32768, 32512], first 8 bits "
473 case Match_InvalidB4const:
475 "expected b4const immediate");
476 case Match_InvalidB4constu:
478 "expected b4constu immediate");
479 case Match_InvalidImm12:
481 "expected immediate in range [-2048, 2047]");
482 case Match_InvalidImm12m:
484 "expected immediate in range [-2048, 2047]");
485 case Match_InvalidImm1_16:
487 "expected immediate in range [1, 16]");
488 case Match_InvalidImm1n_15:
490 "expected immediate in range [-1, 15] except 0");
491 case Match_InvalidImm32n_95:
493 "expected immediate in range [-32, 95]");
494 case Match_InvalidShimm1_31:
496 "expected immediate in range [1, 31]");
497 case Match_InvalidUimm4:
499 "expected immediate in range [0, 15]");
500 case Match_InvalidUimm5:
502 "expected immediate in range [0, 31]");
503 case Match_InvalidOffset8m8:
505 "expected immediate in range [0, 255]");
506 case Match_InvalidOffset8m16:
508 "expected immediate in range [0, 510], first bit "
510 case Match_InvalidOffset8m32:
512 "expected immediate in range [0, 1020], first 2 bits "
514 case Match_InvalidOffset4m32:
516 "expected immediate in range [0, 60], first 2 bits "
530 const MCExpr *Expr =
nullptr;
537 if (Expr->
getKind() == MCExpr::ExprKind::Constant)
538 return Error(getLoc(),
"unknown operand");
549 Reg = Xtensa::NoRegister;
557 return Error(StartLoc,
"invalid register name");
561 bool AllowParens,
bool SR) {
562 SMLoc FirstS = getLoc();
563 bool HadParens =
false;
638 if (
getParser().parseIdentifier(Identifier))
646 return parseOperandWithModifier(
Operands);
676 if (parseRegister(
Operands,
true, SR).isSuccess())
680 if (parseImmediate(
Operands).isSuccess())
684 return Error(getLoc(),
"unknown operand");
690 if ((
Name.starts_with(
"wsr.") ||
Name.starts_with(
"rsr.") ||
691 Name.starts_with(
"xsr.")) &&
706 return Error(NameLoc,
"invalid register name");
726 return Error(Loc,
"unexpected token");
737 return Error(Loc,
"unexpected token");
747 if (
Name.starts_with(
"wsr") ||
Name.starts_with(
"rsr") ||
748 Name.starts_with(
"xsr")) {
749 return ParseInstructionWithSR(Info,
Name, NameLoc,
Operands);
771 return Error(Loc,
"unexpected token");
778bool XtensaAsmParser::parseLiteralDirective(
SMLoc L) {
790 return Error(LiteralLoc,
"literal label must be a symbol");
797 return Error(OpcodeLoc,
"expected value");
816 if (IDVal ==
".literal_position") {
822 if (IDVal ==
".literal") {
823 return parseLiteralDirective(Loc);
static MCRegister MatchRegisterName(StringRef Name)
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.
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser()
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
XtensaAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options)
Target independent representation for an assembler token.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
void UnLex(AsmToken const &Token)
SMLoc getLoc() const
Get the current source location.
const AsmToken & getTok() const
Get the current (last) lexed token.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
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.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
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 const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
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.
Instances of this class represent operands of the MCInst class.
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.
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
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
@ FIRST_TARGET_MATCH_RESULT_TY
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
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
LLVM Value Representation.
static const XtensaMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
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.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Target & getTheXtensaTarget()
DWARFExpression::Operation Op
bool isOffset4m32() const
bool isOffset8m16() const
static std::unique_ptr< XtensaOperand > createToken(StringRef Str, SMLoc S)
void addRegOperands(MCInst &Inst, unsigned N) const
void addExpr(MCInst &Inst, const MCExpr *Expr) const
void addImmOperands(MCInst &Inst, unsigned N) const
StringRef getToken() const
enum XtensaOperand::KindTy Kind
bool isMem() const override
isMem - Is this a memory operand?
bool isToken() const override
isToken - Is this a token operand?
MCRegister getReg() const override
SMLoc getStartLoc() const override
getStartLoc - Gets location of the first token of this operand
bool isImm(int64_t MinValue, int64_t MaxValue) const
void print(raw_ostream &OS) const override
print - Print a debug representation of the operand to the given stream.
bool isReg() const override
isReg - Is this a register operand?
bool isImm() const override
isImm - Is this an immediate operand?
static std::unique_ptr< XtensaOperand > createReg(unsigned RegNo, SMLoc S, SMLoc E)
SMLoc getEndLoc() const override
getEndLoc - Gets location of the last token of this operand
const MCExpr * getImm() const
XtensaOperand(const XtensaOperand &o)
static std::unique_ptr< XtensaOperand > createImm(const MCExpr *Val, SMLoc S, SMLoc E)
bool isOffset8m32() const
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...