Support default parameters/arguments for assembler macros.

This patch is based on the one by PaX Team.

Patch by Andy Zhang!

llvm-svn: 164246
This commit is contained in:
Preston Gurd 2012-09-19 20:29:04 +00:00
parent eb3ebf16ab
commit 242ed3158a
2 changed files with 41 additions and 9 deletions

View File

@ -47,7 +47,7 @@ namespace {
/// \brief Helper class for tracking macro definitions.
typedef std::vector<AsmToken> MacroArgument;
typedef std::vector<MacroArgument> MacroArguments;
typedef StringRef MacroParameter;
typedef std::pair<StringRef, MacroArgument> MacroParameter;
typedef std::vector<MacroParameter> MacroParameters;
struct Macro {
@ -1534,7 +1534,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
StringRef Argument(Begin, I - (Pos +1));
unsigned Index = 0;
for (; Index < NParameters; ++Index)
if (Parameters[Index] == Argument)
if (Parameters[Index].first == Argument)
break;
// FIXME: We should error at the macro definition.
@ -1606,10 +1606,27 @@ bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
if (ParseMacroArgument(MA))
return true;
A.push_back(MA);
if (!MA.empty() || !NParameters)
A.push_back(MA);
else if (NParameters) {
if (!M->Parameters[Parameter].second.empty())
A.push_back(M->Parameters[Parameter].second);
}
if (Lexer.is(AsmToken::EndOfStatement))
// At the end of the statement, fill in remaining arguments that have
// default values. If there aren't any, then the next argument is
// required but missing
if (Lexer.is(AsmToken::EndOfStatement)) {
if (NParameters && Parameter < NParameters - 1) {
if (M->Parameters[Parameter + 1].second.empty())
return TokError("macro argument '" +
Twine(M->Parameters[Parameter + 1].first) +
"' is missing");
else
continue;
}
return false;
}
if (Lexer.is(AsmToken::Comma))
Lex();
@ -3091,8 +3108,15 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
MacroParameter Parameter;
if (getParser().ParseIdentifier(Parameter))
if (getParser().ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.macro' directive");
if (getLexer().is(AsmToken::Equal)) {
Lex();
if (getParser().ParseMacroArgument(Parameter.second))
return true;
}
Parameters.push_back(Parameter);
if (getLexer().isNot(AsmToken::Comma))
@ -3308,7 +3332,7 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
MacroParameters Parameters;
MacroParameter Parameter;
if (ParseIdentifier(Parameter))
if (ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.irp' directive");
Parameters.push_back(Parameter);
@ -3354,7 +3378,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
MacroParameters Parameters;
MacroParameter Parameter;
if (ParseIdentifier(Parameter))
if (ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.irpc' directive");
Parameters.push_back(Parameter);

View File

@ -4,10 +4,18 @@
movl \var@GOTOFF(%ebx),\re2g
.endm
.macro GET_DEFAULT var, re2g=%ebx, re3g=%ecx
movl 2(\re2g, \re3g, 2), \var
.endm
GET is_sse, %eax
GET is_sse, %eax
// CHECK: movl is_sse@GOTOFF(%ebx), %eax
// CHECK: movl is_sse@GOTOFF(%ebx), %eax
GET_DEFAULT %ebx, , %edx
// CHECK: movl 2(%ebx,%edx,2), %ebx
GET_DEFAULT %ebx, %edx
// CHECK: movl 2(%edx,%ecx,2), %ebx
.macro bar
.long $n