Commit 639a8102 by Stephane Carrez Committed by Stephane Carrez

m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Fix typo in writing .interrupt command.

	* config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Fix typo in
	writing .interrupt command.
	* config/m68hc11/m68hc11.md ("call"): Look at the symbol to see
	if it's a far or near function.
	("call_value"): Likewise.
	* config/m68hc11/m68hc11.c (m68hc11_attribute_table): Add far and
	near attributes.
	(m68hc11_handle_fntype_attribute): Accept attributes on methods.
	(m68hc11_override_options): Ignore -mlong-calls for 68HC11.
	(m68hc11_initial_elimination_offset): Set current_function_far
	according to attributes.
	(expand_prologue): Likewise.
	(trap_handler_symbol): New global to keep track of trap handlers.
	(m68hc11_encode_section_info): Mark symbol as far if needed; set
	trap symbol.
	(m68hc11_is_far_symbol): New function.
	(m68hc11_is_trap_symbol): New function.
	* config/m68hc11/m68hc11-protos.h (m68hc11_is_far_symbol): Declare.
	(m68hc11_is_trap_symbol): Declare.

From-SVN: r64685
parent d7394366
2003-03-22 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Fix typo in
writing .interrupt command.
* config/m68hc11/m68hc11.md ("call"): Look at the symbol to see
if it's a far or near function.
("call_value"): Likewise.
* config/m68hc11/m68hc11.c (m68hc11_attribute_table): Add far and
near attributes.
(m68hc11_handle_fntype_attribute): Accept attributes on methods.
(m68hc11_override_options): Ignore -mlong-calls for 68HC11.
(m68hc11_initial_elimination_offset): Set current_function_far
according to attributes.
(expand_prologue): Likewise.
(trap_handler_symbol): New global to keep track of trap handlers.
(m68hc11_encode_section_info): Mark symbol as far if needed; set
trap symbol.
(m68hc11_is_far_symbol): New function.
(m68hc11_is_trap_symbol): New function.
* config/m68hc11/m68hc11-protos.h (m68hc11_is_far_symbol): Declare.
(m68hc11_is_trap_symbol): Declare.
Fri Mar 21 23:12:33 CET 2003 Jan Hubicka <jh@suse.cz> Fri Mar 21 23:12:33 CET 2003 Jan Hubicka <jh@suse.cz>
* i386.c (ix86_compute_frame_layout): Recompute fast prologues * i386.c (ix86_compute_frame_layout): Recompute fast prologues
......
...@@ -141,6 +141,9 @@ extern int m68hc11_function_arg_padding PARAMS((enum machine_mode, tree)); ...@@ -141,6 +141,9 @@ extern int m68hc11_function_arg_padding PARAMS((enum machine_mode, tree));
extern void m68hc11_function_epilogue PARAMS((FILE*,int)); extern void m68hc11_function_epilogue PARAMS((FILE*,int));
extern int m68hc11_is_far_symbol PARAMS((rtx));
extern int m68hc11_is_trap_symbol PARAMS((rtx));
#endif /* TREE_CODE */ #endif /* TREE_CODE */
extern HOST_WIDE_INT m68hc11_min_offset; extern HOST_WIDE_INT m68hc11_min_offset;
......
...@@ -276,6 +276,7 @@ m68hc11_override_options () ...@@ -276,6 +276,7 @@ m68hc11_override_options ()
m68hc11_tmp_regs_class = D_REGS; m68hc11_tmp_regs_class = D_REGS;
if (m68hc11_soft_reg_count == 0 && !TARGET_M6812) if (m68hc11_soft_reg_count == 0 && !TARGET_M6812)
m68hc11_soft_reg_count = "4"; m68hc11_soft_reg_count = "4";
target_flags &= ~MASK_LONG_CALLS;
} }
/* Configure for a 68hc12 processor. */ /* Configure for a 68hc12 processor. */
...@@ -1232,9 +1233,16 @@ const struct attribute_spec m68hc11_attribute_table[] = ...@@ -1232,9 +1233,16 @@ const struct attribute_spec m68hc11_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", 0, 0, false, true, true, m68hc11_handle_fntype_attribute }, { "interrupt", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
{ "trap", 0, 0, false, true, true, m68hc11_handle_fntype_attribute }, { "trap", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
{ "far", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
{ "near", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
{ NULL, 0, 0, false, false, false, NULL } { NULL, 0, 0, false, false, false, NULL }
}; };
/* Keep track of the symbol which has a `trap' attribute and which uses
the `swi' calling convention. Since there is only one trap, we only
record one such symbol. If there are several, a warning is reported. */
static rtx trap_handler_symbol = 0;
/* Handle an attribute requiring a FUNCTION_TYPE, FIELD_DECL or TYPE_DECL; /* Handle an attribute requiring a FUNCTION_TYPE, FIELD_DECL or TYPE_DECL;
arguments as in struct attribute_spec.handler. */ arguments as in struct attribute_spec.handler. */
static tree static tree
...@@ -1246,6 +1254,7 @@ m68hc11_handle_fntype_attribute (node, name, args, flags, no_add_attrs) ...@@ -1246,6 +1254,7 @@ m68hc11_handle_fntype_attribute (node, name, args, flags, no_add_attrs)
bool *no_add_attrs; bool *no_add_attrs;
{ {
if (TREE_CODE (*node) != FUNCTION_TYPE if (TREE_CODE (*node) != FUNCTION_TYPE
&& TREE_CODE (*node) != METHOD_TYPE
&& TREE_CODE (*node) != FIELD_DECL && TREE_CODE (*node) != FIELD_DECL
&& TREE_CODE (*node) != TYPE_DECL) && TREE_CODE (*node) != TYPE_DECL)
{ {
...@@ -1268,16 +1277,56 @@ m68hc11_encode_section_info (decl, first) ...@@ -1268,16 +1277,56 @@ m68hc11_encode_section_info (decl, first)
{ {
tree func_attr; tree func_attr;
int trap_handler; int trap_handler;
int is_far = 0;
rtx rtl; rtx rtl;
if (TREE_CODE (decl) != FUNCTION_DECL) if (TREE_CODE (decl) != FUNCTION_DECL)
return; return;
rtl = DECL_RTL (decl); rtl = DECL_RTL (decl);
func_attr = TYPE_ATTRIBUTES (TREE_TYPE (decl)); func_attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
if (lookup_attribute ("far", func_attr) != NULL_TREE)
is_far = 1;
else if (lookup_attribute ("near", func_attr) == NULL_TREE)
is_far = TARGET_LONG_CALLS != 0;
trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE; trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE;
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = trap_handler; if (trap_handler && is_far)
{
warning ("`trap' and `far' attributes are not compatible, ignoring `far'");
trap_handler = 0;
}
if (trap_handler)
{
if (trap_handler_symbol != 0)
warning ("`trap' attribute is already used");
else
trap_handler_symbol = XEXP (rtl, 0);
}
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = is_far;
}
int
m68hc11_is_far_symbol (sym)
rtx sym;
{
if (GET_CODE (sym) == MEM)
sym = XEXP (sym, 0);
return SYMBOL_REF_FLAG (sym);
}
int
m68hc11_is_trap_symbol (sym)
rtx sym;
{
if (GET_CODE (sym) == MEM)
sym = XEXP (sym, 0);
return trap_handler_symbol != 0 && rtx_equal_p (trap_handler_symbol, sym);
} }
...@@ -1317,6 +1366,14 @@ m68hc11_initial_elimination_offset (from, to) ...@@ -1317,6 +1366,14 @@ m68hc11_initial_elimination_offset (from, to)
/* For a trap handler, we must take into account the registers which /* For a trap handler, we must take into account the registers which
are pushed on the stack during the trap (except the PC). */ are pushed on the stack during the trap (except the PC). */
func_attr = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)); func_attr = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
if (lookup_attribute ("far", func_attr) != 0)
current_function_far = 1;
else if (lookup_attribute ("near", func_attr) != 0)
current_function_far = 0;
else
current_function_far = TARGET_LONG_CALLS != 0;
trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE; trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE;
if (trap_handler && from == ARG_POINTER_REGNUM) if (trap_handler && from == ARG_POINTER_REGNUM)
size = 7; size = 7;
...@@ -1611,6 +1668,12 @@ expand_prologue () ...@@ -1611,6 +1668,12 @@ expand_prologue ()
current_function_interrupt = lookup_attribute ("interrupt", current_function_interrupt = lookup_attribute ("interrupt",
func_attr) != NULL_TREE; func_attr) != NULL_TREE;
current_function_trap = lookup_attribute ("trap", func_attr) != NULL_TREE; current_function_trap = lookup_attribute ("trap", func_attr) != NULL_TREE;
if (lookup_attribute ("far", func_attr) != NULL_TREE)
current_function_far = 1;
else if (lookup_attribute ("near", func_attr) != NULL_TREE)
current_function_far = 0;
else
current_function_far = TARGET_LONG_CALLS != 0;
/* Get the scratch register to build the frame and push registers. /* Get the scratch register to build the frame and push registers.
If the first argument is a 32-bit quantity, the D+X registers If the first argument is a 32-bit quantity, the D+X registers
......
...@@ -1560,7 +1560,7 @@ do { \ ...@@ -1560,7 +1560,7 @@ do { \
{ \ { \
fprintf (FILE, "\t.interrupt\t"); \ fprintf (FILE, "\t.interrupt\t"); \
assemble_name (FILE, NAME); \ assemble_name (FILE, NAME); \
putc ('\b', FILE); \ putc ('\n', FILE); \
} \ } \
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
ASM_OUTPUT_LABEL(FILE, NAME); \ ASM_OUTPUT_LABEL(FILE, NAME); \
......
...@@ -6390,14 +6390,17 @@ ...@@ -6390,14 +6390,17 @@
"" ""
"* "*
{ {
int far_call = current_function_far;
if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
{ {
if (SYMBOL_REF_FLAG (XEXP (operands[0], 0)) == 1) if (m68hc11_is_far_symbol (operands[0]))
{
output_asm_insn (\"call\\t%0\", operands);
return \"\";
}
if (m68hc11_is_trap_symbol (operands[0]))
return \"swi\"; return \"swi\";
else else
return far_call ? \"call\\t%0\" : \"bsr\\t%0\"; return \"bsr\\t%0\";
} }
else else
{ {
...@@ -6412,14 +6415,17 @@ ...@@ -6412,14 +6415,17 @@
"" ""
"* "*
{ {
int far_call = current_function_far;
if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
{ {
if (SYMBOL_REF_FLAG (XEXP (operands[1], 0)) == 1) if (m68hc11_is_far_symbol (operands[1]))
{
output_asm_insn (\"call\\t%1\", operands);
return \"\";
}
if (m68hc11_is_trap_symbol (operands[0]))
return \"swi\"; return \"swi\";
else else
return far_call ? \"call\\t%1\" : \"bsr\\t%1\"; return \"bsr\\t%1\";
} }
else else
{ {
......
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