aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Carrez <stcarrez@nerim.fr>2003-03-22 00:25:21 +0100
committerStephane Carrez <ciceron@gcc.gnu.org>2003-03-22 00:25:21 +0100
commit639a8102c038087dc5c48115522a5e1f9259d38e (patch)
treef9e71f168442d54c90c2837ecd5516d584bd85d2
parentd7394366f2888097b0cb0cc38fc865d78e35b848 (diff)
downloadgcc-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/ChangeLog22
-rw-r--r--gcc/config/m68hc11/m68hc11-protos.h3
-rw-r--r--gcc/config/m68hc11/m68hc11.c67
-rw-r--r--gcc/config/m68hc11/m68hc11.h2
-rw-r--r--gcc/config/m68hc11/m68hc11.md22
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
{