summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog45
-rw-r--r--gcc/config/alpha/alpha.h6
-rw-r--r--gcc/config/avr/avr-protos.h4
-rw-r--r--gcc/config/avr/avr.c9
-rw-r--r--gcc/config/avr/avr.h2
-rw-r--r--gcc/config/h8300/h8300.h8
-rw-r--r--gcc/config/i386/i386.c32
-rw-r--r--gcc/config/i386/i386.h13
-rw-r--r--gcc/config/iq2000/iq2000.h3
-rw-r--r--gcc/config/lm32/lm32.h3
-rw-r--r--gcc/config/m32r/m32r.h5
-rw-r--r--gcc/config/mep/mep.h3
-rw-r--r--gcc/config/microblaze/microblaze.h3
-rw-r--r--gcc/config/mn10300/mn10300.h6
-rw-r--r--gcc/config/moxie/moxie.h5
-rw-r--r--gcc/config/score/score.h5
-rw-r--r--gcc/config/spu/spu.h3
-rw-r--r--gcc/config/stormy16/stormy16.h3
-rw-r--r--gcc/config/v850/v850.h6
-rw-r--r--gcc/config/vax/vax.h11
-rw-r--r--gcc/config/xtensa/xtensa.h9
-rw-r--r--gcc/doc/tm.texi17
-rw-r--r--gcc/doc/tm.texi.in17
-rw-r--r--gcc/ira-conflicts.c4
-rw-r--r--gcc/ira-costs.c6
-rw-r--r--gcc/ira.c2
-rw-r--r--gcc/ira.h4
-rw-r--r--gcc/reginfo.c3
-rw-r--r--gcc/reload.c12
-rw-r--r--gcc/target.def8
-rw-r--r--gcc/targhooks.c13
-rw-r--r--gcc/targhooks.h1
32 files changed, 147 insertions, 124 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1dd9ca8e12a..26eb56f7f96 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,48 @@
+2011-07-20 Anatoly Sokolov <aesok@post.ru>
+
+ * target.def (class_max_nregs): New hook.
+ * doc/tm.texi.in (TARGET_CLASS_MAX_NREGS): Document.
+ * doc/tm.texi: Regenerate.
+ * targhooks.c (default_class_max_nregs): New function.
+ * targhooks.h (default_class_max_nregs): Declare.
+ * ira.h (target_ira): Change type x_ira_reg_class_max_nregs and
+ x_ira_reg_class_min_nregs arrays to unsigned char.
+ * ira.c (setup_reg_class_nregs): Use TARGET_CLASS_MAX_NREGS target
+ hook instead of CLASS_MAX_NREGS macro.
+ * reginfo.c (restore_register_info): Ditto.
+ * ira-conflicts.c (process_regs_for_copy): Use
+ ira_reg_class_max_nregs array instead of CLASS_MAX_NREGS macro.
+ Change type rclass and aclass vars to reg_class_t.
+ * ira-costs.c (record_reg_classes): Use ira_reg_class_max_nregs
+ array instead of CLASS_MAX_NREGS macro. Change type rclass var to
+ reg_class_t.
+ * reload.c (combine_reloads, find_reloads, find_reloads_address_1):
+ Use ira_reg_class_max_nregs array instead of CLASS_MAX_NREGS macro.
+
+ * config/i386/i386.h (CLASS_MAX_NREGS): Remove.
+ * config/i386/i386.c (ix86_class_max_nregs): New function.
+ (ix86_register_move_cost): Use TARGET_CLASS_MAX_NREGS target hook
+ instead of CLASS_MAX_NREGS macro.
+ (TARGET_CLASS_MAX_NREGS): Define.
+ * config/avr/avr.h (CLASS_MAX_NREGS): Remove.
+ * config/avr/avr-protos.h (class_max_nregs): Remove declaration.
+ * config/avr/avr.c (class_max_nregs): Remove function.
+ * config/alpha/alpha.h (CLASS_MAX_NREGS): Remove.
+ * config/spu/spu.h (CLASS_MAX_NREGS): Remove.
+ * config/mep/mep.h (CLASS_MAX_NREGS): Remove.
+ * config/m32r/m32r.h (CLASS_MAX_NREGS): Remove.
+ * config/microblaze/microblaze.h (CLASS_MAX_NREGS): Remove.
+ * config/xtensa/xtensa.h (CLASS_MAX_NREGS): Remove.
+ * config/stormy16/stormy16.h (CLASS_MAX_NREGS): Remove.
+ * config/lm32/lm32.h (CLASS_MAX_NREGS): Remove.
+ * config/moxie/moxie.h (CLASS_MAX_NREGS): Remove.
+ * config/iq2000/iq2000.h (CLASS_MAX_NREGS): Remove.
+ * config/mn10300/mn10300.h (CLASS_MAX_NREGS): Remove.
+ * config/score/score.h (CLASS_MAX_NREGS): Remove.
+ * config/vax/vax.h (CLASS_MAX_NREGS): Remove.
+ * config/h8300/h8300.h (CLASS_MAX_NREGS): Remove.
+ * config/v850/v850.h (CLASS_MAX_NREGS): Remove.
+
2011-07-19 Eric Botcazou <ebotcazou@adacore.com>
* cif-code.def (OVERWRITABLE): Fix typo and move around.
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index cc16cfa974e..07ffa9fe8b1 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -549,12 +549,6 @@ enum reg_class {
: GET_MODE_SIZE (MODE) >= 4 ? (MODE) \
: mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0))
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Return the class of registers that cannot change mode from FROM to TO. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 718aa420c74..9b95caa0111 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -110,10 +110,6 @@ extern void out_shift_with_cnt (const char *templ, rtx insn,
extern rtx avr_incoming_return_addr_rtx (void);
#endif /* RTX_CODE */
-#ifdef HAVE_MACHINE_MODES
-extern int class_max_nregs (enum reg_class rclass, enum machine_mode mode);
-#endif /* HAVE_MACHINE_MODES */
-
#ifdef REAL_VALUE_TYPE
extern void asm_output_float (FILE *file, REAL_VALUE_TYPE n);
#endif
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 209a5b92a04..ebfec0da024 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -1491,15 +1491,6 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
}
}
-/* Return maximum number of consecutive registers of
- class CLASS needed to hold a value of mode MODE. */
-
-int
-class_max_nregs (enum reg_class rclass ATTRIBUTE_UNUSED,enum machine_mode mode)
-{
- return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
-}
-
/* Choose mode for jump insn:
1 - relative jump in range -63 <= x <= 62 ;
2 - relative jump in range -2046 <= x <= 2045 ;
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 9b27f703807..ddd30d6ee3a 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -312,8 +312,6 @@ enum reg_class {
#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
-#define CLASS_MAX_NREGS(CLASS, MODE) class_max_nregs (CLASS, MODE)
-
#define STACK_PUSH_CODE POST_DEC
#define STACK_GROWS_DOWNWARD
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 936aabfa229..82e55f6628b 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -357,14 +357,6 @@ enum reg_class {
#define INDEX_REG_CLASS (TARGET_H8300SX ? GENERAL_REGS : NO_REGS)
#define BASE_REG_CLASS GENERAL_REGS
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-
-/* On the H8, this is the size of MODE in words. */
-
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Stack layout; function entry, exit and calling. */
/* Define this if pushing a word on the stack
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a87fb29d5e3..814250fa24e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -28263,6 +28263,32 @@ ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
return inline_secondary_memory_needed (class1, class2, mode, strict);
}
+/* Implement the TARGET_CLASS_MAX_NREGS hook.
+
+ On the 80386, this is the size of MODE in words,
+ except in the FP regs, where a single reg is always enough. */
+
+static unsigned char
+ix86_class_max_nregs (reg_class_t rclass, enum machine_mode mode)
+{
+ if (MAYBE_INTEGER_CLASS_P (rclass))
+ {
+ if (mode == XFmode)
+ return (TARGET_64BIT ? 2 : 3);
+ else if (mode == XCmode)
+ return (TARGET_64BIT ? 4 : 6);
+ else
+ return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
+ }
+ else
+ {
+ if (COMPLEX_MODE_P (mode))
+ return 2;
+ else
+ return 1;
+ }
+}
+
/* Return true if the registers in CLASS cannot represent the change from
modes FROM to TO. */
@@ -28459,7 +28485,8 @@ ix86_register_move_cost (enum machine_mode mode, reg_class_t class1_i,
/* In case of copying from general_purpose_register we may emit multiple
stores followed by single load causing memory size mismatch stall.
Count this as arbitrarily high cost of 20. */
- if (CLASS_MAX_NREGS (class1, mode) > CLASS_MAX_NREGS (class2, mode))
+ if (targetm.class_max_nregs (class1, mode)
+ > targetm.class_max_nregs (class2, mode))
cost += 20;
/* In the case of FP/MMX moves, the registers actually overlap, and we
@@ -34931,6 +34958,9 @@ ix86_autovectorize_vector_sizes (void)
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD ix86_secondary_reload
+#undef TARGET_CLASS_MAX_NREGS
+#define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
+
#undef TARGET_PREFERRED_RELOAD_CLASS
#define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
#undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 4c7df9d1b1d..47c1388c9c0 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1357,19 +1357,6 @@ enum reg_class
? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \
: MODE)
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-/* On the 80386, this is the size of MODE in words,
- except in the FP regs, where a single reg is always enough. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- (MAYBE_INTEGER_CLASS_P (CLASS) \
- ? ((MODE) == XFmode \
- ? (TARGET_64BIT ? 2 : 3) \
- : (MODE) == XCmode \
- ? (TARGET_64BIT ? 4 : 6) \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) \
- : (COMPLEX_MODE_P (MODE) ? 2 : 1))
-
/* Return a class of registers that cannot change FROM mode to TO mode. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h
index e909ef94b57..130acc9b384 100644
--- a/gcc/config/iq2000/iq2000.h
+++ b/gcc/config/iq2000/iq2000.h
@@ -228,9 +228,6 @@ enum reg_class
? (GR_REGS) \
: (CLASS))))
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Basic Stack Layout. */
diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h
index 75a24160fd9..5c516860bed 100644
--- a/gcc/config/lm32/lm32.h
+++ b/gcc/config/lm32/lm32.h
@@ -202,9 +202,6 @@ enum reg_class
#define REGNO_REG_CLASS(REGNO) \
(G_REG_P(REGNO) ? GENERAL_REGS : NO_REGS)
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
#define INDEX_REG_CLASS NO_REGS
#define BASE_REG_CLASS GENERAL_REGS
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 50b5b2aa1a3..0072b2f0da3 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -509,11 +509,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER];
#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO)
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Return true if a value is inside a range. */
#define IN_RANGE_P(VALUE, LOW, HIGH) \
(((unsigned HOST_WIDE_INT)((VALUE) - (LOW))) \
diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h
index f5de83f5d1d..dbb48143034 100644
--- a/gcc/config/mep/mep.h
+++ b/gcc/config/mep/mep.h
@@ -428,9 +428,6 @@ enum reg_class
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
mep_secondary_memory_needed (CLASS1, CLASS2, MODE)
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
#if 0
#define CONST_OK_FOR_LETTER_P(VALUE, C) mep_const_ok_for_letter_p (VALUE, C)
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index a667acadaf8..92f0f60f1ff 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -388,9 +388,6 @@ extern enum reg_class microblaze_regno_to_class[];
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
(GET_MODE_CLASS (MODE) == MODE_INT)
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + (UNITS_PER_WORD) - 1) / (UNITS_PER_WORD))
-
/* Stack layout; function entry, exit and calling. */
#define STACK_GROWS_DOWNWARD
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index 7f70d5b25d2..79b20f5a4d8 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -388,12 +388,6 @@ enum reg_class
#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
(!TARGET_AM33 && (MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS)
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* A class that contains registers which the compiler must always
access in a mode that is the same size as the mode in which it
loaded the register. */
diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h
index 86c66631441..d2a455b289c 100644
--- a/gcc/config/moxie/moxie.h
+++ b/gcc/config/moxie/moxie.h
@@ -189,11 +189,6 @@ enum reg_class
accessible in mode MODE2 without copying. */
#define MODES_TIEABLE_P(MODE1, MODE2) 1
-/* A C expression for the maximum number of consecutive registers of
- class CLASS needed to hold a value of mode MODE. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* The Overall Framework of an Assembler File */
#undef ASM_SPEC
diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h
index 1f9975600fe..3c8851a602f 100644
--- a/gcc/config/score/score.h
+++ b/gcc/config/score/score.h
@@ -418,11 +418,6 @@ extern enum reg_class score_char_to_class[256];
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
score_secondary_reload_class (CLASS, MODE, X)
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
? reg_classes_intersect_p (HI_REG, (CLASS)) : 0)
diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h
index 16258911ef3..c69cf7efc4e 100644
--- a/gcc/config/spu/spu.h
+++ b/gcc/config/spu/spu.h
@@ -225,9 +225,6 @@ enum reg_class {
#define INT_REG_OK_FOR_BASE_P(X,STRICT) \
((!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X))))
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* GCC assumes that modes are in the lowpart of a register, which is
only true for SPU. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h
index 871e523a67b..43833625608 100644
--- a/gcc/config/stormy16/stormy16.h
+++ b/gcc/config/stormy16/stormy16.h
@@ -227,9 +227,6 @@ enum reg_class
#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \
xstormy16_secondary_reload_class (CLASS, MODE, X)
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Basic Stack Layout. */
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index 0784d89bf67..f5b64deab2b 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -341,12 +341,6 @@ enum reg_class
#define REGNO_OK_FOR_INDEX_P(regno) 0
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Convenience wrappers around insn_const_int_ok_for_constraint. */
#define CONST_OK_FOR_I(VALUE) \
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index a3e9d83e8f8..0c835637ae1 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -219,11 +219,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
#define REG_CLASS_NAMES \
{ "NO_REGS", "ALL_REGS" }
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */
@@ -242,12 +237,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
#define INDEX_REG_CLASS ALL_REGS
#define BASE_REG_CLASS ALL_REGS
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-/* On the VAX, this is always the size of MODE in words,
- since all registers are the same size. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* Stack layout; function entry, exit and calling. */
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index d3ce1479443..b1a24c6d86d 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -450,15 +450,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
the RTL, as either incoming or outgoing arguments. */
#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-#define CLASS_UNITS(mode, size) \
- ((GET_MODE_SIZE (mode) + (size) - 1) / (size))
-
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- (CLASS_UNITS (MODE, UNITS_PER_WORD))
-
-
/* Stack layout; function entry, exit and calling. */
#define STACK_GROWS_DOWNWARD
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 08acb351ba3..097531f7f6b 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2846,6 +2846,23 @@ the only effect of such implementation would be to slow down register
allocation.
@end deftypefn
+@deftypefn {Target Hook} {unsigned char} TARGET_CLASS_MAX_NREGS (reg_class_t @var{rclass}, enum machine_mode @var{mode})
+A target hook returns the maximum number of consecutive registers
+of class @var{rclass} needed to hold a value of mode @var{mode}.
+
+This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact,
+the value returned by @code{TERGET_CLASS_MAX_NREGS (@var{rclass},
+@var{mode})} target hook should be the maximum value of
+@code{HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno}
+values in the class @var{rclass}.
+
+This target hook helps control the handling of multiple-word values
+in the reload pass.
+
+The default version of this target hook returns the size of @var{mode}
+in words.
+@end deftypefn
+
@defmac CLASS_MAX_NREGS (@var{class}, @var{mode})
A C expression for the maximum number of consecutive registers
of class @var{class} needed to hold a value of mode @var{mode}.
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 7990c763a73..01beeb47920 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2832,6 +2832,23 @@ the only effect of such implementation would be to slow down register
allocation.
@end deftypefn
+@hook TARGET_CLASS_MAX_NREGS
+A target hook returns the maximum number of consecutive registers
+of class @var{rclass} needed to hold a value of mode @var{mode}.
+
+This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact,
+the value returned by @code{TERGET_CLASS_MAX_NREGS (@var{rclass},
+@var{mode})} target hook should be the maximum value of
+@code{HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno}
+values in the class @var{rclass}.
+
+This target hook helps control the handling of multiple-word values
+in the reload pass.
+
+The default version of this target hook returns the size of @var{mode}
+in words.
+@end deftypefn
+
@defmac CLASS_MAX_NREGS (@var{class}, @var{mode})
A C expression for the maximum number of consecutive registers
of class @var{class} needed to hold a value of mode @var{mode}.
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index be002839fa2..3df65709f6f 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -393,7 +393,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
bool only_regs_p;
ira_allocno_t a;
- enum reg_class rclass, aclass;
+ reg_class_t rclass, aclass;
enum machine_mode mode;
ira_copy_t cp;
@@ -438,7 +438,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
mode = ALLOCNO_MODE (a);
aclass = ALLOCNO_CLASS (a);
if (only_regs_p && insn != NULL_RTX
- && reg_class_size[rclass] <= (unsigned) CLASS_MAX_NREGS (rclass, mode))
+ && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
/* It is already taken into account in ira-costs.c. */
return false;
index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index da14089f913..39ef33a541c 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -930,15 +930,15 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
enum machine_mode mode = GET_MODE (ops[!i]);
cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
enum reg_class *cost_classes = cost_classes_ptr->classes;
- enum reg_class rclass;
+ reg_class_t rclass;
int nr;
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{
rclass = cost_classes[k];
if (TEST_HARD_REG_BIT (reg_class_contents[rclass], other_regno)
- && (reg_class_size[rclass]
- == (unsigned) CLASS_MAX_NREGS (rclass, mode)))
+ && (reg_class_size[(int) rclass]
+ == ira_reg_class_max_nregs [(int) rclass][(int) mode]))
{
if (reg_class_size[rclass] == 1)
op_costs[i]->cost[k] = -frequency;
diff --git a/gcc/ira.c b/gcc/ira.c
index 6cca90807df..b54762e8962 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1403,7 +1403,7 @@ setup_reg_class_nregs (void)
for (cl = 0; cl < N_REG_CLASSES; cl++)
ira_reg_class_max_nregs[cl][m]
= ira_reg_class_min_nregs[cl][m]
- = CLASS_MAX_NREGS ((enum reg_class) cl, (enum machine_mode) m);
+ = targetm.class_max_nregs ((reg_class_t) cl, (enum machine_mode) m);
for (cl = 0; cl < N_REG_CLASSES; cl++)
for (i = 0;
(cl2 = alloc_reg_class_subclasses[cl][i]) != LIM_REG_CLASSES;
diff --git a/gcc/ira.h b/gcc/ira.h
index a31a03ca21b..60518ecb313 100644
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -68,8 +68,8 @@ struct target_ira {
/* Maps: register class x machine mode -> maximal/minimal number of
hard registers of given class needed to store value of given
mode. */
- int x_ira_reg_class_max_nregs[N_REG_CLASSES][MAX_MACHINE_MODE];
- int x_ira_reg_class_min_nregs[N_REG_CLASSES][MAX_MACHINE_MODE];
+ unsigned char x_ira_reg_class_max_nregs[N_REG_CLASSES][MAX_MACHINE_MODE];
+ unsigned char x_ira_reg_class_min_nregs[N_REG_CLASSES][MAX_MACHINE_MODE];
/* Array analogous to target hook TARGET_MEMORY_MOVE_COST. */
short x_ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 1da4cb8f40a..537364192da 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -529,8 +529,7 @@ init_reg_sets_1 (void)
SET_HARD_REG_BIT (ok_regs, j);
for (i = 0; i < N_REG_CLASSES; i++)
- if (((unsigned) CLASS_MAX_NREGS ((enum reg_class) i,
- (enum machine_mode) m)
+ if ((targetm.class_max_nregs ((reg_class_t) i, (enum machine_mode) m)
<= reg_class_size[i])
&& hard_reg_set_intersect_p (ok_regs, reg_class_contents[i]))
{
diff --git a/gcc/reload.c b/gcc/reload.c
index b5e991e386d..c671765ba93 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1767,9 +1767,9 @@ combine_reloads (void)
&& rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS
&& rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
&& rld[i].when_needed != RELOAD_OTHER
- && (CLASS_MAX_NREGS (rld[i].rclass, rld[i].inmode)
- == CLASS_MAX_NREGS (rld[output_reload].rclass,
- rld[output_reload].outmode))
+ && (ira_reg_class_max_nregs [(int)rld[i].rclass][(int) rld[i].inmode]
+ == ira_reg_class_max_nregs [(int) rld[output_reload].rclass]
+ [(int) rld[output_reload].outmode])
&& rld[i].inc == 0
&& rld[i].reg_rtx == 0
#ifdef SECONDARY_MEMORY_NEEDED
@@ -4542,7 +4542,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
> GET_MODE_SIZE (rld[i].inmode)))
? rld[i].outmode : rld[i].inmode;
- rld[i].nregs = CLASS_MAX_NREGS (rld[i].rclass, rld[i].mode);
+ rld[i].nregs = ira_reg_class_max_nregs [rld[i].rclass][rld[i].mode];
}
/* Special case a simple move with an input reload and a
@@ -5992,8 +5992,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
else
{
enum reg_class rclass = context_reg_class;
- if ((unsigned) CLASS_MAX_NREGS (rclass, GET_MODE (SUBREG_REG (x)))
- > reg_class_size[rclass])
+ if (ira_reg_class_max_nregs [rclass][GET_MODE (SUBREG_REG (x))]
+ > reg_class_size[(int) rclass])
{
x = find_reloads_subreg_address (x, 0, opnum,
ADDR_TYPE (type),
diff --git a/gcc/target.def b/gcc/target.def
index 3a0b413a80a..9ff97e690e9 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2245,6 +2245,14 @@ DEFHOOK
bool, (reg_class_t rclass),
default_class_likely_spilled_p)
+/* Return the maximum number of consecutive registers
+ needed to represent mode MODE in a register of class RCLASS. */
+DEFHOOK
+(class_max_nregs,
+ "",
+ unsigned char, (reg_class_t rclass, enum machine_mode mode),
+ default_class_max_nregs)
+
DEFHOOK
(preferred_rename_class,
"A target hook that places additional preference on the register\
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index f69b39626a6..16d0b189f65 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1309,6 +1309,19 @@ default_class_likely_spilled_p (reg_class_t rclass)
return (reg_class_size[(int) rclass] == 1);
}
+/* The default implementation of TARGET_CLASS_MAX_NREGS. */
+
+unsigned char
+default_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+#ifdef CLASS_MAX_NREGS
+ return (unsigned char) CLASS_MAX_NREGS ((enum reg_class) rclass, mode);
+#else
+ return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
+#endif
+}
+
/* Determine the debugging unwind mechanism for the target. */
enum unwind_info_type
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 62e888445bb..552407b21db 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -163,6 +163,7 @@ extern reg_class_t default_preferred_reload_class (rtx, reg_class_t);
extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t);
extern reg_class_t default_preferred_rename_class (reg_class_t rclass);
extern bool default_class_likely_spilled_p (reg_class_t);
+extern unsigned char default_class_max_nregs (reg_class_t, enum machine_mode);
extern enum unwind_info_type default_debug_unwind_info (void);