OSDN Git Service

PR target/37633
authorkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Oct 2008 23:40:41 +0000 (23:40 +0000)
committerkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Oct 2008 23:40:41 +0000 (23:40 +0000)
* config/sh/sh.c (sh_hard_regno_mode_ok): New function.
* config/sh/sh.h (HARD_REGNO_MODE_OK): Use it.
* config/sh/sh-protos.h (sh_hard_regno_mode_ok): Declare.

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

gcc/ChangeLog
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.h

index 08743f8..f95f4e4 100644 (file)
@@ -1,3 +1,10 @@
+2008-10-22  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       PR target/37633
+       * config/sh/sh.c (sh_hard_regno_mode_ok): New function.
+       * config/sh/sh.h (HARD_REGNO_MODE_OK): Use it.
+       * config/sh/sh-protos.h (sh_hard_regno_mode_ok): Declare.
+
 2008-10-22  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/37880
index a03c624..5b97196 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2003,
-   2004, 2005, 2006, 2007
+   2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed by Steve Chamberlain (sac@cygnus.com).
    Improved by Jim Wilson (wilson@cygnus.com).
@@ -174,7 +174,7 @@ extern enum reg_class sh_secondary_reload (bool, rtx, enum reg_class,
 extern int sh2a_get_function_vector_number (rtx);
 extern int sh2a_is_function_vector_call (rtx);
 extern void sh_fix_range (const char *);
-
+extern bool sh_hard_regno_mode_ok (unsigned int, enum machine_mode);
 #endif /* ! GCC_SH_PROTOS_H */
 
 #ifdef SYMBIAN
index 7c0bdd4..14892ce 100644 (file)
@@ -10193,6 +10193,108 @@ sh_expand_binop_v2sf (enum rtx_code code, rtx op0, rtx op1, rtx op2)
   emit_insn (gen_binary_sf_op1 (op0, op1, op2, op));
 }
 
+/* Return true if hard register REGNO can hold a value of machine-mode MODE.
+   We can allow any mode in any general register.  The special registers
+   only allow SImode.  Don't allow any mode in the PR.
+
+   We cannot hold DCmode values in the XD registers because alter_reg
+   handles subregs of them incorrectly.  We could work around this by
+   spacing the XD registers like the DR registers, but this would require
+   additional memory in every compilation to hold larger register vectors.
+   We could hold SFmode / SCmode values in XD registers, but that
+   would require a tertiary reload when reloading from / to memory,
+   and a secondary reload to reload from / to general regs; that
+   seems to be a loosing proposition.
+
+   We want to allow TImode FP regs so that when V4SFmode is loaded as TImode,
+   it won't be ferried through GP registers first.  */
+
+bool
+sh_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
+{
+  if (SPECIAL_REGISTER_P (regno))
+    return mode == SImode;
+
+  if (regno == FPUL_REG)
+    return (mode == SImode || mode == SFmode);
+
+  if (FP_REGISTER_P (regno) && mode == SFmode)
+    return true;
+
+  if (mode == V2SFmode)
+    {
+      if (((FP_REGISTER_P (regno) && (regno - FIRST_FP_REG) % 2 == 0)
+          || GENERAL_REGISTER_P (regno)))
+       return true;
+      else
+       return false;
+    }
+
+  if (mode == V4SFmode)
+    {
+      if ((FP_REGISTER_P (regno) && (regno - FIRST_FP_REG) % 4 == 0)
+         || GENERAL_REGISTER_P (regno))
+       return true;
+      else
+       return false;
+    }
+
+  if (mode == V16SFmode)
+    {
+      if (TARGET_SHMEDIA)
+       {
+         if (FP_REGISTER_P (regno) && (regno - FIRST_FP_REG) % 16 == 0)
+           return true;
+         else
+           return false;
+       }
+      else
+       return regno == FIRST_XD_REG;
+    }
+
+  if (FP_REGISTER_P (regno))
+    {
+      if (mode == SFmode
+         || mode == SImode
+         || ((TARGET_SH2E || TARGET_SHMEDIA) && mode == SCmode)
+         || ((((TARGET_SH4 || TARGET_SH2A_DOUBLE) && mode == DFmode)
+              || mode == DCmode
+              || (TARGET_SHMEDIA
+                  && (mode == DFmode || mode == DImode
+                      || mode == V2SFmode || mode == TImode)))
+             && ((regno - FIRST_FP_REG) & 1) == 0)
+         || ((TARGET_SH4 || TARGET_SHMEDIA) && mode == TImode
+             && ((regno - FIRST_FP_REG) & 3) == 0))
+       return true;
+      else
+       return false;
+    }
+
+  if (XD_REGISTER_P (regno))
+    return mode == DFmode;
+
+  if (TARGET_REGISTER_P (regno))
+    return (mode == DImode || mode == SImode || mode == PDImode);
+
+  if (regno == PR_REG)
+    return mode == SImode;
+
+  if (regno == FPSCR_REG)
+    return mode == PSImode;
+
+  /* FIXME.  This works around PR target/37633 for -O0.  */
+  if (!optimize && TARGET_SHMEDIA32 && GET_MODE_SIZE (mode) > 4)
+    {
+      unsigned int n = GET_MODE_SIZE (mode) / 8;
+
+      if (regno >= FIRST_GENERAL_REG + 10 - n + 1
+         && regno <= FIRST_GENERAL_REG + 14)
+       return false;
+    }
+
+  return true;
+}
+
 /* Return the class of registers for which a mode change from FROM to TO
    is invalid.  */
 bool
index 8b9ec86..6a4ccb0 100644 (file)
@@ -1208,52 +1208,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
     ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD/2 - 1) / (UNITS_PER_WORD/2)) \
     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
-   We can allow any mode in any general register.  The special registers
-   only allow SImode.  Don't allow any mode in the PR.  */
-
-/* We cannot hold DCmode values in the XD registers because alter_reg
-   handles subregs of them incorrectly.  We could work around this by
-   spacing the XD registers like the DR registers, but this would require
-   additional memory in every compilation to hold larger register vectors.
-   We could hold SFmode / SCmode values in XD registers, but that
-   would require a tertiary reload when reloading from / to memory,
-   and a secondary reload to reload from / to general regs; that
-   seems to be a loosing proposition.  */
-/* We want to allow TImode FP regs so that when V4SFmode is loaded as TImode,
-   it won't be ferried through GP registers first.  */
+/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.  */
+
 #define HARD_REGNO_MODE_OK(REGNO, MODE)                \
-  (SPECIAL_REGISTER_P (REGNO) ? (MODE) == SImode \
-   : (REGNO) == FPUL_REG ? (MODE) == SImode || (MODE) == SFmode        \
-   : FP_REGISTER_P (REGNO) && (MODE) == SFmode \
-   ? 1 \
-   : (MODE) == V2SFmode \
-   ? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 2 == 0) \
-      || GENERAL_REGISTER_P (REGNO)) \
-   : (MODE) == V4SFmode \
-   ? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 4 == 0) \
-      || GENERAL_REGISTER_P (REGNO)) \
-   : (MODE) == V16SFmode \
-   ? (TARGET_SHMEDIA \
-      ? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 16 == 0) \
-      : (REGNO) == FIRST_XD_REG) \
-   : FP_REGISTER_P (REGNO) \
-   ? ((MODE) == SFmode || (MODE) == SImode \
-      || ((TARGET_SH2E || TARGET_SHMEDIA) && (MODE) == SCmode) \
-      || ((((TARGET_SH4 || TARGET_SH2A_DOUBLE) && (MODE) == DFmode) || (MODE) == DCmode \
-          || (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
-                                 || (MODE) == V2SFmode || (MODE) == TImode))) \
-         && (((REGNO) - FIRST_FP_REG) & 1) == 0) \
-      || ((TARGET_SH4 || TARGET_SHMEDIA) \
-         && (MODE) == TImode \
-         && (((REGNO) - FIRST_FP_REG) & 3) == 0)) \
-   : XD_REGISTER_P (REGNO) \
-   ? (MODE) == DFmode \
-   : TARGET_REGISTER_P (REGNO) \
-   ? ((MODE) == DImode || (MODE) == SImode || (MODE) == PDImode) \
-   : (REGNO) == PR_REG ? (MODE) == SImode \
-   : (REGNO) == FPSCR_REG ? (MODE) == PSImode \
-   : 1)
+  sh_hard_regno_mode_ok ((REGNO), (MODE))
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.