aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog44
-rw-r--r--gcc/config/alpha/alpha.c17
-rw-r--r--gcc/config/alpha/alpha.h10
-rw-r--r--gcc/config/i386/i386.c16
-rw-r--r--gcc/config/i386/i386.h8
-rw-r--r--gcc/config/powerpcspe/powerpcspe-protos.h1
-rw-r--r--gcc/config/powerpcspe/powerpcspe.c9
-rw-r--r--gcc/config/powerpcspe/powerpcspe.h7
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c9
-rw-r--r--gcc/config/rs6000/rs6000.h7
-rw-r--r--gcc/config/s390/s390.c15
-rw-r--r--gcc/config/s390/s390.h7
-rw-r--r--gcc/config/sparc/sparc.c27
-rw-r--r--gcc/config/sparc/sparc.h12
-rw-r--r--gcc/doc/tm.texi32
-rw-r--r--gcc/doc/tm.texi.in24
-rw-r--r--gcc/lra-constraints.c12
-rw-r--r--gcc/reload.c8
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/target.def24
-rw-r--r--gcc/targhooks.c12
-rw-r--r--gcc/targhooks.h1
23 files changed, 187 insertions, 118 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1f941d4..6b8f7f3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,47 @@
+2017-09-13 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * target.def (secondary_memory_needed_mode): New hook:
+ * targhooks.c (default_secondary_memory_needed_mode): Declare.
+ * targhooks.h (default_secondary_memory_needed_mode): New function.
+ * doc/tm.texi.in (SECONDARY_MEMORY_NEEDED_MODE): Replace with...
+ (TARGET_SECONDARY_MEMORY_NEEDED_MODE): ...this.
+ * doc/tm.texi: Regenerate.
+ * lra-constraints.c (check_and_process_move): Use
+ targetm.secondary_memory_needed_mode instead of
+ TARGET_SECONDARY_MEMORY_NEEDED_MODE.
+ (curr_insn_transform): Likewise.
+ * reload.c (get_secondary_mem): Likewise.
+ * config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+ * config/alpha/alpha.c (alpha_secondary_memory_needed_mode): New
+ function.
+ (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
+ * config/i386/i386.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+ * config/i386/i386.c (ix86_secondary_memory_needed_mode): New function.
+ (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
+ * config/powerpcspe/powerpcspe.h (SECONDARY_MEMORY_NEEDED_MODE):
+ Delete.
+ * config/powerpcspe/powerpcspe-protos.h
+ (rs6000_secondary_memory_needed_mode): Delete.
+ * config/powerpcspe/powerpcspe.c
+ (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
+ (rs6000_secondary_memory_needed_mode): Make static.
+ * config/rs6000/rs6000.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+ * config/rs6000/rs6000-protos.h (rs6000_secondary_memory_needed_mode):
+ Delete.
+ * config/rs6000/rs6000.c (TARGET_SECONDARY_MEMORY_NEEDED_MODE):
+ Redefine.
+ (rs6000_secondary_memory_needed_mode): Make static.
+ * config/s390/s390.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+ * config/s390/s390.c (s390_secondary_memory_needed_mode): New function.
+ (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
+ * config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
+ * config/sparc/sparc.c (TARGET_SECONDARY_MEMORY_NEEDED_MODE):
+ Redefine.
+ (sparc_secondary_memory_needed_mode): New function.
+ * system.h (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Poison.
+
2017-09-13 Jackson Woodruff <jackson.woodruff@arm.com>
* config/aarch64/constraints.md (Umq): New constraint.
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index ecc915d..28fe467 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -1688,6 +1688,21 @@ alpha_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
return NO_REGS;
}
+
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE. If MODE is
+ floating-point, use it. Otherwise, widen to a word like the default.
+ This is needed because we always store integers in FP registers in
+ quadword format. This whole area is very tricky! */
+
+static machine_mode
+alpha_secondary_memory_needed_mode (machine_mode mode)
+{
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ return mode;
+ if (GET_MODE_SIZE (mode) >= 4)
+ return mode;
+ return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require ();
+}
/* Given SEQ, which is an INSN list, look for any MEMs in either
a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
@@ -10062,6 +10077,8 @@ alpha_modes_tieable_p (machine_mode mode1, machine_mode mode2)
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD alpha_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE alpha_secondary_memory_needed_mode
#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 56ba895..10f32b7 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -486,16 +486,6 @@ enum reg_class {
(! TARGET_FIX && (((CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS) \
|| ((CLASS2) == FLOAT_REGS && (CLASS1) != FLOAT_REGS)))
-/* Specify the mode to be used for memory when a secondary memory
- location is needed. If MODE is floating-point, use it. Otherwise,
- widen to a word like the default. This is needed because we always
- store integers in FP registers in quadword format. This whole
- area is very tricky! */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE) \
- : GET_MODE_SIZE (MODE) >= 4 ? (MODE) \
- : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require ())
-
/* 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/i386/i386.c b/gcc/config/i386/i386.c
index edcc2d6..a508f56 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -41162,6 +41162,20 @@ ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
return inline_secondary_memory_needed (class1, class2, mode, strict);
}
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
+
+ get_secondary_mem widens integral modes to BITS_PER_WORD.
+ There is no need to emit full 64 bit move on 64 bit targets
+ for integral modes that can be moved using 32 bit move. */
+
+static machine_mode
+ix86_secondary_memory_needed_mode (machine_mode mode)
+{
+ if (GET_MODE_BITSIZE (mode) < 32 && INTEGRAL_MODE_P (mode))
+ return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
+ return mode;
+}
+
/* Implement the TARGET_CLASS_MAX_NREGS hook.
On the 80386, this is the size of MODE in words,
@@ -53206,6 +53220,8 @@ ix86_run_selftests (void)
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD ix86_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode
#undef TARGET_CLASS_MAX_NREGS
#define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index a89782a..09b8da5 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1524,14 +1524,6 @@ enum reg_class
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
ix86_secondary_memory_needed ((CLASS1), (CLASS2), (MODE), 1)
-/* Get_secondary_mem widens integral modes to BITS_PER_WORD.
- There is no need to emit full 64 bit move on 64 bit targets
- for integral modes that can be moved using 32 bit move. */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
- (GET_MODE_BITSIZE (MODE) < 32 && INTEGRAL_MODE_P (MODE) \
- ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \
- : MODE)
-
/* 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/powerpcspe/powerpcspe-protos.h b/gcc/config/powerpcspe/powerpcspe-protos.h
index 20587ba..f3aa41b 100644
--- a/gcc/config/powerpcspe/powerpcspe-protos.h
+++ b/gcc/config/powerpcspe/powerpcspe-protos.h
@@ -154,7 +154,6 @@ extern void rs6000_emit_le_vsx_move (rtx, rtx, machine_mode);
extern bool valid_sf_si_move (rtx, rtx, machine_mode);
extern void rs6000_emit_move (rtx, rtx, machine_mode);
extern rtx rs6000_secondary_memory_needed_rtx (machine_mode);
-extern machine_mode rs6000_secondary_memory_needed_mode (machine_mode);
extern rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode,
int, int, int, int *);
extern bool rs6000_legitimate_offset_address_p (machine_mode, rtx,
diff --git a/gcc/config/powerpcspe/powerpcspe.c b/gcc/config/powerpcspe/powerpcspe.c
index 7784676..9b8d68b 100644
--- a/gcc/config/powerpcspe/powerpcspe.c
+++ b/gcc/config/powerpcspe/powerpcspe.c
@@ -1897,6 +1897,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE rs6000_secondary_memory_needed_mode
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
@@ -21811,10 +21813,9 @@ rs6000_secondary_memory_needed_rtx (machine_mode mode)
return ret;
}
-/* Return the mode to be used for memory when a secondary memory
- location is needed. For SDmode values we need to use DDmode, in
- all other cases we can use the same mode. */
-machine_mode
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE. For SDmode values we
+ need to use DDmode, in all other cases we can use the same mode. */
+static machine_mode
rs6000_secondary_memory_needed_mode (machine_mode mode)
{
if (lra_in_progress && mode == SDmode)
diff --git a/gcc/config/powerpcspe/powerpcspe.h b/gcc/config/powerpcspe/powerpcspe.h
index c4b6dc3..5d1a138 100644
--- a/gcc/config/powerpcspe/powerpcspe.h
+++ b/gcc/config/powerpcspe/powerpcspe.h
@@ -1611,13 +1611,6 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
rs6000_secondary_memory_needed_rtx (MODE)
-/* Specify the mode to be used for memory when a secondary memory
- location is needed. For cpus that cannot load/store SDmode values
- from the 64-bit FP registers without using a full 64-bit
- load/store, we need a wider mode. */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
- rs6000_secondary_memory_needed_mode (MODE)
-
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index f9be5d3..b21652b 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -155,7 +155,6 @@ extern void rs6000_emit_le_vsx_permute (rtx, rtx, machine_mode);
extern void rs6000_emit_le_vsx_move (rtx, rtx, machine_mode);
extern bool valid_sf_si_move (rtx, rtx, machine_mode);
extern void rs6000_emit_move (rtx, rtx, machine_mode);
-extern machine_mode rs6000_secondary_memory_needed_mode (machine_mode);
extern rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode,
int, int, int, int *);
extern bool rs6000_legitimate_offset_address_p (machine_mode, rtx,
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 1338371..a4a89d0 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1876,6 +1876,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE rs6000_secondary_memory_needed_mode
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
@@ -19242,10 +19244,9 @@ mems_ok_for_quad_peep (rtx mem1, rtx mem2)
return 1;
}
-/* Return the mode to be used for memory when a secondary memory
- location is needed. For SDmode values we need to use DDmode, in
- all other cases we can use the same mode. */
-machine_mode
+/* Implement TARGET_SECONDARY_RELOAD_NEEDED_MODE. For SDmode values we
+ need to use DDmode, in all other cases we can use the same mode. */
+static machine_mode
rs6000_secondary_memory_needed_mode (machine_mode mode)
{
if (lra_in_progress && mode == SDmode)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 7ac6e3b..1a7ce96 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1514,13 +1514,6 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
rs6000_secondary_memory_needed_ptr (CLASS1, CLASS2, MODE)
-/* Specify the mode to be used for memory when a secondary memory
- location is needed. For cpus that cannot load/store SDmode values
- from the 64-bit FP registers without using a full 64-bit
- load/store, we need a wider mode. */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
- rs6000_secondary_memory_needed_mode (MODE)
-
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 46d6c32..1319f68 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -4409,6 +4409,19 @@ s390_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
return NO_REGS;
}
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
+
+ get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit
+ because the movsi and movsf patterns don't handle r/f moves. */
+
+static machine_mode
+s390_secondary_memory_needed_mode (machine_mode mode)
+{
+ if (GET_MODE_BITSIZE (mode) < 32)
+ return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
+ return mode;
+}
+
/* Generate code to load SRC, which is PLUS that is not a
legitimate operand for the LA instruction, into TARGET.
SCRATCH may be used as scratch register. */
@@ -15959,6 +15972,8 @@ s390_asan_shadow_offset (void)
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD s390_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE s390_secondary_memory_needed_mode
#undef TARGET_LIBGCC_CMP_RETURN_MODE
#define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 0682fb6..b4a23c3 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -599,13 +599,6 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
&& (!TARGET_VX || (SCALAR_FLOAT_MODE_P (MODE) \
&& GET_MODE_SIZE (MODE) > 8)))
-/* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit
- because the movsi and movsf patterns don't handle r/f moves. */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
- (GET_MODE_BITSIZE (MODE) < 32 \
- ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \
- : (MODE))
-
/* Stack layout and calling conventions. */
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 9a7e467..469b03d 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -672,6 +672,7 @@ static void sparc_print_operand_address (FILE *, machine_mode, rtx);
static reg_class_t sparc_secondary_reload (bool, rtx, reg_class_t,
machine_mode,
secondary_reload_info *);
+static machine_mode sparc_secondary_memory_needed_mode (machine_mode);
static scalar_int_mode sparc_cstore_mode (enum insn_code icode);
static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *);
static bool sparc_fixed_condition_code_regs (unsigned int *, unsigned int *);
@@ -859,6 +860,8 @@ char sparc_hard_reg_printed[8];
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD sparc_secondary_reload
+#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
+#define TARGET_SECONDARY_MEMORY_NEEDED_MODE sparc_secondary_memory_needed_mode
#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE sparc_conditional_register_usage
@@ -13050,6 +13053,30 @@ sparc_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
return NO_REGS;
}
+/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
+
+ get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9
+ because the movsi and movsf patterns don't handle r/f moves.
+ For v8 we copy the default definition. */
+
+static machine_mode
+sparc_secondary_memory_needed_mode (machine_mode mode)
+{
+ if (TARGET_ARCH64)
+ {
+ if (GET_MODE_BITSIZE (mode) < 32)
+ return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
+ return mode;
+ }
+ else
+ {
+ if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
+ return mode_for_size (BITS_PER_WORD,
+ GET_MODE_CLASS (mode), 0).require ();
+ return mode;
+ }
+}
+
/* Emit code to conditionally move either OPERANDS[2] or OPERANDS[3] into
OPERANDS[0] in MODE. OPERANDS[1] is the operator of the condition. */
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index e037897..51bc318 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1055,18 +1055,6 @@ extern char leaf_reg_remap[];
|| GET_MODE_SIZE (MODE) > 8 \
|| GET_MODE_SIZE (MODE) < 4))
-/* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9
- because the movsi and movsf patterns don't handle r/f moves.
- For v8 we copy the default definition. */
-#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
- (TARGET_ARCH64 \
- ? (GET_MODE_BITSIZE (MODE) < 32 \
- ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \
- : MODE) \
- : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \
- ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require () \
- : MODE))
-
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
/* On SPARC, this is the size of MODE in words. */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 98e6015..5e90208 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2747,29 +2747,27 @@ Do not define this macro if you do not define
@code{SECONDARY_MEMORY_NEEDED}.
@end defmac
-@defmac SECONDARY_MEMORY_NEEDED_MODE (@var{mode})
-When the compiler needs a secondary memory location to copy between two
-registers of mode @var{mode}, it normally allocates sufficient memory to
-hold a quantity of @code{BITS_PER_WORD} bits and performs the store and
-load operations in a mode that many bits wide and whose class is the
-same as that of @var{mode}.
-
-This is right thing to do on most machines because it ensures that all
-bits of the register are copied and prevents accesses to the registers
-in a narrower mode, which some machines prohibit for floating-point
-registers.
+@deftypefn {Target Hook} machine_mode TARGET_SECONDARY_MEMORY_NEEDED_MODE (machine_mode @var{mode})
+If @code{SECONDARY_MEMORY_NEEDED} tells the compiler to use memory
+when moving between two particular registers of mode @var{mode},
+this hook specifies the mode that the memory should have.
+
+The default depends on @code{TARGET_LRA_P}. Without LRA, the default
+is to use a word-sized mode for integral modes that are smaller than a
+a word. This is right thing to do on most machines because it ensures
+that all bits of the register are copied and prevents accesses to the
+registers in a narrower mode, which some machines prohibit for
+floating-point registers.
However, this default behavior is not correct on some machines, such as
the DEC Alpha, that store short integers in floating-point registers
differently than in integer registers. On those machines, the default
-widening will not work correctly and you must define this macro to
-suppress that widening in some cases. See the file @file{alpha.h} for
+widening will not work correctly and you must define this hook to
+suppress that widening in some cases. See the file @file{alpha.c} for
details.
-Do not define this macro if you do not define
-@code{SECONDARY_MEMORY_NEEDED} or if widening @var{mode} to a mode that
-is @code{BITS_PER_WORD} bits wide is correct for your machine.
-@end defmac
+With LRA, the default is to use @var{mode} unmodified.
+@end deftypefn
@deftypefn {Target Hook} bool TARGET_CLASS_LIKELY_SPILLED_P (reg_class_t @var{rclass})
A target hook which returns @code{true} if pseudos that have been assigned
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index acf47e0..1919176 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2324,29 +2324,7 @@ Do not define this macro if you do not define
@code{SECONDARY_MEMORY_NEEDED}.
@end defmac
-@defmac SECONDARY_MEMORY_NEEDED_MODE (@var{mode})
-When the compiler needs a secondary memory location to copy between two
-registers of mode @var{mode}, it normally allocates sufficient memory to
-hold a quantity of @code{BITS_PER_WORD} bits and performs the store and
-load operations in a mode that many bits wide and whose class is the
-same as that of @var{mode}.
-
-This is right thing to do on most machines because it ensures that all
-bits of the register are copied and prevents accesses to the registers
-in a narrower mode, which some machines prohibit for floating-point
-registers.
-
-However, this default behavior is not correct on some machines, such as
-the DEC Alpha, that store short integers in floating-point registers
-differently than in integer registers. On those machines, the default
-widening will not work correctly and you must define this macro to
-suppress that widening in some cases. See the file @file{alpha.h} for
-details.
-
-Do not define this macro if you do not define
-@code{SECONDARY_MEMORY_NEEDED} or if widening @var{mode} to a mode that
-is @code{BITS_PER_WORD} bits wide is correct for your machine.
-@end defmac
+@hook TARGET_SECONDARY_MEMORY_NEEDED_MODE
@hook TARGET_CLASS_LIKELY_SPILLED_P
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 4859c58..84be6c3 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1203,11 +1203,9 @@ check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED)
return false;
#ifdef SECONDARY_MEMORY_NEEDED
if (SECONDARY_MEMORY_NEEDED (sclass, dclass, GET_MODE (src))
-#ifdef SECONDARY_MEMORY_NEEDED_MODE
&& ((sclass != NO_REGS && dclass != NO_REGS)
- || GET_MODE (src) != SECONDARY_MEMORY_NEEDED_MODE (GET_MODE (src)))
-#endif
- )
+ || (GET_MODE (src)
+ != targetm.secondary_memory_needed_mode (GET_MODE (src)))))
{
*sec_mem_p = true;
return false;
@@ -3940,11 +3938,7 @@ curr_insn_transform (bool check_only_p)
&& curr_static_id->operand[in].type == OP_IN);
rld = partial_subreg_p (GET_MODE (src), GET_MODE (dest)) ? src : dest;
rld_mode = GET_MODE (rld);
-#ifdef SECONDARY_MEMORY_NEEDED_MODE
- sec_mode = SECONDARY_MEMORY_NEEDED_MODE (rld_mode);
-#else
- sec_mode = rld_mode;
-#endif
+ sec_mode = targetm.secondary_memory_needed_mode (rld_mode);
new_reg = lra_create_new_reg (sec_mode, NULL_RTX,
NO_REGS, "secondary");
/* If the mode is changed, it should be wider. */
diff --git a/gcc/reload.c b/gcc/reload.c
index a5dd47c..d0061e5 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -574,13 +574,7 @@ get_secondary_mem (rtx x ATTRIBUTE_UNUSED, machine_mode mode,
locations do not support short load and stores from all registers
(e.g., FP registers). */
-#ifdef SECONDARY_MEMORY_NEEDED_MODE
- mode = SECONDARY_MEMORY_NEEDED_MODE (mode);
-#else
- if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode))
- mode = mode_for_size (BITS_PER_WORD,
- GET_MODE_CLASS (mode), 0).require ();
-#endif
+ mode = targetm.secondary_memory_needed_mode (mode);
/* If we already have made a MEM for this operand in MODE, return it. */
if (secondary_memlocs_elim[(int) mode][opnum] != 0)
diff --git a/gcc/system.h b/gcc/system.h
index 00c3e3f..7543339 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -913,7 +913,7 @@ extern void fancy_abort (const char *, int, const char *)
STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD \
HARD_REGNO_CALL_PART_CLOBBERED HARD_REGNO_MODE_OK \
MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS \
- HARD_REGNO_NREGS
+ HARD_REGNO_NREGS SECONDARY_MEMORY_NEEDED_MODE
/* Target macros only used for code built for the target, that have
moved to libgcc-tm.h or have never been present elsewhere. */
diff --git a/gcc/target.def b/gcc/target.def
index 6462c94..7abb74e 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5265,6 +5265,30 @@ forwarding logic, you can set @code{sri->extra_cost} to a negative amount.",
secondary_reload_info *sri),
default_secondary_reload)
+DEFHOOK
+(secondary_memory_needed_mode,
+ "If @code{SECONDARY_MEMORY_NEEDED} tells the compiler to use memory\n\
+when moving between two particular registers of mode @var{mode},\n\
+this hook specifies the mode that the memory should have.\n\
+\n\
+The default depends on @code{TARGET_LRA_P}. Without LRA, the default\n\
+is to use a word-sized mode for integral modes that are smaller than a\n\
+a word. This is right thing to do on most machines because it ensures\n\
+that all bits of the register are copied and prevents accesses to the\n\
+registers in a narrower mode, which some machines prohibit for\n\
+floating-point registers.\n\
+\n\
+However, this default behavior is not correct on some machines, such as\n\
+the DEC Alpha, that store short integers in floating-point registers\n\
+differently than in integer registers. On those machines, the default\n\
+widening will not work correctly and you must define this hook to\n\
+suppress that widening in some cases. See the file @file{alpha.c} for\n\
+details.\n\
+\n\
+With LRA, the default is to use @var{mode} unmodified.",
+ machine_mode, (machine_mode mode),
+ default_secondary_memory_needed_mode)
+
/* Given an rtx X being reloaded into a reg required to be in class CLASS,
return the class of reg to actually use. */
DEFHOOK
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index d2b7082..98e553c 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1129,6 +1129,18 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
return rclass;
}
+/* The default implementation of TARGET_SECONDARY_MEMORY_NEEDED_MODE. */
+
+machine_mode
+default_secondary_memory_needed_mode (machine_mode mode)
+{
+ if (!targetm.lra_p ()
+ && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
+ && INTEGRAL_MODE_P (mode))
+ return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require ();
+ return mode;
+}
+
/* By default, if flag_pic is true, then neither local nor global relocs
should be placed in readonly memory. */
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index a0bd4aa..3d03215 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -159,6 +159,7 @@ extern bool default_different_addr_displacement_p (void);
extern reg_class_t default_secondary_reload (bool, rtx, reg_class_t,
machine_mode,
secondary_reload_info *);
+extern machine_mode default_secondary_memory_needed_mode (machine_mode);
extern void default_target_option_override (void);
extern void hook_void_bitmap (bitmap);
extern int default_reloc_rw_mask (void);