Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi (revision 136946) +++ gcc/doc/tm.texi (working copy) @@ -2242,6 +2242,16 @@ allocation. @end defmac +@deftypefn {Target Hook} bool TARGET_HARD_REGNO_SCRATCH_OK (unsigned int @var{regno}) +This target hook should return 'true' if it is OK to use a hard register +@var{regno} as scratch reg in peephole2. + +One common use of this macro is to prevent using of a register that +is not saved by a prologue in an interrupt handler. + +TThe default version of this hook always returns 'true'. +@end deftypefn + @defmac AVOID_CCMODE_COPIES Define this macro if the compiler should avoid copies to/from @code{CCmode} registers. You should only define this macro if support for copying to/from Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c (revision 136946) +++ gcc/targhooks.c (working copy) @@ -703,4 +703,10 @@ return true; } +bool +default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED) +{ + return true; +} + #include "gt-targhooks.h" Index: gcc/targhooks.h =================================================================== --- gcc/targhooks.h (revision 136946) +++ gcc/targhooks.h (working copy) @@ -97,3 +97,5 @@ extern tree default_mangle_decl_assembler_name (tree, tree); extern tree default_emutls_var_fields (tree, tree *); extern tree default_emutls_var_init (tree, tree, tree); + +extern bool default_hard_regno_scratch_ok (unsigned int); Index: gcc/target.h =================================================================== --- gcc/target.h (revision 136946) +++ gcc/target.h (working copy) @@ -866,6 +866,10 @@ but will be later. */ void (* instantiate_decls) (void); + /* Return true if is OK to use a hard register REGNO as scratch register + in peephole2. */ + bool (* hard_regno_scratch_ok) (unsigned int regno); + /* Functions specific to the C family of frontends. */ struct c { /* Return machine mode for non-standard suffix Index: gcc/recog.c =================================================================== --- gcc/recog.c (revision 136946) +++ gcc/recog.c (working copy) @@ -40,6 +40,7 @@ #include "basic-block.h" #include "output.h" #include "reload.h" +#include "target.h" #include "timevar.h" #include "tree-pass.h" #include "df.h" @@ -2898,6 +2899,9 @@ /* Don't allocate fixed registers. */ if (fixed_regs[regno]) continue; + /* Don't allocate global registers. */ + if (global_regs[regno]) + continue; /* Make sure the register is of the right class. */ if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno)) continue; @@ -2907,6 +2911,9 @@ /* And that we don't create an extra save/restore. */ if (! call_used_regs[regno] && ! df_regs_ever_live_p (regno)) continue; + if (! targetm.hard_regno_scratch_ok (regno)) + continue; + /* And we don't clobber traceback for noreturn functions. */ if ((regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM) && (! reload_completed || frame_pointer_needed)) Index: gcc/target-def.h =================================================================== --- gcc/target-def.h (revision 136946) +++ gcc/target-def.h (working copy) @@ -617,6 +617,10 @@ #define TARGET_INSTANTIATE_DECLS hook_void_void #endif +#ifndef TARGET_HARD_REGNO_SCRATCH_OK +#define TARGET_HARD_REGNO_SCRATCH_OK default_hard_regno_scratch_ok +#endif + /* C specific. */ #ifndef TARGET_C_MODE_FOR_SUFFIX #define TARGET_C_MODE_FOR_SUFFIX default_mode_for_suffix @@ -842,6 +846,7 @@ TARGET_SECONDARY_RELOAD, \ TARGET_EXPAND_TO_RTL_HOOK, \ TARGET_INSTANTIATE_DECLS, \ + TARGET_HARD_REGNO_SCRATCH_OK, \ TARGET_C, \ TARGET_CXX, \ TARGET_EMUTLS, \