aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorChristian Bruel <chrbr@gcc.gnu.org>2013-01-16 09:29:54 +0100
committerChristian Bruel <chrbr@gcc.gnu.org>2013-01-16 09:29:54 +0100
commit8b0a1e0b4371c8c2597a5f310f2a1843832d38da (patch)
tree857fdfe16236f5fe35daa750a92b7fbbe40b29ce /gcc
parent19006c45f5153e69530a26b8dc35ae255aa118c7 (diff)
downloadgcc-8b0a1e0b4371c8c2597a5f310f2a1843832d38da.zip
gcc-8b0a1e0b4371c8c2597a5f310f2a1843832d38da.tar.gz
gcc-8b0a1e0b4371c8c2597a5f310f2a1843832d38da.tar.bz2
re PR target/55301 ([SH] broken sp_switch function attribute)
PR target/55301 * config/sh/sh.c (sh_expand_prologue): Postpone new_stack mem symbol. (broken_move): Handle UNSPECV_SP_SWITCH_B. * config/sh/sh.md (sp_switch_1): Use set (reg:SI SP_REG). * config/sh/sh.md (UNSPECV_SP_SWITCH_B): New. (UNSPECV_SP_SWITCH_E): New. (sp_switch_1): Change to an unspec. (sp_switch_2): Change to an unspec. Don't use post-inc when we replace $r15. * gcc.target/sh/sh-switch.c: New testcase. From-SVN: r195230
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/config/sh/sh.c11
-rw-r--r--gcc/config/sh/sh.md10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/sh/sp-switch.c10
5 files changed, 48 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1f66518..3d1dcbd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,19 @@
-2013-01-15 Uros Bizjak <ubizjak@gmail.com>
+2013-01-16 Christian Bruel <christian.bruel@st.com>
+
+ PR target/55301
+ * config/sh/sh.c (sh_expand_prologue): Postpone new_stack mem symbol.
+ (broken_move): Handle UNSPECV_SP_SWITCH_B.
+ * config/sh/sh.md (sp_switch_1): Use set (reg:SI SP_REG).
+
+2013-01-16 DJ Delorie <dj@redhat.com>
+
+ * config/sh/sh.md (UNSPECV_SP_SWITCH_B): New.
+ (UNSPECV_SP_SWITCH_E): New.
+ (sp_switch_1): Change to an unspec.
+ (sp_switch_2): Change to an unspec. Don't use post-inc when we
+ replace $r15.
+
+2013-01-16 Uros Bizjak <ubizjak@gmail.com>
* emit-rtl.c (need_atomic_barrier_p): Mask memory model argument
with MEMMODEL_MASK before comparing with MEMMODEL_* memory types.
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 731c7fe..0d0dcb5 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -4926,6 +4926,8 @@ broken_move (rtx insn)
order bits end up as. */
&& GET_MODE (SET_DEST (pat)) != QImode
&& (CONSTANT_P (SET_SRC (pat))
+ || (GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
+ && XINT (SET_SRC (pat), 1) == UNSPECV_SP_SWITCH_B)
/* Match mova_const. */
|| (GET_CODE (SET_SRC (pat)) == UNSPEC
&& XINT (SET_SRC (pat), 1) == UNSPEC_MOVA
@@ -6422,6 +6424,14 @@ sh_reorg (void)
gen_rtvec (1, newsrc),
UNSPEC_MOVA);
}
+ else if (GET_CODE (src) == UNSPEC_VOLATILE
+ && XINT (src, 1) == UNSPECV_SP_SWITCH_B)
+ {
+ newsrc = XVECEXP (src, 0, 0);
+ XVECEXP (src, 0, 0) = gen_const_mem (mode, newsrc);
+ INSN_CODE (scan) = -1;
+ continue;
+ }
else
{
lab = add_constant (src, mode, 0);
@@ -7624,7 +7634,6 @@ sh_expand_prologue (void)
lab = add_constant (sp_switch, SImode, 0);
newsrc = gen_rtx_LABEL_REF (VOIDmode, lab);
- newsrc = gen_const_mem (SImode, newsrc);
emit_insn (gen_sp_switch_1 (newsrc));
}
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 30568aa..02e9f99 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -174,6 +174,8 @@
(UNSPECV_CONST_END 11)
(UNSPECV_EH_RETURN 12)
(UNSPECV_GBR 13)
+ (UNSPECV_SP_SWITCH_B 14)
+ (UNSPECV_SP_SWITCH_E 15)
])
;; -------------------------------------------------------------------------
@@ -13587,7 +13589,8 @@ label:
;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
(define_insn "sp_switch_1"
- [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
+ [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")]
+ UNSPECV_SP_SWITCH_B))]
"TARGET_SH1"
{
return "mov.l r0,@-r15" "\n"
@@ -13601,10 +13604,11 @@ label:
;; Switch back to the original stack for interrupt functions with the
;; sp_switch attribute.
(define_insn "sp_switch_2"
- [(const_int 2)]
+ [(unspec_volatile [(const_int 0)]
+ UNSPECV_SP_SWITCH_E)]
"TARGET_SH1"
{
- return "mov.l @r15+,r15" "\n"
+ return "mov.l @r15,r15" "\n"
" mov.l @r15+,r0";
}
[(set_attr "length" "4")])
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 01065d4..b86f63a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-01-16 Christian Bruel <christian.bruel@st.com>
+
+ PR target/55301
+ * gcc.target/sh/sh-switch.c: New testcase.
+
2013-01-15 Janis Johnson <janisjo@codesourcery.com>
* gcc.dg/webizer.c: Increase the array size.
diff --git a/gcc/testsuite/gcc.target/sh/sp-switch.c b/gcc/testsuite/gcc.target/sh/sp-switch.c
new file mode 100644
index 0000000..1bfe6a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sp-switch.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target "sh-*-*" } } */
+/* { dg-final { scan-assembler "mov\tr0,r15" } } */
+/* { dg-final { scan-assembler ".long\t_alt_stack" } } */
+
+void *alt_stack;
+void f() __attribute__ ((interrupt_handler, sp_switch ("alt_stack")));
+
+void f()
+{
+}