///
/// \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
///
/// 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:
void X86_64ABIInfo::classify(QualType Ty,
ASTContext &Context,
+ unsigned OffsetBase,
Class &Lo, Class &Hi) const {
Lo = Memory;
Hi = NoClass;
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);
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.
// Classify this field.
Class FieldLo, FieldHi;
- classify(i->getType(), Context, FieldLo, FieldHi);
+ classify(i->getType(), Context, Offset, FieldLo, FieldHi);
// Merge the lo field classifcation.
//
// 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) {