summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-02-05 09:16:39 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-02-05 09:16:39 +0000
commit747865af0c3fe31e8e7fd179056ba9db9d4fdcc7 (patch)
treec97d172a620ab4358d95620a1ae0c11f27ea1671 /clang/lib/CodeGen/CGCall.cpp
parent9d8bfbfdef30784a9fc07f755306071ea9e5c40f (diff)
downloadbcm5719-llvm-747865af0c3fe31e8e7fd179056ba9db9d4fdcc7.tar.gz
bcm5719-llvm-747865af0c3fe31e8e7fd179056ba9db9d4fdcc7.zip
Implement ABI Indirect sematics for arguments.
- No intended functionality change, all current ABI implementations were only using indirect for complex/aggregate types, which were being passed indirectly with the Direct ABIInfo kind. llvm-svn: 63858
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp38
1 files changed, 32 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index ab775131886..703bcd0d852 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1048,7 +1048,6 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
ie = FI.arg_end(); it != ie; ++it) {
const ABIArgInfo &AI = it->info;
- const llvm::Type *Ty = ConvertType(it->type);
switch (AI.getKind()) {
case ABIArgInfo::Ignore:
@@ -1060,11 +1059,11 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
case ABIArgInfo::Indirect:
// indirect arguments are always on the stack, which is addr space #0.
- ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
+ ArgTys.push_back(llvm::PointerType::getUnqual(ConvertType(it->type)));
break;
case ABIArgInfo::Direct:
- ArgTys.push_back(Ty);
+ ArgTys.push_back(ConvertType(it->type));
break;
case ABIArgInfo::Expand:
@@ -1199,8 +1198,24 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
const ABIArgInfo &ArgI = info_it->info;
switch (ArgI.getKind()) {
- // FIXME: Implement correct [in]direct semantics.
- case ABIArgInfo::Indirect:
+ case ABIArgInfo::Indirect: {
+ llvm::Value* V = AI;
+ if (hasAggregateLLVMType(Ty)) {
+ // Do nothing, aggregates and complex variables are accessed by
+ // reference.
+ } else {
+ // Load scalar value from indirect argument.
+ V = Builder.CreateLoad(V);
+ if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
+ // This must be a promotion, for something like
+ // "void a(x) short x; {..."
+ V = EmitScalarConversion(V, Ty, Arg->getType());
+ }
+ }
+ EmitParmDecl(*Arg, V);
+ break;
+ }
+
case ABIArgInfo::Direct: {
assert(AI != Fn->arg_end() && "Argument mismatch!");
llvm::Value* V = AI;
@@ -1346,8 +1361,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
RValue RV = I->first;
switch (ArgInfo.getKind()) {
- // FIXME: Implement correct [in]direct semantics.
case ABIArgInfo::Indirect:
+ if (RV.isScalar() || RV.isComplex()) {
+ // Make a temporary alloca to pass the argument.
+ Args.push_back(CreateTempAlloca(ConvertType(I->second)));
+ if (RV.isScalar())
+ Builder.CreateStore(RV.getScalarVal(), Args.back());
+ else
+ StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
+ } else {
+ Args.push_back(RV.getAggregateAddr());
+ }
+ break;
+
case ABIArgInfo::Direct:
if (RV.isScalar()) {
Args.push_back(RV.getScalarVal());
OpenPOWER on IntegriCloud