diff options
-rw-r--r-- | gcc/ChangeLog | 44 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.c | 17 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 10 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 16 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 8 | ||||
-rw-r--r-- | gcc/config/powerpcspe/powerpcspe-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/powerpcspe/powerpcspe.c | 9 | ||||
-rw-r--r-- | gcc/config/powerpcspe/powerpcspe.h | 7 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 9 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 7 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 15 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 7 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 27 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 12 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 32 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 24 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 12 | ||||
-rw-r--r-- | gcc/reload.c | 8 | ||||
-rw-r--r-- | gcc/system.h | 2 | ||||
-rw-r--r-- | gcc/target.def | 24 | ||||
-rw-r--r-- | gcc/targhooks.c | 12 | ||||
-rw-r--r-- | gcc/targhooks.h | 1 |
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); |