34 #define DEBUG_TYPE "avr-asm-parser" 44 const std::string GENERATE_STUBS =
"gs";
46 #define GET_ASSEMBLER_HEADER 47 #include "AVRGenAsmMatcher.inc" 49 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
52 bool MatchingInlineAsm)
override;
54 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
59 bool ParseDirective(
AsmToken DirectiveID)
override;
64 int parseRegisterName(
unsigned (*matchFn)(
StringRef));
65 int parseRegisterName();
73 unsigned Kind)
override;
75 unsigned toDREG(
unsigned Reg,
unsigned From = AVR::sub_lo) {
76 MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
85 bool parseLiteralValues(
unsigned SizeInBytes,
SMLoc L);
92 MRI = getContext().getRegisterInfo();
94 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
104 enum KindTy { k_Immediate, k_Register, k_Token, k_Memri }
Kind;
108 : Base(), Kind(k_Token), Tok(Tok), Start(S), End(S) {}
109 AVROperand(
unsigned Reg,
SMLoc const &S,
SMLoc const &
E)
110 : Base(), Kind(k_Register), RegImm({
Reg,
nullptr}), Start(S), End(
E) {}
112 : Base(), Kind(k_Immediate), RegImm({0, Imm}), Start(S), End(
E) {}
114 : Base(), Kind(k_Memri), RegImm({
Reg, Imm}), Start(S), End(
E) {}
116 struct RegisterImmediate {
122 RegisterImmediate RegImm;
128 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
129 assert(Kind == k_Register &&
"Unexpected operand kind");
130 assert(N == 1 &&
"Invalid number of operands!");
139 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
145 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
146 assert(Kind == k_Immediate &&
"Unexpected operand kind");
147 assert(N == 1 &&
"Invalid number of operands!");
149 const MCExpr *Expr = getImm();
154 void addMemriOperands(
MCInst &Inst,
unsigned N)
const {
155 assert(Kind == k_Memri &&
"Unexpected operand kind");
156 assert(N == 2 &&
"Invalid number of operands");
159 addExpr(Inst, getImm());
162 void addImmCom8Operands(
MCInst &Inst,
unsigned N)
const {
163 assert(N == 1 &&
"Invalid number of operands!");
170 bool isImmCom8()
const {
171 if (!isImm())
return false;
173 if (!CE)
return false;
178 bool isReg()
const {
return Kind == k_Register; }
179 bool isImm()
const {
return Kind == k_Immediate; }
180 bool isToken()
const {
return Kind == k_Token; }
181 bool isMem()
const {
return Kind == k_Memri; }
182 bool isMemri()
const {
return Kind == k_Memri; }
185 assert(Kind == k_Token &&
"Invalid access!");
190 assert((Kind == k_Register || Kind == k_Memri) &&
"Invalid access!");
195 const MCExpr *getImm()
const {
196 assert((Kind == k_Immediate || Kind == k_Memri) &&
"Invalid access!");
200 static std::unique_ptr<AVROperand> CreateToken(
StringRef Str,
SMLoc S) {
201 return make_unique<AVROperand>(Str, S);
204 static std::unique_ptr<AVROperand> CreateReg(
unsigned RegNum,
SMLoc S,
206 return make_unique<AVROperand>(RegNum, S,
E);
209 static std::unique_ptr<AVROperand> CreateImm(
const MCExpr *Val,
SMLoc S,
211 return make_unique<AVROperand>(Val, S,
E);
214 static std::unique_ptr<AVROperand>
216 return make_unique<AVROperand>(RegNum, Val, S,
E);
224 void makeReg(
unsigned RegNo) {
226 RegImm = {RegNo,
nullptr};
229 void makeImm(
MCExpr const *Ex) {
234 void makeMemri(
unsigned RegNo,
MCExpr const *Imm) {
236 RegImm = {RegNo, Imm};
239 SMLoc getStartLoc()
const {
return Start; }
240 SMLoc getEndLoc()
const {
return End; }
245 O <<
"Token: \"" <<
getToken() <<
"\"";
248 O <<
"Register: " <<
getReg();
251 O <<
"Immediate: \"" << *getImm() <<
"\"";
256 O <<
"Memri: \"" <<
getReg() <<
'+' << *getImm() <<
"\"";
276 bool AVRAsmParser::invalidOperand(
SMLoc const &Loc,
279 SMLoc ErrorLoc = Loc;
280 char const *Diag = 0;
282 if (ErrorInfo != ~0U) {
283 if (ErrorInfo >= Operands.
size()) {
284 Diag =
"too few operands for instruction.";
286 AVROperand
const &
Op = (AVROperand
const &)*Operands[ErrorInfo];
289 if (Op.getStartLoc() !=
SMLoc()) {
290 ErrorLoc = Op.getStartLoc();
296 Diag =
"invalid operand for instruction";
299 return Error(ErrorLoc, Diag);
302 bool AVRAsmParser::missingFeature(
llvm::SMLoc const &Loc,
303 uint64_t
const &ErrorInfo) {
304 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
314 bool AVRAsmParser::MatchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
317 bool MatchingInlineAsm) {
319 unsigned MatchResult =
320 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
322 switch (MatchResult) {
323 case Match_Success:
return emit(Inst, Loc, Out);
324 case Match_MissingFeature:
return missingFeature(Loc, ErrorInfo);
325 case Match_InvalidOperand:
return invalidOperand(Loc, Operands, ErrorInfo);
326 case Match_MnemonicFail:
return Error(Loc,
"invalid instruction");
327 default:
return true;
333 int AVRAsmParser::parseRegisterName(
unsigned (*matchFn)(
StringRef)) {
336 int RegNum = matchFn(Name);
342 if (RegNum == AVR::NoRegister) {
343 RegNum = matchFn(Name.
lower());
345 if (RegNum == AVR::NoRegister) {
346 RegNum = matchFn(Name.
upper());
352 int AVRAsmParser::parseRegisterName() {
355 if (RegNum == AVR::NoRegister)
361 int AVRAsmParser::parseRegister() {
362 int RegNum = AVR::NoRegister;
372 RegNum = toDREG(parseRegisterName());
375 RegNum = parseRegisterName();
381 bool AVRAsmParser::tryParseRegisterOperand(
OperandVector &Operands) {
382 int RegNo = parseRegister();
384 if (RegNo == AVR::NoRegister)
394 bool AVRAsmParser::tryParseExpression(
OperandVector &Operands) {
397 if (!tryParseRelocExpression(Operands))
410 if (getParser().parseExpression(Expression))
414 Operands.
push_back(AVROperand::CreateImm(Expression, S, E));
418 bool AVRAsmParser::tryParseRelocExpression(
OperandVector &Operands) {
419 bool isNegated =
false;
428 if (ReadCount == 2) {
463 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
479 MCExpr const *InnerExpression;
480 if (getParser().parseExpression(InnerExpression))
494 isNegated, getContext());
497 Operands.
push_back(AVROperand::CreateImm(Expression, S, E));
505 switch (getLexer().getKind()) {
512 if (!tryParseRegisterOperand(Operands)) {
519 return tryParseExpression(Operands);
524 switch (getLexer().peekTok().getKind()) {
529 if (!tryParseExpression(Operands))
557 RegNo = parseRegister();
559 if (RegNo == AVR::NoRegister)
568 if (getParser().parseExpression(Expression))
574 Operands.
push_back(AVROperand::CreateMemri(RegNo, Expression, S, E));
579 bool AVRAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
582 RegNo = parseRegister();
585 return (RegNo == AVR::NoRegister);
588 void AVRAsmParser::eatComma() {
599 Operands.
push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
603 if (!first) eatComma();
607 auto MatchResult = MatchOperandParserImpl(Operands, Mnemonic);
614 SMLoc Loc = getLexer().getLoc();
617 return Error(Loc,
"failed to parse register and immediate pair");
620 if (parseOperand(Operands)) {
621 SMLoc Loc = getLexer().getLoc();
623 return Error(Loc,
"unexpected token in argument list");
632 if (IDVal.
lower() ==
".long") {
634 }
else if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short") {
636 }
else if (IDVal.
lower() ==
".byte") {
637 parseLiteralValues(1, DirectiveID.
getLoc());
642 bool AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes,
SMLoc L) {
674 auto parseOne = [&]() ->
bool {
681 return (parseMany(parseOne));
688 #define GET_REGISTER_MATCHER 689 #define GET_MATCHER_IMPLEMENTATION 690 #include "AVRGenAsmMatcher.inc" 694 unsigned ExpectedKind) {
695 AVROperand &Op =
static_cast<AVROperand &
>(AsmOp);
696 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
701 if (
MCConstantExpr const *Const = dyn_cast<MCConstantExpr>(Op.getImm())) {
702 int64_t RegNum = Const->getValue();
703 std::ostringstream RegName;
704 RegName <<
"r" << RegNum;
706 if (RegNum != AVR::NoRegister) {
708 if (validateOperandClass(Op, Expected) == Match_Success) {
709 return Match_Success;
719 if (isSubclass(Expected, MCK_DREGS)) {
720 unsigned correspondingDREG = toDREG(Op.getReg());
722 if (correspondingDREG != AVR::NoRegister) {
723 Op.makeReg(correspondingDREG);
724 return validateOperandClass(Op, Expected);
728 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.
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
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)
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.
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.
constexpr bool isUInt< 8 >(uint64_t x)
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.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
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.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
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