[llvm-commits] [llvm-gcc-4.2] r96222 - /llvm-gcc-4.2/trunk/gcc/llvm-abi-linux-ppc.cpp

Rafael Espindola rafael.espindola at gmail.com
Mon Feb 15 07:41:19 PST 2010


Author: rafael
Date: Mon Feb 15 09:41:17 2010
New Revision: 96222

URL: http://llvm.org/viewvc/llvm-project?rev=96222&view=rev
Log:
Move all ppc linux specific logic to llvm_ppc_try_pass_aggregate_custom. With
this patch the only difference between the default and the ppc linux
implementations is the call to llvm_ppc_try_pass_aggregate_custom.


Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-abi-linux-ppc.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi-linux-ppc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi-linux-ppc.cpp?rev=96222&r1=96221&r2=96222&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi-linux-ppc.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi-linux-ppc.cpp Mon Feb 15 09:41:17 2010
@@ -83,52 +83,31 @@
   return NumGPRs < 8 ? NumGPRs : 8;
 }
 
-/// HandleArgument - This is invoked by the target-independent code for each
-/// argument type passed into the function.  It potentially breaks down the
-/// argument and invokes methods on the client that indicate how its pieces
-/// should be handled.  This handles things like decimating structures into
-/// their fields.
-///
+static bool isSVR4ABI() {
+#if defined(POWERPC_LINUX) && (TARGET_64BIT == 0)
+  return true;
+#else
+  return false;
+#endif
+}
+
 /// _Complex arguments are never split, thus their two scalars are either
 /// passed both in argument registers or both on the stack. Also _Complex
 /// arguments are always passed in general purpose registers, never in
 /// Floating-point registers or vector registers.
-void SVR4ABI::HandleArgument(tree type, std::vector<const Type*> &ScalarElts,
-			     Attributes *Attributes) {
-  unsigned Size = 0;
-  bool DontCheckAlignment = false;
+static bool
+llvm_ppc_try_pass_aggregate_custom(tree type, std::vector<const Type*> &ScalarElts,
+                                   const CallingConv::ID &CC,
+                                   struct DefaultABIClient* C) {
+  if (!isSVR4ABI())
+    return false;
+
   // Eight GPR's are availabe for parameter passing.
   const unsigned NumArgRegs = 8;
   unsigned NumGPR = count_num_registers_uses(ScalarElts);
   const Type *Ty = ConvertType(type);
-  // Figure out if this field is zero bits wide, e.g. {} or [0 x int].  Do
-  // not include variable sized fields here.
-  std::vector<const Type*> Elts;
   const Type* Int32Ty = Type::getInt32Ty(getGlobalContext());
-  if (Ty->isVoidTy()) {
-    // Handle void explicitly as an opaque type.
-    const Type *OpTy = OpaqueType::get(getGlobalContext());
-    C.HandleScalarArgument(OpTy, type);
-    ScalarElts.push_back(OpTy);
-  } else if (isPassedByInvisibleReference(type)) { // variable size -> by-ref.
-    const Type *PtrTy = Ty->getPointerTo();
-    C.HandleByInvisibleReferenceArgument(PtrTy, type);
-    ScalarElts.push_back(PtrTy);
-  } else if (isa<VectorType>(Ty)) {
-    if (LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(type)) {
-      PassInIntegerRegisters(type, ScalarElts, 0, false);
-    } else if (LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(type)) {
-      C.HandleByValArgument(Ty, type);
-      if (Attributes) {
-	*Attributes |= Attribute::ByVal;
-	*Attributes |= 
-	  Attribute::constructAlignmentFromInt(LLVM_BYVAL_ALIGNMENT(type));
-      }
-    } else {
-      C.HandleScalarArgument(Ty, type);
-      ScalarElts.push_back(Ty);
-    }
-  } else if (Ty->isSingleValueType()) {
+  if (Ty->isSingleValueType()) {
     if (Ty->isInteger()) {
       unsigned TypeSize = Ty->getPrimitiveSizeInBits();
 
@@ -141,13 +120,13 @@
       if (TypeSize == 64 && (NumGPR % 2) == 1) {
 	NumGPR++;
 	ScalarElts.push_back(Int32Ty);
-	C.HandlePad(Int32Ty);
+	C->HandlePad(Int32Ty);
       }
 
       if (NumGPR > (NumArgRegs - NumRegs)) {
 	for (unsigned int i = 0; i < NumArgRegs - NumGPR; ++i) {
 	  ScalarElts.push_back(Int32Ty);
-	  C.HandlePad(Int32Ty);
+	  C->HandlePad(Int32Ty);
 	}
       }
     } else if (!(Ty->isFloatingPoint() ||
@@ -156,70 +135,105 @@
       abort();
     }
 
-    C.HandleScalarArgument(Ty, type);
+    C->HandleScalarArgument(Ty, type);
     ScalarElts.push_back(Ty);
-  } else if (LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(type, Ty)) {
-    C.HandleFCAArgument(Ty, type);
-  } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(type, Ty,
-						      C.getCallingConv(),
-						      Elts)) {
-    HOST_WIDE_INT SrcSize = int_size_in_bytes(type);
-
-    // With the SVR4 ABI, the only aggregates which are passed in registers
-    // are _Complex aggregates.
-    assert(TREE_CODE(type) == COMPLEX_TYPE && "Not a _Complex type!");
-
-    switch (SrcSize) {
-    default:
-      abort();
-      break;
-    case 32:
-      // _Complex long double
-      if (NumGPR != 0) {
-	for (unsigned int i = 0; i < NumArgRegs - NumGPR; ++i) {
-	  ScalarElts.push_back(Int32Ty);
-	  C.HandlePad(Int32Ty);
-	}
-      }
-      break;
-    case 16:
-      // _Complex long long
-      // _Complex double
-      if (NumGPR > (NumArgRegs - 4)) {
-	for (unsigned int i = 0; i < NumArgRegs - NumGPR; ++i) {
-	  ScalarElts.push_back(Int32Ty);
-	  C.HandlePad(Int32Ty);
-	}
-      }
-      break;
-    case 8:
-      // _Complex int
-      // _Complex long
-      // _Complex float
+    return true;
+  }
+  if (TREE_CODE(type) == COMPLEX_TYPE) {
+    unsigned SrcSize = int_size_in_bytes(type);
+    unsigned NumRegs = (SrcSize + 3) / 4;
+    std::vector<const Type*> Elts;
 
+    // This looks very strange, but matches the old code.
+    if (SrcSize == 8) {
       // Make sure argument registers are aligned. 64-bit arguments are put in
       // a register pair which starts with an odd register number.
       if (NumGPR % 2 == 1) {
 	NumGPR++;
 	ScalarElts.push_back(Int32Ty);
-	C.HandlePad(Int32Ty);
+	C->HandlePad(Int32Ty);
       }
+    }
 
-      if (NumGPR > (NumArgRegs - 2)) {
-	for (unsigned int i = 0; i < NumArgRegs - NumGPR; ++i) {
-	  ScalarElts.push_back(Int32Ty);
-	  C.HandlePad(Int32Ty);
-	}
+    if (NumGPR > (NumArgRegs - NumRegs)) {
+      for (unsigned int i = 0; i < NumArgRegs - NumGPR; ++i) {
+        ScalarElts.push_back(Int32Ty);
+        C->HandlePad(Int32Ty);
       }
-      break;
-    case 4:
-    case 2:
-      // _Complex short
-      // _Complex char
-      break;
     }
+    for (unsigned int i = 0; i < NumRegs; ++i) {
+      Elts.push_back(Int32Ty);
+    }
+    const StructType *STy = StructType::get(getGlobalContext(), Elts, false);
+    for (unsigned int i = 0; i < NumRegs; ++i) {
+      C->EnterField(i, STy);
+      C->HandleScalarArgument(Int32Ty, 0);
+      ScalarElts.push_back(Int32Ty);
+      C->ExitField();
+    }
+    return true;
+  }
+  return false;
+}
 
-    PassInMixedRegisters(Ty, Elts, ScalarElts);
+/// HandleArgument - This is invoked by the target-independent code for each
+/// argument type passed into the function.  It potentially breaks down the
+/// argument and invokes methods on the client that indicate how its pieces
+/// should be handled.  This handles things like decimating structures into
+/// their fields.
+void SVR4ABI::HandleArgument(tree type, std::vector<const Type*> &ScalarElts,
+			     Attributes *Attributes) {
+  unsigned Size = 0;
+  bool DontCheckAlignment = false;
+  const Type *Ty = ConvertType(type);
+  // Figure out if this field is zero bits wide, e.g. {} or [0 x int].  Do
+  // not include variable sized fields here.
+  std::vector<const Type*> Elts;
+  if (Ty->isVoidTy()) {
+    // Handle void explicitly as an opaque type.
+    const Type *OpTy = OpaqueType::get(getGlobalContext());
+    C.HandleScalarArgument(OpTy, type);
+    ScalarElts.push_back(OpTy);
+  } else if (isPassedByInvisibleReference(type)) { // variable size -> by-ref.
+    const Type *PtrTy = Ty->getPointerTo();
+    C.HandleByInvisibleReferenceArgument(PtrTy, type);
+    ScalarElts.push_back(PtrTy);
+  } else if (isa<VectorType>(Ty)) {
+    if (LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(type)) {
+      PassInIntegerRegisters(type, ScalarElts, 0, false);
+    } else if (LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(type)) {
+      C.HandleByValArgument(Ty, type);
+      if (Attributes) {
+	*Attributes |= Attribute::ByVal;
+	*Attributes |= 
+	  Attribute::constructAlignmentFromInt(LLVM_BYVAL_ALIGNMENT(type));
+      }
+    } else {
+      C.HandleScalarArgument(Ty, type);
+      ScalarElts.push_back(Ty);
+    }
+  } else if (llvm_ppc_try_pass_aggregate_custom(type, ScalarElts, C.getCallingConv(), &C)) {
+    // Nothing to do.
+  } else if (Ty->isSingleValueType()) {
+    C.HandleScalarArgument(Ty, type);
+    ScalarElts.push_back(Ty);
+  } else if (LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(type, Ty)) {
+    C.HandleFCAArgument(Ty, type);
+  } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(type, Ty,
+						      C.getCallingConv(),
+						      Elts)) {
+    if (!LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(Elts, ScalarElts,
+						 C.isShadowReturn(),
+						 C.getCallingConv()))
+      PassInMixedRegisters(Ty, Elts, ScalarElts);
+    else {
+      C.HandleByValArgument(Ty, type);
+      if (Attributes) {
+	*Attributes |= Attribute::ByVal;
+	*Attributes |= 
+	  Attribute::constructAlignmentFromInt(LLVM_BYVAL_ALIGNMENT(type));
+      }
+    }
   } else if (LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(type, Ty)) {
     C.HandleByValArgument(Ty, type);
     if (Attributes) {





More information about the llvm-commits mailing list