diff mbox

[SH] re-fix the sp_switch attribute

Message ID 50F52C66.3070404@st.com
State New
Headers show

Commit Message

Christian Bruel Jan. 15, 2013, 10:16 a.m. UTC
Hello.

It seems that the .md part from the patch posted in
http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01797.html
is missing after rev 150306

Thus compiling the sp_switch attribute documentation example still fail
with an "unrecognizable insn" error.

However, after re-applying the missing part (updated with new unspec
enums), the test still fails with a "pcrel too far" assembly error
because the new stack symbol constant pool entry was not emitted
(dump_table not called properly)

This patch fixes the sp_switch unspec pattern to be recognized by
broken_move, where it is now handled to force a dump_table when necessary.

The example from the documentation now compiles fine. Added it to the
regression tests. OK for trunk ?

ps: Added again the original ChangeLog entry for the missing .md part.

Thanks,

Christian

Comments

Oleg Endo Jan. 15, 2013, 4:55 p.m. UTC | #1
Hi,

On Tue, 2013-01-15 at 11:16 +0100, Christian Bruel wrote:
> Hello.
> 
> It seems that the .md part from the patch posted in
> http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01797.html
> is missing after rev 150306
> 
> Thus compiling the sp_switch attribute documentation example still fail
> with an "unrecognizable insn" error.
> 
> However, after re-applying the missing part (updated with new unspec
> enums), the test still fails with a "pcrel too far" assembly error
> because the new stack symbol constant pool entry was not emitted
> (dump_table not called properly)
> 
> This patch fixes the sp_switch unspec pattern to be recognized by
> broken_move, where it is now handled to force a dump_table when necessary.
> 
> The example from the documentation now compiles fine. Added it to the
> regression tests. OK for trunk ?
> 
> ps: Added again the original ChangeLog entry for the missing .md part.
> 

I think this is PR 55301, which I opened a while ago.
Christian, when committing, could you please add PR target/55301 to the
ChangeLog etc, so that it pops up in the PR?

Thanks,
Oleg
Kaz Kojima Jan. 15, 2013, 10:32 p.m. UTC | #2
Christian Bruel <christian.bruel@st.com> wrote:
> This patch fixes the sp_switch unspec pattern to be recognized by
> broken_move, where it is now handled to force a dump_table when necessary.
> 
> The example from the documentation now compiles fine. Added it to the
> regression tests. OK for trunk ?

OK with the PR number line of the ChangeLog entry suggested by Oleg:
http://gcc.gnu.org/ml/gcc-patches/2013-01/msg00794.html
Thanks!

Regards,
	kaz
diff mbox

Patch

2013-01-12  Christian Bruel  <christian.bruel@st.com>

	* 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-13  Christian Bruel  <christian.bruel@st.com>

	* gcc.target/sh/sh-switch.c: New testcase.

2013-01-12  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.

Index: gcc/testsuite/gcc.target/sh/sp-switch.c
===================================================================
--- gcc/testsuite/gcc.target/sh/sp-switch.c	(revision 0)
+++ gcc/testsuite/gcc.target/sh/sp-switch.c	(revision 0)
@@ -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()
+{
+}
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	(revision 195142)
+++ gcc/config/sh/sh.c	(working copy)
@@ -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: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 195142)
+++ gcc/config/sh/sh.md	(working copy)
@@ -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")])