diff options
Diffstat (limited to 'contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp')
| -rw-r--r-- | contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp index 5004736365c7..b527ad3e0b14 100644 --- a/contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp +++ b/contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp @@ -9,6 +9,7 @@ #include "AVR.h" #include "AVRRegisterInfo.h" +#include "MCTargetDesc/AVRMCELFStreamer.h" #include "MCTargetDesc/AVRMCExpr.h" #include "MCTargetDesc/AVRMCTargetDesc.h" @@ -40,6 +41,7 @@ class AVRAsmParser : public MCTargetAsmParser { const MCSubtargetInfo &STI; MCAsmParser &Parser; const MCRegisterInfo *MRI; + const std::string GENERATE_STUBS = "gs"; #define GET_ASSEMBLER_HEADER #include "AVRGenAsmMatcher.inc" @@ -54,7 +56,7 @@ class AVRAsmParser : public MCTargetAsmParser { bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) override; - bool ParseDirective(AsmToken directiveID) override; + bool ParseDirective(AsmToken DirectiveID) override; OperandMatchResultTy parseMemriOperand(OperandVector &Operands); @@ -80,10 +82,12 @@ class AVRAsmParser : public MCTargetAsmParser { uint64_t const &ErrorInfo); bool missingFeature(SMLoc const &Loc, uint64_t const &ErrorInfo); + bool parseLiteralValues(unsigned SizeInBytes, SMLoc L); + public: AVRAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(Options, STI), STI(STI), Parser(Parser) { + : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) { MCAsmParserExtension::Initialize(Parser); MRI = getContext().getRegisterInfo(); @@ -404,11 +408,14 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) { size_t ReadCount = Parser.getLexer().peekTokens(tokens); if (ReadCount == 2) { - if (tokens[0].getKind() == AsmToken::Identifier && - tokens[1].getKind() == AsmToken::LParen) { + if ((tokens[0].getKind() == AsmToken::Identifier && + tokens[1].getKind() == AsmToken::LParen) || + (tokens[0].getKind() == AsmToken::LParen && + tokens[1].getKind() == AsmToken::Minus)) { AsmToken::TokenKind CurTok = Parser.getLexer().getKind(); - if (CurTok == AsmToken::Minus) { + if (CurTok == AsmToken::Minus || + tokens[1].getKind() == AsmToken::Minus) { isNegated = true; } else { assert(CurTok == AsmToken::Plus); @@ -416,7 +423,8 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) { } // Eat the sign - Parser.Lex(); + if (CurTok == AsmToken::Minus || CurTok == AsmToken::Plus) + Parser.Lex(); } } @@ -432,14 +440,34 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) { if (ModifierKind != AVRMCExpr::VK_AVR_None) { Parser.Lex(); Parser.Lex(); // Eat modifier name and parenthesis + if (Parser.getTok().getString() == GENERATE_STUBS && + Parser.getTok().getKind() == AsmToken::Identifier) { + std::string GSModName = ModifierName.str() + "_" + GENERATE_STUBS; + ModifierKind = AVRMCExpr::getKindByName(GSModName.c_str()); + if (ModifierKind != AVRMCExpr::VK_AVR_None) + Parser.Lex(); // Eat gs modifier name + } } else { return Error(Parser.getTok().getLoc(), "unknown modifier"); } + if (tokens[1].getKind() == AsmToken::Minus || + tokens[1].getKind() == AsmToken::Plus) { + Parser.Lex(); + assert(Parser.getTok().getKind() == AsmToken::LParen); + Parser.Lex(); // Eat the sign and parenthesis + } + MCExpr const *InnerExpression; if (getParser().parseExpression(InnerExpression)) return true; + if (tokens[1].getKind() == AsmToken::Minus || + tokens[1].getKind() == AsmToken::Plus) { + assert(Parser.getTok().getKind() == AsmToken::RParen); + Parser.Lex(); // Eat closing parenthesis + } + // If we have a modifier wrap the inner expression assert(Parser.getTok().getKind() == AsmToken::RParen); Parser.Lex(); // Eat closing parenthesis @@ -580,7 +608,59 @@ bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info, return false; } -bool AVRAsmParser::ParseDirective(llvm::AsmToken DirectiveID) { return true; } +bool AVRAsmParser::ParseDirective(llvm::AsmToken DirectiveID) { + StringRef IDVal = DirectiveID.getIdentifier(); + if (IDVal.lower() == ".long") { + parseLiteralValues(SIZE_LONG, DirectiveID.getLoc()); + } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") { + parseLiteralValues(SIZE_WORD, DirectiveID.getLoc()); + } else if (IDVal.lower() == ".byte") { + parseLiteralValues(1, DirectiveID.getLoc()); + } + return true; +} + +bool AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) { + MCAsmParser &Parser = getParser(); + AVRMCELFStreamer &AVRStreamer = + static_cast<AVRMCELFStreamer &>(Parser.getStreamer()); + AsmToken Tokens[2]; + size_t ReadCount = Parser.getLexer().peekTokens(Tokens); + if (ReadCount == 2 && Parser.getTok().getKind() == AsmToken::Identifier && + Tokens[0].getKind() == AsmToken::Minus && + Tokens[1].getKind() == AsmToken::Identifier) { + MCSymbol *Symbol = getContext().getOrCreateSymbol(".text"); + AVRStreamer.EmitValueForModiferKind(Symbol, SizeInBytes, L, + AVRMCExpr::VK_AVR_None); + return false; + } + + if (Parser.getTok().getKind() == AsmToken::Identifier && + Parser.getLexer().peekTok().getKind() == AsmToken::LParen) { + StringRef ModifierName = Parser.getTok().getString(); + AVRMCExpr::VariantKind ModifierKind = + AVRMCExpr::getKindByName(ModifierName.str().c_str()); + if (ModifierKind != AVRMCExpr::VK_AVR_None) { + Parser.Lex(); + Parser.Lex(); // Eat the modifier and parenthesis + } else { + return Error(Parser.getTok().getLoc(), "unknown modifier"); + } + MCSymbol *Symbol = + getContext().getOrCreateSymbol(Parser.getTok().getString()); + AVRStreamer.EmitValueForModiferKind(Symbol, SizeInBytes, L, ModifierKind); + return false; + } + + auto parseOne = [&]() -> bool { + const MCExpr *Value; + if (Parser.parseExpression(Value)) + return true; + Parser.getStreamer().EmitValue(Value, SizeInBytes, L); + return false; + }; + return (parseMany(parseOne)); +} extern "C" void LLVMInitializeAVRAsmParser() { RegisterMCAsmParser<AVRAsmParser> X(getTheAVRTarget()); |
