Turn HARD_REGNO_CALL_PART_CLOBBERED into a target hook
authorRichard Sandiford <richard.sandiford@linaro.org>
Mon, 4 Sep 2017 10:49:21 +0000 (10:49 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 4 Sep 2017 10:49:21 +0000 (10:49 +0000)
The SVE patches change the size of a machine_mode from a compile-time
constant to a runtime invariant.  However, target-specific code can
continue to treat the modes as constant-sized if the target only has
constant-sized modes.

The main snag with this approach is that target-independent code still
uses macros from the target .h file.  This patch is one of several that
converts a target macro to a hook.

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

gcc/
* target.def (hard_regno_call_part_clobbered): New hook.
* doc/tm.texi.in (HARD_REGNO_CALL_PART_CLOBBERED): Replace with...
(TARGET_HARD_REGNO_CALL_PART_CLOBBERED): ...this hook.
* doc/tm.texi: Regenerate.
* hooks.h (hook_bool_uint_mode_false): Declare.
* hooks.c (hook_bool_uint_mode_false): New function.
* regs.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
* cselib.c (cselib_process_insn): Use
targetm.hard_regno_call_part_clobbered instead of
HARD_REGNO_CALL_PART_CLOBBERED.
* ira-conflicts.c (ira_build_conflicts): Likewise.
* ira-costs.c (ira_tune_allocno_costs): Likewise.
* lra-constraints.c (need_for_call_save_p): Likewise.
* lra-lives.c: Include target.h.
(check_pseudos_live_through_calls): Use
targetm.hard_regno_call_part_clobbered instead of
HARD_REGNO_CALL_PART_CLOBBERED.
* regcprop.c: Include target.h.
(copyprop_hardreg_forward_1): Use
targetm.hard_regno_call_part_clobbered instead of
HARD_REGNO_CALL_PART_CLOBBERED.
* reginfo.c (choose_hard_reg_mode): Likewise.
* regrename.c (check_new_reg_p): Likewise.
* reload.c (find_equiv_reg): Likewise.
* reload1.c (emit_reload_insns): Likewise.
* sched-deps.c (deps_analyze_insn): Likewise.
* sel-sched.c (init_regs_for_mode): Likewise.
(mark_unavailable_hard_regs): Likewise.
* targhooks.c (default_dwarf_frame_reg_mode): Likewise.
* config/aarch64/aarch64.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
* config/aarch64/aarch64.c (aarch64_hard_regno_call_part_clobbered):
New function.
(TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
* config/avr/avr.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
* config/avr/avr-protos.h (avr_hard_regno_call_part_clobbered):
Delete.
* config/avr/avr.c (avr_hard_regno_call_part_clobbered): Make static
and return a bool.
(TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
* config/i386/i386.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
* config/i386/i386.c (ix86_hard_regno_call_part_clobbered): New
function.
(TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
* config/mips/mips.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
* config/mips/mips.c (mips_hard_regno_call_part_clobbered): New
function.
(TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
* config/powerpcspe/powerpcspe.h (HARD_REGNO_CALL_PART_CLOBBERED):
Delete.
* config/powerpcspe/powerpcspe.c
(rs6000_hard_regno_call_part_clobbered): New function.
(TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
* config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
* config/rs6000/rs6000.c (rs6000_hard_regno_call_part_clobbered):
New function.
(TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
* config/s390/s390.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
* config/s390/s390.c (s390_hard_regno_call_part_clobbered): New
function.
(TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
* config/sh/sh.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
* system.h (HARD_REGNO_CALL_PART_CLOBBERED): Poison.

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

37 files changed:
gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.h
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/powerpcspe/powerpcspe.c
gcc/config/powerpcspe/powerpcspe.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/sh/sh.h
gcc/cselib.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/hooks.c
gcc/hooks.h
gcc/ira-conflicts.c
gcc/ira-costs.c
gcc/lra-constraints.c
gcc/lra-lives.c
gcc/regcprop.c
gcc/reginfo.c
gcc/regrename.c
gcc/regs.h
gcc/reload.c
gcc/reload1.c
gcc/sched-deps.c
gcc/sel-sched.c
gcc/system.h
gcc/target.def
gcc/targhooks.c

index 5d468c9493d98f260b3e1e7dcfb5301c67f6a21c..1c5100173ee5137f5e3f23d88797445da72880a9 100644 (file)
@@ -1,3 +1,70 @@
+2017-09-04  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * target.def (hard_regno_call_part_clobbered): New hook.
+       * doc/tm.texi.in (HARD_REGNO_CALL_PART_CLOBBERED): Replace with...
+       (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): ...this hook.
+       * doc/tm.texi: Regenerate.
+       * hooks.h (hook_bool_uint_mode_false): Declare.
+       * hooks.c (hook_bool_uint_mode_false): New function.
+       * regs.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
+       * cselib.c (cselib_process_insn): Use
+       targetm.hard_regno_call_part_clobbered instead of
+       HARD_REGNO_CALL_PART_CLOBBERED.
+       * ira-conflicts.c (ira_build_conflicts): Likewise.
+       * ira-costs.c (ira_tune_allocno_costs): Likewise.
+       * lra-constraints.c (need_for_call_save_p): Likewise.
+       * lra-lives.c: Include target.h.
+       (check_pseudos_live_through_calls): Use
+       targetm.hard_regno_call_part_clobbered instead of
+       HARD_REGNO_CALL_PART_CLOBBERED.
+       * regcprop.c: Include target.h.
+       (copyprop_hardreg_forward_1): Use
+       targetm.hard_regno_call_part_clobbered instead of
+       HARD_REGNO_CALL_PART_CLOBBERED.
+       * reginfo.c (choose_hard_reg_mode): Likewise.
+       * regrename.c (check_new_reg_p): Likewise.
+       * reload.c (find_equiv_reg): Likewise.
+       * reload1.c (emit_reload_insns): Likewise.
+       * sched-deps.c (deps_analyze_insn): Likewise.
+       * sel-sched.c (init_regs_for_mode): Likewise.
+       (mark_unavailable_hard_regs): Likewise.
+       * targhooks.c (default_dwarf_frame_reg_mode): Likewise.
+       * config/aarch64/aarch64.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
+       * config/aarch64/aarch64.c (aarch64_hard_regno_call_part_clobbered):
+       New function.
+       (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
+       * config/avr/avr.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
+       * config/avr/avr-protos.h (avr_hard_regno_call_part_clobbered):
+       Delete.
+       * config/avr/avr.c (avr_hard_regno_call_part_clobbered): Make static
+       and return a bool.
+       (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
+       * config/i386/i386.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
+       * config/i386/i386.c (ix86_hard_regno_call_part_clobbered): New
+       function.
+       (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
+       * config/mips/mips.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
+       * config/mips/mips.c (mips_hard_regno_call_part_clobbered): New
+       function.
+       (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
+       * config/powerpcspe/powerpcspe.h (HARD_REGNO_CALL_PART_CLOBBERED):
+       Delete.
+       * config/powerpcspe/powerpcspe.c
+       (rs6000_hard_regno_call_part_clobbered): New function.
+       (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
+       * config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
+       * config/rs6000/rs6000.c (rs6000_hard_regno_call_part_clobbered):
+       New function.
+       (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
+       * config/s390/s390.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
+       * config/s390/s390.c (s390_hard_regno_call_part_clobbered): New
+       function.
+       (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine.
+       * config/sh/sh.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete.
+       * system.h (HARD_REGNO_CALL_PART_CLOBBERED): Poison.
+
 2017-09-04  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index fe5b59c3a707f947d3fbd9ee8de2ed8da54a03b4..ba48b28d1d54af52a0921e9f180af863b11e24ca 100644 (file)
@@ -1115,6 +1115,16 @@ aarch64_hard_regno_mode_ok (unsigned regno, machine_mode mode)
   return 0;
 }
 
+/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  The callee only saves
+   the lower 64 bits of a 128-bit register.  Tell the compiler the callee
+   clobbers the top 64 bits when restoring the bottom 64 bits.  */
+
+static bool
+aarch64_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode)
+{
+  return FP_REGNUM_P (regno) && GET_MODE_SIZE (mode) > 8;
+}
+
 /* Implement HARD_REGNO_CALLER_SAVE_MODE.  */
 machine_mode
 aarch64_hard_regno_caller_save_mode (unsigned regno, unsigned nregs,
@@ -15659,6 +15669,10 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4
 
+#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
+#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
+  aarch64_hard_regno_call_part_clobbered
+
 #if CHECKING_P
 #undef TARGET_RUN_TARGET_SELFTESTS
 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
index a6e0479cd09e550560c4fd2298645951a1983851..fd5d53d51b28ef2d23f8dc05a6ed04d8c56d68cd 100644 (file)
@@ -888,12 +888,6 @@ typedef struct
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
   aarch64_hard_regno_caller_save_mode ((REGNO), (NREGS), (MODE))
 
-/* Callee only saves lower 64-bits of a 128-bit register.  Tell the
-   compiler the callee clobbers the top 64-bits when restoring the
-   bottom 64-bits.  */
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
-               (FP_REGNUM_P (REGNO) && GET_MODE_SIZE (MODE) > 8)
-
 #undef SWITCHABLE_TARGET
 #define SWITCHABLE_TARGET 1
 
index 5d5524b2e6534d4fc5d8294c41f16bc002c22b20..f9116e6bf30e688b67a7e91a6cd0542101769279 100644 (file)
@@ -46,7 +46,6 @@ extern void avr_init_cumulative_args (CUMULATIVE_ARGS*, tree, rtx, tree);
 #endif /* TREE_CODE */
 
 #ifdef RTX_CODE
-extern int avr_hard_regno_call_part_clobbered (unsigned, machine_mode);
 extern const char *output_movqi (rtx_insn *insn, rtx operands[], int *l);
 extern const char *output_movhi (rtx_insn *insn, rtx operands[], int *l);
 extern const char *output_movsisf (rtx_insn *insn, rtx operands[], int *l);
index 09bf5eedbde88dc53e2b5cae2a53bc95687e298d..df4cbf343b4d609258bf0d16dcefd015638faced 100644 (file)
@@ -12186,9 +12186,9 @@ avr_hard_regno_mode_ok (int regno, machine_mode mode)
 }
 
 
-/* Implement `HARD_REGNO_CALL_PART_CLOBBERED'.  */
+/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  */
 
-int
+static bool
 avr_hard_regno_call_part_clobbered (unsigned regno, machine_mode mode)
 {
   /* FIXME: This hook gets called with MODE:REGNO combinations that don't
@@ -14693,6 +14693,10 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
 
 #undef  TARGET_HARD_REGNO_SCRATCH_OK
 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
+#undef  TARGET_HARD_REGNO_CALL_PART_CLOBBERED
+#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
+  avr_hard_regno_call_part_clobbered
+
 #undef  TARGET_CASE_VALUES_THRESHOLD
 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
 
index 579c8faa0b53123e41cafef4cf9d0f7078cbc771..212ca695ad50efcd891cbb5c8045935f0d38862b 100644 (file)
@@ -285,9 +285,6 @@ enum reg_class {
 
 #define REGNO_OK_FOR_INDEX_P(NUM) 0
 
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)     \
-  avr_hard_regno_call_part_clobbered (REGNO, MODE)
-
 #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 #define STACK_PUSH_CODE POST_DEC
index 68cb32bc9cf48ef63afecd1c9022e5ce322bb698..6c1057fba598900680a5257453540c2e6d53592b 100644 (file)
@@ -41407,6 +41407,17 @@ ix86_hard_regno_mode_ok (int regno, machine_mode mode)
   return false;
 }
 
+/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  The only ABI that
+   saves SSE registers across calls is Win64 (thus no need to check the
+   current ABI here), and with AVX enabled Win64 only guarantees that
+   the low 16 bytes are saved.  */
+
+static bool
+ix86_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode)
+{
+  return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
+}
+
 /* A subroutine of ix86_modes_tieable_p.  Return true if MODE is a
    tieable integer mode.  */
 
@@ -53250,6 +53261,10 @@ ix86_run_selftests (void)
 #undef TARGET_NOCE_CONVERSION_PROFITABLE_P
 #define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p
 
+#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
+#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
+  ix86_hard_regno_call_part_clobbered
+
 #if CHECKING_P
 #undef TARGET_RUN_TARGET_SELFTESTS
 #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
index dad6499ca1d1442c91548fea712507eecb16a755..05dabf273e228569e01b9041a25aa098b8c6eb5d 100644 (file)
@@ -1214,12 +1214,6 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
                           || MASK_REGNO_P (REGNO)) ? SImode            \
    : (MODE))
 
-/* The only ABI that saves SSE registers across calls is Win64 (thus no
-   need to check the current ABI here), and with AVX enabled Win64 only
-   guarantees that the low 16 bytes are saved.  */
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)             \
-  (SSE_REGNO_P (REGNO) && GET_MODE_SIZE (MODE) > 16)
-
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
 
index c80686e31bf4e4c8291636d04e0fabe7cc835052..0ee6a31a8ca108cfa0fc518f142fbc14b1feb6cc 100644 (file)
@@ -12857,6 +12857,26 @@ mips_hard_regno_scratch_ok (unsigned int regno)
   return true;
 }
 
+/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  Odd-numbered
+   single-precision registers are not considered callee-saved for o32
+   FPXX as they will be clobbered when run on an FR=1 FPU.  MSA vector
+   registers with MODE > 64 bits are part clobbered too.  */
+
+static bool
+mips_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode)
+{
+  if (TARGET_FLOATXX
+      && hard_regno_nregs[regno][mode] == 1
+      && FP_REG_P (regno)
+      && (regno & 1) != 0)
+    return true;
+
+  if (ISA_HAS_MSA && FP_REG_P (regno) && GET_MODE_SIZE (mode) > 8)
+    return true;
+
+  return false;
+}
+
 /* Implement HARD_REGNO_NREGS.  */
 
 unsigned int
@@ -22558,6 +22578,10 @@ mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
 #undef TARGET_HARD_REGNO_SCRATCH_OK
 #define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok
 
+#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
+#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
+  mips_hard_regno_call_part_clobbered
+
 /* The architecture reserves bit 0 for MIPS16 so use bit 1 for descriptors.  */
 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2
index 3016ce0bb8e4710d4f770a3fd50f664118a46f26..4358b92f637d81b04896a691636ee0b44e8c389e 100644 (file)
@@ -1971,14 +1971,6 @@ FP_ASM_SPEC "\
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
   mips_hard_regno_caller_save_mode (REGNO, NREGS, MODE)
 
-/* Odd-numbered single-precision registers are not considered callee-saved
-   for o32 FPXX as they will be clobbered when run on an FR=1 FPU.
-   MSA vector registers with MODE > 64 bits are part clobbered too.  */
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)                    \
-  ((TARGET_FLOATXX && hard_regno_nregs[REGNO][MODE] == 1               \
-   && FP_REG_P (REGNO) && ((REGNO) & 1))                               \
-   || (ISA_HAS_MSA && FP_REG_P (REGNO) && GET_MODE_SIZE (MODE) > 8))
-
 #define MODES_TIEABLE_P mips_modes_tieable_p
 
 /* Register to use for pushing function arguments.  */
index 0df373dbe0f9b806aded535c4b2c3766eb73768c..4c37be79a50978704e2082fc0429d360b9c363e5 100644 (file)
@@ -1971,6 +1971,10 @@ static const struct attribute_spec rs6000_attribute_table[] =
 
 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
+
+#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
+#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
+  rs6000_hard_regno_call_part_clobbered
 \f
 
 /* Processor table.  */
@@ -2156,6 +2160,26 @@ rs6000_hard_regno_mode_ok (int regno, machine_mode mode)
   return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
 }
 
+/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  */
+
+static bool
+rs6000_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode)
+{
+  if (TARGET_32BIT
+      && TARGET_POWERPC64
+      && GET_MODE_SIZE (mode) > 4
+      && INT_REGNO_P (regno))
+    return true;
+
+  if (TARGET_VSX
+      && FP_REGNO_P (regno)
+      && GET_MODE_SIZE (mode) > 8
+      && !FLOAT128_2REG_P (mode))
+    return true;
+
+  return false;
+}
+
 /* Print interesting facts about registers.  */
 static void
 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
index f805f9b32ef39677d7267a5e37727f07720c76db..4e4078f3377497b25dae39b063fb66e03362c68a 100644 (file)
@@ -1302,13 +1302,6 @@ enum data_align { align_abi, align_opt, align_both };
    ? DImode                                                            \
    : choose_hard_reg_mode ((REGNO), (NREGS), false))
 
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)                    \
-  (((TARGET_32BIT && TARGET_POWERPC64                                  \
-     && (GET_MODE_SIZE (MODE) > 4)                                     \
-     && INT_REGNO_P (REGNO)) ? 1 : 0)                                  \
-   || (TARGET_VSX && FP_REGNO_P (REGNO)                                        \
-       && GET_MODE_SIZE (MODE) > 8 && !FLOAT128_2REG_P (MODE)))
-
 #define VSX_VECTOR_MODE(MODE)          \
         ((MODE) == V4SFmode            \
          || (MODE) == V2DFmode)        \
index a787a29f9f870919d96b1496d270143b8fcbc358..9c6beb1839a9b8caa481efaa63d4152078159307 100644 (file)
@@ -1962,6 +1962,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #undef TARGET_OPTION_FUNCTION_VERSIONS
 #define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions
 
+#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
+#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
+  rs6000_hard_regno_call_part_clobbered
 \f
 
 /* Processor table.  */
@@ -2124,6 +2127,26 @@ rs6000_hard_regno_mode_ok (int regno, machine_mode mode)
   return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
 }
 
+/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  */
+
+static bool
+rs6000_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode)
+{
+  if (TARGET_32BIT
+      && TARGET_POWERPC64
+      && GET_MODE_SIZE (mode) > 4
+      && INT_REGNO_P (regno))
+    return true;
+
+  if (TARGET_VSX
+      && FP_REGNO_P (regno)
+      && GET_MODE_SIZE (mode) > 8
+      && !FLOAT128_2REG_P (mode))
+    return true;
+
+  return false;
+}
+
 /* Print interesting facts about registers.  */
 static void
 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
index d668c9b8f509d62eed1a7e3357658b1f2d88ecfb..9114b35e46f66b31afbf9d06392c479aed130416 100644 (file)
@@ -1236,13 +1236,6 @@ enum data_align { align_abi, align_opt, align_both };
    ? DImode                                                            \
    : choose_hard_reg_mode ((REGNO), (NREGS), false))
 
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)                    \
-  (((TARGET_32BIT && TARGET_POWERPC64                                  \
-     && (GET_MODE_SIZE (MODE) > 4)                                     \
-     && INT_REGNO_P (REGNO)) ? 1 : 0)                                  \
-   || (TARGET_VSX && FP_REGNO_P (REGNO)                                        \
-       && GET_MODE_SIZE (MODE) > 8 && !FLOAT128_2REG_P (MODE)))
-
 #define VSX_VECTOR_MODE(MODE)          \
         ((MODE) == V4SFmode            \
          || (MODE) == V2DFmode)        \
index 8b6991adef9fa24a8babe66024e5e3ff35a8ebf5..86b77138d0a3252c72a4f593e2fc2a521d432a99 100644 (file)
@@ -10491,6 +10491,29 @@ s390_hard_regno_scratch_ok (unsigned int regno)
   return true;
 }
 
+/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  When generating
+   code that runs in z/Architecture mode, but conforms to the 31-bit
+   ABI, GPRs can hold 8 bytes; the ABI guarantees only that the lower 4
+   bytes are saved across calls, however.  */
+
+static bool
+s390_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode)
+{
+  if (!TARGET_64BIT
+      && TARGET_ZARCH
+      && GET_MODE_SIZE (mode) > 4
+      && ((regno >= 6 && regno <= 15) || regno == 32))
+    return true;
+
+  if (TARGET_VX
+      && GET_MODE_SIZE (mode) > 8
+      && (((TARGET_64BIT && regno >= 24 && regno <= 31))
+         || (!TARGET_64BIT && (regno == 18 || regno == 19))))
+    return true;
+
+  return false;
+}
+
 /* Maximum number of registers to represent a value of mode MODE
    in a register of class RCLASS.  */
 
@@ -15938,6 +15961,10 @@ s390_asan_shadow_offset (void)
 #undef TARGET_HARD_REGNO_SCRATCH_OK
 #define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok
 
+#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
+#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
+  s390_hard_regno_call_part_clobbered
+
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE s390_attribute_table
 
index 917aa2930734f71ba7e04661021a56b4feb78a74..bdeba1e867647813ded9842b6537b838e38e2414 100644 (file)
@@ -509,19 +509,6 @@ extern const char *s390_host_detect_local_cpu (int argc, const char **argv);
    (((MODE1) == SFmode || (MODE1) == DFmode)   \
    == ((MODE2) == SFmode || (MODE2) == DFmode))
 
-/* When generating code that runs in z/Architecture mode,
-   but conforms to the 31-bit ABI, GPRs can hold 8 bytes;
-   the ABI guarantees only that the lower 4 bytes are
-   saved across calls, however.  */
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)                    \
-  ((!TARGET_64BIT && TARGET_ZARCH                                      \
-    && GET_MODE_SIZE (MODE) > 4                                                \
-    && (((REGNO) >= 6 && (REGNO) <= 15) || (REGNO) == 32))             \
-   || (TARGET_VX                                                       \
-       && GET_MODE_SIZE (MODE) > 8                                     \
-       && (((TARGET_64BIT && (REGNO) >= 24 && (REGNO) <= 31))          \
-          || (!TARGET_64BIT && ((REGNO) == 18 || (REGNO) == 19)))))
-
 /* Maximum number of registers to represent a value of mode MODE
    in a register of class CLASS.  */
 #define CLASS_MAX_NREGS(CLASS, MODE)                                           \
index da0c354e1d308098999de8d0cbd695a13165460f..195f50419783aeab7fb9bd46e36135241e07a930 100644 (file)
@@ -812,8 +812,6 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
   1,      1,      0,      0,                                           \
 }
 
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO,MODE) (false)
-
 /* Return number of consecutive hard regs needed starting at reg REGNO
    to hold something of mode MODE.
    This is ordinarily the length in words of a value of mode MODE
index d20e4bb662b43deb07cc39021e9438dcc4852221..c11c9ee20ff5c6727306b843052b7477f81e6cfd 100644 (file)
@@ -2662,8 +2662,8 @@ cselib_process_insn (rtx_insn *insn)
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (call_used_regs[i]
            || (REG_VALUES (i) && REG_VALUES (i)->elt
-               && HARD_REGNO_CALL_PART_CLOBBERED (i,
-                     GET_MODE (REG_VALUES (i)->elt->val_rtx))))
+               && (targetm.hard_regno_call_part_clobbered
+                   (i, GET_MODE (REG_VALUES (i)->elt->val_rtx)))))
          cselib_invalidate_regno (i, reg_raw_mode[i]);
 
       /* Since it is not clear how cselib is going to be used, be
index ae51e75a5ea96ca843332bbae893a74faeddfec6..0c77b533adbe1571e9e8936e00bc7be4bf7df4c1 100644 (file)
@@ -1869,16 +1869,19 @@ This macro is optional.  If not specified, it defaults to the value
 of @code{CALL_USED_REGISTERS}.
 @end defmac
 
-@defmac HARD_REGNO_CALL_PART_CLOBBERED (@var{regno}, @var{mode})
 @cindex call-used register
 @cindex call-clobbered register
 @cindex call-saved register
-A C expression that is nonzero if it is not permissible to store a
-value of mode @var{mode} in hard register number @var{regno} across a
-call without some part of it being clobbered.  For most machines this
-macro need not be defined.  It is only required for machines that do not
-preserve the entire contents of a register across a call.
-@end defmac
+@deftypefn {Target Hook} bool TARGET_HARD_REGNO_CALL_PART_CLOBBERED (unsigned int @var{regno}, machine_mode @var{mode})
+This hook should return true if @var{regno} is partly call-saved and
+partly call-clobbered, and if a value of mode @var{mode} would be partly
+clobbered by a call.  For example, if the low 32 bits of @var{regno} are
+preserved across a call but higher bits are clobbered, this hook should
+return true for a 64-bit mode but false for a 32-bit mode.
+
+The default implementation returns false, which is correct
+for targets that don't have partly call-clobbered registers.
+@end deftypefn
 
 @findex fixed_regs
 @findex call_used_regs
index 6df08a2c477a7e186edbe54163896a53d6b42b78..3fec545d8f9551e87ef9787a4e44bf958b1fb477 100644 (file)
@@ -1698,16 +1698,10 @@ This macro is optional.  If not specified, it defaults to the value
 of @code{CALL_USED_REGISTERS}.
 @end defmac
 
-@defmac HARD_REGNO_CALL_PART_CLOBBERED (@var{regno}, @var{mode})
 @cindex call-used register
 @cindex call-clobbered register
 @cindex call-saved register
-A C expression that is nonzero if it is not permissible to store a
-value of mode @var{mode} in hard register number @var{regno} across a
-call without some part of it being clobbered.  For most machines this
-macro need not be defined.  It is only required for machines that do not
-preserve the entire contents of a register across a call.
-@end defmac
+@hook TARGET_HARD_REGNO_CALL_PART_CLOBBERED
 
 @findex fixed_regs
 @findex call_used_regs
index f4591dc585c978a08b70bae080d85b909108fa95..be23dec6217eb2bcb88ae214c8d7c31d4c45172f 100644 (file)
@@ -126,6 +126,13 @@ hook_bool_mode_uhwi_false (machine_mode, unsigned HOST_WIDE_INT)
   return false;
 }
 
+/* Generic hook that takes (unsigned int, machine_mode) and returns false.  */
+bool
+hook_bool_uint_mode_false (unsigned int, machine_mode)
+{
+  return false;
+}
+
 /* Generic hook that takes (FILE *, const char *) and does nothing.  */
 void
 hook_void_FILEptr_constcharptr (FILE *, const char *)
index 95f78109e305f9303bb21336507edf00bd1f5f85..b8f17f62d0021efac3e4048a31aeaa61f8c86615 100644 (file)
@@ -38,6 +38,7 @@ extern bool hook_bool_const_rtx_insn_const_rtx_insn_true (const rtx_insn *,
                                                          const rtx_insn *);
 extern bool hook_bool_mode_uhwi_false (machine_mode,
                                       unsigned HOST_WIDE_INT);
+extern bool hook_bool_uint_mode_false (unsigned int, machine_mode);
 extern bool hook_bool_tree_false (tree);
 extern bool hook_bool_const_tree_false (const_tree);
 extern bool hook_bool_tree_true (tree);
index e3d479383d631aead71e674f3779396735468d45..50069c1d10574fc6257c0b0b4198c26bf7b76f57 100644 (file)
@@ -743,6 +743,7 @@ ira_build_conflicts (void)
       for (i = 0; i < n; i++)
        {
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
+         machine_mode obj_mode = obj->allocno->mode;
          rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];
 
          if ((! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
@@ -804,8 +805,8 @@ ira_build_conflicts (void)
                 regs must conflict with them.  */
              for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
                if (!TEST_HARD_REG_BIT (call_used_reg_set, regno)
-                   && HARD_REGNO_CALL_PART_CLOBBERED (regno,
-                                                      obj->allocno->mode))
+                   && targetm.hard_regno_call_part_clobbered (regno,
+                                                              obj_mode))
                  {
                    SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
                    SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
index 1690e889471fe2186c36e94365e20619324a53b4..187802f35fa178fb0a0271cf6773c4d1cd716d53 100644 (file)
@@ -2336,7 +2336,8 @@ ira_tune_allocno_costs (void)
                                                   *crossed_calls_clobber_regs)
                  && (ira_hard_reg_set_intersection_p (regno, mode,
                                                       call_used_reg_set)
-                     || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
+                     || targetm.hard_regno_call_part_clobbered (regno,
+                                                                mode)))
                cost += (ALLOCNO_CALL_FREQ (a)
                         * (ira_memory_move_cost[mode][rclass][0]
                            + ira_memory_move_cost[mode][rclass][1]));
index 6da910e33a8720c023f6827b0f1ba6f7f30e8f24..221642ed3a6d1c29fa8bde8ec577eacc0c4b1e7e 100644 (file)
@@ -5295,8 +5295,8 @@ need_for_call_save_p (int regno)
               ? lra_reg_info[regno].actual_call_used_reg_set
               : call_used_reg_set,
               PSEUDO_REGNO_MODE (regno), reg_renumber[regno])
-             || HARD_REGNO_CALL_PART_CLOBBERED (reg_renumber[regno],
-                                                PSEUDO_REGNO_MODE (regno))));
+             || (targetm.hard_regno_call_part_clobbered
+                 (reg_renumber[regno], PSEUDO_REGNO_MODE (regno)))));
 }
 
 /* Global registers occurring in the current EBB.  */
index 8650dc7fca7520656579053b164a6f00b9eeaeea..f29dd049bad0e7d55c7382fe62d7f59020a5e379 100644 (file)
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.        If not see
 #include "cfganal.h"
 #include "sparseset.h"
 #include "lra-int.h"
+#include "target.h"
 
 /* Program points are enumerated by numbers from range
    0..LRA_LIVE_MAX_POINT-1.  There are approximately two times more
@@ -575,7 +576,8 @@ check_pseudos_live_through_calls (int regno,
                    last_call_used_reg_set);
 
   for (hr = 0; hr < FIRST_PSEUDO_REGISTER; hr++)
-    if (HARD_REGNO_CALL_PART_CLOBBERED (hr, PSEUDO_REGNO_MODE (regno)))
+    if (targetm.hard_regno_call_part_clobbered (hr,
+                                               PSEUDO_REGNO_MODE (regno)))
       SET_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, hr);
   lra_reg_info[regno].call_p = true;
   if (! sparseset_bit_p (pseudos_live_through_setjumps, regno))
index 0d4ec172aee22d53e166c41fdabca6e063c6bcb4..40307b01fb2da6c60ca2fda9bb32771289e29724 100644 (file)
@@ -34,6 +34,7 @@
 #include "tree-pass.h"
 #include "rtl-iter.h"
 #include "cfgrtl.h"
+#include "target.h"
 
 /* The following code does forward propagation of hard register copies.
    The object is to eliminate as many dependencies as possible, so that
@@ -1055,7 +1056,8 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
                                  regs_invalidated_by_call);
          for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
            if ((TEST_HARD_REG_BIT (regs_invalidated_by_this_call, regno)
-                || HARD_REGNO_CALL_PART_CLOBBERED (regno, vd->e[regno].mode))
+                || (targetm.hard_regno_call_part_clobbered
+                    (regno, vd->e[regno].mode)))
                && (regno < set_regno || regno >= set_regno + set_nregs))
              kill_value_regno (regno, 1, vd);
 
index 9f07176d9b7a51e1cd4ea2d251d4c1f7033a4a06..970cbb61e0df2173f719d16ccaa807a3076557ce 100644 (file)
@@ -635,28 +635,32 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
   FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
        && HARD_REGNO_MODE_OK (regno, mode)
-       && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+       && (!call_saved
+           || !targetm.hard_regno_call_part_clobbered (regno, mode))
        && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
        && HARD_REGNO_MODE_OK (regno, mode)
-       && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+       && (!call_saved
+           || !targetm.hard_regno_call_part_clobbered (regno, mode))
        && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT)
     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
        && HARD_REGNO_MODE_OK (regno, mode)
-       && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+       && (!call_saved
+           || !targetm.hard_regno_call_part_clobbered (regno, mode))
        && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
        && HARD_REGNO_MODE_OK (regno, mode)
-       && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+       && (!call_saved
+           || !targetm.hard_regno_call_part_clobbered (regno, mode))
        && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
       found_mode = mode;
 
@@ -669,7 +673,8 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
       mode = (machine_mode) m;
       if ((unsigned) hard_regno_nregs[regno][mode] == nregs
          && HARD_REGNO_MODE_OK (regno, mode)
-         && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
+         && (!call_saved
+             || !targetm.hard_regno_call_part_clobbered (regno, mode)))
        return mode;
     }
 
index 58036644fc6acd5d16e4b78e1d30ac64c69ec908..ff5f3e2efe903254266953e3310da9a4857c6808 100644 (file)
@@ -338,9 +338,9 @@ check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
     if ((! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc))
         && ! DEBUG_INSN_P (tmp->insn))
        || (this_head->need_caller_save_reg
-           && ! (HARD_REGNO_CALL_PART_CLOBBERED
+           && ! (targetm.hard_regno_call_part_clobbered
                  (reg, GET_MODE (*tmp->loc)))
-           && (HARD_REGNO_CALL_PART_CLOBBERED
+           && (targetm.hard_regno_call_part_clobbered
                (new_reg, GET_MODE (*tmp->loc)))))
       return false;
 
index bdaa9ba0639d953c8abc9e65d942cfc719b5df0e..1a3ccce6e55c491751f6767042a118a3b8fe1a87 100644 (file)
@@ -193,12 +193,6 @@ extern int caller_save_needed;
   choose_hard_reg_mode (REGNO, NREGS, false)
 #endif
 
-/* Registers that get partially clobbered by a call in a given mode.
-   These must not be call used registers.  */
-#ifndef HARD_REGNO_CALL_PART_CLOBBERED
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) 0
-#endif
-
 /* Target-dependent globals.  */
 struct target_regs {
   /* For each starting hard register, the number of consecutive hard
index e0793cff8b9dd6d75a95076cf7ae8dcf283611bd..ee4798d07081abaa8a40b0db4475d07642cb7baa 100644 (file)
@@ -6927,13 +6927,14 @@ find_equiv_reg (rtx goal, rtx_insn *insn, enum reg_class rclass, int other,
          if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
            for (i = 0; i < nregs; ++i)
              if (call_used_regs[regno + i]
-                 || HARD_REGNO_CALL_PART_CLOBBERED (regno + i, mode))
+                 || targetm.hard_regno_call_part_clobbered (regno + i, mode))
                return 0;
 
          if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER)
            for (i = 0; i < valuenregs; ++i)
              if (call_used_regs[valueno + i]
-                 || HARD_REGNO_CALL_PART_CLOBBERED (valueno + i, mode))
+                 || targetm.hard_regno_call_part_clobbered (valueno + i,
+                                                            mode))
                return 0;
        }
 
index 023eaeea63e38ea04818c5dda97c53706983e059..d1ac40a25b43173ee6ce699e112a022ef73b03b2 100644 (file)
@@ -8275,7 +8275,8 @@ emit_reload_insns (struct insn_chain *chain)
                           : out_regno + k);
                      reg_reloaded_insn[regno + k] = insn;
                      SET_HARD_REG_BIT (reg_reloaded_valid, regno + k);
-                     if (HARD_REGNO_CALL_PART_CLOBBERED (regno + k, mode))
+                     if (targetm.hard_regno_call_part_clobbered (regno + k,
+                                                                 mode))
                        SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
                                          regno + k);
                      else
@@ -8354,7 +8355,8 @@ emit_reload_insns (struct insn_chain *chain)
                           : in_regno + k);
                      reg_reloaded_insn[regno + k] = insn;
                      SET_HARD_REG_BIT (reg_reloaded_valid, regno + k);
-                     if (HARD_REGNO_CALL_PART_CLOBBERED (regno + k, mode))
+                     if (targetm.hard_regno_call_part_clobbered (regno + k,
+                                                                 mode))
                        SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
                                          regno + k);
                      else
@@ -8468,8 +8470,8 @@ emit_reload_insns (struct insn_chain *chain)
                      reg_reloaded_insn[src_regno + k] = store_insn;
                      CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + k);
                      SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + k);
-                     if (HARD_REGNO_CALL_PART_CLOBBERED (src_regno + k,
-                                                         mode))
+                     if (targetm.hard_regno_call_part_clobbered
+                         (src_regno + k, mode))
                        SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
                                          src_regno + k);
                      else
index 844bf02803ee3304a30ce63dbc26a6d21826f884..20838b26d7570f67b672cea928b9ee54c4d2e7c1 100644 (file)
@@ -3706,7 +3706,8 @@ deps_analyze_insn (struct deps_desc *deps, rtx_insn *insn)
              Since we only have a choice between 'might be clobbered'
              and 'definitely not clobbered', we must include all
              partly call-clobbered registers here.  */
-            else if (HARD_REGNO_CALL_PART_CLOBBERED (i, reg_raw_mode[i])
+           else if (targetm.hard_regno_call_part_clobbered (i,
+                                                            reg_raw_mode[i])
                      || TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
               SET_REGNO_REG_SET (reg_pending_clobbers, i);
           /* We don't know what set of fixed registers might be used
index 708d0887e77d0bdbcdeba8a7c741012cb7bc5392..b504b5d1482e9f6e22ce3bab41762ea78aa43f9e 100644 (file)
@@ -1102,7 +1102,7 @@ init_regs_for_mode (machine_mode mode)
       if (i >= 0)
         continue;
 
-      if (HARD_REGNO_CALL_PART_CLOBBERED (cur_reg, mode))
+      if (targetm.hard_regno_call_part_clobbered (cur_reg, mode))
         SET_HARD_REG_BIT (sel_hrd.regs_for_call_clobbered[mode],
                           cur_reg);
 
@@ -1251,7 +1251,7 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
 
   /* Exclude registers that are partially call clobbered.  */
   if (def->crosses_call
-      && ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+      && !targetm.hard_regno_call_part_clobbered (regno, mode))
     AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming,
                             sel_hrd.regs_for_call_clobbered[mode]);
 
index 5e16a77854188ebe0b15e813a4d4ebcbe0c8f185..4eea495f00b20ef5c4a5e84d7d4ee263307fe3a8 100644 (file)
@@ -910,7 +910,8 @@ extern void fancy_abort (const char *, int, const char *)
        ASM_BYTE_OP MEMBER_TYPE_FORCES_BLK LIBGCC2_HAS_SF_MODE          \
        LIBGCC2_HAS_DF_MODE LIBGCC2_HAS_XF_MODE LIBGCC2_HAS_TF_MODE     \
        CLEAR_BY_PIECES_P MOVE_BY_PIECES_P SET_BY_PIECES_P              \
-       STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD
+       STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD                        \
+       HARD_REGNO_CALL_PART_CLOBBERED
 
 /* Target macros only used for code built for the target, that have
    moved to libgcc-tm.h or have never been present elsewhere.  */
index 83724b303bb49d41ceda0b1bac2ef11c7330977f..689c0a03ef0c1ae6d4c422d26fa360dc09ebca0b 100644 (file)
@@ -5395,6 +5395,19 @@ The default version of this hook always returns @code{true}.",
  bool, (unsigned int regno),
  default_hard_regno_scratch_ok)
 
+DEFHOOK
+(hard_regno_call_part_clobbered,
+ "This hook should return true if @var{regno} is partly call-saved and\n\
+partly call-clobbered, and if a value of mode @var{mode} would be partly\n\
+clobbered by a call.  For example, if the low 32 bits of @var{regno} are\n\
+preserved across a call but higher bits are clobbered, this hook should\n\
+return true for a 64-bit mode but false for a 32-bit mode.\n\
+\n\
+The default implementation returns false, which is correct\n\
+for targets that don't have partly call-clobbered registers.",
+ bool, (unsigned int regno, machine_mode mode),
+ hook_bool_uint_mode_false)
+
 /* Return the smallest number of different values for which it is best to
    use a jump-table instead of a tree of conditional branches.  */
 DEFHOOK
index 51babfac3cf7cc62c4c6086b121301191daf91db..78657fbd410bbb73e35aeb825f9e3cb2294465fa 100644 (file)
@@ -1737,7 +1737,7 @@ default_dwarf_frame_reg_mode (int regno)
 {
   machine_mode save_mode = reg_raw_mode[regno];
 
-  if (HARD_REGNO_CALL_PART_CLOBBERED (regno, save_mode))
+  if (targetm.hard_regno_call_part_clobbered (regno, save_mode))
     save_mode = choose_hard_reg_mode (regno, 1, true);
   return save_mode;
 }