[ms-inline asm] Have MSAsmStmts use the generic EmitAsmStmt codegen function.

llvm-svn: 162796
This commit is contained in:
Chad Rosier 2012-08-28 21:11:24 +00:00
parent a82412da21
commit 649dfc317d
3 changed files with 8 additions and 42 deletions

View File

@ -132,8 +132,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break;
case Stmt::GCCAsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break;
case Stmt::MSAsmStmtClass: EmitMSAsmStmt(cast<MSAsmStmt>(*S)); break;
case Stmt::GCCAsmStmtClass: // Intentional fall-through.
case Stmt::MSAsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break;
case Stmt::ObjCAtTryStmtClass:
EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S));
@ -1619,6 +1619,10 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
llvm::CallInst *Result = Builder.CreateCall(IA, Args);
Result->addAttribute(~0, llvm::Attribute::NoUnwind);
// Add the inline asm non-standard dialect attribute on MS-style inline asms.
if (isa<MSAsmStmt>(&S))
Result->addAttribute(~0, llvm::Attribute::IANSDialect);
// Slap the source location of the inline asm into a !srcloc metadata on the
// call. FIXME: Handle metadata for MS-style inline asms.
if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S))
@ -1668,41 +1672,3 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
EmitStoreThroughLValue(RValue::get(Tmp), ResultRegDests[i]);
}
}
void CodeGenFunction::EmitMSAsmStmt(const MSAsmStmt &S) {
std::vector<llvm::Value*> Args;
std::vector<llvm::Type *> ArgTypes;
std::string Constraints;
// Clobbers
for (unsigned i = 0, e = S.getNumClobbers(); i != e; ++i) {
StringRef Clobber = S.getClobber(i);
if (Clobber != "memory" && Clobber != "cc")
Clobber = Target.getNormalizedGCCRegisterName(Clobber);
if (i != 0)
Constraints += ',';
Constraints += "~{";
Constraints += Clobber;
Constraints += '}';
}
// Add machine specific clobbers
std::string MachineClobbers = Target.getClobbers();
if (!MachineClobbers.empty()) {
if (!Constraints.empty())
Constraints += ',';
Constraints += MachineClobbers;
}
llvm::FunctionType *FTy =
llvm::FunctionType::get(VoidTy, ArgTypes, false);
llvm::InlineAsm *IA =
llvm::InlineAsm::get(FTy, *S.getAsmString(), Constraints, true);
llvm::CallInst *Result = Builder.CreateCall(IA, Args);
Result->addAttribute(~0, llvm::Attribute::NoUnwind);
Result->addAttribute(~0, llvm::Attribute::IANSDialect);
}

View File

@ -2002,7 +2002,6 @@ public:
void EmitCaseStmt(const CaseStmt &S);
void EmitCaseStmtRange(const CaseStmt &S);
void EmitAsmStmt(const AsmStmt &S);
void EmitMSAsmStmt(const MSAsmStmt &S);
void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S);
void EmitObjCAtTryStmt(const ObjCAtTryStmt &S);

View File

@ -88,7 +88,8 @@ 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", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
// Note: The AsmParser isn't properly matching the second instruction (i.e., j is being marked as an input, when in fact it is an output).
// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32 %0, i32 %1) nounwind ia_nsdialect
// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
// CHECK: ret i32 [[RET]]
}