|
@@ -424,7 +424,8 @@ class X86_32ABIInfo : public ABIInfo {
|
|
return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
|
|
return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
|
|
}
|
|
}
|
|
|
|
|
|
- static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
|
|
|
|
|
|
+ static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context,
|
|
|
|
+ unsigned callingConvention);
|
|
|
|
|
|
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
|
|
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
|
|
/// such that the argument will be passed in memory.
|
|
/// such that the argument will be passed in memory.
|
|
@@ -435,11 +436,13 @@ class X86_32ABIInfo : public ABIInfo {
|
|
|
|
|
|
public:
|
|
public:
|
|
|
|
|
|
- ABIArgInfo classifyReturnType(QualType RetTy) const;
|
|
|
|
|
|
+ ABIArgInfo classifyReturnType(QualType RetTy,
|
|
|
|
+ unsigned callingConvention) const;
|
|
ABIArgInfo classifyArgumentType(QualType RetTy) const;
|
|
ABIArgInfo classifyArgumentType(QualType RetTy) const;
|
|
|
|
|
|
virtual void computeInfo(CGFunctionInfo &FI) const {
|
|
virtual void computeInfo(CGFunctionInfo &FI) const {
|
|
- FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
|
|
|
|
|
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
|
|
|
|
+ FI.getCallingConvention());
|
|
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
|
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
|
it != ie; ++it)
|
|
it != ie; ++it)
|
|
it->info = classifyArgumentType(it->type);
|
|
it->info = classifyArgumentType(it->type);
|
|
@@ -485,7 +488,8 @@ public:
|
|
/// shouldReturnTypeInRegister - Determine if the given type should be
|
|
/// shouldReturnTypeInRegister - Determine if the given type should be
|
|
/// passed in a register (for the Darwin ABI).
|
|
/// passed in a register (for the Darwin ABI).
|
|
bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
|
|
bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
|
|
- ASTContext &Context) {
|
|
|
|
|
|
+ ASTContext &Context,
|
|
|
|
+ unsigned callingConvention) {
|
|
uint64_t Size = Context.getTypeSize(Ty);
|
|
uint64_t Size = Context.getTypeSize(Ty);
|
|
|
|
|
|
// Type must be register sized.
|
|
// Type must be register sized.
|
|
@@ -510,7 +514,8 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
|
|
|
|
|
|
// Arrays are treated like records.
|
|
// Arrays are treated like records.
|
|
if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty))
|
|
if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty))
|
|
- return shouldReturnTypeInRegister(AT->getElementType(), Context);
|
|
|
|
|
|
+ return shouldReturnTypeInRegister(AT->getElementType(), Context,
|
|
|
|
+ callingConvention);
|
|
|
|
|
|
// Otherwise, it must be a record type.
|
|
// Otherwise, it must be a record type.
|
|
const RecordType *RT = Ty->getAs<RecordType>();
|
|
const RecordType *RT = Ty->getAs<RecordType>();
|
|
@@ -518,6 +523,13 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
|
|
|
|
|
|
// FIXME: Traverse bases here too.
|
|
// FIXME: Traverse bases here too.
|
|
|
|
|
|
|
|
+ // For thiscall conventions, structures will never be returned in
|
|
|
|
+ // a register. This is for compatibility with the MSVC ABI
|
|
|
|
+ if (callingConvention == llvm::CallingConv::X86_ThisCall &&
|
|
|
|
+ RT->isStructureType()) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
// Structure types are passed in register if all fields would be
|
|
// Structure types are passed in register if all fields would be
|
|
// passed in a register.
|
|
// passed in a register.
|
|
for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(),
|
|
for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(),
|
|
@@ -529,14 +541,15 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
|
|
continue;
|
|
continue;
|
|
|
|
|
|
// Check fields recursively.
|
|
// Check fields recursively.
|
|
- if (!shouldReturnTypeInRegister(FD->getType(), Context))
|
|
|
|
|
|
+ if (!shouldReturnTypeInRegister(FD->getType(), Context,
|
|
|
|
+ callingConvention))
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
-
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy) const {
|
|
|
|
|
|
+ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
|
|
|
|
+ unsigned callingConvention) const {
|
|
if (RetTy->isVoidType())
|
|
if (RetTy->isVoidType())
|
|
return ABIArgInfo::getIgnore();
|
|
return ABIArgInfo::getIgnore();
|
|
|
|
|
|
@@ -583,7 +596,8 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy) const {
|
|
|
|
|
|
// Small structures which are register sized are generally returned
|
|
// Small structures which are register sized are generally returned
|
|
// in a register.
|
|
// in a register.
|
|
- if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) {
|
|
|
|
|
|
+ if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(),
|
|
|
|
+ callingConvention)) {
|
|
uint64_t Size = getContext().getTypeSize(RetTy);
|
|
uint64_t Size = getContext().getTypeSize(RetTy);
|
|
|
|
|
|
// As a special-case, if the struct is a "single-element" struct, and
|
|
// As a special-case, if the struct is a "single-element" struct, and
|