aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2002-11-04 16:58:39 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2002-11-04 16:58:39 +0000
commitcff9f8d50930e9e8dd627c92ce5255323576ed02 (patch)
tree9864774f05d9aef4abaed8431d0fa7b660a6a998 /gcc/config
parentf1c129e309fc1681abecfd655bafa9318306bbb8 (diff)
downloadgcc-cff9f8d50930e9e8dd627c92ce5255323576ed02.zip
gcc-cff9f8d50930e9e8dd627c92ce5255323576ed02.tar.gz
gcc-cff9f8d50930e9e8dd627c92ce5255323576ed02.tar.bz2
hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): New.
2002-11-04 Aldy Hernandez <aldyh@redhat.com> * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): New. * config/rs6000/rs6000.h (CLASS_CANNOT_CHANGE_MODE_P): Remove. (CLASS_CANNOT_CHANGE_MODE): Remove. (CANNOT_CHANGE_MODE_CLASS): New. * config/alpha/alpha.h: Same. * config/ia64/ia64.h: Same. * config/mips/mips.h: Same. * config/s390/s390.h: Same. * config/sh/sh.h: Same. * config/pa/pa64-regs.h: Same. * config/sh/sh-protos.h (sh_cannot_change_mode_class): Add prototype. * config/sh/sh.c (sh_cannot_change_mode_class): New. * config/mips/mips-protos.h (mips_cannot_change_mode_class): Add prototype. * config/mips/mips.c (mips_cannot_change_mode_class): New. * doc/tm.texi (Register Classes): Remove CLASS_CANNOT_CHANGE_MODE and CLASS_CANNOT_CHANGE_MODE_P. Document CANNOT_CHANGE_MODE_CLASS. * reload.c (push_reload): Use CANNOT_CHANGE_MODE_CLASS. (push_reload): Same. * simplify-rtx.c (simplify_subreg): Same. * reload1.c (choose_reload_regs): Same. * recog.c (register_operand): Same. * regrename.c (mode_change_ok): Change to use new CANNOT_CHANGE_MODE_CLASS infrastructure. * regclass.c (cannot_change_mode_set_regs): New. Declare subregs_of_mode. (regclass): Use subregs_of_mode. Remove references to reg_changes_mode. (init_reg_sets_1): Remove class_can_change_mode and reg_changes_mode code. (invalid_mode_change_p): New. (dump_regclass): Use invalid_mode_change_p instead of class_can_change_mode. (regclass): Same. (record_operand_costs): Do not set reg_changes_mode. * local-alloc.c (struct qty): Remove changes_mode field. (alloc_qty): Remove changes_mode initialization. (update_qty_class): Remove set of changes_mode. (find_free_reg): Use subregs_of_mode. * global.c (find_reg): Use subregs_of_mode info. * rtl.h (cannot_change_mode_set_regs): New prototype. (invalid_mode_change_p): Same. (REG_CANNOT_CHANGE_MODE_P): New macro. * flow.c (mark_used_regs): Calculate subregs_of_mode. Remove REG_CHANGES_MODE. (life_analysis): Clear subregs_of_mode. * combine.c (subst): Pass class to CLASS_CANNOT_CHANGE_MODE_P. Remove use of CLASS_CANNOT_CHANGE_MODE. (simplify_set): Same. (gen_lowpart_for_combine): Calculate subregs_of_mode. Remove REG_CHANGES_MODE. * regs.h: Add extern for subregs_of_mode; Include hard-reg-set and basic-block. (REG_CHANGES_MODE): Delete. From-SVN: r58794
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/alpha/alpha.h11
-rw-r--r--gcc/config/ia64/ia64.h12
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c17
-rw-r--r--gcc/config/mips/mips.h10
-rw-r--r--gcc/config/pa/pa64-regs.h12
-rw-r--r--gcc/config/rs6000/rs6000.h12
-rw-r--r--gcc/config/s390/s390.h6
-rw-r--r--gcc/config/sh/sh-protos.h2
-rw-r--r--gcc/config/sh/sh.c22
-rw-r--r--gcc/config/sh/sh.h10
11 files changed, 64 insertions, 52 deletions
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 3997377..9e39a40 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -857,15 +857,10 @@ enum reg_class {
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-/* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
+/* Return the class of registers that cannot change mode from FROM to TO. */
-#define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
-
-/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
-
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS : NO_REGS)
/* Define the cost of moving between registers of various classes. Moving
between FLOAT_REGS and anything else except float regs is expensive.
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 578e354..59d6e23 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -1008,17 +1008,11 @@ enum reg_class
: ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-/* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
-
-#define CLASS_CANNOT_CHANGE_MODE FR_REGS
-
-/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.
- In FP regs, we can't change FP values to integer values and vice
+/* In FP regs, we can't change FP values to integer values and vice
versa, but we can change e.g. DImode to SImode. */
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO))
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+ (GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO) ? FR_REGS : NO_REGS)
/* A C expression that defines the machine-dependent operand constraint
letters (`I', `J', `K', .. 'P') that specify particular ranges of
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index df943af..d92f7e5 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -122,6 +122,8 @@ extern int mips_adjust_insn_length PARAMS ((rtx, int));
extern enum reg_class mips_secondary_reload_class PARAMS ((enum reg_class,
enum machine_mode,
rtx, int));
+extern enum reg_class mips_cannot_change_mode_class
+ PARAMS ((enum machine_mode, enum machine_mode));
extern int mips_class_max_nregs PARAMS ((enum reg_class,
enum machine_mode));
extern int mips_register_move_cost PARAMS ((enum machine_mode,
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index dafa920..d58afff 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -8399,6 +8399,23 @@ function_arg_pass_by_reference (cum, mode, type, named)
return size == -1 || size > UNITS_PER_WORD;
}
+/* Return the class of registers for which a mode change from FROM to TO
+ is invalid. */
+enum reg_class
+mips_cannot_change_mode_class (from, to)
+ enum machine_mode from, to;
+{
+ if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
+ {
+ if (TARGET_BIG_ENDIAN)
+ return FP_REGS;
+ if (TARGET_FLOAT64)
+ return HI_AND_FP_REGS;
+ return HI_REG;
+ }
+ return NO_REGS;
+}
+
/* This function returns the register class required for a secondary
register when copying between one of the registers in CLASS, and X,
using MODE. If IN_P is nonzero, the copy is going from X to the
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 87513a2..bc37a14 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2343,14 +2343,8 @@ extern enum reg_class mips_char_to_class[256];
We can't allow 64-bit float registers to change from a 32-bit
mode to a 64-bit mode. */
-#define CLASS_CANNOT_CHANGE_MODE \
- (TARGET_BIG_ENDIAN ? FP_REGS \
- : (TARGET_FLOAT64 ? HI_AND_FP_REGS : HI_REG))
-
-/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
-
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+ mips_cannot_change_mode_class (FROM, TO)
/* Stack layout; function entry, exit and calling. */
diff --git a/gcc/config/pa/pa64-regs.h b/gcc/config/pa/pa64-regs.h
index 0af4c5f..2d0ebe3 100644
--- a/gcc/config/pa/pa64-regs.h
+++ b/gcc/config/pa/pa64-regs.h
@@ -232,12 +232,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
{0x00000000, 0x10000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */
-/* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
-
-#define CLASS_CANNOT_CHANGE_MODE (FP_REGS)
-
-/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.
+/* Defines invalid mode changes.
SImode loads to floating-point registers are not zero-extended.
The definition for LOAD_EXTEND_OP specifies that integer loads
@@ -245,8 +240,9 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
we inhibit changes from SImode unless they are to a mode that is
identical in size. */
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- ((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+ ((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? FP_REGS : NO_REGS)
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 5580549..39ef154 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1314,16 +1314,14 @@ enum reg_class
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-/* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
-#define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
+/* Return a class of registers that cannot change FROM mode to TO mode. */
-/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS \
+ : (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1 ? GENERAL_REGS \
+ : NO_REGS)
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
-
/* Stack layout; function entry, exit and calling. */
/* Enumeration to give which calling sequence to use. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 009f8a4..268ee2f 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -330,10 +330,8 @@ do \
/* If a 4-byte value is loaded into a FPR, it is placed into the
*upper* half of the register, not the lower. Therefore, we
cannot use SUBREGs to switch between modes in FP registers. */
-#define CLASS_CANNOT_CHANGE_MODE FP_REGS
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
-
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FP_REGS : NO_REGS)
/* Register classes. */
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index a2152ef..a729462 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -126,6 +126,8 @@ extern int sh_pr_n_sets PARAMS ((void));
extern int sh_hard_regno_rename_ok PARAMS ((unsigned int, unsigned int));
extern int sh_cfun_interrupt_handler_p PARAMS ((void));
extern void sh_initialize_trampoline PARAMS ((rtx, rtx, rtx));
+extern enum reg_class sh_cannot_change_mode_class
+ PARAMS ((enum machine_mode, enum machine_mode));
#ifdef HARD_CONST
extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 4e6981b..d2cc471 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -7733,4 +7733,26 @@ sh_expand_binop_v2sf (code, op0, op1, op2)
emit_insn ((*fn) (op0, op1, op2, op, sel1, sel1, sel1));
}
+/* Return the class of registers for which a mode change from FROM to TO
+ is invalid. */
+enum reg_class
+sh_cannot_change_mode_class (from, to)
+ enum machine_mode from, to;
+{
+ if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
+ {
+ if (TARGET_LITTLE_ENDIAN)
+ {
+ if (GET_MODE_SIZE (to) < 8 || GET_MODE_SIZE (from) < 8)
+ return DF_REGS;
+ }
+ else
+ {
+ if (GET_MODE_SIZE (from) < 8)
+ return DF_HI_REGS;
+ }
+ }
+ return NO_REGS;
+}
+
#include "gt-sh.h"
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index d0bbbdf..feadbb7 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1372,14 +1372,8 @@ extern const enum reg_class reg_class_from_letter[];
/* ??? We need to renumber the internal numbers for the frnn registers
when in little endian in order to allow mode size changes. */
-#define CLASS_CANNOT_CHANGE_MODE (TARGET_LITTLE_ENDIAN ? DF_REGS : DF_HI_REGS)
-
-/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
-
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- && ((TARGET_LITTLE_ENDIAN && GET_MODE_SIZE (TO) < 8) \
- || GET_MODE_SIZE (FROM) < 8))
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+ sh_cannot_change_mode_class (FROM, TO)
/* Stack layout; function entry, exit and calling. */