void classify(QualType T, ASTContext &Context, uint64_t OffsetBase,
Class &Lo, Class &Hi) const;
+ /// getCoerceResult - Given a source type \arg Ty and an LLVM type
+ /// to coerce to, chose the best way to pass Ty in the same place
+ /// that \arg CoerceTo would be passed, but while keeping the
+ /// emitted code as simple as possible.
+ ///
+ /// FIXME: Note, this should be cleaned up to just take an
+ /// enumeration of all the ways we might want to pass things,
+ /// instead of constructing an LLVM type. This makes this code more
+ /// explicit, and it makes it clearer that we are also doing this
+ /// for correctness in the case of passing scalar types.
+ ABIArgInfo getCoerceResult(QualType Ty,
+ const llvm::Type *CoerceTo,
+ ASTContext &Context) const;
+
ABIArgInfo classifyReturnType(QualType RetTy,
ASTContext &Context) const;
}
}
+ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
+ const llvm::Type *CoerceTo,
+ ASTContext &Context) const {
+ if (CoerceTo == llvm::Type::Int64Ty) {
+ // Integer and pointer types will end up in a general purpose
+ // register.
+ if (Ty->isIntegerType() || Ty->isPointerType())
+ return ABIArgInfo::getDirect();
+ } else if (CoerceTo == llvm::Type::DoubleTy) {
+ // Float and double end up in a single SSE reg.
+ if (Ty == Context.FloatTy || Ty == Context.DoubleTy)
+ return ABIArgInfo::getDirect();
+ }
+
+ return ABIArgInfo::getCoerce(CoerceTo);
+}
ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
ASTContext &Context) const {
break;
}
- return ABIArgInfo::getCoerce(ResType);
+ return getCoerceResult(RetTy, ResType, Context);
}
ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, ASTContext &Context,
break;
}
- return ABIArgInfo::getCoerce(ResType);
+ return getCoerceResult(Ty, ResType, Context);
}
void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context) const {
--- /dev/null
+// RUN: clang -triple x86_64-unknown-unknown -emit-llvm -o %t %s &&
+// RUN: grep 'define signext i8 @f0()' %t &&
+// RUN: grep 'define signext i16 @f1()' %t &&
+// RUN: grep 'define i32 @f2()' %t &&
+// RUN: grep 'define float @f3()' %t &&
+// RUN: grep 'define double @f4()' %t &&
+// RUN: grep 'define x86_fp80 @f5()' %t &&
+// RUN: grep 'define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8\* %a4)' %t
+
+char f0(void) {
+}
+
+short f1(void) {
+}
+
+int f2(void) {
+}
+
+float f3(void) {
+}
+
+double f4(void) {
+}
+
+long double f5(void) {
+}
+
+void f6(char a0, short a1, int a2, long long a3, void *a4) {
+}