diff options
Diffstat (limited to 'lib/Target/Mips/MipsISelLowering.cpp')
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index a0e5f30d78..9281940019 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -48,6 +48,7 @@ getTargetNodeName(unsigned Opcode) const case MipsISD::FPSelectCC : return "MipsISD::FPSelectCC"; case MipsISD::FPBrcond : return "MipsISD::FPBrcond"; case MipsISD::FPCmp : return "MipsISD::FPCmp"; + case MipsISD::FPRound : return "MipsISD::FPRound"; default : return NULL; } } @@ -96,8 +97,10 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM) setOperationAction(ISD::SELECT, MVT::f32, Custom); setOperationAction(ISD::SELECT, MVT::i32, Custom); setOperationAction(ISD::SETCC, MVT::f32, Custom); + setOperationAction(ISD::SETCC, MVT::f64, Custom); setOperationAction(ISD::BRCOND, MVT::Other, Custom); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); // We custom lower AND/OR to handle the case where the DAG contain 'ands/ors' // with operands comming from setcc fp comparions. This is necessary since @@ -166,6 +169,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); + case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); @@ -359,6 +363,39 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, //===----------------------------------------------------------------------===// SDValue MipsTargetLowering:: +LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) +{ + if (!Subtarget->isMips1()) + return Op; + + MachineFunction &MF = DAG.getMachineFunction(); + unsigned CCReg = AddLiveIn(MF, Mips::FCR31, Mips::CCRRegisterClass); + + SDValue Chain = DAG.getEntryNode(); + DebugLoc dl = Op.getDebugLoc(); + SDValue Src = Op.getOperand(0); + + // Set the condition register + SDValue CondReg = DAG.getCopyFromReg(Chain, dl, CCReg, MVT::i32); + CondReg = DAG.getCopyToReg(Chain, dl, Mips::AT, CondReg); + CondReg = DAG.getCopyFromReg(CondReg, dl, Mips::AT, MVT::i32); + + SDValue Cst = DAG.getConstant(3, MVT::i32); + SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, CondReg, Cst); + Cst = DAG.getConstant(2, MVT::i32); + SDValue Xor = DAG.getNode(ISD::XOR, dl, MVT::i32, Or, Cst); + + SDValue InFlag(0, 0); + CondReg = DAG.getCopyToReg(Chain, dl, Mips::FCR31, Xor, InFlag); + + // Emit the round instruction and bit convert to integer + SDValue Trunc = DAG.getNode(MipsISD::FPRound, dl, MVT::f32, + Src, CondReg.getValue(1)); + SDValue BitCvt = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Trunc); + return BitCvt; +} + +SDValue MipsTargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) { SDValue Chain = Op.getOperand(0); |