ir_node *dmemory_default_alloc_array(ir_type *eltype, ir_node *count, ir_graph *irg, ir_node *block, ir_node **mem) { ir_node *cur_mem = *mem; unsigned count_size = get_mode_size_bytes(default_arraylength_mode); unsigned element_size = is_Class_type(eltype) ? get_mode_size_bytes(mode_P) : get_type_size_bytes(eltype); // FIXME: some langs support arrays of structs. /* increase element count so we have enough space for a counter at the front */ unsigned add_size = (element_size + (count_size-1)) / count_size; ir_node *count_u = new_r_Conv(block, count, mode_Iu); ir_node *addv = new_r_Const_long(irg, mode_Iu, add_size); ir_node *add1 = new_r_Add(block, count_u, addv, mode_Iu); ir_node *elsizev = new_r_Const_long(irg, mode_Iu, element_size); ir_node *size = new_r_Mul(block, add1, elsizev, mode_Iu); unsigned addr_delta = add_size * element_size; symconst_symbol calloc_sym; calloc_sym.entity_p = calloc_entity; ir_node *callee = new_r_SymConst(irg, mode_P, calloc_sym, symconst_addr_ent); ir_node *one = new_r_Const_long(irg, mode_Iu, 1); ir_node *in[2] = { one, size }; ir_type *call_type = get_entity_type(calloc_entity); ir_node *call = new_r_Call(block, cur_mem, callee, 2, in, call_type); cur_mem = new_r_Proj(call, mode_M, pn_Call_M); ir_node *ress = new_r_Proj(call, mode_T, pn_Call_T_result); ir_node *res = new_r_Proj(ress, mode_P, 0); /* write length of array */ ir_node *len_value = new_r_Conv(block, count, default_arraylength_mode); ir_node *len_delta = new_r_Const_long(irg, mode_P, (int)addr_delta-4); //FIXME: replace magic num ir_node *len_addr = new_r_Add(block, res, len_delta, mode_P); ir_node *store = new_r_Store(block, cur_mem, len_addr, len_value, cons_none); cur_mem = new_r_Proj(store, mode_M, pn_Store_M); if (addr_delta > 0) { ir_node *delta = new_r_Const_long(irg, mode_P, (int)addr_delta); res = new_r_Add(block, res, delta, mode_P); } *mem = cur_mem; return res; }
/** * Turn a small CopyB node into a series of Load/Store nodes. */ static void lower_small_copyb_node(ir_node *irn) { ir_graph *irg = get_irn_irg(irn); ir_node *block = get_nodes_block(irn); ir_type *tp = get_CopyB_type(irn); ir_node *addr_src = get_CopyB_src(irn); ir_node *addr_dst = get_CopyB_dst(irn); ir_node *mem = get_CopyB_mem(irn); ir_mode *mode_ref = get_irn_mode(addr_src); unsigned mode_bytes = allow_misalignments ? native_mode_bytes : get_type_alignment_bytes(tp); unsigned size = get_type_size_bytes(tp); unsigned offset = 0; while (offset < size) { ir_mode *mode = get_ir_mode(mode_bytes); for (; offset + mode_bytes <= size; offset += mode_bytes) { ir_mode *mode_ref_int = get_reference_offset_mode(mode_ref); /* construct offset */ ir_node *addr_const = new_r_Const_long(irg, mode_ref_int, offset); ir_node *add = new_r_Add(block, addr_src, addr_const, mode_ref); ir_node *load = new_r_Load(block, mem, add, mode, tp, cons_none); ir_node *load_res = new_r_Proj(load, mode, pn_Load_res); ir_node *load_mem = new_r_Proj(load, mode_M, pn_Load_M); ir_node *addr_const2 = new_r_Const_long(irg, mode_ref_int, offset); ir_node *add2 = new_r_Add(block, addr_dst, addr_const2, mode_ref); ir_node *store = new_r_Store(block, load_mem, add2, load_res, tp, cons_none); ir_node *store_mem = new_r_Proj(store, mode_M, pn_Store_M); mem = store_mem; } mode_bytes /= 2; } exchange(irn, mem); }