diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 98 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.h | 4 | 
4 files changed, 70 insertions, 64 deletions
| diff --git a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp index eba1419f43b..8c4b2b6a9a8 100644 --- a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp +++ b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp @@ -22,7 +22,6 @@  #include "llvm/Function.h"  #include "llvm/CodeGen/MachineConstantPool.h"  #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFrameInfo.h"  #include "llvm/CodeGen/SelectionDAG.h"  #include "llvm/CodeGen/SelectionDAGISel.h"  #include "llvm/CodeGen/SSARegMap.h" @@ -818,6 +817,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {      Tmp3 = SelectExpr(N.getOperand(2));      BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);      return Result; +  case PPCISD::FCTIWZ: +    Tmp1 = SelectExpr(N.getOperand(0)); +    BuildMI(BB, PPC::FCTIWZ, 1, Result).addReg(Tmp1); +    return Result;    case ISD::UNDEF:      if (Node->getValueType(0) == MVT::i32)        BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Result); @@ -1436,16 +1439,6 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {      return Result+N.ResNo;    } -  case ISD::FP_TO_SINT: { -    Tmp1 = SelectExpr(N.getOperand(0)); -    Tmp2 = MakeFPReg(); -    BuildMI(BB, PPC::FCTIWZ, 1, Tmp2).addReg(Tmp1); -    int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); -    addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx); -    addFrameReference(BuildMI(BB, PPC::LWZ, 2, Result), FrameIdx, 4); -    return Result; -  } -    case ISD::SETCC: {      ISD::CondCode CC = cast<CondCodeSDNode>(Node->getOperand(2))->get();      if (isIntImmediate(Node->getOperand(1), Tmp3)) { diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 9a978295b84..082c876859b 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -17,7 +17,6 @@  #include "PPC32ISelLowering.h"  #include "llvm/CodeGen/MachineInstrBuilder.h"  #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFrameInfo.h"  #include "llvm/CodeGen/SSARegMap.h"  #include "llvm/CodeGen/SelectionDAG.h"  #include "llvm/CodeGen/SelectionDAGISel.h" @@ -793,6 +792,10 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {                           Select(N->getOperand(1)),                           Select(N->getOperand(2)));      break; +  case PPCISD::FCTIWZ: +    CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), +                         Select(N->getOperand(0))); +    break;    case ISD::ADD: {      MVT::ValueType Ty = N->getValueType(0);      if (Ty == MVT::i32) { @@ -1119,18 +1122,6 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {             MVT::f64 == N->getOperand(0).getValueType() && "Illegal FP_ROUND");      CurDAG->SelectNodeTo(N, PPC::FRSP, MVT::f32, Select(N->getOperand(0)));      break; -  case ISD::FP_TO_SINT: { -    SDOperand In = Select(N->getOperand(0)); -    In = CurDAG->getTargetNode(PPC::FCTIWZ, MVT::f64, In); - -    int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); -    SDOperand FI = CurDAG->getTargetFrameIndex(FrameIdx, MVT::f64); -    SDOperand ST = CurDAG->getTargetNode(PPC::STFD, MVT::Other, In, -                                         getI32Imm(0), FI); -    CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, MVT::Other, -                         getI32Imm(4), FI, ST); -    break; -  }    case ISD::FNEG: {      SDOperand Val = Select(N->getOperand(0));      MVT::ValueType Ty = N->getValueType(0); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 987ffe1612b..5b77784819f 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -84,6 +84,9 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)    // PowerPC does not have FP_TO_UINT    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); +  // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores. +  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); +      // PowerPC does not have [U|S]INT_TO_FP    setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);    setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); @@ -111,61 +114,76 @@ static bool isFloatingPointZero(SDOperand Op) {  SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {    switch (Op.getOpcode()) {    default: assert(0 && "Wasn't expecting to be able to lower this!");  -  case ISD::SELECT_CC: +  case ISD::FP_TO_SINT: { +    assert(Op.getValueType() == MVT::i32 && +           MVT::isFloatingPoint(Op.getOperand(0).getValueType())); +    Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0)); +    +    int FrameIdx = +      DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); +    SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); +    SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), +                               Op, FI, DAG.getSrcValue(0)); +    FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32)); +    return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); +  } +  case ISD::SELECT_CC: {      // Turn FP only select_cc's into fsel instructions. -    if (MVT::isFloatingPoint(Op.getOperand(0).getValueType()) && -        MVT::isFloatingPoint(Op.getOperand(2).getValueType())) { -      ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); -       -      // Cannot handle SETEQ/SETNE. -      if (CC == ISD::SETEQ || CC == ISD::SETNE) break; -       -      MVT::ValueType ResVT = Op.getValueType(); -      MVT::ValueType CmpVT = Op.getOperand(0).getValueType(); -      SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); -      SDOperand TV  = Op.getOperand(2), FV  = Op.getOperand(3); +    if (!MVT::isFloatingPoint(Op.getOperand(0).getValueType()) || +        !MVT::isFloatingPoint(Op.getOperand(2).getValueType())) +      break; +     +    ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); +     +    // Cannot handle SETEQ/SETNE. +    if (CC == ISD::SETEQ || CC == ISD::SETNE) break; +     +    MVT::ValueType ResVT = Op.getValueType(); +    MVT::ValueType CmpVT = Op.getOperand(0).getValueType(); +    SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); +    SDOperand TV  = Op.getOperand(2), FV  = Op.getOperand(3); -      // If the RHS of the comparison is a 0.0, we don't need to do the -      // subtraction at all. -      if (isFloatingPointZero(RHS)) -        switch (CC) { -        default: assert(0 && "Invalid FSEL condition"); abort(); -        case ISD::SETULT: -        case ISD::SETLT: -          std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt -        case ISD::SETUGE: -        case ISD::SETGE: -          return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); -        case ISD::SETUGT: -        case ISD::SETGT: -          std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt -        case ISD::SETULE: -        case ISD::SETLE: -          return DAG.getNode(PPCISD::FSEL, ResVT, -                             DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV); -        } -       +    // If the RHS of the comparison is a 0.0, we don't need to do the +    // subtraction at all. +    if (isFloatingPointZero(RHS))        switch (CC) {        default: assert(0 && "Invalid FSEL condition"); abort();        case ISD::SETULT:        case ISD::SETLT: -        return DAG.getNode(PPCISD::FSEL, ResVT, -                           DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV); +        std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt        case ISD::SETUGE:        case ISD::SETGE: -        return DAG.getNode(PPCISD::FSEL, ResVT, -                           DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV); +        return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV);        case ISD::SETUGT:        case ISD::SETGT: -        return DAG.getNode(PPCISD::FSEL, ResVT, -                           DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV); +        std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt        case ISD::SETULE:        case ISD::SETLE:          return DAG.getNode(PPCISD::FSEL, ResVT, -                           DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV); +                           DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV);        } +     +    switch (CC) { +    default: assert(0 && "Invalid FSEL condition"); abort(); +    case ISD::SETULT: +    case ISD::SETLT: +      return DAG.getNode(PPCISD::FSEL, ResVT, +                         DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV); +    case ISD::SETUGE: +    case ISD::SETGE: +      return DAG.getNode(PPCISD::FSEL, ResVT, +                         DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV); +    case ISD::SETUGT: +    case ISD::SETGT: +      return DAG.getNode(PPCISD::FSEL, ResVT, +                         DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV); +    case ISD::SETULE: +    case ISD::SETLE: +      return DAG.getNode(PPCISD::FSEL, ResVT, +                         DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV);      } -    break;     +    break; +  }    case ISD::SHL: {      assert(Op.getValueType() == MVT::i64 &&             Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index bdd55480b74..924a672d2cc 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -28,6 +28,10 @@ namespace llvm {        /// FSEL - Traditional three-operand fsel node.        ///        FSEL, +       +      /// FCTIWZ - The FCTIWZ instruction, taking an f32 or f64 operand, +      /// producing an f64 value. +      FCTIWZ,      };    }   | 

