summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-28 12:47:21 +0000
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-28 12:47:21 +0000
commitd7041732999cc4ab850ff823358b34eba59af6bf (patch)
treea9bda2464d7b200ebd679487ccda3fef16f416b1
parent99005f0295bbd3d43057a21061be9e36015a7258 (diff)
downloadppe42-gcc-d7041732999cc4ab850ff823358b34eba59af6bf.tar.gz
ppe42-gcc-d7041732999cc4ab850ff823358b34eba59af6bf.zip
PR target/15286
* final.c (alter_subreg): Compute correct offset to use with paradoxical SUBREGs of memory operands. * recog.c (general_operand): Allow paradoxical SUBREGs of memory operands after reload. * simplify-rtx.c (simplify_gen_subreg): Fail if simplify_subreg has failed when passed a hard register. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89752 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/final.c19
-rw-r--r--gcc/recog.c6
-rw-r--r--gcc/simplify-rtx.c3
4 files changed, 34 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4eb71fbc149..e4de1ded60c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2004-10-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR target/15286
+ * final.c (alter_subreg): Compute correct offset to use with
+ paradoxical SUBREGs of memory operands.
+ * recog.c (general_operand): Allow paradoxical SUBREGs of
+ memory operands after reload.
+ * simplify-rtx.c (simplify_gen_subreg): Fail if simplify_subreg
+ has failed when passed a hard register.
+
2004-10-28 Aldy Hernandez <aldyh@redhat.com>
* function.c (assign_parm_setup_block): Handle parallels correctly.
diff --git a/gcc/final.c b/gcc/final.c
index bf4f521bcf5..3952b9ff82c 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2608,7 +2608,24 @@ alter_subreg (rtx *xp)
/* simplify_subreg does not remove subreg from volatile references.
We are required to. */
if (MEM_P (y))
- *xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x));
+ {
+ int offset = SUBREG_BYTE (x);
+
+ /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
+ contains 0 instead of the proper offset. See simplify_subreg. */
+ if (offset == 0
+ && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
+ {
+ int difference = GET_MODE_SIZE (GET_MODE (y))
+ - GET_MODE_SIZE (GET_MODE (x));
+ if (WORDS_BIG_ENDIAN)
+ offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
+ if (BYTES_BIG_ENDIAN)
+ offset += difference % UNITS_PER_WORD;
+ }
+
+ *xp = adjust_address (y, GET_MODE (x), offset);
+ }
else
{
rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
diff --git a/gcc/recog.c b/gcc/recog.c
index 61e1186d07a..eeb37afe9bb 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -936,8 +936,10 @@ general_operand (rtx op, enum machine_mode mode)
#ifdef INSN_SCHEDULING
/* On machines that have insn scheduling, we want all memory
- reference to be explicit, so outlaw paradoxical SUBREGs. */
- if (MEM_P (sub)
+ reference to be explicit, so outlaw paradoxical SUBREGs.
+ However, we must allow them after reload so that they can
+ get cleaned up by cleanup_subreg_operands. */
+ if (!reload_completed && MEM_P (sub)
&& GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (sub)))
return 0;
#endif
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 4af468a40ca..e463fef1efe 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -3789,7 +3789,8 @@ simplify_gen_subreg (enum machine_mode outermode, rtx op,
if (newx)
return newx;
- if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode)
+ if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode
+ || (REG_P (op) && REGNO (op) < FIRST_PSEUDO_REGISTER))
return NULL_RTX;
return gen_rtx_SUBREG (outermode, op, byte);
OpenPOWER on IntegriCloud