From: Oleg Endo Date: Fri, 12 Oct 2012 23:22:48 +0000 (+0000) Subject: re PR target/54602 ([SH] Register pop insn not put in rts delay slot) X-Git-Tag: misc/gccgo-go1_1_2~192 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fd90d92c8f8a23e4b10d592e8ea17091b4f5b7e9;p=thirdparty%2Fgcc.git re PR target/54602 ([SH] Register pop insn not put in rts delay slot) PR target/54602 * config/sh/sh.md: Correct define_delay for return insns. (*movsi_pop): Delete. 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. From-SVN: r192417 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a501decafda4..e967498f7c6d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-10-12 Oleg Endo + + PR target/54602 + * config/sh/sh.md: Correct define_delay for return insns. + (*movsi_pop): Delete. + 2012-10-12 Oleg Endo PR target/54680 @@ -21,13 +27,13 @@ 2012-10-12 Aaron Gray Diego Novillo - * gengtype-lex.l: Support for C++ single line comments. - Support for classes. + * gengtype-lex.l: Support for C++ single line comments. + Support for classes. (CXX_KEYWORD): New. Support C++ keywords inline, public, protected, private, template, operator, friend, &, ~. (TYPEDEF): New. Support typedef. - * gengtype-parser.c: updated 'token_names[]' - (direct_declarator): Add support for parsing functions + * gengtype-parser.c: updated 'token_names[]' + (direct_declarator): Add support for parsing functions and ctors. 2012-10-12 Diego Novillo diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 6e168eafd2d0..1b6c284e388b 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -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. @@ -6232,21 +6232,6 @@ label: 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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 96624674ecd9..033c8522fa23 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2012-10-12 Oleg Endo + + 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. + 2012-10-12 Oleg Endo PR target/54680 diff --git a/gcc/testsuite/gcc.target/sh/pr54602-1.c b/gcc/testsuite/gcc.target/sh/pr54602-1.c new file mode 100644 index 000000000000..e5c035708e48 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr54602-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/sh/pr54602-2.c b/gcc/testsuite/gcc.target/sh/pr54602-2.c new file mode 100644 index 000000000000..4f3877c41b11 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr54602-2.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/sh/pr54602-3.c b/gcc/testsuite/gcc.target/sh/pr54602-3.c new file mode 100644 index 000000000000..29292589c626 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr54602-3.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/sh/pr54602-4.c b/gcc/testsuite/gcc.target/sh/pr54602-4.c new file mode 100644 index 000000000000..0b77d0983ae4 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr54602-4.c @@ -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; +}