diff options
| author | Akira Hatanaka <ahatanaka@mips.com> | 2011-10-03 20:01:11 +0000 |
|---|---|---|
| committer | Akira Hatanaka <ahatanaka@mips.com> | 2011-10-03 20:01:11 +0000 |
| commit | a279d9bd6adc5af63b751ca99f4e8adc04baf6a4 (patch) | |
| tree | 3ed4322f4200eca20626c65423319172d0644709 /llvm/lib | |
| parent | cdcc74563cef83a81c55b45c404aa98fdcfb4968 (diff) | |
| download | bcm5719-llvm-a279d9bd6adc5af63b751ca99f4e8adc04baf6a4.tar.gz bcm5719-llvm-a279d9bd6adc5af63b751ca99f4e8adc04baf6a4.zip | |
Add support for 64-bit integer multiply instructions.
llvm-svn: 141017
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/Mips/Mips64InstrInfo.td | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 18 |
2 files changed, 26 insertions, 4 deletions
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 3e65f999b5c..2fdc2ff007e 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -90,6 +90,14 @@ class LogicR_shift_rotate_reg64<bits<6> func, bits<5> _shamt, string instr_asm, let shamt = _shamt; } +// Mul, Div +let Defs = [HI64, LO64] in { + let isCommutable = 1 in + class Mul64<bits<6> func, string instr_asm, InstrItinClass itin>: + FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b), + !strconcat(instr_asm, "\t$a, $b"), [], itin>; +} + // Move from Hi/Lo let shamt = 0 in { let rs = 0, rt = 0 in @@ -139,6 +147,10 @@ let Predicates = [HasMips64r2] in { def DROTRV : LogicR_shift_rotate_reg64<0x16, 0x01, "drotrv", rotr>; } +/// Multiply and Divide Instructions. +def DMULT : Mul64<0x1c, "dmult", IIImul>; +def DMULTu : Mul64<0x1d, "dmultu", IIImul>; + let Defs = [HI64] in def MTHI64 : MoveToLOHI64<0x11, "mthi">; let Defs = [LO64] in diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 658bdcf82d5..3face6e342a 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -237,6 +237,8 @@ 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); @@ -262,21 +264,29 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { /// Special Muls case ISD::MUL: - if (Subtarget.hasMips32()) + // Mips32 has a 32-bit three operand mul instruction. + if (Subtarget.hasMips32() && Node->getValueType(0) == MVT::i32) break; 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 : Mips::MULT); + 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) - return CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, InFlag); + if (Opcode == ISD::MUL) { + unsigned Opc = (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64); + return CurDAG->getMachineNode(Opc, dl, Ty, InFlag); + } else return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag); } |

