diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-06-19 21:05:09 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-06-19 21:05:09 +0000 |
commit | 277f0741c5ea123b30360c382a153df238c31cae (patch) | |
tree | c0be364871e0f65d36bc5bb8ad76f3f4ea14f313 /lib/Target | |
parent | 3f931b8c0e3f27aeb52d8acf209c64e182defb3f (diff) | |
download | external_llvm-277f0741c5ea123b30360c382a153df238c31cae.zip external_llvm-277f0741c5ea123b30360c382a153df238c31cae.tar.gz external_llvm-277f0741c5ea123b30360c382a153df238c31cae.tar.bz2 |
Allow predicated immediate ARM to ARM calls.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37659 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 7 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.h | 1 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 7 |
3 files changed, 14 insertions, 1 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index aeaa7e3..0f82ce5 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -267,6 +267,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { case ARMISD::Wrapper: return "ARMISD::Wrapper"; case ARMISD::WrapperJT: return "ARMISD::WrapperJT"; case ARMISD::CALL: return "ARMISD::CALL"; + case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED"; case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK"; case ARMISD::tCALL: return "ARMISD::tCALL"; case ARMISD::BRCOND: return "ARMISD::BRCOND"; @@ -517,6 +518,7 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { // node so that legalize doesn't hack it. bool isDirect = false; bool isARMFunc = false; + bool isLocalARMFunc = false; if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { GlobalValue *GV = G->getGlobal(); isDirect = true; @@ -525,6 +527,8 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { bool isStub = (isExt && Subtarget->isTargetDarwin()) && getTargetMachine().getRelocationModel() != Reloc::Static; isARMFunc = !Subtarget->isThumb() || isStub; + // ARM call to a local ARM function is predicable. + isLocalARMFunc = !Subtarget->isThumb() && !isExt; // tBX takes a register source operand. if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) { ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex, @@ -564,7 +568,8 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { CallOpc = isARMFunc ? ARMISD::CALL : ARMISD::tCALL; } else { CallOpc = (isDirect || Subtarget->hasV5TOps()) - ? ARMISD::CALL : ARMISD::CALL_NOLINK; + ? (isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL) + : ARMISD::CALL_NOLINK; } if (CallOpc == ARMISD::CALL_NOLINK && !Subtarget->isThumb()) { // implicit def LR - LR mustn't be allocated as GRP:$dst of CALL_NOLINK diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index b0c5e89..d51b680 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -34,6 +34,7 @@ namespace llvm { WrapperJT, // WrapperJT - A wrapper node for TargetJumpTable CALL, // Function call. + CALL_PRED, // Function call that's predicable. CALL_NOLINK, // Function call with branch not branch-and-link. tCALL, // Thumb function call. BRCOND, // Conditional branch. diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 5a7b72b..742b882 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -52,6 +52,8 @@ def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeq, def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; +def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall, + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; @@ -621,6 +623,11 @@ let isCall = 1, noResults = 1, clobbersPred = 1, def BL : AXI<(ops i32imm:$func, variable_ops), "bl ${func:call}", [(ARMcall tglobaladdr:$func)]>; + + def BL_pred : AI<(ops i32imm:$func, variable_ops), + "bl", " ${func:call}", + [(ARMcall_pred tglobaladdr:$func)]>; + // ARMv5T and above def BLX : AXI<(ops GPR:$dst, variable_ops), "blx $dst", |