Turn SECONDARY_MEMORY_NEEDED into a hook
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 13 Sep 2017 17:05:16 +0000 (17:05 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 13 Sep 2017 17:05:16 +0000 (17:05 +0000)
Since the patch is going through all the definitions anyway, it seemed
like a good opportunity to put the mode argument first, to match the
order for register_move_cost.

2017-09-13  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* target.def (secondary_memory_needed): New hook.
(secondary_reload): Refer to TARGET_SECONDARY_MEMORY_NEEDED
instead of SECONDARY_MEMORY_NEEDED.
(secondary_memory_needed_mode): Likewise.
* hooks.h (hook_bool_mode_reg_class_t_reg_class_t_false): Declare.
* hooks.c (hook_bool_mode_reg_class_t_reg_class_t_false): New function.
* doc/tm.texi.in (SECONDARY_MEMORY_NEEDED): Replace with...
(TARGET_SECONDARY_MEMORY_NEEDED): ...this.
(SECONDARY_MEMORY_NEEDED_RTX): Update reference accordingly.
* doc/tm.texi: Regenerate.
* config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/alpha/alpha.c (alpha_secondary_memory_needed): New function.
(TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
* config/i386/i386.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/i386/i386-protos.h (ix86_secondary_memory_needed): Delete.
* config/i386/i386.c (inline_secondary_memory_needed): Put the
mode argument first and change the reg_class arguments to reg_class_t.
(ix86_secondary_memory_needed): Likewise.  Remove the strict parameter.
Make static.  Update the call to inline_secondary_memory_needed.
(ix86_register_move_cost): Update the call to
inline_secondary_memory_needed.
(TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
* config/ia64/ia64.h (SECONDARY_MEMORY_NEEDED): Delete commented-out
definition.
* config/ia64/ia64.c (spill_xfmode_rfmode_operand): Refer to
TARGET_SECONDARY_MEMORY_NEEDED rather than SECONDARY_MEMORY_NEEDED
in comment.
* config/mips/mips.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/mips/mips-protos.h (mips_secondary_memory_needed): Delete.
* config/mips/mips.c (mips_secondary_memory_needed): Make static
and match hook interface.  Add comment from mips.h.
(TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
* config/mmix/mmix.md (truncdfsf2): Refer to
TARGET_SECONDARY_MEMORY_NEEDED rather than SECONDARY_MEMORY_NEEDED
in comment.
* config/pa/pa-64.h (SECONDARY_MEMORY_NEEDED): Rename to...
(PA_SECONDARY_MEMORY_NEEDED): ...this, and put the mode argument first.
* config/pa/pa.c (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
(pa_secondary_memory_needed): New function.
* config/pdp11/pdp11.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/pdp11/pdp11-protos.h (pdp11_secondary_memory_needed): Delete.
* config/pdp11/pdp11.c (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
(pdp11_secondary_memory_needed): Make static and match hook interface.
* config/powerpcspe/powerpcspe.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/powerpcspe/powerpcspe-protos.h
(rs6000_secondary_memory_needed_ptr): Delete.
* config/powerpcspe/powerpcspe.c (rs6000_secondary_memory_needed_ptr):
Delete.
(TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
(rs6000_option_override_internal): Assign to
targetm.secondary_memory_needed rather than
rs6000_secondary_memory_needed_ptr.
(rs6000_secondary_memory_needed): Match hook interface.
(rs6000_debug_secondary_memory_needed): Likewise.
* config/riscv/riscv.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/riscv/riscv.c (riscv_secondary_memory_needed): New function.
(riscv_register_move_cost): Use it instead of SECONDARY_MEMORY_NEEDED.
(TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
* config/rs6000/rs6000.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/rs6000/rs6000-protos.h (rs6000_secondary_memory_needed_ptr):
Delete.
* config/rs6000/rs6000.c (rs6000_secondary_memory_needed_ptr): Delete.
(TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
(rs6000_option_override_internal): Assign to
targetm.secondary_memory_needed rather than
rs6000_secondary_memory_needed_ptr.
(rs6000_secondary_memory_needed): Match hook interface.
(rs6000_debug_secondary_memory_needed): Likewise.
* config/s390/s390.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/s390/s390.c (s390_secondary_memory_needed): New function.
(TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
* config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED): Delete.
* config/sparc/sparc.c (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
(sparc_secondary_memory_needed): New function.
* lra-constraints.c (check_and_process_move): Refer to
TARGET_SECONDARY_MEMORY_NEEDED rather than SECONDARY_MEMORY_NEEDED
in comment.
(curr_insn_transform): Likewise.
(process_alt_operands): Use targetm.secondary_memory_needed
instead of TARGET_SECONDARY_MEMORY_NEEDED.
(check_secondary_memory_needed_p): Likewise.
(choose_split_class): Likewise.
* reload.c: Unconditionally include code that was previously
conditional on SECONDARY_MEMORY_NEEDED.
(push_secondary_reload): Use targetm.secondary_memory_needed
instead of TARGET_SECONDARY_MEMORY_NEEDED.
(push_reload): Likewise.
* reload1.c: Unconditionally include code that was previously
conditional on SECONDARY_MEMORY_NEEDED.
(choose_reload_regs): Use targetm.secondary_memory_needed
instead of TARGET_SECONDARY_MEMORY_NEEDED.
(gen_reload): Likewise.
* system.h (SECONDARY_MEMORY_NEEDED): Poison.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r252461

38 files changed:
gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mmix/mmix.md
gcc/config/pa/pa-64.h
gcc/config/pa/pa.c
gcc/config/pdp11/pdp11-protos.h
gcc/config/pdp11/pdp11.c
gcc/config/pdp11/pdp11.h
gcc/config/powerpcspe/powerpcspe-protos.h
gcc/config/powerpcspe/powerpcspe.c
gcc/config/powerpcspe/powerpcspe.h
gcc/config/riscv/riscv.c
gcc/config/riscv/riscv.h
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/hooks.c
gcc/hooks.h
gcc/lra-constraints.c
gcc/reload.c
gcc/reload1.c
gcc/system.h
gcc/target.def

index 6b8f7f3fa1669580f6998fc8fdda034df5340cb8..7bba8a938faa14660a1f629e141a7260e54c63db 100644 (file)
@@ -1,3 +1,101 @@
+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): New hook.
+       (secondary_reload): Refer to TARGET_SECONDARY_MEMORY_NEEDED
+       instead of SECONDARY_MEMORY_NEEDED.
+       (secondary_memory_needed_mode): Likewise.
+       * hooks.h (hook_bool_mode_reg_class_t_reg_class_t_false): Declare.
+       * hooks.c (hook_bool_mode_reg_class_t_reg_class_t_false): New function.
+       * doc/tm.texi.in (SECONDARY_MEMORY_NEEDED): Replace with...
+       (TARGET_SECONDARY_MEMORY_NEEDED): ...this.
+       (SECONDARY_MEMORY_NEEDED_RTX): Update reference accordingly.
+       * doc/tm.texi: Regenerate.
+       * config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/alpha/alpha.c (alpha_secondary_memory_needed): New function.
+       (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       * config/i386/i386.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/i386/i386-protos.h (ix86_secondary_memory_needed): Delete.
+       * config/i386/i386.c (inline_secondary_memory_needed): Put the
+       mode argument first and change the reg_class arguments to reg_class_t.
+       (ix86_secondary_memory_needed): Likewise.  Remove the strict parameter.
+       Make static.  Update the call to inline_secondary_memory_needed.
+       (ix86_register_move_cost): Update the call to
+       inline_secondary_memory_needed.
+       (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       * config/ia64/ia64.h (SECONDARY_MEMORY_NEEDED): Delete commented-out
+       definition.
+       * config/ia64/ia64.c (spill_xfmode_rfmode_operand): Refer to
+       TARGET_SECONDARY_MEMORY_NEEDED rather than SECONDARY_MEMORY_NEEDED
+       in comment.
+       * config/mips/mips.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/mips/mips-protos.h (mips_secondary_memory_needed): Delete.
+       * config/mips/mips.c (mips_secondary_memory_needed): Make static
+       and match hook interface.  Add comment from mips.h.
+       (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       * config/mmix/mmix.md (truncdfsf2): Refer to
+       TARGET_SECONDARY_MEMORY_NEEDED rather than SECONDARY_MEMORY_NEEDED
+       in comment.
+       * config/pa/pa-64.h (SECONDARY_MEMORY_NEEDED): Rename to...
+       (PA_SECONDARY_MEMORY_NEEDED): ...this, and put the mode argument first.
+       * config/pa/pa.c (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       (pa_secondary_memory_needed): New function.
+       * config/pdp11/pdp11.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/pdp11/pdp11-protos.h (pdp11_secondary_memory_needed): Delete.
+       * config/pdp11/pdp11.c (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       (pdp11_secondary_memory_needed): Make static and match hook interface.
+       * config/powerpcspe/powerpcspe.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/powerpcspe/powerpcspe-protos.h
+       (rs6000_secondary_memory_needed_ptr): Delete.
+       * config/powerpcspe/powerpcspe.c (rs6000_secondary_memory_needed_ptr):
+       Delete.
+       (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       (rs6000_option_override_internal): Assign to
+       targetm.secondary_memory_needed rather than
+       rs6000_secondary_memory_needed_ptr.
+       (rs6000_secondary_memory_needed): Match hook interface.
+       (rs6000_debug_secondary_memory_needed): Likewise.
+       * config/riscv/riscv.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/riscv/riscv.c (riscv_secondary_memory_needed): New function.
+       (riscv_register_move_cost): Use it instead of SECONDARY_MEMORY_NEEDED.
+       (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       * config/rs6000/rs6000.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/rs6000/rs6000-protos.h (rs6000_secondary_memory_needed_ptr):
+       Delete.
+       * config/rs6000/rs6000.c (rs6000_secondary_memory_needed_ptr): Delete.
+       (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       (rs6000_option_override_internal): Assign to
+       targetm.secondary_memory_needed rather than
+       rs6000_secondary_memory_needed_ptr.
+       (rs6000_secondary_memory_needed): Match hook interface.
+       (rs6000_debug_secondary_memory_needed): Likewise.
+       * config/s390/s390.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/s390/s390.c (s390_secondary_memory_needed): New function.
+       (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       * config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED): Delete.
+       * config/sparc/sparc.c (TARGET_SECONDARY_MEMORY_NEEDED): Redefine.
+       (sparc_secondary_memory_needed): New function.
+       * lra-constraints.c (check_and_process_move): Refer to
+       TARGET_SECONDARY_MEMORY_NEEDED rather than SECONDARY_MEMORY_NEEDED
+       in comment.
+       (curr_insn_transform): Likewise.
+       (process_alt_operands): Use targetm.secondary_memory_needed
+       instead of TARGET_SECONDARY_MEMORY_NEEDED.
+       (check_secondary_memory_needed_p): Likewise.
+       (choose_split_class): Likewise.
+       * reload.c: Unconditionally include code that was previously
+       conditional on SECONDARY_MEMORY_NEEDED.
+       (push_secondary_reload): Use targetm.secondary_memory_needed
+       instead of TARGET_SECONDARY_MEMORY_NEEDED.
+       (push_reload): Likewise.
+       * reload1.c: Unconditionally include code that was previously
+       conditional on SECONDARY_MEMORY_NEEDED.
+       (choose_reload_regs): Use targetm.secondary_memory_needed
+       instead of TARGET_SECONDARY_MEMORY_NEEDED.
+       (gen_reload): Likewise.
+       * system.h (SECONDARY_MEMORY_NEEDED): Poison.
+
 2017-09-13  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 28fe4672b9c645bcc221b13c1efad56f501e56c7..bb81f8e5f61d18a4aa0cc1d2b6562215133a0fcb 100644 (file)
@@ -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
 
index 10f32b73db86738aaba656367a8af5e221ec9fc3..e42b64985e8692c93e3c205a55fafa20768f07af 100644 (file)
@@ -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)              \
index 4c57615093bf284c2efca2e4b0e5a2490ccff18d..ecb0a4c9682e7978df09baae169080b9eda8fc9e 100644 (file)
@@ -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);
 
index a508f568eaf5704fc2bace0882c6819f0a4b3d9f..b2b02acc58ad1387f8d0128d3e2cc36136d7d656 100644 (file)
@@ -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
 
index 09b8da564eca59dbb65ca6451e584f815ef73a7c..cbd6a111f57054b1ca3bcad7b06c411405de1306 100644 (file)
@@ -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) \
index d1f44d6b1cece0fed487b67d015bf0a0a5b29a9d..b9b85a019258cb6b86072cf27dab109026b7eb7a 100644 (file)
@@ -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.
index cdb91a38ce52dbd5b04c9e969956fb88e29c7b77..7eefa444a21a89e618b3d3100c3b8aa76557e68d 100644 (file)
@@ -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.  */
index ed26aaa8184e700381cfe5831ddb3c8c8493dafd..d487f6f93ee41c6b149a4bfe615f2aa11422a979 100644 (file)
@@ -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);
index 266daec191935dc157a906725447f58e1f26fffc..20051a7e291b36a3b83e2e51d06237ea56713bc2 100644 (file)
@@ -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;
 \f
 #include "gt-mips.h"
index 4ebefcca5bc510023db54aa9c76bea7303f8b50f..1a54dc624b16781e8acda5f7f510fe3c06426c08 100644 (file)
@@ -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.  */
 
index 60b1e580ca67ce1994afa6b8577eb8fe63bde5cd..27251079b77df04be5e5dbdb11691e9a2d36b944 100644 (file)
@@ -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")))]
index 1d08b28e76c12fe4b8addc50b540a269830f96d1..e10cbb3b331b414188d86183d18f28bf6d7f0c69 100644 (file)
@@ -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))
 
index f9c7a7cdb4b8e8bf8cd57ae2769cf1192516a11c..f39b6721d2440c1e3e2c7476f1eec8d1be2f7eb9 100644 (file)
@@ -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,
index b89e1f9624f7b4f07fc6de0c95c5cf17e5abc957..2fe138634e65b71c5888afe9beda2485cbc278c0 100644 (file)
@@ -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, 
index fd50e6aeec7cc4f8f6533d61612641c1f0dcfc10..5364b47451cfb5da4c0b10310784a60ed4b87f66 100644 (file)
@@ -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
 \f
 /* 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);
index cd1d135403542db03d15eb3f13117d9b6c50751a..d220697f30b5399ce2cb276190a71ae54c0ebda5 100644 (file)
@@ -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)   \
index f3aa41bc516d4f0ec05b02b9a8a79a436d391ab1..c87a6a08bd9c17805f80d8adbebe910e85e08228 100644 (file)
@@ -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);
index 9b8d68b8ea7c955d7611f8ec0174f5c76523f794..499dc1d694d4c134cf56f32a460d33341d6aa1cd 100644 (file)
@@ -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, "
index 5d1a138f75825df53dd1e18f256a0e333aa79224..be3d0e887e8dc51790a8e05d5cd12c18953fd036 100644 (file)
@@ -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.  */
index 999f93e1f1e3a8574392894c92d3cae8a39ae021..c6390aaec95f2e95b22724fe84abb3f1503aadbf 100644 (file)
@@ -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"
index 4e672119ce954d1f998bed5eef52265184ca16fa..0a5ae406605319fbfe324b0d13f67c78d254cae9 100644 (file)
@@ -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
 
index b21652b40b49cc2fef05a85b243d31dbca9b4c49..6e80396b80b9c6a64e15b341477697f738bdb50d 100644 (file)
@@ -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);
index a4a89d03dfead74502aa56636adad597db481a8b..3fee22836feedfb8eecf8a041683278f6a890f06 100644 (file)
@@ -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, "
index 1a7ce96202048451d1a4961cee8926fc68e89a8e..8ec192ea70012053f4a1de0283650d1c2e71f38d 100644 (file)
@@ -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.
 
index 1319f680eb13d0d1b8f27b919a27310c2b984995..f62d740ec642686dba0c963f78f8800818d906ca 100644 (file)
@@ -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
 
index b4a23c3aa8cd1b416d2a4cf072cde362dd3927e0..09325918da35477a09a70c8c97e51ff69bc87cfd 100644 (file)
@@ -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
index 469b03d2f8883464890579e82656ec061b9a568a..aa66f24f1b3d32383da0144e3fa6464dede12e0f 100644 (file)
@@ -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
index 51bc3183ed5e36a341d06a77aa834942a38fed24..a9672e3bf1ce4c6e1ee03930fb565ae03d3ebd3f 100644 (file)
@@ -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.  */
index 5e90208f5eba42900791078bf3c89be3d0903462..04038015e8cccd51d8aa315b99a444d2831d1e52 100644 (file)
@@ -2656,7 +2656,7 @@ in memory and the hard register number if it is in a register.
 
 Scratch operands in memory (constraint @code{"=m"} / @code{"=&m"}) are
 currently not supported.  For the time being, you will have to continue
-to use @code{SECONDARY_MEMORY_NEEDED} for that purpose.
+to use @code{TARGET_SECONDARY_MEMORY_NEEDED} for that purpose.
 
 @code{copy_cost} also uses this target hook to find out how values are
 copied.  If you want it to include some extra cost for the need to allocate
@@ -2726,29 +2726,28 @@ intermediate storage.  This case often occurs between floating-point and
 general registers.
 @end defmac
 
-@defmac SECONDARY_MEMORY_NEEDED (@var{class1}, @var{class2}, @var{m})
+@deftypefn {Target Hook} bool TARGET_SECONDARY_MEMORY_NEEDED (machine_mode @var{mode}, reg_class_t @var{class1}, reg_class_t @var{class2})
 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
-@var{m} in registers of @var{class1} can only be copied to registers of
-class @var{class2} by storing a register of @var{class1} into memory
-and loading that memory location into a register of @var{class2}.
-
-Do not define this macro if its value would always be zero.
-@end defmac
+to some other registers without using memory.  Define this hook on
+those machines to return true if objects of mode @var{m} in registers
+of @var{class1} can only be copied to registers of class @var{class2} by
+ storing a register of @var{class1} into memory and loading that memory
+location into a register of @var{class2}.  The default definition returns
+false for all inputs.
+@end deftypefn
 
 @defmac SECONDARY_MEMORY_NEEDED_RTX (@var{mode})
-Normally when @code{SECONDARY_MEMORY_NEEDED} is defined, the compiler
+Normally when @code{TARGET_SECONDARY_MEMORY_NEEDED} is defined, the compiler
 allocates a stack slot for a memory location needed for register copies.
 If this macro is defined, the compiler instead uses the memory location
 defined by this macro.
 
 Do not define this macro if you do not define
-@code{SECONDARY_MEMORY_NEEDED}.
+@code{TARGET_SECONDARY_MEMORY_NEEDED}.
 @end defmac
 
 @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
+If @code{TARGET_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.
 
index 1919176d866a3401347f875582701774df9026fc..f6a0d09f1887f8377296de1c27d562b3e45b0413 100644 (file)
@@ -2303,25 +2303,16 @@ intermediate storage.  This case often occurs between floating-point and
 general registers.
 @end defmac
 
-@defmac SECONDARY_MEMORY_NEEDED (@var{class1}, @var{class2}, @var{m})
-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
-@var{m} in registers of @var{class1} can only be copied to registers of
-class @var{class2} by storing a register of @var{class1} into memory
-and loading that memory location into a register of @var{class2}.
-
-Do not define this macro if its value would always be zero.
-@end defmac
+@hook TARGET_SECONDARY_MEMORY_NEEDED
 
 @defmac SECONDARY_MEMORY_NEEDED_RTX (@var{mode})
-Normally when @code{SECONDARY_MEMORY_NEEDED} is defined, the compiler
+Normally when @code{TARGET_SECONDARY_MEMORY_NEEDED} is defined, the compiler
 allocates a stack slot for a memory location needed for register copies.
 If this macro is defined, the compiler instead uses the memory location
 defined by this macro.
 
 Do not define this macro if you do not define
-@code{SECONDARY_MEMORY_NEEDED}.
+@code{TARGET_SECONDARY_MEMORY_NEEDED}.
 @end defmac
 
 @hook TARGET_SECONDARY_MEMORY_NEEDED_MODE
index 65b9fe5ce50a91f86da2f9f0bd933b1a7008cb08..44ebd6f5c857bcca75489d17f9c1829638250338 100644 (file)
@@ -495,3 +495,12 @@ hook_bool_reg_class_t_false (reg_class_t regclass ATTRIBUTE_UNUSED)
   return false;
 }
 
+/* Generic hook that takes a machine_mode and 2 register classes
+   and returns false.  */
+bool
+hook_bool_mode_reg_class_t_reg_class_t_false (machine_mode, reg_class_t,
+                                             reg_class_t)
+{
+  return false;
+}
+
index 06ffd27deb7cbf8b67f3803470e01a6b28d74e67..e5741df7f1cb862d92460355c61e7b6539108f4a 100644 (file)
@@ -59,6 +59,9 @@ extern bool hook_bool_rtx_false (rtx);
 extern bool hook_bool_rtx_insn_int_false (rtx_insn *, int);
 extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *);
 extern bool hook_bool_reg_class_t_false (reg_class_t regclass);
+extern bool hook_bool_mode_reg_class_t_reg_class_t_false (machine_mode,
+                                                         reg_class_t,
+                                                         reg_class_t);
 extern bool hook_bool_rtx_mode_int_int_intp_bool_false (rtx, machine_mode,
                                                        int, int, int *, bool);
 extern bool hook_bool_tree_tree_false (tree, tree);
index 84be6c3fdcafd9bd5a17b5b8cd74c01d40f66f8b..d90bde2817aa0b4b29e6af27a462a79424a77cb9 100644 (file)
@@ -1159,8 +1159,8 @@ emit_spill_move (bool to_p, rtx mem_pseudo, rtx val)
 
 /* Process a special case insn (register move), return true if we
    don't need to process it anymore.  INSN should be a single set
-   insn.  Set up that RTL was changed through CHANGE_P and macro
-   SECONDARY_MEMORY_NEEDED says to use secondary memory through
+   insn.  Set up that RTL was changed through CHANGE_P and that hook
+   TARGET_SECONDARY_MEMORY_NEEDED says to use secondary memory through
    SEC_MEM_P.  */
 static bool
 check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED)
@@ -1201,8 +1201,7 @@ check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED)
     return false;
   if (sclass == NO_REGS && dclass == NO_REGS)
     return false;
-#ifdef SECONDARY_MEMORY_NEEDED
-  if (SECONDARY_MEMORY_NEEDED (sclass, dclass, GET_MODE (src))
+  if (targetm.secondary_memory_needed (GET_MODE (src), sclass, dclass)
       && ((sclass != NO_REGS && dclass != NO_REGS)
          || (GET_MODE (src)
              != targetm.secondary_memory_needed_mode (GET_MODE (src)))))
@@ -1210,7 +1209,6 @@ check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED)
       *sec_mem_p = true;
       return false;
     }
-#endif
   if (! REG_P (dreg) || ! REG_P (sreg))
     return false;
   sri.prev_sri = NULL;
@@ -2739,19 +2737,18 @@ process_alt_operands (int only_alternative)
                  reject += 3;
                }
              
-#ifdef SECONDARY_MEMORY_NEEDED
              /* If reload requires moving value through secondary
                 memory, it will need one more insn at least.  */
              if (this_alternative != NO_REGS 
                  && REG_P (op) && (cl = get_reg_class (REGNO (op))) != NO_REGS
                  && ((curr_static_id->operand[nop].type != OP_OUT
-                      && SECONDARY_MEMORY_NEEDED (cl, this_alternative,
-                                                  GET_MODE (op)))
+                      && targetm.secondary_memory_needed (GET_MODE (op), cl,
+                                                          this_alternative))
                      || (curr_static_id->operand[nop].type != OP_IN
-                         && SECONDARY_MEMORY_NEEDED (this_alternative, cl,
-                                                     GET_MODE (op)))))
+                         && (targetm.secondary_memory_needed
+                             (GET_MODE (op), this_alternative, cl)))))
                losers++;
-#endif
+
              /* Input reloads can be inherited more often than output
                 reloads can be removed, so penalize output
                 reloads.  */
@@ -3716,9 +3713,7 @@ curr_insn_transform (bool check_only_p)
   /* Flag that the insn has been changed through a transformation.  */
   bool change_p;
   bool sec_mem_p;
-#ifdef SECONDARY_MEMORY_NEEDED
   bool use_sec_mem_p;
-#endif
   int max_regno_before;
   int reused_alternative_num;
 
@@ -3899,8 +3894,7 @@ curr_insn_transform (bool check_only_p)
       change_p = true;
     }
 
-#ifdef SECONDARY_MEMORY_NEEDED
-  /* Some target macros SECONDARY_MEMORY_NEEDED (e.g. x86) are defined
+  /* Some targets' TARGET_SECONDARY_MEMORY_NEEDED (e.g. x86) are defined
      too conservatively.  So we use the secondary memory only if there
      is no any alternative without reloads.  */
   use_sec_mem_p = false;
@@ -3985,7 +3979,6 @@ curr_insn_transform (bool check_only_p)
       lra_update_insn_regno_info (curr_insn);
       return true;
     }
-#endif
 
   lra_assert (goal_alt_number >= 0);
   lra_set_used_insn_alternative (curr_insn, goal_alt_number);
@@ -5084,9 +5077,6 @@ static bool
 check_secondary_memory_needed_p (enum reg_class inher_cl ATTRIBUTE_UNUSED,
                                 rtx usage_insns ATTRIBUTE_UNUSED)
 {
-#ifndef SECONDARY_MEMORY_NEEDED
-  return false;
-#else
   rtx_insn *insn;
   rtx set, dest;
   enum reg_class cl;
@@ -5103,8 +5093,7 @@ check_secondary_memory_needed_p (enum reg_class inher_cl ATTRIBUTE_UNUSED,
   lra_assert (inher_cl != NO_REGS);
   cl = get_reg_class (REGNO (dest));
   return (cl != NO_REGS && cl != ALL_REGS
-         && SECONDARY_MEMORY_NEEDED (inher_cl, cl, GET_MODE (dest)));
-#endif
+         && targetm.secondary_memory_needed (GET_MODE (dest), inher_cl, cl));
 }
 
 /* Registers involved in inheritance/split in the current EBB
@@ -5364,28 +5353,24 @@ choose_split_class (enum reg_class allocno_class,
                    int hard_regno ATTRIBUTE_UNUSED,
                    machine_mode mode ATTRIBUTE_UNUSED)
 {
-#ifndef SECONDARY_MEMORY_NEEDED
-  return allocno_class;
-#else
   int i;
   enum reg_class cl, best_cl = NO_REGS;
   enum reg_class hard_reg_class ATTRIBUTE_UNUSED
     = REGNO_REG_CLASS (hard_regno);
 
-  if (! SECONDARY_MEMORY_NEEDED (allocno_class, allocno_class, mode)
+  if (! targetm.secondary_memory_needed (mode, allocno_class, allocno_class)
       && TEST_HARD_REG_BIT (reg_class_contents[allocno_class], hard_regno))
     return allocno_class;
   for (i = 0;
        (cl = reg_class_subclasses[allocno_class][i]) != LIM_REG_CLASSES;
        i++)
-    if (! SECONDARY_MEMORY_NEEDED (cl, hard_reg_class, mode)
-       && ! SECONDARY_MEMORY_NEEDED (hard_reg_class, cl, mode)
+    if (! targetm.secondary_memory_needed (mode, cl, hard_reg_class)
+       && ! targetm.secondary_memory_needed (mode, hard_reg_class, cl)
        && TEST_HARD_REG_BIT (reg_class_contents[cl], hard_regno)
        && (best_cl == NO_REGS
            || ira_class_hard_regs_num[best_cl] < ira_class_hard_regs_num[cl]))
       best_cl = cl;
   return best_cl;
-#endif
 }
 
 /* Copy any equivalence information from ORIGINAL_REGNO to NEW_REGNO.
index d0061e5b27087a2c49dc697c4599091727f9a46c..c9b946134f3ef450697a56d4b1864240acef2ada 100644 (file)
@@ -172,8 +172,6 @@ struct decomposition
   HOST_WIDE_INT end;   /* Ending offset or register number.  */
 };
 
-#ifdef SECONDARY_MEMORY_NEEDED
-
 /* Save MEMs needed to copy from one class of registers to another.  One MEM
    is used per mode, but normally only one or two modes are ever used.
 
@@ -185,7 +183,6 @@ struct decomposition
 static rtx secondary_memlocs[NUM_MACHINE_MODES];
 static rtx secondary_memlocs_elim[NUM_MACHINE_MODES][MAX_RECOG_OPERANDS];
 static int secondary_memlocs_elim_used = 0;
-#endif
 
 /* The instruction we are doing reloads for;
    so we can test whether a register dies in it.  */
@@ -456,14 +453,13 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
 
   if (s_reload == n_reloads)
     {
-#ifdef SECONDARY_MEMORY_NEEDED
       /* If we need a memory location to copy between the two reload regs,
         set it up now.  Note that we do the input case before making
         the reload and the output case after.  This is due to the
         way reloads are output.  */
 
       if (in_p && icode == CODE_FOR_nothing
-         && SECONDARY_MEMORY_NEEDED (rclass, reload_class, mode))
+         && targetm.secondary_memory_needed (mode, rclass, reload_class))
        {
          get_secondary_mem (x, reload_mode, opnum, type);
 
@@ -471,7 +467,6 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
             the new reload at the end.  */
          s_reload = n_reloads;
        }
-#endif
 
       /* We need to make a new secondary reload for this register class.  */
       rld[s_reload].in = rld[s_reload].out = 0;
@@ -497,11 +492,9 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
 
       n_reloads++;
 
-#ifdef SECONDARY_MEMORY_NEEDED
       if (! in_p && icode == CODE_FOR_nothing
-         && SECONDARY_MEMORY_NEEDED (reload_class, rclass, mode))
+         && targetm.secondary_memory_needed (mode, reload_class, rclass))
        get_secondary_mem (x, mode, opnum, type);
-#endif
     }
 
   *picode = icode;
@@ -556,8 +549,6 @@ scratch_reload_class (enum insn_code icode)
   return rclass;
 }
 \f
-#ifdef SECONDARY_MEMORY_NEEDED
-
 /* Return a memory location that will be used to copy X in mode MODE.
    If we haven't already made a location for this mode in this insn,
    call find_reloads_address on the location being returned.  */
@@ -634,7 +625,6 @@ clear_secondary_mem (void)
 {
   memset (secondary_memlocs, 0, sizeof secondary_memlocs);
 }
-#endif /* SECONDARY_MEMORY_NEEDED */
 \f
 
 /* Find the largest class which has at least one register valid in
@@ -1353,7 +1343,6 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
       /* We found no existing reload suitable for re-use.
         So add an additional reload.  */
 
-#ifdef SECONDARY_MEMORY_NEEDED
       if (subreg_in_class == NO_REGS
          && in != 0
          && (REG_P (in)
@@ -1362,9 +1351,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
        subreg_in_class = REGNO_REG_CLASS (reg_or_subregno (in));
       /* If a memory location is needed for the copy, make one.  */
       if (subreg_in_class != NO_REGS
-         && SECONDARY_MEMORY_NEEDED (subreg_in_class, rclass, inmode))
+         && targetm.secondary_memory_needed (inmode, subreg_in_class, rclass))
        get_secondary_mem (in, inmode, opnum, type);
-#endif
 
       i = n_reloads;
       rld[i].in = in;
@@ -1388,16 +1376,13 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 
       n_reloads++;
 
-#ifdef SECONDARY_MEMORY_NEEDED
       if (out != 0
           && (REG_P (out)
              || (GET_CODE (out) == SUBREG && REG_P (SUBREG_REG (out))))
          && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
-         && SECONDARY_MEMORY_NEEDED (rclass,
-                                     REGNO_REG_CLASS (reg_or_subregno (out)),
-                                     outmode))
+         && (targetm.secondary_memory_needed
+             (outmode, rclass, REGNO_REG_CLASS (reg_or_subregno (out)))))
        get_secondary_mem (out, outmode, opnum, type);
-#endif
     }
   else
     {
@@ -1797,14 +1782,12 @@ combine_reloads (void)
                                       [(int) rld[output_reload].outmode])
        && rld[i].inc == 0
        && rld[i].reg_rtx == 0
-#ifdef SECONDARY_MEMORY_NEEDED
        /* Don't combine two reloads with different secondary
           memory locations.  */
        && (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum] == 0
            || secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] == 0
            || rtx_equal_p (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum],
                            secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
-#endif
        && (targetm.small_register_classes_for_mode_p (VOIDmode)
            ? (rld[i].rclass == rld[output_reload].rclass)
            : (reg_class_subset_p (rld[i].rclass,
@@ -1854,12 +1837,10 @@ combine_reloads (void)
              = rld[output_reload].secondary_out_icode;
          }
 
-#ifdef SECONDARY_MEMORY_NEEDED
        /* Copy any secondary MEM.  */
        if (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] != 0)
          secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum]
            = secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum];
-#endif
        /* If required, minimize the register class.  */
        if (reg_class_subset_p (rld[output_reload].rclass,
                                rld[i].rclass))
@@ -2668,7 +2649,6 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
   if (HAVE_cc0 && reg_set_p (cc0_rtx, PATTERN (insn)))
     no_output_reloads = 1;
 
-#ifdef SECONDARY_MEMORY_NEEDED
   /* The eliminated forms of any secondary memory locations are per-insn, so
      clear them out here.  */
 
@@ -2678,7 +2658,6 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
              sizeof (secondary_memlocs_elim[0]) * secondary_memlocs_elim_used);
       secondary_memlocs_elim_used = 0;
     }
-#endif
 
   /* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
      is cheap to move between them.  If it is not, there may not be an insn
index e59f6d900da69146ea59407b3cb122ccd7a732d6..1ad4b63e09e4922603acbf29506a8bccc845d93d 100644 (file)
@@ -768,10 +768,8 @@ reload (rtx_insn *first, int global)
   /* Enable find_equiv_reg to distinguish insns made by reload.  */
   reload_first_uid = get_max_uid ();
 
-#ifdef SECONDARY_MEMORY_NEEDED
   /* Initialize the secondary memory table.  */
   clear_secondary_mem ();
-#endif
 
   /* We don't have a stack slot for any spill reg yet.  */
   memset (spill_stack_slot, 0, sizeof spill_stack_slot);
@@ -6331,7 +6329,6 @@ choose_reload_regs_init (struct insn_chain *chain, rtx *save_reload_reg_rtx)
                              rld[i].when_needed, rld[i].mode);
 }
 
-#ifdef SECONDARY_MEMORY_NEEDED
 /* If X is not a subreg, return it unmodified.  If it is a subreg,
    look up whether we made a replacement for the SUBREG_REG.  Return
    either the replacement or the SUBREG_REG.  */
@@ -6343,7 +6340,6 @@ replaced_subreg (rtx x)
     return find_replacement (&SUBREG_REG (x));
   return x;
 }
-#endif
 
 /* Compute the offset to pass to subreg_regno_offset, for a pseudo of
    mode OUTERMODE that is available in a hard reg of mode INNERMODE.
@@ -6593,12 +6589,8 @@ choose_reload_regs (struct insn_chain *chain)
                              && (secondary_reload_class (1, rclass, mode,
                                                          last_reg)
                                  == NO_REGS)
-#ifdef SECONDARY_MEMORY_NEEDED
-                             && ! SECONDARY_MEMORY_NEEDED (last_class, rclass,
-                                                           mode)
-#endif
-                             ))
-
+                             && !(targetm.secondary_memory_needed
+                                  (mode, last_class, rclass))))
                      && (rld[r].nregs == max_group_size
                          || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
                                                  i))
@@ -6973,9 +6965,7 @@ choose_reload_regs (struct insn_chain *chain)
        {
          int r = reload_order[j];
          rtx check_reg;
-#ifdef SECONDARY_MEMORY_NEEDED
          rtx tem;
-#endif
          if (reload_inherited[r] && rld[r].reg_rtx)
            check_reg = rld[r].reg_rtx;
          else if (reload_override_in[r]
@@ -7014,15 +7004,15 @@ choose_reload_regs (struct insn_chain *chain)
              if (pass)
                pass = 2;
            }
-#ifdef SECONDARY_MEMORY_NEEDED
          /* If we needed a memory location for the reload, we also have to
             remove its related reloads.  */
          else if (rld[r].in
                   && rld[r].out != rld[r].in
                   && (tem = replaced_subreg (rld[r].in), REG_P (tem))             
                   && REGNO (tem) < FIRST_PSEUDO_REGISTER
-                  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (tem)),
-                                              rld[r].rclass, rld[r].inmode)
+                  && (targetm.secondary_memory_needed
+                      (rld[r].inmode, REGNO_REG_CLASS (REGNO (tem)),
+                       rld[r].rclass))
                   && remove_address_replacements
                      (get_secondary_mem (tem, rld[r].inmode, rld[r].opnum,
                                          rld[r].when_needed)))
@@ -7030,7 +7020,6 @@ choose_reload_regs (struct insn_chain *chain)
              if (pass)
                pass = 2;
            }
-#endif
        }
     }
 
@@ -8535,9 +8524,7 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
 {
   rtx_insn *last = get_last_insn ();
   rtx_insn *tem;
-#ifdef SECONDARY_MEMORY_NEEDED
   rtx tem1, tem2;
-#endif
 
   /* If IN is a paradoxical SUBREG, remove it and try to put the
      opposite SUBREG on OUT.  Likewise for a paradoxical SUBREG on OUT.  */
@@ -8673,15 +8660,14 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
       set_dst_reg_note (insn, REG_EQUIV, in, out);
     }
 
-#ifdef SECONDARY_MEMORY_NEEDED
   /* If we need a memory location to do the move, do it that way.  */
   else if ((tem1 = replaced_subreg (in), tem2 = replaced_subreg (out),
            (REG_P (tem1) && REG_P (tem2)))
           && REGNO (tem1) < FIRST_PSEUDO_REGISTER
           && REGNO (tem2) < FIRST_PSEUDO_REGISTER
-          && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (tem1)),
-                                      REGNO_REG_CLASS (REGNO (tem2)),
-                                      GET_MODE (out)))
+          && targetm.secondary_memory_needed (GET_MODE (out),
+                                              REGNO_REG_CLASS (REGNO (tem1)),
+                                              REGNO_REG_CLASS (REGNO (tem2))))
     {
       /* Get the memory to use and rewrite both registers to its mode.  */
       rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
@@ -8695,7 +8681,6 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
       gen_reload (loc, in, opnum, type);
       gen_reload (out, loc, opnum, type);
     }
-#endif
   else if (REG_P (out) && UNARY_P (in))
     {
       rtx op1;
index 7543339978e1f4872c1f6770da885b312cc23f3f..95a7195f5c83b6ebf50db7bcc1bf651b5664795c 100644 (file)
@@ -913,7 +913,8 @@ 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 SECONDARY_MEMORY_NEEDED_MODE
+       HARD_REGNO_NREGS SECONDARY_MEMORY_NEEDED_MODE                   \
+       SECONDARY_MEMORY_NEEDED
 
 /* Target macros only used for code built for the target, that have
    moved to libgcc-tm.h or have never been present elsewhere.  */
index 7abb74e79c0352c885da3d1aefe2eb416d28097d..350d98425d8ba3e320bbed021f4a857705675354 100644 (file)
@@ -5252,7 +5252,7 @@ in memory and the hard register number if it is in a register.\n\
 \n\
 Scratch operands in memory (constraint @code{\"=m\"} / @code{\"=&m\"}) are\n\
 currently not supported.  For the time being, you will have to continue\n\
-to use @code{SECONDARY_MEMORY_NEEDED} for that purpose.\n\
+to use @code{TARGET_SECONDARY_MEMORY_NEEDED} for that purpose.\n\
 \n\
 @code{copy_cost} also uses this target hook to find out how values are\n\
 copied.  If you want it to include some extra cost for the need to allocate\n\
@@ -5265,9 +5265,21 @@ forwarding logic, you can set @code{sri->extra_cost} to a negative amount.",
   secondary_reload_info *sri),
  default_secondary_reload)
 
+DEFHOOK
+(secondary_memory_needed,
+ "Certain machines have the property that some registers cannot be copied\n\
+to some other registers without using memory.  Define this hook on\n\
+those machines to return true if objects of mode @var{m} in registers\n\
+of @var{class1} can only be copied to registers of class @var{class2} by\n\
+ storing a register of @var{class1} into memory and loading that memory\n\
+location into a register of @var{class2}.  The default definition returns\n\
+false for all inputs.",
+ bool, (machine_mode mode, reg_class_t class1, reg_class_t class2),
+ hook_bool_mode_reg_class_t_reg_class_t_false)
+
 DEFHOOK
 (secondary_memory_needed_mode,
- "If @code{SECONDARY_MEMORY_NEEDED} tells the compiler to use memory\n\
+ "If @code{TARGET_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\