Go to the documentation of this file.
34 #define DEBUG_TYPE "avr-asm-parser"
44 const std::string GENERATE_STUBS =
"gs";
46 enum AVRMatchResultTy {
47 Match_InvalidRegisterOnTiny = FIRST_TARGET_MATCH_RESULT_TY + 1,
50 #define GET_ASSEMBLER_HEADER
51 #include "AVRGenAsmMatcher.inc"
53 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
56 bool MatchingInlineAsm)
override;
58 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
60 SMLoc &EndLoc)
override;
65 bool ParseDirective(
AsmToken DirectiveID)
override;
70 int parseRegisterName(
unsigned (*matchFn)(
StringRef));
71 int parseRegisterName();
72 int parseRegister(
bool RestoreOnFailure =
false);
79 unsigned Kind)
override;
81 unsigned toDREG(
unsigned Reg,
unsigned From = AVR::sub_lo) {
82 MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
83 return MRI->getMatchingSuperReg(
Reg,
From, Class);
91 bool parseLiteralValues(
unsigned SizeInBytes,
SMLoc L);
98 MRI = getContext().getRegisterInfo();
100 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
110 enum KindTy { k_Immediate, k_Register, k_Token, k_Memri }
Kind;
114 :
Kind(k_Token), Tok(Tok), Start(
S), End(
S) {}
122 struct RegisterImmediate {
134 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
135 assert(
Kind == k_Register &&
"Unexpected operand kind");
136 assert(
N == 1 &&
"Invalid number of operands!");
145 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
151 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
152 assert(
Kind == k_Immediate &&
"Unexpected operand kind");
153 assert(
N == 1 &&
"Invalid number of operands!");
155 const MCExpr *Expr = getImm();
160 void addMemriOperands(
MCInst &Inst,
unsigned N)
const {
161 assert(
Kind == k_Memri &&
"Unexpected operand kind");
162 assert(
N == 2 &&
"Invalid number of operands");
165 addExpr(Inst, getImm());
168 void addImmCom8Operands(
MCInst &Inst,
unsigned N)
const {
169 assert(
N == 1 &&
"Invalid number of operands!");
172 const auto *
CE = cast<MCConstantExpr>(getImm());
176 bool isImmCom8()
const {
179 const auto *
CE = dyn_cast<MCConstantExpr>(getImm());
182 int64_t
Value =
CE->getValue();
186 bool isReg()
const override {
return Kind == k_Register; }
187 bool isImm()
const override {
return Kind == k_Immediate; }
188 bool isToken()
const override {
return Kind == k_Token; }
189 bool isMem()
const override {
return Kind == k_Memri; }
190 bool isMemri()
const {
return Kind == k_Memri; }
197 unsigned getReg()
const override {
198 assert((
Kind == k_Register ||
Kind == k_Memri) &&
"Invalid access!");
203 const MCExpr *getImm()
const {
204 assert((
Kind == k_Immediate ||
Kind == k_Memri) &&
"Invalid access!");
208 static std::unique_ptr<AVROperand> CreateToken(
StringRef Str,
SMLoc S) {
209 return std::make_unique<AVROperand>(Str,
S);
212 static std::unique_ptr<AVROperand> CreateReg(
unsigned RegNum,
SMLoc S,
214 return std::make_unique<AVROperand>(RegNum,
S,
E);
217 static std::unique_ptr<AVROperand> CreateImm(
const MCExpr *Val,
SMLoc S,
219 return std::make_unique<AVROperand>(Val,
S,
E);
222 static std::unique_ptr<AVROperand>
224 return std::make_unique<AVROperand>(RegNum, Val,
S,
E);
232 void makeReg(
unsigned RegNo) {
234 RegImm = {RegNo,
nullptr};
237 void makeImm(
MCExpr const *Ex) {
242 void makeMemri(
unsigned RegNo,
MCExpr const *
Imm) {
247 SMLoc getStartLoc()
const override {
return Start; }
248 SMLoc getEndLoc()
const override {
return End; }
253 O <<
"Token: \"" << getToken() <<
"\"";
259 O <<
"Immediate: \"" << *getImm() <<
"\"";
264 O <<
"Memri: \"" <<
getReg() <<
'+' << *getImm() <<
"\"";
284 bool AVRAsmParser::invalidOperand(
SMLoc const &Loc,
287 SMLoc ErrorLoc = Loc;
288 char const *Diag =
nullptr;
292 Diag =
"too few operands for instruction.";
297 if (
Op.getStartLoc() !=
SMLoc()) {
298 ErrorLoc =
Op.getStartLoc();
304 Diag =
"invalid operand for instruction";
307 return Error(ErrorLoc, Diag);
310 bool AVRAsmParser::missingFeature(
llvm::SMLoc const &Loc,
312 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
322 bool AVRAsmParser::MatchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
325 bool MatchingInlineAsm) {
327 unsigned MatchResult =
330 switch (MatchResult) {
332 return emit(Inst, Loc, Out);
333 case Match_MissingFeature:
335 case Match_InvalidOperand:
337 case Match_MnemonicFail:
338 return Error(Loc,
"invalid instruction");
339 case Match_InvalidRegisterOnTiny:
340 return Error(Loc,
"invalid register on avrtiny");
348 int AVRAsmParser::parseRegisterName(
unsigned (*matchFn)(
StringRef)) {
351 int RegNum = matchFn(
Name);
357 if (RegNum == AVR::NoRegister) {
358 RegNum = matchFn(
Name.lower());
360 if (RegNum == AVR::NoRegister) {
361 RegNum = matchFn(
Name.upper());
367 int AVRAsmParser::parseRegisterName() {
370 if (RegNum == AVR::NoRegister)
376 int AVRAsmParser::parseRegister(
bool RestoreOnFailure) {
377 int RegNum = AVR::NoRegister;
389 RegNum = toDREG(parseRegisterName());
391 if (RegNum == AVR::NoRegister && RestoreOnFailure) {
396 RegNum = parseRegisterName();
403 int RegNo = parseRegister();
405 if (RegNo == AVR::NoRegister)
409 if (AVR::R0 <= RegNo && RegNo <= AVR::R15 &&
414 Operands.push_back(AVROperand::CreateReg(RegNo,
T.getLoc(),
T.getEndLoc()));
423 if (!tryParseRelocExpression(
Operands))
445 bool isNegated =
false;
454 if (ReadCount == 2) {
488 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
504 MCExpr const *InnerExpression;
505 if (getParser().parseExpression(InnerExpression))
530 switch (getLexer().getKind()) {
537 if (!tryParseRegisterOperand(
Operands)) {
544 return tryParseExpression(
Operands);
549 switch (getLexer().peekTok().getKind()) {
581 RegNo = parseRegister();
583 if (RegNo == AVR::NoRegister)
603 bool AVRAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
606 RegNo = parseRegister(
false);
609 return (RegNo == AVR::NoRegister);
616 RegNo = parseRegister(
true);
619 if (RegNo == AVR::NoRegister)
624 void AVRAsmParser::eatComma() {
635 Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
644 auto MatchResult = MatchOperandParserImpl(
Operands, Mnemonic);
651 SMLoc Loc = getLexer().getLoc();
654 return Error(Loc,
"failed to parse register and immediate pair");
658 SMLoc Loc = getLexer().getLoc();
660 return Error(Loc,
"unexpected token in argument list");
669 if (IDVal.
lower() ==
".long") {
671 }
else if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short") {
673 }
else if (IDVal.
lower() ==
".byte") {
674 parseLiteralValues(1, DirectiveID.
getLoc());
679 bool AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes,
SMLoc L) {
711 auto parseOne = [&]() ->
bool {
718 return (parseMany(parseOne));
725 #define GET_REGISTER_MATCHER
726 #define GET_MATCHER_IMPLEMENTATION
727 #include "AVRGenAsmMatcher.inc"
731 unsigned ExpectedKind) {
732 AVROperand &
Op =
static_cast<AVROperand &
>(AsmOp);
733 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
739 int64_t RegNum = Const->getValue();
742 if (0 <= RegNum && RegNum <= 15 &&
744 return Match_InvalidRegisterOnTiny;
749 if (RegNum != AVR::NoRegister) {
751 if (validateOperandClass(
Op,
Expected) == Match_Success) {
752 return Match_Success;
762 if (isSubclass(
Expected, MCK_DREGS)) {
763 unsigned correspondingDREG = toDREG(
Op.getReg());
765 if (correspondingDREG != AVR::NoRegister) {
766 Op.makeReg(correspondingDREG);
771 return Match_InvalidOperand;
Generic assembler parser interface, for use by target specific assembly parsers.
should just be implemented with a CLZ instruction Since there are other e that share this it would be best to implement this in a target independent as zero is the default value for the binary encoder e add r0 add r5 Register operands should be distinct That is
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
This is an optimization pass for GlobalISel generic memory operations.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool is(TokenKind K) const
static VariantKind getKindByName(StringRef Name)
static MCOperand createExpr(const MCExpr *Val)
Generic assembler lexer interface, for use by target specific assembly lexers.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
static MCOperand createImm(int64_t Val)
Reg
All possible values of the reg field in the ModR/M byte.
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Tagged union holding either a T or a Error.
Instances of this class represent a single low-level machine instruction.
Target independent representation for an assembler token.
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
MCRegisterClass - Base class of TargetRegisterClass.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
Streaming machine code generation interface.
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmParser()
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Represents a location in source code.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool hasFeature(unsigned Feature) const
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
void emitValueForModiferKind(const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc=SMLoc(), AVRMCExpr::VariantKind ModifierKind=AVRMCExpr::VK_AVR_None)
Target & getTheAVRTarget()
const FeatureBitset & getFeatureBits() const
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
This class implements an extremely fast bulk output stream that can only output to a stream.
TokenKind getKind() const
Analysis containing CSE Info
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
void addOperand(const MCOperand Op)
mir Rename Register Operands
static const AVRMCExpr * create(VariantKind Kind, const MCExpr *Expr, bool isNegated, MCContext &Ctx)
Creates an AVR machine code expression.
#define LLVM_EXTERNAL_VISIBILITY
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
std::string lower() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
constexpr bool isUInt< 8 >(uint64_t x)
@ CE
Windows NT (Windows on ARM)
Base class for user error types.
static bool isReg(const MCInst &MI, unsigned OpNo)
Class representing an expression and its matching format.
StringRef - Represent a constant reference to a string, i.e.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
static MCOperand createReg(unsigned Reg)
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
unsigned const MachineRegisterInfo * MRI
AsmToken::TokenKind getKind() const
Get the kind of current token.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
Interface to description of machine instruction set.
const char * getPointer() const
Lightweight error class with error context and mandatory checking.
VariantKind
Specifies the type of an expression.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
virtual MCAsmLexer & getLexer()=0
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
static bool isMem(const MachineInstr &MI, unsigned Op)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static SMLoc getFromPointer(const char *Ptr)
std::string str() const
str - Get the contents as an std::string.
BlockVerifier::State From
Generic base class for all target subtargets.
LLVM Value Representation.
Base class for the full range of assembler expressions which are needed for parsing.