mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-14 23:29:51 +00:00
Provide "wide" muls and divs/rems
llvm-svn: 75958
This commit is contained in:
parent
6ad41d1540
commit
d984dc6c9d
@ -41,8 +41,9 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) :
|
||||
RegInfo = TM.getRegisterInfo();
|
||||
|
||||
// Set up the register classes.
|
||||
addRegisterClass(MVT::i32, SystemZ::GR32RegisterClass);
|
||||
addRegisterClass(MVT::i64, SystemZ::GR64RegisterClass);
|
||||
addRegisterClass(MVT::i32, SystemZ::GR32RegisterClass);
|
||||
addRegisterClass(MVT::i64, SystemZ::GR64RegisterClass);
|
||||
addRegisterClass(MVT::i128, SystemZ::GR128RegisterClass);
|
||||
|
||||
// Compute derived properties from the register classes
|
||||
computeRegisterProperties();
|
||||
@ -73,16 +74,10 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) :
|
||||
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
|
||||
|
||||
// FIXME: We can lower this better
|
||||
setOperationAction(ISD::MULHS, MVT::i32, Expand);
|
||||
// Funny enough: we don't have 64-bit signed versions of these stuff, but have
|
||||
// unsigned.
|
||||
setOperationAction(ISD::MULHS, MVT::i64, Expand);
|
||||
setOperationAction(ISD::MULHU, MVT::i32, Expand);
|
||||
setOperationAction(ISD::MULHU, MVT::i64, Expand);
|
||||
|
||||
setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
|
||||
}
|
||||
|
||||
SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
|
@ -83,18 +83,20 @@ bool SystemZInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
|
||||
CommonRC = 0;
|
||||
|
||||
if (CommonRC) {
|
||||
unsigned Opc;
|
||||
if (CommonRC == &SystemZ::GR64RegClass ||
|
||||
CommonRC == &SystemZ::ADDR64RegClass) {
|
||||
Opc = SystemZ::MOV64rr;
|
||||
BuildMI(MBB, I, DL, get(SystemZ::MOV64rr), DestReg).addReg(SrcReg);
|
||||
} else if (CommonRC == &SystemZ::GR32RegClass ||
|
||||
CommonRC == &SystemZ::ADDR32RegClass) {
|
||||
Opc = SystemZ::MOV32rr;
|
||||
BuildMI(MBB, I, DL, get(SystemZ::MOV32rr), DestReg).addReg(SrcReg);
|
||||
} else if (CommonRC == &SystemZ::GR64PRegClass) {
|
||||
BuildMI(MBB, I, DL, get(SystemZ::MOV64rrP), DestReg).addReg(SrcReg);
|
||||
} else if (CommonRC == &SystemZ::GR128RegClass) {
|
||||
BuildMI(MBB, I, DL, get(SystemZ::MOV128rr), DestReg).addReg(SrcReg);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
BuildMI(MBB, I, DL, get(Opc), DestReg).addReg(SrcReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -126,6 +128,8 @@ SystemZInstrInfo::isMoveInstr(const MachineInstr& MI,
|
||||
return false;
|
||||
case SystemZ::MOV32rr:
|
||||
case SystemZ::MOV64rr:
|
||||
case SystemZ::MOV64rrP:
|
||||
case SystemZ::MOV128rr:
|
||||
assert(MI.getNumOperands() >= 2 &&
|
||||
MI.getOperand(0).isReg() &&
|
||||
MI.getOperand(1).isReg() &&
|
||||
|
@ -330,6 +330,16 @@ def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src),
|
||||
def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src),
|
||||
"lgr\t{$dst, $src}",
|
||||
[]>;
|
||||
def MOV128rr : Pseudo<(outs GR128:$dst), (ins GR128:$src),
|
||||
"# MOV128 PSEUDO!"
|
||||
"lgr\t{$dst:subreg_odd, $src:subreg_odd}\n"
|
||||
"lgr\t{$dst:subreg_even, $src:subreg_even}",
|
||||
[]>;
|
||||
def MOV64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src),
|
||||
"# MOV64P PSEUDO!"
|
||||
"lr\t{$dst:subreg_odd, $src:subreg_odd}\n"
|
||||
"lr\t{$dst:subreg_even, $src:subreg_even}",
|
||||
[]>;
|
||||
}
|
||||
|
||||
def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
|
||||
@ -616,8 +626,19 @@ def MUL32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
|
||||
def MUL64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
|
||||
"msgr\t{$dst, $src2}",
|
||||
[(set GR64:$dst, (mul GR64:$src1, GR64:$src2))]>;
|
||||
|
||||
def MUL64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
|
||||
"mr\t{$dst, $src2}",
|
||||
[]>;
|
||||
def UMUL64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
|
||||
"mlr\t{$dst, $src2}",
|
||||
[]>;
|
||||
def UMUL128rrP : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
|
||||
"mlgr\t{$dst, $src2}",
|
||||
[]>;
|
||||
}
|
||||
|
||||
|
||||
def MUL32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32i16imm:$src2),
|
||||
"mhi\t{$dst, $src2}",
|
||||
[(set GR32:$dst, (mul GR32:$src1, i32immSExt16:$src2))]>;
|
||||
@ -641,6 +662,23 @@ def MUL64rm : Pseudo<(outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
|
||||
def MULSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR32:$src2),
|
||||
"msgfr\t{$dst, $src2}",
|
||||
[(set GR64:$dst, (mul GR64:$src1, (sext GR32:$src2)))]>;
|
||||
|
||||
def SDIVREM64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
|
||||
"dr\t{$dst, $src2}",
|
||||
[]>;
|
||||
|
||||
def SDIVREM128rrP : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
|
||||
"dsgr\t{$dst, $src2}",
|
||||
[]>;
|
||||
|
||||
def UDIVREM64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
|
||||
"dlr\t{$dst, $src2}",
|
||||
[]>;
|
||||
|
||||
def UDIVREM128rrP : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
|
||||
"dlgr\t{$dst, $src2}",
|
||||
[]>;
|
||||
|
||||
} // isTwoAddress = 1
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -794,3 +832,67 @@ def : Pat<(SystemZcall (i64 tglobaladdr:$dst)),
|
||||
(CALLi tglobaladdr:$dst)>;
|
||||
def : Pat<(SystemZcall (i64 texternalsym:$dst)),
|
||||
(CALLi texternalsym:$dst)>;
|
||||
|
||||
// muls
|
||||
def : Pat<(mulhs GR32:$src1, GR32:$src2),
|
||||
(EXTRACT_SUBREG (MUL64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
|
||||
GR32:$src1, subreg_odd),
|
||||
GR32:$src2),
|
||||
subreg_even)>;
|
||||
|
||||
def : Pat<(mulhu GR32:$src1, GR32:$src2),
|
||||
(EXTRACT_SUBREG (UMUL64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
|
||||
GR32:$src1, subreg_odd),
|
||||
GR32:$src2),
|
||||
subreg_even)>;
|
||||
def : Pat<(mulhu GR64:$src1, GR64:$src2),
|
||||
(EXTRACT_SUBREG (UMUL128rrP (INSERT_SUBREG (i128 (IMPLICIT_DEF)),
|
||||
GR64:$src1, subreg_odd),
|
||||
GR64:$src2),
|
||||
subreg_even)>;
|
||||
|
||||
// divs
|
||||
// FIXME: Add memory versions
|
||||
def : Pat<(sdiv GR32:$src1, GR32:$src2),
|
||||
(EXTRACT_SUBREG (SDIVREM64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
|
||||
GR32:$src1, subreg_odd),
|
||||
GR32:$src2),
|
||||
subreg_odd)>;
|
||||
def : Pat<(sdiv GR64:$src1, GR64:$src2),
|
||||
(EXTRACT_SUBREG (SDIVREM128rrP (INSERT_SUBREG (i128 (IMPLICIT_DEF)),
|
||||
GR64:$src1, subreg_odd),
|
||||
GR64:$src2),
|
||||
subreg_odd)>;
|
||||
def : Pat<(udiv GR32:$src1, GR32:$src2),
|
||||
(EXTRACT_SUBREG (UDIVREM64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
|
||||
GR32:$src1, subreg_odd),
|
||||
GR32:$src2),
|
||||
subreg_odd)>;
|
||||
def : Pat<(udiv GR64:$src1, GR64:$src2),
|
||||
(EXTRACT_SUBREG (UDIVREM128rrP (INSERT_SUBREG (i128 (IMPLICIT_DEF)),
|
||||
GR64:$src1, subreg_odd),
|
||||
GR64:$src2),
|
||||
subreg_odd)>;
|
||||
|
||||
// rems
|
||||
// FIXME: Add memory versions
|
||||
def : Pat<(srem GR32:$src1, GR32:$src2),
|
||||
(EXTRACT_SUBREG (SDIVREM64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
|
||||
GR32:$src1, subreg_odd),
|
||||
GR32:$src2),
|
||||
subreg_even)>;
|
||||
def : Pat<(srem GR64:$src1, GR64:$src2),
|
||||
(EXTRACT_SUBREG (SDIVREM128rrP (INSERT_SUBREG (i128 (IMPLICIT_DEF)),
|
||||
GR64:$src1, subreg_odd),
|
||||
GR64:$src2),
|
||||
subreg_even)>;
|
||||
def : Pat<(urem GR32:$src1, GR32:$src2),
|
||||
(EXTRACT_SUBREG (UDIVREM64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
|
||||
GR32:$src1, subreg_odd),
|
||||
GR32:$src2),
|
||||
subreg_even)>;
|
||||
def : Pat<(urem GR64:$src1, GR64:$src2),
|
||||
(EXTRACT_SUBREG (UDIVREM128rrP (INSERT_SUBREG (i128 (IMPLICIT_DEF)),
|
||||
GR64:$src1, subreg_odd),
|
||||
GR64:$src2),
|
||||
subreg_even)>;
|
||||
|
55
test/CodeGen/SystemZ/08-DivRem.ll
Normal file
55
test/CodeGen/SystemZ/08-DivRem.ll
Normal file
@ -0,0 +1,55 @@
|
||||
; RUN: llvm-as < %s | llc | grep dsgr | count 2
|
||||
; RUN: llvm-as < %s | llc | grep dr | count 2
|
||||
; RUN: llvm-as < %s | llc | grep dlr | count 2
|
||||
; RUN: llvm-as < %s | llc | grep dlgr | count 2
|
||||
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define i64 @div(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%div = sdiv i64 %a, %b ; <i64> [#uses=1]
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i32 @div1(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%div = sdiv i32 %a, %b ; <i32> [#uses=1]
|
||||
ret i32 %div
|
||||
}
|
||||
|
||||
define i64 @div2(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%div = udiv i64 %a, %b ; <i64> [#uses=1]
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i32 @div3(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%div = udiv i32 %a, %b ; <i32> [#uses=1]
|
||||
ret i32 %div
|
||||
}
|
||||
|
||||
define i64 @rem(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%rem = srem i64 %a, %b ; <i64> [#uses=1]
|
||||
ret i64 %rem
|
||||
}
|
||||
|
||||
define i32 @rem1(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%rem = srem i32 %a, %b ; <i32> [#uses=1]
|
||||
ret i32 %rem
|
||||
}
|
||||
|
||||
define i64 @rem2(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%rem = urem i64 %a, %b ; <i64> [#uses=1]
|
||||
ret i64 %rem
|
||||
}
|
||||
|
||||
define i32 @rem3(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%rem = urem i32 %a, %b ; <i32> [#uses=1]
|
||||
ret i32 %rem
|
||||
}
|
Loading…
Reference in New Issue
Block a user