+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
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;
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. */
| 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)
((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.