[llvm] r301797 - [LLVM][inline-asm] Altmacro absolute expression '%' feature
Michael Zuckerman via llvm-commits
llvm-commits at lists.llvm.org
Mon May 1 06:20:13 PDT 2017
Author: mzuckerm
Date: Mon May 1 08:20:12 2017
New Revision: 301797
URL: http://llvm.org/viewvc/llvm-project?rev=301797&view=rev
Log:
[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
Added:
llvm/trunk/test/MC/AsmParser/altmacro_expression.s
llvm/trunk/test/MC/AsmParser/negativ_altmacro_expression.s
Modified:
llvm/trunk/include/llvm/MC/MCParser/MCAsmLexer.h
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
llvm/trunk/lib/MC/MCParser/MCAsmLexer.cpp
Modified: llvm/trunk/include/llvm/MC/MCParser/MCAsmLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCParser/MCAsmLexer.h?rev=301797&r1=301796&r2=301797&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCParser/MCAsmLexer.h (original)
+++ llvm/trunk/include/llvm/MC/MCParser/MCAsmLexer.h Mon May 1 08:20:12 2017
@@ -161,6 +161,7 @@ protected: // Can only create subclasses
bool IsAtStartOfStatement = true;
AsmCommentConsumer *CommentConsumer = nullptr;
+ bool AltMacroMode;
MCAsmLexer();
virtual AsmToken LexToken() = 0;
@@ -175,6 +176,14 @@ public:
MCAsmLexer &operator=(const MCAsmLexer &) = delete;
virtual ~MCAsmLexer();
+ bool IsaAltMacroMode() {
+ return AltMacroMode;
+ }
+
+ void SetAltMacroMode(bool AltMacroSet) {
+ AltMacroMode = AltMacroSet;
+ }
+
/// Consume the next token from the input stream and return it.
///
/// The lexer will continuosly return the end-of-file token once the end of
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=301797&r1=301796&r2=301797&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Mon May 1 08:20:12 2017
@@ -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(ParseStat
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_
} 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(cons
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::parseDirectiveCFIUndefin
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::initializeDirectiveKindM
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;
Modified: llvm/trunk/lib/MC/MCParser/MCAsmLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/MCAsmLexer.cpp?rev=301797&r1=301796&r2=301797&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/MCAsmLexer.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/MCAsmLexer.cpp Mon May 1 08:20:12 2017
@@ -13,7 +13,7 @@
using namespace llvm;
-MCAsmLexer::MCAsmLexer() {
+MCAsmLexer::MCAsmLexer() : AltMacroMode(false) {
CurTok.emplace_back(AsmToken::Space, StringRef());
}
Added: llvm/trunk/test/MC/AsmParser/altmacro_expression.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/altmacro_expression.s?rev=301797&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/altmacro_expression.s (added)
+++ llvm/trunk/test/MC/AsmParser/altmacro_expression.s Mon May 1 08:20:12 2017
@@ -0,0 +1,65 @@
+# RUN: llvm-mc %s| FileCheck %s
+
+# Checking that the '%' was evaluated as a string first
+# In a fail scenario: The asmprint will print: addl $%(1+4), %eax
+
+# CHECK: addl $5, %eax
+.altmacro
+.macro percent_expr arg
+ addl $\arg, %eax
+.endm
+
+percent_expr %(1+4)
+
+
+# Checking that the second '%' acts as modulo operator
+# The altmacro percent '%' must be located before the first argument
+# If a percent is located in the middle of the estimated argument without any
+# '%' in the beginning , error will be generated.
+# The second percent '%' after the first altmacro percent '%' is a regular operator.
+
+# CHECK: addl $1, %eax
+.macro inner_percent arg
+ addl $\arg, %eax
+.endm
+
+inner_percent %(1%4)
+
+
+# Checking for nested macro
+# The first argument use is for the calling function and the second use is for the evaluation.
+
+# CHECK: addl $1, %eax
+.macro macro_call_0 number
+ addl $\number, %eax
+.endm
+
+.macro macro_call_1 number
+ macro_call_\number %(\number + 1)
+.endm
+
+macro_call_1 %(1-1)
+
+
+# Checking the ability to pass a number of arguments.
+# The arguments can be separated by ',' or not.
+
+# CHECK: label013:
+# CHECK: addl $0, %eax
+# CHECK: addl $1, %eax
+# CHECK: addl $3, %eax
+
+# CHECK: label014:
+# CHECK: addl $0, %eax
+# CHECK: addl $1, %eax
+# CHECK: addl $4, %eax
+
+.macro multi_args_macro arg1 arg2 arg3
+ label\arg1\arg2\arg3:
+ addl $\arg1, %eax
+ addl $\arg2, %eax
+ addl $\arg3, %eax
+.endm
+
+multi_args_macro %(1+4-5) 1 %2+1
+multi_args_macro %(1+4-5),1,%4%10
Added: llvm/trunk/test/MC/AsmParser/negativ_altmacro_expression.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/negativ_altmacro_expression.s?rev=301797&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/negativ_altmacro_expression.s (added)
+++ llvm/trunk/test/MC/AsmParser/negativ_altmacro_expression.s Mon May 1 08:20:12 2017
@@ -0,0 +1,34 @@
+# RUN: not llvm-mc %s 2>&1 | FileCheck %s
+
+# This test is a negative test for the altmacro expression.
+# In this test we check the '.noaltmacro' directive.
+# We expect that '.altmacro' and '.noaltmacro' will act as a switch on/off directives to the alternate macro mode.
+# .noaltmacro returns the format into a regular macro handling.
+# The defult mode is ".noaltmacro" as first test checks.
+
+# CHECK: error: unknown token in expression
+# CHECK-NEXT: addl $%(1%4), %eax
+.macro inner_percent arg
+ addl $\arg, %eax
+.endm
+
+inner_percent %(1%4)
+
+.altmacro
+.noaltmacro
+
+# CHECK: multi_args_macro %(1+4-5) 1 %2+1
+# CHECK: error: unknown token in expression
+# CHECK-NEXT: addl $%(1+4-5), %eax
+
+
+# CHECK: multi_args_macro %(1+4-5),1,%4%10
+# CHECK: error: unknown token in expression
+# CHECK-NEXT: addl $%(1+4-5), %eax
+.macro multi_args_macro arg1 arg2 arg3
+ label\arg1\arg2\arg3:
+ addl $\arg1, %eax
+.endm
+
+multi_args_macro %(1+4-5) 1 %2+1
+multi_args_macro %(1+4-5),1,%4%10
More information about the llvm-commits
mailing list