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
This commit is contained in:
parent
ab6bd6931e
commit
a424273720
|
@ -1,3 +1,24 @@
|
|||
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>
|
||||
|
||||
Fix PR tree-optimization/31911
|
||||
|
|
|
@ -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[]);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
|
||||
* alloc_comp_basics_1.f90: Fix dg directive.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue