33#define DEBUG_TYPE "xtensa-asm-parser"
40 enum XtensaRegisterType { Xtensa_Generic, Xtensa_SR, Xtensa_UR };
45 "do not have a target streamer");
54 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
57 bool MatchingInlineAsm)
override;
59 unsigned Kind)
override;
65#define GET_ASSEMBLER_HEADER
66#include "XtensaGenAsmMatcher.inc"
72 XtensaRegisterType SR = Xtensa_Generic,
77 XtensaRegisterType SR = Xtensa_Generic,
82 SMLoc &EndLoc)
override {
87 bool parseLiteralDirective(SMLoc L);
92#define GET_OPERAND_DIAGNOSTIC_TYPES
93#include "XtensaGenAsmMatcher.inc"
94#undef GET_OPERAND_DIAGNOSTIC_TYPES
110static bool inRange(
const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
112 int64_t
Value = CE->getValue();
113 return Value >= MinValue &&
Value <= MaxValue;
164 bool isMem()
const override {
return false; }
166 bool isImm(int64_t MinValue, int64_t MaxValue)
const {
173 return isImm(-32768, 32512) &&
183 return isImm(0, 60) &&
190 return isImm(0, 510) &&
195 return isImm(0, 1020) &&
200 return isImm(0, 32760) &&
222 return isImm(-64, -4) &&
230 int64_t
Value = CE->getValue();
260 int64_t
Value = CE->getValue();
299 return isImm(-128, 112) &&
304 return isImm(-1024, 1016) &&
309 return isImm(-2048, 2032) &&
314 return isImm(-512, 508) &&
319 return isImm(0, 254) &&
326 return isImm(-512, 496) &&
366 auto Op = std::make_unique<XtensaOperand>(
Token);
375 auto Op = std::make_unique<XtensaOperand>(
Register);
376 Op->Reg.RegNum = RegNo;
384 auto Op = std::make_unique<XtensaOperand>(
Immediate);
392 assert(Expr &&
"Expr shouldn't be null!");
394 bool IsConstant =
false;
398 Imm = CE->getValue();
409 assert(
N == 1 &&
"Invalid number of operands!");
414 assert(
N == 1 &&
"Invalid number of operands!");
419#define GET_REGISTER_MATCHER
420#define GET_MATCHER_IMPLEMENTATION
421#include "XtensaGenAsmMatcher.inc"
432 if (ErrorLoc ==
SMLoc())
439bool XtensaAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
443 const unsigned Opcode = Inst.
getOpcode();
446 const MCSymbolRefExpr *OpExpr =
452 XtensaTargetStreamer &TS = this->getTargetStreamer();
457 int32_t
Imm = ImmOp64;
459 XtensaTargetStreamer &TS = this->getTargetStreamer();
494bool XtensaAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
498 bool MatchingInlineAsm) {
501 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
507 processInstruction(Inst, IDLoc, Out,
STI);
512 return Error(IDLoc,
"instruction use requires an option to be enabled");
514 return Error(IDLoc,
"unrecognized instruction mnemonic");
516 SMLoc ErrorLoc = IDLoc;
517 if (ErrorInfo != ~0U) {
519 return Error(ErrorLoc,
"too few operands for instruction");
521 ErrorLoc = ((XtensaOperand &)*
Operands[ErrorInfo]).getStartLoc();
522 if (ErrorLoc == SMLoc())
525 return Error(ErrorLoc,
"invalid operand for instruction");
527 case Match_InvalidImm8:
529 "expected immediate in range [-128, 127]");
530 case Match_InvalidImm8_sh8:
532 "expected immediate in range [-32768, 32512], first 8 bits "
534 case Match_InvalidB4const:
536 "expected b4const immediate");
537 case Match_InvalidB4constu:
539 "expected b4constu immediate");
540 case Match_InvalidImm12:
542 "expected immediate in range [-2048, 2047]");
543 case Match_InvalidImm12m:
545 "expected immediate in range [-2048, 2047]");
546 case Match_InvalidImm1_16:
548 "expected immediate in range [1, 16]");
549 case Match_InvalidImm1n_15:
551 "expected immediate in range [-1, 15] except 0");
552 case Match_InvalidImm32n_95:
554 "expected immediate in range [-32, 95]");
555 case Match_InvalidImm64n_4n:
557 "expected immediate in range [-64, -4]");
558 case Match_InvalidImm8n_7:
560 "expected immediate in range [-8, 7]");
561 case Match_InvalidShimm1_31:
563 "expected immediate in range [1, 31]");
564 case Match_InvalidUimm4:
566 "expected immediate in range [0, 15]");
567 case Match_InvalidUimm5:
569 "expected immediate in range [0, 31]");
570 case Match_InvalidOffset8m8:
572 "expected immediate in range [0, 255]");
573 case Match_InvalidOffset8m16:
575 "expected immediate in range [0, 510], first bit "
577 case Match_InvalidOffset8m32:
579 "expected immediate in range [0, 1020], first 2 bits "
581 case Match_InvalidOffset4m32:
583 "expected immediate in range [0, 60], first 2 bits "
585 case Match_Invalidentry_imm12:
587 "expected immediate in range [0, 32760], first 3 bits "
589 case Match_Invalidimm7_22:
591 "expected immediate in range [7, 22]");
592 case Match_InvalidSelect_2:
594 "expected immediate in range [0, 1]");
595 case Match_InvalidSelect_4:
597 "expected immediate in range [0, 3]");
598 case Match_InvalidSelect_8:
600 "expected immediate in range [0, 7]");
601 case Match_InvalidSelect_16:
603 "expected immediate in range [0, 15]");
604 case Match_InvalidSelect_256:
606 "expected immediate in range [0, 255]");
607 case Match_InvalidOffset_16_16:
610 "expected immediate in range [-128, 112], first 4 bits should be zero");
611 case Match_InvalidOffset_256_8:
613 "expected immediate in range [-1024, 1016], first 3 bits "
615 case Match_InvalidOffset_256_16:
617 "expected immediate in range [-2048, 2032], first 4 bits "
619 case Match_InvalidOffset_256_4:
622 "expected immediate in range [-512, 508], first 2 bits should be zero");
623 case Match_InvalidOffset_128_2:
626 "expected immediate in range [0, 254], first bit should be zero");
627 case Match_InvalidOffset_128_1:
629 "expected immediate in range [0, 127]");
630 case Match_InvalidOffset_64_16:
633 "expected immediate in range [-512, 496], first 4 bits should be zero");
646 const MCExpr *Expr =
nullptr;
647 if (Parser.parseExpression(Expr)) {
653 if (Expr->
getKind() == MCExpr::ExprKind::Constant)
654 return Error(getLoc(),
"unknown operand");
665 if (RegNo == Xtensa::GPIO_OUT_S2 &&
666 getSTI().getFeatureBits()[Xtensa::FeatureESP32S3Ops])
667 RegNo = Xtensa::GPIO_OUT_S3;
677 Reg = Xtensa::NoRegister;
685 return Error(StartLoc,
"invalid register name");
690 XtensaRegisterType RegType,
692 SMLoc FirstS = getLoc();
693 bool HadParens =
false;
708 MCRegister RegNo = 0;
714 if (RegType == Xtensa_Generic)
720 if (RegType == Xtensa_UR) {
730 RegNo = getRegisterByName(
RegName);
781 return parseOperandWithModifier(
Operands);
797 XtensaRegisterType RegType,
801 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic);
812 if (parseRegister(
Operands,
true, RegType, RAType).isSuccess())
816 if (parseImmediate(
Operands).isSuccess())
820 return Error(getLoc(),
"unknown operand");
831 if ((
Name.size() > 4) && Name[3] ==
'.') {
839 MCRegister RegNo = getRegisterByName(
RegName);
842 return Error(NameLoc,
"invalid register name");
862 return Error(Loc,
"unexpected token");
866 if (parseOperand(
Operands, Name, Name[1] ==
's' ? Xtensa_SR : Xtensa_UR,
874 return Error(Loc,
"unexpected token");
884 if (
Name.starts_with(
"wsr") ||
Name.starts_with(
"rsr") ||
885 Name.starts_with(
"xsr") ||
Name.starts_with(
"rur") ||
886 Name.starts_with(
"wur")) {
887 return ParseInstructionWithSR(Info, Name, NameLoc,
Operands);
909 return Error(Loc,
"unexpected token");
916bool XtensaAsmParser::parseLiteralDirective(
SMLoc L) {
920 XtensaTargetStreamer &TS = this->getTargetStreamer();
922 if (Parser.parseExpression(
Value))
928 return Error(LiteralLoc,
"literal label must be a symbol");
930 if (Parser.parseComma())
935 return Error(OpcodeLoc,
"expected value");
937 if (Parser.parseExpression(
Value))
951 StringRef IDVal = DirectiveID.
getString();
954 if (IDVal ==
".literal_position") {
955 XtensaTargetStreamer &TS = this->getTargetStreamer();
960 if (IDVal ==
".literal") {
961 return parseLiteralDirective(Loc);
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")
#define LLVM_EXTERNAL_VISIBILITY
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
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)
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)
MCStreamer & getStreamer()
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.
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(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
Represent a constant reference to a string, i.e.
LLVM Value Representation.
virtual void emitLiteralPosition()
virtual void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, bool SwitchLiteralSection, SMLoc L=SMLoc())
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.
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<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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<X> - Return the argument parameter cast to the specified type.
bool isOffset_256_8() const
bool isOffset4m32() const
bool isOffset8m16() const
static std::unique_ptr< XtensaOperand > createToken(StringRef Str, SMLoc S)
void addRegOperands(MCInst &Inst, unsigned N) const
bool isOffset_64_16() const
void addExpr(MCInst &Inst, const MCExpr *Expr) const
void addImmOperands(MCInst &Inst, unsigned N) const
StringRef getToken() const
bool isOffset_256_16() 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 isSelect_256() const
bool isImm(int64_t MinValue, int64_t MaxValue) const
bool isReg() const override
isReg - Is this a register operand?
bool isImm() const override
isImm - Is this an immediate operand?
bool isentry_imm12() const
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
bool isOffset_16_16() const
const MCExpr * getImm() const
bool isOffset_256_4() const
void print(raw_ostream &OS, const MCAsmInfo &MAI) const override
print - Print a debug representation of the operand to the given stream.
XtensaOperand(const XtensaOperand &o)
bool isOffset_128_1() const
bool isOffset_128_2() const
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,...