summaryrefslogtreecommitdiff
path: root/devel/avr-gcc/files/patch-502-gcc-4.5.1-bug-18145-v4
blob: 1115f35d404e97aa678a8e048a38083c553bf65e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
--- gcc/config/avr/avr.c	2011-06-09 15:41:06.000000000 -0500
+++ gcc/config/avr/avr.c	2011-06-09 15:46:03.000000000 -0500
@@ -81,6 +81,12 @@ static rtx avr_function_value (const_tre
 static void avr_insert_attributes (tree, tree *);
 static void avr_asm_init_sections (void);
 static unsigned int avr_section_type_flags (tree, const char *, int);
+static void avr_asm_named_section (const char *name, unsigned int flags, tree decl);
+/* Track if code will use .bss and/or .data */
+static int avr_need_clear_bss_p = 0;
+static int avr_need_copy_data_p = 0;
+static void avr_output_data_section_asm_op (const void*);
+static void avr_output_bss_section_asm_op (const void*);
 
 static void avr_reorg (void);
 static void avr_asm_out_ctor (rtx, int);
@@ -6102,6 +6108,54 @@ avr_output_progmem_section_asm_op (const
   fprintf (asm_out_file, "\t.p2align 1\n");
 }
 
+/* ASM_OUTPUT_COMMON */
+/* Track need of __do_clear_bss */
+
+void
+avr_asm_output_common (FILE *stream, const char *name,
+                       unsigned HOST_WIDE_INT size,
+                       unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
+{
+    avr_need_clear_bss_p = 1;
+    fputs ("\t.comm ", stream);
+    assemble_name (stream, name);
+    fprintf (stream, ",%lu,1\n", (unsigned long) size);  
+}
+
+/* ASM_OUTPUT_LOCAL */
+/* Track need of __do_clear_bss */
+
+void
+avr_asm_output_local (FILE *stream, const char *name,
+                      unsigned HOST_WIDE_INT size,
+                      unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
+{                                                    
+    avr_need_clear_bss_p = 1;                           
+    fputs ("\t.lcomm ", stream);                      
+    assemble_name (stream, name);                   
+    fprintf (stream, ",%d\n", (int) size);           
+}
+
+/* Unnamed section callback to track need of __do_copy_data */
+
+static void
+avr_output_data_section_asm_op (const void *data)
+{
+    avr_need_copy_data_p = 1;
+    /* Dispatch to default */
+    output_section_asm_op (data);
+}
+
+/* Unnamed section callback to track need of __do_clear_bss */
+
+static void
+avr_output_bss_section_asm_op (const void *data)
+{
+    avr_need_clear_bss_p = 1;
+    /* Dispatch to default */
+    output_section_asm_op (data);
+}
+
 /* Implement TARGET_ASM_INIT_SECTIONS.  */
 
 static void
@@ -6111,6 +6165,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;
+}
+
+/* TARGET_ASM_NAMED_SECTION */
+/* Track need of __do_clear_bss, __do_copy_data for named sections */
+
+static 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.", 14));
+    
+    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
@@ -6152,12 +6227,6 @@ avr_file_start (void)
   AVR_TINY ? fputs ("__tmp_reg__ = 16\n" 
 		            "__zero_reg__ = 17\n", asm_out_file) : 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);
 }
 
 /* Outputs to the stdio stream FILE some
@@ -6166,6 +6235,16 @@ avr_file_start (void)
 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
diff -Naurp gcc/config/avr/avr.h gcc/config/avr/avr.h
--- gcc/config/avr/avr.h	2011-06-09 14:30:33.000000000 -0500
+++ gcc/config/avr/avr.h	2011-06-09 15:46:03.000000000 -0500
@@ -562,7 +562,7 @@ 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_NAMED_SECTION avr_asm_named_section
 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
 
 #define ASM_OUTPUT_ASCII(FILE, P, SIZE)	 gas_output_ascii (FILE,P,SIZE)
@@ -570,21 +570,13 @@ do {									    \
 #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)
+        avr_asm_output_common (STREAM, NAME, SIZE, ROUNDED)
 
 #define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ROUNDED)			\
   asm_output_bss ((FILE), (DECL), (NAME), (SIZE), (ROUNDED))
 
 #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)
+        avr_asm_output_local (STREAM, NAME, SIZE, ROUNDED)
 
 #undef TYPE_ASM_OP
 #undef SIZE_ASM_OP
diff -Naurp gcc/config/avr/avr-protos.h gcc/config/avr/avr-protos.h
--- gcc/config/avr/avr-protos.h	2011-06-09 14:30:33.000000000 -0500
+++ gcc/config/avr/avr-protos.h	2011-06-09 15:46:03.000000000 -0500
@@ -35,6 +35,9 @@ extern int avr_simple_epilogue (void);
 extern void gas_output_limited_string (FILE *file, const char *str);
 extern void gas_output_ascii (FILE *file, const char *str, size_t length);
 extern int avr_hard_regno_rename_ok (unsigned int, unsigned int);
+extern void avr_asm_output_common (FILE *stream, const char *name, unsigned HOST_WIDE_INT size, unsigned HOST_WIDE_INT rounded);
+extern void avr_asm_output_local (FILE *stream, const char *name, unsigned HOST_WIDE_INT size, unsigned HOST_WIDE_INT rounded);
+  
 extern rtx avr_return_addr_rtx (int count, const_rtx tem);
 
 #ifdef TREE_CODE