[cfe-commits] r63305 - /cfe/trunk/lib/CodeGen/CGCall.cpp
Daniel Dunbar
daniel at zuster.org
Thu Jan 29 01:42:07 PST 2009
Author: ddunbar
Date: Thu Jan 29 03:42:07 2009
New Revision: 63305
URL: http://llvm.org/viewvc/llvm-project?rev=63305&view=rev
Log:
x86_64 ABI: Handle fields / complex components which straddle
eightbyte boundaries.
- Getting harder to test now that we handle cases gcc & llvm-gcc get
wrong ( { _Complex char; _Complex int; } is a good example). :)
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=63305&r1=63304&r2=63305&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Jan 29 03:42:07 2009
@@ -411,6 +411,9 @@
///
/// \param Lo - The classification for the low word of the type.
/// \param Hi - The classification for the high word of the type.
+ /// \param OffsetBase - The byte position of the type in the root
+ /// structure. Some parameters are classified different depending on
+ /// whether they straddle an eightbyte boundary.
///
/// If a word is unused its result will be NoClass; if a type should
/// be passed in Memory then at least the classification of \arg Lo
@@ -420,7 +423,7 @@
///
/// If the \arg Lo class is ComplexX87, then the \arg Hi class will
/// be NoClass.
- void classify(QualType T, ASTContext &Context,
+ void classify(QualType T, ASTContext &Context, unsigned OffsetBase,
Class &Lo, Class &Hi) const;
public:
@@ -434,6 +437,7 @@
void X86_64ABIInfo::classify(QualType Ty,
ASTContext &Context,
+ unsigned OffsetBase,
Class &Lo, Class &Hi) const {
Lo = Memory;
Hi = NoClass;
@@ -483,6 +487,13 @@
Lo = Hi = SSE;
else if (ET == Context.LongDoubleTy)
Lo = ComplexX87;
+
+ // If this complex type crosses an eightbyte boundary then it
+ // should be split.
+ unsigned EB_Real = (OffsetBase) >> 3;
+ unsigned EB_Imag = (OffsetBase + Context.getTypeSize(ET)) >> 3;
+ if (Hi == NoClass && EB_Real != EB_Imag)
+ Hi = Lo;
} else if (const RecordType *RT = Ty->getAsRecordType()) {
unsigned Size = Context.getTypeSize(Ty);
@@ -504,7 +515,7 @@
unsigned idx = 0;
for (RecordDecl::field_iterator i = RD->field_begin(),
e = RD->field_end(); i != e; ++i, ++idx) {
- unsigned Offset = Layout.getFieldOffset(idx);
+ unsigned Offset = OffsetBase + Layout.getFieldOffset(idx);
// AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
// fields, it has class MEMORY.
@@ -523,7 +534,7 @@
// Classify this field.
Class FieldLo, FieldHi;
- classify(i->getType(), Context, FieldLo, FieldHi);
+ classify(i->getType(), Context, Offset, FieldLo, FieldHi);
// Merge the lo field classifcation.
//
@@ -593,7 +604,7 @@
// AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the
// classification algorithm.
X86_64ABIInfo::Class Lo, Hi;
- classify(RetTy, Context, Lo, Hi);
+ classify(RetTy, Context, 0, Lo, Hi);
const llvm::Type *ResType = 0;
switch (Lo) {
More information about the cfe-commits
mailing list