OSDN Git Service

* config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Fix typo in
authorciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Mar 2003 23:25:21 +0000 (23:25 +0000)
committerciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Mar 2003 23:25:21 +0000 (23:25 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@64685 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/m68hc11/m68hc11-protos.h
gcc/config/m68hc11/m68hc11.c
gcc/config/m68hc11/m68hc11.h
gcc/config/m68hc11/m68hc11.md

index 29d1c3c..c07cfb9 100644 (file)
@@ -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
index 01352b3..20b5ae0 100644 (file)
@@ -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;
index 0794a3e..1a0cd80 100644 (file)
@@ -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);
 }
 \f
 
@@ -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
index 95d3f60..4ba1389 100644 (file)
@@ -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);                    \
index 99c11b6..7b202c4 100644 (file)
   ""
  "*
 {
-  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
     {
   ""
  "*
 {
-  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
     {