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 | 04d3762ff111085e21cb8f8570e68dff7f847b6d (patch) | |
tree | d40a0b111256d36a93af800361cbe2c42a763233 | |
parent | 36787939b27d9b238e10fc4ba42cb621003a5a31 (diff) | |
download | llvm-04d3762ff111085e21cb8f8570e68dff7f847b6d.tar.gz llvm-04d3762ff111085e21cb8f8570e68dff7f847b6d.tar.bz2 llvm-04d3762ff111085e21cb8f8570e68dff7f847b6d.tar.xz |
Add support for 64-bit integer multiply instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141017 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/Mips64InstrInfo.td | 12 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 18 | ||||
-rw-r--r-- | test/CodeGen/Mips/mips64instrs.ll | 13 |
3 files changed, 39 insertions, 4 deletions
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 3e65f999b5..2fdc2ff007 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/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/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 658bdcf82d..3face6e342 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/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); } diff --git a/test/CodeGen/Mips/mips64instrs.ll b/test/CodeGen/Mips/mips64instrs.ll index 67776aae41..98aff526de 100644 --- a/test/CodeGen/Mips/mips64instrs.ll +++ b/test/CodeGen/Mips/mips64instrs.ll @@ -70,3 +70,16 @@ entry: ret i64 %xor } +define i64 @f12(i64 %a, i64 %b) nounwind readnone { +entry: +; CHECK: mult + %mul = mul nsw i64 %b, %a + ret i64 %mul +} + +define i64 @f13(i64 %a, i64 %b) nounwind readnone { +entry: +; CHECK: mult + %mul = mul i64 %b, %a + ret i64 %mul +} |