*
* $Id$
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
#include <assert.h>
#include "irnode_t.h"
#include "irprintf.h"
#include "debug.h"
-#include "..\belive_t.h"
-#include "..\besched.h"
-#include "..\benode_t.h"
+#include "../belive_t.h"
+#include "../besched.h"
+#include "../benode_t.h"
#include "ia32_new_nodes.h"
#include "gen_ia32_new_nodes.h"
#include "gen_ia32_regalloc_if.h"
* Push a virtual Register onto the stack.
*/
static void x87_push(x87_state *state, int reg_idx, ir_node *node) {
-// assert(x87_on_stack(state, reg_idx) == -1 && "double push");
+ assert(x87_on_stack(state, reg_idx) == -1 && "double push");
assert(state->depth < N_x87_REGS && "stack overrun");
++state->depth;
attr->x87[0] = &ia32_st_regs[pos];
attr->x87[2] = &ia32_st_regs[0];
- DB((dbg, LEVEL_2, "%+F replaced input %d of %+F\n", fxch, node_idx, user));
-
- if (user)
+ if (user) {
+ DB((dbg, LEVEL_2, "%+F replaced input %d of %+F\n", fxch, node_idx, user));
set_irn_n(user, node_idx, fxch);
+ }
else {
- /* This is a node from another block. Changing it's user might be wrong,
- sp just keep it alive.
- The "right" solution would require a new Phi, but we don't care here.
+ /*
+ * This is a node from a dominator block. Changing it's user might be wrong,
+ * so just keep it alive.
+ * The "right" solution would require a new Phi, but we don't care here.
*/
keep_alive(fxch);
}
/**
* dump liveness info.
*/
-static vfp_dump_live(unsigned live) {
+static void vfp_dump_live(unsigned live) {
int i;
DB((dbg, LEVEL_2, "Live registers here: \n"));
GEN_UNOP(fsqrt)
/**
- * Simulate a virtual Copy
+ * Simulate a be_Copy.
*/
static void sim_Copy(x87_state *state, ir_node *n, const arch_env_t *env) {
ir_mode *mode = get_irn_mode(n);
}
}
+/**
+ * Simulate a be_Call
+ */
+static void sim_Call(x87_state *state, ir_node *n, const arch_env_t *env) {
+ ir_type *call_tp = be_Call_get_type(n);
+
+ /* at the begin of a call the x87 state should be empty */
+ assert(state->depth == 0 && "stack not empty before call");
+
+ /*
+ * If the called function returns a float, it is returned in st(0).
+ * This even happens if the return value is NOT used.
+ * Moreover, only one return result is supported.
+ */
+ if (get_method_n_ress(call_tp) > 0) {
+ ir_type *res_type = get_method_res_type(call_tp, 0);
+ ir_mode *mode = get_type_mode(res_type);
+
+ if (mode && mode_is_float(mode)) {
+ /*
+ * TODO: what to push here? The result might be unused and currently
+ * we have no possibility to detect this :-(
+ */
+ x87_push(state, 0, n);
+ }
+ }
+}
+
+/**
+ * Simulate a be_Spill.
+ */
+static void sim_Spill(x87_state *state, ir_node *n, const arch_env_t *env) {
+ assert(0 && "Spill not lowered");
+ sim_fst(state, n, env);
+}
+
+/**
+ * Simulate a be_Reload
+ */
+static void sim_Reload(x87_state *state, ir_node *n, const arch_env_t *env) {
+ assert(0 && "Reload not lowered");
+ sim_fld(state, n, env);
+}
+
/**
* Run a simulation and fix all virtual instructions for a block.
*
/**
* Create a new x87 simulator.
*/
-static void x87_init_simulator(x87_simulator *sim, const arch_env_t *env) {
+static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, const arch_env_t *env) {
obstack_init(&sim->obst);
sim->blk_states = pmap_create();
sim->env = env;
FIRM_DBG_REGISTER(dbg, "firm.be.ia32.x87");
firm_dbg_set_mask(dbg, SET_LEVEL_2);
- DB((dbg, LEVEL_1, "x87 Simulator started\n"));
+ DB((dbg, LEVEL_1, "--------------------------------\n"
+ "x87 Simulator started for %+F\n", irg));
/* set the generic function pointer of instruction we must simulate */
clear_irp_opcodes_generic_func();
ASSOC_IA32(fsqrt);
ASSOC_IA32(fst);
ASSOC_BE(Copy);
+ ASSOC_BE(Call);
+ ASSOC_BE(Spill);
+ ASSOC_BE(Reload);
ASSOC(Phi);
#undef ASSOC_BE
#undef ASSOC_IA32
static void x87_destroy_simulator(x87_simulator *sim) {
pmap_destroy(sim->blk_states);
obstack_free(&sim->obst, NULL);
- DB((dbg, LEVEL_1, "x87 Simulator stopped\n"));
+ DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
}
/**
be_liveness(irg);
/* create the simulator */
- x87_init_simulator(&sim, env);
+ x87_init_simulator(&sim, irg, env);
start_block = get_irg_start_block(irg);
bl_state = x87_get_bl_state(&sim, start_block);