diff options
author | Stephane Carrez <stcarrez@nerim.fr> | 2003-03-22 00:25:21 +0100 |
---|---|---|
committer | Stephane Carrez <ciceron@gcc.gnu.org> | 2003-03-22 00:25:21 +0100 |
commit | 639a8102c038087dc5c48115522a5e1f9259d38e (patch) | |
tree | f9e71f168442d54c90c2837ecd5516d584bd85d2 | |
parent | d7394366f2888097b0cb0cc38fc865d78e35b848 (diff) | |
download | gcc-639a8102c038087dc5c48115522a5e1f9259d38e.zip gcc-639a8102c038087dc5c48115522a5e1f9259d38e.tar.gz gcc-639a8102c038087dc5c48115522a5e1f9259d38e.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/config/m68hc11/m68hc11-protos.h | 3 | ||||
-rw-r--r-- | gcc/config/m68hc11/m68hc11.c | 67 | ||||
-rw-r--r-- | gcc/config/m68hc11/m68hc11.h | 2 | ||||
-rw-r--r-- | gcc/config/m68hc11/m68hc11.md | 22 |
5 files changed, 105 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 29d1c3c..c07cfb9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +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> * i386.c (ix86_compute_frame_layout): Recompute fast prologues diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h index 01352b3..20b5ae0 100644 --- a/gcc/config/m68hc11/m68hc11-protos.h +++ b/gcc/config/m68hc11/m68hc11-protos.h @@ -141,6 +141,9 @@ extern int m68hc11_function_arg_padding PARAMS((enum machine_mode, tree)); 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 */ extern HOST_WIDE_INT m68hc11_min_offset; diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c index 0794a3e..1a0cd80 100644 --- a/gcc/config/m68hc11/m68hc11.c +++ b/gcc/config/m68hc11/m68hc11.c @@ -276,6 +276,7 @@ m68hc11_override_options () m68hc11_tmp_regs_class = D_REGS; if (m68hc11_soft_reg_count == 0 && !TARGET_M6812) m68hc11_soft_reg_count = "4"; + target_flags &= ~MASK_LONG_CALLS; } /* Configure for a 68hc12 processor. */ @@ -1232,9 +1233,16 @@ const struct attribute_spec m68hc11_attribute_table[] = /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ { "interrupt", 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 } }; +/* 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; arguments as in struct attribute_spec.handler. */ static tree @@ -1246,6 +1254,7 @@ m68hc11_handle_fntype_attribute (node, name, args, flags, no_add_attrs) bool *no_add_attrs; { if (TREE_CODE (*node) != FUNCTION_TYPE + && TREE_CODE (*node) != METHOD_TYPE && TREE_CODE (*node) != FIELD_DECL && TREE_CODE (*node) != TYPE_DECL) { @@ -1268,16 +1277,56 @@ m68hc11_encode_section_info (decl, first) { tree func_attr; int trap_handler; + int is_far = 0; rtx rtl; - + if (TREE_CODE (decl) != FUNCTION_DECL) return; rtl = DECL_RTL (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; - 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) /* For a trap handler, we must take into account the registers which are pushed on the stack during the trap (except the PC). */ 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; if (trap_handler && from == ARG_POINTER_REGNUM) size = 7; @@ -1611,6 +1668,12 @@ expand_prologue () current_function_interrupt = lookup_attribute ("interrupt", 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. If the first argument is a 32-bit quantity, the D+X registers diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h index 95d3f60..4ba1389 100644 --- a/gcc/config/m68hc11/m68hc11.h +++ b/gcc/config/m68hc11/m68hc11.h @@ -1560,7 +1560,7 @@ do { \ { \ fprintf (FILE, "\t.interrupt\t"); \ assemble_name (FILE, NAME); \ - putc ('\b', FILE); \ + putc ('\n', FILE); \ } \ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ ASM_OUTPUT_LABEL(FILE, NAME); \ diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md index 99c11b6..7b202c4 100644 --- a/gcc/config/m68hc11/m68hc11.md +++ b/gcc/config/m68hc11/m68hc11.md @@ -6390,14 +6390,17 @@ "" "* { - int far_call = current_function_far; - 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\"; else - return far_call ? \"call\\t%0\" : \"bsr\\t%0\"; + return \"bsr\\t%0\"; } else { @@ -6412,14 +6415,17 @@ "" "* { - int far_call = current_function_far; - 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\"; else - return far_call ? \"call\\t%1\" : \"bsr\\t%1\"; + return \"bsr\\t%1\"; } else { |