re PR target/18145 (Do not emit __do_copy_data or __do_clear_bss if .data or .bss...
authorGeorg-Johann Lay <avr@gjlay.de>
Wed, 20 Apr 2011 13:38:05 +0000 (13:38 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Wed, 20 Apr 2011 13:38:05 +0000 (13:38 +0000)
PR target/18145

* config/avr/avr.h (TARGET_ASM_INIT_SECTIONS): Delete.
(ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Delete.
(ASM_OUTPUT_ALIGNED_DECL_COMMON): Define.
(ASM_OUTPUT_ALIGNED_DECL_LOCAL): Define.
(TARGET_ASM_NAMED_SECTION): Change to avr_asm_named_section.

* config/avr/avr-protos.h (avr_asm_output_aligned_common):
New prototype.

* config/avr/avr.c (TARGET_ASM_INIT_SECTIONS): Define.
(avr_asm_named_section, avr_asm_output_aligned_common,
avr_output_data_section_asm_op, avr_output_bss_section_asm_op):
New functions to update...
(avr_need_clear_bss_p, avr_need_copy_data_p): ...these new variables.
(avr_asm_init_sections): Overwrite section callbacks for
data_section, bss_section.
(avr_file_start): Move output of __do_copy_data, __do_clear_bss
from here to...
(avr_file_end): ...here.

From-SVN: r172769

gcc/ChangeLog
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.h

index da88769f6ca2b80b1f7b84ffccecfafdfde34497..ca18ffa018c77643c5c54fa252f954f99cfeab09 100644 (file)
@@ -1,3 +1,27 @@
+2011-04-20  Georg-Johann Lay  <avr@gjlay.de>
+
+       PR target/18145
+
+       * config/avr/avr.h (TARGET_ASM_INIT_SECTIONS): Delete.
+       (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Delete.
+       (ASM_OUTPUT_ALIGNED_DECL_COMMON): Define.
+       (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Define.
+       (TARGET_ASM_NAMED_SECTION): Change to avr_asm_named_section.
+
+       * config/avr/avr-protos.h (avr_asm_output_aligned_common):
+       New prototype.
+
+       * config/avr/avr.c (TARGET_ASM_INIT_SECTIONS): Define.
+       (avr_asm_named_section, avr_asm_output_aligned_common,
+       avr_output_data_section_asm_op, avr_output_bss_section_asm_op):
+       New functions to update...
+       (avr_need_clear_bss_p, avr_need_copy_data_p): ...these new variables.
+       (avr_asm_init_sections): Overwrite section callbacks for
+       data_section, bss_section.
+       (avr_file_start): Move output of __do_copy_data, __do_clear_bss
+       from here to...
+       (avr_file_end): ...here.
+
 2011-04-20  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/48695
index b00637e069ef71b74f292922aaeea969984bc6d9..2f3e93d883c01619261aa06880aaf3de65a2043d 100644 (file)
@@ -36,6 +36,7 @@ extern int avr_hard_regno_rename_ok (unsigned int, unsigned int);
 extern rtx avr_return_addr_rtx (int count, rtx tem);
 
 #ifdef TREE_CODE
+extern void avr_asm_output_aligned_decl_common (FILE*, const_tree, const char*, unsigned HOST_WIDE_INT, unsigned int, bool);
 extern void asm_output_external (FILE *file, tree decl, char *name);
 extern int avr_progmem_p (tree decl, tree attributes);
 
index 500a5b287aee0916cb78d85fcc00f2ade7532f4d..9184d6cd963751bede59437427893e6cf11d8010 100644 (file)
@@ -108,6 +108,7 @@ static void avr_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
                                      const_tree, bool);
 static void avr_help (void);
 static bool avr_function_ok_for_sibcall (tree, tree);
+static void avr_asm_named_section (const char *name, unsigned int flags, tree decl);
 
 /* Allocate registers from r25 to r8 for parameters for function calls.  */
 #define FIRST_CUM_REG 26
@@ -132,6 +133,10 @@ const struct mcu_type_s *avr_current_device;
 
 section *progmem_section;
 
+/* To track if code will use .bss and/or .data.  */
+bool avr_need_clear_bss_p = false;
+bool avr_need_copy_data_p = false;
+
 /* AVR attributes.  */
 static const struct attribute_spec avr_attribute_table[] =
 {
@@ -197,6 +202,12 @@ static const struct default_options avr_option_optimization_table[] =
 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
 #undef TARGET_SECTION_TYPE_FLAGS
 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
+
+/* `TARGET_ASM_NAMED_SECTION' must be defined in avr.h.  */
+
+#undef TARGET_ASM_INIT_SECTIONS
+#define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
+
 #undef TARGET_REGISTER_MOVE_COST
 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
 #undef TARGET_MEMORY_MOVE_COST
@@ -5190,7 +5201,60 @@ avr_output_progmem_section_asm_op (const void *arg ATTRIBUTE_UNUSED)
   fprintf (asm_out_file, "\t.p2align 1\n");
 }
 
-/* Implement TARGET_ASM_INIT_SECTIONS.  */
+
+/* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'.  */
+/* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'.  */
+/* Track need of __do_clear_bss.  */
+
+void
+avr_asm_output_aligned_decl_common (FILE * stream, const_tree decl ATTRIBUTE_UNUSED,
+                                    const char *name, unsigned HOST_WIDE_INT size,
+                                    unsigned int align, bool local_p)
+{
+  avr_need_clear_bss_p = true;
+
+  if (local_p)
+    {
+      fputs ("\t.local\t", stream);
+      assemble_name (stream, name);
+      fputs ("\n", stream);
+    }
+  
+  fputs ("\t.comm\t", stream);
+  assemble_name (stream, name);
+  fprintf (stream,
+           "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
+           size, align / BITS_PER_UNIT);
+}
+
+
+/* Unnamed section callback for data_section
+   to track need of __do_copy_data.  */
+
+static void
+avr_output_data_section_asm_op (const void *data)
+{
+  avr_need_copy_data_p = true;
+  
+  /* Dispatch to default.  */
+  output_section_asm_op (data);
+}
+
+
+/* Unnamed section callback for bss_section
+   to track need of __do_clear_bss.  */
+
+static void
+avr_output_bss_section_asm_op (const void *data)
+{
+  avr_need_clear_bss_p = true;
+  
+  /* Dispatch to default.  */
+  output_section_asm_op (data);
+}
+
+
+/* Implement `TARGET_ASM_INIT_SECTIONS'.  */
 
 static void
 avr_asm_init_sections (void)
@@ -5199,6 +5263,27 @@ avr_asm_init_sections (void)
                                         avr_output_progmem_section_asm_op,
                                         NULL);
   readonly_data_section = data_section;
+
+  data_section->unnamed.callback = avr_output_data_section_asm_op;
+  bss_section->unnamed.callback = avr_output_bss_section_asm_op;
+}
+
+
+/* Implement `TARGET_ASM_NAMED_SECTION'.  */
+/* Track need of __do_clear_bss, __do_copy_data for named sections.  */
+
+void
+avr_asm_named_section (const char *name, unsigned int flags, tree decl)
+{
+  if (!avr_need_copy_data_p)
+    avr_need_copy_data_p = (0 == strncmp (name, ".data", 5)
+                            || 0 == strncmp (name, ".rodata", 7)
+                            || 0 == strncmp (name, ".gnu.linkonce.d", 15));
+  
+  if (!avr_need_clear_bss_p)
+    avr_need_clear_bss_p = (0 == strncmp (name, ".bss", 4));
+  
+  default_elf_asm_named_section (name, flags, decl);
 }
 
 static unsigned int
@@ -5219,6 +5304,8 @@ avr_section_type_flags (tree decl, const char *name, int reloc)
   return flags;
 }
 
+
+/* Implement `TARGET_ASM_FILE_START'.  */
 /* Outputs some appropriate text to go at the start of an assembler
    file.  */
 
@@ -5237,20 +5324,27 @@ avr_file_start (void)
   
   fputs ("__tmp_reg__ = 0\n" 
          "__zero_reg__ = 1\n", asm_out_file);
-
-  /* FIXME: output these only if there is anything in the .data / .bss
-     sections - some code size could be saved by not linking in the
-     initialization code from libgcc if one or both sections are empty.  */
-  fputs ("\t.global __do_copy_data\n", asm_out_file);
-  fputs ("\t.global __do_clear_bss\n", asm_out_file);
 }
 
+
+/* Implement `TARGET_ASM_FILE_END'.  */
 /* Outputs to the stdio stream FILE some
    appropriate text to go at the end of an assembler file.  */
 
 static void
 avr_file_end (void)
 {
+  /* Output these only if there is anything in the
+     .data* / .rodata* / .gnu.linkonce.* resp. .bss*
+     input section(s) - some code size can be saved by not
+     linking in the initialization code from libgcc if resp.
+     sections are empty.  */
+
+  if (avr_need_copy_data_p)
+    fputs (".global __do_copy_data\n", asm_out_file);
+
+  if (avr_need_clear_bss_p)
+    fputs (".global __do_clear_bss\n", asm_out_file);
 }
 
 /* Choose the order in which to allocate hard registers for
index aaf29dc31c5d418b90a724b491c395aef7160691..b0c1b49486ec28ebd577a2bcdab7e3d42063bdf9 100644 (file)
@@ -460,29 +460,20 @@ do {                                                                          \
 #define ASM_APP_OFF "/* #NOAPP */\n"
 
 /* Switch into a generic section.  */
-#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-#define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
+#define TARGET_ASM_NAMED_SECTION avr_asm_named_section
 
 #define ASM_OUTPUT_ASCII(FILE, P, SIZE)         gas_output_ascii (FILE,P,SIZE)
 
 #define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == '\n' || ((C) == '$'))
 
-#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED)                    \
-do {                                                                      \
-     fputs ("\t.comm ", (STREAM));                                        \
-     assemble_name ((STREAM), (NAME));                                    \
-     fprintf ((STREAM), ",%lu,1\n", (unsigned long)(SIZE));               \
-} while (0)
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN) \
+  avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, false)
 
 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
   asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
 
-#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED)                  \
-do {                                                                   \
-     fputs ("\t.lcomm ", (STREAM));                                    \
-     assemble_name ((STREAM), (NAME));                                 \
-     fprintf ((STREAM), ",%d\n", (int)(SIZE));                         \
-} while (0)
+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN)  \
+  avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, true)
 
 #undef TYPE_ASM_OP
 #undef SIZE_ASM_OP