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