OSDN Git Service

gcc/:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Apr 2007 04:11:47 +0000 (04:11 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Apr 2007 04:11:47 +0000 (04:11 +0000)
PR target/28675
* reload.c (find_reloads_subreg_address): If the address was valid
in the original mode but not in the new mode, reload the whole
address.
testsuite/:
PR target/28675
* gcc.c-torture/compile/pr28675.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124211 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/reload.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr28675.c [new file with mode: 0644]

index 2b6d43c..526c390 100644 (file)
@@ -1,3 +1,10 @@
+2007-04-26  Ian Lance Taylor  <iant@google.com>
+
+       PR target/28675
+       * reload.c (find_reloads_subreg_address): If the address was valid
+       in the original mode but not in the new mode, reload the whole
+       address.
+
 2007-04-27  Zdenek Dvorak  <dvorakz@suse.cz>
 
        * tree-cfgcleanup.c (cfgcleanup_altered_bbs): New global variable.
index b0374d8..de6093b 100644 (file)
@@ -6006,6 +6006,8 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
              unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
              int offset;
              rtx orig = tem;
+             enum machine_mode orig_mode = GET_MODE (orig);
+             int reloaded;
 
              /* For big-endian paradoxical subregs, SUBREG_BYTE does not
                 hold the correct (negative) byte offset.  */
@@ -6038,13 +6040,32 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
                    return x;
                }
 
-             find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
-                                   &XEXP (tem, 0), opnum, type,
-                                   ind_levels, insn);
+             reloaded = find_reloads_address (GET_MODE (tem), &tem,
+                                              XEXP (tem, 0), &XEXP (tem, 0),
+                                              opnum, type, ind_levels, insn);
              /* ??? Do we need to handle nonzero offsets somehow?  */
              if (!offset && !rtx_equal_p (tem, orig))
                push_reg_equiv_alt_mem (regno, tem);
 
+             /* For some processors an address may be valid in the
+                original mode but not in a smaller mode.  For
+                example, ARM accepts a scaled index register in
+                SImode but not in HImode.  find_reloads_address
+                assumes that we pass it a valid address, and doesn't
+                force a reload.  This will probably be fine if
+                find_reloads_address finds some reloads.  But if it
+                doesn't find any, then we may have just converted a
+                valid address into an invalid one.  Check for that
+                here.  */
+             if (reloaded != 1
+                 && strict_memory_address_p (orig_mode, XEXP (tem, 0))
+                 && !strict_memory_address_p (GET_MODE (tem),
+                                              XEXP (tem, 0)))
+               push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
+                            base_reg_class (GET_MODE (tem), MEM, SCRATCH),
+                            GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,
+                            opnum, type);
+
              /* If this is not a toplevel operand, find_reloads doesn't see
                 this substitution.  We have to emit a USE of the pseudo so
                 that delete_output_reload can see it.  */
index 6b7bcc7..40c811b 100644 (file)
@@ -1,3 +1,8 @@
+2007-04-26  Ian Lance Taylor  <iant@google.com>
+
+       PR target/28675
+       * gcc.c-torture/compile/pr28675.c: New test.
+
 2007-04-26  Andrew Pinski  <andrew_pinski@playstation.sony.com>
 
        PR C++/30016
@@ -79,7 +84,7 @@
 
 2007-04-24  Ian Lance Taylor  <iant@google.com>
 
-       PR tree-optimizatoin/31605
+       PR tree-optimization/31605
        * gcc.c-torture/execute/pr31605.c: New test.
 
 2007-04-24  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr28675.c b/gcc/testsuite/gcc.c-torture/compile/pr28675.c
new file mode 100644 (file)
index 0000000..0d78353
--- /dev/null
@@ -0,0 +1,38 @@
+struct fb_cmap {
+ unsigned int start;
+ unsigned int len;
+ unsigned short *red;
+ unsigned short *green;
+ unsigned short *blue;
+ unsigned short *transp;
+};
+
+typedef struct {
+    int r;
+    int g;
+    int b;
+    int a;
+} rgba_t;
+
+static unsigned int cmap_len;
+
+extern unsigned int red_len, green_len, blue_len, alpha_len;
+extern struct fb_cmap fb_cmap;
+extern rgba_t *clut;
+extern int fb_set_cmap(void);
+
+void directcolor_update_cmap(void)
+{
+    unsigned int i;
+
+    for (i = 0; i < cmap_len; i++) {
+      if (i < red_len)
+       fb_cmap.red[i] = clut[i].r;
+      if (i < green_len)
+       fb_cmap.green[i] = clut[i].g;
+      if (i < blue_len)
+       fb_cmap.blue[i] = clut[i].b;
+      if (fb_cmap.transp && i < alpha_len)
+       fb_cmap.transp[i] = clut[i].a;
+    }
+}