From f39a4211bdea6c136562a5225e5a84d54e62dc8f Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 5 Feb 2008 20:01:53 +0000 Subject: [PATCH] More improvements to inline asm CG. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46762 91177308-0d34-0410-b5e6-96231b3b80d8 --- CodeGen/CGStmt.cpp | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/CodeGen/CGStmt.cpp b/CodeGen/CGStmt.cpp index 6393d1da97..c651970850 100644 --- a/CodeGen/CGStmt.cpp +++ b/CodeGen/CGStmt.cpp @@ -600,6 +600,11 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { std::vector ArgTypes; std::vector Args; + + // Keep track of inout constraints. + std::string InOutConstraints; + std::vector InOutArgs; + std::vector InOutArgTypes; for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(), @@ -629,9 +634,33 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Args.push_back(Dest.getAddress()); if (i != 0) Constraints += ','; - Constraints += '*'; + Constraints += "=*"; Constraints += OutputConstraint; - } + } + + if (Info & TargetInfo::CI_ReadWrite) { + // FIXME: This code should be shared with the code that handles inputs. + InOutConstraints += ','; + + const Expr *InputExpr = S.getOutputExpr(i); + llvm::Value *Arg; + if ((Info & TargetInfo::CI_AllowsRegister) || + !(Info & TargetInfo::CI_AllowsMemory)) { + if (ConvertType(InputExpr->getType())->isFirstClassType()) { + Arg = EmitScalarExpr(InputExpr); + } else { + assert(0 && "FIXME: Implement passing non first class types as inputs"); + } + } else { + LValue Dest = EmitLValue(InputExpr); + Arg = Dest.getAddress(); + InOutConstraints += '*'; + } + + InOutArgTypes.push_back(Arg->getType()); + InOutArgs.push_back(Arg); + InOutConstraints += OutputConstraint; + } } unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs(); @@ -674,6 +703,13 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Constraints += InputConstraint; } + // Append the "input" part of inout constraints last. + for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { + ArgTypes.push_back(InOutArgTypes[i]); + Args.push_back(InOutArgs[i]); + } + Constraints += InOutConstraints; + // Clobbers for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { std::string Clobber(S.getClobber(i)->getStrData(), @@ -692,7 +728,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Constraints += ','; Constraints += C; } - + const llvm::FunctionType *FTy = llvm::FunctionType::get(ResultType, ArgTypes, false); -- 2.50.1