Patchwork [SH] PR 54602

login
register
mail settings
Submitter Oleg Endo
Date Oct. 12, 2012, 9 a.m.
Message ID <1350032413.8747.53.camel@yam-132-YW-E178-FTW>
Download mbox | patch
Permalink /patch/191074/
State New
Headers show

Comments

Oleg Endo - Oct. 12, 2012, 9 a.m.
Hello,

This fixes the issue of PR 54602 as proposed in the PR.
Tested on rev 192200 with
make -k check RUNTESTFLAGS="--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"

and no new failures.
OK?

Cheers,
Oleg

gcc/ChangeLog:

	PR target/54602
	* config/sh/sh.md: Correct define_delay for return insns.
	(*movsi_pop): Delete.

testsuite/ChangeLog:

	PR target/54602
	* gcc.target/sh/pr54602-1.c: New.
	* gcc.target/sh/pr54602-2.c: New.
	* gcc.target/sh/pr54602-3.c: New.
	* gcc.target/sh/pr54602-4.c: New.
Kaz Kojima - Oct. 12, 2012, 10:41 p.m.
Oleg Endo <oleg.endo@t-online.de> wrote:
> This fixes the issue of PR 54602 as proposed in the PR.
> Tested on rev 192200 with
> make -k check RUNTESTFLAGS="--target_board=sh-sim
> \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"
> 
> and no new failures.
> OK?

OK.

Regards,
	kaz

Patch

Index: gcc/testsuite/gcc.target/sh/pr54602-1.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr54602-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/sh/pr54602-1.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* Verify that the delay slot is stuffed with register pop insns for normal
+   (i.e. not interrupt handler) function returns.  If everything goes as
+   expected we won't see any nop insns.  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } }  */
+/* { dg-final { scan-assembler-not "nop" } } */
+
+int test00 (int a, int b);
+
+int
+test01 (int a, int b, int c, int d)
+{
+  return test00 (a, b) + c;
+}
Index: gcc/testsuite/gcc.target/sh/pr54602-3.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr54602-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/sh/pr54602-3.c	(revision 0)
@@ -0,0 +1,12 @@ 
+/* Verify that the rte delay slot is not stuffed with register pop insns
+   which touch the banked registers r0..r7 on SH3* and SH4* targets.  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m3*" "-m4*" } }  */
+/* { dg-final { scan-assembler-times "nop" 1 } } */
+
+int __attribute__ ((interrupt_handler))
+test00 (int a, int b, int c, int d)
+{
+  return a + b;
+}
Index: gcc/testsuite/gcc.target/sh/pr54602-2.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr54602-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/sh/pr54602-2.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* Verify that the delay slot is not stuffed with register pop insns for
+   interrupt handler function returns on SH1* and SH2* targets, where the
+   rte insn uses the stack pointer.  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m1*" "-m2*" } }  */
+/* { dg-final { scan-assembler-times "nop" 1 } } */
+
+int test00 (int a, int b);
+
+int __attribute__ ((interrupt_handler))
+test01 (int a, int b, int c, int d)
+{
+  return test00 (a, b) + c;
+}
Index: gcc/testsuite/gcc.target/sh/pr54602-4.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr54602-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/sh/pr54602-4.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* Verify that the delay slot is stuffed with register pop insns on SH3* and
+   SH4* targets, where the stack pointer is not used by the rte insn.  If
+   everything works out, we won't see a nop insn.  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m3*" "-m4*" } }  */
+/* { dg-final { scan-assembler-not "nop" } } */
+
+int test00 (int a, int b);
+
+int __attribute__ ((interrupt_handler))
+test01 (int a, int b, int c, int d)
+{
+  return test00 (a, b) + c;
+}
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 192200)
+++ gcc/config/sh/sh.md	(working copy)
@@ -541,22 +541,22 @@ 
   (eq_attr "needs_delay_slot" "yes")
   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
 
-;; On the SH and SH2, the rte instruction reads the return pc from the stack,
-;; and thus we can't put a pop instruction in its delay slot.
-;; On the SH3 and SH4, the rte instruction does not use the stack, so a pop
-;; instruction can go in the delay slot.
 ;; Since a normal return (rts) implicitly uses the PR register,
 ;; we can't allow PR register loads in an rts delay slot.
+;; On the SH1* and SH2*, the rte instruction reads the return pc from the
+;; stack, and thus we can't put a pop instruction in its delay slot.
+;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
+;; pop instruction can go in the delay slot, unless it references a banked
+;; register (the register bank is switched by rte).
 (define_delay
   (eq_attr "type" "return")
   [(and (eq_attr "in_delay_slot" "yes")
 	(ior (and (eq_attr "interrupt_function" "no")
 		  (eq_attr "type" "!pload,prset"))
 	     (and (eq_attr "interrupt_function" "yes")
-		  (ior
-		   (not (match_test "TARGET_SH3"))
-		   (eq_attr "hit_stack" "no")
-		   (eq_attr "banked" "no"))))) (nil) (nil)])
+		  (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
+		  (eq_attr "banked" "no"))))
+   (nil) (nil)])
 
 ;; Since a call implicitly uses the PR register, we can't allow
 ;; a PR register store in a jsr delay slot.
@@ -6186,21 +6186,6 @@ 
   emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
 })
 
-;; Define additional pop for SH1 and SH2 so it does not get 
-;; placed in the delay slot.
-(define_insn "*movsi_pop"
-  [(set (match_operand:SI 0 "register_operand" "=r,x,l")
-        (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
-  "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
-   && ! TARGET_SH3"
-  "@
-	mov.l	%1,%0
-	lds.l	%1,%0
-	lds.l	%1,%0"
-  [(set_attr "type" "load_si,mem_mac,pload")
-   (set_attr "length" "2,2,2")
-   (set_attr "in_delay_slot" "no,no,no")])
-
 ;; t/r must come after r/r, lest reload will try to reload stuff like
 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.