re PR target/55301 ([SH] broken sp_switch function attribute)
authorChristian Bruel <chrbr@gcc.gnu.org>
Wed, 16 Jan 2013 08:29:54 +0000 (09:29 +0100)
committerChristian Bruel <chrbr@gcc.gnu.org>
Wed, 16 Jan 2013 08:29:54 +0000 (09:29 +0100)
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

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/sp-switch.c [new file with mode: 0644]

index 1f66518ee45cdf3db9d8d92611a6c5c382a26a09..3d1dcbdddd6a4f24931fd85a91440cef59913bee 100644 (file)
@@ -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.
index 731c7fe03c10ff88ed18834d4622fff688678122..0d0dcb54af0bf44181f31461306a6071ae3ab62a 100644 (file)
@@ -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));
     }
index 30568aa2676c2ee807313daee47a1941dbaf3026..02e9f990f4419e5371f1489872d9b532aa27b59b 100644 (file)
   (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")])
index 01065d4802f79afc579336fb7246bddf85647014..b86f63a79aa2c9486f5375efa040ec21036a5830 100644 (file)
@@ -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 (file)
index 0000000..1bfe6a7
--- /dev/null
@@ -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()
+{
+}