mirror of
https://github.com/RPCSX/llvm.git
synced 2025-03-05 03:19:11 +00:00
Allow predicated immediate ARM to ARM calls.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37659 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3f931b8c0e
commit
277f0741c5
@ -267,6 +267,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case ARMISD::Wrapper: return "ARMISD::Wrapper";
|
case ARMISD::Wrapper: return "ARMISD::Wrapper";
|
||||||
case ARMISD::WrapperJT: return "ARMISD::WrapperJT";
|
case ARMISD::WrapperJT: return "ARMISD::WrapperJT";
|
||||||
case ARMISD::CALL: return "ARMISD::CALL";
|
case ARMISD::CALL: return "ARMISD::CALL";
|
||||||
|
case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED";
|
||||||
case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK";
|
case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK";
|
||||||
case ARMISD::tCALL: return "ARMISD::tCALL";
|
case ARMISD::tCALL: return "ARMISD::tCALL";
|
||||||
case ARMISD::BRCOND: return "ARMISD::BRCOND";
|
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.
|
// node so that legalize doesn't hack it.
|
||||||
bool isDirect = false;
|
bool isDirect = false;
|
||||||
bool isARMFunc = false;
|
bool isARMFunc = false;
|
||||||
|
bool isLocalARMFunc = false;
|
||||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
|
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
|
||||||
GlobalValue *GV = G->getGlobal();
|
GlobalValue *GV = G->getGlobal();
|
||||||
isDirect = true;
|
isDirect = true;
|
||||||
@ -525,6 +527,8 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
bool isStub = (isExt && Subtarget->isTargetDarwin()) &&
|
bool isStub = (isExt && Subtarget->isTargetDarwin()) &&
|
||||||
getTargetMachine().getRelocationModel() != Reloc::Static;
|
getTargetMachine().getRelocationModel() != Reloc::Static;
|
||||||
isARMFunc = !Subtarget->isThumb() || isStub;
|
isARMFunc = !Subtarget->isThumb() || isStub;
|
||||||
|
// ARM call to a local ARM function is predicable.
|
||||||
|
isLocalARMFunc = !Subtarget->isThumb() && !isExt;
|
||||||
// tBX takes a register source operand.
|
// tBX takes a register source operand.
|
||||||
if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) {
|
if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) {
|
||||||
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex,
|
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex,
|
||||||
@ -564,7 +568,8 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
CallOpc = isARMFunc ? ARMISD::CALL : ARMISD::tCALL;
|
CallOpc = isARMFunc ? ARMISD::CALL : ARMISD::tCALL;
|
||||||
} else {
|
} else {
|
||||||
CallOpc = (isDirect || Subtarget->hasV5TOps())
|
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()) {
|
if (CallOpc == ARMISD::CALL_NOLINK && !Subtarget->isThumb()) {
|
||||||
// implicit def LR - LR mustn't be allocated as GRP:$dst of CALL_NOLINK
|
// implicit def LR - LR mustn't be allocated as GRP:$dst of CALL_NOLINK
|
||||||
|
@ -34,6 +34,7 @@ namespace llvm {
|
|||||||
WrapperJT, // WrapperJT - A wrapper node for TargetJumpTable
|
WrapperJT, // WrapperJT - A wrapper node for TargetJumpTable
|
||||||
|
|
||||||
CALL, // Function call.
|
CALL, // Function call.
|
||||||
|
CALL_PRED, // Function call that's predicable.
|
||||||
CALL_NOLINK, // Function call with branch not branch-and-link.
|
CALL_NOLINK, // Function call with branch not branch-and-link.
|
||||||
tCALL, // Thumb function call.
|
tCALL, // Thumb function call.
|
||||||
BRCOND, // Conditional branch.
|
BRCOND, // Conditional branch.
|
||||||
|
@ -52,6 +52,8 @@ def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeq,
|
|||||||
|
|
||||||
def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
|
def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
|
||||||
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
||||||
|
def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
|
||||||
|
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
||||||
def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
|
def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
|
||||||
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
||||||
|
|
||||||
@ -621,6 +623,11 @@ let isCall = 1, noResults = 1, clobbersPred = 1,
|
|||||||
def BL : AXI<(ops i32imm:$func, variable_ops),
|
def BL : AXI<(ops i32imm:$func, variable_ops),
|
||||||
"bl ${func:call}",
|
"bl ${func:call}",
|
||||||
[(ARMcall tglobaladdr:$func)]>;
|
[(ARMcall tglobaladdr:$func)]>;
|
||||||
|
|
||||||
|
def BL_pred : AI<(ops i32imm:$func, variable_ops),
|
||||||
|
"bl", " ${func:call}",
|
||||||
|
[(ARMcall_pred tglobaladdr:$func)]>;
|
||||||
|
|
||||||
// ARMv5T and above
|
// ARMv5T and above
|
||||||
def BLX : AXI<(ops GPR:$dst, variable_ops),
|
def BLX : AXI<(ops GPR:$dst, variable_ops),
|
||||||
"blx $dst",
|
"blx $dst",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user