aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rix <trix@redhat.com>2002-01-02 03:48:53 +0000
committerTom Rix <trix@gcc.gnu.org>2002-01-02 03:48:53 +0000
commit252b88f78c6dd7615992ef7e89be748251b7257d (patch)
tree20a15e63d1644beb9bbddbd4e0a7125db9510a06
parent99e9e773cba195bd70a4c757d46afe9b55f6c399 (diff)
downloadgcc-252b88f78c6dd7615992ef7e89be748251b7257d.zip
gcc-252b88f78c6dd7615992ef7e89be748251b7257d.tar.gz
gcc-252b88f78c6dd7615992ef7e89be748251b7257d.tar.bz2
Fix for rs6000_emit_allocate_stack's use of rs6000_emit_set_long_const for ppc64.
From-SVN: r48458
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/rs6000/rs6000.c39
2 files changed, 39 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a9eaf973..c4f7c95 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -19,6 +19,11 @@
* tree.h: Document new use of TREE_ADDRESSABLE.
(expand_expr_stmt_value): Declare.
+2002-01-01 Tom Rix <trix@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_set_long_const): Fix for use by
+ rs6000_emit_allocate_stack.
+
2002-01-01 Joseph S. Myers <jsm28@cam.ac.uk>
* configure.in: Prepend ${srcdir}/config/${cpu_type}/ instead of
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 2b3587c..c244552 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2002,7 +2002,12 @@ rs6000_emit_set_long_const (dest, c1, c2)
}
else
{
- HOST_WIDE_INT d1, d2, d3, d4;
+ HOST_WIDE_INT d1, d2, d2_s, d3, d4;
+
+ /* This function is called by rs6000_emit_allocate_stack after reload
+ with a dest of r0. r0 is an invalid register for addsi. Use an addi
+ and a shift instead. */
+ int regnum = REGNO (dest);
/* Decompose the entire word */
#if HOST_BITS_PER_WIDE_INT >= 64
@@ -2011,6 +2016,7 @@ rs6000_emit_set_long_const (dest, c1, c2)
d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d1;
d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ d2_s = d2 >> 16;
c1 = (c1 - d2) >> 32;
d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d3;
@@ -2021,6 +2027,7 @@ rs6000_emit_set_long_const (dest, c1, c2)
d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d1;
d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ d2_s = d2 >> 16;
if (c1 != d2)
abort ();
c2 += (d2 < 0);
@@ -2039,18 +2046,40 @@ rs6000_emit_set_long_const (dest, c1, c2)
emit_move_insn (dest,
gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
}
- else
+ else if (d3 != 0)
emit_move_insn (dest, GEN_INT (d3));
/* Shift it into place */
if (d3 != 0 || d4 != 0)
- emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
+ if (regnum == 0 && d2 != 0)
+ emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
+ else
+ emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
/* Add in the low bits. */
if (d2 != 0)
- emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d2)));
+ {
+ if (d3 != 0 || d4 != 0)
+ {
+ if (regnum == 0)
+ {
+ emit_move_insn (dest, gen_rtx_PLUS (DImode, dest,
+ GEN_INT (d2_s)));
+ emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest,
+ GEN_INT (16)));
+ }
+ else
+ emit_move_insn (dest, gen_rtx_PLUS (DImode, dest,
+ GEN_INT (d2)));
+ }
+ else
+ emit_move_insn (dest, GEN_INT (d2));
+ }
if (d1 != 0)
- emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
+ if (d2 != 0 || d3 != 0 || d4 != 0)
+ emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
+ else
+ emit_move_insn (dest, GEN_INT (d1));
}
return dest;