diff options
Diffstat (limited to 'lib/Target/Mips/MipsISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index a53e918..e3a45d2 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -396,9 +396,9 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { else Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV); - SDNode *Node = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2); + SDNode *MulDiv = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2); - SDValue InFlag = SDValue(Node, 0); + SDValue InFlag = SDValue(MulDiv, 0); SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, MVT::Flag, InFlag); InFlag = SDValue(Lo,1); @@ -461,9 +461,18 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { case ISD::ConstantFP: { ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node); if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { - SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32); - ReplaceUses(SDValue(Node, 0), Zero); - return Zero.getNode(); + SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, + Mips::ZERO, MVT::i32); + SDValue Undef = SDValue( + CurDAG->getMachineNode( + TargetInstrInfo::IMPLICIT_DEF, dl, MVT::f64), 0); + SDNode *MTC = CurDAG->getMachineNode(Mips::MTC1, dl, MVT::f32, Zero); + SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPEVEN, dl, + MVT::f64, Undef, SDValue(MTC, 0)); + SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPODD, dl, + MVT::f64, I0, SDValue(MTC, 0)); + ReplaceUses(SDValue(Node, 0), I1); + return I1.getNode(); } break; } @@ -486,10 +495,15 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { /// be loaded with 3 instructions. case MipsISD::JmpLink: { if (TM.getRelocationModel() == Reloc::PIC_) { + unsigned LastOpNum = Node->getNumOperands()-1; + SDValue Chain = Node->getOperand(0); SDValue Callee = Node->getOperand(1); - SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32); - SDValue InFlag(0, 0); + SDValue InFlag; + + // Skip the incomming flag if present + if (Node->getOperand(LastOpNum).getValueType() == MVT::Flag) + LastOpNum--; if ( (isa<GlobalAddressSDNode>(Callee)) || (isa<ExternalSymbolSDNode>(Callee)) ) @@ -504,18 +518,28 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { Chain = Load.getValue(1); // Call target must be on T9 - Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Load, InFlag); + Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag); } else /// Indirect call - Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Callee, InFlag); + Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag); + + // Map the JmpLink operands to JALR + SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Flag); + SmallVector<SDValue, 8> Ops; + Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32)); + + for (unsigned i = 2, e = LastOpNum+1; i != e; ++i) + Ops.push_back(Node->getOperand(i)); + Ops.push_back(Chain); + Ops.push_back(Chain.getValue(1)); // Emit Jump and Link Register - SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, MVT::Other, - MVT::Flag, T9Reg, Chain); - Chain = SDValue(ResNode, 0); - InFlag = SDValue(ResNode, 1); - ReplaceUses(SDValue(Node, 0), Chain); - ReplaceUses(SDValue(Node, 1), InFlag); + SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys, + &Ops[0], Ops.size()); + + // Replace Chain and InFlag + ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0)); + ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1)); return ResNode; } } |