diff options
author | Chad Rosier <mcrosier@apple.com> | 2012-08-22 19:18:30 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2012-08-22 19:18:30 +0000 |
commit | 2735df2eb16acfb92b8cd24e163e3a74a7a4d950 (patch) | |
tree | fc1aa04884e6c787b5aa616af1e62324f0eb4d19 | |
parent | a148fbcb5f441a089ea33067473fae5a8d5f778e (diff) |
[ms-inline asm] Start sending non-simple inline asms to the AsmParser.
The parser still can't handle all cases, so fall back to emitting a simple
MSAsmStmt if we get into trouble.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162382 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaStmtAsm.cpp | 42 | ||||
-rw-r--r-- | test/CodeGen/ms-inline-asm.c | 2 |
3 files changed, 28 insertions, 18 deletions
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index d78908dee8..4c24d2b391 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -1687,8 +1687,6 @@ void CodeGenFunction::EmitMSAsmStmt(const MSAsmStmt &S) { if (!CGM.getCodeGenOpts().EmitMicrosoftInlineAsm) return; - assert (S.isSimple() && "CodeGen can only handle simple MSAsmStmts."); - std::vector<llvm::Value*> Args; std::vector<llvm::Type *> ArgTypes; std::string Constraints; diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 96ccd7574f..a4a7a41277 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -338,6 +338,20 @@ static StringRef getSpelling(Sema &SemaRef, Token AsmTok) { return Asm; } +static bool bailOnMSAsm(std::vector<StringRef> Piece) { + for (unsigned i = 0, e = Piece.size(); i != e; ++i) + if (isMSAsmKeyword(Piece[i])) + return true; + return false; +} + +static bool bailOnMSAsm(std::vector<std::vector<StringRef> > Pieces) { + for (unsigned i = 0, e = Pieces.size(); i != e; ++i) + if (bailOnMSAsm(Pieces[i])) + return true; + return false; +} + static bool isSimpleMSAsm(std::vector<StringRef> &Pieces, const TargetInfo &TI) { if (isMSAsmKeyword(Pieces[0])) @@ -401,6 +415,12 @@ static std::string buildMSAsmString(Sema &SemaRef, return Res.c_str(); } +#define DEF_SIMPLE_MSASM \ + MSAsmStmt *NS = \ + new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \ + /*IsVolatile*/ true, AsmToks, Inputs, Outputs, \ + AsmString, Clobbers, EndLoc); + StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef<Token> AsmToks, @@ -415,10 +435,7 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, // Empty asm statements don't need to instantiate the AsmParser, etc. if (AsmToks.empty()) { StringRef AsmString; - MSAsmStmt *NS = - new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, - /*IsVolatile*/ true, AsmToks, Inputs, Outputs, - AsmString, Clobbers, EndLoc); + DEF_SIMPLE_MSASM; return Owned(NS); } @@ -437,14 +454,8 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, IsSimple = isSimpleMSAsm(Pieces[i], Context.getTargetInfo()); } - // AsmParser doesn't fully support non-simple asm statements. - if (!IsSimple) { - MSAsmStmt *NS = - new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, - /*IsVolatile*/ true, AsmToks, Inputs, Outputs, - AsmString, Clobbers, EndLoc); - return Owned(NS); - } + // AsmParser doesn't fully support these asm statements. + if (bailOnMSAsm(Pieces)) { DEF_SIMPLE_MSASM; return Owned(NS); } // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); @@ -497,7 +508,8 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SmallVector<llvm::MCParsedAsmOperand*, 8> Operands; bool HadError = TargetParser->ParseInstruction(Opcode.str(), IDLoc, Operands); - assert (!HadError && "Unexpected error parsing instruction"); + // If we had an error parsing the operands, fail gracefully. + if (HadError) { DEF_SIMPLE_MSASM; return Owned(NS); } // Match the MCInstr. unsigned ErrorInfo; @@ -505,8 +517,8 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, HadError = TargetParser->MatchInstruction(IDLoc, Operands, Instrs, ErrorInfo, /*matchingInlineAsm*/ true); - assert (!HadError && "Unexpected error matching instruction"); - assert ((Instrs.size() == 1) && "Expected only a single instruction."); + // If we had an error parsing the operands, fail gracefully. + if (HadError) { DEF_SIMPLE_MSASM; return Owned(NS); } // Get the instruction descriptor. llvm::MCInst Inst = Instrs[0]; diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c index 7680e3efa9..bd9fe53554 100644 --- a/test/CodeGen/ms-inline-asm.c +++ b/test/CodeGen/ms-inline-asm.c @@ -88,7 +88,7 @@ unsigned t10(void) { // CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4 // CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4 // CHECK: store i32 1, i32* [[I]], align 4 -// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4 // CHECK: ret i32 [[RET]] } |