Fixed some problems due to refactoring in previous revisions.
[libfirm] / ir / be / ia32 / ia32_common_transform.c
index cc6a7ae..d81b1cf 100644 (file)
@@ -33,7 +33,8 @@
 #include "bitset.h"
 
 #include "../betranshlp.h"
-#include "../beirg_t.h"
+#include "../beirg.h"
+#include "../beabi.h"
 
 #include "ia32_architecture.h"
 #include "ia32_common_transform.h"
@@ -471,6 +472,8 @@ ir_node *gen_ASM(ir_node *node)
        ident                     **clobbers;
        int                         clobbers_flags = 0;
        unsigned                    clobber_bits[N_CLASSES];
+       int                         out_size;
+       backend_info_t             *info;
 
        memset(&clobber_bits, 0, sizeof(clobber_bits));
 
@@ -543,7 +546,8 @@ ir_node *gen_ASM(ir_node *node)
        memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
 
        /* construct output constraints */
-       out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
+       out_size = out_arity + 1;
+       out_reg_reqs = obstack_alloc(obst, out_size * sizeof(out_reg_reqs[0]));
 
        for (out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
                const ir_asm_constraint   *constraint = &out_constraints[out_idx];
@@ -648,7 +652,7 @@ ir_node *gen_ASM(ir_node *node)
                ++out_idx;
        }
 
-       /* Attempt to make ASM node register pressure faithfull.
+       /* Attempt to make ASM node register pressure faithful.
         * (This does not work for complicated cases yet!)
         *
         * Algorithm: Check if there are fewer inputs or outputs (I will call this
@@ -714,7 +718,6 @@ ir_node *gen_ASM(ir_node *node)
                int       i;
                bitset_t *used_outs = bitset_alloca(out_arity);
                int       orig_out_arity = out_arity;
-               int       out_size       = out_arity;
                for (i = 0; i < arity; ++i) {
                        int   o;
                        const arch_register_req_t *inreq = in_reg_reqs[i];
@@ -756,13 +759,32 @@ ir_node *gen_ASM(ir_node *node)
                }
        }
 
+       /* append none register requirement for the memory output */
+       if (out_arity + 1 >= out_size) {
+               const arch_register_req_t **new_out_reg_reqs;
+
+               out_size = out_arity + 1;
+               new_out_reg_reqs
+                       = obstack_alloc(obst, out_size*sizeof(out_reg_reqs[0]));
+               memcpy(new_out_reg_reqs, out_reg_reqs,
+                          out_arity * sizeof(new_out_reg_reqs[0]));
+               out_reg_reqs = new_out_reg_reqs;
+       }
+
+       /* add a new (dummy) output which occupies the register */
+       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);
 
-       set_ia32_out_req_all(new_node, out_reg_reqs);
+       info = be_get_info(new_node);
+       for (i = 0; i < out_arity; ++i) {
+               info->out_infos[i].req = out_reg_reqs[i];
+       }
        set_ia32_in_req_all(new_node, in_reg_reqs);
 
        SET_IA32_ORIG_NODE(new_node, node);