updated Header
[libfirm] / ir / be / begnuas.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * Dumps global variables and constants as gas assembler.
22  * @author Christian Wuerdig, Matthias Braun
23  * @date 04.11.2005
24  * @version $Id$
25  */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "begnuas.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <assert.h>
36
37 #include "obst.h"
38 #include "tv.h"
39 #include "irnode.h"
40 #include "entity.h"
41 #include "irprog.h"
42 #include "pdeq.h"
43 #include "error.h"
44
45 #include "be_t.h"
46 #include "beemitter.h"
47 #include "be_dbgout.h"
48
49 typedef struct obstack obstack_t;
50
51 /** by default, we generate assembler code for the Linux gas */
52 be_gas_flavour_t be_gas_flavour = GAS_FLAVOUR_NORMAL;
53
54 /**
55  * Return the pseudo-instruction to be issued for a section switch
56  * depending on the current flavour.
57  *
58  * @param section  the section to switch to
59  *
60  * @return  the pseudo-instruction
61  */
62 static const char *get_section_name(be_gas_section_t section) {
63         static const char *text[GAS_FLAVOUR_MAX][GAS_SECTION_MAX] = {
64                 {
65                         ".section\t.text",
66                         ".section\t.data",
67                         ".section\t.rodata",
68                         ".section\t.bss",
69                         ".section\t.tbss,\"awT\",@nobits",
70                         ".section\t.ctors,\"aw\",@progbits"
71                 },
72                 {
73                         ".section\t.text",
74                         ".section\t.data",
75                         ".section .rdata,\"dr\"",
76                         ".section\t.bss",
77                         ".section\t.tbss,\"awT\",@nobits",
78                         ".section\t.ctors,\"aw\",@progbits"
79                 }
80         };
81
82         assert(be_gas_flavour >= 0 && be_gas_flavour < GAS_FLAVOUR_MAX);
83         assert(section >= 0 && section < GAS_SECTION_MAX);
84         return text[be_gas_flavour][section];
85 }
86
87 /**
88  * Emit necessary code to switch to a section.
89  *
90  * @param env      the emitter environment
91  * @param section  the section to switch to
92  */
93 void be_gas_emit_switch_section(be_emit_env_t *env, be_gas_section_t section) {
94         be_emit_char(env, '\t');
95         be_emit_string(env, get_section_name(section));
96         be_emit_char(env, '\n');
97         be_emit_write_line(env);
98 }
99
100 typedef struct _ia32_decl_env {
101         obstack_t *rodata_obst;
102         obstack_t *data_obst;
103         obstack_t *bss_obst;
104         obstack_t *ctor_obst;
105         const be_main_env_t *main_env;
106         waitq     *worklist;
107 } ia32_decl_env_t;
108
109 /************************************************************************/
110
111 /**
112  * output a tarval
113  */
114 static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes)
115 {
116         switch (bytes) {
117
118         case 1:
119                 obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
120                 break;
121
122         case 2:
123                 obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
124                 break;
125
126         case 4:
127                 obstack_printf(obst, "0x%02x%02x%02x%02x",
128                         get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
129                 break;
130
131         case 8:
132                 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
133                         get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
134                         get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
135                 break;
136
137         case 10:
138         case 12:
139                 break;
140
141         case 16:
142                 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x"
143                                                "%02x%02x%02x%02x%02x%02x%02x%02x",
144                         get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 16),
145                         get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
146                         get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
147                         get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
148                         get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
149                         get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
150                         get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
151                         get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
152                 break;
153
154
155         default:
156                 fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
157                 assert(0);
158         }
159 }
160
161 /**
162  * Return the tarval of an atomic initializer.
163  */
164 static tarval *get_atomic_init_tv(ir_node *init)
165 {
166         for (;;) {
167                 ir_mode *mode = get_irn_mode(init);
168
169                 switch (get_irn_opcode(init)) {
170
171                 case iro_Cast:
172                         init = get_Cast_op(init);
173                         continue;
174
175                 case iro_Conv:
176                         init = get_Conv_op(init);
177                         continue;
178
179                 case iro_Const:
180                         return get_Const_tarval(init);
181
182                 case iro_SymConst:
183                         switch (get_SymConst_kind(init)) {
184                         case symconst_ofs_ent:
185                                 return new_tarval_from_long(get_entity_offset(get_SymConst_entity(init)), mode);
186
187                         case symconst_type_size:
188                                 return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(init)), mode);
189
190                         case symconst_type_align:
191                                 return new_tarval_from_long(get_type_alignment_bytes(get_SymConst_type(init)), mode);
192
193                         case symconst_enum_const:
194                                 return get_enumeration_value(get_SymConst_enum(init));
195
196                         default:
197                                 return NULL;
198                         }
199
200                 default:
201                         return NULL;
202                 }
203         }
204 }
205
206 /**
207  * dump an atomic value
208  */
209 static void do_dump_atomic_init(ia32_decl_env_t *env, obstack_t *obst,
210                                 ir_node *init)
211 {
212         ir_mode *mode = get_irn_mode(init);
213         int bytes     = get_mode_size_bytes(mode);
214         tarval *tv;
215         ir_entity *ent;
216
217         switch (get_irn_opcode(init)) {
218
219         case iro_Cast:
220                 do_dump_atomic_init(env, obst, get_Cast_op(init));
221                 return;
222
223         case iro_Conv:
224                 do_dump_atomic_init(env, obst, get_Conv_op(init));
225                 return;
226
227         case iro_Const:
228                 tv = get_Const_tarval(init);
229
230                 /* it's a arithmetic value */
231                 dump_arith_tarval(obst, tv, bytes);
232                 return;
233
234         case iro_SymConst:
235                 switch (get_SymConst_kind(init)) {
236                 case symconst_addr_name:
237                         obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
238                         break;
239
240                 case symconst_addr_ent:
241                         ent = get_SymConst_entity(init);
242                         if(!entity_visited(ent)) {
243                                 waitq_put(env->worklist, ent);
244                                 mark_entity_visited(ent);
245                         }
246                         obstack_printf(obst, "%s", get_entity_ld_name(ent));
247                         break;
248
249                 case symconst_ofs_ent:
250                         ent = get_SymConst_entity(init);
251 #if 0       /* not needed, is it? */
252                         if(!entity_visited(ent)) {
253                                 waitq_put(env->worklist, ent);
254                                 mark_entity_visited(ent);
255                         }
256 #endif
257                         obstack_printf(obst, "%d", get_entity_offset(ent));
258                         break;
259
260                 case symconst_type_size:
261                         obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
262                         break;
263
264                 case symconst_type_align:
265                         obstack_printf(obst, "%d", get_type_alignment_bytes(get_SymConst_type(init)));
266                         break;
267
268                 case symconst_enum_const:
269                         tv = get_enumeration_value(get_SymConst_enum(init));
270                         dump_arith_tarval(obst, tv, bytes);
271                         break;
272
273                 default:
274                         assert(!"dump_atomic_init(): don't know how to init from this SymConst");
275                 }
276                 return;
277
278                 case iro_Add:
279                         do_dump_atomic_init(env, obst, get_Add_left(init));
280                         obstack_printf(obst, " + ");
281                         do_dump_atomic_init(env, obst, get_Add_right(init));
282                         return;
283
284                 case iro_Sub:
285                         do_dump_atomic_init(env, obst, get_Sub_left(init));
286                         obstack_printf(obst, " - ");
287                         do_dump_atomic_init(env, obst, get_Sub_right(init));
288                         return;
289
290                 case iro_Mul:
291                         do_dump_atomic_init(env, obst, get_Mul_left(init));
292                         obstack_printf(obst, " * ");
293                         do_dump_atomic_init(env, obst, get_Mul_right(init));
294                         return;
295
296                 default:
297                         assert(0 && "dump_atomic_init(): unknown IR-node");
298         }
299 }
300
301 /**
302  * dumps the type for given size (.byte, .long, ...)
303  */
304 static void dump_size_type(obstack_t *obst, int size) {
305         switch (size) {
306
307         case 1:
308                 obstack_printf(obst, "\t.byte\t");
309                 break;
310
311         case 2:
312                 obstack_printf(obst, "\t.value\t");
313                 break;
314
315         case 4:
316                 obstack_printf(obst, "\t.long\t");
317                 break;
318
319         case 8:
320                 obstack_printf(obst, "\t.quad\t");
321                 break;
322
323         case 10:
324         case 12:
325                 /* handled in arith */
326                 break;
327
328         case 16:
329                 obstack_printf(obst, "\t.octa\t");
330                 break;
331
332         default:
333                 fprintf(stderr, "Try to dump a type with %d bytes\n", size);
334                 assert(0);
335         }
336 }
337
338 /**
339  * dump an atomic value to an obstack
340  */
341 static void dump_atomic_init(ia32_decl_env_t *env, obstack_t *obst,
342                              ir_node *init)
343 {
344         ir_mode *mode = get_irn_mode(init);
345         int bytes     = get_mode_size_bytes(mode);
346
347         dump_size_type(obst, bytes);
348         do_dump_atomic_init(env, obst, init);
349         obstack_printf(obst, "\n");
350 }
351
352 /************************************************************************/
353 /* Routines to dump global variables                                    */
354 /************************************************************************/
355
356 /**
357  * Determine if an entity is a string constant
358  * @param ent The entity
359  * @return 1 if it is a string constant, 0 otherwise
360  */
361 static int ent_is_string_const(ir_entity *ent)
362 {
363         ir_type *type, *element_type;
364         ir_mode *mode;
365         int i, c, n;
366
367         type = get_entity_type(ent);
368
369         /* if it's an array */
370         if (!is_Array_type(type))
371                 return 0;
372
373         element_type = get_array_element_type(type);
374
375         /* and the array's element type is primitive */
376         if (!is_Primitive_type(element_type))
377                 return 0;
378
379         /* and the mode of the element type is an int of
380          * the same size as the byte mode */
381         mode = get_type_mode(element_type);
382         if (!mode_is_int(mode)
383                 || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
384                 return 0;
385
386         /* if it contains only printable chars and a 0 at the end */
387         n = get_compound_ent_n_values(ent);
388         for (i = 0; i < n; ++i) {
389                 ir_node *irn = get_compound_ent_value(ent, i);
390                 if(get_irn_opcode(irn) != iro_Const)
391                         return 0;
392
393                 c = (int) get_tarval_long(get_Const_tarval(irn));
394
395                 if((i < n - 1 && !(isgraph(c) || isspace(c)))
396                                 || (i == n - 1 && c != '\0'))
397                         return 0;
398         }
399
400         /* then we can emit it as a string constant */
401         return 1;
402 }
403
404 /**
405  * Dump a string constant.
406  * No checks are made!!
407  * @param obst The obst to dump on.
408  * @param ent The entity to dump.
409  */
410 static void dump_string_cst(obstack_t *obst, ir_entity *ent)
411 {
412         int i, n;
413
414         obstack_printf(obst, "\t.string \"");
415         n = get_compound_ent_n_values(ent);
416
417         for (i = 0; i < n-1; ++i) {
418                 ir_node *irn;
419                 int c;
420
421                 irn = get_compound_ent_value(ent, i);
422                 c = (int) get_tarval_long(get_Const_tarval(irn));
423
424                 switch (c) {
425                 case '"' : obstack_printf(obst, "\\\""); break;
426                 case '\n': obstack_printf(obst, "\\n"); break;
427                 case '\r': obstack_printf(obst, "\\r"); break;
428                 case '\t': obstack_printf(obst, "\\t"); break;
429                 case '\\': obstack_printf(obst, "\\\\"); break;
430                 default  :
431                         if (isprint(c))
432                                 obstack_printf(obst, "%c", c);
433                         else
434                                 obstack_printf(obst, "\\%o", c);
435                         break;
436                 }
437         }
438         obstack_printf(obst, "\"\n");
439 }
440
441 static void dump_array_init(ia32_decl_env_t *env, obstack_t *obst,
442                             ir_entity *ent)
443 {
444         const ir_type *ty = get_entity_type(ent);
445         int i;
446         int filler;
447         int size = 0;
448
449         /* potential spare values should be already included! */
450         for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
451                 ir_entity *step = get_compound_ent_value_member(ent, i);
452                 ir_type *stype = get_entity_type(step);
453
454                 if (get_type_mode(stype)) {
455                         int align = (get_type_alignment_bits(stype) + 7) >> 3;
456                         int n     = size % align;
457
458                         if (n > 0) {
459                                 obstack_printf(obst, "\t.zero\t%d\n", align - n);
460                                 size += align - n;
461                         }
462                 }
463                 dump_atomic_init(env, obst, get_compound_ent_value(ent, i));
464                 size += get_type_size_bytes(stype);
465         }
466         filler = get_type_size_bytes(ty) - size;
467
468         if (filler > 0)
469                 obstack_printf(obst, "\t.skip\t%d\n", filler);
470 }
471
472 enum normal_or_bitfield_kind {
473         NORMAL = 0,
474         BITFIELD
475 };
476
477 typedef struct {
478         enum normal_or_bitfield_kind kind;
479         union {
480                 ir_node *value;
481                 unsigned char bf_val;
482         } v;
483 } normal_or_bitfield;
484
485 /**
486  * Dump an initializer for a compound entity.
487  */
488 static void dump_compound_init(ia32_decl_env_t *env, obstack_t *obst,
489                                ir_entity *ent)
490 {
491         normal_or_bitfield *vals;
492         int i, j, n = get_compound_ent_n_values(ent);
493         int last_ofs;
494
495         /* Find the initializer size. Sorrily gcc support a nasty feature:
496            The last field of a compound may be a flexible array. This allows
497            initializers bigger than the type size. */
498         last_ofs = get_type_size_bytes(get_entity_type(ent));
499         for (i = 0; i < n; ++i) {
500                 int offset = get_compound_ent_value_offset_bytes(ent, i);
501                 int bits_remainder = get_compound_ent_value_offset_bit_remainder(ent, i);
502                 const compound_graph_path *path = get_compound_ent_value_path(ent, i);
503                 int path_len = get_compound_graph_path_length(path);
504                 ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
505                 int value_len = get_type_size_bits(get_entity_type(last_ent));
506
507                 offset += (value_len + bits_remainder + 7) >> 3;
508
509                 if (offset > last_ofs) {
510                         last_ofs = offset;
511                 }
512         }
513
514         /*
515          * In the worst case, every initializer allocates one byte.
516          * Moreover, initializer might be big, do not allocate on stack.
517          */
518         vals = xcalloc(last_ofs, sizeof(vals[0]));
519
520         /* collect the values and store them at the offsets */
521         for (i = 0; i < n; ++i) {
522                 const compound_graph_path *path = get_compound_ent_value_path(ent, i);
523                 int path_len = get_compound_graph_path_length(path);
524                 int offset = get_compound_ent_value_offset_bytes(ent, i);
525                 int offset_bits = get_compound_ent_value_offset_bit_remainder(ent, i);
526                 ir_node *value = get_compound_ent_value(ent, i);
527                 ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
528                 int value_len = get_type_size_bits(get_entity_type(last_ent));
529                 assert(offset >= 0);
530                 assert(offset_bits >= 0);
531
532                 if (offset_bits != 0 ||
533                         (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) {
534                         tarval *shift, *shifted;
535                         tarval *tv = get_atomic_init_tv(value);
536                         if (tv == NULL) {
537                                 panic("Couldn't get numeric value for bitfield initializer '%s'\n",
538                                       get_entity_ld_name(ent));
539                         }
540                         tv = tarval_convert_to(tv, mode_Lu);
541                         shift = new_tarval_from_long(offset_bits, mode_Is);
542                         shifted = tarval_shl(tv, shift);
543                         if (shifted == tarval_bad || shifted == tarval_undefined) {
544                                 panic("Couldn't shift numeric value for bitfield initializer '%s'\n",
545                                       get_entity_ld_name(ent));
546                         }
547
548                         for (j = 0; value_len > 0; ++j) {
549                                 assert(offset + j < last_ofs);
550                                 assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL);
551                                 vals[offset + j].kind = BITFIELD;
552                                 vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j);
553                                 value_len -= 8 - offset_bits;
554                                 offset_bits = 0;
555                         }
556                 } else {
557                         assert(offset < last_ofs);
558                         assert(vals[offset].kind == NORMAL);
559                         assert(vals[offset].v.value == NULL);
560                         vals[offset].v.value = value;
561                 }
562         }
563
564         /* now write them sorted */
565         for (i = 0; i < last_ofs; ) {
566                 int space = 0, skip = 0;
567                 if (vals[i].kind == NORMAL) {
568                         if(vals[i].v.value != NULL) {
569                                 dump_atomic_init(env, obst, vals[i].v.value);
570                                 skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
571                         } else {
572                                 space = 1;
573                         }
574                 } else {
575                         assert(vals[i].kind == BITFIELD);
576                         obstack_printf(obst, "\t.byte\t%d\n", vals[i].v.bf_val);
577                 }
578
579                 ++i;
580                 space = 0;
581                 while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
582                         ++space;
583                         ++i;
584                 }
585                 space -= skip;
586                 assert(space >= 0);
587
588                 /* a gap */
589                 if (space > 0)
590                         obstack_printf(obst, "\t.skip\t%d\n", space);
591         }
592         xfree(vals);
593 }
594
595 /**
596  * Dump a global entity.
597  */
598 static void dump_global(ia32_decl_env_t *env, ir_entity *ent, int emit_commons)
599 {
600         obstack_t *obst;
601         ir_type *type = get_entity_type(ent);
602         const char *ld_name = get_entity_ld_name(ent);
603         ir_variability variability = get_entity_variability(ent);
604         ir_visibility visibility = get_entity_visibility(ent);
605         int align = get_type_alignment_bytes(type);
606         int emit_as_common = 0;
607
608         obst = env->data_obst;
609         if (is_Method_type(type)) {
610                 if (get_method_img_section(ent) == section_constructors) {
611                         obst = env->ctor_obst;
612                         obstack_printf(obst, ".balign\t%d\n", align);
613                         dump_size_type(obst, align);
614                         obstack_printf(obst, "%s\n", ld_name);
615                 }
616                 return;
617         } else if (variability == variability_constant) {
618                 /* a constant entity, put it on the rdata */
619                 obst = env->rodata_obst;
620         } else if (variability == variability_uninitialized) {
621                 /* uninitialized entity put it in bss segment */
622                 obst = env->bss_obst;
623                 if(emit_commons && visibility != visibility_local)
624                         emit_as_common = 1;
625         }
626
627         be_dbg_variable(env->main_env->db_handle, obst, ent);
628
629         /* global or not global */
630         if (visibility == visibility_external_visible && !emit_as_common) {
631                 obstack_printf(obst, ".global\t%s\n", ld_name);
632         } else if(visibility == visibility_external_allocated) {
633                 obstack_printf(obst, ".global\t%s\n", ld_name);
634                 /* we can return now... */
635                 return;
636         }
637         /* alignment */
638         if (align > 1 && !emit_as_common) {
639                 obstack_printf(obst, ".balign\t%d\n", align);
640         }
641
642         if (!emit_as_common) {
643                 obstack_printf(obst, "%s:\n", ld_name);
644         }
645
646         if (variability == variability_uninitialized) {
647                 if(emit_as_common) {
648                         obstack_printf(obst, "\t.comm %s,%d,%d\n",
649                                         ld_name, get_type_size_bytes(type), align);
650                 } else {
651                         obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
652                 }
653         } else if (is_atomic_type(type)) {
654                 dump_atomic_init(env, obst, get_atomic_ent_value(ent));
655         } else if (ent_is_string_const(ent)) {
656                 dump_string_cst(obst, ent);
657         } else if (is_Array_type(type)) {
658                 dump_array_init(env, obst, ent);
659         } else if (is_compound_type(type)) {
660                 dump_compound_init(env, obst, ent);
661         } else {
662                 assert(0 && "unsupported type");
663         }
664 }
665
666 /**
667  * Dumps declarations of global variables and the initialization code.
668  */
669 static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env,
670                               int emit_commons, int only_emit_marked)
671 {
672         int i, n = get_compound_n_members(gt);
673         waitq *worklist = new_waitq();
674
675         if(only_emit_marked) {
676                 for (i = 0; i < n; i++) {
677                         ir_entity *ent = get_compound_member(gt, i);
678                         if(entity_visited(ent) ||
679                                         get_entity_visibility(ent) != visibility_external_allocated) {
680                                 waitq_put(worklist, ent);
681                                 mark_entity_visited(ent);
682                         }
683                 }
684         } else {
685                 inc_master_type_visited();
686                 for (i = 0; i < n; i++) {
687                         ir_entity *ent = get_compound_member(gt, i);
688                         mark_entity_visited(ent);
689                         waitq_put(worklist, ent);
690                 }
691         }
692
693         env->worklist = worklist;
694
695         while(!waitq_empty(worklist)) {
696                 ir_entity *ent = waitq_get(worklist);
697
698                 dump_global(env, ent, emit_commons);
699         }
700
701         del_waitq(worklist);
702         env->worklist = NULL;
703 }
704
705 /************************************************************************/
706
707 void be_gas_emit_decls(be_emit_env_t *emit, const be_main_env_t *main_env,
708                        int only_emit_marked_entities)
709 {
710         ia32_decl_env_t env;
711         obstack_t rodata, data, bss, ctor;
712         int    size;
713         char   *cp;
714
715         /* dump the global type */
716         obstack_init(&rodata);
717         obstack_init(&data);
718         obstack_init(&bss);
719         obstack_init(&ctor);
720
721         env.rodata_obst = &rodata;
722         env.data_obst   = &data;
723         env.bss_obst    = &bss;
724         env.ctor_obst   = &ctor;
725         env.main_env    = main_env;
726
727         ia32_dump_globals(get_glob_type(), &env, 1, only_emit_marked_entities);
728
729         size = obstack_object_size(&data);
730         cp   = obstack_finish(&data);
731         if (size > 0) {
732                 be_gas_emit_switch_section(emit, GAS_SECTION_DATA);
733                 be_emit_string_len(emit, cp, size);
734                 be_emit_write_line(emit);
735         }
736
737         size = obstack_object_size(&rodata);
738         cp   = obstack_finish(&rodata);
739         if (size > 0) {
740                 be_gas_emit_switch_section(emit, GAS_SECTION_RODATA);
741                 be_emit_string_len(emit, cp, size);
742                 be_emit_write_line(emit);
743         }
744
745         size = obstack_object_size(&bss);
746         cp   = obstack_finish(&bss);
747         if (size > 0) {
748                 be_gas_emit_switch_section(emit, GAS_SECTION_COMMON);
749                 be_emit_string_len(emit, cp, size);
750                 be_emit_write_line(emit);
751         }
752
753         size = obstack_object_size(&ctor);
754         cp   = obstack_finish(&ctor);
755         if (size > 0) {
756                 be_gas_emit_switch_section(emit, GAS_SECTION_CTOR);
757                 be_emit_string_len(emit, cp, size);
758                 be_emit_write_line(emit);
759         }
760
761         obstack_free(&rodata, NULL);
762         obstack_free(&data, NULL);
763         obstack_free(&bss, NULL);
764         obstack_free(&ctor, NULL);
765
766         /* dump the Thread Local Storage */
767         obstack_init(&data);
768
769         env.rodata_obst = &data;
770         env.data_obst   = &data;
771         env.bss_obst    = &data;
772         env.ctor_obst   = NULL;
773
774         ia32_dump_globals(get_tls_type(), &env, 0, only_emit_marked_entities);
775
776         size = obstack_object_size(&data);
777         cp   = obstack_finish(&data);
778         if (size > 0) {
779                 be_gas_emit_switch_section(emit, GAS_SECTION_TLS);
780                 be_emit_cstring(emit, ".balign\t32\n");
781                 be_emit_write_line(emit);
782                 be_emit_string_len(emit, cp, size);
783                 be_emit_write_line(emit);
784         }
785
786         obstack_free(&data, NULL);
787 }