diff options
author | J"orn Rennecke <joern.rennecke@st.com> | 2006-01-30 15:07:43 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2006-01-30 15:07:43 +0000 |
commit | a6ab9fc0872bbc3330490c0e3ad5d0a61dbe4458 (patch) | |
tree | 2c0dc139501a3b56003fa7a9d0a9f3e5ae212d8e /gcc/testsuite/gcc.dg | |
parent | 52a64bd38e2af65bef3c1c4f4d93e0477c56ec15 (diff) | |
download | gcc-a6ab9fc0872bbc3330490c0e3ad5d0a61dbe4458.zip gcc-a6ab9fc0872bbc3330490c0e3ad5d0a61dbe4458.tar.gz gcc-a6ab9fc0872bbc3330490c0e3ad5d0a61dbe4458.tar.bz2 |
re PR target/14798 (In case of SH target with -O2 option #pragma interrupt doesn't get resetted.)
PR target/14798:
gcc:
* sh.c (pragma_interrupt, trap_exit, sp_switch): Remove variable.
(pragma_trap, pragma_nosave_low_regs): Likewise.
(current_function_anonymous_args): Likewise.
(sh_deferred_function_attributes): New variable.
(sh_deferred_function_attributes_tail): Likewise.
(print_operand): For '@', look up trap_exit attribute.
(calc_live_regs): Look up trapa_handler attribute. For trapa
handlers, save/restore fpscr, but don't do any other
interrupt-specific saves.
Don't save r0..r7 if the nosave_low_regs attribute is in effect.
Fix check for partially saved registers to check for SHmedia.
(sh_expand_prologue, sh_expand_epilogue): Look up sp_switch attribute.
(sh_output_function_epilogue): Don't clear any of the removed
variables.
(sh_insert_attributes): Don't check pragma_interrupt.
Insert deferred attributes. Check that interrupt attribute is
present for other attributes that require its presence.
(sh_attribute_table): Add new attributes trapa_handler and
nosave_low_regs.
(sh_handle_sp_switch_attribute, sh_handle_trap_exit_attribute):
Don't check for pragma_interrupt. Don't store argument.
* sh.h (pragma_interrupt, sp_switch): Don't declare.
(sh_deferred_function_attributes): Declare.
(sh_deferred_function_attributes_tail): Likewise.
* sh.md (sp_switch_1): Add operand. Change generator caller.
(sh_pr_interrupt, sh_pr_trapa, sh_pr_nosave_low_regs): Remove.
(*return_i): Don't use when trap_exit attribute is in effect.
(*return_trapa): New insn pattern.
* sh-c.c: New file.
* config.gcc (sh[123456ble]*-* | sh-*-*): New trailer stanza,
setting c_target_objs and cxx_target_objs.
* t-sh: Add rule for sh-c.o.
gcc/testsuite:
* gcc.dg/pragma-isr.c: Added target sh[1234ble]*-*-*.
* gcc.dg/pragma-isr2.c, gcc.dg/pragma-isr-trapa.c: New tests.
* gcc.dg/pragma-isr-trapa2.c: Likewise.
* gcc.dg/pragma-isr-nosave_low_regs.c: Likewise.
* gcc.dg/pragma-isr-trap_exit.c: Likewise.
* gcc.dg/attr-isr.c, gcc.dg/attr-isr-trapa.c: Likewise.
* gcc.dg/attr-isr-trap_exit.c: Likewise.
* gcc.dg/attr-isr-nosave_low_regs.c: Likewise.
From-SVN: r110398
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r-- | gcc/testsuite/gcc.dg/attr-isr-nosave_low_regs.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/attr-isr-trap_exit.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/attr-isr-trapa.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/attr-isr.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pragma-isr-nosave_low_regs.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pragma-isr-trap_exit.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pragma-isr-trapa.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pragma-isr-trapa2.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pragma-isr.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pragma-isr2.c | 16 |
10 files changed, 179 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/attr-isr-nosave_low_regs.c b/gcc/testsuite/gcc.dg/attr-isr-nosave_low_regs.c new file mode 100644 index 0000000..5f3acdf --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-isr-nosave_low_regs.c @@ -0,0 +1,28 @@ +/* { dg-do compile { target sh-*-* sh[1234ble]*-*-*} } */ +/* { dg-options "-O" } */ + +extern void bar (); + +void foo () +{ +} + +#pragma interrupt +void ( __attribute__ ((nosave_low_regs)) isr) () +{ + bar (); +} + +void delay(int a) +{ +} + +/* { dg-final { scan-assembler-times "rte" 1} } */ +/* A call will clobber all call-saved registers, but because of + #pragma nosave_low_regs, r0..r7 need not be saved/restored. + One of these registers will also do fine to hold the function address. + Call-saved registers r8..r13 also don't need to be restored. */ +/* { dg-final { scan-assembler-not "\[^f\]r\[0-9\]\[ \t\]*," } } */ +/* { dg-final { scan-assembler-not "\[^f\]r\[89\]" } } */ +/* { dg-final { scan-assembler-not "\[^f\]r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-times "macl" 2} } */ diff --git a/gcc/testsuite/gcc.dg/attr-isr-trap_exit.c b/gcc/testsuite/gcc.dg/attr-isr-trap_exit.c new file mode 100644 index 0000000..880db37 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-isr-trap_exit.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target sh-*-* sh[1234ble]*-*-*} } */ +/* { dg-options "-O" } */ +/* Check that trapa / interrput_handler attributes can paired in + either order. */ +void h0() __attribute__ ((trap_exit (4))) __attribute__ ((interrupt_handler)); +void h1() __attribute__ ((interrupt_handler)) __attribute__ ((trap_exit (5))); + +void foo () +{ +} + +void h0 () {} +/* { dg-final { scan-assembler "trapa\[ \t\]\[ \t\]*#4"} } */ +/* { dg-final { scan-assembler-times "trapa" 1} } */ + +void delay(int a) +{ +} +int main() +{ + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/attr-isr-trapa.c b/gcc/testsuite/gcc.dg/attr-isr-trapa.c new file mode 100644 index 0000000..d176805 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-isr-trapa.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target sh-*-* sh[1234ble]*-*-*} } */ +/* { dg-options "-O" } */ +extern void foo (); + +void +(__attribute__ ((trapa_handler)) isr) () +{ + foo (); +} + +/* { dg-final { scan-assembler-times "rte" 1} } */ +/* No interrupt-specific saves should be needed. / +/* { dg-final { scan-assembler-not "\[^f\]r\[0-7\]\[ \t,\]\[^\n\]*r15" } } */ +/* { dg-final { scan-assembler-not "@r15\[^\n\]*\[^f\]r\[0-7\]\n" } } */ +/* { dg-final { scan-assembler-not "\[^f\]r\[8-9\]" } } */ +/* { dg-final { scan-assembler-not "\[^f\]r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-not "macl" } } */ diff --git a/gcc/testsuite/gcc.dg/attr-isr.c b/gcc/testsuite/gcc.dg/attr-isr.c new file mode 100644 index 0000000..113ac21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-isr.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target sh-*-* sh[1234ble]*-*-*} } */ +/* { dg-options "-O" } */ +extern void foo (); + +void +(__attribute ((interrupt_handler)) isr)() +{ + foo (); +} + +/* { dg-final { scan-assembler-times "rte" 1} } */ +/* The call will clobber r0..r7, which will need not be saved/restored. + One of these registers will do fine to hold the function address, + hence the all-saved registers r8..r13 don't need to be restored. */ +/* { dg-final { scan-assembler-times "r15\[+\],\[ \t\]*r\[0-9\]\[ \t\]*\n" 8 } } */ +/* { dg-final { scan-assembler-times "\[^f\]r\[0-9\]\[ \t\]*," 8 } } */ +/* { dg-final { scan-assembler-not "\[^f\]r1\[0-3\]" } } */ +/* { dg-final { scan-assembler-times "macl" 2} } */ diff --git a/gcc/testsuite/gcc.dg/pragma-isr-nosave_low_regs.c b/gcc/testsuite/gcc.dg/pragma-isr-nosave_low_regs.c new file mode 100644 index 0000000..5e04922 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-isr-nosave_low_regs.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target sh-*-* sh[1234ble]*-*-*} } */ +/* { dg-options "-O" } */ +extern void foo (); +#pragma interrupt +#pragma nosave_low_regs +void +isr() +{ + foo (); +} + +/* { dg-final { scan-assembler-times "rte" 1} } */ +/* A call will clobber all call-saved registers, but because of + #pragma nosave_low_regs, r0..r7 need not be saved/restored. + One of these registers will also do fine to hold the function address. + Call-saved registers r8..r13 also don't need to be restored. */ +/* { dg-final { scan-assembler-not "\[^f\]r\[0-9\]\[ \t\]*," } } */ +/* { dg-final { scan-assembler-not "\[^f\]r\[89\]" } } */ +/* { dg-final { scan-assembler-not "\[^f\]r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-times "macl" 2} } */ diff --git a/gcc/testsuite/gcc.dg/pragma-isr-trap_exit.c b/gcc/testsuite/gcc.dg/pragma-isr-trap_exit.c new file mode 100644 index 0000000..9b3233a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-isr-trap_exit.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target sh-*-* sh[1234ble]*-*-*} } */ +/* { dg-options "-O" } */ +/* This test case will check whether trapa is generated only for isr. */ +#pragma interrupt +void isr() __attribute__ ((trap_exit (4))); +void isr() +{ +} +void delay(int a) +{ +} +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler-times "trapa\[ \t\]\[ \t\]*#4" 1} } */ diff --git a/gcc/testsuite/gcc.dg/pragma-isr-trapa.c b/gcc/testsuite/gcc.dg/pragma-isr-trapa.c new file mode 100644 index 0000000..cd019d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-isr-trapa.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target sh-*-* sh[1234ble]*-*-*} } */ +/* { dg-options "-O" } */ +extern void foo (); +#pragma trapa +void +isr() +{ + foo (); +} + +/* { dg-final { scan-assembler-times "rte" 1} } */ +/* No interrupt-specific saves should be needed. / +/* { dg-final { scan-assembler-not "r\[0-7\]\[ \t,\]\[^\n\]*r15" } } */ +/* { dg-final { scan-assembler-not "@r15\[^\n\]*r\[0-7\]\n" } } */ +/* { dg-final { scan-assembler-not "r\[8-9\]" } } */ +/* { dg-final { scan-assembler-not "r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-not "macl" } } */ diff --git a/gcc/testsuite/gcc.dg/pragma-isr-trapa2.c b/gcc/testsuite/gcc.dg/pragma-isr-trapa2.c new file mode 100644 index 0000000..21c940b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-isr-trapa2.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target sh-*-* sh4*-*-*} } */ +/* { dg-options "-O -m4" } */ + +extern void foo (); +#pragma trapa +void +isr() +{ + foo (); +} + +/* { dg-final { scan-assembler-times "rte" 1} } */ +/* No interrupt-specific saves should be needed. + The function call will require to load the address first into a register, + then use that for a jsr or jmp. It will also need to load a constant + address in order to load fpscr. */ +/* { dg-final { scan-assembler-times "r\[0-7\]\n" 3 } } */ +/* { dg-final { scan-assembler-not "r\[8-9\]" } } */ +/* { dg-final { scan-assembler-not "r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-not "macl" } } */ +/* fpscr needs to be saved, loaded and restored. */ +/* { dg-final { scan-assembler-times "\[^_\]fpscr" 3 } } */ diff --git a/gcc/testsuite/gcc.dg/pragma-isr.c b/gcc/testsuite/gcc.dg/pragma-isr.c index de16639..07d8fa7 100644 --- a/gcc/testsuite/gcc.dg/pragma-isr.c +++ b/gcc/testsuite/gcc.dg/pragma-isr.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target h8300-*-* sh-*-*} } */ +/* { dg-do compile { target h8300-*-* sh-*-* sh[1234ble]*-*-*} } */ /* { dg-options "-O3" } */ /* Test case will check whether rte is generated for two ISRs*/ extern void foo(); diff --git a/gcc/testsuite/gcc.dg/pragma-isr2.c b/gcc/testsuite/gcc.dg/pragma-isr2.c new file mode 100644 index 0000000..7dba7f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-isr2.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target h8300-*-* sh-*-* sh[1234ble]*-*-*} } */ +/* { dg-options "-O" } */ +/* This test case will check whether rte is generated only for isr. */ +#pragma interrupt +void isr() +{ +} +void delay(int a) +{ +} +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler-times "rte" 1} } */ |