diff options
author | Doug Evans <dje@gnu.org> | 1996-03-23 22:07:00 +0000 |
---|---|---|
committer | Doug Evans <dje@gnu.org> | 1996-03-23 22:07:00 +0000 |
commit | cf54c2cdf26dc45f2d39cf0fa73a6ddd6ed8daf9 (patch) | |
tree | 59cdc49ba8dd13f814331cabd8a0ebf7526914a0 /gcc | |
parent | 57b7e1bf863f4e38f9b32ded83c11a337a193283 (diff) | |
download | gcc-cf54c2cdf26dc45f2d39cf0fa73a6ddd6ed8daf9.zip gcc-cf54c2cdf26dc45f2d39cf0fa73a6ddd6ed8daf9.tar.gz gcc-cf54c2cdf26dc45f2d39cf0fa73a6ddd6ed8daf9.tar.bz2 |
(make_extraction): In BITS_BIG_ENDIAN correction of POS, need to treat
MEM and REG differently.
From-SVN: r11603
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/combine.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 9fe6835..fdc0060 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -5272,16 +5272,25 @@ make_extraction (mode, inner, pos, pos_rtx, len, if (BITS_BIG_ENDIAN) { - /* If position is constant, compute new position. Otherwise, - build subtraction. */ + /* POS is passed as if BITS_BIG_ENDIAN == 0, so we need to convert it to + BITS_BIG_ENDIAN style. If position is constant, compute new + position. Otherwise, build subtraction. + Note that POS is relative to the mode of the original argument. + If it's a MEM we need to recompute POS relative to that. + However, if we're extracting from (or inserting into) a register, + we want to recompute POS relative to wanted_inner_mode. */ + int width = (GET_CODE (inner) == MEM + ? GET_MODE_BITSIZE (is_mode) + : GET_MODE_BITSIZE (wanted_inner_mode)); + if (pos_rtx == 0) - pos = GET_MODE_BITSIZE (wanted_inner_mode) - len - pos; + pos = width - len - pos; else pos_rtx = gen_rtx_combine (MINUS, GET_MODE (pos_rtx), - GEN_INT (GET_MODE_BITSIZE (wanted_inner_mode) - - len), - pos_rtx); + GEN_INT (width - len), pos_rtx); + /* POS may be less than 0 now, but we check for that below. + Note that it can only be less than 0 if GET_CODE (inner) != MEM. */ } /* If INNER has a wider mode, make it smaller. If this is a constant |