aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-10-24 01:58:58 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-10-24 01:58:58 +0000
commitb6932692234eba2472ef85a38434496e9342fd38 (patch)
tree9693a70c02dbbd0ea97a491e467a73490055ab03 /lib/CodeGen
parent6d919fb67bf6aa3db09608fb2948b558977c6929 (diff)
Add inreg markers with the x86_fastcallcc calling convention.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166537 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/TargetInfo.cpp49
1 files changed, 39 insertions, 10 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 6a929a17cc..534c8f685d 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -528,8 +528,10 @@ class X86_32ABIInfo : public ABIInfo {
Class classify(QualType Ty) const;
ABIArgInfo classifyReturnType(QualType RetTy,
unsigned callingConvention) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs) const;
- bool shouldUseInReg(QualType Ty, unsigned &FreeRegs) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs,
+ bool IsFastCall) const;
+ bool shouldUseInReg(QualType Ty, unsigned &FreeRegs,
+ bool IsFastCall) const;
public:
@@ -804,12 +806,14 @@ X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const {
return Integer;
}
-bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs) const {
+bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
+ bool IsFastCall) const {
Class C = classify(Ty);
if (C == Float)
return false;
- unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
+ unsigned Size = getContext().getTypeSize(Ty);
+ unsigned SizeInRegs = (Size + 31) / 32;
if (SizeInRegs == 0)
return false;
@@ -820,11 +824,29 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs) const {
}
FreeRegs -= SizeInRegs;
+
+ if (IsFastCall) {
+ if (Size > 32)
+ return false;
+
+ if (Ty->isIntegralOrEnumerationType())
+ return true;
+
+ if (Ty->isPointerType())
+ return true;
+
+ if (Ty->isReferenceType())
+ return true;
+
+ return false;
+ }
+
return true;
}
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
- unsigned &FreeRegs) const {
+ unsigned &FreeRegs,
+ bool IsFastCall) const {
// FIXME: Set alignment on indirect arguments.
if (isAggregateTypeForABI(Ty)) {
// Structures with flexible arrays are always indirect.
@@ -842,7 +864,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
- if (shouldUseInReg(Ty, FreeRegs)) {
+ if (shouldUseInReg(Ty, FreeRegs, IsFastCall)) {
unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
llvm::LLVMContext &LLVMContext = getVMContext();
llvm::Type *Int32 = llvm::Type::getInt32Ty(LLVMContext);
@@ -892,7 +914,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
- bool InReg = shouldUseInReg(Ty, FreeRegs);
+ bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall);
if (Ty->isPromotableIntegerType()) {
if (InReg)
@@ -908,8 +930,15 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
FI.getCallingConvention());
- unsigned FreeRegs = FI.getHasRegParm() ? FI.getRegParm() :
- DefaultNumRegisterParameters;
+ unsigned CC = FI.getCallingConvention();
+ bool IsFastCall = CC == llvm::CallingConv::X86_FastCall;
+ unsigned FreeRegs;
+ if (IsFastCall)
+ FreeRegs = 2;
+ else if (FI.getHasRegParm())
+ FreeRegs = FI.getRegParm();
+ else
+ FreeRegs = DefaultNumRegisterParameters;
// If the return value is indirect, then the hidden argument is consuming one
// integer register.
@@ -923,7 +952,7 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it)
- it->info = classifyArgumentType(it->type, FreeRegs);
+ it->info = classifyArgumentType(it->type, FreeRegs, IsFastCall);
}
llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,