summaryrefslogtreecommitdiffstats
path: root/lib/Target/Mips/MipsISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips/MipsISelDAGToDAG.cpp')
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp54
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;
}
}
OpenPOWER on IntegriCloud