More improvements to inline asm CG.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46762 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGStmt.cpp b/CodeGen/CGStmt.cpp
index 6393d1d..c651970 100644
--- a/CodeGen/CGStmt.cpp
+++ b/CodeGen/CGStmt.cpp
@@ -600,6 +600,11 @@
std::vector<const llvm::Type*> ArgTypes;
std::vector<llvm::Value*> Args;
+
+ // Keep track of inout constraints.
+ std::string InOutConstraints;
+ std::vector<llvm::Value*> InOutArgs;
+ std::vector<const llvm::Type*> InOutArgTypes;
for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(),
@@ -629,9 +634,33 @@
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 @@
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 @@
Constraints += ',';
Constraints += C;
}
-
+
const llvm::FunctionType *FTy =
llvm::FunctionType::get(ResultType, ArgTypes, false);