mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-01 01:14:12 +00:00
Move SHL,SHR i64 -> legalizer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23178 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c22af9e5df
commit
bc11c3482c
@ -72,7 +72,9 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
|
||||
|
||||
// PowerPC wants to expand SRA_PARTS into SELECT_CC and stuff.
|
||||
// PowerPC wants to expand i64 shifts itself.
|
||||
setOperationAction(ISD::SHL, MVT::i64, Custom);
|
||||
setOperationAction(ISD::SRL, MVT::i64, Custom);
|
||||
setOperationAction(ISD::SRA, MVT::i64, Custom);
|
||||
|
||||
// PowerPC does not have BRCOND* which requires SetCC
|
||||
@ -164,7 +166,59 @@ SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ISD::SRA:
|
||||
case ISD::SHL: {
|
||||
assert(Op.getValueType() == MVT::i64 &&
|
||||
Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!");
|
||||
// The generic code does a fine job expanding shift by a constant.
|
||||
if (isa<ConstantSDNode>(Op.getOperand(1))) break;
|
||||
|
||||
// Otherwise, expand into a bunch of logical ops. Note that these ops
|
||||
// depend on the PPC behavior for oversized shift amounts.
|
||||
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
|
||||
DAG.getConstant(0, MVT::i32));
|
||||
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
SDOperand Amt = Op.getOperand(1);
|
||||
|
||||
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
|
||||
DAG.getConstant(32, MVT::i32), Amt);
|
||||
SDOperand Tmp2 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Amt);
|
||||
SDOperand Tmp3 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Tmp1);
|
||||
SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
|
||||
SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
|
||||
DAG.getConstant(-32U, MVT::i32));
|
||||
SDOperand Tmp6 = DAG.getNode(ISD::SHL, MVT::i32, Lo, Tmp5);
|
||||
SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
|
||||
SDOperand OutLo = DAG.getNode(ISD::SHL, MVT::i32, Lo, Amt);
|
||||
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
||||
}
|
||||
case ISD::SRL: {
|
||||
assert(Op.getValueType() == MVT::i64 &&
|
||||
Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!");
|
||||
// The generic code does a fine job expanding shift by a constant.
|
||||
if (isa<ConstantSDNode>(Op.getOperand(1))) break;
|
||||
|
||||
// Otherwise, expand into a bunch of logical ops. Note that these ops
|
||||
// depend on the PPC behavior for oversized shift amounts.
|
||||
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
|
||||
DAG.getConstant(0, MVT::i32));
|
||||
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
SDOperand Amt = Op.getOperand(1);
|
||||
|
||||
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
|
||||
DAG.getConstant(32, MVT::i32), Amt);
|
||||
SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt);
|
||||
SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1);
|
||||
SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
|
||||
SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
|
||||
DAG.getConstant(-32U, MVT::i32));
|
||||
SDOperand Tmp6 = DAG.getNode(ISD::SRL, MVT::i32, Hi, Tmp5);
|
||||
SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
|
||||
SDOperand OutHi = DAG.getNode(ISD::SRL, MVT::i32, Hi, Amt);
|
||||
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
||||
}
|
||||
case ISD::SRA: {
|
||||
assert(Op.getValueType() == MVT::i64 &&
|
||||
Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!");
|
||||
// The generic code does a fine job expanding shift by a constant.
|
||||
@ -190,6 +244,7 @@ SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
Tmp4, Tmp6, ISD::SETLE);
|
||||
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
||||
}
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user