summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-07-16 13:56:42 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-07-16 13:56:42 +0000
commitf0d7d6ce65371000aa2bcecca2c4f15b17fb2530 (patch)
tree0dc2e1e0fa4f92160b7edee17695132d390c3d01 /llvm/lib
parentd919010b6a37bad35a52edf2242a41420ef890de (diff)
downloadbcm5719-llvm-f0d7d6ce65371000aa2bcecca2c4f15b17fb2530.tar.gz
bcm5719-llvm-f0d7d6ce65371000aa2bcecca2c4f15b17fb2530.zip
Provide "wide" muls and divs/rems
llvm-svn: 75958
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelLowering.cpp15
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp12
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.td102
3 files changed, 115 insertions, 14 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index a5999feaa3e..62bd46b011c 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -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) {
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 9734709c6b3..0348e1e5ca8 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -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() &&
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index 4b5a9ce3ba9..f58021cf737 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -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)>;
OpenPOWER on IntegriCloud