mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[ms-inline-asm][AVX512] Add ability to use k registers in MS inline asm + 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
This commit is contained in:
parent
1e851654db
commit
dcbfbce154
@ -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).
|
||||
};
|
||||
|
||||
@ -55,6 +56,7 @@ const char AsmRewritePrecedence [] = {
|
||||
3, // AOK_Output
|
||||
5, // AOK_SizeDirective
|
||||
1, // AOK_Label
|
||||
5, // AOK_EndOfStatement
|
||||
2 // AOK_Skip
|
||||
};
|
||||
|
||||
|
@ -251,6 +251,7 @@ private:
|
||||
|
||||
bool parseStatement(ParseStatementInfo &Info,
|
||||
MCAsmParserSemaCallback *SI);
|
||||
bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
|
||||
void eatToEndOfLine();
|
||||
bool parseCppHashLineFilenameComment(SMLoc L);
|
||||
|
||||
@ -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() {
|
||||
@ -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;
|
||||
@ -5159,6 +5182,9 @@ bool AsmParser::parseMSInlineAsm(
|
||||
OS << '.';
|
||||
OS << AR.Val;
|
||||
break;
|
||||
case AOK_EndOfStatement:
|
||||
OS << "\n\t";
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip the original expression.
|
||||
|
@ -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
|
||||
@ -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");
|
||||
}
|
||||
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user