X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_common_transform.c;h=bbe9d3f7c38cd57812e23a84196d5f28752a06fd;hb=26e4122270acb4d7644f91b08b088fe64a864611;hp=8a50d317f8ec51a05446447011127ec1a383d661;hpb=07ce9818702faae854ee98b17e94a30a7a7022b5;p=libfirm diff --git a/ir/be/ia32/ia32_common_transform.c b/ir/be/ia32/ia32_common_transform.c index 8a50d317f..bbe9d3f7c 100644 --- a/ir/be/ia32/ia32_common_transform.c +++ b/ir/be/ia32/ia32_common_transform.c @@ -22,7 +22,6 @@ * @brief This file implements the common parts of IR transformation from * firm into ia32-Firm. * @author Matthias Braun, Sebastian Buchwald - * @version $Id: ia32_common_transform.c 21012 2008-08-06 13:35:17Z beck $ */ #include "config.h" @@ -33,9 +32,9 @@ #include "bitset.h" #include "heights.h" -#include "../betranshlp.h" -#include "../beirg.h" -#include "../beabi.h" +#include "betranshlp.h" +#include "beirg.h" +#include "beabi.h" #include "ia32_architecture.h" #include "ia32_common_transform.h" @@ -44,10 +43,7 @@ #include "gen_ia32_new_nodes.h" #include "gen_ia32_regalloc_if.h" -/** hold the current code generator during transformation */ -ia32_code_gen_t *env_cg = NULL; - -ir_heights_t *heights = NULL; +ir_heights_t *ia32_heights = NULL; static int check_immediate_constraint(long val, char immediate_constraint_type) { @@ -67,28 +63,19 @@ static int check_immediate_constraint(long val, char immediate_constraint_type) } } -/** - * Get a primitive type for a mode with alignment 16. - */ -static ir_type *ia32_get_prim_type(pmap *types, ir_mode *mode) +ir_type *ia32_get_prim_type(const ir_mode *mode) { - ir_type *res = pmap_get(types, mode); - if (res != NULL) - return res; - - res = new_type_primitive(mode); - if (get_mode_size_bits(mode) >= 80) { - set_type_alignment_bytes(res, 16); + if (mode == ia32_mode_E) { + return ia32_type_E; + } else { + return get_type_for_mode(mode); } - pmap_insert(types, mode, res); - return res; } -ir_entity *create_float_const_entity(ir_node *cnst) +ir_entity *ia32_create_float_const_entity(ia32_isa_t *isa, ir_tarval *tv, + ident *name) { - ia32_isa_t *isa = env_cg->isa; - tarval *tv = get_Const_tarval(cnst); - ir_entity *res = pmap_get(isa->tv_ent, tv); + ir_entity *res = pmap_get(ir_entity, isa->tv_ent, tv); ir_initializer_t *initializer; ir_mode *mode; ir_type *tp; @@ -113,8 +100,11 @@ ir_entity *create_float_const_entity(ir_node *cnst) } } - tp = ia32_get_prim_type(isa->types, mode); - res = new_entity(get_glob_type(), id_unique("C%u"), tp); + if (name == NULL) + name = id_unique("C%u"); + + tp = ia32_get_prim_type(mode); + res = new_entity(get_glob_type(), name, tp); set_entity_ld_ident(res, get_entity_ident(res)); set_entity_visibility(res, ir_visibility_private); add_entity_linkage(res, IR_LINKAGE_CONSTANT); @@ -131,8 +121,8 @@ ir_node *ia32_create_Immediate(ir_entity *symconst, int symconst_sign, long val) ir_graph *irg = current_ir_graph; ir_node *start_block = get_irg_start_block(irg); ir_node *immediate = new_bd_ia32_Immediate(NULL, start_block, symconst, - symconst_sign, no_pic_adjust, val); - arch_set_irn_register(immediate, &ia32_gp_regs[REG_GP_NOREG]); + symconst_sign, ia32_no_pic_adjust, val); + arch_set_irn_register(immediate, &ia32_registers[REG_GP_NOREG]); return immediate; } @@ -146,7 +136,7 @@ const arch_register_t *ia32_get_clobber_register(const char *clobber) /* TODO: construct a hashmap instead of doing linear search for clobber * register */ - for (c = 0; c < N_CLASSES; ++c) { + for (c = 0; c < N_IA32_CLASSES; ++c) { cls = & ia32_reg_classes[c]; for (r = 0; r < cls->n_regs; ++r) { const arch_register_t *temp_reg = arch_register_for_index(cls, r); @@ -165,7 +155,7 @@ const arch_register_t *ia32_get_clobber_register(const char *clobber) int ia32_mode_needs_gp_reg(ir_mode *mode) { - if (mode == mode_fpcw) + if (mode == ia32_mode_fpcw) return 0; if (get_mode_size_bits(mode) > 32) return 0; @@ -173,7 +163,7 @@ int ia32_mode_needs_gp_reg(ir_mode *mode) } static void parse_asm_constraints(constraint_t *constraint, const char *c, - int is_output) + bool is_output) { char immediate_type = '\0'; unsigned limited = 0; @@ -219,32 +209,32 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, case 'a': assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_EAX; + limited |= 1 << REG_GP_EAX; break; case 'b': assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_EBX; + limited |= 1 << REG_GP_EBX; break; case 'c': assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_ECX; + limited |= 1 << REG_GP_ECX; break; case 'd': assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_EDX; + limited |= 1 << REG_GP_EDX; break; case 'D': assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_EDI; + limited |= 1 << REG_GP_EDI; break; case 'S': assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_ESI; + limited |= 1 << REG_GP_ESI; break; case 'Q': case 'q': @@ -252,20 +242,20 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, * difference to Q for us (we only assign whole registers) */ assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX | - 1 << REG_EDX; + limited |= 1 << REG_GP_EAX | 1 << REG_GP_EBX | 1 << REG_GP_ECX | + 1 << REG_GP_EDX; break; case 'A': assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_EAX | 1 << REG_EDX; + limited |= 1 << REG_GP_EAX | 1 << REG_GP_EDX; break; case 'l': assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]); cls = &ia32_reg_classes[CLASS_ia32_gp]; - limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX | - 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI | - 1 << REG_EBP; + limited |= 1 << REG_GP_EAX | 1 << REG_GP_EBX | 1 << REG_GP_ECX | + 1 << REG_GP_EDX | 1 << REG_GP_ESI | 1 << REG_GP_EDI | + 1 << REG_GP_EBP; break; case 'R': @@ -372,11 +362,9 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, case 'e': /* not available in 32 bit mode */ panic("unsupported asm constraint '%c' found in (%+F)", *c, current_ir_graph); - break; default: panic("unknown asm constraint '%c' found in (%+F)", *c, current_ir_graph); - break; } ++c; } @@ -426,101 +414,77 @@ static inline ir_node *get_new_node(ir_node *node) #endif } -ir_node *gen_ASM(ir_node *node) +ir_node *ia32_gen_ASM(ir_node *node) { - ir_node *block = get_nodes_block(node); - ir_node *new_block = get_new_node(block); - dbg_info *dbgi = get_irn_dbg_info(node); - int i, arity; - int value_arity; - int out_idx; - ir_node **in; - ir_node *new_node; - int out_arity; - int n_out_constraints; - int n_clobbers; - const arch_register_req_t **out_reg_reqs; - const arch_register_req_t **in_reg_reqs; - ia32_asm_reg_t *register_map; - unsigned reg_map_size = 0; - struct obstack *obst; - const ir_asm_constraint *in_constraints; - const ir_asm_constraint *out_constraints; - ident **clobbers; - int clobbers_flags = 0; - unsigned clobber_bits[N_CLASSES]; - int out_size; - backend_info_t *info; - + ir_node *block = get_nodes_block(node); + ir_node *new_block = get_new_node(block); + dbg_info *dbgi = get_irn_dbg_info(node); + int n_inputs = get_ASM_n_inputs(node); + int n_ins = n_inputs+1; + ir_node **in = ALLOCANZ(ir_node*, n_ins); + size_t n_clobbers = 0; + ident **clobbers = get_ASM_clobbers(node); + unsigned reg_map_size = 0; + ir_graph *irg = get_irn_irg(node); + struct obstack *obst = get_irg_obstack(irg); + unsigned clobber_bits[N_IA32_CLASSES]; memset(&clobber_bits, 0, sizeof(clobber_bits)); - /* workaround for lots of buggy code out there as most people think volatile - * asm is enough for everything and forget the flags (linux kernel, etc.) - */ - if (get_irn_pinned(node) == op_pin_state_pinned) { - clobbers_flags = 1; - } - - arity = get_irn_arity(node); - in = ALLOCANZ(ir_node*, arity); - - clobbers = get_ASM_clobbers(node); - n_clobbers = 0; - for (i = 0; i < get_ASM_n_clobbers(node); ++i) { - const arch_register_req_t *req; - const char *c = get_id_str(clobbers[i]); - - if (strcmp(c, "memory") == 0) - continue; - if (strcmp(c, "cc") == 0) { - clobbers_flags = 1; + for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) { + const char *clobber = get_id_str(clobbers[c]); + const arch_register_req_t *req = ia32_parse_clobber(clobber); + if (req == NULL) continue; - } - req = parse_clobber(c); clobber_bits[req->cls->index] |= *req->limited; - - n_clobbers++; + assert(req->cls->n_regs <= sizeof(unsigned)*8); + ++n_clobbers; } - n_out_constraints = get_ASM_n_output_constraints(node); - out_arity = n_out_constraints + n_clobbers; + size_t n_out_constraints = get_ASM_n_output_constraints(node); + size_t out_arity = n_out_constraints + n_clobbers; - in_constraints = get_ASM_input_constraints(node); - out_constraints = get_ASM_output_constraints(node); + const ir_asm_constraint *in_constraints = get_ASM_input_constraints(node); + const ir_asm_constraint *out_constraints = get_ASM_output_constraints(node); /* determine size of register_map */ - for (out_idx = 0; out_idx < n_out_constraints; ++out_idx) { + for (size_t out_idx = 0; out_idx < n_out_constraints; ++out_idx) { const ir_asm_constraint *constraint = &out_constraints[out_idx]; - if (constraint->pos > reg_map_size) - reg_map_size = constraint->pos; + if (constraint->pos+1 > reg_map_size) + reg_map_size = constraint->pos+1; } - for (i = 0; i < arity; ++i) { + for (int i = 0; i < n_inputs; ++i) { const ir_asm_constraint *constraint = &in_constraints[i]; - if (constraint->pos > reg_map_size) - reg_map_size = constraint->pos; + if (constraint->pos+1 > reg_map_size) + reg_map_size = constraint->pos+1; } - ++reg_map_size; - obst = get_irg_obstack(current_ir_graph); - register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size); + ia32_asm_reg_t *register_map + = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size); memset(register_map, 0, reg_map_size * sizeof(register_map[0])); /* construct output constraints */ - out_size = out_arity + 1; - out_reg_reqs = obstack_alloc(obst, out_size * sizeof(out_reg_reqs[0])); + size_t out_size = out_arity + 1; + const arch_register_req_t **out_reg_reqs + = OALLOCN(obst, const arch_register_req_t*, out_size); + size_t out_idx; for (out_idx = 0; out_idx < n_out_constraints; ++out_idx) { - const ir_asm_constraint *constraint = &out_constraints[out_idx]; - const char *c = get_id_str(constraint->constraint); - unsigned pos = constraint->pos; - constraint_t parsed_constraint; - const arch_register_req_t *req; - - parse_asm_constraints(&parsed_constraint, c, 1); - req = make_register_req(&parsed_constraint, n_out_constraints, - out_reg_reqs, out_idx); + constraint_t parsed_constraint; + const ir_asm_constraint *constraint = &out_constraints[out_idx]; + const char *c = get_id_str(constraint->constraint); + unsigned pos = constraint->pos; + parse_asm_constraints(&parsed_constraint, c, true); + const arch_register_req_t *req + = ia32_make_register_req(&parsed_constraint, n_out_constraints, + out_reg_reqs, out_idx); out_reg_reqs[out_idx] = req; + /* multiple constraints for same pos. This can happen for example when + * a =A constraint gets lowered to two constraints: =a and =d for the + * same pos */ + if (register_map[pos].valid) + continue; + register_map[pos].use_input = 0; register_map[pos].valid = 1; register_map[pos].memory = 0; @@ -529,26 +493,26 @@ ir_node *gen_ASM(ir_node *node) } /* inputs + input constraints */ - in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0])); - for (i = 0; i < arity; ++i) { - ir_node *pred = get_irn_n(node, i); + const arch_register_req_t **in_reg_reqs + = OALLOCN(obst, const arch_register_req_t*, n_ins); + for (int i = 0; i < n_inputs; ++i) { + constraint_t parsed_constraint; + ir_node *pred = get_ASM_input(node, i); const ir_asm_constraint *constraint = &in_constraints[i]; ident *constr_id = constraint->constraint; const char *c = get_id_str(constr_id); unsigned pos = constraint->pos; int is_memory_op = 0; ir_node *input = NULL; - unsigned r_clobber_bits; - constraint_t parsed_constraint; - const arch_register_req_t *req; - parse_asm_constraints(&parsed_constraint, c, 0); + parse_asm_constraints(&parsed_constraint, c, false); if (parsed_constraint.cls != NULL) { - r_clobber_bits = clobber_bits[parsed_constraint.cls->index]; + unsigned r_clobber_bits + = clobber_bits[parsed_constraint.cls->index]; if (r_clobber_bits != 0) { if (parsed_constraint.all_registers_allowed) { parsed_constraint.all_registers_allowed = 0; - be_abi_set_non_ignore_regs(be_get_irg_abi(env_cg->irg), + be_set_allocatable_regs(irg, parsed_constraint.cls, &parsed_constraint.allowed_registers); } @@ -556,22 +520,23 @@ ir_node *gen_ASM(ir_node *node) } } - req = make_register_req(&parsed_constraint, n_out_constraints, - out_reg_reqs, i); + const arch_register_req_t *req + = ia32_make_register_req(&parsed_constraint, n_out_constraints, + out_reg_reqs, i); in_reg_reqs[i] = req; if (parsed_constraint.immediate_type != '\0') { char imm_type = parsed_constraint.immediate_type; - input = try_create_Immediate(pred, imm_type); + input = ia32_try_create_Immediate(pred, imm_type); } if (input == NULL) { - ir_node *pred = get_irn_n(node, i); input = get_new_node(pred); if (parsed_constraint.cls == NULL && parsed_constraint.same_as < 0) { is_memory_op = 1; + in_reg_reqs[i] = ia32_reg_classes[CLASS_ia32_gp].class_req; } else if (parsed_constraint.memory_possible) { /* TODO: match Load or Load/Store if memory possible is set */ } @@ -585,28 +550,21 @@ ir_node *gen_ASM(ir_node *node) register_map[pos].mode = constraint->mode; } - /* parse clobbers */ - for (i = 0; i < get_ASM_n_clobbers(node); ++i) { - const char *c = get_id_str(clobbers[i]); - const arch_register_req_t *req; + assert(n_inputs == n_ins-1); + ir_node *mem = get_ASM_mem(node); + in[n_inputs] = be_transform_node(mem); + in_reg_reqs[n_inputs] = arch_no_register_req; - if (strcmp(c, "memory") == 0 || strcmp(c, "cc") == 0) + /* parse clobbers */ + for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) { + const char *clobber = get_id_str(clobbers[c]); + const arch_register_req_t *req = ia32_parse_clobber(clobber); + if (req == NULL) continue; - - req = parse_clobber(c); out_reg_reqs[out_idx] = req; ++out_idx; } - /* count inputs which are real values (and not memory) */ - value_arity = 0; - for (i = 0; i < arity; ++i) { - ir_node *in = get_irn_n(node, i); - if (get_irn_mode(in) == mode_M) - continue; - ++value_arity; - } - /* Attempt to make ASM node register pressure faithful. * (This does not work for complicated cases yet!) * @@ -619,44 +577,41 @@ ir_node *gen_ASM(ir_node *node) * before... * FIXME: need to do this per register class... */ - if (out_arity <= value_arity) { - int orig_arity = arity; - int in_size = arity; - int o; - bitset_t *used_ins = bitset_alloca(arity); - for (o = 0; o < out_arity; ++o) { - int i; + if (out_arity <= (size_t)n_inputs) { + int orig_inputs = n_ins; + int in_size = n_ins; + bitset_t *used_ins = bitset_alloca(n_ins); + for (size_t o = 0; o < out_arity; ++o) { const arch_register_req_t *outreq = out_reg_reqs[o]; if (outreq->cls == NULL) { continue; } - for (i = 0; i < orig_arity; ++i) { - const arch_register_req_t *inreq; + int i; + for (i = 0; i < orig_inputs; ++i) { if (bitset_is_set(used_ins, i)) continue; - inreq = in_reg_reqs[i]; + const arch_register_req_t *inreq = in_reg_reqs[i]; if (!can_match(outreq, inreq)) continue; bitset_set(used_ins, i); break; } /* did we find any match? */ - if (i < orig_arity) + if (i < orig_inputs) continue; /* we might need more space in the input arrays */ - if (arity >= in_size) { - const arch_register_req_t **new_in_reg_reqs; - ir_node **new_in; - + if (n_ins >= in_size) { in_size *= 2; - new_in_reg_reqs - = obstack_alloc(obst, in_size*sizeof(in_reg_reqs[0])); - memcpy(new_in_reg_reqs, in_reg_reqs, arity * sizeof(new_in_reg_reqs[0])); - new_in = ALLOCANZ(ir_node*, in_size); - memcpy(new_in, in, arity*sizeof(new_in[0])); + const arch_register_req_t **new_in_reg_reqs + = OALLOCN(obst, const arch_register_req_t*, + in_size); + memcpy(new_in_reg_reqs, in_reg_reqs, + n_ins*sizeof(new_in_reg_reqs[0])); + ir_node **new_in = ALLOCANZ(ir_node*, in_size); + memcpy(new_in, in, n_ins*sizeof(new_in[0])); in_reg_reqs = new_in_reg_reqs; in = new_in; @@ -664,23 +619,20 @@ ir_node *gen_ASM(ir_node *node) /* add a new (dummy) input which occupies the register */ assert(outreq->type & arch_register_req_type_limited); - in_reg_reqs[arity] = outreq; - in[arity] = new_bd_ia32_ProduceVal(NULL, block); - be_dep_on_frame(in[arity]); - ++arity; + in_reg_reqs[n_ins] = outreq; + in[n_ins] = new_bd_ia32_ProduceVal(NULL, block); + ++n_ins; } } else { - int i; - bitset_t *used_outs = bitset_alloca(out_arity); - int orig_out_arity = out_arity; - for (i = 0; i < arity; ++i) { - int o; + bitset_t *used_outs = bitset_alloca(out_arity); + size_t orig_out_arity = out_arity; + for (int i = 0; i < n_inputs; ++i) { const arch_register_req_t *inreq = in_reg_reqs[i]; - if (inreq->cls == NULL) { + if (inreq->cls == NULL) continue; - } + size_t o; for (o = 0; o < orig_out_arity; ++o) { const arch_register_req_t *outreq; if (bitset_is_set(used_outs, o)) @@ -701,7 +653,7 @@ ir_node *gen_ASM(ir_node *node) out_size *= 2; new_out_reg_reqs - = obstack_alloc(obst, out_size*sizeof(out_reg_reqs[0])); + = OALLOCN(obst, const arch_register_req_t*, out_size); memcpy(new_out_reg_reqs, out_reg_reqs, out_arity * sizeof(new_out_reg_reqs[0])); out_reg_reqs = new_out_reg_reqs; @@ -720,7 +672,7 @@ ir_node *gen_ASM(ir_node *node) out_size = out_arity + 1; new_out_reg_reqs - = obstack_alloc(obst, out_size*sizeof(out_reg_reqs[0])); + = OALLOCN(obst, const arch_register_req_t*, out_size); memcpy(new_out_reg_reqs, out_reg_reqs, out_arity * sizeof(new_out_reg_reqs[0])); out_reg_reqs = new_out_reg_reqs; @@ -730,24 +682,21 @@ ir_node *gen_ASM(ir_node *node) out_reg_reqs[out_arity] = arch_no_register_req; ++out_arity; - new_node = new_bd_ia32_Asm(dbgi, new_block, arity, in, out_arity, - get_ASM_text(node), register_map); - - if (arity == 0) - be_dep_on_frame(new_node); + ir_node *new_node = new_bd_ia32_Asm(dbgi, new_block, n_ins, in, out_arity, + get_ASM_text(node), register_map); - info = be_get_info(new_node); - for (i = 0; i < out_arity; ++i) { - info->out_infos[i].req = out_reg_reqs[i]; + backend_info_t *info = be_get_info(new_node); + for (size_t o = 0; o < out_arity; ++o) { + info->out_infos[o].req = out_reg_reqs[o]; } - arch_set_in_register_reqs(new_node, in_reg_reqs); + arch_set_irn_register_reqs_in(new_node, in_reg_reqs); SET_IA32_ORIG_NODE(new_node, node); return new_node; } -ir_node *gen_CopyB(ir_node *node) +ir_node *ia32_gen_CopyB(ir_node *node) { ir_node *block = get_new_node(get_nodes_block(node)); ir_node *src = get_CopyB_src(node); @@ -759,6 +708,7 @@ ir_node *gen_CopyB(ir_node *node) ir_node *res = NULL; dbg_info *dbgi = get_irn_dbg_info(node); int size = get_type_size_bytes(get_CopyB_type(node)); + int throws_exception = ir_throws_exception(node); int rem; /* If we have to copy more than 32 bytes, we use REP MOVSx and */ @@ -768,7 +718,6 @@ ir_node *gen_CopyB(ir_node *node) size >>= 2; res = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, size); - be_dep_on_frame(res); res = new_bd_ia32_CopyB(dbgi, block, new_dst, new_src, res, new_mem, rem); } else { @@ -778,23 +727,21 @@ ir_node *gen_CopyB(ir_node *node) } res = new_bd_ia32_CopyB_i(dbgi, block, new_dst, new_src, new_mem, size); } + ir_set_throws_exception(res, throws_exception); SET_IA32_ORIG_NODE(res, node); return res; } -ir_node *gen_Proj_tls(ir_node *node) +ir_node *ia32_gen_Proj_tls(ir_node *node) { ir_node *block = get_new_node(get_nodes_block(node)); - ir_node *res = NULL; - - res = new_bd_ia32_LdTls(NULL, block, mode_Iu); - + ir_node *res = new_bd_ia32_LdTls(NULL, block); return res; } -ir_node *gen_Unknown(ir_node *node) +ir_node *ia32_gen_Unknown(ir_node *node) { ir_mode *mode = get_irn_mode(node); ir_graph *irg = current_ir_graph; @@ -814,12 +761,12 @@ ir_node *gen_Unknown(ir_node *node) panic("unsupported Unknown-Mode"); } - be_dep_on_frame(res); return res; } -const arch_register_req_t *make_register_req(const constraint_t *constraint, - int n_outs, const arch_register_req_t **out_reqs, int pos) +const arch_register_req_t *ia32_make_register_req( + const constraint_t *constraint, int n_outs, + const arch_register_req_t **out_reqs, int pos) { struct obstack *obst = get_irg_obstack(current_ir_graph); int same_as = constraint->same_as; @@ -833,7 +780,7 @@ const arch_register_req_t *make_register_req(const constraint_t *constraint, other_constr = out_reqs[same_as]; - req = obstack_alloc(obst, sizeof(req[0])); + req = OALLOC(obst, arch_register_req_t); *req = *other_constr; req->type |= arch_register_req_type_should_be_same; req->other_same = 1U << pos; @@ -855,7 +802,7 @@ const arch_register_req_t *make_register_req(const constraint_t *constraint, && !constraint->all_registers_allowed) { unsigned *limited_ptr; - req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned)); + req = (arch_register_req_t*)obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned)); memset(req, 0, sizeof(req[0])); limited_ptr = (unsigned*) (req+1); @@ -863,8 +810,7 @@ const arch_register_req_t *make_register_req(const constraint_t *constraint, *limited_ptr = constraint->allowed_registers; req->limited = limited_ptr; } else { - req = obstack_alloc(obst, sizeof(req[0])); - memset(req, 0, sizeof(req[0])); + req = OALLOCZ(obst, arch_register_req_t); req->type = arch_register_req_type_normal; } req->cls = constraint->cls; @@ -873,8 +819,11 @@ const arch_register_req_t *make_register_req(const constraint_t *constraint, return req; } -const arch_register_req_t *parse_clobber(const char *clobber) +const arch_register_req_t *ia32_parse_clobber(const char *clobber) { + if (strcmp(clobber, "memory") == 0 || strcmp(clobber, "cc") == 0) + return NULL; + struct obstack *obst = get_irg_obstack(current_ir_graph); const arch_register_t *reg = ia32_get_clobber_register(clobber); arch_register_req_t *req; @@ -886,11 +835,10 @@ const arch_register_req_t *parse_clobber(const char *clobber) assert(reg->index < 32); - limited = obstack_alloc(obst, sizeof(limited[0])); + limited = OALLOC(obst, unsigned); *limited = 1 << reg->index; - req = obstack_alloc(obst, sizeof(req[0])); - memset(req, 0, sizeof(req[0])); + req = OALLOCZ(obst, arch_register_req_t); req->type = arch_register_req_type_limited; req->cls = arch_register_get_class(reg); req->limited = limited; @@ -900,7 +848,7 @@ const arch_register_req_t *parse_clobber(const char *clobber) } -int prevents_AM(ir_node *const block, ir_node *const am_candidate, +int ia32_prevents_AM(ir_node *const block, ir_node *const am_candidate, ir_node *const other) { if (get_nodes_block(other) != block) @@ -919,7 +867,7 @@ int prevents_AM(ir_node *const block, ir_node *const am_candidate, if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate) continue; - if (!heights_reachable_in_block(heights, pred, am_candidate)) + if (!heights_reachable_in_block(ia32_heights, pred, am_candidate)) continue; return 1; @@ -931,21 +879,21 @@ int prevents_AM(ir_node *const block, ir_node *const am_candidate, if (is_Proj(other) && get_Proj_pred(other) == am_candidate) return 0; - if (!heights_reachable_in_block(heights, other, am_candidate)) + if (!heights_reachable_in_block(ia32_heights, other, am_candidate)) return 0; return 1; } } -ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type) +ir_node *ia32_try_create_Immediate(ir_node *node, char immediate_constraint_type) { - long val = 0; - ir_entity *symconst_ent = NULL; - ir_mode *mode; - ir_node *cnst = NULL; - ir_node *symconst = NULL; - ir_node *new_node; + long val = 0; + ir_entity *symconst_ent = NULL; + ir_mode *mode; + ir_node *cnst = NULL; + ir_node *symconst = NULL; + ir_node *new_node; mode = get_irn_mode(node); if (!mode_is_int(mode) && !mode_is_reference(mode)) { @@ -955,16 +903,17 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type) if (is_Const(node)) { cnst = node; symconst = NULL; - } else if (is_Global(node)) { + } else if (is_SymConst_addr_ent(node) + && get_entity_owner(get_SymConst_entity(node)) != get_tls_type()) { cnst = NULL; symconst = node; } else if (is_Add(node)) { ir_node *left = get_Add_left(node); ir_node *right = get_Add_right(node); - if (is_Const(left) && is_Global(right)) { + if (is_Const(left) && is_SymConst_addr_ent(right)) { cnst = left; symconst = right; - } else if (is_Global(left) && is_Const(right)) { + } else if (is_SymConst_addr_ent(left) && is_Const(right)) { cnst = right; symconst = left; } @@ -973,7 +922,7 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type) } if (cnst != NULL) { - tarval *offset = get_Const_tarval(cnst); + ir_tarval *offset = get_Const_tarval(cnst); if (!tarval_is_long(offset)) { ir_fprintf(stderr, "Optimisation Warning: tarval of %+F is not a long?\n", cnst); return NULL; @@ -989,7 +938,7 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type) return NULL; } - symconst_ent = get_Global_entity(symconst); + symconst_ent = get_SymConst_entity(symconst); } if (cnst == NULL && symconst == NULL) return NULL;