diff options
Diffstat (limited to 'lib/Target/Mips/MipsSEISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 109 |
1 files changed, 42 insertions, 67 deletions
diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index d6d2207..8a6523a 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -35,6 +35,36 @@ #include "llvm/Target/TargetMachine.h" using namespace llvm; +bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { + if (Subtarget.inMips16Mode()) + return false; + return MipsDAGToDAGISel::runOnMachineFunction(MF); +} + +void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, + MachineFunction &MF) { + MachineInstrBuilder MIB(MF, &MI); + unsigned Mask = MI.getOperand(1).getImm(); + unsigned Flag = IsDef ? RegState::ImplicitDefine : RegState::Implicit; + + if (Mask & 1) + MIB.addReg(Mips::DSPPos, Flag); + + if (Mask & 2) + MIB.addReg(Mips::DSPSCount, Flag); + + if (Mask & 4) + MIB.addReg(Mips::DSPCarry, Flag); + + if (Mask & 8) + MIB.addReg(Mips::DSPOutFlag, Flag); + + if (Mask & 16) + MIB.addReg(Mips::DSPCCond, Flag); + + if (Mask & 32) + MIB.addReg(Mips::DSPEFI, Flag); +} bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr& MI) { @@ -173,29 +203,14 @@ void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE; ++MFI) - for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) - replaceUsesWithZeroReg(MRI, *I); -} - -/// Select multiply instructions. -std::pair<SDNode*, SDNode*> -MipsSEDAGToDAGISel::selectMULT(SDNode *N, unsigned Opc, DebugLoc DL, EVT Ty, - bool HasLo, bool HasHi) { - SDNode *Lo = 0, *Hi = 0; - SDNode *Mul = CurDAG->getMachineNode(Opc, DL, MVT::Glue, N->getOperand(0), - N->getOperand(1)); - SDValue InFlag = SDValue(Mul, 0); - - if (HasLo) { - unsigned Opcode = (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64); - Lo = CurDAG->getMachineNode(Opcode, DL, Ty, MVT::Glue, InFlag); - InFlag = SDValue(Lo, 1); - } - if (HasHi) { - unsigned Opcode = (Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64); - Hi = CurDAG->getMachineNode(Opcode, DL, Ty, InFlag); - } - return std::make_pair(Lo, Hi); + for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) { + if (I->getOpcode() == Mips::RDDSP) + addDSPCtrlRegOperands(false, *I, MF); + else if (I->getOpcode() == Mips::WRDSP) + addDSPCtrlRegOperands(true, *I, MF); + else + replaceUsesWithZeroReg(MRI, *I); + } } SDNode *MipsSEDAGToDAGISel::selectAddESubE(unsigned MOp, SDValue InFlag, @@ -211,7 +226,7 @@ SDNode *MipsSEDAGToDAGISel::selectAddESubE(unsigned MOp, SDValue InFlag, SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1); EVT VT = LHS.getValueType(); - SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, DL, VT, Ops, 2); + SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, DL, VT, Ops); SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, DL, VT, SDValue(Carry, 0), RHS); return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, @@ -307,9 +322,7 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { // Instruction Selection not handled by the auto-generated // tablegen selection should be handled here. /// - EVT NodeTy = Node->getValueType(0); SDNode *Result; - unsigned MultOpc; switch(Opcode) { default: break; @@ -321,51 +334,13 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { } case ISD::ADDE: { + if (Subtarget.hasDSP()) // Select DSP instructions, ADDSC and ADDWC. + break; SDValue InFlag = Node->getOperand(2); Result = selectAddESubE(Mips::ADDu, InFlag, InFlag.getValue(0), DL, Node); return std::make_pair(true, Result); } - /// Mul with two results - case ISD::SMUL_LOHI: - case ISD::UMUL_LOHI: { - if (NodeTy == MVT::i32) - MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT); - else - MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT); - - std::pair<SDNode*, SDNode*> LoHi = selectMULT(Node, MultOpc, DL, NodeTy, - true, true); - - if (!SDValue(Node, 0).use_empty()) - ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0)); - - if (!SDValue(Node, 1).use_empty()) - ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0)); - - return std::make_pair(true, (SDNode*)NULL); - } - - /// Special Muls - case ISD::MUL: { - // Mips32 has a 32-bit three operand mul instruction. - if (Subtarget.hasMips32() && NodeTy == MVT::i32) - break; - MultOpc = NodeTy == MVT::i32 ? Mips::MULT : Mips::DMULT; - Result = selectMULT(Node, MultOpc, DL, NodeTy, true, false).first; - return std::make_pair(true, Result); - } - case ISD::MULHS: - case ISD::MULHU: { - if (NodeTy == MVT::i32) - MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT); - else - MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT); - - Result = selectMULT(Node, MultOpc, DL, NodeTy, false, true).second; - return std::make_pair(true, Result); - } - case ISD::ConstantFP: { ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node); if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { @@ -460,7 +435,7 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { const SDValue Ops[] = { RegClass, Node->getOperand(0), LoIdx, Node->getOperand(1), HiIdx }; SDNode *Res = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, - MVT::Untyped, Ops, 5); + MVT::Untyped, Ops); return std::make_pair(true, Res); } } |