From acc22b6b5a8ba501f896fb0d00afdff5c5a3f090 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Thu, 6 Sep 2012 19:35:00 +0000 Subject: [PATCH] [ms-inline asm] The IR representation of inline assembly enumerates the input and output expressions much like that in GNU-style inline assembly. Output expressions are first. Do this for MS-style inline asms. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163342 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaStmtAsm.cpp | 25 +++++++++++++++++++++++++ test/CodeGen/ms-inline-asm.c | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index e19ee96436..c6432ddc66 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -474,6 +474,8 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SmallVector Outputs; SmallVector InputExprs; SmallVector OutputExprs; + SmallVector InputExprNames; + SmallVector OutputExprNames; // Empty asm statements don't need to instantiate the AsmParser, etc. if (AsmToks.empty()) { @@ -628,10 +630,12 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, if (isDef || isMemDef) { Outputs.push_back(II); OutputExprs.push_back(Result.take()); + OutputExprNames.push_back(Name.str()); OutputConstraints.push_back("=r"); } else { Inputs.push_back(II); InputExprs.push_back(Result.take()); + InputExprNames.push_back(Name.str()); InputConstraints.push_back("r"); } } @@ -654,6 +658,27 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, E = InputConstraints.end(); I != E; ++I) Constraints.push_back(*I); + // Enumerate the AsmString expressions. + // FIXME: This isn't going to work if: + // 1. The symbol name and an opcode/reg share the same, or are a substring of + // the, name. + // 2. The symbol name appears more then once in the asm string. + unsigned OpNum = 0; + for (unsigned i = 0, e = OutputExprNames.size(); i != e; ++i, ++OpNum) { + size_t found = AsmString.find(OutputExprNames[i]); + SmallString<32> Res; + llvm::raw_svector_ostream OS(Res); + OS << '$' << OpNum; + AsmString.replace(found, OutputExprNames[i].size(), OS.str()); + } + for (unsigned i = 0, e = InputExprNames.size(); i != e; ++i, ++OpNum) { + size_t found = AsmString.find(InputExprNames[i]); + SmallString<32> Res; + llvm::raw_svector_ostream OS(Res); + OS << '$' << OpNum; + AsmString.replace(found, InputExprNames[i].size(), OS.str()); + } + MSAsmStmt *NS = new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple, /*IsVolatile*/ true, AsmToks, Inputs, Outputs, diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c index f90bb3aba2..0a4e7775cf 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 i32 asm sideeffect inteldialect "mov eax, i\0Amov j, eax", "=r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32 %{{.*}}) nounwind +// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1\0Amov $0, eax", "=r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32 %{{.*}}) nounwind // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4 // CHECK: ret i32 [[RET]] } -- 2.40.0