35#define DEBUG_TYPE "avr-asm-parser"
45 const std::string GENERATE_STUBS =
"gs";
47 enum AVRMatchResultTy {
48 Match_InvalidRegisterOnTiny = FIRST_TARGET_MATCH_RESULT_TY + 1,
51#define GET_ASSEMBLER_HEADER
52#include "AVRGenAsmMatcher.inc"
57 bool MatchingInlineAsm)
override;
60 SMLoc &EndLoc)
override;
62 SMLoc &EndLoc)
override;
72 int parseRegisterName(
unsigned (*matchFn)(
StringRef));
73 int parseRegisterName();
81 unsigned Kind)
override;
83 unsigned toDREG(
unsigned Reg,
unsigned From = AVR::sub_lo) {
84 MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
85 return MRI->getMatchingSuperReg(Reg,
From, Class);
93 bool parseLiteralValues(
unsigned SizeInBytes,
SMLoc L);
112 enum KindTy { k_Immediate, k_Register, k_Token, k_Memri }
Kind;
116 :
Kind(k_Token), Tok(Tok), Start(S), End(S) {}
117 AVROperand(
unsigned Reg,
SMLoc const &S,
SMLoc const &
E)
124 struct RegisterImmediate {
136 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
137 assert(Kind == k_Register &&
"Unexpected operand kind");
138 assert(
N == 1 &&
"Invalid number of operands!");
147 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
153 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
154 assert(Kind == k_Immediate &&
"Unexpected operand kind");
155 assert(
N == 1 &&
"Invalid number of operands!");
157 const MCExpr *Expr = getImm();
162 void addMemriOperands(
MCInst &Inst,
unsigned N)
const {
163 assert(Kind == k_Memri &&
"Unexpected operand kind");
164 assert(
N == 2 &&
"Invalid number of operands");
167 addExpr(Inst, getImm());
170 void addImmCom8Operands(
MCInst &Inst,
unsigned N)
const {
171 assert(
N == 1 &&
"Invalid number of operands!");
174 const auto *
CE = cast<MCConstantExpr>(getImm());
178 bool isImmCom8()
const {
181 const auto *
CE = dyn_cast<MCConstantExpr>(getImm());
184 int64_t
Value =
CE->getValue();
185 return isUInt<8>(
Value);
188 bool isReg()
const override {
return Kind == k_Register; }
189 bool isImm()
const override {
return Kind == k_Immediate; }
190 bool isToken()
const override {
return Kind == k_Token; }
191 bool isMem()
const override {
return Kind == k_Memri; }
192 bool isMemri()
const {
return Kind == k_Memri; }
195 assert(Kind == k_Token &&
"Invalid access!");
199 unsigned getReg()
const override {
200 assert((Kind == k_Register || Kind == k_Memri) &&
"Invalid access!");
205 const MCExpr *getImm()
const {
206 assert((Kind == k_Immediate || Kind == k_Memri) &&
"Invalid access!");
210 static std::unique_ptr<AVROperand> CreateToken(
StringRef Str,
SMLoc S) {
211 return std::make_unique<AVROperand>(Str, S);
214 static std::unique_ptr<AVROperand> CreateReg(
unsigned RegNum,
SMLoc S,
216 return std::make_unique<AVROperand>(RegNum, S,
E);
219 static std::unique_ptr<AVROperand> CreateImm(
const MCExpr *Val,
SMLoc S,
221 return std::make_unique<AVROperand>(Val, S,
E);
224 static std::unique_ptr<AVROperand>
226 return std::make_unique<AVROperand>(RegNum, Val, S,
E);
234 void makeReg(
unsigned RegNo) {
236 RegImm = {RegNo,
nullptr};
239 void makeImm(
MCExpr const *Ex) {
244 void makeMemri(
unsigned RegNo,
MCExpr const *Imm) {
255 O <<
"Token: \"" << getToken() <<
"\"";
261 O <<
"Immediate: \"" << *getImm() <<
"\"";
266 O <<
"Memri: \"" <<
getReg() <<
'+' << *getImm() <<
"\"";
286bool AVRAsmParser::invalidOperand(
SMLoc const &Loc,
289 SMLoc ErrorLoc = Loc;
290 char const *Diag =
nullptr;
294 Diag =
"too few operands for instruction.";
299 if (
Op.getStartLoc() !=
SMLoc()) {
300 ErrorLoc =
Op.getStartLoc();
306 Diag =
"invalid operand for instruction";
309 return Error(ErrorLoc, Diag);
312bool AVRAsmParser::missingFeature(
llvm::SMLoc const &Loc,
314 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
324bool AVRAsmParser::MatchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
327 bool MatchingInlineAsm) {
329 unsigned MatchResult =
332 switch (MatchResult) {
334 return emit(Inst, Loc, Out);
335 case Match_MissingFeature:
337 case Match_InvalidOperand:
339 case Match_MnemonicFail:
340 return Error(Loc,
"invalid instruction");
341 case Match_InvalidRegisterOnTiny:
342 return Error(Loc,
"invalid register on avrtiny");
350int AVRAsmParser::parseRegisterName(
unsigned (*matchFn)(
StringRef)) {
353 int RegNum = matchFn(
Name);
359 if (RegNum == AVR::NoRegister) {
360 RegNum = matchFn(
Name.lower());
362 if (RegNum == AVR::NoRegister) {
363 RegNum = matchFn(
Name.upper());
369int AVRAsmParser::parseRegisterName() {
372 if (RegNum == AVR::NoRegister)
378int AVRAsmParser::parseRegister(
bool RestoreOnFailure) {
379 int RegNum = AVR::NoRegister;
391 RegNum = toDREG(parseRegisterName());
393 if (RegNum == AVR::NoRegister && RestoreOnFailure) {
394 getLexer().UnLex(std::move(ColonTok));
395 getLexer().UnLex(std::move(HighTok));
398 RegNum = parseRegisterName();
405 int RegNo = parseRegister();
407 if (RegNo == AVR::NoRegister)
411 if (AVR::R0 <= RegNo && RegNo <= AVR::R15 &&
416 Operands.push_back(AVROperand::CreateReg(RegNo,
T.getLoc(),
T.getEndLoc()));
425 if (!tryParseRelocExpression(
Operands))
447 bool isNegated =
false;
479 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
495 MCExpr const *InnerExpression;
496 if (getParser().parseExpression(InnerExpression))
521 switch (getLexer().getKind()) {
527 if (maybeReg && !tryParseRegisterOperand(
Operands)) {
534 return tryParseExpression(
Operands);
539 switch (getLexer().peekTok().getKind()) {
571 RegNo = parseRegister();
573 if (RegNo == AVR::NoRegister)
596 RegNo = parseRegister(
false);
599 return (RegNo == AVR::NoRegister);
606 RegNo = parseRegister(
true);
609 if (RegNo == AVR::NoRegister)
614void AVRAsmParser::eatComma() {
625 Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
633 auto MatchResult = MatchOperandParserImpl(
Operands, Mnemonic);
640 SMLoc Loc = getLexer().getLoc();
643 return Error(Loc,
"failed to parse register and immediate pair");
648 bool maybeReg =
true;
649 if (OperandNum == 1) {
650 std::array<StringRef, 8> Insts = {
"lds",
"adiw",
"sbiw",
"ldi"};
651 for (
auto Inst : Insts) {
652 if (Inst == Mnemonic) {
657 }
else if (OperandNum == 0) {
658 std::array<StringRef, 8> Insts = {
"sts",
"call",
"rcall",
"rjmp",
"jmp"};
659 for (
auto Inst : Insts) {
660 if (Inst == Mnemonic) {
667 if (parseOperand(
Operands, maybeReg)) {
668 SMLoc Loc = getLexer().getLoc();
670 return Error(Loc,
"unexpected token in argument list");
679 if (IDVal.
lower() ==
".long") {
681 }
else if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short") {
683 }
else if (IDVal.
lower() ==
".byte") {
684 parseLiteralValues(1, DirectiveID.
getLoc());
689bool AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes,
SMLoc L) {
721 auto parseOne = [&]() ->
bool {
728 return (parseMany(parseOne));
735#define GET_REGISTER_MATCHER
736#define GET_MATCHER_IMPLEMENTATION
737#include "AVRGenAsmMatcher.inc"
741 unsigned ExpectedKind) {
742 AVROperand &Op =
static_cast<AVROperand &
>(AsmOp);
743 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
748 if (
MCConstantExpr const *Const = dyn_cast<MCConstantExpr>(Op.getImm())) {
749 int64_t RegNum = Const->getValue();
752 if (0 <= RegNum && RegNum <= 15 &&
754 return Match_InvalidRegisterOnTiny;
759 if (RegNum != AVR::NoRegister) {
761 if (validateOperandClass(Op,
Expected) == Match_Success) {
762 return Match_Success;
772 if (isSubclass(
Expected, MCK_DREGS)) {
773 unsigned correspondingDREG = toDREG(Op.getReg());
775 if (correspondingDREG != AVR::NoRegister) {
776 Op.makeReg(correspondingDREG);
777 return validateOperandClass(Op,
Expected);
781 return Match_InvalidOperand;
unsigned const MachineRegisterInfo * MRI
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file implements a class to represent arbitrary precision integral constant values and operations...
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmParser()
BlockVerifier::State From
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#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())
void emitValueForModiferKind(const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc=SMLoc(), AVRMCExpr::VariantKind ModifierKind=AVRMCExpr::VK_AVR_None)
static const AVRMCExpr * create(VariantKind Kind, const MCExpr *Expr, bool isNegated, MCContext &Ctx)
Creates an AVR machine code expression.
static VariantKind getKindByName(StringRef Name)
VariantKind
Specifies the type of an expression.
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...
bool is(TokenKind K) const
TokenKind getKind() 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.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Class representing an expression and its matching format.
Generic assembler lexer interface, for use by target specific assembly lexers.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
AsmToken::TokenKind getKind() const
Get the kind of current token.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
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.
virtual MCAsmLexer & getLexer()=0
const MCRegisterInfo * getRegisterInfo() const
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.
void addOperand(const MCOperand Op)
Interface to description of machine instruction set.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual unsigned getReg() const =0
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterClass - Base class of TargetRegisterClass.
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.
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool ParseDirective(AsmToken DirectiveID)=0
ParseDirective - Parse a target specific assembler directive.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
void setAvailableFeatures(const FeatureBitset &Value)
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
virtual OperandMatchResultTy tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
const MCSubtargetInfo * STI
Current STI.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
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.
std::string str() const
str - Get the contents as an std::string.
std::string lower() const
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheAVRTarget()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...