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
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).
};
3, // AOK_Output
5, // AOK_SizeDirective
1, // AOK_Label
+ 5, // AOK_EndOfStatement
2 // AOK_Skip
};
bool parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI);
+ bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
void eatToEndOfLine();
bool parseCppHashLineFilenameComment(SMLoc L);
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() {
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;
OS << '.';
OS << AR.Val;
break;
+ case AOK_EndOfStatement:
+ OS << "\n\t";
+ break;
}
// Skip the original expression.
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
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");
}
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.