[llvm-commits] [llvm-gcc-4.2] r52192 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386.cpp llvm-abi.h
Dale Johannesen
dalej at apple.com
Tue Jun 10 18:13:03 PDT 2008
Author: johannes
Date: Tue Jun 10 20:13:02 2008
New Revision: 52192
URL: http://llvm.org/viewvc/llvm-project?rev=52192&view=rev
Log:
X86-64 ABI compatibility. Words consisting only of
padding can occur in the middle of structs as well as
at the end; handle this with the MixedRegisters mechanism.
Some unions are passed in memory even though they are
converted to a struct consisting only of ints; the
special case looking for the latter is removed.
All compat and struct-layout-1 tests now pass, comparing
llvm-gcc against itself.
Modified:
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
llvm-gcc-4.2/trunk/gcc/llvm-abi.h
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=52192&r1=52191&r2=52192&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Tue Jun 10 20:13:02 2008
@@ -629,13 +629,6 @@
if (Bytes == 0)
return false;
- if (TARGET_64BIT &&
- (Bytes == GET_MODE_SIZE(SImode) || Bytes == GET_MODE_SIZE(DImode))) {
- // 32-bit or 64-bit and all elements are integers, not passed in memory.
- const Type *Ty = ConvertType(TreeType);
- if (llvm_x86_is_all_integer_types(Ty))
- return false;
- }
if (!TARGET_64BIT) {
std::vector<const Type*> Elts;
return !llvm_x86_32_should_pass_aggregate_in_mixed_regs(TreeType, Ty, Elts);
@@ -662,6 +655,9 @@
++NumXMMs;
} else if (Ty->isInteger() || isa<PointerType>(Ty)) {
++NumGPRs;
+ } else if (Ty==Type::VoidTy) {
+ // Padding bytes that are not passed anywhere
+ ;
} else {
// Floating point scalar argument.
assert(Ty->isFloatingPoint() && Ty->isPrimitiveType() &&
@@ -728,6 +724,7 @@
std::vector<const Type*> &Elts){
enum x86_64_reg_class Class[MAX_CLASSES];
enum machine_mode Mode = ix86_getNaturalModeForType(TreeType);
+ bool totallyEmpty = true;
HOST_WIDE_INT Bytes =
(Mode == BLKmode) ? int_size_in_bytes(TreeType) : (int) GET_MODE_SIZE(Mode);
int NumClasses = ix86_ClassifyArgument(Mode, TreeType, Class, 0);
@@ -743,9 +740,11 @@
case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS:
Elts.push_back(Type::Int64Ty);
+ totallyEmpty = false;
Bytes -= 8;
break;
case X86_64_SSE_CLASS:
+ totallyEmpty = false;
// If it's a SSE class argument, then one of the followings are possible:
// 1. 1 x SSE, size is 8: 1 x Double.
// 2. 1 x SSE, size is 4: 1 x Float.
@@ -811,6 +810,7 @@
} else if (Class[i+1] == X86_64_NO_CLASS) {
// padding bytes, don't pass
Elts.push_back(Type::DoubleTy);
+ Elts.push_back(Type::VoidTy);
Bytes -= 16;
} else
assert(0 && "Not yet handled!");
@@ -819,10 +819,12 @@
assert(0 && "Not yet handled!");
break;
case X86_64_SSESF_CLASS:
+ totallyEmpty = false;
Elts.push_back(Type::FloatTy);
Bytes -= 4;
break;
case X86_64_SSEDF_CLASS:
+ totallyEmpty = false;
Elts.push_back(Type::DoubleTy);
Bytes -= 8;
break;
@@ -831,12 +833,16 @@
case X86_64_COMPLEX_X87_CLASS:
return false;
case X86_64_NO_CLASS:
- return false;
+ // Padding bytes that are not passed (unless the entire object consists
+ // of padding)
+ Elts.push_back(Type::VoidTy);
+ Bytes -= 8;
+ break;
default: assert(0 && "Unexpected register class!");
}
}
- return true;
+ return !totallyEmpty;
}
/* On Darwin, vectors which are not MMX nor SSE should be passed as integers. */
Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=52192&r1=52191&r2=52192&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Tue Jun 10 20:13:02 2008
@@ -607,9 +607,20 @@
/// mixed integer, floating point, and vector registers, convert it to a
/// structure containing the specified struct elements in.
void PassInMixedRegisters(tree type, const Type *Ty,
- std::vector<const Type*> &Elts,
+ std::vector<const Type*> &OrigElts,
std::vector<const Type*> &ScalarElts) {
+ // We use VoidTy in OrigElts to mean "this is a word in the aggregate
+ // that occupies storage but has no useful information, and is not passed
+ // anywhere". Happens on x86-64.
+ std::vector<const Type*> Elts(OrigElts);
+ const Type* wordType = getTargetData().getPointerSize() == 4 ? Type::Int32Ty :
+ Type::Int64Ty;
+ for (unsigned i=0, e=Elts.size(); i!=e; ++i)
+ if (OrigElts[i]==Type::VoidTy)
+ Elts[i] = wordType;
+
const StructType *STy = StructType::get(Elts, false);
+
unsigned Size = getTargetData().getABITypeSize(STy);
const StructType *InSTy = dyn_cast<StructType>(Ty);
unsigned InSize = 0;
@@ -627,13 +638,15 @@
}
}
for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
- C.EnterField(i, STy);
- unsigned RealSize = 0;
- if (LastEltSizeDiff && i == (e - 1))
- RealSize = LastEltSizeDiff;
- C.HandleScalarArgument(Elts[i], 0, RealSize);
- ScalarElts.push_back(Elts[i]);
- C.ExitField();
+ if (OrigElts[i] != Type::VoidTy) {
+ C.EnterField(i, STy);
+ unsigned RealSize = 0;
+ if (LastEltSizeDiff && i == (e - 1))
+ RealSize = LastEltSizeDiff;
+ C.HandleScalarArgument(Elts[i], 0, RealSize);
+ ScalarElts.push_back(Elts[i]);
+ C.ExitField();
+ }
}
}
};
More information about the llvm-commits
mailing list