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,
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"
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:
} 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();
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()) {
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
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;
--- /dev/null
+# 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
--- /dev/null
+# 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