Commit a4242737 by Kazu Hirata Committed by Kazu Hirata

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
parent ab6bd693
2007-05-14 Kazu Hirata <kazu@codesourcery.com>
* 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 <dberlin@dberlin.org> 2007-05-13 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/31911 Fix PR tree-optimization/31911
......
...@@ -21,7 +21,7 @@ Boston, MA 02110-1301, USA. */ ...@@ -21,7 +21,7 @@ Boston, MA 02110-1301, USA. */
/* Define functions defined in aux-output.c and used in templates. */ /* Define functions defined in aux-output.c and used in templates. */
#ifdef RTX_CODE #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 HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to);
extern void split_di (rtx[], int, rtx[], rtx[]); extern void split_di (rtx[], int, rtx[], rtx[]);
......
...@@ -223,6 +223,7 @@ static const struct attribute_spec m68k_attribute_table[] = ...@@ -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 } */ /* { 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_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 } { NULL, 0, 0, false, false, false, NULL }
}; };
...@@ -633,10 +634,12 @@ m68k_cpp_cpu_family (const char *prefix) ...@@ -633,10 +634,12 @@ m68k_cpp_cpu_family (const char *prefix)
return concat ("__m", prefix, "_family_", m68k_cpu_entry->family, NULL); return concat ("__m", prefix, "_family_", m68k_cpu_entry->family, NULL);
} }
/* Return nonzero if FUNC is an interrupt function as specified by the /* Return m68k_fk_interrupt_handler if FUNC has an "interrupt_handler"
"interrupt_handler" attribute. */ attribute and interrupt_thread if FUNC has an "interrupt_thread"
bool attribute. Otherwise, return m68k_fk_normal_function. */
m68k_interrupt_function_p (tree func)
enum m68k_function_kind
m68k_get_function_kind (tree func)
{ {
tree a; tree a;
...@@ -644,7 +647,14 @@ m68k_interrupt_function_p (tree func) ...@@ -644,7 +647,14 @@ m68k_interrupt_function_p (tree func)
return false; return false;
a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func)); 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 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
...@@ -662,6 +672,19 @@ m68k_handle_fndecl_attribute (tree *node, tree name, ...@@ -662,6 +672,19 @@ m68k_handle_fndecl_attribute (tree *node, tree name,
*no_add_attrs = true; *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; return NULL_TREE;
} }
...@@ -670,7 +693,10 @@ m68k_compute_frame_layout (void) ...@@ -670,7 +693,10 @@ m68k_compute_frame_layout (void)
{ {
int regno, saved; int regno, saved;
unsigned int mask; 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. /* Only compute the frame once per function.
Don't cache information until reload has been completed. */ Don't cache information until reload has been completed. */
...@@ -681,6 +707,9 @@ m68k_compute_frame_layout (void) ...@@ -681,6 +707,9 @@ m68k_compute_frame_layout (void)
current_frame.size = (get_frame_size () + 3) & -4; current_frame.size = (get_frame_size () + 3) & -4;
mask = saved = 0; mask = saved = 0;
/* Interrupt thread does not need to save any register. */
if (!interrupt_thread)
for (regno = 0; regno < 16; regno++) for (regno = 0; regno < 16; regno++)
if (m68k_save_reg (regno, interrupt_handler)) if (m68k_save_reg (regno, interrupt_handler))
{ {
...@@ -695,6 +724,8 @@ m68k_compute_frame_layout (void) ...@@ -695,6 +724,8 @@ m68k_compute_frame_layout (void)
mask = saved = 0; mask = saved = 0;
if (TARGET_HARD_FLOAT) if (TARGET_HARD_FLOAT)
{ {
/* Interrupt thread does not need to save any register. */
if (!interrupt_thread)
for (regno = 16; regno < 24; regno++) for (regno = 16; regno < 24; regno++)
if (m68k_save_reg (regno, interrupt_handler)) if (m68k_save_reg (regno, interrupt_handler))
{ {
...@@ -4211,7 +4242,8 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED, ...@@ -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 saved by the prologue, even if they would normally be
call-clobbered. */ 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]) && !regs_ever_live[new_reg])
return 0; return 0;
......
...@@ -904,7 +904,9 @@ do { if (cc_prev_status.flags & CC_IN_68881) \ ...@@ -904,7 +904,9 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
/* All registers are live on exit from an interrupt routine. */ /* All registers are live on exit from an interrupt routine. */
#define EPILOGUE_USES(REGNO) \ #define EPILOGUE_USES(REGNO) \
(reload_completed && m68k_interrupt_function_p (current_function_decl)) (reload_completed \
&& (m68k_get_function_kind (current_function_decl) \
== m68k_fk_interrupt_handler))
/* Describe how we implement __builtin_eh_return. */ /* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_DATA_REGNO(N) \ #define EH_RETURN_DATA_REGNO(N) \
...@@ -1098,6 +1100,13 @@ enum fpu_type ...@@ -1098,6 +1100,13 @@ enum fpu_type
FPUTYPE_COLDFIRE 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. */ /* Variables in m68k.c; see there for details. */
extern const char *m68k_library_id_string; extern const char *m68k_library_id_string;
extern int m68k_last_compare_had_fp_operands; extern int m68k_last_compare_had_fp_operands;
......
...@@ -6833,15 +6833,23 @@ ...@@ -6833,15 +6833,23 @@
[(return)] [(return)]
"" ""
{ {
if (m68k_interrupt_function_p (current_function_decl)) switch (m68k_get_function_kind (current_function_decl))
{
case m68k_fk_interrupt_handler:
return "rte"; return "rte";
else if (current_function_pops_args)
case m68k_fk_interrupt_thread:
return "sleep";
default:
if (current_function_pops_args)
{ {
operands[0] = GEN_INT (current_function_pops_args); operands[0] = GEN_INT (current_function_pops_args);
return "rtd %0"; return "rtd %0";
} }
else else
return "rts"; return "rts";
}
}) })
(define_insn "*m68k_store_multiple" (define_insn "*m68k_store_multiple"
......
...@@ -2047,6 +2047,14 @@ indicate that the specified function is an interrupt handler. The compiler ...@@ -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 will generate function entry and exit sequences suitable for use in an
interrupt handler when this attribute is present. 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 @item kspisusp
@cindex User stack pointer in interrupts on the Blackfin @cindex User stack pointer in interrupts on the Blackfin
When used together with @code{interrupt_handler}, @code{exception_handler} When used together with @code{interrupt_handler}, @code{exception_handler}
......
2007-05-14 Kazu Hirata <kazu@codesourcery.com>
* 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 <dominiq@lps.ens.fr> 2007-05-13 Dominique d'Humières <dominiq@lps.ens.fr>
* alloc_comp_basics_1.f90: Fix dg directive. * alloc_comp_basics_1.f90: Fix dg directive.
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
# GCC testsuite that uses the `dg.exp' driver. # GCC testsuite that uses the `dg.exp' driver.
# Exit immediately if this isn't an m68k target. # Exit immediately if this isn't an m68k target.
if ![istarget m68k*-*-*] then { if { ![istarget m68k*-*-*] && ![istarget fido*-*-*] } then {
return return
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment