35 #define DEBUG_TYPE "avr-asm-parser" 45 const std::string GENERATE_STUBS =
"gs";
47 #define GET_ASSEMBLER_HEADER 48 #include "AVRGenAsmMatcher.inc" 50 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
53 bool MatchingInlineAsm)
override;
55 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
60 bool ParseDirective(
AsmToken DirectiveID)
override;
65 int parseRegisterName(
unsigned (*matchFn)(
StringRef));
66 int parseRegisterName();
74 unsigned Kind)
override;
76 unsigned toDREG(
unsigned Reg,
unsigned From = AVR::sub_lo) {
77 MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
86 bool parseLiteralValues(
unsigned SizeInBytes,
SMLoc L);
93 MRI = getContext().getRegisterInfo();
95 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
105 enum KindTy { k_Immediate, k_Register, k_Token, k_Memri }
Kind;
109 : Base(), Kind(k_Token), Tok(Tok), Start(S), End(S) {}
110 AVROperand(
unsigned Reg,
SMLoc const &S,
SMLoc const &
E)
111 : Base(), Kind(k_Register), RegImm({
Reg,
nullptr}), Start(S), End(
E) {}
113 : Base(), Kind(k_Immediate), RegImm({0, Imm}), Start(S), End(
E) {}
115 : Base(), Kind(k_Memri), RegImm({
Reg, Imm}), Start(S), End(
E) {}
117 struct RegisterImmediate {
123 RegisterImmediate RegImm;
129 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
130 assert(Kind == k_Register &&
"Unexpected operand kind");
131 assert(N == 1 &&
"Invalid number of operands!");
140 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
146 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
147 assert(Kind == k_Immediate &&
"Unexpected operand kind");
148 assert(N == 1 &&
"Invalid number of operands!");
150 const MCExpr *Expr = getImm();
155 void addMemriOperands(
MCInst &Inst,
unsigned N)
const {
156 assert(Kind == k_Memri &&
"Unexpected operand kind");
157 assert(N == 2 &&
"Invalid number of operands");
160 addExpr(Inst, getImm());
163 bool isReg()
const {
return Kind == k_Register; }
164 bool isImm()
const {
return Kind == k_Immediate; }
165 bool isToken()
const {
return Kind == k_Token; }
166 bool isMem()
const {
return Kind == k_Memri; }
167 bool isMemri()
const {
return Kind == k_Memri; }
170 assert(Kind == k_Token &&
"Invalid access!");
175 assert((Kind == k_Register || Kind == k_Memri) &&
"Invalid access!");
180 const MCExpr *getImm()
const {
181 assert((Kind == k_Immediate || Kind == k_Memri) &&
"Invalid access!");
185 static std::unique_ptr<AVROperand> CreateToken(
StringRef Str,
SMLoc S) {
186 return make_unique<AVROperand>(Str, S);
189 static std::unique_ptr<AVROperand> CreateReg(
unsigned RegNum,
SMLoc S,
191 return make_unique<AVROperand>(RegNum, S,
E);
194 static std::unique_ptr<AVROperand> CreateImm(
const MCExpr *Val,
SMLoc S,
196 return make_unique<AVROperand>(Val, S,
E);
199 static std::unique_ptr<AVROperand>
201 return make_unique<AVROperand>(RegNum, Val, S,
E);
209 void makeReg(
unsigned RegNo) {
211 RegImm = {RegNo,
nullptr};
214 void makeImm(
MCExpr const *Ex) {
219 void makeMemri(
unsigned RegNo,
MCExpr const *Imm) {
221 RegImm = {RegNo, Imm};
224 SMLoc getStartLoc()
const {
return Start; }
225 SMLoc getEndLoc()
const {
return End; }
230 O <<
"Token: \"" <<
getToken() <<
"\"";
233 O <<
"Register: " <<
getReg();
236 O <<
"Immediate: \"" << *getImm() <<
"\"";
241 O <<
"Memri: \"" <<
getReg() <<
'+' << *getImm() <<
"\"";
261 bool AVRAsmParser::invalidOperand(
SMLoc const &Loc,
264 SMLoc ErrorLoc = Loc;
265 char const *Diag = 0;
267 if (ErrorInfo != ~0U) {
268 if (ErrorInfo >= Operands.
size()) {
269 Diag =
"too few operands for instruction.";
271 AVROperand
const &
Op = (AVROperand
const &)*Operands[ErrorInfo];
274 if (Op.getStartLoc() !=
SMLoc()) {
275 ErrorLoc = Op.getStartLoc();
281 Diag =
"invalid operand for instruction";
284 return Error(ErrorLoc, Diag);
287 bool AVRAsmParser::missingFeature(
llvm::SMLoc const &Loc,
288 uint64_t
const &ErrorInfo) {
289 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
299 bool AVRAsmParser::MatchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
302 bool MatchingInlineAsm) {
304 unsigned MatchResult =
305 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
307 switch (MatchResult) {
308 case Match_Success:
return emit(Inst, Loc, Out);
309 case Match_MissingFeature:
return missingFeature(Loc, ErrorInfo);
310 case Match_InvalidOperand:
return invalidOperand(Loc, Operands, ErrorInfo);
311 case Match_MnemonicFail:
return Error(Loc,
"invalid instruction");
312 default:
return true;
318 int AVRAsmParser::parseRegisterName(
unsigned (*matchFn)(
StringRef)) {
321 int RegNum = matchFn(Name);
327 if (RegNum == AVR::NoRegister) {
328 RegNum = matchFn(Name.
lower());
330 if (RegNum == AVR::NoRegister) {
331 RegNum = matchFn(Name.
upper());
337 int AVRAsmParser::parseRegisterName() {
340 if (RegNum == AVR::NoRegister)
346 int AVRAsmParser::parseRegister() {
347 int RegNum = AVR::NoRegister;
357 RegNum = toDREG(parseRegisterName());
360 RegNum = parseRegisterName();
366 bool AVRAsmParser::tryParseRegisterOperand(
OperandVector &Operands) {
367 int RegNo = parseRegister();
369 if (RegNo == AVR::NoRegister)
379 bool AVRAsmParser::tryParseExpression(
OperandVector &Operands) {
382 if (!tryParseRelocExpression(Operands))
395 if (getParser().parseExpression(Expression))
399 Operands.
push_back(AVROperand::CreateImm(Expression, S, E));
403 bool AVRAsmParser::tryParseRelocExpression(
OperandVector &Operands) {
404 bool isNegated =
false;
413 if (ReadCount == 2) {
448 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
464 MCExpr const *InnerExpression;
465 if (getParser().parseExpression(InnerExpression))
479 isNegated, getContext());
482 Operands.
push_back(AVROperand::CreateImm(Expression, S, E));
490 switch (getLexer().getKind()) {
497 if (!tryParseRegisterOperand(Operands)) {
504 return tryParseExpression(Operands);
509 switch (getLexer().peekTok().getKind()) {
514 if (!tryParseExpression(Operands))
542 RegNo = parseRegister();
544 if (RegNo == AVR::NoRegister)
553 if (getParser().parseExpression(Expression))
559 Operands.
push_back(AVROperand::CreateMemri(RegNo, Expression, S, E));
564 bool AVRAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
567 RegNo = parseRegister();
570 return (RegNo == AVR::NoRegister);
573 void AVRAsmParser::eatComma() {
584 Operands.
push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
588 if (!first) eatComma();
592 auto MatchResult = MatchOperandParserImpl(Operands, Mnemonic);
599 SMLoc Loc = getLexer().getLoc();
602 return Error(Loc,
"failed to parse register and immediate pair");
605 if (parseOperand(Operands)) {
606 SMLoc Loc = getLexer().getLoc();
608 return Error(Loc,
"unexpected token in argument list");
617 if (IDVal.
lower() ==
".long") {
619 }
else if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short") {
621 }
else if (IDVal.
lower() ==
".byte") {
622 parseLiteralValues(1, DirectiveID.
getLoc());
627 bool AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes,
SMLoc L) {
659 auto parseOne = [&]() ->
bool {
666 return (parseMany(parseOne));
673 #define GET_REGISTER_MATCHER 674 #define GET_MATCHER_IMPLEMENTATION 675 #include "AVRGenAsmMatcher.inc" 679 unsigned ExpectedKind) {
680 AVROperand &Op =
static_cast<AVROperand &
>(AsmOp);
681 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
686 if (
MCConstantExpr const *Const = dyn_cast<MCConstantExpr>(Op.getImm())) {
687 int64_t RegNum = Const->getValue();
688 std::ostringstream RegName;
689 RegName <<
"r" << RegNum;
691 if (RegNum != AVR::NoRegister) {
693 if (validateOperandClass(Op, Expected) == Match_Success) {
694 return Match_Success;
704 if (isSubclass(Expected, MCK_DREGS)) {
705 unsigned correspondingDREG = toDREG(Op.getReg());
707 if (correspondingDREG != AVR::NoRegister) {
708 Op.makeReg(correspondingDREG);
709 return validateOperandClass(Op, Expected);
713 return Match_InvalidOperand;
static bool isReg(const MCInst &MI, unsigned OpNo)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
This class represents lattice values for constants.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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.
void push_back(const T &Elt)
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
Target & getTheAVRTarget()
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
VariantKind
Specifies the type of an expression.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static MCOperand createReg(unsigned Reg)
const FeatureBitset & getFeatureBits() const
Generic assembler lexer interface, for use by target specific assembly lexers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
Target independent representation for an assembler token.
Tagged union holding either a T or a Error.
static bool isMem(const MachineInstr &MI, unsigned Op)
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.
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
MCRegisterClass - Base class of TargetRegisterClass.
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
void EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Instances of this class represent a single low-level machine instruction.
Analysis containing CSE Info
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
const char * getPointer() const
Streaming machine code generation interface.
unsigned const MachineRegisterInfo * MRI
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...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Interface to description of machine instruction set.
virtual MCAsmLexer & getLexer()=0
void LLVMInitializeAVRAsmParser()
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
AsmToken::TokenKind getKind() const
Get the kind of current token.
BlockVerifier::State From
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is(TokenKind K) const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Base class for user error types.
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
static SMLoc getFromPointer(const char *Ptr)
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)
LLVM_NODISCARD std::string lower() const
void EmitValueForModiferKind(const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc=SMLoc(), AVRMCExpr::VariantKind ModifierKind=AVRMCExpr::VK_AVR_None)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
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.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
Represents a location in source code.
static MCOperand createImm(int64_t Val)
TokenKind getKind() const