From e11b0c62e8f7bf10a4348907aebc59bc6bae2785 Mon Sep 17 00:00:00 2001 From: Michael Zuckerman Date: Thu, 4 May 2017 10:37:00 +0000 Subject: [PATCH] [LLVM][inline-asm][Altmacor] Altmacro string delimiter '<..>' In this patch, I introduce a new altmacro string delimiter. This review is the second review in a series of four reviews. (one for each altmacro feature: LOCAL, string delimiter, string '!' escape sign and absolute expression as a string '%' ). In the alternate macro mode, you can delimit strings with matching angle brackets <..> when using it as a part of calling macro arguments. As described in the https://sourceware.org/binutils/docs-2.27/as/Altmacro.html " You can delimit strings with matching angle brackets." assumptions: 1. If an argument begins with '<' and ends with '>'. The argument is considered as a string. 2. Except adding new string mark '<..>', a regular macro behavior is expected. 3. The altmacro cannot affect the regular less/greater behavior. 4. If a comma is present inside an angle brackets it considered as a character and not as a separator. Differential Revision: https://reviews.llvm.org/D32701 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302135 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCParser/AsmParser.cpp | 42 +++++++++-- test/MC/AsmParser/altmacro_string.s | 73 ++++++++++++++++++++ test/MC/AsmParser/negative_altmacro_string.s | 29 ++++++++ 3 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 test/MC/AsmParser/altmacro_string.s create mode 100644 test/MC/AsmParser/negative_altmacro_string.s diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index f36a21bf112..66ba853da2f 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -287,6 +287,7 @@ public: /// } private: + bool isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc); bool parseStatement(ParseStatementInfo &Info, MCAsmParserSemaCallback *SI); bool parseCurlyBlockScope(SmallVectorImpl& AsmStrRewrites); @@ -1192,6 +1193,31 @@ AsmParser::applyModifierToExpr(const MCExpr *E, llvm_unreachable("Invalid expression kind!"); } +/// This function checks if the next token is type or arithmetic. +/// string that begin with character '<' must end with character '>'. +/// otherwise it is arithmetics. +/// If the function returns a 'true' value, +/// the End argument will be filled with the last location pointed to the '>' +/// character. + +/// There is a gap between the AltMacro's documentation and the single quote implementation. +/// GCC does not fully support this feature and so we will not support it. +/// TODO: Adding single quote as a string. +bool AsmParser::isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc) { + assert((StrLoc.getPointer() != NULL) && + "Argument to the function cannot be a NULL value"); + const char *CharPtr = StrLoc.getPointer(); + while ((*CharPtr != '>') && (*CharPtr != '\n') && + (*CharPtr != '\r') && (*CharPtr != '\0')){ + CharPtr++; + } + if (*CharPtr == '>') { + EndLoc = StrLoc.getFromPointer(CharPtr + 1); + return true; + } + return false; +} + /// \brief Parse an expression and return it. /// /// expr ::= expr &&,|| expr -> lowest. @@ -2461,9 +2487,9 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, if (NamedParametersFound && FA.Name.empty()) return Error(IDLoc, "cannot mix positional and keyword arguments"); + SMLoc StrLoc = Lexer.getLoc(); + SMLoc EndLoc; if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Percent)) { - SMLoc StrLoc = Lexer.getLoc(); - SMLoc EndLoc; const MCExpr *AbsoluteExp; int64_t Value; /// Eat '%' @@ -2476,8 +2502,16 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, 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)) + } else if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Less) && + isAltmacroString(StrLoc, EndLoc)) { + const char *StrChar = StrLoc.getPointer(); + const char *EndChar = EndLoc.getPointer(); + jumpToLoc(EndLoc, CurBuffer); + /// Eat from '<' to '>' + Lex(); + AsmToken newToken(AsmToken::String, StringRef(StrChar, EndChar - StrChar)); + FA.Value.push_back(newToken); + } else if(parseMacroArgument(FA.Value, Vararg)) return true; unsigned PI = Parameter; diff --git a/test/MC/AsmParser/altmacro_string.s b/test/MC/AsmParser/altmacro_string.s new file mode 100644 index 00000000000..70012b2b852 --- /dev/null +++ b/test/MC/AsmParser/altmacro_string.s @@ -0,0 +1,73 @@ +# RUN: llvm-mc -triple i386-linux-gnu %s| FileCheck %s + +# This test checks the altmacro string delimiter '<' and '>'. + +.altmacro + +# Test #1: +# You can delimit strings with matching angle brackets '<' '>'. +# If an argument begins with '<' and ends with '>'. +# The argument is considered as a string. + +# CHECK: simpleCheck: +.macro simple_check_0 name + \name: + addl $5,%eax +.endm + +simple_check_0 + +# Test #2: +# Except adding new string marks '<..>', a regular macro behavior is expected. + +# CHECK: simpleCheck0: +# CHECK: addl $0, %eax +.macro concat string1 string2 string3 + \string1\string2\string3: + addl $\string3, %eax +.endm + +concat ,,<0> + +# Test #3: +# The altmacro cannot affect the regular less/greater behavior. + +# CHECK: addl $1, %eax +# CHECK: addl $0, %eax + +.macro fun3 arg1 arg2 + addl $\arg1,%eax + addl $\arg2,%eax +.endm + +fun3 5<6 , 5>8 + +# Test #4: +# If a comma is present inside an angle brackets, +# the comma considered as a character and not as a separator. +# This check checks the ability to split the string to different +# arguments according to the use of the comma. +# Fun2 sees the comma as a character. +# Fun3 sees the comma as a separator. + +# CHECK: addl $5, %eax +# CHECK: addl $6, %eax +.macro fun2 arg + fun3 \arg +.endm + +fun2 <5,6> + +# Test #5: +# If argument begin with '<' and there is no '>' to close it. +# A regular macro behavior is expected. + +# CHECK: addl $4, %eax +.macro fun4 arg1 arg2 + .if \arg2\arg1 + addl $\arg2,%eax + .endif +.endm + +fun4 <5,4 +.noaltmacro diff --git a/test/MC/AsmParser/negative_altmacro_string.s b/test/MC/AsmParser/negative_altmacro_string.s new file mode 100644 index 00000000000..81096c6cbda --- /dev/null +++ b/test/MC/AsmParser/negative_altmacro_string.s @@ -0,0 +1,29 @@ +# RUN: not llvm-mc -triple i386-linux-gnu %s 2>&1 | FileCheck %s + +# This test checks the altmacro string delimiter '<' and '>'. +# 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 default mode is ".noaltmacro". + +# Test #1: default mode +# CHECK: error: unexpected token at start of statement +# CHECK-NEXT: : +.macro simple_check_0 name + \name: +.endm + +simple_check_0 + + +.altmacro +.noaltmacro + +# Test #2: Switching from alternate mode to default mode +# CHECK: error: unexpected token at start of statement +# CHECK-NEXT: : +.macro simple_check_1 name + \name: +.endm + +simple_check_1 -- 2.50.1