Index: include/llvm/MC/MCParser/MCTargetAsmParser.h =================================================================== --- include/llvm/MC/MCParser/MCTargetAsmParser.h +++ include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -40,6 +40,7 @@ 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 @@ 3, // AOK_Output 5, // AOK_SizeDirective 1, // AOK_Label + 5, // AOK_EndOfStatement 2 // AOK_Skip }; Index: lib/MC/MCParser/AsmParser.cpp =================================================================== --- lib/MC/MCParser/AsmParser.cpp +++ lib/MC/MCParser/AsmParser.cpp @@ -4982,10 +4982,27 @@ // While we have input, parse each statement. unsigned InputIdx = 0; unsigned OutputIdx = 0; + SMLoc LastStatementLoc = getLexer().getLoc(); while (getLexer().isNot(AsmToken::Eof)) { ParseStatementInfo Info(&AsmStrRewrites); + + if (Lexer.is(AsmToken::LCurly) || Lexer.is(AsmToken::RCurly)) { + // Identify curly brace marking block start/end + SMLoc StartLoc = Lexer.getLoc(); + Lex(); // Eat curly brace + if (Lexer.is(AsmToken::EndOfStatement)) + Lex(); // Eat EndOfStatement after curly brace + + // Erase the block start/end brace from the output asm string + AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, + Lexer.getLoc().getPointer() - + StartLoc.getPointer()); + continue; + } + if (parseStatement(Info, &SI)) return true; + LastStatementLoc = Lexer.getLoc(); if (Info.ParseError) return true; @@ -5044,6 +5061,14 @@ ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end()); } + // We don't want to add another new line before EOF + for (AsmRewrite &AR : AsmStrRewrites) { + if (AR.Loc.getPointer() < LastStatementLoc.getPointer()) + continue; + if (AR.Kind == AOK_EndOfStatement) + AR.Kind = AOK_Delete; + } + // Set the number of Outputs and Inputs. NumOutputs = OutputDecls.size(); NumInputs = InputDecls.size(); @@ -5159,6 +5184,9 @@ OS << '.'; OS << AR.Val; break; + case AOK_EndOfStatement: + OS << "\n\t"; + break; } // Skip the original expression. Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2304,6 +2304,7 @@ 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 @@ 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 @@ 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.