Panic when get_call_result_proj() does not find the Proj.
[libfirm] / ir / be / ia32 / ia32_x87.c
index 0117472..b5ca4ed 100644 (file)
@@ -52,8 +52,6 @@
 #include "ia32_x87.h"
 #include "ia32_architecture.h"
 
-#define MASK_TOS(x)    ((x) & (N_ia32_st_REGS - 1))
-
 /** the debug handle */
 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
@@ -88,13 +86,11 @@ typedef struct st_entry {
 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. */
-static x87_state _empty = { { {0, NULL}, }, 0, 0, NULL };
-static x87_state *empty = (x87_state *)&_empty;
+static x87_state empty = { { {0, NULL}, }, 0, NULL };
 
 /**
  * Return values of the instruction simulator functions.
@@ -152,6 +148,12 @@ static int x87_get_depth(const x87_state *state)
        return state->depth;
 }
 
+static st_entry *x87_get_entry(x87_state *const state, int const pos)
+{
+       assert(0 <= pos && pos < state->depth);
+       return &state->st[N_ia32_st_REGS - state->depth + pos];
+}
+
 /**
  * Return the virtual register index at st(pos).
  *
@@ -162,25 +164,10 @@ static int x87_get_depth(const x87_state *state)
  */
 static int x87_get_st_reg(const x87_state *state, int pos)
 {
-       assert(pos < state->depth);
-       return state->st[MASK_TOS(state->tos + pos)].reg_idx;
+       return x87_get_entry((x87_state*)state, pos)->reg_idx;
 }
 
 #ifdef DEBUG_libfirm
-/**
- * Return the node at st(pos).
- *
- * @param state  the x87 state
- * @param pos    a stack position
- *
- * @return the IR node that produced the value at st(pos)
- */
-static ir_node *x87_get_st_node(const x87_state *state, int pos)
-{
-       assert(pos < state->depth);
-       return state->st[MASK_TOS(state->tos + pos)].node;
-}
-
 /**
  * Dump the stack for debugging.
  *
@@ -188,11 +175,9 @@ static ir_node *x87_get_st_node(const x87_state *state, int pos)
  */
 static void x87_dump_stack(const x87_state *state)
 {
-       int i;
-
-       for (i = state->depth - 1; i >= 0; --i) {
-               DB((dbg, LEVEL_2, "vf%d(%+F) ", x87_get_st_reg(state, i),
-                   x87_get_st_node(state, i)));
+       for (int i = state->depth; i-- != 0;) {
+               st_entry const *const entry = x87_get_entry((x87_state*)state, i);
+               DB((dbg, LEVEL_2, "vf%d(%+F) ", entry->reg_idx, entry->node));
        }
        DB((dbg, LEVEL_2, "<-- TOS\n"));
 }
@@ -208,9 +193,9 @@ static void x87_dump_stack(const x87_state *state)
  */
 static void x87_set_st(x87_state *state, int reg_idx, ir_node *node, int pos)
 {
-       assert(0 < state->depth);
-       state->st[MASK_TOS(state->tos + pos)].reg_idx = reg_idx;
-       state->st[MASK_TOS(state->tos + pos)].node    = node;
+       st_entry *const entry = x87_get_entry(state, pos);
+       entry->reg_idx = reg_idx;
+       entry->node    = node;
 
        DB((dbg, LEVEL_2, "After SET_REG: "));
        DEBUG_ONLY(x87_dump_stack(state);)
@@ -236,12 +221,11 @@ static void x87_set_tos(x87_state *state, int reg_idx, ir_node *node)
  */
 static void x87_fxch(x87_state *state, int pos)
 {
-       st_entry entry;
-       assert(pos < state->depth);
-
-       entry = state->st[MASK_TOS(state->tos + pos)];
-       state->st[MASK_TOS(state->tos + pos)] = state->st[MASK_TOS(state->tos)];
-       state->st[MASK_TOS(state->tos)] = entry;
+       st_entry *const a = x87_get_entry(state, pos);
+       st_entry *const b = x87_get_entry(state, 0);
+       st_entry  const t = *a;
+       *a = *b;
+       *b = t;
 
        DB((dbg, LEVEL_2, "After FXCH: "));
        DEBUG_ONLY(x87_dump_stack(state);)
@@ -258,11 +242,10 @@ static void x87_fxch(x87_state *state, int pos)
  */
 static int x87_on_stack(const x87_state *state, int reg_idx)
 {
-       int i, tos = state->tos;
-
-       for (i = 0; i < state->depth; ++i)
-               if (state->st[MASK_TOS(tos + i)].reg_idx == reg_idx)
+       for (int i = 0; i < state->depth; ++i) {
+               if (x87_get_st_reg(state, i) == reg_idx)
                        return i;
+       }
        return -1;
 }
 
@@ -278,9 +261,9 @@ static void x87_push_dbl(x87_state *state, int reg_idx, ir_node *node)
        assert(state->depth < N_ia32_st_REGS && "stack overrun");
 
        ++state->depth;
-       state->tos = MASK_TOS(state->tos - 1);
-       state->st[state->tos].reg_idx = reg_idx;
-       state->st[state->tos].node    = node;
+       st_entry *const entry = x87_get_entry(state, 0);
+       entry->reg_idx = reg_idx;
+       entry->node    = node;
 
        DB((dbg, LEVEL_2, "After PUSH: ")); DEBUG_ONLY(x87_dump_stack(state);)
 }
@@ -309,7 +292,6 @@ static void x87_pop(x87_state *state)
        assert(state->depth > 0 && "stack underrun");
 
        --state->depth;
-       state->tos = MASK_TOS(state->tos + 1);
 
        DB((dbg, LEVEL_2, "After POP: ")); DEBUG_ONLY(x87_dump_stack(state);)
 }
@@ -322,7 +304,6 @@ static void x87_pop(x87_state *state)
 static void x87_emms(x87_state *state)
 {
        state->depth = 0;
-       state->tos   = 0;
 }
 
 /**
@@ -348,21 +329,6 @@ static blk_state *x87_get_bl_state(x87_simulator *sim, ir_node *block)
        return res;
 }
 
-/**
- * Creates a new x87 state.
- *
- * @param sim    the x87 simulator handle
- *
- * @return a new x87 state
- */
-static x87_state *x87_alloc_state(x87_simulator *sim)
-{
-       x87_state *res = OALLOC(&sim->obst, x87_state);
-
-       res->sim = sim;
-       return res;
-}
-
 /**
  * Clone a x87 state.
  *
@@ -373,8 +339,7 @@ static x87_state *x87_alloc_state(x87_simulator *sim)
  */
 static x87_state *x87_clone_state(x87_simulator *sim, const x87_state *src)
 {
-       x87_state *res = x87_alloc_state(sim);
-
+       x87_state *const res = OALLOC(&sim->obst, x87_state);
        *res = *src;
        return res;
 }
@@ -1840,7 +1805,7 @@ static ir_node *get_call_result_proj(ir_node *call)
                        return proj;
        }
 
-       return NULL;
+       panic("result Proj missing");
 }
 
 static int sim_Asm(x87_state *const state, ir_node *const n)
@@ -1898,7 +1863,6 @@ static int sim_Call(x87_state *state, ir_node *n)
                goto end_call;
 
        resproj = get_call_result_proj(n);
-       assert(resproj != NULL);
 
        reg = x87_get_irn_register(resproj);
        x87_push(state, arch_register_get_index(reg), resproj);
@@ -2254,8 +2218,8 @@ void ia32_x87_simulate_graph(ir_graph *irg)
        bl_state    = x87_get_bl_state(&sim, start_block);
 
        /* start with the empty state */
-       bl_state->begin = empty;
-       empty->sim      = &sim;
+       empty.sim       = &sim;
+       bl_state->begin = &empty;
 
        sim.worklist = new_waitq();
        waitq_put(sim.worklist, start_block);