[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