1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

Add support for 64-bit integer multiply instructions.

llvm-svn: 141017
This commit is contained in:
Akira Hatanaka 2011-10-03 20:01:11 +00:00
parent 3f3d72c052
commit e3c1d7eac0
3 changed files with 39 additions and 4 deletions

View File

@ -90,6 +90,14 @@ class LogicR_shift_rotate_reg64<bits<6> func, bits<5> _shamt, string instr_asm,
let shamt = _shamt; 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 // Move from Hi/Lo
let shamt = 0 in { let shamt = 0 in {
let rs = 0, rt = 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>; 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 let Defs = [HI64] in
def MTHI64 : MoveToLOHI64<0x11, "mthi">; def MTHI64 : MoveToLOHI64<0x11, "mthi">;
let Defs = [LO64] in let Defs = [LO64] in

View File

@ -237,6 +237,8 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
/// Mul with two results /// Mul with two results
case ISD::SMUL_LOHI: case ISD::SMUL_LOHI:
case ISD::UMUL_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 Op1 = Node->getOperand(0);
SDValue Op2 = Node->getOperand(1); SDValue Op2 = Node->getOperand(1);
@ -262,21 +264,29 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
/// Special Muls /// Special Muls
case ISD::MUL: case ISD::MUL:
if (Subtarget.hasMips32()) // Mips32 has a 32-bit three operand mul instruction.
if (Subtarget.hasMips32() && Node->getValueType(0) == MVT::i32)
break; break;
case ISD::MULHS: case ISD::MULHS:
case ISD::MULHU: { 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 MulOp1 = Node->getOperand(0);
SDValue MulOp2 = Node->getOperand(1); 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, SDNode *MulNode = CurDAG->getMachineNode(MulOp, dl,
MVT::Glue, MulOp1, MulOp2); MVT::Glue, MulOp1, MulOp2);
SDValue InFlag = SDValue(MulNode, 0); SDValue InFlag = SDValue(MulNode, 0);
if (Opcode == ISD::MUL) if (Opcode == ISD::MUL) {
return CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, InFlag); unsigned Opc = (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64);
return CurDAG->getMachineNode(Opc, dl, Ty, InFlag);
}
else else
return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag); return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
} }

View File

@ -70,3 +70,16 @@ entry:
ret i64 %xor 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
}