rs6000-protos.h (rs6000_hard_regno_mode_ok_p): Declare.
authorAldy Hernandez <aldyh@redhat.com>
Sat, 8 May 2004 17:08:51 +0000 (17:08 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Sat, 8 May 2004 17:08:51 +0000 (17:08 +0000)
* config/rs6000/rs6000-protos.h (rs6000_hard_regno_mode_ok_p):
Declare.

* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok_p): New.
(rs6000_hard_regno_mode_ok): New.
(rs6000_init_hard_regno_mode_ok): New.
(rs6000_override_options): Call rs6000_init_hard_regno_mode_ok.

* config/rs6000/rs6000.h (HARD_REGNO_NREGS): Use precomputed
result.

From-SVN: r81642

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

index 0c3f1cdf1bec84f07c6f03d3e187eae18c0e056d..c08dc3bb5ddfce0b996d0eca612a830ad5f24968 100644 (file)
@@ -1,3 +1,16 @@
+2004-05-07  Aldy Hernandez  <aldyh@redhat.com>
+
+       * config/rs6000/rs6000-protos.h (rs6000_hard_regno_mode_ok_p):
+       Declare.
+
+       * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok_p): New.
+       (rs6000_hard_regno_mode_ok): New.
+       (rs6000_init_hard_regno_mode_ok): New.
+       (rs6000_override_options): Call rs6000_init_hard_regno_mode_ok.
+
+       * config/rs6000/rs6000.h (HARD_REGNO_NREGS): Use precomputed
+       result.
+
 2004-05-07  Ziemowit Laski  <zlaski@apple.com>
 
        * config/rs6000/altivec.h (vector, pixel, bool): Do not
index 93ed98a2581e58bc905fac01b966a1f28c01a5ac..fa8a3829e726349a5763d637aec5f38ee1c265df 100644 (file)
@@ -212,4 +212,5 @@ extern void rs6000_cpu_cpp_builtins (struct cpp_reader *);
 char *output_call (rtx, rtx *, int, int);
 #endif
 
+extern bool rs6000_hard_regno_mode_ok_p[][FIRST_PSEUDO_REGISTER];
 #endif  /* rs6000-protos.h */
index 5c82d75c071838bb3fc15792a8119e5e5b69d2c4..bf831eabdbd7a32822e5938d478437f188771e54 100644 (file)
@@ -215,6 +215,9 @@ const char *rs6000_debug_name;
 int rs6000_debug_stack;                /* debug stack applications */
 int rs6000_debug_arg;          /* debug argument handling */
 
+/* Value is TRUE if register/mode pair is accepatable.  */
+bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
+
 /* Opaque types.  */
 static GTY(()) tree opaque_V2SI_type_node;
 static GTY(()) tree opaque_V2SF_type_node;
@@ -645,6 +648,58 @@ static const char alt_reg_names[][8] =
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
+
+/* Value is 1 if hard register REGNO can hold a value of machine-mode
+   MODE.  */
+static int
+rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
+{
+  /* The GPRs can hold any mode, but values bigger than one register
+     cannot go past R31.  */
+  if (INT_REGNO_P (regno))
+    return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
+
+  /* The float registers can only hold floating modes and DImode.  */
+  if (FP_REGNO_P (regno))
+    return
+      (GET_MODE_CLASS (mode) == MODE_FLOAT
+       && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
+      || (GET_MODE_CLASS (mode) == MODE_INT
+         && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
+
+  /* The CR register can only hold CC modes.  */
+  if (CR_REGNO_P (regno))
+    return GET_MODE_CLASS (mode) == MODE_CC;
+
+  if (XER_REGNO_P (regno))
+    return mode == PSImode;
+
+  /* AltiVec only in AldyVec registers.  */
+  if (ALTIVEC_REGNO_P (regno))
+    return ALTIVEC_VECTOR_MODE (mode);
+
+  /* ...but GPRs can hold SIMD data on the SPE in one register.  */
+  if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
+    return 1;
+
+  /* We cannot put TImode anywhere except general register and it must be
+     able to fit within the register set.  */
+
+  return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
+}
+
+/* Initialize rs6000_hard_regno_mode_ok_p table.  */
+static void
+rs6000_init_hard_regno_mode_ok (void)
+{
+  int r, m;
+
+  for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
+    for (m = 0; m < NUM_MACHINE_MODES; ++m)
+      if (rs6000_hard_regno_mode_ok (r, m))
+       rs6000_hard_regno_mode_ok_p[m][r] = true;
+}
+
 /* Override command line options.  Mostly we process the processor
    type and sometimes adjust other TARGET_ options.  */
 
@@ -747,6 +802,9 @@ rs6000_override_options (const char *default_cpu)
                     | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
                     | MASK_MFCRF)
   };
+
+  rs6000_init_hard_regno_mode_ok ();
+
  set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
 #ifdef OS_MISSING_POWERPC64
   if (OS_MISSING_POWERPC64)
index 2f256bebd6b7641c47351e01c2e8ad511e60154e..8bd516d3f2b3c927125a75215c6c900a13d08d30 100644 (file)
@@ -1027,26 +1027,10 @@ extern const char *rs6000_warn_altivec_long_switch;
         ((TARGET_SPE && SPE_VECTOR_MODE (MODE))                \
         || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
 
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
-   For POWER and PowerPC, the GPRs can hold any mode, but values bigger
-   than one register cannot go past R31.  The float
-   registers only can hold floating modes and DImode, and CR register only
-   can hold CC modes.  We cannot put TImode anywhere except general
-   register and it must be able to fit within the register set.  */
-
-#define HARD_REGNO_MODE_OK(REGNO, MODE)                                        \
-  (INT_REGNO_P (REGNO) ?                                               \
-     INT_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1)          \
-   : FP_REGNO_P (REGNO) ?                                              \
-     ((GET_MODE_CLASS (MODE) == MODE_FLOAT                             \
-       && FP_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1))     \
-      || (GET_MODE_CLASS (MODE) == MODE_INT                            \
-         && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))                \
-   : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)              \
-   : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
-   : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC             \
-   : XER_REGNO_P (REGNO) ? (MODE) == PSImode                           \
-   : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
+/* Value is TRUE if hard register REGNO can hold a value of
+   machine-mode MODE.  */
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+  rs6000_hard_regno_mode_ok_p[(int)(MODE)][REGNO]
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.