mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-17 23:44:43 +00:00
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
This commit is contained in:
parent
2932795309
commit
385f5a99ec
@ -57,7 +57,18 @@ namespace CallingConv {
|
||||
/// X86_FastCall - 'fast' analog of X86_StdCall. Passes first two arguments
|
||||
/// in ECX:EDX registers, others - via stack. Callee is responsible for
|
||||
/// stack cleaning.
|
||||
X86_FastCall = 65
|
||||
X86_FastCall = 65,
|
||||
|
||||
/// ARM_APCS - ARM Procedure Calling Standard calling convention (obsolete,
|
||||
/// but still used on some targets).
|
||||
ARM_APCS = 66,
|
||||
|
||||
/// ARM_AAPCS - ARM Architecture Procedure Calling Standard calling
|
||||
/// convention (aka EABI). Soft float variant.
|
||||
ARM_AAPCS = 67,
|
||||
|
||||
/// ARM_AAPCS_VFP - Same as ARM_AAPCS, but uses hard floating point ABI.
|
||||
ARM_AAPCS_VFP = 68
|
||||
};
|
||||
} // End CallingConv namespace
|
||||
|
||||
|
@ -526,6 +526,10 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
KEYWORD(coldcc);
|
||||
KEYWORD(x86_stdcallcc);
|
||||
KEYWORD(x86_fastcallcc);
|
||||
KEYWORD(arm_apcscc);
|
||||
KEYWORD(arm_aapcscc);
|
||||
KEYWORD(arm_aapcs_vfpcc);
|
||||
|
||||
KEYWORD(cc);
|
||||
KEYWORD(c);
|
||||
|
||||
|
@ -808,8 +808,11 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) {
|
||||
/// ::= 'coldcc'
|
||||
/// ::= 'x86_stdcallcc'
|
||||
/// ::= 'x86_fastcallcc'
|
||||
/// ::= 'arm_apcscc'
|
||||
/// ::= 'arm_aapcscc'
|
||||
/// ::= 'arm_aapcs_vfpcc'
|
||||
/// ::= 'cc' UINT
|
||||
///
|
||||
///
|
||||
bool LLParser::ParseOptionalCallingConv(unsigned &CC) {
|
||||
switch (Lex.getKind()) {
|
||||
default: CC = CallingConv::C; return false;
|
||||
@ -818,6 +821,9 @@ bool LLParser::ParseOptionalCallingConv(unsigned &CC) {
|
||||
case lltok::kw_coldcc: CC = CallingConv::Cold; break;
|
||||
case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break;
|
||||
case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break;
|
||||
case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break;
|
||||
case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break;
|
||||
case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
|
||||
case lltok::kw_cc: Lex.Lex(); return ParseUInt32(CC);
|
||||
}
|
||||
Lex.Lex();
|
||||
|
@ -60,7 +60,9 @@ namespace lltok {
|
||||
kw_gc,
|
||||
kw_c,
|
||||
|
||||
kw_cc, kw_ccc, kw_fastcc, kw_coldcc, kw_x86_stdcallcc, kw_x86_fastcallcc,
|
||||
kw_cc, kw_ccc, kw_fastcc, kw_coldcc,
|
||||
kw_x86_stdcallcc, kw_x86_fastcallcc,
|
||||
kw_arm_apcscc, kw_arm_aapcscc, kw_arm_aapcs_vfpcc,
|
||||
|
||||
kw_signext,
|
||||
kw_zeroext,
|
||||
|
@ -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>
|
||||
]>;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1384,7 +1384,10 @@ void AssemblyWriter::printFunction(const Function *F) {
|
||||
case CallingConv::Fast: Out << "fastcc "; break;
|
||||
case CallingConv::Cold: Out << "coldcc "; break;
|
||||
case CallingConv::X86_StdCall: Out << "x86_stdcallcc "; break;
|
||||
case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break;
|
||||
case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break;
|
||||
case CallingConv::ARM_APCS: Out << "arm_apcscc "; break;
|
||||
case CallingConv::ARM_AAPCS: Out << "arm_aapcscc "; break;
|
||||
case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break;
|
||||
default: Out << "cc" << F->getCallingConv() << " "; break;
|
||||
}
|
||||
|
||||
@ -1640,7 +1643,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
|
||||
case CallingConv::Fast: Out << " fastcc"; break;
|
||||
case CallingConv::Cold: Out << " coldcc"; break;
|
||||
case CallingConv::X86_StdCall: Out << " x86_stdcallcc"; break;
|
||||
case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
|
||||
case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
|
||||
case CallingConv::ARM_APCS: Out << " arm_apcscc "; break;
|
||||
case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break;
|
||||
case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
|
||||
default: Out << " cc" << CI->getCallingConv(); break;
|
||||
}
|
||||
|
||||
@ -1688,6 +1694,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
|
||||
case CallingConv::Cold: Out << " coldcc"; break;
|
||||
case CallingConv::X86_StdCall: Out << " x86_stdcallcc"; break;
|
||||
case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
|
||||
case CallingConv::ARM_APCS: Out << " arm_apcscc "; break;
|
||||
case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break;
|
||||
case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
|
||||
default: Out << " cc" << II->getCallingConv(); break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user