Index: lib/Target/AVR/AsmParser/AVRAsmParser.cpp =================================================================== --- lib/Target/AVR/AsmParser/AVRAsmParser.cpp +++ lib/Target/AVR/AsmParser/AVRAsmParser.cpp @@ -80,6 +80,8 @@ uint64_t const &ErrorInfo); bool missingFeature(SMLoc const &Loc, uint64_t const &ErrorInfo); + bool parseLiteralValues(unsigned Size, SMLoc L); + public: AVRAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) @@ -432,6 +434,11 @@ if (ModifierKind != AVRMCExpr::VK_AVR_None) { Parser.Lex(); Parser.Lex(); // Eat modifier name and parenthesis + // FIXME: Not support gs(foo) so just eat gs. + if (Parser.getTok().getString() == "gs" && + Parser.getTok().getKind() == AsmToken::Identifier) { + Parser.Lex(); + } } else { return Error(Parser.getTok().getLoc(), "unknown modifier"); } @@ -580,7 +587,33 @@ return false; } -bool AVRAsmParser::ParseDirective(llvm::AsmToken DirectiveID) { return true; } +bool AVRAsmParser::ParseDirective(llvm::AsmToken DirectiveID) { + StringRef IDVal = DirectiveID.getIdentifier(); + if (IDVal == ".word") + parseLiteralValues(4, DirectiveID.getLoc()); + else if (IDVal == ".short") + parseLiteralValues(2, DirectiveID.getLoc()); + else if (IDVal == ".byte") + parseLiteralValues(1, DirectiveID.getLoc()); + return true; +} + +bool AVRAsmParser::parseLiteralValues(unsigned Size, SMLoc L) { + MCAsmParser &Parser = getParser(); + if (Parser.getTok().getKind() == AsmToken::Identifier && + Parser.getLexer().peekTok().getKind() == AsmToken::LParen) { + const MCExpr *Value; + return Parser.parseExpression(Value); + } + auto parseOne = [&]() -> bool { + const MCExpr *Value; + if (Parser.parseExpression(Value)) + return true; + Parser.getStreamer().EmitValue(Value, Size, L); + return false; + }; + return (parseMany(parseOne)); +} extern "C" void LLVMInitializeAVRAsmParser() { RegisterMCAsmParser X(getTheAVRTarget()); Index: test/MC/AVR/relocations.s =================================================================== --- test/MC/AVR/relocations.s +++ test/MC/AVR/relocations.s @@ -73,3 +73,24 @@ ; CHECK-NEXT: R_AVR_HH8_LDI_PM_NEG ldi r25, -pm_hh8(foo) + +; CHECK-NEXT: R_AVR_LO8_LDI_GS +ldi r17, lo8(gs(foo)) + +; CHECK-NEXT: R_AVR_HI8_LDI_GS +ldi r18, hi8(gs(foo)) + +; CHECK-NEXT: R_AVR_16_PM +.short foo + +; CHECK-NEXT: R_AVR_8 +.byte foo + +; CHECK-NEXT: R_AVR_8_LO8 +.byte lo8(foo) + +; CHECK-NEXT: R_AVR_8_HI8 +.byte hi8(foo) + +; CHECK-NEXT: R_AVR_8_HLO8 +.byte hlo8(foo)