diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-08-31 20:23:54 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-08-31 20:23:54 +0000 |
| commit | e675a08e1099c6042ea371f1102324f9b117fd22 (patch) | |
| tree | 5988e8483fc466a6cbc81788f881f3a40401d8fb /llvm/lib/Target/PowerPC | |
| parent | 3a04a4b767d36a04f16df7020241da4f0d0b6861 (diff) | |
| download | bcm5719-llvm-e675a08e1099c6042ea371f1102324f9b117fd22.tar.gz bcm5719-llvm-e675a08e1099c6042ea371f1102324f9b117fd22.zip | |
Move SHL,SHR i64 -> legalizer
llvm-svn: 23178
Diffstat (limited to 'llvm/lib/Target/PowerPC')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index c6511e8f5cd..987ffe1612b 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -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(); } |

