Skip to content

Commit

Permalink
[ms-inline-asm][AVX512] Add ability to use k registers in MS inline a…
Browse files Browse the repository at this point in the history
…sm + fix bag with curly braces

Until now curly braces could only be used in MS inline assembly to mark block start/end.
All curly braces were removed completely at a very early stage.
This approach caused bugs like:
"m{o}v eax, ebx" turned into "mov eax, ebx" without any error.

In addition, AVX-512 added special operands (e.g., k registers), which are also surrounded by curly braces that mark them as such.
Now, we need to keep the curly braces and identify at a later stage if they are marking block start/end (if so, ignore them), or surrounding special AVX-512 operands (if so, parse them as such).

This patch fixes the bug described above and enables the use of AVX-512 special operands.

This commit is the the llvm part of the patch.
The clang part of the review is: http://reviews.llvm.org/D17766
The llvm part of the review is: http://reviews.llvm.org/D17767

Differential Revision: http://reviews.llvm.org/D17767

llvm-svn: 262843
  • Loading branch information
Marina Yatsina committed Mar 7, 2016
1 parent 5f77679 commit 5f5de9f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
2 changes: 2 additions & 0 deletions llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
Expand Up @@ -40,6 +40,7 @@ enum AsmRewriteKind {
AOK_Output, // Rewrite in terms of $N.
AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr).
AOK_Label, // Rewrite local labels.
AOK_EndOfStatement, // Add EndOfStatement (e.g., "\n\t").
AOK_Skip // Skip emission (e.g., offset/type operators).
};

Expand All @@ -55,6 +56,7 @@ const char AsmRewritePrecedence [] = {
3, // AOK_Output
5, // AOK_SizeDirective
1, // AOK_Label
5, // AOK_EndOfStatement
2 // AOK_Skip
};

Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/MC/MCParser/AsmParser.cpp
Expand Up @@ -251,6 +251,7 @@ class AsmParser : public MCAsmParser {

bool parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI);
bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
void eatToEndOfLine();
bool parseCppHashLineFilenameComment(SMLoc L);

Expand Down Expand Up @@ -1820,6 +1821,24 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return false;
}

// Parse and erase curly braces marking block start/end
bool
AsmParser::parseCurlyBlockScope(SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
// Identify curly brace marking block start/end
if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
return false;

SMLoc StartLoc = Lexer.getLoc();
Lex(); // Eat the brace
if (Lexer.is(AsmToken::EndOfStatement))
Lex(); // Eat EndOfStatement following the brace

// Erase the block start/end brace from the output asm string
AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
StartLoc.getPointer());
return true;
}

/// eatToEndOfLine uses the Lexer to eat the characters to the end of the line
/// since they may not be able to be tokenized to get to the end of line token.
void AsmParser::eatToEndOfLine() {
Expand Down Expand Up @@ -4983,6 +5002,10 @@ bool AsmParser::parseMSInlineAsm(
unsigned InputIdx = 0;
unsigned OutputIdx = 0;
while (getLexer().isNot(AsmToken::Eof)) {
// Parse curly braces marking block start/end
if (parseCurlyBlockScope(AsmStrRewrites))
continue;

ParseStatementInfo Info(&AsmStrRewrites);
if (parseStatement(Info, &SI))
return true;
Expand Down Expand Up @@ -5159,6 +5182,9 @@ bool AsmParser::parseMSInlineAsm(
OS << '.';
OS << AR.Val;
break;
case AOK_EndOfStatement:
OS << "\n\t";
break;
}

// Skip the original expression.
Expand Down
12 changes: 11 additions & 1 deletion llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
Expand Up @@ -2304,6 +2304,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
Name == "repne" || Name == "repnz" ||
Name == "rex64" || Name == "data16";

bool CurlyAsEndOfStatement = false;
// This does the actual operand parsing. Don't parse any more if we have a
// prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
// just want to parse the "lock" as the first instruction and the "incl" as
Expand Down Expand Up @@ -2331,7 +2332,12 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
break;
}

if (getLexer().isNot(AsmToken::EndOfStatement))
// In MS inline asm curly braces mark the begining/end of a block, therefore
// they should be interepreted as end of statement
CurlyAsEndOfStatement =
isParsingIntelSyntax() && isParsingInlineAsm() &&
(getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
return ErrorAndEatStatement(getLexer().getLoc(),
"unexpected token in argument list");
}
Expand All @@ -2340,6 +2346,10 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
if (getLexer().is(AsmToken::EndOfStatement) ||
(isPrefix && getLexer().is(AsmToken::Slash)))
Parser.Lex();
else if (CurlyAsEndOfStatement)
// Add an actual EndOfStatement before the curly brace
Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
getLexer().getTok().getLoc(), 0);

// This is for gas compatibility and cannot be done in td.
// Adding "p" for some floating point with no argument.
Expand Down

0 comments on commit 5f5de9f

Please sign in to comment.