summaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-07-16 14:17:52 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-07-16 14:17:52 +0000
commit09e39001da6a17531b32849964899ccaf50c2cb9 (patch)
tree34d3437a1e7aac56173f2a55957f44a5caf46357 /lib/Target
parentcd3dfafef134ca0b923f8e80910c0f1e1fc50d3d (diff)
downloadllvm-09e39001da6a17531b32849964899ccaf50c2cb9.tar.gz
llvm-09e39001da6a17531b32849964899ccaf50c2cb9.tar.bz2
llvm-09e39001da6a17531b32849964899ccaf50c2cb9.tar.xz
Use divide single for 32 bit signed divides
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76010 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/SystemZ/SystemZISelDAGToDAG.cpp34
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td8
2 files changed, 28 insertions, 14 deletions
diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index c63376683a..8ca936f07d 100644
--- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -636,17 +636,18 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
switch (Opcode) {
default: break;
case ISD::SDIVREM: {
- unsigned Opc, MOpc, ClrOpc = 0;
+ unsigned Opc, MOpc;
SDValue N0 = Node->getOperand(0);
SDValue N1 = Node->getOperand(1);
MVT ResVT;
+ bool is32Bit = false;
switch (NVT.getSimpleVT()) {
default: assert(0 && "Unsupported VT!");
case MVT::i32:
Opc = SystemZ::SDIVREM32r; MOpc = SystemZ::SDIVREM32m;
- ClrOpc = SystemZ::MOV64Pr0_even;
- ResVT = MVT::v2i32;
+ ResVT = MVT::v2i64;
+ is32Bit = true;
break;
case MVT::i64:
Opc = SystemZ::SDIVREM64r; MOpc = SystemZ::SDIVREM64m;
@@ -658,7 +659,11 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
bool foldedLoad = TryFoldLoad(Op, N1, Tmp0, Tmp1, Tmp2);
// Prepare the dividend
- SDNode *Dividend = N0.getNode();
+ SDNode *Dividend;
+ if (is32Bit)
+ Dividend = CurDAG->getTargetNode(SystemZ::MOVSX64rr32, dl, MVT::i64, N0);
+ else
+ Dividend = N0.getNode();
// Insert prepared dividend into suitable 'subreg'
SDNode *Tmp = CurDAG->getTargetNode(TargetInstrInfo::IMPLICIT_DEF,
@@ -668,10 +673,6 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
SDValue(Tmp, 0), SDValue(Dividend, 0),
CurDAG->getTargetConstant(subreg_odd, MVT::i32));
- // Zero out even subreg, if needed
- if (ClrOpc)
- Dividend = CurDAG->getTargetNode(ClrOpc, dl, ResVT, SDValue(Dividend, 0));
-
SDNode *Result;
SDValue DivVal = SDValue(Dividend, 0);
if (foldedLoad) {
@@ -686,10 +687,16 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
// Copy the division (odd subreg) result, if it is needed.
if (!Op.getValue(0).use_empty()) {
SDNode *Div = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,
- dl, NVT,
+ dl, (is32Bit ? MVT::v2i32 : MVT::i64),
SDValue(Result, 0),
CurDAG->getTargetConstant(subreg_odd,
MVT::i32));
+ if (is32Bit)
+ Div = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,
+ dl, NVT,
+ SDValue(Div, 0),
+ CurDAG->getTargetConstant(subreg_32bit,
+ MVT::i32));
ReplaceUses(Op.getValue(0), SDValue(Div, 0));
#ifndef NDEBUG
DOUT << std::string(Indent-2, ' ') << "=> ";
@@ -701,10 +708,17 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
// Copy the remainder (even subreg) result, if it is needed.
if (!Op.getValue(1).use_empty()) {
SDNode *Rem = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,
- dl, NVT,
+ dl, (is32Bit ? MVT::v2i32 : MVT::i64),
SDValue(Result, 0),
CurDAG->getTargetConstant(subreg_even,
MVT::i32));
+ if (is32Bit)
+ Rem = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,
+ dl, NVT,
+ SDValue(Rem, 0),
+ CurDAG->getTargetConstant(subreg_32bit,
+ MVT::i32));
+
ReplaceUses(Op.getValue(1), SDValue(Rem, 0));
#ifndef NDEBUG
DOUT << std::string(Indent-2, ' ') << "=> ";
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td
index b4e25e6c3a..d5364aefed 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -588,8 +588,8 @@ 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 SDIVREM32r : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
- "dr\t{$dst, $src2}",
+def SDIVREM32r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR32:$src2),
+ "dsgfr\t{$dst, $src2}",
[]>;
def SDIVREM64r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
"dsgr\t{$dst, $src2}",
@@ -602,8 +602,8 @@ def UDIVREM64r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
"dlgr\t{$dst, $src2}",
[]>;
let mayLoad = 1 in {
-def SDIVREM32m : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, rriaddr:$src2),
- "d\t{$dst, $src2}",
+def SDIVREM32m : Pseudo<(outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
+ "dsgf\t{$dst, $src2}",
[]>;
def SDIVREM64m : Pseudo<(outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
"dsg\t{$dst, $src2}",