diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-08-14 20:10:52 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-08-14 20:10:52 +0000 |
commit | 72977a45a8ad9d9524c9b49399e89fb9a3a676ed (patch) | |
tree | c55553467012faa67e7cbf7d9d59fff93516a821 | |
parent | e6c835f42418c0fae6b63908d3c576a26d64cab2 (diff) | |
download | external_llvm-72977a45a8ad9d9524c9b49399e89fb9a3a676ed.zip external_llvm-72977a45a8ad9d9524c9b49399e89fb9a3a676ed.tar.gz external_llvm-72977a45a8ad9d9524c9b49399e89fb9a3a676ed.tar.bz2 |
Allow targets to specify their choice of calling conventions per
libcall. Take advantage of this in the ARM backend to rectify broken
choice of CC when hard float is in effect. PIC16 may want to see if
it could be of use in MakePIC16Libcall, which works unchanged.
Patch by Sandeep!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79033 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 17 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 9 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 9 | ||||
-rw-r--r-- | lib/Target/CellSPU/SPUISelLowering.cpp | 2 |
7 files changed, 44 insertions, 6 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 5a05c8c..fda362d 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -22,6 +22,7 @@ #ifndef LLVM_TARGET_TARGETLOWERING_H #define LLVM_TARGET_TARGETLOWERING_H +#include "llvm/CallingConv.h" #include "llvm/InlineAsm.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/RuntimeLibcalls.h" @@ -1539,6 +1540,18 @@ public: return CmpLibcallCCs[Call]; } + /// setLibcallCallingConv - Set the CallingConv that should be used for the + /// specified libcall. + void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) { + LibcallCallingConvs[Call] = CC; + } + + /// getLibcallCallingConv - Get the CallingConv that should be used for the + /// specified libcall. + CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const { + return LibcallCallingConvs[Call]; + } + private: TargetMachine &TM; const TargetData *TD; @@ -1705,6 +1718,10 @@ private: /// of each of the comparison libcall against zero. ISD::CondCode CmpLibcallCCs[RTLIB::UNKNOWN_LIBCALL]; + /// LibcallCallingConvs - Stores the CallingConv that should be used for each + /// libcall. + CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL]; + protected: /// When lowering \@llvm.memset this field specifies the maximum number of /// store operations that may be substituted for the call to memset. Targets diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index ab4ebef..66469ef 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1869,7 +1869,7 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, const Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, - 0, CallingConv::C, false, + 0, TLI.getLibcallCallingConv(LC), false, /*isReturnValueUsed=*/true, Callee, Args, DAG, Node->getDebugLoc()); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 11ec9f1..1518317 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -1019,7 +1019,7 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, EVT RetVT, const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); std::pair<SDValue,SDValue> CallInfo = TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, - false, 0, CallingConv::C, false, + false, 0, TLI.getLibcallCallingConv(LC), false, /*isReturnValueUsed=*/true, Callee, Args, DAG, dl); return CallInfo.first; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index afcbc09..5d4717a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3390,7 +3390,8 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst, // FIXME: pass in DebugLoc std::pair<SDValue,SDValue> CallResult = TLI.LowerCallTo(Chain, Type::getVoidTy(*getContext()), - false, false, false, false, 0, CallingConv::C, false, + false, false, false, false, 0, + TLI.getLibcallCallingConv(RTLIB::MEMCPY), false, /*isReturnValueUsed=*/false, getExternalSymbol(TLI.getLibcallName(RTLIB::MEMCPY), TLI.getPointerTy()), @@ -3438,7 +3439,8 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst, // FIXME: pass in DebugLoc std::pair<SDValue,SDValue> CallResult = TLI.LowerCallTo(Chain, Type::getVoidTy(*getContext()), - false, false, false, false, 0, CallingConv::C, false, + false, false, false, false, 0, + TLI.getLibcallCallingConv(RTLIB::MEMMOVE), false, /*isReturnValueUsed=*/false, getExternalSymbol(TLI.getLibcallName(RTLIB::MEMMOVE), TLI.getPointerTy()), @@ -3496,7 +3498,8 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst, // FIXME: pass in DebugLoc std::pair<SDValue,SDValue> CallResult = TLI.LowerCallTo(Chain, Type::getVoidTy(*getContext()), - false, false, false, false, 0, CallingConv::C, false, + false, false, false, false, 0, + TLI.getLibcallCallingConv(RTLIB::MEMSET), false, /*isReturnValueUsed=*/false, getExternalSymbol(TLI.getLibcallName(RTLIB::MEMSET), TLI.getPointerTy()), diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 767238e..3414fee 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -247,6 +247,14 @@ static void InitLibcallNames(const char **Names) { Names[RTLIB::UNWIND_RESUME] = "_Unwind_Resume"; } +/// InitLibcallCallingConvs - Set default libcall CallingConvs. +/// +static void InitLibcallCallingConvs(CallingConv::ID *CCs) { + for (int i = 0; i < RTLIB::UNKNOWN_LIBCALL; ++i) { + CCs[i] = CallingConv::C; + } +} + /// getFPEXT - Return the FPEXT_*_* value for the given types, or /// UNKNOWN_LIBCALL if there is none. RTLIB::Libcall RTLIB::getFPEXT(EVT OpVT, EVT RetVT) { @@ -520,6 +528,7 @@ TargetLowering::TargetLowering(TargetMachine &tm,TargetLoweringObjectFile *tlof) InitLibcallNames(LibcallRoutineNames); InitCmpLibcallCCs(CmpLibcallCCs); + InitLibcallCallingConvs(LibcallCallingConvs); // Tell Legalize whether the assembler supports DEBUG_LOC. const TargetAsmInfo *TASM = TM.getTargetAsmInfo(); diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 9138c57..a447100 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -201,6 +201,15 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setLibcallName(RTLIB::SRL_I128, 0); setLibcallName(RTLIB::SRA_I128, 0); + // Libcalls should use the AAPCS base standard ABI, even if hard float + // is in effect, as per the ARM RTABI specification, section 4.1.2. + if (Subtarget->isAAPCS_ABI()) { + for (int i = 0; i < RTLIB::UNKNOWN_LIBCALL; ++i) { + setLibcallCallingConv(static_cast<RTLIB::Libcall>(i), + CallingConv::ARM_AAPCS); + } + } + if (Subtarget->isThumb1Only()) addRegisterClass(MVT::i32, ARM::tGPRRegisterClass); else diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index be3030d..84dbb6a 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -116,7 +116,7 @@ namespace { Op.getNode()->getValueType(0).getTypeForEVT(*DAG.getContext()); std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, - 0, CallingConv::C, false, + 0, TLI.getLibcallCallingConv(LC), false, /*isReturnValueUsed=*/true, Callee, Args, DAG, Op.getDebugLoc()); |