- implemented ull -> float conversion for x87
[libfirm] / ir / be / ia32 / ia32_x87.c
index 5d91bd3..e67bf47 100644 (file)
@@ -380,7 +380,7 @@ static x87_state *x87_clone_state(x87_simulator *sim, const x87_state *src)
 {
        x87_state *res = x87_alloc_state(sim);
 
-       memcpy(res, src, sizeof(*res));
+       *res = *src;
        return res;
 }  /* x87_clone_state */
 
@@ -442,7 +442,7 @@ static ir_node *get_irn_Proj_for_mode(ir_node *n, ir_mode *m)
 /**
  * Wrap the arch_* function here so we can check for errors.
  */
-static INLINE const arch_register_t *x87_get_irn_register(const ir_node *irn)
+static inline const arch_register_t *x87_get_irn_register(const ir_node *irn)
 {
        const arch_register_t *res = arch_get_irn_register(irn);
 
@@ -450,6 +450,15 @@ static INLINE const arch_register_t *x87_get_irn_register(const ir_node *irn)
        return res;
 }  /* x87_get_irn_register */
 
+static inline const arch_register_t *x87_irn_get_register(const ir_node *irn,
+                                                          int pos)
+{
+       const arch_register_t *res = arch_irn_get_register(irn, pos);
+
+       assert(res->reg_class->regs == ia32_vfp_regs);
+       return res;
+}
+
 /* -------------- x87 perm --------------- */
 
 /**
@@ -469,7 +478,7 @@ static ir_node *x87_fxch_shuffle(x87_state *state, int pos, ir_node *block)
        ir_node         *fxch;
        ia32_x87_attr_t *attr;
 
-       fxch = new_rd_ia32_fxch(NULL, get_irn_irg(block), block);
+       fxch = new_bd_ia32_fxch(NULL, block);
        attr = get_ia32_x87_attr(fxch);
        attr->x87[0] = &ia32_st_regs[pos];
        attr->x87[2] = &ia32_st_regs[0];
@@ -634,12 +643,11 @@ static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos)
 {
        ir_node         *fxch;
        ia32_x87_attr_t *attr;
-       ir_graph        *irg = get_irn_irg(n);
        ir_node         *block = get_nodes_block(n);
 
        x87_fxch(state, pos);
 
-       fxch = new_rd_ia32_fxch(NULL, irg, block);
+       fxch = new_bd_ia32_fxch(NULL, block);
        attr = get_ia32_x87_attr(fxch);
        attr->x87[0] = &ia32_st_regs[pos];
        attr->x87[2] = &ia32_st_regs[0];
@@ -667,7 +675,7 @@ static void x87_create_fpush(x87_state *state, ir_node *n, int pos, int op_idx)
 
        x87_push_dbl(state, arch_register_get_index(out), pred);
 
-       fpush = new_rd_ia32_fpush(NULL, get_irn_irg(n), get_nodes_block(n));
+       fpush = new_bd_ia32_fpush(NULL, get_nodes_block(n));
        attr  = get_ia32_x87_attr(fpush);
        attr->x87[0] = &ia32_st_regs[pos];
        attr->x87[2] = &ia32_st_regs[0];
@@ -696,9 +704,9 @@ static ir_node *x87_create_fpop(x87_state *state, ir_node *n, int num)
        while (num > 0) {
                x87_pop(state);
                if (ia32_cg_config.use_ffreep)
-                       fpop = new_rd_ia32_ffreep(NULL, get_irn_irg(n), get_nodes_block(n));
+                       fpop = new_bd_ia32_ffreep(NULL, get_nodes_block(n));
                else
-                       fpop = new_rd_ia32_fpop(NULL, get_irn_irg(n), get_nodes_block(n));
+                       fpop = new_bd_ia32_fpop(NULL, get_nodes_block(n));
                attr = get_ia32_x87_attr(fpop);
                attr->x87[0] = &ia32_st_regs[0];
                attr->x87[1] = &ia32_st_regs[0];
@@ -723,11 +731,10 @@ static ir_node *x87_create_fpop(x87_state *state, ir_node *n, int num)
  */
 static ir_node *x87_create_fldz(x87_state *state, ir_node *n, int regidx)
 {
-       ir_graph *irg = get_irn_irg(n);
        ir_node *block = get_nodes_block(n);
        ir_node *fldz;
 
-       fldz = new_rd_ia32_fldz(NULL, irg, block, mode_E);
+       fldz = new_bd_ia32_fldz(NULL, block, mode_E);
 
        sched_add_before(n, fldz);
        DB((dbg, LEVEL_1, "<<< %s\n", get_irn_opname(fldz)));
@@ -893,8 +900,6 @@ static void vfp_dump_live(vfp_liveness live)
 
 /* --------------------------------- simulators ---------------------------------------- */
 
-#define XCHG(a, b) do { int t = (a); (a) = (b); (b) = t; } while (0)
-
 /* Pseudocode:
 
 
@@ -926,7 +931,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl)
        ir_node               *op2     = get_irn_n(n, n_ia32_binary_right);
        const arch_register_t *op1_reg = x87_get_irn_register(op1);
        const arch_register_t *op2_reg = x87_get_irn_register(op2);
-       const arch_register_t *out     = x87_get_irn_register(n);
+       const arch_register_t *out     = x87_irn_get_register(n, pn_ia32_res);
        int reg_index_1                = arch_register_get_index(op1_reg);
        int reg_index_2                = arch_register_get_index(op2_reg);
        vfp_liveness           live    = vfp_live_args_after(sim, n, REGMASK(out));
@@ -1144,14 +1149,14 @@ static int sim_unop(x87_state *state, ir_node *n, ir_op *op)
  *
  * @return NO_NODE_ADDED
  */
-static int sim_load(x87_state *state, ir_node *n, ir_op *op)
+static int sim_load(x87_state *state, ir_node *n, ir_op *op, int res_pos)
 {
-       const arch_register_t *out = x87_get_irn_register(n);
+       const arch_register_t *out = x87_irn_get_register(n, res_pos);
        ia32_x87_attr_t *attr;
 
        DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, arch_register_get_name(out)));
        x87_push(state, arch_register_get_index(out), x87_patch_insn(n, op));
-       assert(out == x87_get_irn_register(n));
+       assert(out == x87_irn_get_register(n, res_pos));
        attr = get_ia32_x87_attr(n);
        attr->x87[2] = out = &ia32_st_regs[0];
        DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
@@ -1254,8 +1259,7 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
                                x87_patch_insn(n, op_p);
 
                                block = get_nodes_block(n);
-                               irg   = get_irn_irg(n);
-                               vfld  = new_rd_ia32_vfld(NULL, irg, block, get_irn_n(n, 0), get_irn_n(n, 1), new_rd_NoMem(irg), get_ia32_ls_mode(n));
+                               vfld  = new_bd_ia32_vfld(NULL, block, get_irn_n(n, 0), get_irn_n(n, 1), new_NoMem(), get_ia32_ls_mode(n));
 
                                /* copy all attributes */
                                set_ia32_frame_ent(vfld, get_ia32_frame_ent(n));
@@ -1266,6 +1270,7 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
                                set_ia32_am_sc(vfld, get_ia32_am_sc(n));
                                set_ia32_ls_mode(vfld, get_ia32_ls_mode(n));
 
+                               irg   = get_irn_irg(n);
                                rproj = new_r_Proj(irg, block, vfld, get_ia32_ls_mode(vfld), pn_ia32_vfld_res);
                                mproj = new_r_Proj(irg, block, vfld, mode_M, pn_ia32_vfld_M);
                                mem   = get_irn_Proj_for_mode(n, mode_M);
@@ -1320,13 +1325,11 @@ static int sim_##op(x87_state *state, ir_node *n) { \
 #define GEN_BINOP(op)   _GEN_BINOP(op, op)
 #define GEN_BINOPR(op) _GEN_BINOP(op, op##r)
 
-#define GEN_LOAD2(op, nop) \
-static int sim_##op(x87_state *state, ir_node *n) { \
-       return sim_load(state, n, op_ia32_##nop); \
+#define GEN_LOAD(op)                                              \
+static int sim_##op(x87_state *state, ir_node *n) {               \
+       return sim_load(state, n, op_ia32_##op, pn_ia32_v##op##_res); \
 }
 
-#define GEN_LOAD(op)   GEN_LOAD2(op, op)
-
 #define GEN_UNOP(op) \
 static int sim_##op(x87_state *state, ir_node *n) { \
        return sim_unop(state, n, op_ia32_##op); \
@@ -1715,15 +1718,12 @@ static int sim_Keep(x87_state *state, ir_node *node)
 
 static void keep_float_node_alive(ir_node *node)
 {
-       ir_graph                    *irg;
-       ir_node                     *block;
+       ir_graph                    *irg    = get_irn_irg(node);
+       ir_node                     *block  = get_nodes_block(node);
+       const arch_register_class_t *cls    = arch_get_irn_reg_class_out(node);
        ir_node                     *in[1];
        ir_node                     *keep;
-       const arch_register_class_t *cls;
 
-       irg    = get_irn_irg(node);
-       block  = get_nodes_block(node);
-       cls    = arch_get_irn_reg_class(node, -1);
        in[0]  = node;
        keep   = be_new_Keep(cls, irg, block, 1, in);
 
@@ -1741,12 +1741,11 @@ static void keep_float_node_alive(ir_node *node)
  */
 static ir_node *create_Copy(x87_state *state, ir_node *n)
 {
-       ir_graph *irg = get_irn_irg(n);
        dbg_info *n_dbg = get_irn_dbg_info(n);
        ir_mode *mode = get_irn_mode(n);
        ir_node *block = get_nodes_block(n);
        ir_node *pred = get_irn_n(n, 0);
-       ir_node *(*cnstr)(dbg_info *, ir_graph *, ir_node *, ir_mode *) = NULL;
+       ir_node *(*cnstr)(dbg_info *, ir_node *, ir_mode *) = NULL;
        ir_node *res;
        const arch_register_t *out;
        const arch_register_t *op1;
@@ -1756,25 +1755,25 @@ static ir_node *create_Copy(x87_state *state, ir_node *n)
        switch (get_ia32_irn_opcode(pred)) {
        case iro_ia32_Unknown_VFP:
        case iro_ia32_fldz:
-               cnstr = new_rd_ia32_fldz;
+               cnstr = new_bd_ia32_fldz;
                break;
        case iro_ia32_fld1:
-               cnstr = new_rd_ia32_fld1;
+               cnstr = new_bd_ia32_fld1;
                break;
        case iro_ia32_fldpi:
-               cnstr = new_rd_ia32_fldpi;
+               cnstr = new_bd_ia32_fldpi;
                break;
        case iro_ia32_fldl2e:
-               cnstr = new_rd_ia32_fldl2e;
+               cnstr = new_bd_ia32_fldl2e;
                break;
        case iro_ia32_fldl2t:
-               cnstr = new_rd_ia32_fldl2t;
+               cnstr = new_bd_ia32_fldl2t;
                break;
        case iro_ia32_fldlg2:
-               cnstr = new_rd_ia32_fldlg2;
+               cnstr = new_bd_ia32_fldlg2;
                break;
        case iro_ia32_fldln2:
-               cnstr = new_rd_ia32_fldln2;
+               cnstr = new_bd_ia32_fldln2;
                break;
        default:
                break;
@@ -1785,7 +1784,7 @@ static ir_node *create_Copy(x87_state *state, ir_node *n)
 
        if (cnstr != NULL) {
                /* copy a constant */
-               res = (*cnstr)(n_dbg, irg, block, mode);
+               res = (*cnstr)(n_dbg, block, mode);
 
                x87_push(state, arch_register_get_index(out), res);
 
@@ -1794,7 +1793,7 @@ static ir_node *create_Copy(x87_state *state, ir_node *n)
        } else {
                int op1_idx = x87_on_stack(state, arch_register_get_index(op1));
 
-               res = new_rd_ia32_fpushCopy(n_dbg, irg, block, pred, mode);
+               res = new_bd_ia32_fpushCopy(n_dbg, block, pred, mode);
 
                x87_push(state, arch_register_get_index(out), res);
 
@@ -1826,7 +1825,7 @@ static int sim_Copy(x87_state *state, ir_node *n)
        int                         op1_idx, out_idx;
        unsigned                    live;
 
-       cls = arch_get_irn_reg_class(n, -1);
+       cls = arch_get_irn_reg_class_out(n);
        if (cls->regs != ia32_vfp_regs)
                return 0;
 
@@ -2004,7 +2003,7 @@ end_call:
  */
 static int sim_Spill(x87_state *state, ir_node *n)
 {
-       assert(0 && "Spill not lowered");
+       panic("Spill not lowered");
        return sim_fst(state, n);
 }  /* sim_Spill */
 
@@ -2018,7 +2017,7 @@ static int sim_Spill(x87_state *state, ir_node *n)
  */
 static int sim_Reload(x87_state *state, ir_node *n)
 {
-       assert(0 && "Reload not lowered");
+       panic("Reload not lowered");
        return sim_fld(state, n);
 }  /* sim_Reload */
 
@@ -2128,7 +2127,7 @@ static int sim_Barrier(x87_state *state, ir_node *node)
 
                /* create a zero */
                block = get_nodes_block(node);
-               zero  = new_rd_ia32_fldz(NULL, current_ir_graph, block, mode_E);
+               zero  = new_bd_ia32_fldz(NULL, block, mode_E);
                x87_push(state, arch_register_get_index(reg), zero);
 
                attr = get_ia32_x87_attr(zero);
@@ -2183,10 +2182,10 @@ static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *
                        if (ia32_cg_config.use_femms || ia32_cg_config.use_emms) {
                                if (ia32_cg_config.use_femms) {
                                        /* use FEMMS on AMD processors to clear all */
-                                       keep = new_rd_ia32_femms(NULL, get_irn_irg(block), block);
+                                       keep = new_bd_ia32_femms(NULL, block);
                                } else {
                                        /* use EMMS to clear all */
-                                       keep = new_rd_ia32_emms(NULL, get_irn_irg(block), block);
+                                       keep = new_bd_ia32_emms(NULL, block);
                                }
                                sched_add_before(first_insn, keep);
                                keep_alive(keep);
@@ -2254,7 +2253,7 @@ static void fix_unknown_phis(x87_state *state, ir_node *block,
                reg = arch_get_irn_register(node);
 
                /* create a zero at end of pred block */
-               zero = new_rd_ia32_fldz(NULL, current_ir_graph, pred_block, mode_E);
+               zero = new_bd_ia32_fldz(NULL, pred_block, mode_E);
                x87_push(state, arch_register_get_index(reg), zero);
 
                attr = get_ia32_x87_attr(zero);
@@ -2432,6 +2431,8 @@ static void update_liveness_walker(ir_node *block, void *data)
 
 void x87_simulate_graph(be_irg_t *birg)
 {
+       /* TODO improve code quality (less executed fxch) by using execfreqs */
+
        ir_node       *block, *start_block;
        blk_state     *bl_state;
        x87_simulator sim;