diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/save-restore-5.c | 16 |
4 files changed, 49 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b36c380..240d5e7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2007-07-06 Richard Sandiford <richard@codesourcery.com> + + * config/mips/mips.c (mips16e_save_restore_pattern_p): Check that + the topmost argument register is not also included in the save mask. + (mips16e_collect_argument_save_p): Take a pointer to the argument + register, rather than a pointer to the number of arguments. + (mips16e_collect_argument_saves): Only include argument saves + that aren't in the register mask. + 2007-07-06 Uros Bizjak <ubizjak@gmail.com> PR rtl_optimization/32450 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 783ff03..8c7b70c 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -7334,6 +7334,12 @@ mips16e_save_restore_pattern_p (rtx pattern, HOST_WIDE_INT adjust, if (extra != 0) return false; + /* Make sure that the topmost argument register is not saved twice. + The checks above ensure that the same is then true for the other + argument registers. */ + if (nargs > 0 && BITSET_P (mask, GP_ARG_FIRST + nargs - 1)) + return false; + /* Pass back information, if requested. */ if (info) { @@ -7458,14 +7464,13 @@ mips16e_collect_propagate_value (rtx x, rtx *reg_values) } /* Return true if (set DEST SRC) stores an argument register into its - caller-allocated save slot. If the register is not included in - [GP_ARG_FIRST, GP_ARG_LAST + *NARGS_PTR), destructively modify - *NARGS_PTR such that this condition holds. REG_VALUES is as for + caller-allocated save slot, storing the number of that argument + register in *REGNO_PTR if so. REG_VALUES is as for mips16e_collect_propagate_value. */ static bool -mips16e_collect_argument_save (rtx dest, rtx src, rtx *reg_values, - unsigned int *nargs_ptr) +mips16e_collect_argument_save_p (rtx dest, rtx src, rtx *reg_values, + unsigned int *regno_ptr) { unsigned int argno, regno; HOST_WIDE_INT offset, required_offset; @@ -7495,10 +7500,7 @@ mips16e_collect_argument_save (rtx dest, rtx src, rtx *reg_values, if (offset != required_offset) return false; - /* Make sure that *NARGS_PTR is big enough. */ - if (*nargs_ptr <= argno) - *nargs_ptr = argno + 1; - + *regno_ptr = regno; return true; } @@ -7514,7 +7516,7 @@ mips16e_collect_argument_saves (void) { rtx reg_values[FIRST_PSEUDO_REGISTER]; rtx insn, next, set, dest, src; - unsigned int nargs; + unsigned int nargs, regno; push_topmost_sequence (); nargs = 0; @@ -7534,8 +7536,14 @@ mips16e_collect_argument_saves (void) dest = SET_DEST (set); src = SET_SRC (set); - if (mips16e_collect_argument_save (dest, src, reg_values, &nargs)) - delete_insn (insn); + if (mips16e_collect_argument_save_p (dest, src, reg_values, ®no)) + { + if (!BITSET_P (cfun->machine->frame.mask, regno)) + { + delete_insn (insn); + nargs = MAX (nargs, (regno - GP_ARG_FIRST) + 1); + } + } else if (REG_P (dest) && GET_MODE (dest) == word_mode) reg_values[REGNO (dest)] = mips16e_collect_propagate_value (src, reg_values); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3772aff..a630290 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-07-06 Richard Sandiford <richard@codesourcery.com> + + * gcc.target/mips/save-restore-5.c: New test. + 2007-07-06 Uros Bizjak <ubizjak@gmail.com> PR rtl_optimization/32450 diff --git a/gcc/testsuite/gcc.target/mips/save-restore-5.c b/gcc/testsuite/gcc.target/mips/save-restore-5.c new file mode 100644 index 0000000..6c2f37c --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/save-restore-5.c @@ -0,0 +1,16 @@ +/* Check that we don't try to save the same register twice. */ +/* { dg-mips-options "-mips32r2 -mgp32 -mips16 -O2" } */ +/* { dg-do assemble } */ + +int bar (int, int, int, int); +void frob (void); + +void +foo (int a1, int a2, int a3, int a4) +{ + asm volatile ("" ::: "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", + "$18", "$19", "$20", "$21", "$22", "$23", "$24", + "$25", "$30", "$31", "memory"); + __builtin_eh_return (bar (a1, a2, a3, a4), frob); +} |