[MIPS] Fix register renaming in the interrupt handlers.
authorRobert Suchanek <robert.suchanek@imgtec.com>
Tue, 18 Aug 2015 12:42:12 +0000 (12:42 +0000)
committerRobert Suchanek <rts@gcc.gnu.org>
Tue, 18 Aug 2015 12:42:12 +0000 (12:42 +0000)
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

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/interrupt_handler-bug-1.c [new file with mode: 0644]

index 3bbbec6e5ba48ebb774079b13780f197d313b6d9..dcd5d4768f529caddc7bef8743134b36a29ab20b 100644 (file)
@@ -1,3 +1,11 @@
+2015-08-18  Robert Suchanek  <robert.suchanek@imgtec.com>
+
+       * 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  <bin.cheng@arm.com>
 
        * tree-ssa-loop-niter.c (refine_value_range_using_guard): New.
index 244eb8d51cba0fb8bfcfb69316769ceae0903491..d9ad9100f99616f8c722d369ac303993041554a0 100644 (file)
@@ -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 *);
index 238b9b0b84e413f305f4466e7a43441a57e1073e..401d73bfeaa72e10eac6d9a211c58c0c1bef6868 100644 (file)
@@ -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;
 \f
 #include "gt-mips.h"
index 6e262d6f5082a0ce61be4138eaef46be52071210..da1de011fc99f1aa8c4a914174726d248a2745d8 100644 (file)
@@ -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)
index c41419120dedaf10a94f3e6b7794d7568087ad84..aff223c8a1628b7da277f84e4cbcfd89373505db 100644 (file)
@@ -1,3 +1,7 @@
+2015-08-18  Robert Suchanek  <robert.suchanek@imgtec.com>
+
+       * gcc.target/mips/interrupt_handler-bug-1.c: New test.
+
 2015-08-18  Bin Cheng  <bin.cheng@arm.com>
 
        * 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 (file)
index 0000000..2784705
--- /dev/null
@@ -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" } } */