make firm compilable with a c++ compiler
[libfirm] / ir / be / ia32 / ia32_x87.c
index 7429188..55c9206 100644 (file)
 #include "ia32_x87.h"
 #include "ia32_architecture.h"
 
-#define N_x87_REGS 8
-
-/* the unop index */
-#define UNOP_IDX 0
-
-#define MASK_TOS(x)            ((x) & (N_x87_REGS - 1))
+#define MASK_TOS(x)    ((x) & (N_ia32_st_REGS - 1))
 
 /** the debug handle */
 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
 /* Forward declaration. */
-typedef struct _x87_simulator x87_simulator;
+typedef struct x87_simulator x87_simulator;
 
 /**
  * An exchange template.
@@ -73,7 +68,7 @@ typedef struct _x87_simulator x87_simulator;
  * their opcodes!
  * Further, x87 supports inverse instructions, so we can handle them.
  */
-typedef struct _exchange_tmpl {
+typedef struct exchange_tmpl {
        ir_op *normal_op;       /**< the normal one */
        ir_op *reverse_op;      /**< the reverse one if exists */
        ir_op *normal_pop_op;   /**< the normal one with tos pop */
@@ -83,7 +78,7 @@ typedef struct _exchange_tmpl {
 /**
  * An entry on the simulated x87 stack.
  */
-typedef struct _st_entry {
+typedef struct st_entry {
        int     reg_idx;        /**< the virtual register index of this stack value */
        ir_node *node;          /**< the node that produced this value */
 } st_entry;
@@ -91,11 +86,11 @@ typedef struct _st_entry {
 /**
  * The x87 state.
  */
-typedef struct _x87_state {
-       st_entry st[N_x87_REGS];  /**< the register stack */
-       int depth;                /**< the current stack depth */
-       int tos;                  /**< position of the tos */
-       x87_simulator *sim;       /**< The simulator. */
+typedef struct x87_state {
+       st_entry st[N_ia32_st_REGS]; /**< the register stack */
+       int depth;                   /**< the current stack depth */
+       int tos;                     /**< position of the tos */
+       x87_simulator *sim;          /**< The simulator. */
 } x87_state;
 
 /** An empty state, used for blocks without fp instructions. */
@@ -126,12 +121,12 @@ typedef int (*sim_func)(x87_state *state, ir_node *n);
 /**
  * A block state: Every block has a x87 state at the beginning and at the end.
  */
-typedef struct _blk_state {
+typedef struct blk_state {
        x87_state *begin;   /**< state at the begin or NULL if not assigned */
        x87_state *end;     /**< state at the end or NULL if not assigned */
 } blk_state;
 
-#define PTR_TO_BLKSTATE(p)     ((blk_state *)(p))
+#define PTR_TO_BLKSTATE(p)    ((blk_state *)(p))
 
 /** liveness bitset for vfp registers. */
 typedef unsigned char vfp_liveness;
@@ -139,7 +134,7 @@ typedef unsigned char vfp_liveness;
 /**
  * The x87 simulator.
  */
-struct _x87_simulator {
+struct x87_simulator {
        struct obstack obst;        /**< An obstack for fast allocating. */
        pmap *blk_states;           /**< Map blocks to states. */
        be_lv_t *lv;                /**< intrablock liveness. */
@@ -252,7 +247,8 @@ static void x87_fxch(x87_state *state, int pos)
        state->st[MASK_TOS(state->tos + pos)] = state->st[MASK_TOS(state->tos)];
        state->st[MASK_TOS(state->tos)] = entry;
 
-       DB((dbg, LEVEL_2, "After FXCH: ")); DEBUG_ONLY(x87_dump_stack(state));
+       DB((dbg, LEVEL_2, "After FXCH: "));
+       DEBUG_ONLY(x87_dump_stack(state));
 }  /* x87_fxch */
 
 /**
@@ -283,7 +279,7 @@ static int x87_on_stack(const x87_state *state, int reg_idx)
  */
 static void x87_push_dbl(x87_state *state, int reg_idx, ir_node *node)
 {
-       assert(state->depth < N_x87_REGS && "stack overrun");
+       assert(state->depth < N_ia32_st_REGS && "stack overrun");
 
        ++state->depth;
        state->tos = MASK_TOS(state->tos - 1);
@@ -347,7 +343,7 @@ static blk_state *x87_get_bl_state(x87_simulator *sim, ir_node *block)
        pmap_entry *entry = pmap_find(sim->blk_states, block);
 
        if (! entry) {
-               blk_state *bl_state = obstack_alloc(&sim->obst, sizeof(*bl_state));
+               blk_state *bl_state = OALLOC(&sim->obst, blk_state);
                bl_state->begin = NULL;
                bl_state->end   = NULL;
 
@@ -367,7 +363,7 @@ static blk_state *x87_get_bl_state(x87_simulator *sim, ir_node *block)
  */
 static x87_state *x87_alloc_state(x87_simulator *sim)
 {
-       x87_state *res = obstack_alloc(&sim->obst, sizeof(*res));
+       x87_state *res = OALLOC(&sim->obst, x87_state);
 
        res->sim = sim;
        return res;
@@ -451,7 +447,7 @@ static inline const arch_register_t *x87_get_irn_register(const ir_node *irn)
 {
        const arch_register_t *res = arch_get_irn_register(irn);
 
-       assert(res->reg_class->regs == ia32_vfp_regs);
+       assert(res->reg_class == &ia32_reg_classes[CLASS_ia32_vfp]);
        return res;
 }  /* x87_get_irn_register */
 
@@ -460,10 +456,15 @@ static inline const arch_register_t *x87_irn_get_register(const ir_node *irn,
 {
        const arch_register_t *res = arch_irn_get_register(irn, pos);
 
-       assert(res->reg_class->regs == ia32_vfp_regs);
+       assert(res->reg_class == &ia32_reg_classes[CLASS_ia32_vfp]);
        return res;
 }  /* x87_irn_get_register */
 
+static inline const arch_register_t *get_st_reg(int index)
+{
+       return &ia32_registers[REG_ST0 + index];
+}
+
 /* -------------- x87 perm --------------- */
 
 /**
@@ -485,8 +486,8 @@ static ir_node *x87_fxch_shuffle(x87_state *state, int pos, ir_node *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];
+       attr->x87[0] = get_st_reg(pos);
+       attr->x87[2] = get_st_reg(0);
 
        keep_alive(fxch);
 
@@ -654,8 +655,8 @@ static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos)
 
        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];
+       attr->x87[0] = get_st_reg(pos);
+       attr->x87[2] = get_st_reg(0);
 
        keep_alive(fxch);
 
@@ -682,8 +683,8 @@ static void x87_create_fpush(x87_state *state, ir_node *n, int pos, int op_idx)
 
        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];
+       attr->x87[0] = get_st_reg(pos);
+       attr->x87[2] = get_st_reg(0);
 
        keep_alive(fpush);
        sched_add_before(n, fpush);
@@ -713,9 +714,9 @@ static ir_node *x87_create_fpop(x87_state *state, ir_node *n, int num)
                else
                        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];
-               attr->x87[2] = &ia32_st_regs[0];
+               attr->x87[0] = get_st_reg(0);
+               attr->x87[1] = get_st_reg(0);
+               attr->x87[2] = get_st_reg(0);
 
                keep_alive(fpop);
                sched_add_before(n, fpop);
@@ -802,7 +803,7 @@ static vfp_liveness vfp_liveness_end_of_block(x87_simulator *sim, const ir_node
 }  /* vfp_liveness_end_of_block */
 
 /** get the register mask from an arch_register */
-#define REGMASK(reg)   (1 << (arch_register_get_index(reg)))
+#define REGMASK(reg)    (1 << (arch_register_get_index(reg)))
 
 /**
  * Return a bitset of argument registers which are live at the end of a node.
@@ -917,18 +918,18 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl)
 
        op1_idx = x87_on_stack(state, reg_index_1);
        assert(op1_idx >= 0);
-       op1_live_after = is_vfp_live(arch_register_get_index(op1_reg), live);
+       op1_live_after = is_vfp_live(reg_index_1, live);
 
        attr     = get_ia32_x87_attr(n);
        permuted = attr->attr.data.ins_permuted;
 
-       if (reg_index_2 != REG_VFP_NOREG) {
+       if (reg_index_2 != REG_VFP_VFP_NOREG) {
                assert(!permuted);
 
                /* second operand is a vfp register */
                op2_idx = x87_on_stack(state, reg_index_2);
                assert(op2_idx >= 0);
-               op2_live_after = is_vfp_live(arch_register_get_index(op2_reg), live);
+               op2_live_after = is_vfp_live(reg_index_2, live);
 
                if (op2_live_after) {
                        /* Second operand is live. */
@@ -1034,13 +1035,13 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl)
        }
 
        /* patch the operation */
-       attr->x87[0] = op1_reg = &ia32_st_regs[op1_idx];
-       if (reg_index_2 != REG_VFP_NOREG) {
-               attr->x87[1] = op2_reg = &ia32_st_regs[op2_idx];
+       attr->x87[0] = op1_reg = get_st_reg(op1_idx);
+       if (reg_index_2 != REG_VFP_VFP_NOREG) {
+               attr->x87[1] = op2_reg = get_st_reg(op2_idx);
        }
-       attr->x87[2] = out = &ia32_st_regs[out_idx];
+       attr->x87[2] = out = get_st_reg(out_idx);
 
-       if (reg_index_2 != REG_VFP_NOREG) {
+       if (reg_index_2 != REG_VFP_VFP_NOREG) {
                DB((dbg, LEVEL_1, "<<< %s %s, %s -> %s\n", get_irn_opname(n),
                        arch_register_get_name(op1_reg), arch_register_get_name(op2_reg),
                        arch_register_get_name(out)));
@@ -1066,7 +1067,7 @@ static int sim_unop(x87_state *state, ir_node *n, ir_op *op)
 {
        int op1_idx;
        x87_simulator         *sim = state->sim;
-       const arch_register_t *op1 = x87_get_irn_register(get_irn_n(n, UNOP_IDX));
+       const arch_register_t *op1 = x87_get_irn_register(get_irn_n(n, 0));
        const arch_register_t *out = x87_get_irn_register(n);
        ia32_x87_attr_t *attr;
        unsigned live = vfp_live_args_after(sim, n, REGMASK(out));
@@ -1078,7 +1079,7 @@ static int sim_unop(x87_state *state, ir_node *n, ir_op *op)
 
        if (is_vfp_live(arch_register_get_index(op1), live)) {
                /* push the operand here */
-               x87_create_fpush(state, n, op1_idx, UNOP_IDX);
+               x87_create_fpush(state, n, op1_idx, 0);
                op1_idx = 0;
        }
        else {
@@ -1091,8 +1092,8 @@ static int sim_unop(x87_state *state, ir_node *n, ir_op *op)
 
        x87_set_tos(state, arch_register_get_index(out), x87_patch_insn(n, op));
        attr = get_ia32_x87_attr(n);
-       attr->x87[0] = op1 = &ia32_st_regs[0];
-       attr->x87[2] = out = &ia32_st_regs[0];
+       attr->x87[0] = op1 = get_st_reg(0);
+       attr->x87[2] = out = get_st_reg(0);
        DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), out->name));
 
        return NO_NODE_ADDED;
@@ -1116,7 +1117,7 @@ static int sim_load(x87_state *state, ir_node *n, ir_op *op, int res_pos)
        x87_push(state, arch_register_get_index(out), x87_patch_insn(n, op));
        assert(out == x87_irn_get_register(n, res_pos));
        attr = get_ia32_x87_attr(n);
-       attr->x87[2] = out = &ia32_st_regs[0];
+       attr->x87[2] = out = get_st_reg(0);
        DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
 
        return NO_NODE_ADDED;
@@ -1189,21 +1190,21 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
                        Note that we cannot test on mode_E, because floats might be 96bit ...
                */
                if (get_mode_size_bits(mode) > 64 || (mode_is_int(mode) && get_mode_size_bits(mode) > 32)) {
-                       if (depth < N_x87_REGS) {
+                       if (depth < N_ia32_st_REGS) {
                                /* ok, we have a free register: push + fstp */
                                x87_create_fpush(state, n, op2_idx, n_ia32_vfst_val);
                                x87_pop(state);
                                x87_patch_insn(n, op_p);
                        } else {
                                ir_node  *vfld, *mem, *block, *rproj, *mproj;
-                               ir_graph *irg;
+                               ir_graph *irg = get_irn_irg(n);
 
                                /* stack full here: need fstp + load */
                                x87_pop(state);
                                x87_patch_insn(n, op_p);
 
                                block = get_nodes_block(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));
+                               vfld  = new_bd_ia32_vfld(NULL, block, get_irn_n(n, 0), get_irn_n(n, 1), new_r_NoMem(irg), get_ia32_ls_mode(n));
 
                                /* copy all attributes */
                                set_ia32_frame_ent(vfld, get_ia32_frame_ent(n));
@@ -1223,7 +1224,6 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
                                arch_set_irn_register(rproj, op2);
 
                                /* reroute all former users of the store memory to the load memory */
-                               irg = get_irn_irg(n);
                                edges_reroute(mem, mproj, irg);
                                /* set the memory input of the load to the store memory */
                                set_irn_n(vfld, n_ia32_vfld_mem, mem);
@@ -1254,7 +1254,7 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
        }
 
        attr = get_ia32_x87_attr(n);
-       attr->x87[1] = op2 = &ia32_st_regs[0];
+       attr->x87[1] = op2 = get_st_reg(0);
        DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
 
        return insn;
@@ -1267,7 +1267,7 @@ 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_BINOPR(op)  _GEN_BINOP(op, op##r)
 
 #define GEN_LOAD(op)                                              \
 static int sim_##op(x87_state *state, ir_node *n) {               \
@@ -1334,7 +1334,7 @@ static int sim_fisttp(x87_state *state, ir_node *n)
        x87_patch_insn(n, op_ia32_fisttp);
 
        attr = get_ia32_x87_attr(n);
-       attr->x87[1] = op2 = &ia32_st_regs[0];
+       attr->x87[1] = op2 = get_st_reg(0);
        DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
 
        return NO_NODE_ADDED;
@@ -1372,7 +1372,7 @@ static int sim_FtstFnstsw(x87_state *state, ir_node *n)
 
        /* patch the operation */
        x87_patch_insn(n, op_ia32_FtstFnstsw);
-       reg1 = &ia32_st_regs[op1_idx];
+       reg1 = get_st_reg(op1_idx);
        attr->x87[0] = reg1;
        attr->x87[1] = NULL;
        attr->x87[2] = NULL;
@@ -1419,7 +1419,7 @@ static int sim_Fucom(x87_state *state, ir_node *n)
        assert(op1_idx >= 0);
 
        /* BEWARE: check for comp a,a cases, they might happen */
-       if (reg_index_2 != REG_VFP_NOREG) {
+       if (reg_index_2 != REG_VFP_VFP_NOREG) {
                /* second operand is a vfp register */
                op2_idx = x87_on_stack(state, reg_index_2);
                assert(op2_idx >= 0);
@@ -1602,10 +1602,10 @@ static int sim_Fucom(x87_state *state, ir_node *n)
                op2_idx = tmp;
        }
 
-       op1 = &ia32_st_regs[op1_idx];
+       op1 = get_st_reg(op1_idx);
        attr->x87[0] = op1;
        if (op2_idx >= 0) {
-               op2 = &ia32_st_regs[op2_idx];
+               op2 = get_st_reg(op2_idx);
                attr->x87[1] = op2;
        }
        attr->x87[2] = NULL;
@@ -1733,7 +1733,7 @@ static ir_node *create_Copy(x87_state *state, ir_node *n)
                x87_push(state, arch_register_get_index(out), res);
 
                attr = get_ia32_x87_attr(res);
-               attr->x87[2] = &ia32_st_regs[0];
+               attr->x87[2] = get_st_reg(0);
        } else {
                int op1_idx = x87_on_stack(state, arch_register_get_index(op1));
 
@@ -1742,8 +1742,8 @@ static ir_node *create_Copy(x87_state *state, ir_node *n)
                x87_push(state, arch_register_get_index(out), res);
 
                attr = get_ia32_x87_attr(res);
-               attr->x87[0] = &ia32_st_regs[op1_idx];
-               attr->x87[2] = &ia32_st_regs[0];
+               attr->x87[0] = get_st_reg(op1_idx);
+               attr->x87[2] = get_st_reg(0);
        }
        arch_set_irn_register(res, out);
 
@@ -1769,7 +1769,7 @@ static int sim_Copy(x87_state *state, ir_node *n)
        unsigned                    live;
 
        cls = arch_get_irn_reg_class_out(n);
-       if (cls->regs != ia32_vfp_regs)
+       if (cls != &ia32_reg_classes[CLASS_ia32_vfp])
                return 0;
 
        pred = get_irn_n(n, 0);
@@ -1820,7 +1820,7 @@ static int sim_Copy(x87_state *state, ir_node *n)
                                /* best case, simple remove and rename */
                                x87_patch_insn(n, op_ia32_Pop);
                                attr = get_ia32_x87_attr(n);
-                               attr->x87[0] = op1 = &ia32_st_regs[0];
+                               attr->x87[0] = op1 = get_st_reg(0);
 
                                x87_pop(state);
                                x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
@@ -1833,7 +1833,7 @@ static int sim_Copy(x87_state *state, ir_node *n)
                                }
                                x87_patch_insn(n, op_ia32_Pop);
                                attr = get_ia32_x87_attr(n);
-                               attr->x87[0] = op1 = &ia32_st_regs[out_idx];
+                               attr->x87[0] = op1 = get_st_reg(out_idx);
 
                                x87_pop(state);
                                x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
@@ -1953,7 +1953,7 @@ static int sim_Return(x87_state *state, ir_node *n)
        return NO_NODE_ADDED;
 }  /* sim_Return */
 
-typedef struct _perm_data_t {
+typedef struct perm_data_t {
        const arch_register_t *in;
        const arch_register_t *out;
 } perm_data_t;
@@ -2209,7 +2209,7 @@ static void x87_init_simulator(x87_simulator *sim, ir_graph *irg)
        obstack_init(&sim->obst);
        sim->blk_states = pmap_create();
        sim->n_idx      = get_irg_last_idx(irg);
-       sim->live       = obstack_alloc(&sim->obst, sizeof(*sim->live) * sim->n_idx);
+       sim->live       = OALLOCN(&sim->obst, vfp_liveness, sim->n_idx);
 
        DB((dbg, LEVEL_1, "--------------------------------\n"
                "x87 Simulator started for %+F\n", irg));
@@ -2259,7 +2259,7 @@ static void x87_destroy_simulator(x87_simulator *sim)
  */
 static void update_liveness_walker(ir_node *block, void *data)
 {
-       x87_simulator *sim = data;
+       x87_simulator *sim = (x87_simulator*)data;
        update_liveness(sim, block);
 }  /* update_liveness_walker */
 
@@ -2268,14 +2268,13 @@ static void update_liveness_walker(ir_node *block, void *data)
  * Replaces all virtual floating point instructions and registers
  * by real ones.
  */
-void x87_simulate_graph(be_irg_t *birg)
+void x87_simulate_graph(ir_graph *irg)
 {
        /* TODO improve code quality (less executed fxch) by using execfreqs */
 
        ir_node       *block, *start_block;
        blk_state     *bl_state;
        x87_simulator sim;
-       ir_graph      *irg = be_get_birg_irg(birg);
 
        /* create the simulator */
        x87_init_simulator(&sim, irg);
@@ -2290,8 +2289,8 @@ void x87_simulate_graph(be_irg_t *birg)
        sim.worklist = new_waitq();
        waitq_put(sim.worklist, start_block);
 
-       be_assure_liveness(birg);
-       sim.lv = be_get_birg_liveness(birg);
+       be_assure_liveness(irg);
+       sim.lv = be_get_irg_liveness(irg);
        be_liveness_assure_sets(sim.lv);
 
        /* Calculate the liveness for all nodes. We must precalculate this info,
@@ -2304,7 +2303,7 @@ void x87_simulate_graph(be_irg_t *birg)
 
        /* iterate */
        do {
-               block = waitq_get(sim.worklist);
+               block = (ir_node*)waitq_get(sim.worklist);
                x87_simulate_block(&sim, block);
        } while (! waitq_empty(sim.worklist));