From: Matthias Braun Date: Mon, 23 Jul 2012 12:15:08 +0000 (+0200) Subject: rework ASM node, it always has a memory input now X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=16a8ee53f0f3f4d5f67f81c35084e66ce0c2afd5;p=libfirm rework ASM node, it always has a memory input now You can still attach NoMem if no memory input is present. This makes it more consistent with the Call node and fixes failing get_ASM_mem in case of no memory input. --- diff --git a/include/libfirm/ircons.h b/include/libfirm/ircons.h index edbe936e8..209411f6d 100644 --- a/include/libfirm/ircons.h +++ b/include/libfirm/ircons.h @@ -734,6 +734,7 @@ FIRM_API ir_node *new_DivRL(ir_node *memop, ir_node *op1, ir_node *op2, * * @param *db A pointer for debug information. * @param *block The block the node belong to. + * @param *mem memory dependency * @param arity The number of data inputs to the node. * @param *in The array of length arity of data inputs. * @param *inputs The array of length arity of input constraints. @@ -743,7 +744,7 @@ FIRM_API ir_node *new_DivRL(ir_node *memop, ir_node *op1, ir_node *op2, * @param *clobber The array of length n_clobber of clobbered registers. * @param *asm_text The assembler text. */ -FIRM_API ir_node *new_rd_ASM(dbg_info *db, ir_node *block, +FIRM_API ir_node *new_rd_ASM(dbg_info *db, ir_node *block, ir_node *mem, int arity, ir_node *in[], ir_asm_constraint *inputs, size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber, ident *clobber[], @@ -752,6 +753,7 @@ FIRM_API ir_node *new_rd_ASM(dbg_info *db, ir_node *block, /** Constructor for an ASM pseudo node. * * @param *block The block the node belong to. + * @param *mem memory dependency * @param arity The number of data inputs to the node. * @param *in The array of length arity of data inputs. * @param *inputs The array of length arity of input constraints. @@ -761,7 +763,7 @@ FIRM_API ir_node *new_rd_ASM(dbg_info *db, ir_node *block, * @param *clobber The array of length n_clobber of clobbered registers. * @param *asm_text The assembler text. */ -FIRM_API ir_node *new_r_ASM(ir_node *block, +FIRM_API ir_node *new_r_ASM(ir_node *block, ir_node *mem, int arity, ir_node *in[], ir_asm_constraint *inputs, size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber, ident *clobber[], @@ -770,6 +772,7 @@ FIRM_API ir_node *new_r_ASM(ir_node *block, /** Constructor for an ASM pseudo node. * * @param *db A pointer for debug information. + * @param *mem memory dependency * @param arity The number of data inputs to the node. * @param *in The array of length arity of data inputs. * @param *inputs The array of length arity of input constraints. @@ -780,14 +783,15 @@ FIRM_API ir_node *new_r_ASM(ir_node *block, * @param *asm_text The assembler text. * @ingroup ASM */ -FIRM_API ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[], - ir_asm_constraint *inputs, +FIRM_API ir_node *new_d_ASM(dbg_info *db, ir_node *mem, int arity, + ir_node *in[], ir_asm_constraint *inputs, size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber, ident *clobber[], ident *asm_text); /** Constructor for an ASM pseudo node. * + * @param *mem memory dependency * @param arity The number of data inputs to the node. * @param *in The array of length arity of data inputs. * @param *inputs The array of length arity of input constraints. @@ -798,8 +802,9 @@ FIRM_API ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[], * @param *asm_text The assembler text. * @ingroup ASM */ -FIRM_API ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs, - size_t n_outs, ir_asm_constraint *outputs, +FIRM_API ir_node *new_ASM(ir_node *mem, int arity, ir_node *in[], + ir_asm_constraint *inputs, size_t n_outs, + ir_asm_constraint *outputs, size_t n_clobber, ident *clobber[], ident *asm_text); /** @} */ diff --git a/include/libfirm/irnode.h b/include/libfirm/irnode.h index 80e9cfa8e..9c6d33a64 100644 --- a/include/libfirm/irnode.h +++ b/include/libfirm/irnode.h @@ -689,7 +689,9 @@ FIRM_API void set_Tuple_pred(ir_node *node, int pos, ir_node *pred); */ /** Returns the number of input constraints for an ASM node. */ -FIRM_API size_t get_ASM_n_input_constraints(const ir_node *node); +FIRM_API int get_ASM_n_inputs(const ir_node *node); +/** Returns input number @p pos of an ASM node. */ +FIRM_API ir_node *get_ASM_input(const ir_node *node, int pos); /** Returns the number of output constraints for an ASM node. */ FIRM_API size_t get_ASM_n_output_constraints(const ir_node *node); /** Returns the number of clobbered registers for an ASM node. */ diff --git a/ir/be/ia32/ia32_common_transform.c b/ir/be/ia32/ia32_common_transform.c index ba687c242..0e2fca788 100644 --- a/ir/be/ia32/ia32_common_transform.c +++ b/ir/be/ia32/ia32_common_transform.c @@ -416,90 +416,66 @@ static inline ir_node *get_new_node(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 arity; - size_t value_arity; - size_t out_idx; - ir_node **in; - ir_node *new_node; - size_t out_arity; - size_t n_out_constraints; - size_t 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; - unsigned clobber_bits[N_IA32_CLASSES]; - size_t out_size; - backend_info_t *info; - int i; - size_t c; - size_t o; - + 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)); - arity = get_irn_arity(node); - in = ALLOCANZ(ir_node*, arity); - - clobbers = get_ASM_clobbers(node); - n_clobbers = 0; - for (c = 0; c < get_ASM_n_clobbers(node); ++c) { - const arch_register_req_t *req; + for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) { const char *clobber = get_id_str(clobbers[c]); - - if (strcmp(clobber, "memory") == 0) + const arch_register_req_t *req = ia32_parse_clobber(clobber); + if (req == NULL) continue; - if (strcmp(clobber, "cc") == 0) { - continue; - } - req = ia32_parse_clobber(clobber); 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 = OALLOCN(obst, const arch_register_req_t*, out_size); + 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; - + 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); - req = ia32_make_register_req(&parsed_constraint, n_out_constraints, + 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; @@ -517,26 +493,26 @@ ir_node *ia32_gen_ASM(ir_node *node) } /* inputs + input constraints */ - in_reg_reqs = OALLOCN(obst, const arch_register_req_t*, arity); - 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, 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_set_allocatable_regs(current_ir_graph, + be_set_allocatable_regs(irg, parsed_constraint.cls, &parsed_constraint.allowed_registers); } @@ -544,8 +520,9 @@ ir_node *ia32_gen_ASM(ir_node *node) } } - req = ia32_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') { @@ -572,28 +549,21 @@ ir_node *ia32_gen_ASM(ir_node *node) register_map[pos].mode = constraint->mode; } + 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; + /* parse clobbers */ - for (c = 0; c < get_ASM_n_clobbers(node); ++c) { + 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; - - if (strcmp(clobber, "memory") == 0 || strcmp(clobber, "cc") == 0) + const arch_register_req_t *req = ia32_parse_clobber(clobber); + if (req == NULL) continue; - - req = ia32_parse_clobber(clobber); 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 *node_in = get_irn_n(node, i); - if (get_irn_mode(node_in) == mode_M) - continue; - ++value_arity; - } - /* Attempt to make ASM node register pressure faithful. * (This does not work for complicated cases yet!) * @@ -606,43 +576,41 @@ ir_node *ia32_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; - bitset_t *used_ins = bitset_alloca(arity); - size_t o; - for (o = 0; o < out_arity; ++o) { + 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 = OALLOCN(obst, const arch_register_req_t*, + 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, arity * sizeof(new_in_reg_reqs[0])); - new_in = ALLOCANZ(ir_node*, in_size); - memcpy(new_in, in, arity*sizeof(new_in[0])); + 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; @@ -650,21 +618,20 @@ 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); - in_reg_reqs[arity] = outreq; - in[arity] = new_bd_ia32_ProduceVal(NULL, block); - ++arity; + in_reg_reqs[n_ins] = outreq; + in[n_ins] = new_bd_ia32_ProduceVal(NULL, block); + ++n_ins; } } else { bitset_t *used_outs = bitset_alloca(out_arity); size_t orig_out_arity = out_arity; - for (i = 0; i < arity; ++i) { + for (int i = 0; i < n_inputs; ++i) { const arch_register_req_t *inreq = in_reg_reqs[i]; - size_t o; - 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)) @@ -714,11 +681,11 @@ ir_node *ia32_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); + 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 (o = 0; o < out_arity; ++o) { + 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_irn_register_reqs_in(new_node, in_reg_reqs); @@ -796,8 +763,9 @@ 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) +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; @@ -852,6 +820,9 @@ const arch_register_req_t *ia32_make_register_req(const constraint_t *constraint 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; diff --git a/ir/ir/ircons.c b/ir/ir/ircons.c index 28d838fe0..f3b3889fe 100644 --- a/ir/ir/ircons.c +++ b/ir/ir/ircons.c @@ -56,13 +56,20 @@ ir_node *new_rd_Const_long(dbg_info *db, ir_graph *irg, ir_mode *mode, return new_rd_Const(db, irg, new_tarval_from_long(value, mode)); } -ir_node *new_rd_ASM(dbg_info *db, ir_node *block, int arity, ir_node *in[], - ir_asm_constraint *inputs, size_t n_outs, - ir_asm_constraint *outputs, size_t n_clobber, +ir_node *new_rd_ASM(dbg_info *db, ir_node *block, ir_node *mem, + int arity, ir_node *in[], ir_asm_constraint *inputs, + size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber, ident *clobber[], ident *text) { ir_graph *irg = get_irn_irg(block); - ir_node *res = new_ir_node(db, irg, block, op_ASM, mode_T, arity, in); + + int r_arity = arity+1; + ir_node **r_in; + NEW_ARR_A(ir_node*, r_in, r_arity); + r_in[0] = mem; + memcpy(&r_in[1], in, arity*sizeof(ir_node*)); + + ir_node *res = new_ir_node(db, irg, block, op_ASM, mode_T, r_arity, r_in); res->attr.assem.pin_state = op_pin_state_pinned; res->attr.assem.input_constraints @@ -142,12 +149,12 @@ ir_node *new_r_simpleSel(ir_node *block, ir_node *store, ir_node *objptr, { return new_rd_Sel(NULL, block, store, objptr, 0, NULL, ent); } -ir_node *new_r_ASM(ir_node *block, +ir_node *new_r_ASM(ir_node *block, ir_node *mem, int arity, ir_node *in[], ir_asm_constraint *inputs, size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber, ident *clobber[], ident *text) { - return new_rd_ASM(NULL, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text); + return new_rd_ASM(NULL, block, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text); } /** Creates a Phi node with 0 predecessors. */ @@ -387,14 +394,14 @@ ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode, symconst_symbol value, return new_rd_SymConst(db, current_ir_graph, mode, value, kind); } -ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[], +ir_node *new_d_ASM(dbg_info *db, ir_node *mem, int arity, ir_node *in[], ir_asm_constraint *inputs, size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber, ident *clobber[], ident *text) { assert(get_irg_phase_state(current_ir_graph) == phase_building); - return new_rd_ASM(db, current_ir_graph->current_block, arity, in, inputs, - n_outs, outputs, n_clobber, clobber, text); + return new_rd_ASM(db, current_ir_graph->current_block, mem, arity, in, + inputs, n_outs, outputs, n_clobber, clobber, text); } ir_node *new_rd_strictConv(dbg_info *dbgi, ir_node *block, ir_node * irn_op, ir_mode * mode) @@ -724,11 +731,12 @@ ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent) { return new_d_simpleSel(NULL, store, objptr, ent); } -ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs, - size_t n_outs, ir_asm_constraint *outputs, - size_t n_clobber, ident *clobber[], ident *text) +ir_node *new_ASM(ir_node *mem, int arity, ir_node *in[], + ir_asm_constraint *inputs, size_t n_outs, + ir_asm_constraint *outputs, size_t n_clobber, + ident *clobber[], ident *text) { - return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text); + return new_d_ASM(NULL, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text); } ir_node *new_r_Anchor(ir_graph *irg) diff --git a/ir/ir/irdumptxt.c b/ir/ir/irdumptxt.c index 2fdd57645..f07ad7591 100644 --- a/ir/ir/irdumptxt.c +++ b/ir/ir/irdumptxt.c @@ -276,39 +276,32 @@ void dump_irnode_to_file(FILE *F, const ir_node *n) fprintf(F, " compare operation: %s\n", get_relation_string(get_Confirm_relation(n))); break; case iro_ASM: { - const ir_asm_constraint *cons; - ident **clobber; - int l; - fprintf(F, " assembler text: %s", get_id_str(get_ASM_text(n))); - l = get_ASM_n_input_constraints(n); - if (l > 0) { - int i; - fprintf(F, "\n inputs: "); - cons = get_ASM_input_constraints(n); - for (i = 0; i < l; ++i) - fprintf(F, "%%%u %s ", cons[i].pos, get_id_str(cons[i].constraint)); - } - l = get_ASM_n_output_constraints(n); - if (l > 0) { - int i; - fprintf(F, "\n outputs: "); - cons = get_ASM_output_constraints(n); - for (i = 0; i < l; ++i) - fprintf(F, "%%%u %s ", cons[i].pos, get_id_str(cons[i].constraint)); + fprintf(F, "\n inputs: "); + const ir_asm_constraint *in_cons = get_ASM_input_constraints(n); + int n_inputs = get_ASM_n_inputs(n); + for (int i = 0; i < n_inputs; ++i) { + fprintf(F, "%%%u %s ", in_cons[i].pos, + get_id_str(in_cons[i].constraint)); } - l = get_ASM_n_clobbers(n); - if (l > 0) { - int i; - fprintf(F, "\n clobber: "); - clobber = get_ASM_clobbers(n); - for (i = 0; i < l; ++i) - fprintf(F, "%s ", get_id_str(clobber[i])); + fprintf(F, "\n outputs: "); + const ir_asm_constraint *out_cons = get_ASM_output_constraints(n); + int n_outputs = get_ASM_n_output_constraints(n); + for (int i = 0; i < n_outputs; ++i) { + fprintf(F, "%%%u %s ", out_cons[i].pos, + get_id_str(out_cons[i].constraint)); } + + fprintf(F, "\n clobber: "); + ident **clobber = get_ASM_clobbers(n); + int n_clobbers = get_ASM_n_clobbers(n); + for (int i = 0; i < n_clobbers; ++i) + fprintf(F, "%s ", get_id_str(clobber[i])); if (get_irn_pinned(n) != op_pin_state_floats) fprintf(F, "\n volatile"); fprintf(F, "\n"); - } break; + break; + } default: break; diff --git a/ir/ir/irio.c b/ir/ir/irio.c index ceb191788..7d4a15bea 100644 --- a/ir/ir/irio.c +++ b/ir/ir/irio.c @@ -881,21 +881,16 @@ static void write_node_nr(write_env_t *env, const ir_node *node) static void write_ASM(write_env_t *env, const ir_node *node) { - ir_asm_constraint *input_constraints = get_ASM_input_constraints(node); - ir_asm_constraint *output_constraints = get_ASM_output_constraints(node); - ident **clobbers = get_ASM_clobbers(node); - size_t n_input_constraints = get_ASM_n_input_constraints(node); - size_t n_output_constraints = get_ASM_n_output_constraints(node); - size_t n_clobbers = get_ASM_n_clobbers(node); - size_t i; - write_symbol(env, "ASM"); write_node_nr(env, node); write_node_nr(env, get_nodes_block(node)); + write_node_nr(env, get_ASM_mem(node)); write_ident(env, get_ASM_text(node)); write_list_begin(env); - for (i = 0; i < n_input_constraints; ++i) { + ir_asm_constraint *input_constraints = get_ASM_input_constraints(node); + int n_inputs = get_ASM_n_inputs(node); + for (int i = 0; i < n_inputs; ++i) { const ir_asm_constraint *constraint = &input_constraints[i]; write_unsigned(env, constraint->pos); write_ident(env, constraint->constraint); @@ -904,7 +899,9 @@ static void write_ASM(write_env_t *env, const ir_node *node) write_list_end(env); write_list_begin(env); - for (i = 0; i < n_output_constraints; ++i) { + ir_asm_constraint *output_constraints = get_ASM_output_constraints(node); + size_t n_output_constraints = get_ASM_n_output_constraints(node); + for (size_t i = 0; i < n_output_constraints; ++i) { const ir_asm_constraint *constraint = &output_constraints[i]; write_unsigned(env, constraint->pos); write_ident(env, constraint->constraint); @@ -913,7 +910,9 @@ static void write_ASM(write_env_t *env, const ir_node *node) write_list_end(env); write_list_begin(env); - for (i = 0; i < n_clobbers; ++i) { + ident **clobbers = get_ASM_clobbers(node); + size_t n_clobbers = get_ASM_n_clobbers(node); + for (size_t i = 0; i < n_clobbers; ++i) { ident *clobber = clobbers[i]; write_ident(env, clobber); } @@ -2093,6 +2092,7 @@ static ir_node *read_ASM(read_env_t *env) ir_asm_constraint *output_constraints = NEW_ARR_F(ir_asm_constraint, 0); ident **clobbers = NEW_ARR_F(ident*, 0); ir_node *block = read_node_ref(env); + ir_node *mem = read_node_ref(env); op_pin_state pin_state; ident *asm_text = read_ident(env); @@ -2131,7 +2131,7 @@ static ir_node *read_ASM(read_env_t *env) return new_r_Bad(env->irg, mode_T); } - newnode = new_r_ASM(block, n_in, in, + newnode = new_r_ASM(block, mem, n_in, in, input_constraints, ARR_LEN(output_constraints), output_constraints, ARR_LEN(clobbers), clobbers, asm_text); diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index ea6e47e95..b9ff6b8ce 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -50,6 +50,7 @@ in the in array */ #define CALL_PARAM_OFFSET (n_Call_max+1) #define BUILTIN_PARAM_OFFSET (n_Builtin_max+1) +#define ASM_PARAM_OFFSET (n_ASM_max+1) #define SEL_INDEX_OFFSET (n_Sel_max+1) #define RETURN_RESULT_OFFSET (n_Return_max+1) #define END_KEEPALIVE_OFFSET 0 @@ -1244,10 +1245,15 @@ void set_Tuple_pred(ir_node *node, int pos, ir_node *pred) set_irn_n(node, pos, pred); } -size_t get_ASM_n_input_constraints(const ir_node *node) +int get_ASM_n_inputs(const ir_node *node) { assert(is_ASM(node)); - return ARR_LEN(node->attr.assem.input_constraints); + return get_irn_arity(node) - ASM_PARAM_OFFSET; +} + +ir_node *get_ASM_input(const ir_node *node, int pos) +{ + return get_irn_n(node, ASM_PARAM_OFFSET + pos); } size_t get_ASM_n_output_constraints(const ir_node *node) diff --git a/ir/ir/irop.c b/ir/ir/irop.c index cbe80e0c1..d8a11db6e 100644 --- a/ir/ir/irop.c +++ b/ir/ir/irop.c @@ -442,47 +442,42 @@ static int node_cmp_attr_Builtin(const ir_node *a, const ir_node *b) /** Compares the attributes of two ASM nodes. */ static int node_cmp_attr_ASM(const ir_node *a, const ir_node *b) { - size_t n; - size_t i; - const ir_asm_constraint *ca; - const ir_asm_constraint *cb; - ident **cla, **clb; - if (get_ASM_text(a) != get_ASM_text(b)) return 1; - /* Should we really check the constraints here? Should be better, but is strange. */ - n = get_ASM_n_input_constraints(a); - if (n != get_ASM_n_input_constraints(b)) + int n_inputs = get_ASM_n_inputs(a); + if (n_inputs != get_ASM_n_inputs(b)) return 1; - ca = get_ASM_input_constraints(a); - cb = get_ASM_input_constraints(b); - for (i = 0; i < n; ++i) { - if (ca[i].pos != cb[i].pos || ca[i].constraint != cb[i].constraint - || ca[i].mode != cb[i].mode) + const ir_asm_constraint *in_a = get_ASM_input_constraints(a); + const ir_asm_constraint *in_b = get_ASM_input_constraints(b); + for (int i = 0; i < n_inputs; ++i) { + if (in_a[i].pos != in_b[i].pos + || in_a[i].constraint != in_b[i].constraint + || in_a[i].mode != in_b[i].mode) return 1; } - n = get_ASM_n_output_constraints(a); - if (n != get_ASM_n_output_constraints(b)) + size_t n_outputs = get_ASM_n_output_constraints(a); + if (n_outputs != get_ASM_n_output_constraints(b)) return 1; - ca = get_ASM_output_constraints(a); - cb = get_ASM_output_constraints(b); - for (i = 0; i < n; ++i) { - if (ca[i].pos != cb[i].pos || ca[i].constraint != cb[i].constraint - || ca[i].mode != cb[i].mode) + const ir_asm_constraint *out_a = get_ASM_output_constraints(a); + const ir_asm_constraint *out_b = get_ASM_output_constraints(b); + for (size_t i = 0; i < n_outputs; ++i) { + if (out_a[i].pos != out_b[i].pos + || out_a[i].constraint != out_b[i].constraint + || out_a[i].mode != out_b[i].mode) return 1; } - n = get_ASM_n_clobbers(a); - if (n != get_ASM_n_clobbers(b)) + size_t n_clobbers = get_ASM_n_clobbers(a); + if (n_clobbers != get_ASM_n_clobbers(b)) return 1; - cla = get_ASM_clobbers(a); - clb = get_ASM_clobbers(b); - for (i = 0; i < n; ++i) { + ident **cla = get_ASM_clobbers(a); + ident **clb = get_ASM_clobbers(b); + for (size_t i = 0; i < n_clobbers; ++i) { if (cla[i] != clb[i]) return 1; } diff --git a/ir/lower/lower_dw.c b/ir/lower/lower_dw.c index e8bee5a5a..f0bf63b56 100644 --- a/ir/lower/lower_dw.c +++ b/ir/lower/lower_dw.c @@ -2243,11 +2243,10 @@ static void lower_ASM(ir_node *asmn, ir_mode *mode) ir_asm_constraint *output_constraints = get_ASM_output_constraints(asmn); ir_asm_constraint *input_constraints = get_ASM_input_constraints(asmn); unsigned n_64bit_outs = 0; - int i; (void)mode; - for (i = get_irn_arity(asmn) - 1; i >= 0; --i) { + for (int i = get_irn_arity(asmn) - 1; i >= 0; --i) { ir_node *op = get_irn_n(asmn, i); ir_mode *op_mode = get_irn_mode(op); if (op_mode == high_signed || op_mode == high_unsigned) { @@ -2255,8 +2254,8 @@ static void lower_ASM(ir_node *asmn, ir_mode *mode) } } - for (i = 0; i < n_outs; ++i) { - const ir_asm_constraint *constraint = &output_constraints[i]; + for (int o = 0; o < n_outs; ++o) { + const ir_asm_constraint *constraint = &output_constraints[o]; if (constraint->mode == high_signed || constraint->mode == high_unsigned) { const char *constr = get_id_str(constraint->constraint); ++n_64bit_outs; @@ -2271,71 +2270,73 @@ static void lower_ASM(ir_node *asmn, ir_mode *mode) if (n_64bit_outs == 0) return; - { - dbg_info *dbgi = get_irn_dbg_info(asmn); - ir_node *block = get_nodes_block(asmn); - int arity = get_irn_arity(asmn); - ir_node **in = get_irn_in(asmn) + 1; - int new_n_outs = 0; - int n_clobber = get_ASM_n_clobbers(asmn); - long *proj_map = ALLOCAN(long, n_outs); - ident **clobbers = get_ASM_clobbers(asmn); - ident *asm_text = get_ASM_text(asmn); - ir_asm_constraint *new_outputs - = ALLOCAN(ir_asm_constraint, n_outs+n_64bit_outs); - ir_node *new_asm; - - for (i = 0; i < n_outs; ++i) { - const ir_asm_constraint *constraint = &output_constraints[i]; - if (constraint->mode == high_signed || constraint->mode == high_unsigned) { - new_outputs[new_n_outs].pos = constraint->pos; - new_outputs[new_n_outs].constraint = new_id_from_str("=a"); - new_outputs[new_n_outs].mode = env->low_unsigned; - proj_map[i] = new_n_outs; - ++new_n_outs; - new_outputs[new_n_outs].pos = constraint->pos; - new_outputs[new_n_outs].constraint = new_id_from_str("=d"); - if (constraint->mode == high_signed) - new_outputs[new_n_outs].mode = env->low_signed; - else - new_outputs[new_n_outs].mode = env->low_unsigned; - ++new_n_outs; - } else { - new_outputs[new_n_outs] = *constraint; - proj_map[i] = new_n_outs; - ++new_n_outs; - } + dbg_info *dbgi = get_irn_dbg_info(asmn); + ir_node *block = get_nodes_block(asmn); + ir_node *mem = get_ASM_mem(asmn); + int new_n_outs = 0; + int n_clobber = get_ASM_n_clobbers(asmn); + long *proj_map = ALLOCAN(long, n_outs); + ident **clobbers = get_ASM_clobbers(asmn); + ident *asm_text = get_ASM_text(asmn); + ir_asm_constraint *new_outputs + = ALLOCAN(ir_asm_constraint, n_outs+n_64bit_outs); + ir_node *new_asm; + + for (int o = 0; o < n_outs; ++o) { + const ir_asm_constraint *constraint = &output_constraints[o]; + if (constraint->mode == high_signed || constraint->mode == high_unsigned) { + new_outputs[new_n_outs].pos = constraint->pos; + new_outputs[new_n_outs].constraint = new_id_from_str("=a"); + new_outputs[new_n_outs].mode = env->low_unsigned; + proj_map[o] = new_n_outs; + ++new_n_outs; + new_outputs[new_n_outs].pos = constraint->pos; + new_outputs[new_n_outs].constraint = new_id_from_str("=d"); + if (constraint->mode == high_signed) + new_outputs[new_n_outs].mode = env->low_signed; + else + new_outputs[new_n_outs].mode = env->low_unsigned; + ++new_n_outs; + } else { + new_outputs[new_n_outs] = *constraint; + proj_map[o] = new_n_outs; + ++new_n_outs; } - assert(new_n_outs == n_outs+(int)n_64bit_outs); + } + assert(new_n_outs == n_outs+(int)n_64bit_outs); - new_asm = new_rd_ASM(dbgi, block, arity, in, input_constraints, - new_n_outs, new_outputs, n_clobber, clobbers, - asm_text); + int n_inputs = get_ASM_n_inputs(asmn); + ir_node **new_ins = ALLOCAN(ir_node*, n_inputs); + for (int i = 0; i < n_inputs; ++i) + new_ins[i] = get_ASM_input(asmn, i); - foreach_out_edge_safe(asmn, edge) { - ir_node *proj = get_edge_src_irn(edge); - ir_mode *proj_mode = get_irn_mode(proj); - long pn; + new_asm = new_rd_ASM(dbgi, block, mem, n_inputs, new_ins, input_constraints, + new_n_outs, new_outputs, n_clobber, clobbers, + asm_text); - if (!is_Proj(proj)) - continue; - pn = get_Proj_proj(proj); + foreach_out_edge_safe(asmn, edge) { + ir_node *proj = get_edge_src_irn(edge); + ir_mode *proj_mode = get_irn_mode(proj); + long pn; - if (pn < n_outs) - pn = proj_map[pn]; - else - pn = new_n_outs + pn - n_outs; - - if (proj_mode == high_signed || proj_mode == high_unsigned) { - ir_mode *high_mode - = proj_mode == high_signed ? env->low_signed : env->low_unsigned; - ir_node *np_low = new_r_Proj(new_asm, env->low_unsigned, pn); - ir_node *np_high = new_r_Proj(new_asm, high_mode, pn+1); - ir_set_dw_lowered(proj, np_low, np_high); - } else { - ir_node *np = new_r_Proj(new_asm, proj_mode, pn); - exchange(proj, np); - } + if (!is_Proj(proj)) + continue; + pn = get_Proj_proj(proj); + + if (pn < n_outs) + pn = proj_map[pn]; + else + pn = new_n_outs + pn - n_outs; + + if (proj_mode == high_signed || proj_mode == high_unsigned) { + ir_mode *high_mode + = proj_mode == high_signed ? env->low_signed : env->low_unsigned; + ir_node *np_low = new_r_Proj(new_asm, env->low_unsigned, pn); + ir_node *np_high = new_r_Proj(new_asm, high_mode, pn+1); + ir_set_dw_lowered(proj, np_low, np_high); + } else { + ir_node *np = new_r_Proj(new_asm, proj_mode, pn); + exchange(proj, np); } } }