#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;)
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.
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).
*
*/
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.
*
*/
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"));
}
*/
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);)
*/
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);)
*/
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;
}
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);)
}
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);)
}
static void x87_emms(x87_state *state)
{
state->depth = 0;
- state->tos = 0;
}
/**
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.
*
*/
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;
}
return proj;
}
- return NULL;
+ panic("result Proj missing");
}
static int sim_Asm(x87_state *const state, ir_node *const 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);
bl_state = x87_get_bl_state(&sim, start_block);
/* start with the empty state */
- bl_state->begin = empty;
- empty->sim = ∼
+ empty.sim = ∼
+ bl_state->begin = ∅
sim.worklist = new_waitq();
waitq_put(sim.worklist, start_block);