From: Robert Suchanek Date: Tue, 18 Aug 2015 12:42:12 +0000 (+0000) Subject: [MIPS] Fix register renaming in the interrupt handlers. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ec8a2131b6a1384c71a69eb0ca24b234621437b6;p=gcc.git [MIPS] Fix register renaming in the interrupt handlers. gcc/ * config/mips/mips-protos.h (mips_hard_regno_rename_ok): New prototype. * config/mips/mips.c (mips_hard_regno_rename_ok): New function. (mips_hard_regno_scratch_ok): Likewise. (TARGET_HARD_REGNO_SCRATCH_OK): Define macro. * config/mips/mips.h (HARD_REGNO_RENAME_OK): New. gcc/testsuite/ * gcc.target/mips/interrupt_handler-bug-1.c: New test. From-SVN: r226968 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3bbbec6e5ba..dcd5d4768f5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-08-18 Robert Suchanek + + * config/mips/mips-protos.h (mips_hard_regno_rename_ok): New prototype. + * config/mips/mips.c (mips_hard_regno_rename_ok): New function. + (mips_hard_regno_scratch_ok): Likewise. + (TARGET_HARD_REGNO_SCRATCH_OK): Define macro. + * config/mips/mips.h (HARD_REGNO_RENAME_OK): New. + 2015-08-18 Bin Cheng * tree-ssa-loop-niter.c (refine_value_range_using_guard): New. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 244eb8d51cb..d9ad9100f99 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -303,6 +303,7 @@ extern const char *mips_output_sync_loop (rtx_insn *, rtx *); extern unsigned int mips_sync_loop_insns (rtx_insn *, rtx *); extern const char *mips_output_division (const char *, rtx *); extern const char *mips_output_probe_stack_range (rtx, rtx); +extern bool mips_hard_regno_rename_ok (unsigned int, unsigned int); extern unsigned int mips_hard_regno_nregs (int, machine_mode); extern bool mips_linked_madd_p (rtx_insn *, rtx_insn *); extern bool mips_store_data_bypass_p (rtx_insn *, rtx_insn *); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 238b9b0b84e..401d73bfeaa 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -12281,6 +12281,33 @@ mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode) return false; } +/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */ + +bool +mips_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED, + unsigned int new_reg) +{ + /* Interrupt functions can only use registers that have already been + saved by the prologue, even if they would normally be call-clobbered. */ + if (cfun->machine->interrupt_handler_p && !df_regs_ever_live_p (new_reg)) + return false; + + return true; +} + +/* Return nonzero if register REGNO can be used as a scratch register + in peephole2. */ + +bool +mips_hard_regno_scratch_ok (unsigned int regno) +{ + /* See mips_hard_regno_rename_ok. */ + if (cfun->machine->interrupt_handler_p && !df_regs_ever_live_p (regno)) + return false; + + return true; +} + /* Implement HARD_REGNO_NREGS. */ unsigned int @@ -19827,6 +19854,9 @@ mips_ira_change_pseudo_allocno_class (int regno, reg_class_t allocno_class) #undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS #define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS mips_ira_change_pseudo_allocno_class +#undef TARGET_HARD_REGNO_SCRATCH_OK +#define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-mips.h" diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 6e262d6f508..da1de011fc9 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1876,6 +1876,9 @@ FP_ASM_SPEC "\ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ mips_hard_regno_mode_ok[ (int)(MODE) ][ (REGNO) ] +#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \ + mips_hard_regno_rename_ok (OLD_REG, NEW_REG) + /* Select a register mode required for caller save of hard regno REGNO. */ #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ mips_hard_regno_caller_save_mode (REGNO, NREGS, MODE) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c41419120de..aff223c8a16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-08-18 Robert Suchanek + + * gcc.target/mips/interrupt_handler-bug-1.c: New test. + 2015-08-18 Bin Cheng * gcc.dg/tree-ssa/loop-bound-1.c: New test. diff --git a/gcc/testsuite/gcc.target/mips/interrupt_handler-bug-1.c b/gcc/testsuite/gcc.target/mips/interrupt_handler-bug-1.c new file mode 100644 index 00000000000..2784705b176 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/interrupt_handler-bug-1.c @@ -0,0 +1,11 @@ +/* { dg-options "-funroll-loops" } */ +int foo; +int bar; + +void __attribute__ ((interrupt)) +isr (void) +{ + if (!foo) + while (bar & 0xFF30); +} +/* { dg-final { scan-assembler-not "^isr:.*\\\$8.*isr" } } */