diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-06-16 18:50:49 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-06-16 18:50:49 +0000 |
commit | 1395c2ca582e562e06227a76f07f0c47cf2447ea (patch) | |
tree | 65b86d2fd305c5556f20201a37308a259308ea72 | |
parent | c96184ada49f4f8329506634d267a5ddd70a5d41 (diff) | |
download | external_llvm-1395c2ca582e562e06227a76f07f0c47cf2447ea.zip external_llvm-1395c2ca582e562e06227a76f07f0c47cf2447ea.tar.gz external_llvm-1395c2ca582e562e06227a76f07f0c47cf2447ea.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
-rw-r--r-- | include/llvm/CallingConv.h | 13 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 4 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 8 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 4 | ||||
-rw-r--r-- | lib/Target/ARM/ARMCallingConv.td | 27 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 41 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.h | 1 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 13 |
8 files changed, 72 insertions, 39 deletions
diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h index 072f7c3..318ea28 100644 --- a/include/llvm/CallingConv.h +++ b/include/llvm/CallingConv.h @@ -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 diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index c5190ef..b3f7cdb 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -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); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index e26e045..909370c 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -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(); diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 9335d19..cff89f8 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -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, 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); diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 6b369b6..73b1ed6 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -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; } |