diff options
author | trix <trix@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-01-02 03:48:53 +0000 |
---|---|---|
committer | trix <trix@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-01-02 03:48:53 +0000 |
commit | 60d2983e1746fac6d4399a12f64f1e918a8f62cb (patch) | |
tree | 20a15e63d1644beb9bbddbd4e0a7125db9510a06 /gcc | |
parent | 53a3481b90431f7ae7d4dcb5048f40e73bf9f05c (diff) | |
download | gcc-60d2983e1746fac6d4399a12f64f1e918a8f62cb.tar.gz |
Fix for rs6000_emit_allocate_stack's use of rs6000_emit_set_long_const for ppc64.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@48458 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 39 |
2 files changed, 39 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a9eaf973d7f..c4f7c950878 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 2b3587c1050..c2445522fbb 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; |