summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-08 17:08:51 +0000
committeraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-08 17:08:51 +0000
commit1aad60579a2c6875264ea0a80a431ec5f41337b6 (patch)
tree7eef947fb0ad3e8f51b9f760e58ee8c82bb1300d /gcc
parent718a2160eee0dbeb4bd668bf32d17d04c7183e25 (diff)
downloadgcc-1aad60579a2c6875264ea0a80a431ec5f41337b6.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@81642 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c58
-rw-r--r--gcc/config/rs6000/rs6000.h24
4 files changed, 76 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0c3f1cdf1be..c08dc3bb5dd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 93ed98a2581..fa8a3829e72 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -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 */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5c82d75c071..bf831eabdbd 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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;
+
+/* 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)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 2f256bebd6b..8bd516d3f2b 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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.