re PR target/7525 ([ARM/Thumb] long calls stubs only in one code section, cannot...
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 14 Jan 2005 13:58:40 +0000 (13:58 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 14 Jan 2005 13:58:40 +0000 (13:58 +0000)
PR target/7525
* arm.h (struct machine_function): Add call_via field.
(thumb_call_via_label): Declare.
* arm.c (thumb_call_via_label): New variable.
(thumb_call_reg_needed): New variable.
(arm_output_function_epilogue): For Thumb code, output any per-function
call-indirect trampolines.
(thumb_call_via_reg): New function.
(arm_file_end): New function.
(TARGET_ASM_FILE_END): Call arm_file_end.
(aof_file_end): Likewise.
* arm-protos.h (thumb_call_via_reg): Declare.
* arm.md (call_reg_thumb, call_value_reg_thumb): Call
thumb_call_via_reg in normal case.

From-SVN: r93641

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

index 9179625..7233c29 100644 (file)
@@ -1,3 +1,20 @@
+2005-01-14  Richard Earnshaw  <rearnsha@arm.com>
+
+       PR target/7525
+       * arm.h (struct machine_function): Add call_via field.
+       (thumb_call_via_label): Declare.
+       * arm.c (thumb_call_via_label): New variable.
+       (thumb_call_reg_needed): New variable.
+       (arm_output_function_epilogue): For Thumb code, output any per-function
+       call-indirect trampolines.
+       (thumb_call_via_reg): New function.
+       (arm_file_end): New function.
+       (TARGET_ASM_FILE_END): Call arm_file_end.
+       (aof_file_end): Likewise.
+       * arm-protos.h (thumb_call_via_reg): Declare.
+       * arm.md (call_reg_thumb, call_value_reg_thumb): Call 
+       thumb_call_via_reg in normal case.
+
 2005-01-14  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/19084
index c46ce82..99c7923 100644 (file)
@@ -1,5 +1,5 @@
 /* Prototypes for exported functions defined in arm.c and pe.c
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    Contributed by Richard Earnshaw (rearnsha@arm.com)
    Minor hacks by Nick Clifton (nickc@cygnus.com)
@@ -150,6 +150,7 @@ extern int thumb_shiftable_const (unsigned HOST_WIDE_INT);
 extern void thumb_final_prescan_insn (rtx);
 extern const char *thumb_load_double_from_address (rtx *);
 extern const char *thumb_output_move_mem_multiple (int, rtx *);
+extern const char *thumb_call_via_reg (rtx);
 extern void thumb_expand_movmemqi (rtx *);
 extern rtx *thumb_legitimize_pic_address (rtx, enum machine_mode, rtx);
 extern int thumb_go_if_legitimate_address (enum machine_mode, rtx);
index 6582021..649fde3 100644 (file)
@@ -1,6 +1,6 @@
 /* Output routines for GCC for ARM.
    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004  Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005  Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
    More major hacks by Richard Earnshaw (rearnsha@arm.com).
@@ -153,6 +153,9 @@ static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
 #ifndef ARM_PE
 static void arm_encode_section_info (tree, rtx, int);
 #endif
+
+static void arm_file_end (void);
+
 #ifdef AOF_ASSEMBLER
 static void aof_globalize_label (FILE *, const char *);
 static void aof_dump_imports (FILE *);
@@ -188,6 +191,9 @@ static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
 #undef  TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE arm_attribute_table
 
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END arm_file_end
+
 #ifdef AOF_ASSEMBLER
 #undef  TARGET_ASM_BYTE_OP
 #define TARGET_ASM_BYTE_OP "\tDCB\t"
@@ -366,6 +372,10 @@ const char * target_abi_name = NULL;
 const char * structure_size_string = NULL;
 int    arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
 
+/* Used for Thumb call_via trampolines.  */
+rtx thumb_call_via_label[13];
+static int thumb_call_reg_needed;
+
 /* Bit values used to identify processor capabilities.  */
 #define FL_CO_PROC    (1 << 0)        /* Has external co-processor bus */
 #define FL_ARCH3M     (1 << 1)        /* Extended multiply */
@@ -9600,6 +9610,23 @@ arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
 
   if (TARGET_THUMB)
     {
+      int regno;
+
+      /* Emit any call-via-reg trampolines that are needed for v4t support
+        of call_reg and call_value_reg type insns.  */
+      for (regno = 0; regno < SP_REGNUM; regno++)
+       {
+         rtx label = cfun->machine->call_via[regno];
+
+         if (label != NULL)
+           {
+             function_section (current_function_decl);
+             targetm.asm_out.internal_label (asm_out_file, "L",
+                                             CODE_LABEL_NUMBER (label));
+             asm_fprintf (asm_out_file, "\tbx\t%r\n", regno);
+           }
+       }
+
       /* ??? Probably not safe to set this here, since it assumes that a
         function will be emitted as assembly immediately after we generate
         RTL for it.  This does not happen for inline functions.  */
@@ -13652,6 +13679,37 @@ thumb_output_move_mem_multiple (int n, rtx *operands)
   return "";
 }
 
+/* Output a call-via instruction for thumb state.  */
+const char *
+thumb_call_via_reg (rtx reg)
+{
+  int regno = REGNO (reg);
+  rtx *labelp;
+
+  gcc_assert (regno < SP_REGNUM);
+
+  /* If we are in the normal text section we can use a single instance
+     per compilation unit.  If we are doing function sections, then we need
+     an entry per section, since we can't rely on reachability.  */
+  if (in_text_section ())
+    {
+      thumb_call_reg_needed = 1;
+
+      if (thumb_call_via_label[regno] == NULL)
+       thumb_call_via_label[regno] = gen_label_rtx ();
+      labelp = thumb_call_via_label + regno;
+    }
+  else
+    {
+      if (cfun->machine->call_via[regno] == NULL)
+       cfun->machine->call_via[regno] = gen_label_rtx ();
+      labelp = cfun->machine->call_via + regno;
+    }
+
+  output_asm_insn ("bl\t%a0", labelp);
+  return "";
+}
+
 /* Routines for generating rtl.  */
 void
 thumb_expand_movmemqi (rtx *operands)
@@ -13762,6 +13820,31 @@ arm_asm_output_labelref (FILE *stream, const char *name)
     asm_fprintf (stream, "%U%s", name);
 }
 
+static void
+arm_file_end (void)
+{
+  int regno;
+
+  if (! thumb_call_reg_needed)
+    return;
+
+  text_section ();
+  asm_fprintf (asm_out_file, "\t.code 16\n");
+  ASM_OUTPUT_ALIGN (asm_out_file, 1);
+
+  for (regno = 0; regno < SP_REGNUM; regno++)
+    {
+      rtx label = thumb_call_via_label[regno];
+
+      if (label != 0)
+       {
+         targetm.asm_out.internal_label (asm_out_file, "L",
+                                         CODE_LABEL_NUMBER (label));
+         asm_fprintf (asm_out_file, "\tbx\t%r\n", regno);
+       }
+    }
+}
+
 rtx aof_pic_label;
 
 #ifdef AOF_ASSEMBLER
@@ -13958,6 +14041,7 @@ aof_file_end (void)
 {
   if (flag_pic)
     aof_dump_pic_table (asm_out_file);
+  arm_file_end ();
   aof_dump_imports (asm_out_file);
   fputs ("\tEND\n", asm_out_file);
 }
index 2278731..9e84626 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler, for ARM.
    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
    More major hacks by Richard Earnshaw (rearnsha@arm.com)
@@ -1703,9 +1703,16 @@ typedef struct machine_function GTY(())
   /* Records if sibcalls are blocked because an argument
      register is needed to preserve stack alignment.  */
   int sibcall_blocked;
+  /* Labels for per-function Thumb call-via stubs.  One per potential calling
+     register.  We can never call via SP, LR or PC.  */
+  rtx call_via[13];
 }
 machine_function;
 
+/* As in the machine_function, a global set of call-via labels, for code 
+   that is in text_section().  */
+extern GTY(()) rtx thumb_call_via_label[13];
+
 /* A C type for declaring a variable that is used as the first argument of
    `FUNCTION_ARG' and other related values.  For some target machines, the
    type `int' suffices and can hold the number of bytes of argument so far.  */
index 3255f05..7d8075f 100644 (file)
@@ -1,6 +1,6 @@
 ;;- Machine description for ARM for GNU compiler
 ;;  Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
-;;  2001, 2002, 2003 2004  Free Software Foundation, Inc.
+;;  2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
 ;;  and Martin Simmons (@harleqn.co.uk).
 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
   "*
   {
     if (!TARGET_CALLER_INTERWORKING)
-      return \"bl\\t%__call_via_%0\";
+      return thumb_call_via_reg (operands[0]);
     else if (operands[1] == const0_rtx)
       return \"bl\\t%__interwork_call_via_%0\";
     else if (frame_pointer_needed)
   "*
   {
     if (!TARGET_CALLER_INTERWORKING)
-      return \"bl\\t%__call_via_%1\";
+      return thumb_call_via_reg (operands[1]);
     else if (operands[2] == const0_rtx)
       return \"bl\\t%__interwork_call_via_%1\";
     else if (frame_pointer_needed)