diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-02-05 11:13:54 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-02-05 11:13:54 +0000 |
commit | 2fbf2f547cf23c0dd89719c2b5c5d6c6f0fa469c (patch) | |
tree | d0ec594cb171994f7ff4680535a0eca59aa07c0d /lib/CodeGen/CGCall.cpp | |
parent | 2969a0243b0939286a45d0ba58dd3e1de226ac60 (diff) |
Implement Direct ABIInfo semantics.
- No intended functionality change, this is essentially enabling
direct passing of complex and aggregate values, which no ABI is
using.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63863 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index af3ea74d23..9c4472ee92 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1219,10 +1219,18 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, case ABIArgInfo::Direct: { assert(AI != Fn->arg_end() && "Argument mismatch!"); llvm::Value* V = AI; - 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()); + if (hasAggregateLLVMType(Ty)) { + // Create a temporary alloca to hold the argument; the rest of + // codegen expects to access aggregates & complex values by + // reference. + V = CreateTempAlloca(ConvertType(Ty)); + Builder.CreateStore(AI, V); + } else { + 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; @@ -1288,10 +1296,8 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, const ABIArgInfo &RetAI = FI.getReturnInfo(); switch (RetAI.getKind()) { - // FIXME: Implement correct [in]direct semantics. case ABIArgInfo::Indirect: if (RetTy->isAnyComplexType()) { - // FIXME: Volatile ComplexPairTy RT = LoadComplexFromAddr(ReturnValue, false); StoreComplexToAddr(RT, CurFn->arg_begin(), false); } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { @@ -1303,6 +1309,8 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, break; case ABIArgInfo::Direct: + // The internal return value temp always will have + // pointer-to-return-type type. RV = Builder.CreateLoad(ReturnValue); break; @@ -1368,11 +1376,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (RV.isScalar()) { Args.push_back(RV.getScalarVal()); } else if (RV.isComplex()) { - // Make a temporary alloca to pass the argument. - Args.push_back(CreateTempAlloca(ConvertType(I->second))); - StoreComplexToAddr(RV.getComplexVal(), Args.back(), false); + llvm::Value *Tmp = llvm::UndefValue::get(ConvertType(I->second)); + Tmp = Builder.CreateInsertValue(Tmp, RV.getComplexVal().first, 0); + Tmp = Builder.CreateInsertValue(Tmp, RV.getComplexVal().second, 1); + Args.push_back(Tmp); } else { - Args.push_back(RV.getAggregateAddr()); + Args.push_back(Builder.CreateLoad(RV.getAggregateAddr())); } break; @@ -1415,7 +1424,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, CI->setName("call"); switch (RetAI.getKind()) { - // FIXME: Implement correct [in]direct semantics. case ABIArgInfo::Indirect: if (RetTy->isAnyComplexType()) return RValue::getComplex(LoadComplexFromAddr(Args[0], false)); @@ -1425,17 +1433,21 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, return RValue::get(Builder.CreateLoad(Args[0])); case ABIArgInfo::Direct: - assert((!RetTy->isAnyComplexType() && - !CodeGenFunction::hasAggregateLLVMType(RetTy)) && - "FIXME: Implement return for non-scalar direct types."); - return RValue::get(CI); + if (RetTy->isAnyComplexType()) { + llvm::Value *Real = Builder.CreateExtractValue(CI, 0); + llvm::Value *Imag = Builder.CreateExtractValue(CI, 1); + return RValue::getComplex(std::make_pair(Real, Imag)); + } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { + llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "agg.tmp"); + Builder.CreateStore(CI, V); + return RValue::getAggregate(V); + } else + return RValue::get(CI); case ABIArgInfo::Ignore: // If we are ignoring an argument that had a result, make sure to // construct the appropriate return value for our caller. return GetUndefRValue(RetTy); - if (RetTy->isVoidType()) - return RValue::get(0); case ABIArgInfo::Coerce: { // FIXME: Avoid the conversion through memory if possible. |