2 * This file implements the x87 support and virtual to stack
3 * register translation for the ia32 backend.
5 * @author: Michael Beck
12 #endif /* HAVE_CONFIG_H */
19 #include "iredges_t.h"
28 #include "../belive_t.h"
29 #include "../besched_t.h"
30 #include "../benode_t.h"
31 #include "ia32_new_nodes.h"
32 #include "gen_ia32_new_nodes.h"
33 #include "gen_ia32_regalloc_if.h"
38 /* first and second binop index */
45 /* the store val index */
46 #define STORE_VAL_IDX 2
48 #define MASK_TOS(x) ((x) & (N_x87_REGS - 1))
50 /** the debug handle */
51 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
54 * An exchange template.
55 * Note that our virtual functions have the same inputs
56 * and attributes as the real ones, so we can simple exchange
58 * Further, x87 supports inverse instructions, so we can handle them.
60 typedef struct _exchange_tmpl {
61 ir_op *normal_op; /**< the normal one */
62 ir_op *reverse_op; /**< the reverse one if exists */
63 ir_op *normal_pop_op; /**< the normal one with tos pop */
64 ir_op *reverse_pop_op; /**< the reverse one with tos pop */
68 * An entry on the simulated x87 stack.
70 typedef struct _st_entry {
71 int reg_idx; /**< the virtual register index of this stack value */
72 ir_node *node; /**< the node that produced this value */
78 typedef struct _x87_state {
79 st_entry st[N_x87_REGS]; /**< the register stack */
80 int depth; /**< the current stack depth */
81 int tos; /**< position of the tos */
84 /** An empty state, used for blocks without fp instructions. */
85 static const x87_state _empty = { { {0, NULL}, }, 0, 0 };
86 static x87_state *empty = (x87_state *)&_empty;
88 /** The type of an instruction simulator */
89 typedef int (*sim_func)(x87_state *state, ir_node *n, const arch_env_t *env);
92 * A block state: Every block has a x87 state at the beginning and at the end.
94 typedef struct _blk_state {
95 x87_state *begin; /**< state at the begin or NULL if not assigned */
96 x87_state *end; /**< state at the end or NULL if not assigned */
99 #define PTR_TO_BLKSTATE(p) ((blk_state *)(p))
104 typedef struct _x87_simulator {
105 struct obstack obst; /**< an obstack for fast allocating */
106 pmap *blk_states; /**< map blocks to states */
107 const arch_env_t *env; /**< architecture environment */
111 * Returns the stack depth.
113 * @param state the x87 state
115 * @return the x87 stack depth
117 static int x87_get_depth(const x87_state *state) {
122 * Check if the state is empty.
124 * @param state the x87 state
126 * returns non-zero if the x87 stack is empty
128 static int x87_state_is_empty(const x87_state *state) {
129 return state->depth == 0;
133 * Return the virtual register index at st(pos).
135 * @param state the x87 state
136 * @param pos a stack position
138 * @return the vfp register index that produced the value at st(pos)
140 static int x87_get_st_reg(const x87_state *state, int pos) {
141 assert(pos < state->depth);
142 return state->st[MASK_TOS(state->tos + pos)].reg_idx;
146 * Return the node at st(pos).
148 * @param state the x87 state
149 * @param pos a stack position
151 * @return the IR node that produced the value at st(pos)
153 static ir_node *x87_get_st_node(const x87_state *state, int pos) {
154 assert(pos < state->depth);
155 return state->st[MASK_TOS(state->tos + pos)].node;
160 * Dump the stack for debugging.
162 * @param state the x87 state
164 static void x87_dump_stack(const x87_state *state) {
167 for (i = state->depth - 1; i >= 0; --i) {
168 DB((dbg, LEVEL_2, "vf%d ", x87_get_st_reg(state, i)));
170 DB((dbg, LEVEL_2, "<-- TOS\n"));
172 #endif /* DEBUG_libfirm */
175 * Set a virtual register to st(pos).
177 * @param state the x87 state
178 * @param reg_idx the vfp register index that should be set
179 * @param node the IR node that produces the value of the vfp register
180 * @param pos the stack position where the new value should be entered
182 static void x87_set_st(x87_state *state, int reg_idx, ir_node *node, int pos) {
183 assert(0 < state->depth);
184 state->st[MASK_TOS(state->tos + pos)].reg_idx = reg_idx;
185 state->st[MASK_TOS(state->tos + pos)].node = node;
187 DB((dbg, LEVEL_2, "After SET_REG:\n ")); DEBUG_ONLY(x87_dump_stack(state));
191 * Set the tos virtual register.
193 * @param state the x87 state
194 * @param reg_idx the vfp register index that should be set
195 * @param node the IR node that produces the value of the vfp register
197 static void x87_set_tos(x87_state *state, int reg_idx, ir_node *node) {
198 x87_set_st(state, reg_idx, node, 0);
202 * Flush the x87 stack.
204 * @param state the x87 state
206 static void x87_flush(x87_state *state) {
212 * Swap st(0) with st(pos).
214 * @param state the x87 state
215 * @param pos the stack position to change the tos with
217 static void x87_fxch(x87_state *state, int pos) {
219 assert(pos < state->depth);
221 entry = state->st[MASK_TOS(state->tos + pos)];
222 state->st[MASK_TOS(state->tos + pos)] = state->st[MASK_TOS(state->tos)];
223 state->st[MASK_TOS(state->tos)] = entry;
225 DB((dbg, LEVEL_2, "After FXCH:\n ")); DEBUG_ONLY(x87_dump_stack(state));
229 * Convert a virtual register to the stack index.
231 * @param state the x87 state
232 * @param reg_idx the register vfp index
234 * @return the stack position where the register is stacked
235 * or -1 if the virtual register was not found
237 static int x87_on_stack(const x87_state *state, int reg_idx) {
238 int i, tos = state->tos;
240 for (i = 0; i < state->depth; ++i)
241 if (state->st[MASK_TOS(tos + i)].reg_idx == reg_idx)
247 * Push a virtual Register onto the stack.
249 * @param state the x87 state
250 * @param reg_idx the register vfp index
251 * @param node the node that produces the value of the vfp register
252 * @param dbl_push if != 0 double pushes are allowd
254 static void x87_push(x87_state *state, int reg_idx, ir_node *node, int dbl_push) {
255 assert(dbl_push || x87_on_stack(state, reg_idx) == -1 && "double push");
256 assert(state->depth < N_x87_REGS && "stack overrun");
259 state->tos = MASK_TOS(state->tos - 1);
260 state->st[state->tos].reg_idx = reg_idx;
261 state->st[state->tos].node = node;
263 DB((dbg, LEVEL_2, "After PUSH:\n ")); DEBUG_ONLY(x87_dump_stack(state));
267 * Pop a virtual Register from the stack.
269 static void x87_pop(x87_state *state) {
270 assert(state->depth > 0 && "stack underrun");
273 state->tos = MASK_TOS(state->tos + 1);
275 DB((dbg, LEVEL_2, "After POP:\n ")); DEBUG_ONLY(x87_dump_stack(state));
279 * Returns the block state of a block.
281 * @param sim the x87 simulator handle
282 * @param block the current block
284 * @return the block state
286 static blk_state *x87_get_bl_state(x87_simulator *sim, ir_node *block) {
287 pmap_entry *entry = pmap_find(sim->blk_states, block);
290 blk_state *bl_state = obstack_alloc(&sim->obst, sizeof(*bl_state));
291 bl_state->begin = NULL;
292 bl_state->end = NULL;
294 pmap_insert(sim->blk_states, block, bl_state);
298 return entry ? PTR_TO_BLKSTATE(entry->value) : NULL;
302 * Creates a new x87 state.
304 * @param sim the x87 simulator handle
305 * @return a new x87 state
307 static x87_state *x87_alloc_state(x87_simulator *sim) {
308 x87_state *res = obstack_alloc(&sim->obst, sizeof(*res));
313 * Create a new empty x87 state.
315 * @param sim the x87 simulator handle
316 * @return a new empty x87 state
318 static x87_state *x87_alloc_empty_state(x87_simulator *sim) {
319 x87_state *res = x87_alloc_state(sim);
328 * @param sim the x87 simulator handle
329 * @param src the x87 state that will be cloned
331 * @return a cloned copy of the src state
333 static x87_state *x87_clone_state(x87_simulator *sim, const x87_state *src) {
334 x87_state *res = x87_alloc_state(sim);
336 memcpy(res, src, sizeof(*res));
341 * Patch a virtual instruction into a x87 one and return
344 * @param n the IR node to patch
345 * @param op the x87 opcode to patch in
347 static ir_node *x87_patch_insn(ir_node *n, ir_op *op) {
348 ir_mode *mode = get_irn_mode(n);
353 if (mode == mode_T) {
354 /* patch all Proj's */
355 const ir_edge_t *edge;
357 foreach_out_edge(n, edge) {
358 ir_node *proj = get_edge_src_irn(edge);
360 mode = get_irn_mode(proj);
361 if (mode_is_float(mode)) {
363 set_irn_mode(proj, mode_E);
368 else if (mode_is_float(mode))
369 set_irn_mode(n, mode_E);
374 * Returns the first Proj of a mode_T node having a given mode.
376 * @param n the mode_T node
377 * @param m the desired mode of the Proj
378 * @return The first Proj of mode @p m found or NULL.
380 static ir_node *get_irn_Proj_for_mode(ir_node *n, ir_mode *m) {
381 const ir_edge_t *edge;
383 assert(get_irn_mode(n) == mode_T && "Need mode_T node");
385 foreach_out_edge(n, edge) {
386 ir_node *proj = get_edge_src_irn(edge);
387 if (get_irn_mode(proj) == m)
394 /* -------------- x87 perm --------------- */
397 * Creates a fxch for shuffle.
399 * @param state the x87 state
400 * @param pos parameter for fxch
401 * @param dst_block the block of the user
403 * Creates a new fxch node and reroute the user of the old node
406 * @return the fxch node
408 static ir_node *x87_fxch_shuffle(x87_state *state, int pos, ir_node *block, ir_node *dst_block)
410 const ir_edge_t *edge;
411 ir_node *n = x87_get_st_node(state, pos);
412 ir_node *user = NULL;
417 if (block == get_nodes_block(n)) {
418 /* this is a node from out block: change it's user */
419 foreach_out_edge(n, edge) {
420 ir_node *succ = get_edge_src_irn(edge);
422 if (is_Phi(succ) && get_nodes_block(succ) == dst_block) {
424 node_idx = get_edge_src_pos(edge);
431 fxch = new_rd_ia32_fxch(NULL, get_irn_irg(block), block, n, get_irn_mode(n));
432 attr = get_ia32_attr(fxch);
433 attr->x87[0] = &ia32_st_regs[pos];
434 attr->x87[2] = &ia32_st_regs[0];
437 DB((dbg, LEVEL_2, "%+F replaced input %d of %+F\n", fxch, node_idx, user));
438 set_irn_n(user, node_idx, fxch);
442 * This is a node from a dominator block. Changing it's user might be wrong,
443 * so just keep it alive.
444 * The "right" solution would require a new Phi, but we don't care here.
449 x87_fxch(state, pos);
454 * Calculate the necessary permutations to reach dst_state.
456 * These permutations are done with fxch instructions and placed
457 * at the end of the block.
459 * Note that critical edges are removed here, so we need only
460 * a shuffle if the current block has only one successor.
462 * @param sim the simulator handle
463 * @param block the current block
464 * @param state the current x87 stack state, might be modified
465 * @param dst_block the destination block
466 * @param dst_state destination state
470 static x87_state *x87_shuffle(x87_simulator *sim, ir_node *block, x87_state *state, ir_node *dst_block, const x87_state *dst_state) {
471 int i, n_cycles, k, ri;
472 unsigned cycles[4], all_mask;
473 char cycle_idx[4][8];
475 ir_node *before, *after;
477 assert(state->depth == dst_state->depth);
479 /* Some mathematics here:
480 If we have a cycle of lenght n that includes the tos,
481 we need n-1 exchange operations.
482 We can always add the tos and restore it, so we need
483 n+1 exchange operations for a cycle not containing the tos.
484 So, the maximum of needed operations is for a cycle of 7
485 not including the tos == 8.
486 This is so same number of ops we would need for store,
487 so exchange is cheaper (we save the loads).
488 On the other hand, we might need an additional exchange
489 in the next block to bring one operand on top, so the
490 number of ops in the first case is identical.
491 Further, no more than 4 cycles can exists.
493 all_mask = (1 << (state->depth)) - 1;
495 for (n_cycles = 0; all_mask; ++n_cycles) {
496 int src_idx, dst_idx;
498 /* find the first free slot */
499 for (i = 0; i < state->depth; ++i) {
500 if (all_mask & (1 << i)) {
501 all_mask &= ~(1 << i);
503 /* check if there are differences here */
504 if (x87_get_st_reg(state, i) != x87_get_st_reg(dst_state, i))
510 /* no more cycles found */
515 cycles[n_cycles] = (1 << i);
516 cycle_idx[n_cycles][k++] = i;
517 for (src_idx = i; ; src_idx = dst_idx) {
518 dst_idx = x87_on_stack(dst_state, x87_get_st_reg(state, src_idx));
520 if ((all_mask & (1 << dst_idx)) == 0)
523 cycle_idx[n_cycles][k++] = dst_idx;
524 cycles[n_cycles] |= (1 << dst_idx);
525 all_mask &= ~(1 << dst_idx);
527 cycle_idx[n_cycles][k] = -1;
531 /* no permutation needed */
535 /* Hmm: permutation needed */
536 DB((dbg, LEVEL_2, "\n%+F needs permutation: from\n", block));
537 DEBUG_ONLY(x87_dump_stack(state));
538 DB((dbg, LEVEL_2, " to\n"));
539 DEBUG_ONLY(x87_dump_stack(dst_state));
543 DB((dbg, LEVEL_2, "Need %d cycles\n", n_cycles));
544 for (ri = 0; ri < n_cycles; ++ri) {
545 DB((dbg, LEVEL_2, " Ring %d:\n ", ri));
546 for (k = 0; cycle_idx[ri][k] != -1; ++k)
547 DB((dbg, LEVEL_2, " st%d ->", cycle_idx[ri][k]));
548 DB((dbg, LEVEL_2, "\n"));
555 * Find the place node must be insert.
556 * We have only one successor block, so the last instruction should
559 before = sched_last(block);
560 assert(is_cfop(before));
562 /* now do the permutations */
563 for (ri = 0; ri < n_cycles; ++ri) {
564 if ((cycles[ri] & 1) == 0) {
565 /* this cycle does not include the tos */
566 fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block, dst_block);
568 sched_add_after(after, fxch);
570 sched_add_before(before, fxch);
573 for (k = 1; cycle_idx[ri][k] != -1; ++k) {
574 fxch = x87_fxch_shuffle(state, cycle_idx[ri][k], block, dst_block);
576 sched_add_after(after, fxch);
578 sched_add_before(before, fxch);
581 if ((cycles[ri] & 1) == 0) {
582 /* this cycle does not include the tos */
583 fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block, dst_block);
584 sched_add_after(after, fxch);
591 * Create a fxch node before another node.
593 * @param state the x87 state
594 * @param n the node before the fxch
595 * @param pos exchange st(pos) with st(0)
596 * @param op_idx if >= 0, replace input op_idx of n with the fxch result
600 static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos, int op_idx) {
601 ir_node *fxch, *pred;
604 x87_fxch(state, pos);
607 pred = get_irn_n(n, op_idx);
609 pred = x87_get_st_node(state, pos);
611 fxch = new_rd_ia32_fxch(NULL, get_irn_irg(n), get_nodes_block(n), pred, get_irn_mode(pred));
612 attr = get_ia32_attr(fxch);
613 attr->x87[0] = &ia32_st_regs[pos];
614 attr->x87[2] = &ia32_st_regs[0];
617 set_irn_n(n, op_idx, fxch);
619 sched_add_before(n, fxch);
620 DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fxch), attr->x87[0]->name, attr->x87[2]->name));
625 * Create a fpush before node n.
627 * @param state the x87 state
628 * @param n the node before the fpush
629 * @param pos push st(pos) on stack
630 * @param op_idx if >= 0, replace input op_idx of n with the fpush result
631 * @param dbl_push if != 0 double pushes are allowd
633 static void x87_create_fpush(const arch_env_t *env, x87_state *state, ir_node *n, int pos, int op_idx, int dbl_push) {
634 ir_node *fpush, *pred = get_irn_n(n, op_idx);
636 const arch_register_t *out = arch_get_irn_register(env, pred);
638 x87_push(state, arch_register_get_index(out), pred, dbl_push);
640 fpush = new_rd_ia32_fpush(NULL, get_irn_irg(n), get_nodes_block(n), pred, get_irn_mode(pred));
641 attr = get_ia32_attr(fpush);
642 attr->x87[0] = &ia32_st_regs[pos];
643 attr->x87[2] = &ia32_st_regs[0];
645 set_irn_n(n, op_idx, fpush);
647 sched_add_before(n, fpush);
648 DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fpush), attr->x87[0]->name, attr->x87[2]->name));
652 * Create a fpop before node n.
654 * @param state the x87 state
655 * @param n the node before the fpop
656 * @param num pop 1 or 2 values
657 * @param pred node to use as predecessor of the fpop
659 * @return the fpop node
661 static ir_node *x87_create_fpop(const arch_env_t *env, x87_state *state, ir_node *n, int num, ir_node *pred) {
667 fpop = new_rd_ia32_fpop(NULL, get_irn_irg(n), get_nodes_block(n), pred, mode_E);
668 attr = get_ia32_attr(fpop);
669 attr->x87[0] = &ia32_st_regs[0];
670 attr->x87[1] = &ia32_st_regs[0];
671 attr->x87[2] = &ia32_st_regs[0];
673 sched_add_before(n, fpop);
674 DB((dbg, LEVEL_1, "<<< %s %s\n", get_irn_opname(fpop), attr->x87[0]->name));
682 /* --------------------------------- liveness ------------------------------------------ */
685 * The liveness transfer function.
686 * Updates a live set over a single step from a given node to its predecessor.
687 * Everything defined at the node is removed from the set, the uses of the node get inserted.
688 * @param arch_env The architecture environment.
689 * @param irn The node at which liveness should be computed.
690 * @param live The bitset of registers live before @p irn. This set gets modified by updating it to
691 * the registers live after irn.
694 static unsigned vfp_liveness_transfer(const arch_env_t *arch_env, ir_node *irn, unsigned live)
697 const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
699 if (arch_irn_consider_in_reg_alloc(arch_env, cls, irn)) {
700 const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
701 live &= ~(1 << reg->index);
704 for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
705 ir_node *op = get_irn_n(irn, i);
707 if (mode_is_float(get_irn_mode(op)) && arch_irn_consider_in_reg_alloc(arch_env, cls, op)) {
708 const arch_register_t *reg = arch_get_irn_register(arch_env, op);
709 live |= 1 << reg->index;
717 * Put all live virtual registers at the end of a block into a bitset.
718 * @param arch_env The architecture environment.
719 * @param bl The block.
720 * @return The live bitset.
722 static unsigned vfp_liveness_end_of_block(const arch_env_t *arch_env, const ir_node *bl)
726 const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
728 live_foreach(bl, li) {
729 ir_node *irn = (ir_node *) li->irn;
730 if (live_is_end(li) && arch_irn_consider_in_reg_alloc(arch_env, cls, irn)) {
731 const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
732 live |= 1 << reg->index;
740 * Compute a bitset of registers which are live at another node.
741 * @param arch_env The architecture environment.
742 * @param pos The node.
743 * @return The live bitset.
745 static unsigned vfp_liveness_nodes_live_at(const arch_env_t *arch_env, const ir_node *pos)
747 const ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos);
748 const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
752 live = vfp_liveness_end_of_block(arch_env, bl);
754 sched_foreach_reverse(bl, irn) {
756 * If we encounter the node we want to insert the Perm after,
757 * exit immediately, so that this node is still live
762 live = vfp_liveness_transfer(arch_env, irn, live);
769 * Returns true if a register is live in a set.
771 * @param reg_idx the vfp register index
772 * @param live a live bitset
774 static unsigned is_vfp_live(int reg_idx, unsigned live) {
775 return live & (1 << reg_idx);
780 * Dump liveness info.
782 * @param live the live bitset
784 static void vfp_dump_live(unsigned live) {
787 DB((dbg, LEVEL_2, "Live registers here: \n"));
788 for (i = 0; i < 8; ++i) {
789 if (live & (1 << i)) {
790 DB((dbg, LEVEL_2, " vf%d", i));
793 DB((dbg, LEVEL_2, "\n"));
795 #endif /* DEBUG_libfirm */
797 /* --------------------------------- simulators ---------------------------------------- */
799 #define XCHG(a, b) do { int t = (a); (a) = (b); (b) = t; } while (0)
802 * Simulate a virtual binop.
804 * @param state the x87 state
805 * @param n the node that should be simulated (and patched)
806 * @param env the architecture environment
807 * @param tmpl the template containing the 4 possible x87 opcodes
809 static int sim_binop(x87_state *state, ir_node *n, const arch_env_t *env, const exchange_tmpl *tmpl) {
810 int op2_idx, op1_idx = -1;
811 int out_idx, do_pop =0;
814 const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_1));
815 const arch_register_t *op2 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_2));
816 const arch_register_t *out = arch_get_irn_register(env, n);
817 unsigned live = vfp_liveness_nodes_live_at(env, n);
819 DB((dbg, LEVEL_1, ">>> %s %s, %s -> %s\n", get_irn_opname(n),
820 arch_register_get_name(op1), arch_register_get_name(op2),
821 arch_register_get_name(out)));
822 DEBUG_ONLY(vfp_dump_live(live));
824 op1_idx = x87_on_stack(state, arch_register_get_index(op1));
825 op2_idx = x87_on_stack(state, arch_register_get_index(op2));
827 if (op2->index != REG_VFP_NOREG) {
828 /* second operand is a vfp register */
830 if (is_vfp_live(op2->index, live)) {
831 /* Second operand is live. */
833 if (is_vfp_live(op1->index, live)) {
834 /* Both operands are live: push the first one.
835 This works even for op1 == op2. */
836 x87_create_fpush(env, state, n, op2_idx, BINOP_IDX_2, 0);
837 out_idx = op2_idx = 0;
839 dst = tmpl->normal_op;
843 /* Second live, first operand is dead here, bring it to tos. */
845 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
849 op1_idx = out_idx = 0;
850 dst = tmpl->normal_op;
855 /* Second operand is dead. */
856 if (is_vfp_live(op1->index, live)) {
857 /* First operand is live: bring second to tos. */
859 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
863 op2_idx = out_idx = 0;
864 dst = tmpl->normal_op;
868 /* Both operands are dead here, pop them from the stack. */
871 XCHG(op2_idx, op1_idx);
872 if (op1_idx == op2_idx) {
873 /* Both are identically, no pop needed. */
874 dst = tmpl->reverse_op;
878 dst = tmpl->reverse_pop_op;
882 else if (op1_idx == 0) {
884 if (op1_idx == op2_idx) {
885 /* Both are identically, no pop needed. */
886 dst = tmpl->normal_op;
890 dst = tmpl->normal_pop_op;
895 /* Bring the first on top. */
896 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
897 if (op1_idx == op2_idx) {
898 /* Both are identically, no pop needed. */
899 out_idx = op1_idx = op2_idx = 0;
900 dst = tmpl->normal_op;
906 dst = tmpl->normal_pop_op;
914 /* second operand is an address mode */
915 if (is_vfp_live(op1->index, live)) {
916 /* first operand is live: push it here */
917 x87_create_fpush(env, state, n, op1_idx, BINOP_IDX_1, 0);
920 /* first operand is dead: bring it to tos */
922 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
924 op1_idx = out_idx = 0;
925 dst = tmpl->normal_op;
929 x87_set_st(state, arch_register_get_index(out), x87_patch_insn(n, dst), out_idx);
933 /* patch the operation */
934 attr = get_ia32_attr(n);
935 attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
937 attr->x87[1] = op2 = &ia32_st_regs[op2_idx];
938 attr->x87[2] = out = &ia32_st_regs[out_idx];
941 DB((dbg, LEVEL_1, "<<< %s %s, %s -> %s\n", get_irn_opname(n),
942 arch_register_get_name(op1), arch_register_get_name(op2),
943 arch_register_get_name(out)));
945 DB((dbg, LEVEL_1, "<<< %s %s, [AM] -> %s\n", get_irn_opname(n),
946 arch_register_get_name(op1),
947 arch_register_get_name(out)));
953 * Simulate a virtual Unop.
955 * @param state the x87 state
956 * @param n the node that should be simulated (and patched)
957 * @param env the architecture environment
958 * @param op the x87 opcode that will replace n's opcode
960 static int sim_unop(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op) {
961 int op1_idx, out_idx;
962 const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, UNOP_IDX));
963 const arch_register_t *out = arch_get_irn_register(env, n);
965 unsigned live = vfp_liveness_nodes_live_at(env, n);
967 DB((dbg, LEVEL_1, ">>> %s -> %s\n", get_irn_opname(n), out->name));
968 DEBUG_ONLY(vfp_dump_live(live));
970 op1_idx = x87_on_stack(state, arch_register_get_index(op1));
972 if (is_vfp_live(op1->index, live)) {
973 /* push the operand here */
974 x87_create_fpush(env, state, n, op1_idx, UNOP_IDX, 0);
977 /* operand is dead, bring it to tos */
979 x87_create_fxch(state, n, op1_idx, UNOP_IDX);
982 x87_set_tos(state, arch_register_get_index(out), x87_patch_insn(n, op));
983 op1_idx = out_idx = 0;
984 attr = get_ia32_attr(n);
985 attr->x87[0] = op1 = &ia32_st_regs[0];
986 attr->x87[2] = out = &ia32_st_regs[0];
987 DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), out->name));
993 * Simulate a virtual Load instruction.
995 * @param state the x87 state
996 * @param n the node that should be simulated (and patched)
997 * @param env the architecture environment
998 * @param op the x87 opcode that will replace n's opcode
1000 static int sim_load(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op) {
1001 const arch_register_t *out = arch_get_irn_register(env, n);
1004 DB((dbg, LEVEL_1, ">>> %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
1005 x87_push(state, arch_register_get_index(out), x87_patch_insn(n, op), 0);
1006 attr = get_ia32_attr(n);
1007 attr->x87[2] = out = &ia32_st_regs[0];
1008 DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
1014 * Rewire all users of @p old_val to @new_val iff they are scheduled after @p store.
1016 * @param store The store
1017 * @param old_val The former value
1018 * @param new_val The new value
1020 static void collect_and_rewire_users(ir_node *store, ir_node *old_val, ir_node *new_val) {
1021 const ir_edge_t *edge, *ne;
1023 foreach_out_edge_safe(old_val, edge, ne) {
1024 ir_node *user = get_edge_src_irn(edge);
1026 if (! user || user == store)
1029 /* if the user is scheduled after the store: rewire */
1030 if (sched_is_scheduled(user) && sched_comes_after(store, user)) {
1032 /* find the input of the user pointing to the old value */
1033 for (i = get_irn_arity(user) - 1; i >= 0; i--) {
1034 if (get_irn_n(user, i) == old_val)
1035 set_irn_n(user, i, new_val);
1042 * Simulate a virtual Store.
1044 * @param state the x87 state
1045 * @param n the node that should be simulated (and patched)
1046 * @param env the architecture environment
1047 * @param op the x87 store opcode
1048 * @param op_p the x87 store and pop opcode
1050 static int sim_store(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op, ir_op *op_p) {
1051 ir_node *val = get_irn_n(n, STORE_VAL_IDX);
1052 const arch_register_t *op2 = arch_get_irn_register(env, val);
1053 unsigned live = vfp_liveness_nodes_live_at(env, n);
1059 op2_idx = x87_on_stack(state, arch_register_get_index(op2));
1060 assert(op2_idx >= 0);
1062 DB((dbg, LEVEL_1, ">>> %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
1064 mode = get_ia32_ls_mode(n);
1065 depth = x87_get_depth(state);
1068 We can only store the tos to memory.
1069 A store of mode_E with free registers
1070 pushes value to tos, so skip it here.
1072 if (! (mode == mode_E && depth < N_x87_REGS) && op2_idx != 0)
1073 x87_create_fxch(state, n, op2_idx, STORE_VAL_IDX);
1075 if (is_vfp_live(op2->index, live)) {
1077 Problem: fst doesn't support mode_E (spills), only fstp does
1079 - stack not full: push value and fstp
1080 - stack full: fstp value and load again
1082 if (mode == mode_E) {
1083 if (depth < N_x87_REGS) {
1084 /* ok, we have a free register: push + fstp */
1085 x87_create_fpush(env, state, n, op2_idx, STORE_VAL_IDX, 1);
1087 x87_patch_insn(n, op_p);
1090 ir_node *vfld, *mem, *block, *rproj, *mproj;
1093 /* stack full here: need fstp + load */
1095 x87_patch_insn(n, op_p);
1097 block = get_nodes_block(n);
1098 irg = get_irn_irg(n);
1099 vfld = new_rd_ia32_vfld(NULL, irg, block, get_irn_n(n, 0), get_irn_n(n, 1), new_rd_NoMem(irg));
1101 /* copy all attributes */
1102 set_ia32_frame_ent(vfld, get_ia32_frame_ent(n));
1103 if (is_ia32_use_frame(n))
1104 set_ia32_use_frame(vfld);
1105 set_ia32_am_flavour(vfld, get_ia32_am_flavour(n));
1106 set_ia32_op_type(vfld, ia32_am_Source);
1107 add_ia32_am_offs(vfld, get_ia32_am_offs(n));
1108 set_ia32_am_sc(vfld, get_ia32_am_sc(n));
1109 set_ia32_ls_mode(vfld, get_ia32_ls_mode(n));
1111 rproj = new_r_Proj(irg, block, vfld, get_ia32_ls_mode(vfld), pn_ia32_vfld_res);
1112 mproj = new_r_Proj(irg, block, vfld, mode_M, pn_ia32_vfld_M);
1113 mem = get_irn_Proj_for_mode(n, mode_M);
1115 assert(mem && "Store memory not found");
1117 arch_set_irn_register(env, rproj, op2);
1119 /* reroute all former users of the store memory to the load memory */
1120 edges_reroute(mem, mproj, irg);
1121 /* set the memory input of the load to the store memory */
1122 set_irn_n(vfld, 2, mem);
1124 sched_add_after(n, vfld);
1125 sched_add_after(vfld, rproj);
1127 /* rewire all users, scheduled after the store, to the loaded value */
1128 collect_and_rewire_users(n, val, rproj);
1134 /* mode != mode_E -> use normal fst */
1135 x87_patch_insn(n, op);
1140 x87_patch_insn(n, op_p);
1143 attr = get_ia32_attr(n);
1144 attr->x87[1] = op2 = &ia32_st_regs[0];
1145 DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
1151 * Simulate a virtual Phi.
1152 * Just for cosmetic reasons change the mode of Phi nodes to mode_E.
1154 * @param state the x87 state
1155 * @param n the node that should be simulated (and patched)
1156 * @param env the architecture environment
1158 static int sim_Phi(x87_state *state, ir_node *n, const arch_env_t *env) {
1159 ir_mode *mode = get_irn_mode(n);
1161 if (mode_is_float(mode))
1162 set_irn_mode(n, mode_E);
1168 #define _GEN_BINOP(op, rev) \
1169 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1170 exchange_tmpl tmpl = { op_ia32_##op, op_ia32_##rev, op_ia32_##op##p, op_ia32_##rev##p }; \
1171 return sim_binop(state, n, env, &tmpl); \
1174 #define GEN_BINOP(op) _GEN_BINOP(op, op)
1175 #define GEN_BINOPR(op) _GEN_BINOP(op, op##r)
1177 #define GEN_LOAD2(op, nop) \
1178 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1179 return sim_load(state, n, env, op_ia32_##nop); \
1182 #define GEN_LOAD(op) GEN_LOAD2(op, op)
1184 #define GEN_UNOP(op) \
1185 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1186 return sim_unop(state, n, env, op_ia32_##op); \
1189 #define GEN_STORE(op) \
1190 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1191 return sim_store(state, n, env, op_ia32_##op, op_ia32_##op##p); \
1210 GEN_LOAD2(fConst, fldConst)
1216 * Simulate a fCondJmp.
1218 * @param state the x87 state
1219 * @param n the node that should be simulated (and patched)
1220 * @param env the architecture environment
1222 static int sim_fCondJmp(x87_state *state, ir_node *n, const arch_env_t *env) {
1223 int op2_idx, op1_idx = -1, pop_cnt = 0;
1226 const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_1));
1227 const arch_register_t *op2 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_2));
1228 unsigned live = vfp_liveness_nodes_live_at(env, n);
1230 DB((dbg, LEVEL_1, ">>> %s %s, %s\n", get_irn_opname(n),
1231 arch_register_get_name(op1), arch_register_get_name(op2)));
1232 DEBUG_ONLY(vfp_dump_live(live));
1234 op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1235 op2_idx = x87_on_stack(state, arch_register_get_index(op2));
1237 /* BEWARE: check for comp a,a cases, they might happen */
1238 if (op2->index != REG_VFP_NOREG) {
1239 /* second operand is a vfp register */
1241 if (is_vfp_live(op2->index, live)) {
1242 /* second operand is live */
1244 if (is_vfp_live(op1->index, live)) {
1245 /* both operands are live: move one of them to tos */
1247 XCHG(op2_idx, op1_idx);
1248 dst = op_ia32_fcomrJmp;
1250 else if (op1_idx == 0) {
1251 dst = op_ia32_fcomJmp;
1254 /* bring the first on top */
1255 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1256 if (op1_idx == op2_idx)
1259 dst = op_ia32_fcomJmp;
1263 /* second live, first operand is dead here, bring it to tos.
1264 This means further, op1_idx != op2_idx. */
1266 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1271 dst = op_ia32_fcompJmp;
1276 /* second operand is dead */
1277 if (is_vfp_live(op1->index, live)) {
1278 /* first operand is live: bring second to tos.
1279 This means further, op1_idx != op2_idx. */
1281 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1286 dst = op_ia32_fcomrpJmp;
1290 /* both operands are dead here, check first for identity. */
1291 if (op1_idx == op2_idx) {
1292 /* identically, one one needed */
1294 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1295 op1_idx = op2_idx = 0;
1297 dst = op_ia32_fcompJmp;
1300 /* different, move them to st and st(1) and pop both.
1301 The tricky part is to get one into st(1).*/
1302 else if (op2_idx == 1) {
1303 /* good, second operand is already in the right place, move the first */
1305 /* bring the first on top */
1306 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1309 dst = op_ia32_fcomppJmp;
1312 else if (op1_idx == 1) {
1313 /* good, first operand is already in the right place, move the second */
1315 /* bring the first on top */
1316 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1319 dst = op_ia32_fcomrppJmp;
1323 /* if one is already the TOS, we need two fxch */
1325 /* first one is TOS, move to st(1) */
1326 x87_create_fxch(state, n, 1, BINOP_IDX_1);
1328 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1330 dst = op_ia32_fcomrppJmp;
1333 else if (op2_idx == 0) {
1334 /* second one is TOS, move to st(1) */
1335 x87_create_fxch(state, n, 1, BINOP_IDX_2);
1337 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1339 dst = op_ia32_fcomrppJmp;
1343 /* none of them is either TOS or st(1), 3 fxch needed */
1344 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1345 x87_create_fxch(state, n, 1, BINOP_IDX_2);
1346 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1349 dst = op_ia32_fcomppJmp;
1357 /* second operand is an address mode */
1358 if (is_vfp_live(op1->index, live)) {
1359 /* first operand is live: bring it to TOS */
1361 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1364 dst = op_ia32_fcomJmp;
1367 /* first operand is dead: bring it to tos */
1369 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1373 dst = op_ia32_fcompJmp;
1377 x87_patch_insn(n, dst);
1383 /* patch the operation */
1384 attr = get_ia32_attr(n);
1385 attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
1387 attr->x87[1] = op2 = &ia32_st_regs[op2_idx];
1390 DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(n),
1391 arch_register_get_name(op1), arch_register_get_name(op2)));
1393 DB((dbg, LEVEL_1, "<<< %s %s, [AM]\n", get_irn_opname(n),
1394 arch_register_get_name(op1)));
1400 * Simulate a be_Copy.
1402 * @param state the x87 state
1403 * @param n the node that should be simulated (and patched)
1404 * @param env the architecture environment
1406 static int sim_Copy(x87_state *state, ir_node *n, const arch_env_t *env) {
1407 ir_mode *mode = get_irn_mode(n);
1409 if (mode_is_float(mode)) {
1410 const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, 0));
1411 const arch_register_t *out = arch_get_irn_register(env, n);
1412 ir_node *node, *next;
1414 int op1_idx, out_idx;
1415 unsigned live = vfp_liveness_nodes_live_at(env, n);
1417 op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1419 DB((dbg, LEVEL_1, ">>> %s %s -> %s\n", get_irn_opname(n),
1420 arch_register_get_name(op1), arch_register_get_name(out)));
1421 DEBUG_ONLY(vfp_dump_live(live));
1423 if (is_vfp_live(op1->index, live)) {
1424 /* operand is still live,a real copy */
1425 node = new_rd_ia32_fpush(get_irn_dbg_info(n), get_irn_irg(n), get_nodes_block(n), get_irn_n(n, 0), mode);
1426 arch_set_irn_register(env, node, out);
1428 x87_push(state, arch_register_get_index(out), node, 0);
1430 attr = get_ia32_attr(node);
1431 attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
1432 attr->x87[2] = out = &ia32_st_regs[0];
1434 next = sched_next(n);
1437 sched_add_before(next, node);
1438 DB((dbg, LEVEL_1, ">>> %s %s -> %s\n", get_irn_opname(node), op1->name, out->name));
1441 out_idx = x87_on_stack(state, arch_register_get_index(out));
1443 if (out_idx >= 0 && out_idx != op1_idx) {
1444 /* op1 must be killed and placed where out is */
1446 /* best case, simple remove and rename */
1447 x87_patch_insn(n, op_ia32_Pop);
1448 attr = get_ia32_attr(n);
1449 attr->x87[0] = op1 = &ia32_st_regs[0];
1452 x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
1455 /* move op1 to tos, store and pop it */
1457 x87_create_fxch(state, n, op1_idx, 0);
1460 x87_patch_insn(n, op_ia32_Pop);
1461 attr = get_ia32_attr(n);
1462 attr->x87[0] = op1 = &ia32_st_regs[out_idx];
1465 x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
1467 DB((dbg, LEVEL_1, ">>> %s %s\n", get_irn_opname(n), op1->name));
1470 /* just a virtual copy */
1471 x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
1473 DB((dbg, LEVEL_1, ">>> KILLED %s\n", get_irn_opname(n)));
1474 exchange(n, get_unop_op(n));
1483 * Simulate a be_Call.
1485 * @param state the x87 state
1486 * @param n the node that should be simulated
1487 * @param env the architecture environment
1489 static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *env) {
1490 ir_type *call_tp = be_Call_get_type(n);
1492 /* at the begin of a call the x87 state should be empty */
1493 assert(state->depth == 0 && "stack not empty before call");
1496 * If the called function returns a float, it is returned in st(0).
1497 * This even happens if the return value is NOT used.
1498 * Moreover, only one return result is supported.
1500 if (get_method_n_ress(call_tp) > 0) {
1501 ir_type *res_type = get_method_res_type(call_tp, 0);
1502 ir_mode *mode = get_type_mode(res_type);
1504 if (mode && mode_is_float(mode)) {
1506 * TODO: what to push here? The result might be unused and currently
1507 * we have no possibility to detect this :-(
1509 x87_push(state, 0, n, 0);
1517 * Simulate a be_Spill.
1519 * @param state the x87 state
1520 * @param n the node that should be simulated (and patched)
1521 * @param env the architecture environment
1523 * Should not happen, spills are lowered before x87 simulator see them.
1525 static int sim_Spill(x87_state *state, ir_node *n, const arch_env_t *env) {
1526 assert(0 && "Spill not lowered");
1527 return sim_fst(state, n, env);
1531 * Simulate a be_Reload.
1533 * @param state the x87 state
1534 * @param n the node that should be simulated (and patched)
1535 * @param env the architecture environment
1537 * Should not happen, reloads are lowered before x87 simulator see them.
1539 static int sim_Reload(x87_state *state, ir_node *n, const arch_env_t *env) {
1540 assert(0 && "Reload not lowered");
1541 return sim_fld(state, n, env);
1545 * Simulate a be_Return.
1547 * @param state the x87 state
1548 * @param n the node that should be simulated (and patched)
1549 * @param env the architecture environment
1551 static int sim_Return(x87_state *state, ir_node *n, const arch_env_t *env) {
1552 int n_res = be_Return_get_n_rets(n);
1553 int i, n_float_res = 0;
1555 /* only floating point return values must resist on stack */
1556 for (i = 0; i < n_res; ++i) {
1557 ir_node *res = get_irn_n(n, be_pos_Return_val + i);
1559 if (mode_is_float(get_irn_mode(res)))
1562 assert(x87_get_depth(state) == n_float_res);
1564 /* pop them virtually */
1565 for (i = n_float_res - 1; i >= 0; --i)
1572 * Kill any dead registers at block start by popping them from the stack.
1574 * @param sim the simulator handle
1575 * @param block the current block
1576 * @param start_state the x87 state at the begin of the block
1578 static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *start_state) {
1579 x87_state *state = start_state;
1580 ir_node *first_insn = sched_first(block);
1581 ir_node *keep = NULL;
1582 unsigned live = vfp_liveness_nodes_live_at(sim->env, block);
1584 int i, depth, num_pop;
1587 depth = x87_get_depth(state);
1588 for (i = depth - 1; i >= 0; --i) {
1589 int reg = x87_get_st_reg(state, i);
1591 if (! is_vfp_live(reg, live))
1592 kill_mask |= (1 << i);
1596 /* create a new state, will be changed */
1597 state = x87_clone_state(sim, state);
1599 DB((dbg, LEVEL_1, "Killing deads:\n"));
1600 DEBUG_ONLY(vfp_dump_live(live));
1601 DEBUG_ONLY(x87_dump_stack(state));
1603 /* now kill registers */
1605 /* we can only kill from TOS, so bring them up */
1606 if (! (kill_mask & 1)) {
1607 /* search from behind, because we can to a double-pop */
1608 for (i = depth - 1; i >= 0; --i) {
1609 if (kill_mask & (1 << i)) {
1610 kill_mask &= ~(1 << i);
1617 x87_set_st(state, -1, keep, i);
1618 keep = x87_create_fxch(state, first_insn, i, -1);
1621 keep = x87_get_st_node(state, 0);
1623 if ((kill_mask & 3) == 3) {
1624 /* we can do a double-pop */
1628 /* only a single pop */
1633 kill_mask >>= num_pop;
1634 keep = x87_create_fpop(sim->env, state, first_insn, num_pop, keep);
1636 add_End_keepalive(get_irg_end(get_irn_irg(block)), keep);
1642 * Run a simulation and fix all virtual instructions for a block.
1644 * @param sim the simulator handle
1645 * @param block the current block
1647 * @return non-zero if simulation is complete,
1648 * zero if the simulation must be rerun
1650 static int x87_simulate_block(x87_simulator *sim, ir_node *block) {
1652 blk_state *bl_state = x87_get_bl_state(sim, block);
1653 x87_state *state = bl_state->begin;
1654 const ir_edge_t *edge;
1655 ir_node *start_block;
1657 /* if we have no assigned start state, we must wait ... */
1661 assert(bl_state->end == NULL);
1663 DB((dbg, LEVEL_1, "Simulate %+F\n", block));
1665 /* at block begin, kill all dead registers */
1666 state = x87_kill_deads(sim, block, state);
1668 /* beware, n might changed */
1669 for (n = sched_first(block); !sched_is_end(n); n = next) {
1670 ir_op *op = get_irn_op(n);
1672 next = sched_next(n);
1673 if (op->ops.generic) {
1675 sim_func func = (sim_func)op->ops.generic;
1677 /* have work to do */
1678 if (state == bl_state->begin) {
1679 /* create a new state, will be changed */
1680 state = x87_clone_state(sim, state);
1684 node_inserted = (*func)(state, n, sim->env);
1687 sim_func might have added additional nodes after n,
1689 beware: n must not be changed by sim_func
1690 (i.e. removed from schedule) in this case
1693 next = sched_next(n);
1697 start_block = get_irg_start_block(get_irn_irg(block));
1699 /* check if the state must be shuffled */
1700 foreach_block_succ(block, edge) {
1701 ir_node *succ = get_edge_src_irn(edge);
1702 blk_state *succ_state = x87_get_bl_state(sim, succ);
1704 if (succ_state->begin && succ != start_block) {
1705 /* There is already a begin state for this block, bad.
1706 Do the necessary permutations.
1707 Note that critical edges are removed, so this is always possible. */
1708 x87_shuffle(sim, block, state, succ, succ_state->begin);
1710 /* Note further, that there can be only one such situation,
1711 so we can break here. */
1715 bl_state->end = state;
1717 /* now propagate the state to all successor blocks */
1718 foreach_block_succ(block, edge) {
1719 ir_node *succ = get_edge_src_irn(edge);
1720 blk_state *succ_state = x87_get_bl_state(sim, succ);
1722 if (! succ_state->begin)
1723 succ_state->begin = state;
1730 * Create a new x87 simulator.
1732 * @param sim a simulator handle, will be initialized
1733 * @param irg the current graph
1734 * @param env the architecture environment
1736 static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, const arch_env_t *env) {
1737 obstack_init(&sim->obst);
1738 sim->blk_states = pmap_create();
1741 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.x87");
1743 DB((dbg, LEVEL_1, "--------------------------------\n"
1744 "x87 Simulator started for %+F\n", irg));
1746 /* set the generic function pointer of instruction we must simulate */
1747 clear_irp_opcodes_generic_func();
1749 #define ASSOC(op) (op_ ## op)->ops.generic = (op_func)(sim_##op)
1750 #define ASSOC_IA32(op) (op_ia32_v ## op)->ops.generic = (op_func)(sim_##op)
1751 #define ASSOC_BE(op) (op_be_ ## op)->ops.generic = (op_func)(sim_##op)
1769 ASSOC_IA32(fCondJmp);
1782 * Destroy a x87 simulator.
1784 * @param sim the simulator handle
1786 static void x87_destroy_simulator(x87_simulator *sim) {
1787 pmap_destroy(sim->blk_states);
1788 obstack_free(&sim->obst, NULL);
1789 DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
1793 * Run a simulation and fix all virtual instructions for a graph.
1795 * @param env the architecture environment
1796 * @param irg the current graph
1797 * @param blk_list the block schedule list
1799 * Needs a block-schedule.
1801 void x87_simulate_graph(const arch_env_t *env, ir_graph *irg, ir_node **blk_list) {
1802 ir_node *block, *start_block;
1804 blk_state *bl_state;
1808 /* we need liveness info for the current graph */
1811 /* create the simulator */
1812 x87_init_simulator(&sim, irg, env);
1814 start_block = get_irg_start_block(irg);
1815 bl_state = x87_get_bl_state(&sim, start_block);
1817 /* start with the empty state */
1818 bl_state->begin = empty;
1820 worklist = new_pdeq();
1822 /* create the worklist for the schedule. */
1823 for (i = 0; i < ARR_LEN(blk_list); ++i)
1824 pdeq_putr(worklist, blk_list[i]);
1828 block = pdeq_getl(worklist);
1829 if (! x87_simulate_block(&sim, block)) {
1830 pdeq_putr(worklist, block);
1833 } while (! pdeq_empty(worklist));
1836 x87_destroy_simulator(&sim);