[cfe-commits] r64469 - /cfe/trunk/lib/CodeGen/CGCall.cpp

Daniel Dunbar daniel at zuster.org
Fri Feb 13 09:46:31 PST 2009


Author: ddunbar
Date: Fri Feb 13 11:46:31 2009
New Revision: 64469

URL: http://llvm.org/viewvc/llvm-project?rev=64469&view=rev
Log:
x86_64 ABI: Support va_arg passed in mixed registers.
 - Now at 1274 passes on gcc compat suite vs 1262.

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=64469&r1=64468&r2=64469&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Feb 13 11:46:31 2009
@@ -963,7 +963,28 @@
     CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(VAListAddr, 3), 
                            "reg_save_area");
   if (neededInt && neededSSE) {
-    assert(0 && "FIXME: Implement support for va_arg in mixed regs");
+    // FIXME: Cleanup.
+    assert(AI.isCoerce() && "Unexpected ABI info for mixed regs");
+    const llvm::StructType *ST = cast<llvm::StructType>(AI.getCoerceToType());
+    llvm::Value *Tmp = CGF.CreateTempAlloca(ST);
+    assert(ST->getNumElements() == 2 && "Unexpected ABI info for mixed regs");
+    const llvm::Type *TyLo = ST->getElementType(0);
+    const llvm::Type *TyHi = ST->getElementType(1);
+    assert((TyLo->isFloatingPoint() ^ TyHi->isFloatingPoint()) &&
+           "Unexpected ABI info for mixed regs");
+    const llvm::Type *PTyLo = llvm::PointerType::getUnqual(TyLo);
+    const llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi);
+    llvm::Value *GPAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset);
+    llvm::Value *FPAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);
+    llvm::Value *RegLoAddr = TyLo->isFloatingPoint() ? FPAddr : GPAddr;
+    llvm::Value *RegHiAddr = TyLo->isFloatingPoint() ? GPAddr : FPAddr;
+    llvm::Value *V = 
+      CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegLoAddr, PTyLo));
+    CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0));
+    V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegHiAddr, PTyHi));
+    CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1));
+    
+    RegAddr = CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(LTy));
   } else if (neededInt) {
     RegAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset);
     RegAddr = CGF.Builder.CreateBitCast(RegAddr, 





More information about the cfe-commits mailing list