aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-06-16 18:50:49 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-06-16 18:50:49 +0000
commit385f5a99ecc7fee48a7539bc63d3e1d3b5089c0d (patch)
tree65b86d2fd305c5556f20201a37308a259308ea72 /lib/Target/ARM
parent29327953097693a0376eaca021046d99c01f9f89 (diff)
downloadexternal_llvm-385f5a99ecc7fee48a7539bc63d3e1d3b5089c0d.zip
external_llvm-385f5a99ecc7fee48a7539bc63d3e1d3b5089c0d.tar.gz
external_llvm-385f5a99ecc7fee48a7539bc63d3e1d3b5089c0d.tar.bz2
Address review comments: add 3 ARM calling conventions.
Dispatch C calling conv. to one of these conventions based on target triple and subtarget features. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73530 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/ARMCallingConv.td27
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp41
-rw-r--r--lib/Target/ARM/ARMISelLowering.h1
3 files changed, 35 insertions, 34 deletions
diff --git a/lib/Target/ARM/ARMCallingConv.td b/lib/Target/ARM/ARMCallingConv.td
index f126760..47151e6 100644
--- a/lib/Target/ARM/ARMCallingConv.td
+++ b/lib/Target/ARM/ARMCallingConv.td
@@ -17,11 +17,6 @@ class CCIfSubtarget<string F, CCAction A>:
class CCIfAlign<string Align, CCAction A>:
CCIf<!strconcat("ArgFlags.getOrigAlign() == ", Align), A>;
-/// CCIfFloatABI - Match of the float ABI and the arg. ABIType may be "Hard" or
-/// "Soft".
-class CCIfFloatABI<string ABIType, CCAction A>:
- CCIf<!strconcat("llvm::FloatABIType == llvm::FloatABI::", ABIType), A>;
-
//===----------------------------------------------------------------------===//
// ARM APCS Calling Convention
//===----------------------------------------------------------------------===//
@@ -105,25 +100,3 @@ def RetCC_ARM_AAPCS_VFP : CallingConv<[
S9, S10, S11, S12, S13, S14, S15]>>,
CCDelegateTo<RetCC_ARM_AAPCS_Common>
]>;
-
-//===----------------------------------------------------------------------===//
-// ARM Calling Convention Dispatch
-//===----------------------------------------------------------------------===//
-
-def CC_ARM : CallingConv<[
- CCIfSubtarget<"isAAPCS_ABI()",
- CCIfSubtarget<"hasVFP2()",
- CCIfFloatABI<"Hard",
- CCDelegateTo<CC_ARM_AAPCS_VFP>>>>,
- CCIfSubtarget<"isAAPCS_ABI()", CCDelegateTo<CC_ARM_AAPCS>>,
- CCDelegateTo<CC_ARM_APCS>
-]>;
-
-def RetCC_ARM : CallingConv<[
- CCIfSubtarget<"isAAPCS_ABI()",
- CCIfSubtarget<"hasVFP2()",
- CCIfFloatABI<"Hard",
- CCDelegateTo<RetCC_ARM_AAPCS_VFP>>>>,
- CCIfSubtarget<"isAAPCS_ABI()", CCDelegateTo<RetCC_ARM_AAPCS>>,
- CCDelegateTo<RetCC_ARM_APCS>
-]>;
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index ec8bd1f..975eb23 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -415,7 +415,7 @@ static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
ARM::NoRegister };
unsigned Reg = State.AllocateReg(HiRegList, LoRegList, 4);
- if (Reg == 0)
+ if (Reg == 0)
return false; // we didn't handle it
unsigned i;
@@ -487,6 +487,33 @@ static bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
State);
}
+/// CCAssignFnForNode - Selects the correct CCAssignFn for a the
+/// given CallingConvention value.
+CCAssignFn *ARMTargetLowering::CCAssignFnForNode(unsigned CC,
+ bool Return) const {
+ switch (CC) {
+ default:
+ assert(0 && "Unsupported calling convention");
+ case CallingConv::C:
+ case CallingConv::Fast:
+ // Use target triple & subtarget features to do actual dispatch.
+ if (Subtarget->isAAPCS_ABI()) {
+ if (Subtarget->hasVFP2() &&
+ FloatABIType == FloatABI::Hard)
+ return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
+ else
+ return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
+ } else
+ return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
+ case CallingConv::ARM_AAPCS_VFP:
+ return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
+ case CallingConv::ARM_AAPCS:
+ return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
+ case CallingConv::ARM_APCS:
+ return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
+ }
+}
+
/// LowerCallResult - Lower the result values of an ISD::CALL into the
/// appropriate copies out of appropriate physical registers. This assumes that
/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call
@@ -501,7 +528,8 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall,
SmallVector<CCValAssign, 16> RVLocs;
bool isVarArg = TheCall->isVarArg();
CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs);
- CCInfo.AnalyzeCallResult(TheCall, RetCC_ARM);
+ CCInfo.AnalyzeCallResult(TheCall,
+ CCAssignFnForNode(CallingConv, /* Return*/ true));
SmallVector<SDValue, 8> ResultVals;
@@ -586,8 +614,6 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
MVT RetVT = TheCall->getRetValType(0);
SDValue Chain = TheCall->getChain();
unsigned CC = TheCall->getCallingConv();
- assert((CC == CallingConv::C ||
- CC == CallingConv::Fast) && "unknown calling convention");
bool isVarArg = TheCall->isVarArg();
SDValue Callee = TheCall->getCallee();
DebugLoc dl = TheCall->getDebugLoc();
@@ -595,7 +621,7 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
- CCInfo.AnalyzeCallOperands(TheCall, CC_ARM);
+ CCInfo.AnalyzeCallOperands(TheCall, CCAssignFnForNode(CC, /* Return*/ false));
// Get a count of how many bytes are to be pushed on the stack.
unsigned NumBytes = CCInfo.getNextStackOffset();
@@ -788,7 +814,7 @@ SDValue ARMTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs);
// Analyze return values of ISD::RET.
- CCInfo.AnalyzeReturn(Op.getNode(), RetCC_ARM);
+ CCInfo.AnalyzeReturn(Op.getNode(), CCAssignFnForNode(CC, /* Return */ true));
// If this is the first return lowered for this function, add
// the regs to the liveout set for the function.
@@ -1085,7 +1111,8 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) {
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
- CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_ARM);
+ CCInfo.AnalyzeFormalArguments(Op.getNode(),
+ CCAssignFnForNode(CC, /* Return*/ false));
SmallVector<SDValue, 16> ArgValues;
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index 2dab2db..8f53e39 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -151,6 +151,7 @@ namespace llvm {
///
unsigned ARMPCLabelIndex;
+ CCAssignFn *CCAssignFnForNode(unsigned CC, bool Return) const;
SDValue LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG,
const SDValue &StackPtr, const CCValAssign &VA,
SDValue Chain, SDValue Arg, ISD::ArgFlagsTy Flags);