Skip to content

Commit

Permalink
[LLVM][inline-asm][Altmacor] Altmacro string delimiter '<..>'
Browse files Browse the repository at this point in the history
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
"<string>
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

llvm-svn: 302135
  • Loading branch information
Michael Zuckerman authored and Michael Zuckerman committed May 4, 2017
1 parent 3f25a7e commit 763e60e
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 4 deletions.
42 changes: 38 additions & 4 deletions llvm/lib/MC/MCParser/AsmParser.cpp
Expand Up @@ -287,6 +287,7 @@ class AsmParser : public MCAsmParser {
/// }

private:
bool isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc);
bool parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI);
bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
Expand Down Expand Up @@ -1192,6 +1193,31 @@ AsmParser::applyModifierToExpr(const MCExpr *E,
llvm_unreachable("Invalid expression kind!");
}

/// This function checks if the next token is <string> 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.
Expand Down Expand Up @@ -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 '%'
Expand All @@ -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;
Expand Down
73 changes: 73 additions & 0 deletions llvm/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 <simpleCheck>

# 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 <simple>,<Check>,<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
29 changes: 29 additions & 0 deletions llvm/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: <simpleCheck>:
.macro simple_check_0 name
\name:
.endm

simple_check_0 <simpleCheck>


.altmacro
.noaltmacro

# Test #2: Switching from alternate mode to default mode
# CHECK: error: unexpected token at start of statement
# CHECK-NEXT: <simpleCheck1>:
.macro simple_check_1 name
\name:
.endm

simple_check_1 <simpleCheck1>

0 comments on commit 763e60e

Please sign in to comment.