diff options
author | Christian Bruel <chrbr@gcc.gnu.org> | 2013-01-16 09:29:54 +0100 |
---|---|---|
committer | Christian Bruel <chrbr@gcc.gnu.org> | 2013-01-16 09:29:54 +0100 |
commit | 8b0a1e0b4371c8c2597a5f310f2a1843832d38da (patch) | |
tree | 857fdfe16236f5fe35daa750a92b7fbbe40b29ce /gcc | |
parent | 19006c45f5153e69530a26b8dc35ae255aa118c7 (diff) | |
download | gcc-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/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 11 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/sp-switch.c | 10 |
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() +{ +} |