reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical SUBREGs of CONST_INTs.
authorJ"orn Rennecke <amylaar@cygnus.co.uk>
Mon, 9 Feb 1998 19:39:35 +0000 (19:39 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Mon, 9 Feb 1998 19:39:35 +0000 (19:39 +0000)
* reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical
SUBREGs of CONST_INTs.

From-SVN: r17809

gcc/ChangeLog
gcc/reload.c

index 8b8eaa7..56cd65e 100644 (file)
@@ -1,3 +1,8 @@
+Tue Feb 10 03:35:43 1998  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical
+       SUBREGs of CONST_INTs.
+
 Mon Feb  9 17:52:36 1998  John Carr  <jfc@mit.edu>
 
        * mips.c (print_operand, function_prologue): Make printf format
index 6006357..22c8c4e 100644 (file)
@@ -1,5 +1,5 @@
 /* Search an insn for pseudo regs that must be in hard regs and are not.
-   Copyright (C) 1987, 88, 89, 92-6, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 89, 92-7, 1998 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -4163,6 +4163,29 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
                                     GET_MODE (SUBREG_REG (x)))) != 0)
        return tem;
 
+      /* If the SUBREG is wider than a word, the above test will fail.
+        For example, we might have a SImode SUBREG of a DImode SUBREG_REG
+        for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
+        a 32 bit target.  We still can - and have to - handle this
+        for non-paradoxical subregs of CONST_INTs.  */
+      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
+         && reg_equiv_constant[regno] != 0
+         && GET_CODE (reg_equiv_constant[regno]) == CONST_INT
+         && (GET_MODE_SIZE (GET_MODE (x))
+             < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
+         {
+           int shift = SUBREG_WORD (x) * BITS_PER_WORD;
+           if (WORDS_BIG_ENDIAN)
+             shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
+                      - GET_MODE_BITSIZE (GET_MODE (x))
+                      - shift);
+           /* Here we use the knowledge that CONST_INTs have a
+              HOST_WIDE_INT field.  */
+           if (shift >= HOST_BITS_PER_WIDE_INT)
+             shift = HOST_BITS_PER_WIDE_INT - 1;
+           return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
+         }
+
       if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
          && reg_equiv_constant[regno] != 0
          && GET_MODE (reg_equiv_constant[regno]) == VOIDmode)