aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRadovan Obradovic <robradovic@mips.com>2014-05-29 08:59:08 +0000
committerTom de Vries <vries@gcc.gnu.org>2014-05-29 08:59:08 +0000
commitc2db3f3d39a5e955c0739367332cb4f3ee5ca890 (patch)
tree9f9a483656688d27a979e680fda462192b02869f /gcc
parent41455f89185c4cf265d15e6d4e2af546514e85db (diff)
downloadgcc-c2db3f3d39a5e955c0739367332cb4f3ee5ca890.zip
gcc-c2db3f3d39a5e955c0739367332cb4f3ee5ca890.tar.gz
gcc-c2db3f3d39a5e955c0739367332cb4f3ee5ca890.tar.bz2
-fuse-caller-save - Enable for MIPS
2014-05-29 Radovan Obradovic <robradovic@mips.com> Tom de Vries <tom@codesourcery.com> * config/mips/mips.h (POST_CALL_TMP_REG): Define. * config/mips/mips.c (mips_emit_call_insn): Add POST_CALL_TMP_REG clobber. (mips_split_call): Use POST_CALL_TMP_REG. (TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): Redefine to true. * gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo options. * gcc.target/mips/fuse-caller-save.h: New include file. * gcc.target/mips/fuse-caller-save.c: New test. * gcc.target/mips/fuse-caller-save-mips16.c: Same. * gcc.target/mips/fuse-caller-save-micromips.c: Same. Co-Authored-By: Tom de Vries <tom@codesourcery.com> From-SVN: r211049
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/mips/mips.c18
-rw-r--r--gcc/config/mips/mips.h7
-rw-r--r--gcc/testsuite/ChangeLog10
-rw-r--r--gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/fuse-caller-save-mips16.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/fuse-caller-save.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/fuse-caller-save.h17
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp1
9 files changed, 109 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 764249c..1eebdac 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2014-05-29 Radovan Obradovic <robradovic@mips.com>
+ Tom de Vries <tom@codesourcery.com>
+
+ * config/mips/mips.h (POST_CALL_TMP_REG): Define.
+ * config/mips/mips.c (mips_emit_call_insn): Add POST_CALL_TMP_REG
+ clobber.
+ (mips_split_call): Use POST_CALL_TMP_REG.
+ (TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): Redefine to true.
+
2014-05-29 Tom de Vries <tom@codesourcery.com>
* final.c (collect_fn_hard_reg_usage): Guard variable declaration
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 46e6b81..804112c 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2848,6 +2848,15 @@ mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
gen_rtx_REG (Pmode, GOT_VERSION_REGNUM));
emit_insn (gen_update_got_version ());
}
+
+ if (TARGET_MIPS16
+ && TARGET_EXPLICIT_RELOCS
+ && TARGET_CALL_CLOBBERED_GP)
+ {
+ rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);
+ clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
+ }
+
return insn;
}
@@ -7104,10 +7113,8 @@ mips_split_call (rtx insn, rtx call_pattern)
{
emit_call_insn (call_pattern);
if (!find_reg_note (insn, REG_NORETURN, 0))
- /* Pick a temporary register that is suitable for both MIPS16 and
- non-MIPS16 code. $4 and $5 are used for returning complex double
- values in soft-float code, so $6 is the first suitable candidate. */
- mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode, GP_ARG_FIRST + 2));
+ mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode,
+ POST_CALL_TMP_REG));
}
/* Return true if a call to DECL may need to use JALX. */
@@ -19143,6 +19150,9 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV mips_atomic_assign_expand_fenv
+#undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
+#define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
+
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 6200ffc..933e053 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2175,6 +2175,13 @@ enum reg_class
#define FP_ARG_FIRST (FP_REG_FIRST + 12)
#define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
+/* Temporary register that is used when restoring $gp after a call. $4 and $5
+ are used for returning complex double values in soft-float code, so $6 is the
+ first suitable candidate for TARGET_MIPS16. For !TARGET_MIPS16 we can use
+ $gp itself as the temporary. */
+#define POST_CALL_TMP_REG \
+ (TARGET_MIPS16 ? GP_ARG_FIRST + 2 : PIC_OFFSET_TABLE_REGNUM)
+
/* 1 if N is a possible register number for function argument passing.
We have no FP argument registers when soft-float. When FP registers
are 32 bits, we can't directly reference the odd numbered ones. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a0bd6b0..92801a9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2014-05-29 Radovan Obradovic <robradovic@mips.com>
+ Tom de Vries <tom@codesourcery.com>
+
+ * gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo
+ options.
+ * gcc.target/mips/fuse-caller-save.h: New include file.
+ * gcc.target/mips/fuse-caller-save.c: New test.
+ * gcc.target/mips/fuse-caller-save-mips16.c: Same.
+ * gcc.target/mips/fuse-caller-save-micromips.c: Same.
+
2014-05-29 Evgeny Stupachenko <evstupac@gmail.com>
* gcc.dg/vect/pr52252-ld.c: Fix target and options for the test.
diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c b/gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c
new file mode 100644
index 0000000..6ad01c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fuse-caller-save (-mmicromips)" } */
+/* At -O0 and -O1, the register allocator behaves more conservatively, and
+ the fuse-caller-save optimization doesnt' trigger. */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */
+/* Testing -fuse-caller-save optimization option. */
+
+#define ATTRIBUTE MICROMIPS
+#include "fuse-caller-save.h"
+
+/* Check that there are only 2 stack-saves: r31 in main and foo. */
+
+/* Check that there only 2 sw/sd. */
+/* { dg-final { scan-assembler-times "(?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\)" 2 } } */
+
+/* Check that the first caller-save register is unused. */
+/* { dg-final { scan-assembler-not "\\\$16" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save-mips16.c b/gcc/testsuite/gcc.target/mips/fuse-caller-save-mips16.c
new file mode 100644
index 0000000..a7c6cf4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save-mips16.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fuse-caller-save (-mips16)" } */
+/* At -O0 and -O1, the register allocator behaves more conservatively, and
+ the fuse-caller-save optimization doesnt' trigger. */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */
+/* Testing -fuse-caller-save optimization option. */
+
+#define ATTRIBUTE MIPS16
+#include "fuse-caller-save.h"
+
+/* Check that there are only 2 stack-saves: r31 in main and foo. */
+
+/* Check that there only 2 sw/sd. */
+/* { dg-final { scan-assembler-times "(?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\)" 2 } } */
+
+/* Check that the first caller-save register is unused. */
+/* { dg-final { scan-assembler-not "\\\$16" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save.c b/gcc/testsuite/gcc.target/mips/fuse-caller-save.c
new file mode 100644
index 0000000..72c08fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fuse-caller-save" } */
+/* At -O0 and -O1, the register allocator behaves more conservatively, and
+ the fuse-caller-save optimization doesnt' trigger. */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */
+/* Testing -fuse-caller-save optimization option. */
+
+#define ATTRIBUTE NOCOMPRESSION
+#include "fuse-caller-save.h"
+
+/* Check that there are only 2 stack-saves: r31 in main and foo. */
+
+/* Check that there only 2 sw/sd. */
+/* { dg-final { scan-assembler-times "(?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\)" 2 } } */
+
+/* Check that the first caller-save register is unused. */
+/* { dg-final { scan-assembler-not "\\\$16" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save.h b/gcc/testsuite/gcc.target/mips/fuse-caller-save.h
new file mode 100644
index 0000000..edf6039
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save.h
@@ -0,0 +1,17 @@
+static int __attribute__((noinline)) ATTRIBUTE
+bar (int x)
+{
+ return x + 3;
+}
+
+int __attribute__((noinline)) ATTRIBUTE
+foo (int y)
+{
+ return y + bar (y);
+}
+
+int ATTRIBUTE
+main (void)
+{
+ return !(foo (5) == 13);
+}
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 8c72cff..6ad8160 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -305,6 +305,7 @@ foreach option {
tree-vectorize
unroll-all-loops
unroll-loops
+ use-caller-save
} {
lappend mips_option_groups $option "-f(no-|)$option"
}