#undef TARGET_ASM_GLOBALIZE_DECL_NAME
#define TARGET_ASM_GLOBALIZE_DECL_NAME rs6000_globalize_decl_name
#endif
+
+#undef TARGET_SETJMP_PRESERVES_NONVOLATILE_REGS_P
+#define TARGET_SETJMP_PRESERVES_NONVOLATILE_REGS_P hook_bool_void_true
\f
/* Processor table. */
@code{mode}.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_SETJMP_PRESERVES_NONVOLATILE_REGS_P (void)
+On some targets, it is assumed that the compiler will spill all pseudos
+ that are live across a call to @code{setjmp}, while other targets treat
+ @code{setjmp} calls as normal function calls.
+
+ This hook returns false if @code{setjmp} calls do not preserve all
+ non-volatile registers so that gcc that must spill all pseudos that are
+ live across @code{setjmp} calls. Define this to return true if the
+ target does not need to spill all pseudos live across @code{setjmp} calls.
+ The default implementation conservatively assumes all pseudos must be
+ spilled across @code{setjmp} calls.
+@end deftypefn
+
@defmac STORE_FLAG_VALUE
A C expression describing the value returned by a comparison operator
with an integral mode and stored by a store-flag instruction
@hook TARGET_MODE_REP_EXTENDED
+@hook TARGET_SETJMP_PRESERVES_NONVOLATILE_REGS_P
+
@defmac STORE_FLAG_VALUE
A C expression describing the value returned by a comparison operator
with an integral mode and stored by a store-flag instruction
call, if this function receives a nonlocal
goto. */
if (cfun->has_nonlocal_label
- || find_reg_note (insn, REG_SETJMP,
- NULL_RTX) != NULL_RTX)
+ || (!targetm.setjmp_preserves_nonvolatile_regs_p ()
+ && (find_reg_note (insn, REG_SETJMP, NULL_RTX)
+ != NULL_RTX)))
{
SET_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj));
SET_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
sparseset_ior (pseudos_live_through_calls,
pseudos_live_through_calls, pseudos_live);
if (cfun->has_nonlocal_label
- || find_reg_note (curr_insn, REG_SETJMP,
- NULL_RTX) != NULL_RTX)
+ || (!targetm.setjmp_preserves_nonvolatile_regs_p ()
+ && (find_reg_note (curr_insn, REG_SETJMP, NULL_RTX)
+ != NULL_RTX)))
sparseset_ior (pseudos_live_through_setjumps,
pseudos_live_through_setjumps, pseudos_live);
}
int, (scalar_int_mode mode, scalar_int_mode rep_mode),
default_mode_rep_extended)
+ DEFHOOK
+(setjmp_preserves_nonvolatile_regs_p,
+ "On some targets, it is assumed that the compiler will spill all pseudos\n\
+ that are live across a call to @code{setjmp}, while other targets treat\n\
+ @code{setjmp} calls as normal function calls.\n\
+ \n\
+ This hook returns false if @code{setjmp} calls do not preserve all\n\
+ non-volatile registers so that gcc that must spill all pseudos that are\n\
+ live across @code{setjmp} calls. Define this to return true if the\n\
+ target does not need to spill all pseudos live across @code{setjmp} calls.\n\
+ The default implementation conservatively assumes all pseudos must be\n\
+ spilled across @code{setjmp} calls.",
+ bool, (void),
+ hook_bool_void_false)
+
/* True if MODE is valid for a pointer in __attribute__((mode("MODE"))). */
DEFHOOK
(valid_pointer_mode,
--- /dev/null
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-options "-O2" } */
+
+#include <stdlib.h>
+#include <setjmp.h>
+
+extern void foo (jmp_buf);
+
+long
+c (long var)
+{
+ jmp_buf env;
+ if (setjmp(env) != 0)
+ abort();
+ foo (env);
+ return var;
+}
+
+/* { dg-final { scan-assembler {\mmr\M} } } */