rework ASM node, it always has a memory input now
authorMatthias Braun <matthias.braun@kit.edu>
Mon, 23 Jul 2012 12:15:08 +0000 (14:15 +0200)
committerMatthias Braun <matthias.braun@kit.edu>
Mon, 23 Jul 2012 12:38:02 +0000 (14:38 +0200)
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.

include/libfirm/ircons.h
include/libfirm/irnode.h
ir/be/ia32/ia32_common_transform.c
ir/ir/ircons.c
ir/ir/irdumptxt.c
ir/ir/irio.c
ir/ir/irnode.c
ir/ir/irop.c
ir/lower/lower_dw.c

index edbe936..209411f 100644 (file)
@@ -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);
 
 /** @} */
index 80e9cfa..9c6d33a 100644 (file)
@@ -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.  */
index ba687c2..0e2fca7 100644 (file)
@@ -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;
index 28d838f..f3b3889 100644 (file)
@@ -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)
index 2fdd576..f07ad75 100644 (file)
@@ -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;
index ceb1917..7d4a15b 100644 (file)
@@ -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);
index ea6e47e..b9ff6b8 100644 (file)
@@ -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)
index cbe80e0..d8a11db 100644 (file)
@@ -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;
        }
index e8bee5a..f0bf63b 100644 (file)
@@ -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);
                }
        }
 }