summaryrefslogtreecommitdiffstats
path: root/gcc/regclass.c
diff options
context:
space:
mode:
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>1994-04-20 03:36:49 +0000
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>1994-04-20 03:36:49 +0000
commitd2b04fb8b653758a614d1595d467dedbd608d24c (patch)
tree67e750186b349d8b84b2bb4467f2df7c000c2ca9 /gcc/regclass.c
parent334fca34c382b3a65cdadf7f0dc0bed329bc3ffc (diff)
downloadppe42-gcc-d2b04fb8b653758a614d1595d467dedbd608d24c.tar.gz
ppe42-gcc-d2b04fb8b653758a614d1595d467dedbd608d24c.zip
(choose_hard_reg_mode): Define here.
(reg_raw_mode): Define. (init_reg_sets_1): Initialize reg_raw_mode. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@7087 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/regclass.c')
-rw-r--r--gcc/regclass.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 3beac27076e..69ed76140e3 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -152,6 +152,13 @@ enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
char *reg_names[] = REGISTER_NAMES;
+/* For each hard register, the widest mode object that it can contain.
+ This will be a MODE_INT mode if the register can hold integers. Otherwise
+ it will be a MODE_FLOAT or a MODE_CC mode, whichever is valid for the
+ register. */
+
+enum machine_mode reg_raw_mode[FIRST_PSEUDO_REGISTER];
+
/* Indexed by n, gives number of times (REG n) is set or clobbered.
This information remains valid for the rest of the compilation
of the current function; it is used to control register allocation.
@@ -391,6 +398,57 @@ init_reg_sets_1 ()
if (call_fixed_regs[i])
SET_HARD_REG_BIT (call_fixed_reg_set, i);
}
+
+ /* Compute the table of register modes.
+ These values are used to record death information for individual registers
+ (as opposed to a multi-register mode).
+ This can't be done until HARD_REGNO_NREGS and HARD_REGNO_MODE_OK are
+ usable which is after OVERRIDE_OPTIONS on some targets. */
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ reg_raw_mode[i] = choose_hard_reg_mode (i, 1);
+}
+
+/* Return a machine mode that is legitimate for hard reg REGNO and large
+ enough to save nregs. If we can't find one, return VOIDmode. */
+
+enum machine_mode
+choose_hard_reg_mode (regno, nregs)
+ int regno;
+ int nregs;
+{
+ enum machine_mode found_mode = VOIDmode, mode;
+
+ /* We first look for the largest integer mode that can be validly
+ held in REGNO. If none, we look for the largest floating-point mode.
+ If we still didn't find a valid mode, try CCmode. */
+
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ if (HARD_REGNO_NREGS (regno, mode) == nregs
+ && HARD_REGNO_MODE_OK (regno, mode))
+ found_mode = mode;
+
+ if (found_mode != VOIDmode)
+ return found_mode;
+
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ if (HARD_REGNO_NREGS (regno, mode) == nregs
+ && HARD_REGNO_MODE_OK (regno, mode))
+ found_mode = mode;
+
+ if (found_mode != VOIDmode)
+ return found_mode;
+
+ if (HARD_REGNO_NREGS (regno, CCmode) == nregs
+ && HARD_REGNO_MODE_OK (regno, CCmode))
+ return CCmode;
+
+ /* We can't find a mode valid for this register. */
+ return VOIDmode;
}
/* Specify the usage characteristics of the register named NAME.
OpenPOWER on IntegriCloud