]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/24950 (ICE in operand_subword_force)
authorAlan Modra <amodra@bigpond.net.au>
Wed, 23 Nov 2005 12:05:41 +0000 (12:05 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Wed, 23 Nov 2005 12:05:41 +0000 (22:35 +1030)
PR middle-end/24950
* expmed.c (store_bit_field): Don't attempt to insv a field
larger than the reg.

Merge from trunk
2005-11-14  Dale Johannesen  <dalej@apple.com>
* expmed.c (store_bit_field):  Add offset unconditionally for
memory targets.
(extract_bit_field):  Don't force extzv or extv operand into
a register if field is too big.
2004-12-01  Richard Henderson  <rth@redhat.com>
* expmed.c (store_bit_field): Use simplify_gen_subreg instead
of gen_rtx_SUBREG directly.

From-SVN: r107417

gcc/ChangeLog
gcc/expmed.c

index b5b3a51a111982b5bc5c9d5e6eedf411686de72d..7a17471c0f6c461ae901e76ceb224616a13bca6b 100644 (file)
@@ -1,3 +1,19 @@
+2005-11-23  Alan Modra  <amodra@bigpond.net.au>
+
+       PR middle-end/24950
+       * expmed.c (store_bit_field): Don't attempt to insv a field
+       larger than the reg.
+
+       Merge from trunk
+       2005-11-14  Dale Johannesen  <dalej@apple.com>
+       * expmed.c (store_bit_field):  Add offset unconditionally for
+       memory targets.
+       (extract_bit_field):  Don't force extzv or extv operand into
+       a register if field is too big.
+       2004-12-01  Richard Henderson  <rth@redhat.com>
+       * expmed.c (store_bit_field): Use simplify_gen_subreg instead
+       of gen_rtx_SUBREG directly.
+
 2005-11-16  Steve Ellcey  <sje@cup.hp.com>
 
        PR target/24718
index a8039346dd2a474ee1b40fb08e131c4fbb966f67..864f78a77d06dca5fd5cd0c41ed91732f749bcb8 100644 (file)
@@ -389,25 +389,11 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
             || (offset * BITS_PER_UNIT % bitsize == 0
                 && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
     {
-      if (GET_MODE (op0) != fieldmode)
-       {
-         if (GET_CODE (op0) == SUBREG)
-           {
-             if (GET_MODE (SUBREG_REG (op0)) == fieldmode
-                 || GET_MODE_CLASS (fieldmode) == MODE_INT
-                 || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT)
-               op0 = SUBREG_REG (op0);
-             else
-               /* Else we've got some float mode source being extracted into
-                  a different float mode destination -- this combination of
-                  subregs results in Severe Tire Damage.  */
-               abort ();
-           }
-         if (GET_CODE (op0) == REG)
-           op0 = gen_rtx_SUBREG (fieldmode, op0, byte_offset);
-         else
-           op0 = adjust_address (op0, fieldmode, offset);
-       }
+      if (GET_CODE (op0) == MEM)
+       op0 = adjust_address (op0, fieldmode, offset);
+      else if (GET_MODE (op0) != fieldmode)
+       op0 = simplify_gen_subreg (fieldmode, op0, GET_MODE (op0),
+                                  byte_offset);
       emit_move_insn (op0, value);
       return value;
     }
@@ -622,6 +608,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
            bestmode = GET_MODE (op0);
 
          if (bestmode == VOIDmode
+             || GET_MODE_SIZE (bestmode) < GET_MODE_SIZE (fieldmode)
              || (SLOW_UNALIGNED_ACCESS (bestmode, MEM_ALIGN (op0))
                  && GET_MODE_BITSIZE (bestmode) > MEM_ALIGN (op0)))
            goto insv_loses;
@@ -1401,6 +1388,11 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
                  xbitpos = bitnum % unit;
                  xop0 = adjust_address (xop0, bestmode, xoffset);
 
+                 /* Make sure register is big enough for the whole field. */
+                 if (xoffset * BITS_PER_UNIT + unit 
+                     < offset * BITS_PER_UNIT + bitsize)
+                   goto extzv_loses;
+
                  /* Fetch it to a register in that size.  */
                  xop0 = force_reg (bestmode, xop0);
 
@@ -1531,6 +1523,11 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
                  xbitpos = bitnum % unit;
                  xop0 = adjust_address (xop0, bestmode, xoffset);
 
+                 /* Make sure register is big enough for the whole field. */
+                 if (xoffset * BITS_PER_UNIT + unit 
+                     < offset * BITS_PER_UNIT + bitsize)
+                   goto extv_loses;
+
                  /* Fetch it to a register in that size.  */
                  xop0 = force_reg (bestmode, xop0);