[cfe-commits] r64880 - /cfe/trunk/lib/CodeGen/CGCall.cpp
Daniel Dunbar
daniel at zuster.org
Tue Feb 17 19:44:20 PST 2009
Author: ddunbar
Date: Tue Feb 17 21:44:19 2009
New Revision: 64880
URL: http://llvm.org/viewvc/llvm-project?rev=64880&view=rev
Log:
x86_64 ABI: Two bug fixes.
1. Return of _Complex long double used wrong type.
2. va_arg of types passed in two SSE registers didn't account for
extra space in register save area.
Down to 18 failures on gcc/compat/x86_64. Combined 32/64 results are:
--
=== gcc Summary ===
# of expected passes 1292
# of unexpected failures 34
# of unsupported tests 2
--
Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=64880&r1=64879&r2=64880&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Feb 17 21:44:19 2009
@@ -752,7 +752,9 @@
// %st1.
case ComplexX87:
assert(Hi == ComplexX87 && "Unexpected ComplexX87 classification.");
- ResType = llvm::VectorType::get(llvm::Type::X86_FP80Ty, 2);
+ ResType = llvm::StructType::get(llvm::Type::X86_FP80Ty,
+ llvm::Type::X86_FP80Ty,
+ NULL);
break;
}
@@ -1028,6 +1030,12 @@
// copying to a temporary location in case the parameter is passed
// in different register classes or requires an alignment greater
// than 8 for general purpose registers and 16 for XMM registers.
+ //
+ // FIXME: This really results in shameful code when we end up
+ // needing to collect arguments from different places; often what
+ // should result in a simple assembling of a structure from
+ // scattered addresses has many more loads than necessary. Can we
+ // clean this up?
const llvm::Type *LTy = CGF.ConvertTypeForMem(Ty);
llvm::Value *RegAddr =
CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(VAListAddr, 3),
@@ -1060,9 +1068,33 @@
RegAddr = CGF.Builder.CreateBitCast(RegAddr,
llvm::PointerType::getUnqual(LTy));
} else {
- RegAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);
- RegAddr = CGF.Builder.CreateBitCast(RegAddr,
- llvm::PointerType::getUnqual(LTy));
+ if (neededSSE == 1) {
+ RegAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);
+ RegAddr = CGF.Builder.CreateBitCast(RegAddr,
+ llvm::PointerType::getUnqual(LTy));
+ } else {
+ assert(neededSSE == 2 && "Invalid number of needed registers!");
+ // SSE registers are spaced 16 bytes apart in the register save
+ // area, we need to collect the two eightbytes together.
+ llvm::Value *RegAddrLo = CGF.Builder.CreateGEP(RegAddr, fp_offset);
+ llvm::Value *RegAddrHi =
+ CGF.Builder.CreateGEP(RegAddrLo,
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, 16));
+ const llvm::Type *DblPtrTy =
+ llvm::PointerType::getUnqual(llvm::Type::DoubleTy);
+ const llvm::StructType *ST = llvm::StructType::get(llvm::Type::DoubleTy,
+ llvm::Type::DoubleTy,
+ NULL);
+ llvm::Value *V, *Tmp = CGF.CreateTempAlloca(ST);
+ V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegAddrLo,
+ DblPtrTy));
+ CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0));
+ V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegAddrHi,
+ DblPtrTy));
+ CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1));
+ RegAddr = CGF.Builder.CreateBitCast(Tmp,
+ llvm::PointerType::getUnqual(LTy));
+ }
}
// AMD64-ABI 3.5.7p5: Step 5. Set:
More information about the cfe-commits
mailing list