From: Chris Lattner Date: Sat, 17 Dec 2005 22:39:19 +0000 (+0000) Subject: implement div and rem X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7087e57872f68978945be227aafd17d6d43ae03e;p=oota-llvm.git implement div and rem git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24798 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 5d60a1bf5e2..4779c3c5365 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -65,6 +65,10 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); + + // Sparc has no REM operation. + setOperationAction(ISD::UREM, MVT::i32, Expand); + setOperationAction(ISD::SREM, MVT::i32, Expand); computeRegisterProperties(); } @@ -278,8 +282,30 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { switch (N->getOpcode()) { default: break; + case ISD::SDIV: + case ISD::UDIV: { + // FIXME: should use a custom expander to expose the SRA to the dag. + SDOperand DivLHS = Select(N->getOperand(0)); + SDOperand DivRHS = Select(N->getOperand(1)); + + // Set the Y register to the high-part. + SDOperand TopPart; + if (N->getOpcode() == ISD::SDIV) { + TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS, + CurDAG->getTargetConstant(31, MVT::i32)); + } else { + TopPart = CurDAG->getRegister(V8::G0, MVT::i32); + } + TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart, + CurDAG->getRegister(V8::G0, MVT::i32)); + + // FIXME: Handle div by immediate. + unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr; + return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart); + } case ISD::MULHU: case ISD::MULHS: { + // FIXME: Handle mul by immediate. SDOperand MulLHS = Select(N->getOperand(0)); SDOperand MulRHS = Select(N->getOperand(1)); unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr; diff --git a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp index 5d60a1bf5e2..4779c3c5365 100644 --- a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp +++ b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp @@ -65,6 +65,10 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); + + // Sparc has no REM operation. + setOperationAction(ISD::UREM, MVT::i32, Expand); + setOperationAction(ISD::SREM, MVT::i32, Expand); computeRegisterProperties(); } @@ -278,8 +282,30 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { switch (N->getOpcode()) { default: break; + case ISD::SDIV: + case ISD::UDIV: { + // FIXME: should use a custom expander to expose the SRA to the dag. + SDOperand DivLHS = Select(N->getOperand(0)); + SDOperand DivRHS = Select(N->getOperand(1)); + + // Set the Y register to the high-part. + SDOperand TopPart; + if (N->getOpcode() == ISD::SDIV) { + TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS, + CurDAG->getTargetConstant(31, MVT::i32)); + } else { + TopPart = CurDAG->getRegister(V8::G0, MVT::i32); + } + TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart, + CurDAG->getRegister(V8::G0, MVT::i32)); + + // FIXME: Handle div by immediate. + unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr; + return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart); + } case ISD::MULHU: case ISD::MULHS: { + // FIXME: Handle mul by immediate. SDOperand MulLHS = Select(N->getOperand(0)); SDOperand MulRHS = Select(N->getOperand(1)); unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr;