34 #define DEBUG_TYPE "avr-asm-parser"
44 #define GET_ASSEMBLER_HEADER
45 #include "AVRGenAsmMatcher.inc"
47 bool MatchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
50 bool MatchingInlineAsm)
override;
52 bool ParseRegister(
unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
override;
54 bool ParseInstruction(ParseInstructionInfo &Info, StringRef
Name,
57 bool ParseDirective(AsmToken directiveID)
override;
62 int parseRegisterName(
unsigned (*matchFn)(StringRef));
63 int parseRegisterName();
70 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
71 unsigned Kind)
override;
73 unsigned toDREG(
unsigned Reg,
unsigned From = AVR::sub_lo) {
74 MCRegisterClass
const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
78 bool emit(MCInst &Instruction, SMLoc
const &Loc, MCStreamer &Out)
const;
79 bool invalidOperand(SMLoc
const &Loc,
OperandVector const &Operands,
80 uint64_t
const &ErrorInfo);
81 bool missingFeature(SMLoc
const &Loc, uint64_t
const &ErrorInfo);
100 enum KindTy { k_Immediate, k_Register, k_Token, k_Memri } Kind;
125 assert(Kind == k_Register &&
"Unexpected operand kind");
126 assert(N == 1 &&
"Invalid number of operands!");
135 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
142 assert(Kind == k_Immediate &&
"Unexpected operand kind");
143 assert(N == 1 &&
"Invalid number of operands!");
151 assert(Kind == k_Memri &&
"Unexpected operand kind");
152 assert(N == 2 &&
"Invalid number of operands");
158 bool isReg()
const {
return Kind == k_Register; }
159 bool isImm()
const {
return Kind == k_Immediate; }
160 bool isToken()
const {
return Kind == k_Token; }
161 bool isMem()
const {
return Kind == k_Memri; }
162 bool isMemri()
const {
return Kind == k_Memri; }
165 assert(Kind == k_Token &&
"Invalid access!");
170 assert((Kind == k_Register || Kind == k_Memri) &&
"Invalid access!");
176 assert((Kind == k_Immediate || Kind == k_Memri) &&
"Invalid access!");
181 return make_unique<AVROperand>(Str, S);
186 return make_unique<AVROperand>(RegNum, S,
E);
191 return make_unique<AVROperand>(Val, S,
E);
194 static std::unique_ptr<AVROperand>
196 return make_unique<AVROperand>(RegNum, Val, S,
E);
206 RegImm = {RegNo,
nullptr};
225 O <<
"Token: \"" <<
getToken() <<
"\"";
228 O <<
"Register: " <<
getReg();
231 O <<
"Immediate: \"" << *
getImm() <<
"\"";
236 O <<
"Memri: \"" <<
getReg() <<
'+' << *
getImm() <<
"\"";
254 bool AVRAsmParser::invalidOperand(SMLoc
const &Loc,
256 uint64_t
const &ErrorInfo) {
257 SMLoc ErrorLoc = Loc;
258 char const *Diag = 0;
260 if (ErrorInfo != ~0U) {
261 if (ErrorInfo >= Operands.size()) {
262 Diag =
"too few operands for instruction.";
264 AVROperand
const &
Op = (AVROperand
const &)*Operands[ErrorInfo];
267 if (Op.getStartLoc() != SMLoc()) {
268 ErrorLoc = Op.getStartLoc();
274 Diag =
"invalid operand for instruction";
277 return Error(ErrorLoc, Diag);
280 bool AVRAsmParser::missingFeature(
llvm::SMLoc const &Loc,
281 uint64_t
const &ErrorInfo) {
282 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
285 bool AVRAsmParser::emit(MCInst &Inst, SMLoc
const &Loc, MCStreamer &Out)
const {
287 Out.EmitInstruction(Inst, STI);
292 bool AVRAsmParser::MatchAndEmitInstruction(SMLoc Loc,
unsigned &Opcode,
294 MCStreamer &Out, uint64_t &ErrorInfo,
295 bool MatchingInlineAsm) {
297 unsigned MatchResult =
298 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
300 switch (MatchResult) {
305 default:
return true;
311 int AVRAsmParser::parseRegisterName(
unsigned (*matchFn)(StringRef)) {
314 int RegNum = matchFn(Name);
320 if (RegNum == AVR::NoRegister) {
321 RegNum = matchFn(Name.lower());
323 if (RegNum == AVR::NoRegister) {
324 RegNum = matchFn(Name.upper());
330 int AVRAsmParser::parseRegisterName() {
333 if (RegNum == AVR::NoRegister)
339 int AVRAsmParser::parseRegister() {
340 int RegNum = AVR::NoRegister;
350 RegNum = toDREG(parseRegisterName());
353 RegNum = parseRegisterName();
359 bool AVRAsmParser::tryParseRegisterOperand(
OperandVector &Operands) {
360 int RegNo = parseRegister();
362 if (RegNo == AVR::NoRegister)
365 AsmToken
const &
T = Parser.
getTok();
372 bool AVRAsmParser::tryParseExpression(
OperandVector &Operands) {
375 if (!tryParseRelocExpression(Operands))
387 MCExpr
const *Expression;
396 bool AVRAsmParser::tryParseRelocExpression(
OperandVector &Operands) {
397 bool isNegated =
false;
406 if (ReadCount == 2) {
439 MCExpr
const *InnerExpression;
466 if (!tryParseRegisterOperand(Operands)) {
472 return tryParseExpression(Operands);
477 switch (
getLexer().peekTok().getKind()) {
482 if (!tryParseExpression(Operands))
501 DEBUG(
dbgs() <<
"parseMemriOperand()\n");
504 MCExpr
const *Expression;
509 RegNo = parseRegister();
511 if (RegNo == AVR::NoRegister)
520 if (
getParser().parseExpression(Expression))
531 bool AVRAsmParser::ParseRegister(
unsigned &RegNo, SMLoc &StartLoc,
534 RegNo = parseRegister();
537 return (RegNo == AVR::NoRegister);
540 void AVRAsmParser::eatComma() {
548 bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info,
549 StringRef Mnemonic, SMLoc NameLoc,
555 if (!first) eatComma();
559 auto MatchResult = MatchOperandParserImpl(Operands, Mnemonic);
569 return Error(Loc,
"failed to parse register and immediate pair");
572 if (parseOperand(Operands)) {
575 return Error(Loc,
"unexpected token in argument list");
582 bool AVRAsmParser::ParseDirective(
llvm::AsmToken DirectiveID) {
return true; }
588 #define GET_REGISTER_MATCHER
589 #define GET_MATCHER_IMPLEMENTATION
590 #include "AVRGenAsmMatcher.inc"
593 unsigned AVRAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
594 unsigned ExpectedKind) {
595 AVROperand &Op =
static_cast<AVROperand &
>(AsmOp);
596 MatchClassKind Expected =
static_cast<MatchClassKind
>(ExpectedKind);
601 if (MCConstantExpr
const *Const = dyn_cast<MCConstantExpr>(Op.getImm())) {
602 int64_t RegNum = Const->getValue();
603 std::ostringstream RegName;
604 RegName <<
"r" << RegNum;
606 if (RegNum != AVR::NoRegister) {
619 if (isSubclass(Expected, MCK_DREGS)) {
620 unsigned correspondingDREG = toDREG(Op.getReg());
622 if (correspondingDREG != AVR::NoRegister) {
623 Op.makeReg(correspondingDREG);
624 return validateOperandClass(Op, Expected);
void addImmOperands(MCInst &Inst, unsigned N) const
virtual void print(raw_ostream &O) const
print - Print a debug representation of the operand to the given stream.
An parsed AVR assembly operand.
const char * getPointer() const
TokenKind getKind() const
void makeReg(unsigned RegNo)
AVROperand(unsigned Reg, MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static MCOperand createExpr(const MCExpr *Val)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
SMLoc getStartLoc() const
getStartLoc - Get the location of the first token of this operand.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
SMLoc getLoc() const
Get the current source location.
StringRef getToken() const
AVROperand(unsigned Reg, SMLoc const &S, SMLoc const &E)
void makeImm(MCExpr const *Ex)
Parses AVR assembly from a stream.
bool Error(SMLoc L, const Twine &Msg, SMRange Range=SMRange())
Target & getTheAVRTarget()
VariantKind
Specifies the type of an expression.
void addRegOperands(MCInst &Inst, unsigned N) const
const MCExpr * getImm() const
static MCOperand createReg(unsigned Reg)
Generic assembler lexer interface, for use by target specific assembly lexers.
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
bool isToken() const
isToken - Is this a token operand?
AsmToken::TokenKind getKind() const
Get the kind of current token.
static std::unique_ptr< AVROperand > CreateReg(unsigned RegNum, SMLoc S, SMLoc E)
Base class for the full range of assembler expressions which are needed for parsing.
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
This file implements a class to represent arbitrary precision integral constant values and operations...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
void addMemriOperands(MCInst &Inst, unsigned N) const
Adds the contained reg+imm operand to an instruction.
AVROperand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
MCAsmLexer & getLexer() const
SMLoc getEndLoc() const
getEndLoc - Get the location of the last token of this operand.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Instances of this class represent a single low-level machine instruction.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
void makeMemri(unsigned RegNo, MCExpr const *Imm)
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
static std::unique_ptr< AVROperand > CreateImm(const MCExpr *Val, SMLoc S, SMLoc E)
static std::unique_ptr< AVROperand > CreateMemri(unsigned RegNum, const MCExpr *Val, SMLoc S, SMLoc E)
Interface to description of machine instruction set.
virtual MCAsmLexer & getLexer()=0
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
AVROperand(StringRef Tok, SMLoc const &S)
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg...
bool isMem() const
isMem - Is this a memory operand?
void makeToken(StringRef Token)
MCAsmParser & getParser() const
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
bool is(TokenKind K) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static std::unique_ptr< AVROperand > CreateToken(StringRef Str, SMLoc S)
static SMLoc getFromPointer(const char *Ptr)
const MCRegisterInfo * getRegisterInfo() const
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
void addExpr(MCInst &Inst, const MCExpr *Expr) const
void setAvailableFeatures(uint64_t Value)
MCSubtargetInfo - Generic base class for all target subtargets.
static const AVRMCExpr * create(VariantKind Kind, const MCExpr *Expr, bool isNegated, MCContext &Ctx)
Creates an AVR machine code expression.
static VariantKind getKindByName(StringRef Name)
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isImm() const
isImm - Is this an immediate operand?
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
This class implements an extremely fast bulk output stream that can only output to a stream...
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
AVRAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options)
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
bool isReg() const
isReg - Is this a register operand?
Represents a location in source code.
void LLVMInitializeAVRAsmParser()
static MCOperand createImm(int64_t Val)