http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54699



--- Comment #3 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-09-30 21:09:29 
UTC ---

Doing this...



Index: gcc/config/sh/sh.c

===================================================================

--- gcc/config/sh/sh.c    (revision 191865)

+++ gcc/config/sh/sh.c    (working copy)

@@ -10079,6 +10079,9 @@

 static bool

 sh_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)

 {

+  if (reload_completed)

+    return true;

+

   if (MAYBE_BASE_REGISTER_RTX_P (x, strict))

     return true;

   else if ((GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)





makes the ICE go away.  However, I have not tested this for any other

consequences.



This one is probably the better fix (max_mov_insn_displacement):



Index: gcc/config/sh/sh.c

===================================================================

--- gcc/config/sh/sh.c    (revision 191865)

+++ gcc/config/sh/sh.c    (working copy)

@@ -3457,21 +3457,20 @@



   /* SH2A supports FPU move insns with 12 bit displacements.

      Other variants to do not support any kind of displacements for

-     FPU move insns.  */

-  if (! consider_sh2a && TARGET_FPU_ANY && GET_MODE_CLASS (mode) ==

MODE_FLOAT)

-    return 0;

-  else

-    {

-      const int mov_insn_sz = mov_insn_size (mode, consider_sh2a);

-      const int mode_sz = GET_MODE_SIZE (mode);

-      int r = 15 * mov_insn_sz * disp_scale;

+     FPU move insns.  However, in the worst case, we can still use SImode

+     loads/stores with displacement, such as in the movsf_ie pattern instead

+     of true FPU move insns.  It's just going to be more expensive because

+     additional gp reg <-> fpu reg moves have to be used for that.  */

+  const int mov_insn_sz = mov_insn_size (mode, consider_sh2a);

+  const int mode_sz = GET_MODE_SIZE (mode);

+  int r = 15 * mov_insn_sz * disp_scale;



-      /* If the mov insn will be split into multiple loads/stores, the

-     maximum possible displacement is a bit smaller.  */

-      if (mode_sz > mov_insn_sz)

-    r -= mode_sz - mov_insn_sz;

-      return r;

-    }

+  /* If the mov insn will be split into multiple loads/stores, the

+     maximum possible displacement is a bit smaller.  */

+  if (mode_sz > mov_insn_sz)

+    r -= mode_sz - mov_insn_sz;

+

+  return r;

 }



 /* Determine the alignment mask for a move insn of the





This makes the ICE go away, but it will wrongly output SH2A fmov.s insns such

as

    fmov.s    @(16,r7),fr3



when compiling for SH4.



The movsf_ie insn looks a bit ... complicated ... and probably should be split

into multiple insns to be able to handle such cases.



Maybe there's an even easier solution, but I can't imagine one at the moment.

Reply via email to