remove old debug printf
[libfirm] / ir / be / ia32 / ia32_gen_decls.c
index a1d9038..6f0da99 100644 (file)
@@ -68,54 +68,72 @@ static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes)
        case 12:
                break;
 
+       case 16:
+               obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x"
+                                              "%02x%02x%02x%02x%02x%02x%02x%02x",
+                       get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 16),
+                       get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
+                       get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
+                       get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
+                       get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
+                       get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+                       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+                       get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
+               break;
+
+
        default:
                fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
                assert(0);
        }
 }
 
+/**
+ * Return the tarval of an atomic initializer.
+ */
 static tarval *get_atomic_init_tv(ir_node *init)
 {
-       ir_mode *mode = get_irn_mode(init);
+       for (;;) {
+               ir_mode *mode = get_irn_mode(init);
 
-       switch (get_irn_opcode(init)) {
+               switch (get_irn_opcode(init)) {
 
-       case iro_Cast:
-               return get_atomic_init_tv(get_Cast_op(init));
+               case iro_Cast:
+                       init = get_Cast_op(init);
+                       continue;
 
-       case iro_Conv:
-               return get_atomic_init_tv(get_Conv_op(init));
+               case iro_Conv:
+                       init = get_Conv_op(init);
+                       continue;
 
-       case iro_Const:
-               return get_Const_tarval(init);
+               case iro_Const:
+                       return get_Const_tarval(init);
 
-       case iro_SymConst:
-               switch (get_SymConst_kind(init)) {
-               case symconst_ofs_ent:
-                       return new_tarval_from_long(get_entity_offset(get_SymConst_entity(init)), mode);
-                       break;
+               case iro_SymConst:
+                       switch (get_SymConst_kind(init)) {
+                       case symconst_ofs_ent:
+                               return new_tarval_from_long(get_entity_offset(get_SymConst_entity(init)), mode);
 
-               case symconst_type_size:
-                       return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(init)), mode);
+                       case symconst_type_size:
+                               return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(init)), mode);
 
-               case symconst_type_align:
-                       return new_tarval_from_long(get_type_alignment_bytes(get_SymConst_type(init)), mode);
+                       case symconst_type_align:
+                               return new_tarval_from_long(get_type_alignment_bytes(get_SymConst_type(init)), mode);
 
-               case symconst_enum_const:
-                       return get_enumeration_value(get_SymConst_enum(init));
+                       case symconst_enum_const:
+                               return get_enumeration_value(get_SymConst_enum(init));
 
-               default:
-                       return NULL;
-               }
+                       default:
+                               return NULL;
+                       }
 
                default:
                        return NULL;
+               }
        }
-
-       return NULL;
 }
 
-/*
+/**
  * dump an atomic value
  */
 static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
@@ -137,9 +155,6 @@ static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
        case iro_Const:
                tv = get_Const_tarval(init);
 
-               /* beware of old stuff */
-               //assert(! mode_is_reference(mode));
-
                /* it's a arithmetic value */
                dump_arith_tarval(obst, tv, bytes);
                return;
@@ -199,7 +214,7 @@ static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
        }
 }
 
-/*
+/**
  * dumps the type for given size (.byte, .long, ...)
  */
 static void dump_size_type(obstack_t *obst, int size) {
@@ -226,14 +241,18 @@ static void dump_size_type(obstack_t *obst, int size) {
                /* handled in arith */
                break;
 
+       case 16:
+               obstack_printf(obst, "\t.octa\t");
+               break;
+
        default:
                fprintf(stderr, "Try to dump a type with %d bytes\n", size);
                assert(0);
        }
 }
 
-/*
- * dump an atomic value
+/**
+ * dump an atomic value to an obstack
  */
 static void dump_atomic_init(obstack_t *obst, ir_node *init)
 {
@@ -256,51 +275,49 @@ static void dump_atomic_init(obstack_t *obst, ir_node *init)
  */
 static int ent_is_string_const(ir_entity *ent)
 {
-       int res = 0;
-       ir_type *ty;
+       ir_type *type, *element_type;
+       ir_mode *mode;
+       int i, c, n;
 
-       ty = get_entity_type(ent);
+       type = get_entity_type(ent);
 
        /* if it's an array */
-       if (is_Array_type(ty)) {
-               ir_type *elm_ty = get_array_element_type(ty);
-
-               /* and the array's element type is primitive */
-               if (is_Primitive_type(elm_ty)) {
-                       ir_mode *mode = get_type_mode(elm_ty);
-
-                       /*
-                       * and the mode of the element type is an int of
-                       * the same size as the byte mode
-                       */
-                       if (mode_is_int(mode)
-                               && get_mode_size_bits(mode) == get_mode_size_bits(mode_Bs))
-                       {
-                               int i, c, n;
-
-                               n = get_compound_ent_n_values(ent);
-                               for (i = 0; i < n; ++i) {
-                                       ir_node *irn = get_compound_ent_value(ent, i);
-                                       if(get_irn_opcode(irn) != iro_Const)
-                                               return 0;
-
-                                       c = (int) get_tarval_long(get_Const_tarval(irn));
-
-                                       if((i < n - 1 && !(isgraph(c) || isspace(c)))
-                                               || (i == n - 1 && c != '\0'))
-                                               return 0;
-                               }
-
-                               res = 1;
-                       }
-               }
+       if (!is_Array_type(type))
+               return 0;
+
+       element_type = get_array_element_type(type);
+
+       /* and the array's element type is primitive */
+       if (!is_Primitive_type(element_type))
+               return 0;
+
+       /* and the mode of the element type is an int of
+        * the same size as the byte mode */
+       mode = get_type_mode(element_type);
+       if (!mode_is_int(mode)
+               || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
+               return 0;
+
+       /* if it contains only printable chars and a 0 at the end */
+       n = get_compound_ent_n_values(ent);
+       for (i = 0; i < n; ++i) {
+               ir_node *irn = get_compound_ent_value(ent, i);
+               if(get_irn_opcode(irn) != iro_Const)
+                       return 0;
+
+               c = (int) get_tarval_long(get_Const_tarval(irn));
+
+               if((i < n - 1 && !(isgraph(c) || isspace(c)))
+                               || (i == n - 1 && c != '\0'))
+                       return 0;
        }
 
-       return res;
+       /* then we can emit it as a string constant */
+       return 1;
 }
 
 /**
- * Dump a atring constant.
+ * Dump a string constant.
  * No checks are made!!
  * @param obst The obst to dump on.
  * @param ent The entity to dump.
@@ -329,7 +346,7 @@ static void dump_string_cst(obstack_t *obst, ir_entity *ent)
                        if (isprint(c))
                                obstack_printf(obst, "%c", c);
                        else
-                               obstack_printf(obst, "%O", c);
+                               obstack_printf(obst, "\\%o", c);
                        break;
                }
        }
@@ -379,29 +396,42 @@ typedef struct {
        } v;
 } normal_or_bitfield;
 
+/**
+ * Dump an initializer for a compound entity.
+ */
 static void dump_compound_init(obstack_t *obst, ir_entity *ent)
 {
-       ir_type *ty = get_entity_type(ent);
        normal_or_bitfield *vals;
-       int type_size;
-       int i, j;
-       int res;
+       int i, j, n = get_compound_ent_n_values(ent);
+       int last_ofs;
+
+       /* Find the initializer size. Sorrily gcc support a nasty feature:
+          The last field of a compound may be a flexible array. This allows
+          initializers bigger than the type size. */
+       last_ofs = 0;
+       for (i = 0; i < n; ++i) {
+               int offset = get_compound_ent_value_offset_bytes(ent, i);
+               int bits_remainder = get_compound_ent_value_offset_bit_remainder(ent, i);
+               const compound_graph_path *path = get_compound_ent_value_path(ent, i);
+               int path_len = get_compound_graph_path_length(path);
+               ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
+               int value_len = get_type_size_bits(get_entity_type(last_ent));
 
-       res = compute_compound_ent_array_indices(ent);
-       if(!res) {
-               panic("Couldn't emit initializer for entity '%s'\n", get_entity_ld_name(ent));
+               offset += (value_len + bits_remainder + 7) >> 3;
+
+               if (offset > last_ofs) {
+                       last_ofs = offset;
+               }
        }
 
        /*
-        * in the worst case, every entity allocates one byte, so the type
-        * size should be equal or bigger the number of fields
+        * In the worst case, every initializer allocates one byte.
+        * Moreover, initializer might be big, do not allocate an stack.
         */
-       type_size = get_type_size_bytes(ty);
-       vals = alloca(type_size * sizeof(vals[0]));
-       memset(vals, 0, type_size * sizeof(vals[0]));
+       vals = xcalloc(last_ofs, sizeof(vals[0]));
 
        /* collect the values and store them at the offsets */
-       for(i = 0; i < get_compound_ent_n_values(ent); ++i) {
+       for (i = 0; i < n; ++i) {
                const compound_graph_path *path = get_compound_ent_value_path(ent, i);
                int path_len = get_compound_graph_path_length(path);
                int offset = get_compound_ent_value_offset_bytes(ent, i);
@@ -409,23 +439,27 @@ static void dump_compound_init(obstack_t *obst, ir_entity *ent)
                ir_node *value = get_compound_ent_value(ent, i);
                ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
                int value_len = get_type_size_bits(get_entity_type(last_ent));
+               assert(offset >= 0);
+               assert(offset_bits >= 0);
 
-               if(offset_bits != 0 || value_len % 8 != 0) {
+               if (offset_bits != 0 ||
+                       (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) {
                        tarval *shift, *shifted;
                        tarval *tv = get_atomic_init_tv(value);
-                       if(tv == NULL) {
+                       if (tv == NULL) {
                                panic("Couldn't get numeric value for bitfield initializer '%s'\n",
                                      get_entity_ld_name(ent));
                        }
+                       tv = tarval_convert_to(tv, mode_Lu);
                        shift = new_tarval_from_long(offset_bits, mode_Is);
                        shifted = tarval_shl(tv, shift);
-                       if(shifted == tarval_bad || shifted == tarval_undefined) {
+                       if (shifted == tarval_bad || shifted == tarval_undefined) {
                                panic("Couldn't shift numeric value for bitfield initializer '%s'\n",
                                      get_entity_ld_name(ent));
                        }
 
-                       for(j = 0; j < 4 && value_len > 0; ++j) {
-                               assert(offset + j < type_size);
+                       for (j = 0; value_len > 0; ++j) {
+                               assert(offset + j < last_ofs);
                                assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL);
                                vals[offset + j].kind = BITFIELD;
                                vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j);
@@ -433,7 +467,7 @@ static void dump_compound_init(obstack_t *obst, ir_entity *ent)
                                offset_bits = 0;
                        }
                } else {
-                       assert(offset < type_size);
+                       assert(offset < last_ofs);
                        assert(vals[offset].kind == NORMAL);
                        assert(vals[offset].v.value == NULL);
                        vals[offset].v.value = value;
@@ -441,22 +475,23 @@ static void dump_compound_init(obstack_t *obst, ir_entity *ent)
        }
 
        /* now write them sorted */
-       for(i = 0; i < type_size; ) {
+       for (i = 0; i < last_ofs; ) {
                int space = 0, skip = 0;
                if (vals[i].kind == NORMAL) {
-                  if(vals[i].v.value != NULL) {
-                          dump_atomic_init(obst, vals[i].v.value);
-                          skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
-                  } else {
-                          space = 1;
-                  }
+                       if(vals[i].v.value != NULL) {
+                               dump_atomic_init(obst, vals[i].v.value);
+                               skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
+                       } else {
+                               space = 1;
+                       }
                } else {
+                       assert(vals[i].kind == BITFIELD);
                        obstack_printf(obst, "\t.byte\t%d\n", vals[i].v.bf_val);
                }
 
                ++i;
                space = 0;
-               while(i < type_size && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
+               while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
                        ++space;
                        ++i;
                }
@@ -464,11 +499,15 @@ static void dump_compound_init(obstack_t *obst, ir_entity *ent)
                assert(space >= 0);
 
                /* a gap */
-               if(space > 0)
+               if (space > 0)
                        obstack_printf(obst, "\t.skip\t%d\n", space);
        }
+       xfree(vals);
 }
 
+/**
+ * Dump a global entity.
+ */
 static void dump_global(ia32_decl_env_t *env, ir_entity *ent)
 {
        obstack_t *obst;
@@ -479,18 +518,18 @@ static void dump_global(ia32_decl_env_t *env, ir_entity *ent)
        int align = get_type_alignment_bytes(type);
 
        obst = env->data_obst;
-       if(is_Method_type(type)) {
-               if(get_method_img_section(ent) == section_constructors) {
+       if (is_Method_type(type)) {
+               if (get_method_img_section(ent) == section_constructors) {
                        obst = env->ctor_obst;
                        obstack_printf(obst, ".balign\t%d\n", align);
                        dump_size_type(obst, align);
                        obstack_printf(obst, "%s\n", ld_name);
                }
                return;
-       } else if(variability == variability_constant) {
+       } else if (variability == variability_constant) {
                /* a constant entity, put it on the rdata */
                obst = env->rodata_obst;
-       } else if(variability == variability_uninitialized) {
+       } else if (variability == variability_uninitialized) {
                /* uninitialized entity put it in bss segment */
                obst = env->bss_obst;
        }
@@ -498,7 +537,8 @@ static void dump_global(ia32_decl_env_t *env, ir_entity *ent)
        be_dbg_variable(env->main_env->db_handle, obst, ent);
 
        /* global or not global */
-       if(visibility == visibility_external_visible) {
+       if(visibility == visibility_external_visible
+                       && variability != variability_uninitialized) {
                obstack_printf(obst, ".global\t%s\n", ld_name);
        } else if(visibility == visibility_external_allocated) {
                obstack_printf(obst, ".global\t%s\n", ld_name);
@@ -506,38 +546,27 @@ static void dump_global(ia32_decl_env_t *env, ir_entity *ent)
                return;
        }
        /* alignment */
-       if(align > 1) {
+       if(align > 1 && variability != variability_uninitialized) {
                obstack_printf(obst, ".balign\t%d\n", align);
        }
 
-       obstack_printf(obst, "%s:\n", ld_name);
-
-       if(variability == variability_uninitialized) {
-               obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
-               return;
+       if(variability != variability_uninitialized) {
+               obstack_printf(obst, "%s:\n", ld_name);
        }
 
-       if (is_atomic_type(type)) {
+       if (variability == variability_uninitialized) {
+               obstack_printf(obst, "\t.comm %s,%d,%d\n",
+                               ld_name, get_type_size_bytes(type), align);
+       } else if (is_atomic_type(type)) {
                dump_atomic_init(obst, get_atomic_ent_value(ent));
-               return;
-       }
-
-       if (ent_is_string_const(ent)) {
+       } else if (ent_is_string_const(ent)) {
                dump_string_cst(obst, ent);
-               return;
-       }
-
-       if (is_Array_type(type)) {
+       } else if (is_Array_type(type)) {
                dump_array_init(obst, ent);
-               return;
-       }
-
-       if (is_compound_type(type)) {
+       } else if (is_compound_type(type)) {
                dump_compound_init(obst, ent);
-               return;
-       }
-
-       assert(0 && "unsupported type");
+       } else
+               assert(0 && "unsupported type");
 }
 
 /**