X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_common_transform.c;h=3451b380ec0928e08d637cf21fc82713eed7bd11;hb=9258061e777a7c1cefe217a9ae449e14caa63a62;hp=47578f0e44bf649c3cbc1b548a48eb65697366f3;hpb=a9132de4425fe5540d316e1a2c7fd37635464514;p=libfirm diff --git a/ir/be/ia32/ia32_common_transform.c b/ir/be/ia32/ia32_common_transform.c index 47578f0e4..3451b380e 100644 --- a/ir/be/ia32/ia32_common_transform.c +++ b/ir/be/ia32/ia32_common_transform.c @@ -33,7 +33,6 @@ #include "heights.h" #include "betranshlp.h" -#include "beirg.h" #include "beabi.h" #include "ia32_architecture.h" @@ -48,7 +47,6 @@ ir_heights_t *ia32_heights = NULL; static int check_immediate_constraint(long val, char immediate_constraint_type) { switch (immediate_constraint_type) { - case 0: case 'i': return 1; case 'I': return 0 <= val && val <= 31; @@ -116,9 +114,8 @@ ir_entity *ia32_create_float_const_entity(ia32_isa_t *isa, ir_tarval *tv, return res; } -ir_node *ia32_create_Immediate(ir_entity *symconst, int symconst_sign, long val) +ir_node *ia32_create_Immediate(ir_graph *const irg, ir_entity *const symconst, int const symconst_sign, long const 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, ia32_no_pic_adjust, val); @@ -271,9 +268,9 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, case 't': case 'u': /* TODO: mark values so the x87 simulator knows about t and u */ - if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_vfp]) + if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_fp]) panic("multiple register classes not supported"); - cls = &ia32_reg_classes[CLASS_ia32_vfp]; + cls = &ia32_reg_classes[CLASS_ia32_fp]; all_registers_allowed = 1; break; @@ -394,8 +391,8 @@ static bool can_match(const arch_register_req_t *in, { if (in->cls != out->cls) return false; - if ( (in->type & arch_register_req_type_limited) == 0 - || (out->type & arch_register_req_type_limited) == 0 ) + if (!arch_register_req_is(in, limited) || + !arch_register_req_is(out, limited)) return true; return (*in->limited & *out->limited) != 0; @@ -414,6 +411,8 @@ static inline ir_node *get_new_node(ir_node *node) #endif } +static arch_register_req_t const *ia32_make_register_req(ir_graph *irg, constraint_t const *constraint, int n_outs, arch_register_req_t const **out_reqs, int pos); + ir_node *ia32_gen_ASM(ir_node *node) { ir_node *block = get_nodes_block(node); @@ -474,9 +473,7 @@ ir_node *ia32_gen_ASM(ir_node *node) 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); + arch_register_req_t const *const req = ia32_make_register_req(irg, &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 @@ -520,9 +517,7 @@ ir_node *ia32_gen_ASM(ir_node *node) } } - const arch_register_req_t *req - = ia32_make_register_req(&parsed_constraint, n_out_constraints, - out_reg_reqs, i); + arch_register_req_t const *const req = ia32_make_register_req(irg, &parsed_constraint, n_out_constraints, out_reg_reqs, i); in_reg_reqs[i] = req; if (parsed_constraint.immediate_type != '\0') { @@ -618,7 +613,7 @@ ir_node *ia32_gen_ASM(ir_node *node) } /* add a new (dummy) input which occupies the register */ - assert(outreq->type & arch_register_req_type_limited); + assert(arch_register_req_is(outreq, limited)); in_reg_reqs[n_ins] = outreq; in[n_ins] = new_bd_ia32_ProduceVal(NULL, block); ++n_ins; @@ -660,7 +655,7 @@ ir_node *ia32_gen_ASM(ir_node *node) } /* add a new (dummy) output which occupies the register */ - assert(inreq->type & arch_register_req_type_limited); + assert(arch_register_req_is(inreq, limited)); out_reg_reqs[out_arity] = inreq; ++out_arity; } @@ -753,7 +748,7 @@ ir_node *ia32_gen_Unknown(ir_node *node) if (ia32_cg_config.use_sse2) { res = new_bd_ia32_xUnknown(dbgi, block); } else { - res = new_bd_ia32_vfldz(dbgi, block); + res = new_bd_ia32_fldz(dbgi, block); } } else if (ia32_mode_needs_gp_reg(mode)) { res = new_bd_ia32_Unknown(dbgi, block); @@ -764,58 +759,44 @@ ir_node *ia32_gen_Unknown(ir_node *node) return res; } -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) +static arch_register_req_t const *ia32_make_register_req(ir_graph *const irg, constraint_t const *const c, int const n_outs, arch_register_req_t const **const out_reqs, int const pos) { - struct obstack *obst = get_irg_obstack(current_ir_graph); - int same_as = constraint->same_as; - arch_register_req_t *req; - + int const same_as = c->same_as; if (same_as >= 0) { - const arch_register_req_t *other_constr; - if (same_as >= n_outs) panic("invalid output number in same_as constraint"); - other_constr = out_reqs[same_as]; - - req = OALLOC(obst, arch_register_req_t); - *req = *other_constr; - req->type |= arch_register_req_type_should_be_same; - req->other_same = 1U << pos; - req->width = 1; + struct obstack *const obst = get_irg_obstack(irg); + arch_register_req_t *const req = OALLOC(obst, arch_register_req_t); + arch_register_req_t const *const other = out_reqs[same_as]; + *req = *other; + req->type |= arch_register_req_type_should_be_same; + req->other_same = 1U << pos; - /* switch constraints. This is because in firm we have same_as + /* Switch constraints. This is because in firm we have same_as * constraints on the output constraints while in the gcc asm syntax - * they are specified on the input constraints */ + * they are specified on the input constraints. */ out_reqs[same_as] = req; - return other_constr; + return other; } - /* pure memory ops */ - if (constraint->cls == NULL) { + /* Pure memory ops. */ + if (!c->cls) return arch_no_register_req; - } - - if (constraint->allowed_registers != 0 - && !constraint->all_registers_allowed) { - unsigned *limited_ptr; - req = (arch_register_req_t*)obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned)); - memset(req, 0, sizeof(req[0])); - limited_ptr = (unsigned*) (req+1); + if (c->allowed_registers == 0 || c->all_registers_allowed) + return c->cls->class_req; - req->type = arch_register_req_type_limited; - *limited_ptr = constraint->allowed_registers; - req->limited = limited_ptr; - } else { - req = OALLOCZ(obst, arch_register_req_t); - req->type = arch_register_req_type_normal; - } - req->cls = constraint->cls; - req->width = 1; + struct obstack *const obst = get_irg_obstack(irg); + arch_register_req_t *const req = (arch_register_req_t*)obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned)); + unsigned *const limited = (unsigned*)(req + 1); + *limited = c->allowed_registers; + memset(req, 0, sizeof(req[0])); + req->type = arch_register_req_type_limited; + req->cls = c->cls; + req->limited = limited; + req->width = 1; return req; } @@ -824,27 +805,11 @@ 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; - unsigned *limited; - - if (reg == NULL) { + arch_register_t const *const reg = ia32_get_clobber_register(clobber); + if (!reg) panic("Register '%s' mentioned in asm clobber is unknown", clobber); - } - - assert(reg->index < 32); - limited = OALLOC(obst, unsigned); - *limited = 1 << reg->index; - - req = OALLOCZ(obst, arch_register_req_t); - req->type = arch_register_req_type_limited; - req->cls = reg->reg_class; - req->limited = limited; - req->width = 1; - - return req; + return reg->single_req; } @@ -888,18 +853,12 @@ int ia32_prevents_AM(ir_node *const block, ir_node *const am_candidate, 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; - - mode = get_irn_mode(node); - if (!mode_is_int(mode) && !mode_is_reference(mode)) { + ir_mode *const mode = get_irn_mode(node); + if (!mode_is_int(mode) && !mode_is_reference(mode)) return NULL; - } + ir_node *cnst; + ir_node *symconst; if (is_Const(node)) { cnst = node; symconst = NULL; @@ -916,11 +875,14 @@ ir_node *ia32_try_create_Immediate(ir_node *node, char immediate_constraint_type } else if (is_SymConst_addr_ent(left) && is_Const(right)) { cnst = right; symconst = left; + } else { + return NULL; } } else { return NULL; } + long val = 0; if (cnst != NULL) { ir_tarval *offset = get_Const_tarval(cnst); if (!tarval_is_long(offset)) { @@ -932,17 +894,16 @@ ir_node *ia32_try_create_Immediate(ir_node *node, char immediate_constraint_type if (!check_immediate_constraint(val, immediate_constraint_type)) return NULL; } + + ir_entity *symconst_ent = NULL; if (symconst != NULL) { - if (immediate_constraint_type != 0) { - /* we need full 32bits for symconsts */ + /* we need full 32bits for symconsts */ + if (immediate_constraint_type != 'i') return NULL; - } symconst_ent = get_SymConst_entity(symconst); } - if (cnst == NULL && symconst == NULL) - return NULL; - new_node = ia32_create_Immediate(symconst_ent, 0, val); - return new_node; + ir_graph *const irg = get_irn_irg(node); + return ia32_create_Immediate(irg, symconst_ent, 0, val); }