mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-11 13:37:07 +00:00
Add specializations of addrmode2 that allow differentiating those forms
which require the use of the shifter-operand. This will be used to split the ldr/str instructions such that those versions needing the shifter operand can get a different scheduling itenerary, as in some cases, the use of the shifter can cause different scheduling than the simpler forms. llvm-svn: 115066
This commit is contained in:
parent
a533bd63e6
commit
fd8705ab4a
@ -46,6 +46,12 @@ DisableShifterOp("disable-shifter-op", cl::Hidden,
|
|||||||
/// instructions for SelectionDAG operations.
|
/// instructions for SelectionDAG operations.
|
||||||
///
|
///
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
enum AddrMode2Type {
|
||||||
|
AM2_BASE, // Simple AM2 (+-imm12)
|
||||||
|
AM2_SHOP // Shifter-op AM2
|
||||||
|
};
|
||||||
|
|
||||||
class ARMDAGToDAGISel : public SelectionDAGISel {
|
class ARMDAGToDAGISel : public SelectionDAGISel {
|
||||||
ARMBaseTargetMachine &TM;
|
ARMBaseTargetMachine &TM;
|
||||||
|
|
||||||
@ -74,8 +80,25 @@ public:
|
|||||||
|
|
||||||
bool SelectShifterOperandReg(SDValue N, SDValue &A,
|
bool SelectShifterOperandReg(SDValue N, SDValue &A,
|
||||||
SDValue &B, SDValue &C);
|
SDValue &B, SDValue &C);
|
||||||
bool SelectAddrMode2(SDValue N, SDValue &Base,
|
AddrMode2Type SelectAddrMode2Worker(SDValue N, SDValue &Base,
|
||||||
SDValue &Offset, SDValue &Opc);
|
SDValue &Offset, SDValue &Opc);
|
||||||
|
bool SelectAddrMode2Base(SDValue N, SDValue &Base, SDValue &Offset,
|
||||||
|
SDValue &Opc) {
|
||||||
|
return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SelectAddrMode2ShOp(SDValue N, SDValue &Base, SDValue &Offset,
|
||||||
|
SDValue &Opc) {
|
||||||
|
return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SelectAddrMode2(SDValue N, SDValue &Base, SDValue &Offset,
|
||||||
|
SDValue &Opc) {
|
||||||
|
SelectAddrMode2Worker(N, Base, Offset, Opc);
|
||||||
|
// This always matches one way or another.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool SelectAddrMode2Offset(SDNode *Op, SDValue N,
|
bool SelectAddrMode2Offset(SDNode *Op, SDValue N,
|
||||||
SDValue &Offset, SDValue &Opc);
|
SDValue &Offset, SDValue &Opc);
|
||||||
bool SelectAddrMode3(SDValue N, SDValue &Base,
|
bool SelectAddrMode3(SDValue N, SDValue &Base,
|
||||||
@ -245,9 +268,10 @@ bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue N,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
|
AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N,
|
||||||
SDValue &Base, SDValue &Offset,
|
SDValue &Base,
|
||||||
SDValue &Opc) {
|
SDValue &Offset,
|
||||||
|
SDValue &Opc) {
|
||||||
if (N.getOpcode() == ISD::MUL) {
|
if (N.getOpcode() == ISD::MUL) {
|
||||||
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
|
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
|
||||||
// X * [3,5,9] -> X + X * [2,4,8] etc.
|
// X * [3,5,9] -> X + X * [2,4,8] etc.
|
||||||
@ -265,7 +289,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
|
|||||||
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
|
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
|
||||||
ARM_AM::lsl),
|
ARM_AM::lsl),
|
||||||
MVT::i32);
|
MVT::i32);
|
||||||
return true;
|
return AM2_SHOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,7 +309,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
|
|||||||
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
|
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
|
||||||
ARM_AM::no_shift),
|
ARM_AM::no_shift),
|
||||||
MVT::i32);
|
MVT::i32);
|
||||||
return true;
|
return AM2_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match simple R +/- imm12 operands.
|
// Match simple R +/- imm12 operands.
|
||||||
@ -309,7 +333,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
|
|||||||
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
|
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
|
||||||
ARM_AM::no_shift),
|
ARM_AM::no_shift),
|
||||||
MVT::i32);
|
MVT::i32);
|
||||||
return true;
|
return AM2_BASE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -353,7 +377,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
|
|||||||
|
|
||||||
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
|
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
|
||||||
MVT::i32);
|
MVT::i32);
|
||||||
return true;
|
return AM2_SHOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N,
|
bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N,
|
||||||
|
@ -369,8 +369,22 @@ def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
|
|||||||
|
|
||||||
// Define ARM specific addressing modes.
|
// Define ARM specific addressing modes.
|
||||||
|
|
||||||
// addrmode2 := reg +/- reg shop imm
|
// addrmode2base := reg +/- imm12
|
||||||
// addrmode2 := reg +/- imm12
|
//
|
||||||
|
def addrmode2base : Operand<i32>,
|
||||||
|
ComplexPattern<i32, 3, "SelectAddrMode2Base", []> {
|
||||||
|
let PrintMethod = "printAddrMode2Operand";
|
||||||
|
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
|
||||||
|
}
|
||||||
|
// addrmode2shop := reg +/- reg shop imm
|
||||||
|
//
|
||||||
|
def addrmode2shop : Operand<i32>,
|
||||||
|
ComplexPattern<i32, 3, "SelectAddrMode2ShOp", []> {
|
||||||
|
let PrintMethod = "printAddrMode2Operand";
|
||||||
|
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// addrmode2 := (addrmode2base || addrmode2shop)
|
||||||
//
|
//
|
||||||
def addrmode2 : Operand<i32>,
|
def addrmode2 : Operand<i32>,
|
||||||
ComplexPattern<i32, 3, "SelectAddrMode2", []> {
|
ComplexPattern<i32, 3, "SelectAddrMode2", []> {
|
||||||
|
Loading…
Reference in New Issue
Block a user