aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@st.com>2006-01-30 15:07:43 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2006-01-30 15:07:43 +0000
commita6ab9fc0872bbc3330490c0e3ad5d0a61dbe4458 (patch)
tree2c0dc139501a3b56003fa7a9d0a9f3e5ae212d8e /gcc/testsuite/gcc.dg
parent52a64bd38e2af65bef3c1c4f4d93e0477c56ec15 (diff)
downloadgcc-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.c28
-rw-r--r--gcc/testsuite/gcc.dg/attr-isr-trap_exit.c23
-rw-r--r--gcc/testsuite/gcc.dg/attr-isr-trapa.c17
-rw-r--r--gcc/testsuite/gcc.dg/attr-isr.c18
-rw-r--r--gcc/testsuite/gcc.dg/pragma-isr-nosave_low_regs.c20
-rw-r--r--gcc/testsuite/gcc.dg/pragma-isr-trap_exit.c17
-rw-r--r--gcc/testsuite/gcc.dg/pragma-isr-trapa.c17
-rw-r--r--gcc/testsuite/gcc.dg/pragma-isr-trapa2.c22
-rw-r--r--gcc/testsuite/gcc.dg/pragma-isr.c2
-rw-r--r--gcc/testsuite/gcc.dg/pragma-isr2.c16
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} } */