- default: break;
-
- case ISD::SUBE:
- case ISD::ADDE: {
- SDValue InFlag = Node->getOperand(2), CmpLHS;
- unsigned Opc = InFlag.getOpcode(); (void)Opc;
- assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
- (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
- "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
-
- unsigned MOp;
- if (Opcode == ISD::ADDE) {
- CmpLHS = InFlag.getValue(0);
- MOp = Mips::ADDu;
- } else {
- CmpLHS = InFlag.getOperand(0);
- MOp = Mips::SUBu;
- }
-
- SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
-
- SDValue LHS = Node->getOperand(0);
- SDValue RHS = Node->getOperand(1);
-
- EVT VT = LHS.getValueType();
- SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, dl, VT, Ops, 2);
- SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT,
- SDValue(Carry,0), RHS);
-
- return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue,
- LHS, SDValue(AddCarry,0));
- }
-
- /// Mul with two results
- case ISD::SMUL_LOHI:
- case ISD::UMUL_LOHI: {
- SDValue Op1 = Node->getOperand(0);
- SDValue Op2 = Node->getOperand(1);
-
- unsigned Op;
- Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
-
- SDNode *Mul = CurDAG->getMachineNode(Op, dl, MVT::Glue, Op1, Op2);
-
- SDValue InFlag = SDValue(Mul, 0);
- SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32,
- MVT::Glue, InFlag);
- InFlag = SDValue(Lo,1);
- SDNode *Hi = CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
-
- if (!SDValue(Node, 0).use_empty())
- ReplaceUses(SDValue(Node, 0), SDValue(Lo,0));
-
- if (!SDValue(Node, 1).use_empty())
- ReplaceUses(SDValue(Node, 1), SDValue(Hi,0));
-
- return NULL;
- }
-
- /// Special Muls
- case ISD::MUL:
- if (Subtarget.isMips32())
- break;
- case ISD::MULHS:
- case ISD::MULHU: {
- SDValue MulOp1 = Node->getOperand(0);
- SDValue MulOp2 = Node->getOperand(1);
-
- unsigned MulOp = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
- SDNode *MulNode = CurDAG->getMachineNode(MulOp, dl,
- MVT::Glue, MulOp1, MulOp2);
-
- SDValue InFlag = SDValue(MulNode, 0);
-
- if (Opcode == ISD::MUL)
- return CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, InFlag);
- else
- return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
- }
-
- // Get target GOT address.
- case ISD::GLOBAL_OFFSET_TABLE:
- return getGlobalBaseReg();
-
- case ISD::ConstantFP: {
- ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
- if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
- SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
- Mips::ZERO, MVT::i32);
- SDValue Undef = SDValue(
- CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::f64), 0);
- SDNode *MTC = CurDAG->getMachineNode(Mips::MTC1, dl, MVT::f32, Zero);
- SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::sub_fpeven, dl,
- MVT::f64, Undef, SDValue(MTC, 0));
- SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::sub_fpodd, dl,
- MVT::f64, I0, SDValue(MTC, 0));
- ReplaceUses(SDValue(Node, 0), I1);
- return I1.getNode();
- }
- break;
- }
-
- case ISD::LOAD:
- if (SDNode *ResNode = SelectLoadFp64(Node))
- return ResNode;
- // Other cases are autogenerated.
- break;
-
- case ISD::STORE:
- if (SDNode *ResNode = SelectStoreFp64(Node))
- return ResNode;
- // Other cases are autogenerated.
- break;
-
- case MipsISD::ThreadPointer: {
- unsigned SrcReg = Mips::HWR29;
- unsigned DestReg = Mips::V1;
- SDNode *Rdhwr = CurDAG->getMachineNode(Mips::RDHWR, Node->getDebugLoc(),
- Node->getValueType(0), CurDAG->getRegister(SrcReg, MVT::i32));
- SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg,
- SDValue(Rdhwr, 0));
- SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, MVT::i32);
- ReplaceUses(SDValue(Node, 0), ResNode);
- return ResNode.getNode();
- }