diff options
Diffstat (limited to 'gcc/config')
28 files changed, 166 insertions, 166 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 28fe467..bb81f8e 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -1689,6 +1689,20 @@ alpha_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, return NO_REGS; } +/* Implement TARGET_SECONDARY_MEMORY_NEEDED. + + If we are copying between general and FP registers, we need a memory + location unless the FIX extension is available. */ + +static bool +alpha_secondary_memory_needed (machine_mode, reg_class_t class1, + reg_class_t class2) +{ + return (!TARGET_FIX + && ((class1 == FLOAT_REGS && class2 != FLOAT_REGS) + || (class2 == FLOAT_REGS && class1 != FLOAT_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 @@ -10077,6 +10091,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 +#define TARGET_SECONDARY_MEMORY_NEEDED alpha_secondary_memory_needed #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE #define TARGET_SECONDARY_MEMORY_NEEDED_MODE alpha_secondary_memory_needed_mode diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 10f32b7..e42b649 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -479,13 +479,6 @@ enum reg_class { #define PREFERRED_RELOAD_CLASS alpha_preferred_reload_class -/* If we are copying between general and FP registers, we need a memory - location unless the FIX extension is available. */ - -#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - (! TARGET_FIX && (((CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS) \ - || ((CLASS2) == FLOAT_REGS && (CLASS1) != FLOAT_REGS))) - /* 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-protos.h b/gcc/config/i386/i386-protos.h index 4c57615..ecb0a4c 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -167,8 +167,6 @@ extern int ix86_reg_parm_stack_space (const_tree); extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, rtx, rtx, rtx); -extern bool ix86_secondary_memory_needed (enum reg_class, enum reg_class, - machine_mode, int); extern bool ix86_cannot_change_mode_class (machine_mode, machine_mode, enum reg_class); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a508f56..b2b02ac 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -41102,8 +41102,8 @@ ix86_class_likely_spilled_p (reg_class_t rclass) To optimize register_move_cost performance, define inline variant. */ static inline bool -inline_secondary_memory_needed (enum reg_class class1, enum reg_class class2, - machine_mode mode, int strict) +inline_secondary_memory_needed (machine_mode mode, reg_class_t class1, + reg_class_t class2, int strict) { if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS)) return false; @@ -41155,11 +41155,13 @@ inline_secondary_memory_needed (enum reg_class class1, enum reg_class class2, return false; } -bool -ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2, - machine_mode mode, int strict) +/* Implement TARGET_SECONDARY_MEMORY_NEEDED. */ + +static bool +ix86_secondary_memory_needed (machine_mode mode, reg_class_t class1, + reg_class_t class2) { - return inline_secondary_memory_needed (class1, class2, mode, strict); + return inline_secondary_memory_needed (mode, class1, class2, true); } /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE. @@ -41380,7 +41382,7 @@ ix86_register_move_cost (machine_mode mode, reg_class_t class1_i, by load. In order to avoid bad register allocation choices, we need for this to be *at least* as high as the symmetric MEMORY_MOVE_COST. */ - if (inline_secondary_memory_needed (class1, class2, mode, 0)) + if (inline_secondary_memory_needed (mode, class1, class2, false)) { int cost = 1; @@ -53220,6 +53222,8 @@ ix86_run_selftests (void) #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD ix86_secondary_reload +#undef TARGET_SECONDARY_MEMORY_NEEDED +#define TARGET_SECONDARY_MEMORY_NEEDED ix86_secondary_memory_needed #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE #define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 09b8da5..cbd6a11 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1519,11 +1519,6 @@ enum reg_class #define INDEX_REG_CLASS INDEX_REGS #define BASE_REG_CLASS GENERAL_REGS -/* If we are copying between general and FP registers, we need a memory - location. The same is true for SSE and MMX registers. */ -#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ - ix86_secondary_memory_needed ((CLASS1), (CLASS2), (MODE), 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/ia64/ia64.c b/gcc/config/ia64/ia64.c index d1f44d6..b9b85a0 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -1626,8 +1626,8 @@ ia64_split_tmode_move (rtx operands[]) /* ??? Fixing GR->FR XFmode moves during reload is hard. You need to go through memory plus an extra GR scratch register. Except that you can - either get the first from SECONDARY_MEMORY_NEEDED or the second from - SECONDARY_RELOAD_CLASS, but not both. + either get the first from TARGET_SECONDARY_MEMORY_NEEDED or the second + from SECONDARY_RELOAD_CLASS, but not both. We got into problems in the first place by allowing a construct like (subreg:XF (reg:TI)), which we got from a union containing a long double. diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index cdb91a3..7eefa44 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -767,24 +767,6 @@ enum reg_class #define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \ ia64_secondary_reload_class (CLASS, MODE, X) -/* Certain machines have the property that some registers cannot be copied to - some other registers without using memory. Define this macro on those - machines to be a C expression that is nonzero if objects of mode M in - registers of CLASS1 can only be copied to registers of class CLASS2 by - storing a register of CLASS1 into memory and loading that memory location - into a register of CLASS2. */ - -#if 0 -/* ??? May need this, but since we've disallowed XFmode in GR_REGS, - I'm not quite sure how it could be invoked. The normal problems - with unions should be solved with the addressof fiddling done by - movxf and friends. */ -#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ - (((MODE) == XFmode || (MODE) == XCmode) \ - && (((CLASS1) == GR_REGS && (CLASS2) == FR_REGS) \ - || ((CLASS1) == FR_REGS && (CLASS2) == GR_REGS))) -#endif - /* A C expression for the maximum number of consecutive registers of class CLASS needed to hold a value of mode MODE. This is closely related to TARGET_HARD_REGNO_NREGS. */ diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index ed26aaa..d487f6f 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -294,8 +294,6 @@ extern bool mips_const_vector_bitimm_set_p (rtx, machine_mode); extern bool mips_const_vector_bitimm_clr_p (rtx, machine_mode); extern rtx mips_msa_vec_parallel_const_half (machine_mode, bool); extern rtx mips_gen_const_int_vector (machine_mode, HOST_WIDE_INT); -extern bool mips_secondary_memory_needed (enum reg_class, enum reg_class, - machine_mode); extern bool mips_cannot_change_mode_class (machine_mode, machine_mode, enum reg_class); extern bool mips_dangerous_for_la25_p (rtx); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 266daec..20051a7 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -13201,11 +13201,22 @@ mips_memory_move_cost (machine_mode mode, reg_class_t rclass, bool in) + memory_move_secondary_cost (mode, rclass, in)); } -/* Implement SECONDARY_MEMORY_NEEDED. */ +/* Implement TARGET_SECONDARY_MEMORY_NEEDED. + + When targeting the o32 FPXX ABI, all moves with a length of doubleword + or greater must be performed by FR-mode-aware instructions. + This can be achieved using MFHC1/MTHC1 when these instructions are + available but otherwise moves must go via memory. + For the o32 FP64A ABI, all odd-numbered moves with a length of + doubleword or greater are required to use memory. Using MTC1/MFC1 + to access the lower-half of these registers would require a forbidden + single-precision access. We require all double-word moves to use + memory because adding even and odd floating-point registers classes + would have a significant impact on the backend. */ -bool -mips_secondary_memory_needed (enum reg_class class1, enum reg_class class2, - machine_mode mode) +static bool +mips_secondary_memory_needed (machine_mode mode, reg_class_t class1, + reg_class_t class2) { /* Ignore spilled pseudos. */ if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS)) @@ -22607,6 +22618,9 @@ mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2 +#undef TARGET_SECONDARY_MEMORY_NEEDED +#define TARGET_SECONDARY_MEMORY_NEEDED mips_secondary_memory_needed + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-mips.h" diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 4ebefcc..1a54dc6 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2298,19 +2298,6 @@ enum reg_class #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ mips_secondary_reload_class (CLASS, MODE, X, false) -/* When targeting the o32 FPXX ABI, all moves with a length of doubleword - or greater must be performed by FR-mode-aware instructions. - This can be achieved using MFHC1/MTHC1 when these instructions are - available but otherwise moves must go via memory. - For the o32 FP64A ABI, all odd-numbered moves with a length of - doubleword or greater are required to use memory. Using MTC1/MFC1 - to access the lower-half of these registers would require a forbidden - single-precision access. We require all double-word moves to use - memory because adding even and odd floating-point registers classes - would have a significant impact on the backend. */ -#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ - mips_secondary_memory_needed ((CLASS1), (CLASS2), (MODE)) - /* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. */ diff --git a/gcc/config/mmix/mmix.md b/gcc/config/mmix/mmix.md index 60b1e58..2725107 100644 --- a/gcc/config/mmix/mmix.md +++ b/gcc/config/mmix/mmix.md @@ -623,7 +623,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") ;; possible to do that? Bug in GCC? Anyway, this used to be a simple ;; pattern with a memory_operand predicate, but was split up with a ;; define_expand with the old pattern as "anonymous". -;; FIXME: Perhaps with SECONDARY_MEMORY_NEEDED? +;; FIXME: Perhaps with TARGET_SECONDARY_MEMORY_NEEDED? (define_expand "truncdfsf2" [(set (match_operand:SF 0 "nonimmediate_operand") (float_truncate:SF (match_operand:DF 1 "register_operand")))] diff --git a/gcc/config/pa/pa-64.h b/gcc/config/pa/pa-64.h index 1d08b28..e10cbb3 100644 --- a/gcc/config/pa/pa-64.h +++ b/gcc/config/pa/pa-64.h @@ -97,7 +97,7 @@ along with GCC; see the file COPYING3. If not see function which has no frame and this function might also use SP-16. We have 14-bit immediates on the 64-bit port, so we use secondary memory for the copies. */ -#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ +#define PA_SECONDARY_MEMORY_NEEDED(MODE, CLASS1, CLASS2) \ (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2) \ || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1)) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index f9c7a7c..f39b672 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -178,6 +178,8 @@ static struct machine_function * pa_init_machine_status (void); static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t, machine_mode, secondary_reload_info *); +static bool pa_secondary_memory_needed (machine_mode, + reg_class_t, reg_class_t); static void pa_extra_live_on_entry (bitmap); static machine_mode pa_promote_function_mode (const_tree, machine_mode, int *, @@ -377,6 +379,8 @@ static size_t n_deferred_plabels = 0; #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD pa_secondary_reload +#undef TARGET_SECONDARY_MEMORY_NEEDED +#define TARGET_SECONDARY_MEMORY_NEEDED pa_secondary_memory_needed #undef TARGET_EXTRA_LIVE_ON_ENTRY #define TARGET_EXTRA_LIVE_ON_ENTRY pa_extra_live_on_entry @@ -6189,6 +6193,20 @@ pa_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, return NO_REGS; } +/* Implement TARGET_SECONDARY_MEMORY_NEEDED. */ + +static bool +pa_secondary_memory_needed (machine_mode mode ATTRIBUTE_UNUSED, + reg_class_t class1 ATTRIBUTE_UNUSED, + reg_class_t class2 ATTRIBUTE_UNUSED) +{ +#ifdef PA_SECONDARY_MEMORY_NEEDED + return PA_SECONDARY_MEMORY_NEEDED (mode, class1, class2); +#else + return false; +#endif +} + /* Implement TARGET_EXTRA_LIVE_ON_ENTRY. The argument pointer is only marked as live on entry by df-scan when it is a fixed register. It isn't a fixed register in the 64-bit runtime, diff --git a/gcc/config/pdp11/pdp11-protos.h b/gcc/config/pdp11/pdp11-protos.h index b89e1f9..2fe1386 100644 --- a/gcc/config/pdp11/pdp11-protos.h +++ b/gcc/config/pdp11/pdp11-protos.h @@ -31,8 +31,6 @@ extern const char *output_jump (enum rtx_code, int, int); extern void print_operand_address (FILE *, rtx); extern bool pdp11_cannot_change_mode_class (machine_mode, machine_mode, enum reg_class); -extern bool pdp11_secondary_memory_needed (reg_class_t, reg_class_t, - machine_mode); typedef enum { no_action, dec_before, inc_after } pdp11_action; typedef enum { little, either, big } pdp11_partorder; extern bool pdp11_expand_operands (rtx *, rtx [][2], int, diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index fd50e6a..5364b47 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -243,6 +243,9 @@ static bool pdp11_scalar_mode_supported_p (scalar_mode); #undef TARGET_MODES_TIEABLE_P #define TARGET_MODES_TIEABLE_P pdp11_modes_tieable_p + +#undef TARGET_SECONDARY_MEMORY_NEEDED +#define TARGET_SECONDARY_MEMORY_NEEDED pdp11_secondary_memory_needed /* A helper function to determine if REGNO should be saved in the current function's stack frame. */ @@ -1453,14 +1456,13 @@ pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED, return LOAD_FPU_REGS; } -/* Target routine to check if register to register move requires memory. +/* Implement TARGET_SECONDARY_MEMORY_NEEDED. The answer is yes if we're going between general register and FPU registers. The mode doesn't matter in making this check. */ -bool -pdp11_secondary_memory_needed (reg_class_t c1, reg_class_t c2, - machine_mode mode ATTRIBUTE_UNUSED) +static bool +pdp11_secondary_memory_needed (machine_mode, reg_class_t c1, reg_class_t c2) { int fromfloat = (c1 == LOAD_FPU_REGS || c1 == NO_LOAD_FPU_REGS || c1 == FPU_REGS); diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h index cd1d135..d220697 100644 --- a/gcc/config/pdp11/pdp11.h +++ b/gcc/config/pdp11/pdp11.h @@ -236,10 +236,6 @@ enum reg_class { NO_REGS, MUL_REGS, GENERAL_REGS, LOAD_FPU_REGS, NO_LOAD_FPU_REG #define INDEX_REG_CLASS GENERAL_REGS #define BASE_REG_CLASS GENERAL_REGS -/* Hook for testing if memory is needed for moving between registers. */ -#define SECONDARY_MEMORY_NEEDED(class1, class2, m) \ - pdp11_secondary_memory_needed (class1, class2, m) - /* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ diff --git a/gcc/config/powerpcspe/powerpcspe-protos.h b/gcc/config/powerpcspe/powerpcspe-protos.h index f3aa41b..c87a6a0 100644 --- a/gcc/config/powerpcspe/powerpcspe-protos.h +++ b/gcc/config/powerpcspe/powerpcspe-protos.h @@ -109,9 +109,6 @@ extern enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, machine_mode, rtx); -extern bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, - enum reg_class, - machine_mode); extern bool (*rs6000_cannot_change_mode_class_ptr) (machine_mode, machine_mode, enum reg_class); diff --git a/gcc/config/powerpcspe/powerpcspe.c b/gcc/config/powerpcspe/powerpcspe.c index 9b8d68b..499dc1d 100644 --- a/gcc/config/powerpcspe/powerpcspe.c +++ b/gcc/config/powerpcspe/powerpcspe.c @@ -1384,11 +1384,9 @@ static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class, static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class); static enum reg_class rs6000_debug_preferred_reload_class (rtx, enum reg_class); -static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class, - machine_mode); -static bool rs6000_debug_secondary_memory_needed (enum reg_class, - enum reg_class, - machine_mode); +static bool rs6000_debug_secondary_memory_needed (machine_mode, + reg_class_t, + reg_class_t); static bool rs6000_cannot_change_mode_class (machine_mode, machine_mode, enum reg_class); @@ -1412,10 +1410,6 @@ enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class) = rs6000_preferred_reload_class; -bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class, - machine_mode) - = rs6000_secondary_memory_needed; - bool (*rs6000_cannot_change_mode_class_ptr) (machine_mode, machine_mode, enum reg_class) @@ -1897,6 +1891,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 +#define TARGET_SECONDARY_MEMORY_NEEDED rs6000_secondary_memory_needed #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE #define TARGET_SECONDARY_MEMORY_NEEDED_MODE rs6000_secondary_memory_needed_mode @@ -5098,7 +5094,7 @@ rs6000_option_override_internal (bool global_init_p) targetm.legitimize_address = rs6000_debug_legitimize_address; rs6000_secondary_reload_class_ptr = rs6000_debug_secondary_reload_class; - rs6000_secondary_memory_needed_ptr + targetm.secondary_memory_needed = rs6000_debug_secondary_memory_needed; rs6000_cannot_change_mode_class_ptr = rs6000_debug_cannot_change_mode_class; @@ -23149,9 +23145,9 @@ rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass) set and vice versa. */ static bool -rs6000_secondary_memory_needed (enum reg_class from_class, - enum reg_class to_class, - machine_mode mode) +rs6000_secondary_memory_needed (machine_mode mode, + reg_class_t from_class, + reg_class_t to_class) { enum rs6000_reg_type from_type, to_type; bool altivec_p = ((from_class == ALTIVEC_REGS) @@ -23175,11 +23171,11 @@ rs6000_secondary_memory_needed (enum reg_class from_class, /* Debug version of rs6000_secondary_memory_needed. */ static bool -rs6000_debug_secondary_memory_needed (enum reg_class from_class, - enum reg_class to_class, - machine_mode mode) +rs6000_debug_secondary_memory_needed (machine_mode mode, + reg_class_t from_class, + reg_class_t to_class) { - bool ret = rs6000_secondary_memory_needed (from_class, to_class, mode); + bool ret = rs6000_secondary_memory_needed (mode, from_class, to_class); fprintf (stderr, "rs6000_secondary_memory_needed, return: %s, from_class = %s, " diff --git a/gcc/config/powerpcspe/powerpcspe.h b/gcc/config/powerpcspe/powerpcspe.h index 5d1a138..be3d0e8 100644 --- a/gcc/config/powerpcspe/powerpcspe.h +++ b/gcc/config/powerpcspe/powerpcspe.h @@ -1596,14 +1596,6 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ rs6000_secondary_reload_class_ptr (CLASS, MODE, IN) -/* If we are copying between FP or AltiVec registers and anything - else, we need a memory location. The exception is when we are - targeting ppc64 and the move to/from fpr to gpr instructions - are available.*/ - -#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - rs6000_secondary_memory_needed_ptr (CLASS1, CLASS2, MODE) - /* For cpus that cannot load/store SDmode values from the 64-bit FP registers without using a full 64-bit load/store, we need to allocate a full 64-bit stack slot for them. */ diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 999f93e..c6390aa 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -3510,13 +3510,26 @@ riscv_can_use_return_insn (void) return reload_completed && cfun->machine->frame.total_size == 0; } +/* Implement TARGET_SECONDARY_MEMORY_NEEDED. + + When floating-point registers are wider than integer ones, moves between + them must go through memory. */ + +static bool +riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1, + reg_class_t class2) +{ + return (GET_MODE_SIZE (mode) > UNITS_PER_WORD + && (class1 == FP_REGS) != (class2 == FP_REGS)); +} + /* Implement TARGET_REGISTER_MOVE_COST. */ static int riscv_register_move_cost (machine_mode mode, reg_class_t from, reg_class_t to) { - return SECONDARY_MEMORY_NEEDED (from, to, mode) ? 8 : 2; + return riscv_secondary_memory_needed (mode, from, to) ? 8 : 2; } /* Implement TARGET_HARD_REGNO_NREGS. */ @@ -4115,6 +4128,9 @@ riscv_slow_unaligned_access (machine_mode, unsigned int) #undef TARGET_SLOW_UNALIGNED_ACCESS #define TARGET_SLOW_UNALIGNED_ACCESS riscv_slow_unaligned_access +#undef TARGET_SECONDARY_MEMORY_NEEDED +#define TARGET_SECONDARY_MEMORY_NEEDED riscv_secondary_memory_needed + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-riscv.h" diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 4e67211..0a5ae40 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -221,12 +221,6 @@ along with GCC; see the file COPYING3. If not see Extensions of pointers to word_mode must be signed. */ #define POINTERS_EXTEND_UNSIGNED false -/* When floating-point registers are wider than integer ones, moves between - them must go through memory. */ -#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - (GET_MODE_SIZE (MODE) > UNITS_PER_WORD \ - && ((CLASS1) == FP_REGS) != ((CLASS2) == FP_REGS)) - /* Define if loading short immediate values into registers sign extends. */ #define SHORT_IMMEDIATES_SIGN_EXTEND 1 diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index b21652b..6e80396 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -110,9 +110,6 @@ extern enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, machine_mode, rtx); -extern bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, - enum reg_class, - machine_mode); extern bool (*rs6000_cannot_change_mode_class_ptr) (machine_mode, machine_mode, enum reg_class); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a4a89d0..3fee228 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1389,11 +1389,9 @@ static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class, static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class); static enum reg_class rs6000_debug_preferred_reload_class (rtx, enum reg_class); -static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class, - machine_mode); -static bool rs6000_debug_secondary_memory_needed (enum reg_class, - enum reg_class, - machine_mode); +static bool rs6000_debug_secondary_memory_needed (machine_mode, + reg_class_t, + reg_class_t); static bool rs6000_cannot_change_mode_class (machine_mode, machine_mode, enum reg_class); @@ -1417,10 +1415,6 @@ enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class) = rs6000_preferred_reload_class; -bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class, - machine_mode) - = rs6000_secondary_memory_needed; - bool (*rs6000_cannot_change_mode_class_ptr) (machine_mode, machine_mode, enum reg_class) @@ -1876,6 +1870,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 +#define TARGET_SECONDARY_MEMORY_NEEDED rs6000_secondary_memory_needed #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE #define TARGET_SECONDARY_MEMORY_NEEDED_MODE rs6000_secondary_memory_needed_mode @@ -4716,7 +4712,7 @@ rs6000_option_override_internal (bool global_init_p) targetm.legitimize_address = rs6000_debug_legitimize_address; rs6000_secondary_reload_class_ptr = rs6000_debug_secondary_reload_class; - rs6000_secondary_memory_needed_ptr + targetm.secondary_memory_needed = rs6000_debug_secondary_memory_needed; rs6000_cannot_change_mode_class_ptr = rs6000_debug_cannot_change_mode_class; @@ -20491,9 +20487,9 @@ rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass) set and vice versa. */ static bool -rs6000_secondary_memory_needed (enum reg_class from_class, - enum reg_class to_class, - machine_mode mode) +rs6000_secondary_memory_needed (machine_mode mode, + reg_class_t from_class, + reg_class_t to_class) { enum rs6000_reg_type from_type, to_type; bool altivec_p = ((from_class == ALTIVEC_REGS) @@ -20517,11 +20513,11 @@ rs6000_secondary_memory_needed (enum reg_class from_class, /* Debug version of rs6000_secondary_memory_needed. */ static bool -rs6000_debug_secondary_memory_needed (enum reg_class from_class, - enum reg_class to_class, - machine_mode mode) +rs6000_debug_secondary_memory_needed (machine_mode mode, + reg_class_t from_class, + reg_class_t to_class) { - bool ret = rs6000_secondary_memory_needed (from_class, to_class, mode); + bool ret = rs6000_secondary_memory_needed (mode, from_class, to_class); fprintf (stderr, "rs6000_secondary_memory_needed, return: %s, from_class = %s, " diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 1a7ce96..8ec192e 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1506,14 +1506,6 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ rs6000_secondary_reload_class_ptr (CLASS, MODE, IN) -/* If we are copying between FP or AltiVec registers and anything - else, we need a memory location. The exception is when we are - targeting ppc64 and the move to/from fpr to gpr instructions - are available.*/ - -#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - rs6000_secondary_memory_needed_ptr (CLASS1, CLASS2, 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 1319f68..f62d740 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -4409,6 +4409,35 @@ s390_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, return NO_REGS; } +/* Implement TARGET_SECONDARY_MEMORY_NEEDED. + + We need secondary memory to move data between GPRs and FPRs. + + - With DFP the ldgr lgdr instructions are available. Due to the + different alignment we cannot use them for SFmode. For 31 bit a + 64 bit value in GPR would be a register pair so here we still + need to go via memory. + + - With z13 we can do the SF/SImode moves with vlgvf. Due to the + overlapping of FPRs and VRs we still disallow TF/TD modes to be + in full VRs so as before also on z13 we do these moves via + memory. + + FIXME: Should we try splitting it into two vlgvg's/vlvg's instead? */ + +static bool +s390_secondary_memory_needed (machine_mode mode, + reg_class_t class1, reg_class_t class2) +{ + return (((reg_classes_intersect_p (class1, VEC_REGS) + && reg_classes_intersect_p (class2, GENERAL_REGS)) + || (reg_classes_intersect_p (class1, GENERAL_REGS) + && reg_classes_intersect_p (class2, VEC_REGS))) + && (!TARGET_DFP || !TARGET_64BIT || GET_MODE_SIZE (mode) != 8) + && (!TARGET_VX || (SCALAR_FLOAT_MODE_P (mode) + && GET_MODE_SIZE (mode) > 8))); +} + /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE. get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit @@ -15972,6 +16001,8 @@ s390_asan_shadow_offset (void) #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD s390_secondary_reload +#undef TARGET_SECONDARY_MEMORY_NEEDED +#define TARGET_SECONDARY_MEMORY_NEEDED s390_secondary_memory_needed #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE #define TARGET_SECONDARY_MEMORY_NEEDED_MODE s390_secondary_memory_needed_mode diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index b4a23c3..0932591 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -577,29 +577,6 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; #define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO) -/* We need secondary memory to move data between GPRs and FPRs. - - - With DFP the ldgr lgdr instructions are available. Due to the - different alignment we cannot use them for SFmode. For 31 bit a - 64 bit value in GPR would be a register pair so here we still - need to go via memory. - - - With z13 we can do the SF/SImode moves with vlgvf. Due to the - overlapping of FPRs and VRs we still disallow TF/TD modes to be - in full VRs so as before also on z13 we do these moves via - memory. - - FIXME: Should we try splitting it into two vlgvg's/vlvg's instead? */ -#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ - (((reg_classes_intersect_p ((CLASS1), VEC_REGS) \ - && reg_classes_intersect_p ((CLASS2), GENERAL_REGS)) \ - || (reg_classes_intersect_p ((CLASS1), GENERAL_REGS) \ - && reg_classes_intersect_p ((CLASS2), VEC_REGS))) \ - && (!TARGET_DFP || !TARGET_64BIT || GET_MODE_SIZE (MODE) != 8) \ - && (!TARGET_VX || (SCALAR_FLOAT_MODE_P (MODE) \ - && GET_MODE_SIZE (MODE) > 8))) - - /* Stack layout and calling conventions. */ /* Our stack grows from higher to lower addresses. However, local variables diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 469b03d..aa66f24 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -672,6 +672,8 @@ 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 bool sparc_secondary_memory_needed (machine_mode, reg_class_t, + reg_class_t); 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 *); @@ -860,6 +862,8 @@ char sparc_hard_reg_printed[8]; #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD sparc_secondary_reload +#undef TARGET_SECONDARY_MEMORY_NEEDED +#define TARGET_SECONDARY_MEMORY_NEEDED sparc_secondary_memory_needed #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE #define TARGET_SECONDARY_MEMORY_NEEDED_MODE sparc_secondary_memory_needed_mode @@ -13053,6 +13057,21 @@ sparc_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, return NO_REGS; } +/* Implement TARGET_SECONDARY_MEMORY_NEEDED. + + On SPARC when not VIS3 it is not possible to directly move data + between GENERAL_REGS and FP_REGS. */ + +static bool +sparc_secondary_memory_needed (machine_mode mode, reg_class_t class1, + reg_class_t class2) +{ + return ((FP_REG_CLASS_P (class1) != FP_REG_CLASS_P (class2)) + && (! TARGET_VIS3 + || GET_MODE_SIZE (mode) > 8 + || GET_MODE_SIZE (mode) < 4)); +} + /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE. get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9 diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 51bc318..a9672e3 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1047,14 +1047,6 @@ extern char leaf_reg_remap[]; #define SPARC_SETHI32_P(X) \ (SPARC_SETHI_P ((unsigned HOST_WIDE_INT) (X) & GET_MODE_MASK (SImode))) -/* On SPARC when not VIS3 it is not possible to directly move data - between GENERAL_REGS and FP_REGS. */ -#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ - ((FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2)) \ - && (! TARGET_VIS3 \ - || GET_MODE_SIZE (MODE) > 8 \ - || GET_MODE_SIZE (MODE) < 4)) - /* 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. */ |