From eab2120d5efebd6b7c29730692ff165b471b7eac Mon Sep 17 00:00:00 2001 From: "J\"orn Rennecke" Date: Mon, 22 Jul 2002 14:29:28 +0000 Subject: [PATCH] rtlanal.c (subreg_regno_offset): Return correct offset for big endian paradoxical subregs. * rtlanal.c (subreg_regno_offset): Return correct offset for big endian paradoxical subregs. From-SVN: r55650 --- gcc/ChangeLog | 5 ++++- gcc/rtlanal.c | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f413bb8dc0..398ce7364ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,7 @@ -Mon Jul 22 15:21:41 2002 J"orn Rennecke +Mon Jul 22 15:27:25 2002 J"orn Rennecke + + * rtlanal.c (subreg_regno_offset): Return correct offset for + big endian paradoxical subregs. * optabs.c (expand_vector_unop): Don't expand using sub_optab if we got the wrong mode. diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index de7efae2d5f..c1fdb7604ae 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -3117,6 +3117,16 @@ subreg_regno_offset (xregno, xmode, offset, ymode) nregs_xmode = HARD_REGNO_NREGS (xregno, xmode); nregs_ymode = HARD_REGNO_NREGS (xregno, ymode); + + /* If this is a big endian paradoxical subreg, which uses more actual + hard registers than the original register, we must return a negative + offset so that we find the proper highpart of the register. */ + if (offset == 0 + && nregs_ymode > nregs_xmode + && (GET_MODE_SIZE (ymode) > UNITS_PER_WORD + ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN)) + return nregs_xmode - nregs_ymode; + if (offset == 0 || nregs_xmode == nregs_ymode) return 0;