mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Add support for 64-bit integer multiply instructions.
llvm-svn: 141017
This commit is contained in:
parent
3f3d72c052
commit
e3c1d7eac0
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user