From cf54c2cdf26dc45f2d39cf0fa73a6ddd6ed8daf9 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Sat, 23 Mar 1996 22:07:00 +0000 Subject: [PATCH] (make_extraction): In BITS_BIG_ENDIAN correction of POS, need to treat MEM and REG differently. From-SVN: r11603 --- gcc/combine.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/gcc/combine.c b/gcc/combine.c index 9fe68356c61c..fdc0060e49c3 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