diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2011-12-20 23:10:57 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2011-12-20 23:10:57 +0000 |
commit | 2fd0475cdbf7e80d4e5097ab0ddedcce18711ec9 (patch) | |
tree | 109720fb2fb03d858b202c6399b8b26f29bdc86a /lib/Target/Mips/MipsISelDAGToDAG.cpp | |
parent | 49d534bb3d21cfefd372e7d337af41dbab6738e3 (diff) | |
download | external_llvm-2fd0475cdbf7e80d4e5097ab0ddedcce18711ec9.zip external_llvm-2fd0475cdbf7e80d4e5097ab0ddedcce18711ec9.tar.gz external_llvm-2fd0475cdbf7e80d4e5097ab0ddedcce18711ec9.tar.bz2 |
Add function MipsDAGToDAGISel::SelectMULT and factor out code that generates
nodes needed for multiplication. Add code for selecting 64-bit MULHS and MULHU
nodes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147008 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/MipsISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 84 |
1 files changed, 47 insertions, 37 deletions
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index f058d7a..76e9afc 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -81,6 +81,10 @@ private: } SDNode *getGlobalBaseReg(); + + std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, + EVT Ty, bool HasLo, bool HasHi); + SDNode *Select(SDNode *N); // Complex Pattern. @@ -176,6 +180,28 @@ SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) { return true; } +/// Select multiply instructions. +std::pair<SDNode*, SDNode*> +MipsDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty, + bool HasLo, bool HasHi) { + SDNode *Lo, *Hi; + SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0), + N->getOperand(1)); + SDValue InFlag = SDValue(Mul, 0); + + if (HasLo) { + Lo = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64, dl, + Ty, MVT::Glue, InFlag); + InFlag = SDValue(Lo, 1); + } + if (HasHi) + Hi = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64, dl, + Ty, InFlag); + + return std::make_pair(Lo, Hi); +} + + /// Select instructions not customized! Used for /// expanded, promoted and normal instructions SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { @@ -195,6 +221,9 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { // Instruction Selection not handled by the auto-generated // tablegen selection should be handled here. /// + EVT NodeTy = Node->getValueType(0); + unsigned MultOpc; + switch(Opcode) { default: break; @@ -232,58 +261,39 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { /// Mul with two results case ISD::SMUL_LOHI: case ISD::UMUL_LOHI: { - assert(Node->getValueType(0) != MVT::i64 && - "64-bit multiplication with two results not handled."); - 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); + if (NodeTy == MVT::i32) + MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT); + else + MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT); - 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); + std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl, NodeTy, + true, true); if (!SDValue(Node, 0).use_empty()) - ReplaceUses(SDValue(Node, 0), SDValue(Lo,0)); + ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0)); if (!SDValue(Node, 1).use_empty()) - ReplaceUses(SDValue(Node, 1), SDValue(Hi,0)); + ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0)); return NULL; } /// Special Muls - case ISD::MUL: + case ISD::MUL: { // Mips32 has a 32-bit three operand mul instruction. - if (Subtarget.hasMips32() && Node->getValueType(0) == MVT::i32) + if (Subtarget.hasMips32() && NodeTy == MVT::i32) break; + return SelectMULT(Node, NodeTy == MVT::i32 ? Mips::MULT : Mips::DMULT, + dl, NodeTy, true, false).first; + } case ISD::MULHS: case ISD::MULHU: { - assert((Opcode == ISD::MUL || Node->getValueType(0) != MVT::i64) && - "64-bit MULH* not handled."); - EVT Ty = Node->getValueType(0); - SDValue MulOp1 = Node->getOperand(0); - SDValue MulOp2 = Node->getOperand(1); - - unsigned MulOp = (Opcode == ISD::MULHU ? - Mips::MULTu : - (Ty == MVT::i32 ? Mips::MULT : Mips::DMULT)); - SDNode *MulNode = CurDAG->getMachineNode(MulOp, dl, - MVT::Glue, MulOp1, MulOp2); - - SDValue InFlag = SDValue(MulNode, 0); - - if (Opcode == ISD::MUL) { - unsigned Opc = (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64); - return CurDAG->getMachineNode(Opc, dl, Ty, InFlag); - } + if (NodeTy == MVT::i32) + MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT); else - return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag); + MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT); + + return SelectMULT(Node, MultOpc, dl, NodeTy, false, true).second; } // Get target GOT address. |