mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 06:30:39 +00:00
In thumb2 mode, add pc is unpredictable. Use add + mov pc instead (that is until more optimization goes in).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77364 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6340632d3b
commit
e7c329bf4b
@ -409,7 +409,6 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case ARMISD::tCALL: return "ARMISD::tCALL";
|
case ARMISD::tCALL: return "ARMISD::tCALL";
|
||||||
case ARMISD::BRCOND: return "ARMISD::BRCOND";
|
case ARMISD::BRCOND: return "ARMISD::BRCOND";
|
||||||
case ARMISD::BR_JT: return "ARMISD::BR_JT";
|
case ARMISD::BR_JT: return "ARMISD::BR_JT";
|
||||||
case ARMISD::BR2_JT: return "ARMISD::BR2_JT";
|
|
||||||
case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG";
|
case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG";
|
||||||
case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD";
|
case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD";
|
||||||
case ARMISD::CMP: return "ARMISD::CMP";
|
case ARMISD::CMP: return "ARMISD::CMP";
|
||||||
@ -1712,17 +1711,15 @@ SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) {
|
|||||||
SDValue UId = DAG.getConstant(AFI->createJumpTableUId(), PTy);
|
SDValue UId = DAG.getConstant(AFI->createJumpTableUId(), PTy);
|
||||||
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
|
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
|
||||||
Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI, UId);
|
Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI, UId);
|
||||||
|
Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, PTy));
|
||||||
|
SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);
|
||||||
if (Subtarget->isThumb2()) {
|
if (Subtarget->isThumb2()) {
|
||||||
// Thumb2 uses a two-level jump. That is, it jumps into the jump table
|
// Thumb2 uses a two-level jump. That is, it jumps into the jump table
|
||||||
// which does another jump to the destination. This also makes it easier
|
// which does another jump to the destination. This also makes it easier
|
||||||
// to translate it to TBB / TBH later.
|
// to translate it to TBB / TBH later.
|
||||||
// FIXME: This might not work if the function is extremely large.
|
// FIXME: This might not work if the function is extremely large.
|
||||||
return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain, Table, Index,
|
return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId);
|
||||||
JTI, UId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, PTy));
|
|
||||||
SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);
|
|
||||||
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
|
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
|
||||||
Addr = DAG.getLoad((MVT)MVT::i32, dl, Chain, Addr, NULL, 0);
|
Addr = DAG.getLoad((MVT)MVT::i32, dl, Chain, Addr, NULL, 0);
|
||||||
Chain = Addr.getValue(1);
|
Chain = Addr.getValue(1);
|
||||||
|
@ -40,7 +40,6 @@ namespace llvm {
|
|||||||
tCALL, // Thumb function call.
|
tCALL, // Thumb function call.
|
||||||
BRCOND, // Conditional branch.
|
BRCOND, // Conditional branch.
|
||||||
BR_JT, // Jumptable branch.
|
BR_JT, // Jumptable branch.
|
||||||
BR2_JT, // Jumptable branch (2 level - jumptable entry is a jump).
|
|
||||||
RET_FLAG, // Return with a flag operand.
|
RET_FLAG, // Return with a flag operand.
|
||||||
|
|
||||||
PIC_ADD, // Add with a PC operand and a PIC label.
|
PIC_ADD, // Add with a PC operand and a PIC label.
|
||||||
|
@ -33,9 +33,6 @@ def SDT_ARMBrcond : SDTypeProfile<0, 2,
|
|||||||
def SDT_ARMBrJT : SDTypeProfile<0, 3,
|
def SDT_ARMBrJT : SDTypeProfile<0, 3,
|
||||||
[SDTCisPtrTy<0>, SDTCisVT<1, i32>,
|
[SDTCisPtrTy<0>, SDTCisVT<1, i32>,
|
||||||
SDTCisVT<2, i32>]>;
|
SDTCisVT<2, i32>]>;
|
||||||
def SDT_ARMBr2JT : SDTypeProfile<0, 4,
|
|
||||||
[SDTCisPtrTy<0>, SDTCisVT<1, i32>,
|
|
||||||
SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
|
|
||||||
|
|
||||||
def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
|
def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
|
||||||
|
|
||||||
@ -75,9 +72,6 @@ def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
|
|||||||
def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
|
def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
|
||||||
[SDNPHasChain]>;
|
[SDNPHasChain]>;
|
||||||
|
|
||||||
def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT,
|
|
||||||
[SDNPHasChain]>;
|
|
||||||
|
|
||||||
def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
|
def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
|
||||||
[SDNPOutFlag]>;
|
[SDNPOutFlag]>;
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ let isBranch = 1, isTerminator = 1 in {
|
|||||||
|
|
||||||
def tBR_JTr : T1JTI<(outs),
|
def tBR_JTr : T1JTI<(outs),
|
||||||
(ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
|
(ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
|
||||||
"mov pc, $target \n\t.align\t2\n$jt",
|
"mov pc, $target\n\t.align\t2\n$jt",
|
||||||
[(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
|
[(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,10 +1050,9 @@ def t2B : T2XI<(outs), (ins brtarget:$target),
|
|||||||
|
|
||||||
let isNotDuplicable = 1, isIndirectBranch = 1 in
|
let isNotDuplicable = 1, isIndirectBranch = 1 in
|
||||||
def t2BR_JT :
|
def t2BR_JT :
|
||||||
T2JTI<(outs),
|
T2JTI<(outs), (ins GPR:$target, jt2block_operand:$jt, i32imm:$id),
|
||||||
(ins GPR:$base, GPR:$idx, jt2block_operand:$jt, i32imm:$id),
|
"mov pc, $target\n$jt",
|
||||||
"add.w pc, $base, $idx, lsl #2\n$jt",
|
[(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
|
||||||
[(ARMbr2jt GPR:$base, GPR:$idx, tjumptable:$jt, imm:$id)]>;
|
|
||||||
} // isBranch, isTerminator, isBarrier
|
} // isBranch, isTerminator, isBarrier
|
||||||
|
|
||||||
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
|
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
define void @bar(i32 %n.u) {
|
define void @bar(i32 %n.u) {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: bar:
|
; CHECK: bar:
|
||||||
; CHECK: add.w pc
|
; CHECK: mov pc
|
||||||
; CHECK: b.w LBB1_2
|
; CHECK: b.w LBB1_2
|
||||||
|
|
||||||
switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ]
|
switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ]
|
||||||
|
Loading…
Reference in New Issue
Block a user