diff options
author | Michael Zuckerman <Michael.zuckerman@intel.com> | 2017-05-01 13:20:12 +0000 |
---|---|---|
committer | Michael Zuckerman <Michael.zuckerman@intel.com> | 2017-05-01 13:20:12 +0000 |
commit | 56704618aa037fbaaa0e141f86b1c78be45569d4 (patch) | |
tree | 49e7c2d494c8f0964bf18c74eb3d29c1327b64da /llvm/lib | |
parent | 6c60ed5a45937d5644bafb2fa7272994c337e8d7 (diff) | |
download | bcm5719-llvm-56704618aa037fbaaa0e141f86b1c78be45569d4.tar.gz bcm5719-llvm-56704618aa037fbaaa0e141f86b1c78be45569d4.zip |
[LLVM][inline-asm] Altmacro absolute expression '%' feature
In this patch, I introduce a new alt macro feature.
This feature adds meaning for the % when using it as a prefix to the calling macro arguments.
In the altmacro mode, the percent sign '%' before an absolute expression convert the expression first to a string.
As described in the https://sourceware.org/binutils/docs-2.27/as/Altmacro.html
"Expression results as strings
You can write `%expr' to evaluate the expression expr and use the result as a string."
expression assumptions:
1. '%' can only evaluate an absolute expression.
2. Altmacro '%' must be the first character of the evaluated expression.
3. If no '%' is located before the expression, a regular module operation is expected.
4. The result of Absolute Expressions can be only integer.
Differential Revision: https://reviews.llvm.org/D32526
llvm-svn: 301797
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 56 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/MCAsmLexer.cpp | 2 |
2 files changed, 51 insertions, 7 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 2fa9c03b608..f36a21bf112 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -412,7 +412,7 @@ private: DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE, DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED, DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE, - DK_MACROS_ON, DK_MACROS_OFF, + DK_MACROS_ON, DK_MACROS_OFF, DK_ALTMACRO, DK_NOALTMACRO, DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM, DK_SLEB128, DK_ULEB128, DK_ERR, DK_ERROR, DK_WARNING, @@ -484,7 +484,8 @@ private: bool parseDirectiveEndMacro(StringRef Directive); bool parseDirectiveMacro(SMLoc DirectiveLoc); bool parseDirectiveMacrosOnOff(StringRef Directive); - + // alternate macro mode directives + bool parseDirectiveAltmacro(StringRef Directive); // ".bundle_align_mode" bool parseDirectiveBundleAlignMode(); // ".bundle_lock" @@ -1922,6 +1923,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, return parseDirectiveMacrosOnOff(IDVal); case DK_MACRO: return parseDirectiveMacro(IDLoc); + case DK_ALTMACRO: + case DK_NOALTMACRO: + return parseDirectiveAltmacro(IDVal); case DK_EXITM: return parseDirectiveExitMacro(IDVal); case DK_ENDM: @@ -2270,9 +2274,18 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, } else { bool VarargParameter = HasVararg && Index == (NParameters - 1); for (const AsmToken &Token : A[Index]) + // For altmacro mode, you can write '%expr'. + // The prefix '%' evaluates the expression 'expr' + // and uses the result as a string (e.g. replace %(1+2) with the string "3"). + // Here, we identify the integer token which is the result of the + // absolute expression evaluation and replace it with its string representation. + if ((Lexer.IsaAltMacroMode()) && + (*(Token.getString().begin()) == '%') && Token.is(AsmToken::Integer)) + // Emit an integer value to the buffer. + OS << Token.getIntVal(); // We expect no quotes around the string's contents when // parsing for varargs. - if (Token.getKind() != AsmToken::String || VarargParameter) + else if (Token.isNot(AsmToken::String) || VarargParameter) OS << Token.getString(); else OS << Token.getStringContents(); @@ -2443,13 +2456,29 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, NamedParametersFound = true; } + bool Vararg = HasVararg && Parameter == (NParameters - 1); if (NamedParametersFound && FA.Name.empty()) return Error(IDLoc, "cannot mix positional and keyword arguments"); - bool Vararg = HasVararg && Parameter == (NParameters - 1); - if (parseMacroArgument(FA.Value, Vararg)) - return true; + if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Percent)) { + SMLoc StrLoc = Lexer.getLoc(); + SMLoc EndLoc; + const MCExpr *AbsoluteExp; + int64_t Value; + /// Eat '%' + Lex(); + if (parseExpression(AbsoluteExp, EndLoc)) + return false; + if (!AbsoluteExp->evaluateAsAbsolute(Value)) + return Error(StrLoc, "expected absolute expression"); + const char *StrChar = StrLoc.getPointer(); + const char *EndChar = EndLoc.getPointer(); + AsmToken newToken(AsmToken::Integer, StringRef(StrChar , EndChar - StrChar), Value); + FA.Value.push_back(newToken); + } + else if(parseMacroArgument(FA.Value, Vararg)) + return true; unsigned PI = Parameter; if (!FA.Name.empty()) { @@ -3841,6 +3870,19 @@ bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) { return false; } +/// parseDirectiveAltmacro +/// ::= .altmacro +/// ::= .noaltmacro +bool AsmParser::parseDirectiveAltmacro(StringRef Directive) { + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '" + Directive + "' directive"); + if (Directive == ".altmacro") + getLexer().SetAltMacroMode(true); + else + getLexer().SetAltMacroMode(false); + return false; +} + /// parseDirectiveMacrosOnOff /// ::= .macros_on /// ::= .macros_off @@ -4938,6 +4980,8 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".err"] = DK_ERR; DirectiveKindMap[".error"] = DK_ERROR; DirectiveKindMap[".warning"] = DK_WARNING; + DirectiveKindMap[".altmacro"] = DK_ALTMACRO; + DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO; DirectiveKindMap[".reloc"] = DK_RELOC; DirectiveKindMap[".dc"] = DK_DC; DirectiveKindMap[".dc.a"] = DK_DC_A; diff --git a/llvm/lib/MC/MCParser/MCAsmLexer.cpp b/llvm/lib/MC/MCParser/MCAsmLexer.cpp index f8fe78aece0..1d12ab85828 100644 --- a/llvm/lib/MC/MCParser/MCAsmLexer.cpp +++ b/llvm/lib/MC/MCParser/MCAsmLexer.cpp @@ -13,7 +13,7 @@ using namespace llvm; -MCAsmLexer::MCAsmLexer() { +MCAsmLexer::MCAsmLexer() : AltMacroMode(false) { CurTok.emplace_back(AsmToken::Space, StringRef()); } |