X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftype.c;h=9a933dc066989a40a963e2c650eeb8b8b14743f6;hb=6ac253f762d463c9444bbb392fc8cdb480127895;hp=29703e30dbc7553e7b7e0d821fbc662962212239;hpb=5958d557085547b9ab6aa94c54c9b65f4d158a98;p=libfirm diff --git a/ir/tr/type.c b/ir/tr/type.c index 29703e30d..9a933dc06 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -17,8 +17,8 @@ * Implementation of the datastructure to hold * type information. * - * (C) 2001-2005 by Universitaet Karlsruhe - * Goetz Lindenmaier + * (C) 2001-2006 by Universitaet Karlsruhe + * Goetz Lindenmaier, Michael Beck * * This module supplies a datastructure to represent all types * known in the compiled program. This includes types specified @@ -67,6 +67,7 @@ # include "mangle.h" # include "tv_t.h" # include "irhooks.h" +# include "irtools.h" # include "array.h" @@ -78,11 +79,6 @@ ir_type *firm_none_type; ir_type *get_none_type(void) { return firm_none_t ir_type *firm_unknown_type; ir_type *get_unknown_type(void) { return firm_unknown_type; } -#ifdef DEBUG_libfirm -/* Returns a new, unique number to number nodes or the like. */ -int get_irp_new_node_nr(void); -#endif - /* Suffixes added to types used for pass-by-value representations. */ static ident *value_params_suffix = NULL; static ident *value_ress_suffix = NULL; @@ -241,7 +237,7 @@ long get_type_nr(const ir_type *tp) { #ifdef DEBUG_libfirm return tp->nr; #else - return (long)tp; + return (long)PTR_TO_INT(tp); #endif } @@ -365,6 +361,7 @@ int get_type_alignment_bits(ir_type *tp) { void set_type_alignment_bits(ir_type *tp, int align) { assert(tp && tp->kind == k_type); + assert((align & (align - 1)) == 0 && "type alignment not power of two"); /* Methods don't have an alignment. */ if (tp->type_op != type_method) { tp->align = align; @@ -445,7 +442,7 @@ set_type_state(ir_type *tp, type_state state) { default: break; } /* switch (tp) */ } - if (state = layout_fixed) + if (state == layout_fixed) tp->flags |= tf_layout_fixed; else tp->flags &= tf_layout_fixed; @@ -1147,6 +1144,7 @@ ir_type *new_d_type_method(ident *name, int n_param, int n_res, dbg_info *db) { res->attr.ma.value_ress = NULL; res->attr.ma.variadicity = variadicity_non_variadic; res->attr.ma.first_variadic_param = -1; + res->attr.ma.additional_properties = mtp_no_property; res->attr.ma.irg_calling_conv = default_cc_mask; hook_new_type(res); return res; @@ -1786,8 +1784,8 @@ void set_pointer_mode(ir_type *tp, ir_mode *mode) { * Not efficient: O(#types). * If not found returns firm_unknown_type. */ ir_type *find_pointer_type_to_type (ir_type *tp) { - int i; - for (i = 0; i < get_irp_n_types(); ++i) { + int i, n = get_irp_n_types(); + for (i = 0; i < n; ++i) { ir_type *found = get_irp_type(i); if (is_Pointer_type(found) && get_pointer_points_to_type(found) == tp) return (found); @@ -1933,3 +1931,60 @@ ir_type *get_associated_type(const ir_type *tp) { void set_default_size_bits(ir_type *tp, int size) { tp->size = size; } + +/* + * Allocate an area of size bytes aligned at alignment + * at the start or the end of a frame type. + * The frame type must have already an fixed layout. + */ +entity *frame_alloc_area(type *frame_type, int size, int alignment, int at_start) +{ + entity *area; + ir_type *tp; + ident *name; + char buf[32]; + int frame_align, i, offset, frame_size; + static unsigned area_cnt = 0; + static ir_type *a_byte = NULL; + + assert(is_frame_type(frame_type)); + assert(get_type_state(frame_type) == layout_fixed); + + if (! a_byte) + a_byte = new_type_primitive(new_id_from_chars("byte", 4), mode_Bu); + + snprintf(buf, sizeof(buf), "area%u", area_cnt++); + name = new_id_from_str(buf); + + /* align the size */ + frame_align = get_type_alignment_bytes(frame_type); + size = (size + frame_align - 1) & -frame_align; + + tp = new_type_array(mangle_u(get_type_ident(frame_type), name), 1, a_byte); + set_array_bounds_int(tp, 0, 0, size); + set_type_alignment_bytes(tp, alignment); + + frame_size = get_type_size_bytes(frame_type); + if (at_start) { + /* fix all offsets so far */ + for (i = get_class_n_members(frame_type) - 1; i >= 0; --i) { + entity *ent = get_class_member(frame_type, i); + + set_entity_offset_bytes(ent, get_entity_offset_bytes(ent) + size); + } + /* calculate offset and new type size */ + offset = 0; + frame_size += size; + } + else { + /* calculate offset and new type size */ + offset = (frame_size + alignment - 1) & -alignment; + frame_size = offset + size; + } + + area = new_entity(frame_type, name, tp); + set_entity_offset_bytes(area, offset); + set_type_size_bytes(frame_type, frame_size); + + return area; +}