Add fastcc cc: pass and return VFP / NEON values in registers. Controlled by -arm-fastcc for now.

llvm-svn: 117119
This commit is contained in:
Evan Cheng 2010-10-22 18:23:05 +00:00
parent 5bfb8ee64e
commit 08dd8c8295
2 changed files with 51 additions and 12 deletions

View File

@ -52,6 +52,34 @@ def RetCC_ARM_APCS : CallingConv<[
CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>> CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>>
]>; ]>;
//===----------------------------------------------------------------------===//
// ARM APCS Calling Convention for FastCC (when VFP2 or later is available)
//===----------------------------------------------------------------------===//
def FastCC_ARM_APCS : CallingConv<[
// Handle all vector types as either f64 or v2f64.
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
S9, S10, S11, S12, S13, S14, S15]>>,
CCDelegateTo<CC_ARM_APCS>
]>;
def RetFastCC_ARM_APCS : CallingConv<[
// Handle all vector types as either f64 or v2f64.
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
S9, S10, S11, S12, S13, S14, S15]>>,
CCDelegateTo<RetCC_ARM_APCS>
]>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// ARM AAPCS (EABI) Calling Convention, common parts // ARM AAPCS (EABI) Calling Convention, common parts
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -105,6 +133,7 @@ def RetCC_ARM_AAPCS : CallingConv<[
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// ARM AAPCS-VFP (EABI) Calling Convention // ARM AAPCS-VFP (EABI) Calling Convention
// Also used for FastCC (when VFP2 or later is available)
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def CC_ARM_AAPCS_VFP : CallingConv<[ def CC_ARM_AAPCS_VFP : CallingConv<[

View File

@ -69,6 +69,10 @@ ARMInterworking("arm-interworking", cl::Hidden,
cl::desc("Enable / disable ARM interworking (for debugging only)"), cl::desc("Enable / disable ARM interworking (for debugging only)"),
cl::init(true)); cl::init(true));
static cl::opt<bool>
ARMFastCC("arm-fastcc", cl::Hidden,
cl::desc("Use AAPCS / AAPCS-VFP calling conventions for fastcc"));
void ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT, void ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT,
EVT PromotedBitwiseVT) { EVT PromotedBitwiseVT) {
if (VT != PromotedLdStVT) { if (VT != PromotedLdStVT) {
@ -955,23 +959,29 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
switch (CC) { switch (CC) {
default: default:
llvm_unreachable("Unsupported calling convention"); llvm_unreachable("Unsupported calling convention");
case CallingConv::C:
case CallingConv::Fast: case CallingConv::Fast:
if (ARMFastCC && Subtarget->hasVFP2() && !isVarArg) {
if (!Subtarget->isAAPCS_ABI())
return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
// For AAPCS ABI targets, just use VFP variant of the calling convention.
return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
}
// Fallthrough
case CallingConv::C: {
// Use target triple & subtarget features to do actual dispatch. // Use target triple & subtarget features to do actual dispatch.
if (Subtarget->isAAPCS_ABI()) { if (!Subtarget->isAAPCS_ABI())
if (Subtarget->hasVFP2() && return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
FloatABIType == FloatABI::Hard && !isVarArg) else if (Subtarget->hasVFP2() &&
return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); FloatABIType == FloatABI::Hard && !isVarArg)
else return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
} else }
return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
case CallingConv::ARM_AAPCS_VFP: case CallingConv::ARM_AAPCS_VFP:
return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
case CallingConv::ARM_AAPCS: case CallingConv::ARM_AAPCS:
return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
case CallingConv::ARM_APCS: case CallingConv::ARM_APCS:
return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
} }
} }