From a4242737202af64a394f5271c06b8be1979cbcfb Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Mon, 14 May 2007 13:52:18 +0000 Subject: [PATCH] m68k-protos.h: Rename m68k_interrupt_function_p to m68k_get_function_kind. gcc/ * config/m68k/m68k-protos.h: Rename m68k_interrupt_function_p to m68k_get_function_kind. Update its prototype. * config/m68k/m68k.c (m68k_attribute_table): Add an entry for interrupt_thread. (m68k_interrupt_function_p): Return enum m68k_function_type instead of bool. Rename to m68k_get_function_kind. (m68k_handle_fndecl_attribute): Reject interrupt_thread if the target is not fido. (m68k_compute_frame_layout): Don't mark any register for save if an interrupt_thread attribute is specified. (m68k_hard_regno_rename_ok): Update a use of m68k_interrupt_function_p. * config/m68k/m68k.h (EPILOGUE_USES): Update a use of m68k_interrupt_function_p. (m68k_function_type): New. * config/m68k/m68k.md (*return): Output a 'sleep' instruction for a function with an interrupt_thread attribute. * doc/extend.texi: Document the interrupt_thread attribute. gcc/testsuite/ * gcc.target/m68k/interrupt_thread-1.c, gcc.target/m68k/interrupt_thread-2.c, gcc.target/m68k/interrupt_thread-3.c: New. * gcc.target/m68k/m68k.exp: Accept fido. From-SVN: r124713 --- gcc/ChangeLog | 21 ++++++++ gcc/config/m68k/m68k-protos.h | 2 +- gcc/config/m68k/m68k.c | 70 +++++++++++++++++++------- gcc/config/m68k/m68k.h | 13 ++++- gcc/config/m68k/m68k.md | 22 +++++--- gcc/doc/extend.texi | 8 +++ gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/gcc.target/m68k/m68k.exp | 2 +- 8 files changed, 115 insertions(+), 30 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 46ee450c5fd..d470dabc4e3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2007-05-14 Kazu Hirata + + * config/m68k/m68k-protos.h: Rename m68k_interrupt_function_p + to m68k_get_function_kind. Update its prototype. + * config/m68k/m68k.c (m68k_attribute_table): Add an entry for + interrupt_thread. + (m68k_interrupt_function_p): Return enum m68k_function_type + instead of bool. Rename to m68k_get_function_kind. + (m68k_handle_fndecl_attribute): Reject interrupt_thread if the + target is not fido. + (m68k_compute_frame_layout): Don't mark any register for save + if an interrupt_thread attribute is specified. + (m68k_hard_regno_rename_ok): Update a use of + m68k_interrupt_function_p. + * config/m68k/m68k.h (EPILOGUE_USES): Update a use of + m68k_interrupt_function_p. + (m68k_function_type): New. + * config/m68k/m68k.md (*return): Output a 'sleep' instruction + for a function with an interrupt_thread attribute. + * doc/extend.texi: Document the interrupt_thread attribute. + 2007-05-13 Daniel Berlin Fix PR tree-optimization/31911 diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h index b3b78a15adb..f5d6c3af76e 100644 --- a/gcc/config/m68k/m68k-protos.h +++ b/gcc/config/m68k/m68k-protos.h @@ -21,7 +21,7 @@ Boston, MA 02110-1301, USA. */ /* Define functions defined in aux-output.c and used in templates. */ #ifdef RTX_CODE -extern bool m68k_interrupt_function_p (tree); +extern enum m68k_function_kind m68k_get_function_kind (tree); extern HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to); extern void split_di (rtx[], int, rtx[], rtx[]); diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index f975e06fea9..87665596726 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -223,6 +223,7 @@ static const struct attribute_spec m68k_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ { "interrupt_handler", 0, 0, true, false, false, m68k_handle_fndecl_attribute }, + { "interrupt_thread", 0, 0, true, false, false, m68k_handle_fndecl_attribute }, { NULL, 0, 0, false, false, false, NULL } }; @@ -633,10 +634,12 @@ m68k_cpp_cpu_family (const char *prefix) return concat ("__m", prefix, "_family_", m68k_cpu_entry->family, NULL); } -/* Return nonzero if FUNC is an interrupt function as specified by the - "interrupt_handler" attribute. */ -bool -m68k_interrupt_function_p (tree func) +/* Return m68k_fk_interrupt_handler if FUNC has an "interrupt_handler" + attribute and interrupt_thread if FUNC has an "interrupt_thread" + attribute. Otherwise, return m68k_fk_normal_function. */ + +enum m68k_function_kind +m68k_get_function_kind (tree func) { tree a; @@ -644,7 +647,14 @@ m68k_interrupt_function_p (tree func) return false; a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func)); - return (a != NULL_TREE); + if (a != NULL_TREE) + return m68k_fk_interrupt_handler; + + a = lookup_attribute ("interrupt_thread", DECL_ATTRIBUTES (func)); + if (a != NULL_TREE) + return m68k_fk_interrupt_thread; + + return m68k_fk_normal_function; } /* Handle an attribute requiring a FUNCTION_DECL; arguments as in @@ -662,6 +672,19 @@ m68k_handle_fndecl_attribute (tree *node, tree name, *no_add_attrs = true; } + if (m68k_get_function_kind (*node) != m68k_fk_normal_function) + { + error ("multiple interrupt attributes not allowed"); + *no_add_attrs = true; + } + + if (!TARGET_FIDOA + && !strcmp (IDENTIFIER_POINTER (name), "interrupt_thread")) + { + error ("interrupt_thread is available only on fido"); + *no_add_attrs = true; + } + return NULL_TREE; } @@ -670,7 +693,10 @@ m68k_compute_frame_layout (void) { int regno, saved; unsigned int mask; - bool interrupt_handler = m68k_interrupt_function_p (current_function_decl); + enum m68k_function_kind func_kind = + m68k_get_function_kind (current_function_decl); + bool interrupt_handler = func_kind == m68k_fk_interrupt_handler; + bool interrupt_thread = func_kind == m68k_fk_interrupt_thread; /* Only compute the frame once per function. Don't cache information until reload has been completed. */ @@ -681,12 +707,15 @@ m68k_compute_frame_layout (void) current_frame.size = (get_frame_size () + 3) & -4; mask = saved = 0; - for (regno = 0; regno < 16; regno++) - if (m68k_save_reg (regno, interrupt_handler)) - { - mask |= 1 << (regno - D0_REG); - saved++; - } + + /* Interrupt thread does not need to save any register. */ + if (!interrupt_thread) + for (regno = 0; regno < 16; regno++) + if (m68k_save_reg (regno, interrupt_handler)) + { + mask |= 1 << (regno - D0_REG); + saved++; + } current_frame.offset = saved * 4; current_frame.reg_no = saved; current_frame.reg_mask = mask; @@ -695,12 +724,14 @@ m68k_compute_frame_layout (void) mask = saved = 0; if (TARGET_HARD_FLOAT) { - for (regno = 16; regno < 24; regno++) - if (m68k_save_reg (regno, interrupt_handler)) - { - mask |= 1 << (regno - FP0_REG); - saved++; - } + /* Interrupt thread does not need to save any register. */ + if (!interrupt_thread) + for (regno = 16; regno < 24; regno++) + if (m68k_save_reg (regno, interrupt_handler)) + { + mask |= 1 << (regno - FP0_REG); + saved++; + } current_frame.foffset = saved * TARGET_FP_REG_SIZE; current_frame.offset += current_frame.foffset; } @@ -4211,7 +4242,8 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED, saved by the prologue, even if they would normally be call-clobbered. */ - if (m68k_interrupt_function_p (current_function_decl) + if ((m68k_get_function_kind (current_function_decl) + == m68k_fk_interrupt_handler) && !regs_ever_live[new_reg]) return 0; diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index baa5bcb6651..1b19b4c8095 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -903,8 +903,10 @@ do { if (cc_prev_status.flags & CC_IN_68881) \ #define INCOMING_FRAME_SP_OFFSET 4 /* All registers are live on exit from an interrupt routine. */ -#define EPILOGUE_USES(REGNO) \ - (reload_completed && m68k_interrupt_function_p (current_function_decl)) +#define EPILOGUE_USES(REGNO) \ + (reload_completed \ + && (m68k_get_function_kind (current_function_decl) \ + == m68k_fk_interrupt_handler)) /* Describe how we implement __builtin_eh_return. */ #define EH_RETURN_DATA_REGNO(N) \ @@ -1098,6 +1100,13 @@ enum fpu_type FPUTYPE_COLDFIRE }; +enum m68k_function_kind +{ + m68k_fk_normal_function, + m68k_fk_interrupt_handler, + m68k_fk_interrupt_thread +}; + /* Variables in m68k.c; see there for details. */ extern const char *m68k_library_id_string; extern int m68k_last_compare_had_fp_operands; diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index 78ddf58f71e..19abe624c29 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -6833,15 +6833,23 @@ [(return)] "" { - if (m68k_interrupt_function_p (current_function_decl)) - return "rte"; - else if (current_function_pops_args) + switch (m68k_get_function_kind (current_function_decl)) { - operands[0] = GEN_INT (current_function_pops_args); - return "rtd %0"; + case m68k_fk_interrupt_handler: + return "rte"; + + case m68k_fk_interrupt_thread: + return "sleep"; + + default: + if (current_function_pops_args) + { + operands[0] = GEN_INT (current_function_pops_args); + return "rtd %0"; + } + else + return "rts"; } - else - return "rts"; }) (define_insn "*m68k_store_multiple" diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 574bc127768..4a8f67455cc 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2047,6 +2047,14 @@ indicate that the specified function is an interrupt handler. The compiler will generate function entry and exit sequences suitable for use in an interrupt handler when this attribute is present. +@item interrupt_thread +@cindex interrupt thread functions on fido +Use this attribute on fido, a subarchitecture of the m68k, to indicate +that the specified function is an interrupt handler that is designed +to run as a thread. The compiler omits generate prologue/epilogue +sequences and replaces the return instruction with a @code{sleep} +instruction. This attribute is available only on fido. + @item kspisusp @cindex User stack pointer in interrupts on the Blackfin When used together with @code{interrupt_handler}, @code{exception_handler} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fe908d11df1..0c3111793de 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2007-05-14 Kazu Hirata + + * gcc.target/m68k/interrupt_thread-1.c, + gcc.target/m68k/interrupt_thread-2.c, + gcc.target/m68k/interrupt_thread-3.c: New. + * gcc.target/m68k/m68k.exp: Accept fido. + 2007-05-13 Dominique d'Humières * alloc_comp_basics_1.f90: Fix dg directive. diff --git a/gcc/testsuite/gcc.target/m68k/m68k.exp b/gcc/testsuite/gcc.target/m68k/m68k.exp index 9398d109cc6..872802d9586 100644 --- a/gcc/testsuite/gcc.target/m68k/m68k.exp +++ b/gcc/testsuite/gcc.target/m68k/m68k.exp @@ -17,7 +17,7 @@ # GCC testsuite that uses the `dg.exp' driver. # Exit immediately if this isn't an m68k target. -if ![istarget m68k*-*-*] then { +if { ![istarget m68k*-*-*] && ![istarget fido*-*-*] } then { return } -- 2.30.2