9b79d1f8d597ef3ba38de53a95341e27fee3021e
[libfirm] / ir / be / ia32 / ia32_x87.c
1 /**
2  * This file implements the x87 support and virtual to stack
3  * register translation for the ia32 backend.
4  *
5  * @author: Michael Beck
6  *
7  * $Id$
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif /* HAVE_CONFIG_H */
13
14 #include <assert.h>
15
16 #include "irnode_t.h"
17 #include "irop_t.h"
18 #include "irprog.h"
19 #include "iredges_t.h"
20 #include "irgmod.h"
21 #include "ircons.h"
22 #include "obst.h"
23 #include "pmap.h"
24 #include "pdeq.h"
25 #include "irprintf.h"
26 #include "debug.h"
27
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"
34 #include "ia32_x87.h"
35
36 #define N_x87_REGS 8
37
38 /* first and second binop index */
39 #define BINOP_IDX_1     2
40 #define BINOP_IDX_2 3
41
42 /* the unop index */
43 #define UNOP_IDX  0
44
45 /* the store val index */
46 #define STORE_VAL_IDX 2
47
48 #define MASK_TOS(x)             ((x) & (N_x87_REGS - 1))
49
50 /** the debug handle */
51 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
52
53 /* Forward declaration. */
54 typedef struct _x87_simulator x87_simulator;
55
56 /**
57  * An exchange template.
58  * Note that our virtual functions have the same inputs
59  * and attributes as the real ones, so we can simple exchange
60  * their opcodes!
61  * Further, x87 supports inverse instructions, so we can handle them.
62  */
63 typedef struct _exchange_tmpl {
64         ir_op *normal_op;       /**< the normal one */
65         ir_op *reverse_op;      /**< the reverse one if exists */
66         ir_op *normal_pop_op;   /**< the normal one with tos pop */
67         ir_op *reverse_pop_op;  /**< the reverse one with tos pop */
68 } exchange_tmpl;
69
70 /**
71  * An entry on the simulated x87 stack.
72  */
73 typedef struct _st_entry {
74         int     reg_idx;        /**< the virtual register index of this stack value */
75         ir_node *node;          /**< the node that produced this value */
76 } st_entry;
77
78 /**
79  * The x87 state.
80  */
81 typedef struct _x87_state {
82         st_entry st[N_x87_REGS];  /**< the register stack */
83         int depth;                /**< the current stack depth */
84         int tos;                  /**< position of the tos */
85         x87_simulator *sim;       /**< The simulator. */
86 } x87_state;
87
88 /** An empty state, used for blocks without fp instructions. */
89 static x87_state _empty = { { {0, NULL}, }, 0, 0 };
90 static x87_state *empty = (x87_state *)&_empty;
91
92 /** The type of an instruction simulator function. */
93 typedef int (*sim_func)(x87_state *state, ir_node *n, const arch_env_t *env);
94
95 /**
96  * A block state: Every block has a x87 state at the beginning and at the end.
97  */
98 typedef struct _blk_state {
99         x87_state *begin;   /**< state at the begin or NULL if not assigned */
100         x87_state *end;     /**< state at the end or NULL if not assigned */
101 } blk_state;
102
103 #define PTR_TO_BLKSTATE(p)      ((blk_state *)(p))
104
105 /**
106  * The x87 simulator.
107  */
108 struct _x87_simulator {
109         struct obstack obst;      /**< an obstack for fast allocating */
110         pmap *blk_states;         /**< map blocks to states */
111         const arch_env_t *env;    /**< architecture environment */
112         unsigned char *live;      /**< Liveness information. */
113         unsigned n_idx;           /**< cached get_irg_last_idx() result */
114 };
115
116 /**
117  * Returns the current stack depth.
118  *
119  * @param state  the x87 state
120  *
121  * @return the x87 stack depth
122  */
123 static int x87_get_depth(const x87_state *state) {
124         return state->depth;
125 }
126
127 /**
128  * Check if the state is empty.
129  *
130  * @param state  the x87 state
131  *
132  * returns non-zero if the x87 stack is empty
133  */
134 static int x87_state_is_empty(const x87_state *state) {
135         return state->depth == 0;
136 }
137
138 /**
139  * Return the virtual register index at st(pos).
140  *
141  * @param state  the x87 state
142  * @param pos    a stack position
143  *
144  * @return the vfp register index that produced the value at st(pos)
145  */
146 static int x87_get_st_reg(const x87_state *state, int pos) {
147         assert(pos < state->depth);
148         return state->st[MASK_TOS(state->tos + pos)].reg_idx;
149 }
150
151 /**
152  * Return the node at st(pos).
153  *
154  * @param state  the x87 state
155  * @param pos    a stack position
156  *
157  * @return the IR node that produced the value at st(pos)
158  */
159 static ir_node *x87_get_st_node(const x87_state *state, int pos) {
160         assert(pos < state->depth);
161         return state->st[MASK_TOS(state->tos + pos)].node;
162 }  /* x87_get_st_node */
163
164 #ifdef DEBUG_libfirm
165 /**
166  * Dump the stack for debugging.
167  *
168  * @param state  the x87 state
169  */
170 static void x87_dump_stack(const x87_state *state) {
171         int i;
172
173         for (i = state->depth - 1; i >= 0; --i) {
174                 DB((dbg, LEVEL_2, "vf%d ", x87_get_st_reg(state, i)));
175         }
176         DB((dbg, LEVEL_2, "<-- TOS\n"));
177 }  /* x87_dump_stack */
178 #endif /* DEBUG_libfirm */
179
180 /**
181  * Set a virtual register to st(pos).
182  *
183  * @param state    the x87 state
184  * @param reg_idx  the vfp register index that should be set
185  * @param node     the IR node that produces the value of the vfp register
186  * @param pos      the stack position where the new value should be entered
187  */
188 static void x87_set_st(x87_state *state, int reg_idx, ir_node *node, int pos) {
189         assert(0 < state->depth);
190         state->st[MASK_TOS(state->tos + pos)].reg_idx = reg_idx;
191         state->st[MASK_TOS(state->tos + pos)].node    = node;
192
193         DB((dbg, LEVEL_2, "After SET_REG:\n ")); DEBUG_ONLY(x87_dump_stack(state));
194 }  /* x87_set_st */
195
196 /**
197  * Set the tos virtual register.
198  *
199  * @param state    the x87 state
200  * @param reg_idx  the vfp register index that should be set
201  * @param node     the IR node that produces the value of the vfp register
202  */
203 static void x87_set_tos(x87_state *state, int reg_idx, ir_node *node) {
204         x87_set_st(state, reg_idx, node, 0);
205 }  /* x87_set_tos */
206
207 /**
208  * Flush the x87 stack.
209  *
210  * @param state    the x87 state
211  */
212 static void x87_flush(x87_state *state) {
213         state->depth = 0;
214         state->tos   = 0;
215 }  /* x87_flush */
216
217 /**
218  * Swap st(0) with st(pos).
219  *
220  * @param state    the x87 state
221  * @param pos      the stack position to change the tos with
222  */
223 static void x87_fxch(x87_state *state, int pos) {
224         st_entry entry;
225         assert(pos < state->depth);
226
227         entry = state->st[MASK_TOS(state->tos + pos)];
228         state->st[MASK_TOS(state->tos + pos)] = state->st[MASK_TOS(state->tos)];
229         state->st[MASK_TOS(state->tos)] = entry;
230
231         DB((dbg, LEVEL_2, "After FXCH:\n ")); DEBUG_ONLY(x87_dump_stack(state));
232 }  /* x87_fxch */
233
234 /**
235  * Convert a virtual register to the stack index.
236  *
237  * @param state    the x87 state
238  * @param reg_idx  the register vfp index
239  *
240  * @return the stack position where the register is stacked
241  *         or -1 if the virtual register was not found
242  */
243 static int x87_on_stack(const x87_state *state, int reg_idx) {
244         int i, tos = state->tos;
245
246         for (i = 0; i < state->depth; ++i)
247                 if (state->st[MASK_TOS(tos + i)].reg_idx == reg_idx)
248                         return i;
249         return -1;
250 }  /* x87_on_stack */
251
252 /**
253  * Push a virtual Register onto the stack, double pushed allowed.
254  *
255  * @param state     the x87 state
256  * @param reg_idx   the register vfp index
257  * @param node      the node that produces the value of the vfp register
258  */
259 static void x87_push_dbl(x87_state *state, int reg_idx, ir_node *node) {
260         assert(state->depth < N_x87_REGS && "stack overrun");
261
262         ++state->depth;
263         state->tos = MASK_TOS(state->tos - 1);
264         state->st[state->tos].reg_idx = reg_idx;
265         state->st[state->tos].node    = node;
266
267         DB((dbg, LEVEL_2, "After PUSH:\n ")); DEBUG_ONLY(x87_dump_stack(state));
268 }  /* x87_push_dbl */
269
270 /**
271  * Push a virtual Register onto the stack, double pushes are NOT allowed..
272  *
273  * @param state     the x87 state
274  * @param reg_idx   the register vfp index
275  * @param node      the node that produces the value of the vfp register
276  * @param dbl_push  if != 0 double pushes are allowed
277  */
278 static void x87_push(x87_state *state, int reg_idx, ir_node *node) {
279         assert(x87_on_stack(state, reg_idx) == -1 && "double push");
280
281         x87_push_dbl(state, reg_idx, node);
282 }  /* x87_push */
283
284 /**
285  * Pop a virtual Register from the stack.
286  */
287 static void x87_pop(x87_state *state) {
288         assert(state->depth > 0 && "stack underrun");
289
290         --state->depth;
291         state->tos = MASK_TOS(state->tos + 1);
292
293         DB((dbg, LEVEL_2, "After POP:\n ")); DEBUG_ONLY(x87_dump_stack(state));
294 }  /* x87_pop */
295
296 /**
297  * Returns the block state of a block.
298  *
299  * @param sim    the x87 simulator handle
300  * @param block  the current block
301  *
302  * @return the block state
303  */
304 static blk_state *x87_get_bl_state(x87_simulator *sim, ir_node *block) {
305         pmap_entry *entry = pmap_find(sim->blk_states, block);
306
307         if (! entry) {
308                 blk_state *bl_state = obstack_alloc(&sim->obst, sizeof(*bl_state));
309                 bl_state->begin = NULL;
310                 bl_state->end   = NULL;
311
312                 pmap_insert(sim->blk_states, block, bl_state);
313                 return bl_state;
314         }
315
316         return PTR_TO_BLKSTATE(entry->value);
317 }  /* x87_get_bl_state */
318
319 /**
320  * Creates a new x87 state.
321  *
322  * @param sim    the x87 simulator handle
323  *
324  * @return a new x87 state
325  */
326 static x87_state *x87_alloc_state(x87_simulator *sim) {
327         x87_state *res = obstack_alloc(&sim->obst, sizeof(*res));
328
329         res->sim = sim;
330         return res;
331 }  /* x87_alloc_state */
332
333 /**
334  * Create a new empty x87 state.
335  *
336  * @param sim    the x87 simulator handle
337  *
338  * @return a new empty x87 state
339  */
340 static x87_state *x87_alloc_empty_state(x87_simulator *sim) {
341         x87_state *res = x87_alloc_state(sim);
342
343         x87_flush(res);
344         return res;
345 }  /* x87_alloc_empty_state */
346
347 /**
348  * Clone a x87 state.
349  *
350  * @param sim    the x87 simulator handle
351  * @param src    the x87 state that will be cloned
352  *
353  * @return a cloned copy of the src state
354  */
355 static x87_state *x87_clone_state(x87_simulator *sim, const x87_state *src) {
356         x87_state *res = x87_alloc_state(sim);
357
358         memcpy(res, src, sizeof(*res));
359         return res;
360 }  /* x87_clone_state */
361
362 /**
363  * Patch a virtual instruction into a x87 one and return
364  * the value node.
365  *
366  * @param n   the IR node to patch
367  * @param op  the x87 opcode to patch in
368  */
369 static ir_node *x87_patch_insn(ir_node *n, ir_op *op) {
370         ir_mode *mode = get_irn_mode(n);
371         ir_node *res = n;
372
373         set_irn_op(n, op);
374
375         if (mode == mode_T) {
376                 /* patch all Proj's */
377                 const ir_edge_t *edge;
378
379                 foreach_out_edge(n, edge) {
380                         ir_node *proj = get_edge_src_irn(edge);
381                         if (is_Proj(proj)) {
382                                 mode = get_irn_mode(proj);
383                                 if (mode_is_float(mode)) {
384                                         res = proj;
385                                         set_irn_mode(proj, mode_E);
386                                 }
387                         }
388                 }
389         }
390         else if (mode_is_float(mode))
391                 set_irn_mode(n, mode_E);
392         return res;
393 }  /* x87_patch_insn */
394
395 /**
396  * Returns the first Proj of a mode_T node having a given mode.
397  *
398  * @param n  the mode_T node
399  * @param m  the desired mode of the Proj
400  * @return The first Proj of mode @p m found or NULL.
401  */
402 static ir_node *get_irn_Proj_for_mode(ir_node *n, ir_mode *m) {
403         const ir_edge_t *edge;
404
405         assert(get_irn_mode(n) == mode_T && "Need mode_T node");
406
407         foreach_out_edge(n, edge) {
408                 ir_node *proj = get_edge_src_irn(edge);
409                 if (get_irn_mode(proj) == m)
410                         return proj;
411         }
412
413         return NULL;
414 }  /* get_irn_Proj_for_mode */
415
416 /* -------------- x87 perm --------------- */
417
418 /**
419  * Creates a fxch for shuffle.
420  *
421  * @param state     the x87 state
422  * @param pos       parameter for fxch
423  * @param dst_block the block of the user
424  *
425  * Creates a new fxch node and reroute the user of the old node
426  * to the fxch.
427  *
428  * @return the fxch node
429  */
430 static ir_node *x87_fxch_shuffle(x87_state *state, int pos, ir_node *block, ir_node *dst_block)
431 {
432         const ir_edge_t *edge;
433         ir_node *n = x87_get_st_node(state, pos);
434         ir_node *user = NULL;
435         ir_node *fxch;
436         int node_idx;
437         ia32_attr_t *attr;
438
439         if (block == get_nodes_block(n)) {
440                 /* this is a node from out block: change it's user */
441                 foreach_out_edge(n, edge) {
442                         ir_node *succ = get_edge_src_irn(edge);
443
444                         if (is_Phi(succ) && get_nodes_block(succ) == dst_block) {
445                                 user = succ;
446                                 node_idx = get_edge_src_pos(edge);
447                                 break;
448                         }
449                 }
450                 assert(user);
451         }
452
453         fxch = new_rd_ia32_fxch(NULL, get_irn_irg(block), block, n, get_irn_mode(n));
454         attr = get_ia32_attr(fxch);
455         attr->x87[0] = &ia32_st_regs[pos];
456         attr->x87[2] = &ia32_st_regs[0];
457
458         if (user) {
459                 DB((dbg, LEVEL_2, "%+F replaced input %d of %+F\n", fxch, node_idx, user));
460                 set_irn_n(user, node_idx, fxch);
461         }
462         else {
463                 /*
464                  * This is a node from a dominator block. Changing it's user might be wrong,
465                  * so just keep it alive.
466                  * The "right" solution would require a new Phi, but we don't care here.
467                  */
468                 keep_alive(fxch);
469         }
470
471         x87_fxch(state, pos);
472         return fxch;
473 }  /* x87_fxch_shuffle */
474
475 /**
476  * Calculate the necessary permutations to reach dst_state.
477  *
478  * These permutations are done with fxch instructions and placed
479  * at the end of the block.
480  *
481  * Note that critical edges are removed here, so we need only
482  * a shuffle if the current block has only one successor.
483  *
484  * @param sim        the simulator handle
485  * @param block      the current block
486  * @param state      the current x87 stack state, might be modified
487  * @param dst_block  the destination block
488  * @param dst_state  destination state
489  *
490  * @return state
491  */
492 static x87_state *x87_shuffle(x87_simulator *sim, ir_node *block, x87_state *state, ir_node *dst_block, const x87_state *dst_state) {
493         int i, n_cycles, k, ri;
494         unsigned cycles[4], all_mask;
495         char cycle_idx[4][8];
496         ir_node *fxch;
497         ir_node *before, *after;
498
499         assert(state->depth == dst_state->depth);
500
501         /* Some mathematics here:
502            If we have a cycle of length n that includes the tos,
503            we need n-1 exchange operations.
504            We can always add the tos and restore it, so we need
505            n+1 exchange operations for a cycle not containing the tos.
506            So, the maximum of needed operations is for a cycle of 7
507            not including the tos == 8.
508            This is the same number of ops we would need for using stores,
509            so exchange is cheaper (we save the loads).
510            On the other hand, we might need an additional exchange
511            in the next block to bring one operand on top, so the
512            number of ops in the first case is identical.
513            Further, no more than 4 cycles can exists (4 x 2).
514         */
515         all_mask = (1 << (state->depth)) - 1;
516
517         for (n_cycles = 0; all_mask; ++n_cycles) {
518                 int src_idx, dst_idx;
519
520                 /* find the first free slot */
521                 for (i = 0; i < state->depth; ++i) {
522                         if (all_mask & (1 << i)) {
523                                 all_mask &= ~(1 << i);
524
525                                 /* check if there are differences here */
526                                 if (x87_get_st_reg(state, i) != x87_get_st_reg(dst_state, i))
527                                         break;
528                         }
529                 }
530
531                 if (! all_mask) {
532                         /* no more cycles found */
533                         break;
534                 }
535
536                 k = 0;
537                 cycles[n_cycles] = (1 << i);
538                 cycle_idx[n_cycles][k++] = i;
539                 for (src_idx = i; ; src_idx = dst_idx) {
540                         dst_idx = x87_on_stack(dst_state, x87_get_st_reg(state, src_idx));
541
542                         if ((all_mask & (1 << dst_idx)) == 0)
543                                 break;
544
545                         cycle_idx[n_cycles][k++] = dst_idx;
546                         cycles[n_cycles] |=  (1 << dst_idx);
547                         all_mask       &= ~(1 << dst_idx);
548                 }
549                 cycle_idx[n_cycles][k] = -1;
550         }
551
552         if (n_cycles <= 0) {
553                 /* no permutation needed */
554                 return state;
555         }
556
557         /* Hmm: permutation needed */
558         DB((dbg, LEVEL_2, "\n%+F needs permutation: from\n", block));
559         DEBUG_ONLY(x87_dump_stack(state));
560         DB((dbg, LEVEL_2, "                  to\n"));
561         DEBUG_ONLY(x87_dump_stack(dst_state));
562
563
564 #ifdef DEBUG_libfirm
565         DB((dbg, LEVEL_2, "Need %d cycles\n", n_cycles));
566         for (ri = 0; ri < n_cycles; ++ri) {
567                 DB((dbg, LEVEL_2, " Ring %d:\n ", ri));
568                 for (k = 0; cycle_idx[ri][k] != -1; ++k)
569                         DB((dbg, LEVEL_2, " st%d ->", cycle_idx[ri][k]));
570                 DB((dbg, LEVEL_2, "\n"));
571         }
572 #endif
573
574         after = NULL;
575
576         /*
577          * Find the place node must be insert.
578          * We have only one successor block, so the last instruction should
579          * be a jump.
580          */
581         before = sched_last(block);
582         assert(is_cfop(before));
583
584         /* now do the permutations */
585         for (ri = 0; ri < n_cycles; ++ri) {
586                 if ((cycles[ri] & 1) == 0) {
587                         /* this cycle does not include the tos */
588                         fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block, dst_block);
589                         if (after)
590                                 sched_add_after(after, fxch);
591                         else
592                                 sched_add_before(before, fxch);
593                         after = fxch;
594                 }
595                 for (k = 1; cycle_idx[ri][k] != -1; ++k) {
596                         fxch = x87_fxch_shuffle(state, cycle_idx[ri][k], block, dst_block);
597                         if (after)
598                                 sched_add_after(after, fxch);
599                         else
600                                 sched_add_before(before, fxch);
601                         after = fxch;
602                 }
603                 if ((cycles[ri] & 1) == 0) {
604                         /* this cycle does not include the tos */
605                         fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block, dst_block);
606                         sched_add_after(after, fxch);
607                 }
608         }
609         return state;
610 }  /* x87_shuffle */
611
612 /**
613  * Create a fxch node before another node.
614  *
615  * @param state   the x87 state
616  * @param n       the node before the fxch
617  * @param pos     exchange st(pos) with st(0)
618  * @param op_idx  if >= 0, replace input op_idx of n with the fxch result
619  *
620  * @return the fxch
621  */
622 static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos, int op_idx) {
623         ir_node *fxch, *pred;
624         ia32_attr_t *attr;
625
626         x87_fxch(state, pos);
627
628         if (op_idx >= 0)
629                 pred = get_irn_n(n, op_idx);
630         else
631                 pred = x87_get_st_node(state, pos);
632
633         fxch = new_rd_ia32_fxch(NULL, get_irn_irg(n), get_nodes_block(n), pred, get_irn_mode(pred));
634         attr = get_ia32_attr(fxch);
635         attr->x87[0] = &ia32_st_regs[pos];
636         attr->x87[2] = &ia32_st_regs[0];
637
638         if (op_idx >= 0)
639                 set_irn_n(n, op_idx, fxch);
640
641         sched_add_before(n, fxch);
642         DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fxch), attr->x87[0]->name, attr->x87[2]->name));
643         return fxch;
644 }  /* x87_create_fxch */
645
646 /**
647  * Create a fpush before node n.
648  *
649  * @param state     the x87 state
650  * @param n         the node before the fpush
651  * @param pos       push st(pos) on stack
652  * @param op_idx    if >= 0, replace input op_idx of n with the fpush result
653  */
654 static void x87_create_fpush(const arch_env_t *env, x87_state *state, ir_node *n, int pos, int op_idx) {
655         ir_node *fpush, *pred = get_irn_n(n, op_idx);
656         ia32_attr_t *attr;
657         const arch_register_t *out = arch_get_irn_register(env, pred);
658
659         x87_push_dbl(state, arch_register_get_index(out), pred);
660
661         fpush = new_rd_ia32_fpush(NULL, get_irn_irg(n), get_nodes_block(n), pred, get_irn_mode(pred));
662         attr  = get_ia32_attr(fpush);
663         attr->x87[0] = &ia32_st_regs[pos];
664         attr->x87[2] = &ia32_st_regs[0];
665         if (op_idx >= 0)
666                 set_irn_n(n, op_idx, fpush);
667
668         sched_add_before(n, fpush);
669         DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fpush), attr->x87[0]->name, attr->x87[2]->name));
670 }  /* x87_create_fpush */
671
672 /**
673  * Create a fpop before node n.
674  *
675  * @param state   the x87 state
676  * @param n       the node before the fpop
677  * @param num     pop 1 or 2 values
678  * @param pred    node to use as predecessor of the fpop
679  *
680  * @return the fpop node
681  */
682 static ir_node *x87_create_fpop(const arch_env_t *env, x87_state *state, ir_node *n, int num, ir_node *pred) {
683         ir_node *fpop;
684         ia32_attr_t *attr;
685
686         while (num > 0) {
687                 x87_pop(state);
688                 fpop = new_rd_ia32_fpop(NULL, get_irn_irg(n), get_nodes_block(n), mode_E);
689                 attr = get_ia32_attr(fpop);
690                 attr->x87[0] = &ia32_st_regs[0];
691                 attr->x87[1] = &ia32_st_regs[0];
692                 attr->x87[2] = &ia32_st_regs[0];
693
694                 sched_add_before(n, fpop);
695                 DB((dbg, LEVEL_1, "<<< %s %s\n", get_irn_opname(fpop), attr->x87[0]->name));
696
697                 pred = fpop;
698                 --num;
699         }
700         return fpop;
701 }  /* x87_create_fpop */
702
703 /* --------------------------------- liveness ------------------------------------------ */
704
705 /**
706  * The liveness transfer function.
707  * Updates a live set over a single step from a given node to its predecessor.
708  * Everything defined at the node is removed from the set, the uses of the node get inserted.
709  *
710  * @param arch_env The architecture environment.
711  * @param irn      The node at which liveness should be computed.
712  * @param live     The bitset of registers live before @p irn. This set gets modified by updating it to
713  *                 the registers live after irn.
714  *
715  * @return The live bitset.
716  */
717 static unsigned vfp_liveness_transfer(const arch_env_t *arch_env, ir_node *irn, unsigned live)
718 {
719         int i, n;
720         const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
721
722         if (arch_irn_consider_in_reg_alloc(arch_env, cls, irn)) {
723                         const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
724                         live &= ~(1 << reg->index);
725         }
726
727         for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
728                 ir_node *op = get_irn_n(irn, i);
729
730                 if (mode_is_float(get_irn_mode(op)) && arch_irn_consider_in_reg_alloc(arch_env, cls, op)) {
731                         const arch_register_t *reg = arch_get_irn_register(arch_env, op);
732                         live |= 1 << reg->index;
733                 }
734         }
735         return live;
736 }  /* vfp_liveness_transfer */
737
738 /**
739  * Put all live virtual registers at the end of a block into a bitset.
740  *
741  * @param env      the architecture environment
742  * @param lv       the liveness information
743  * @param bl       the block
744  *
745  * @return The live bitset at the end of this block
746  */
747 static unsigned vfp_liveness_end_of_block(const arch_env_t *env, be_lv_t *lv, const ir_node *bl)
748 {
749         int i;
750         unsigned live = 0;
751         const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
752
753         be_lv_foreach(lv, bl, be_lv_state_end, i) {
754                 ir_node *irn = be_lv_get_irn(lv, bl, i);
755                 if (arch_irn_consider_in_reg_alloc(env, cls, irn)) {
756                         const arch_register_t *reg = arch_get_irn_register(env, irn);
757                         live |= 1 << reg->index;
758                 }
759         }
760
761         return live;
762 }  /* vfp_liveness_end_of_block */
763
764 /** get the register mask from an arch_register */
765 #define REGMASK(reg)    (1 << (reg)->index)
766
767 /**
768  * Return a bitset of argument registers which are live at the end of a node.
769  *
770  * @param sim    the simulator handle
771  * @param pos    the node
772  * @param kill   kill mask for the output registers
773  *
774  * @return The live bitset.
775  */
776 static unsigned vfp_live_args_after(x87_simulator *sim, const ir_node *pos, unsigned kill)
777 {
778         unsigned idx = get_irn_idx(pos);
779
780         assert(idx < sim->n_idx);
781         return sim->live[idx] & ~kill;
782 }  /* vfp_live_args_after */
783
784 /**
785  * Calculate the liveness for a whole block and cache it.
786  *
787  * @param sim  the simulator handle
788  * @param lv   the liveness handle
789  * @param blk  the block
790  */
791 static void update_liveness(x87_simulator *sim, be_lv_t *lv, ir_node *blk) {
792         unsigned live = vfp_liveness_end_of_block(sim->env, lv, blk);
793         unsigned idx;
794         ir_node *irn;
795
796         /* now iterate through the block backward and cache the results */
797         sched_foreach_reverse(blk, irn) {
798                 /* stop at the first Phi: this produces the live-in */
799                 if (is_Phi(irn))
800                         break;
801
802                 idx = get_irn_idx(irn);
803                 sim->live[idx] = live;
804
805                 live = vfp_liveness_transfer(sim->env, irn, live);
806         }
807         idx = get_irn_idx(blk);
808         sim->live[idx] = live;
809 }  /* update_liveness */
810
811 /**
812  * Returns true if a register is live in a set.
813  *
814  * @param reg_idx  the vfp register index
815  * @param live     a live bitset
816  */
817 #define is_vfp_live(reg_idx, live) ((live) & (1 << (reg_idx)))
818
819 #ifdef DEBUG_libfirm
820 /**
821  * Dump liveness info.
822  *
823  * @param live  the live bitset
824  */
825 static void vfp_dump_live(unsigned live) {
826         int i;
827
828         DB((dbg, LEVEL_2, "Live registers here: \n"));
829         for (i = 0; i < 8; ++i) {
830                 if (live & (1 << i)) {
831                         DB((dbg, LEVEL_2, " vf%d", i));
832                 }
833         }
834         DB((dbg, LEVEL_2, "\n"));
835 }  /* vfp_dump_live */
836 #endif /* DEBUG_libfirm */
837
838 /* --------------------------------- simulators ---------------------------------------- */
839
840 #define XCHG(a, b) do { int t = (a); (a) = (b); (b) = t; } while (0)
841
842 /**
843  * Simulate a virtual binop.
844  *
845  * @param state  the x87 state
846  * @param n      the node that should be simulated (and patched)
847  * @param env    the architecture environment
848  * @param tmpl   the template containing the 4 possible x87 opcodes
849  */
850 static int sim_binop(x87_state *state, ir_node *n, const arch_env_t *env, const exchange_tmpl *tmpl) {
851         int op2_idx, op1_idx = -1;
852         int out_idx, do_pop =0;
853         ia32_attr_t *attr;
854         ir_op *dst;
855         const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_1));
856         const arch_register_t *op2 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_2));
857         const arch_register_t *out = arch_get_irn_register(env, n);
858         unsigned live = vfp_live_args_after(state->sim, n, REGMASK(out));
859
860         DB((dbg, LEVEL_1, ">>> %+F %s, %s -> %s\n", n,
861                 arch_register_get_name(op1), arch_register_get_name(op2),
862                 arch_register_get_name(out)));
863         DEBUG_ONLY(vfp_dump_live(live));
864
865         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
866         op2_idx = x87_on_stack(state, arch_register_get_index(op2));
867
868         if (op2->index != REG_VFP_NOREG) {
869                 /* second operand is a vfp register */
870
871                 if (is_vfp_live(op2->index, live)) {
872                         /* Second operand is live. */
873
874                         if (is_vfp_live(op1->index, live)) {
875                                 /* Both operands are live: push the first one.
876                                    This works even for op1 == op2. */
877                                 x87_create_fpush(env, state, n, op2_idx, BINOP_IDX_2);
878                                 out_idx = op2_idx = 0;
879                                 ++op1_idx;
880                                 dst = tmpl->normal_op;
881                                 do_pop = 0;
882                         }
883                         else {
884                                 /* Second live, first operand is dead here, bring it to tos. */
885                                 if (op1_idx != 0) {
886                                         x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
887                                         if (op2_idx == 0)
888                                                 op2_idx = op1_idx;
889                                 }
890                                 op1_idx = out_idx = 0;
891                                 dst = tmpl->normal_op;
892                                 do_pop = 0;
893                         }
894                 }
895                 else {
896                         /* Second operand is dead. */
897                         if (is_vfp_live(op1->index, live)) {
898                                 /* First operand is live: bring second to tos. */
899                                 if (op2_idx != 0) {
900                                         x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
901                                         if (op1_idx == 0)
902                                                 op1_idx = op2_idx;
903                                 }
904                                 op2_idx = out_idx = 0;
905                                 dst = tmpl->reverse_op;
906                                 do_pop = 0;
907                         }
908                         else {
909                                 /* Both operands are dead here, pop them from the stack. */
910                                 if (op2_idx == 0) {
911                                         out_idx = op1_idx;
912                                         if (op1_idx == op2_idx) {
913                                                 /* Both are identically, no pop needed. */
914                                                 dst = tmpl->normal_op;
915                                                 do_pop = 0;
916                                         }
917                                         else {
918                                                 dst = tmpl->normal_pop_op;
919                                                 do_pop = 1;
920                                         }
921                                 }
922                                 else if (op1_idx == 0) {
923                                         out_idx = op2_idx;
924                                         XCHG(op2_idx, op1_idx);
925                                         if (op1_idx == op2_idx) {
926                                                 /* Both are identically, no pop needed. */
927                                                 dst = tmpl->reverse_op;
928                                                 do_pop = 0;
929                                         }
930                                         else {
931                                                 dst = tmpl->reverse_pop_op;
932                                                 do_pop = 1;
933                                         }
934                                 }
935                                 else {
936                                         /* Bring the second on top. */
937                                         x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
938                                         if (op1_idx == op2_idx) {
939                                                 /* Both are identically, no pop needed. */
940                                                 out_idx = op1_idx = op2_idx = 0;
941                                                 dst = tmpl->normal_op;
942                                                 do_pop = 0;
943                                         }
944                                         else {
945                                                 op2_idx = 0;
946                                                 out_idx = op1_idx;
947                                                 dst = tmpl->normal_pop_op;
948                                                 do_pop = 1;
949                                         }
950                                 }
951                         }
952                 }
953         }
954         else {
955                 /* second operand is an address mode */
956                 if (is_vfp_live(op1->index, live)) {
957                         /* first operand is live: push it here */
958                         x87_create_fpush(env, state, n, op1_idx, BINOP_IDX_1);
959                 }
960                 else {
961                         /* first operand is dead: bring it to tos */
962                         if (op1_idx != 0)
963                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
964                 }
965                 op1_idx = out_idx = 0;
966                 dst = tmpl->normal_op;
967                 do_pop = 0;
968         }
969
970         x87_set_st(state, out->index, x87_patch_insn(n, dst), out_idx);
971         if (do_pop)
972                 x87_pop(state);
973
974         /* patch the operation */
975         attr = get_ia32_attr(n);
976         attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
977         if (op2_idx >= 0)
978                 attr->x87[1] = op2 = &ia32_st_regs[op2_idx];
979         attr->x87[2] = out = &ia32_st_regs[out_idx];
980
981         if (op2_idx >= 0)
982                 DB((dbg, LEVEL_1, "<<< %s %s, %s -> %s\n", get_irn_opname(n),
983                         arch_register_get_name(op1), arch_register_get_name(op2),
984                         arch_register_get_name(out)));
985         else
986                 DB((dbg, LEVEL_1, "<<< %s %s, [AM] -> %s\n", get_irn_opname(n),
987                         arch_register_get_name(op1),
988                         arch_register_get_name(out)));
989
990         return 0;
991 }  /* sim_binop */
992
993 /**
994  * Simulate a virtual Unop.
995  *
996  * @param state  the x87 state
997  * @param n      the node that should be simulated (and patched)
998  * @param env    the architecture environment
999  * @param op     the x87 opcode that will replace n's opcode
1000  */
1001 static int sim_unop(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op) {
1002         int op1_idx, out_idx;
1003         const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, UNOP_IDX));
1004         const arch_register_t *out = arch_get_irn_register(env, n);
1005         ia32_attr_t *attr;
1006         unsigned live = vfp_live_args_after(state->sim, n, REGMASK(out));
1007
1008         DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, out->name));
1009         DEBUG_ONLY(vfp_dump_live(live));
1010
1011         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1012
1013         if (is_vfp_live(op1->index, live)) {
1014                 /* push the operand here */
1015                 x87_create_fpush(env, state, n, op1_idx, UNOP_IDX);
1016         }
1017         else {
1018                 /* operand is dead, bring it to tos */
1019                 if (op1_idx != 0)
1020                         x87_create_fxch(state, n, op1_idx, UNOP_IDX);
1021         }
1022
1023         x87_set_tos(state, arch_register_get_index(out), x87_patch_insn(n, op));
1024         op1_idx = out_idx = 0;
1025         attr = get_ia32_attr(n);
1026         attr->x87[0] = op1 = &ia32_st_regs[0];
1027         attr->x87[2] = out = &ia32_st_regs[0];
1028         DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), out->name));
1029
1030         return 0;
1031 }  /* sim_unop */
1032
1033 /**
1034  * Simulate a virtual Load instruction.
1035  *
1036  * @param state  the x87 state
1037  * @param n      the node that should be simulated (and patched)
1038  * @param env    the architecture environment
1039  * @param op     the x87 opcode that will replace n's opcode
1040  */
1041 static int sim_load(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op) {
1042         const arch_register_t *out = arch_get_irn_register(env, n);
1043         ia32_attr_t *attr;
1044
1045         DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, arch_register_get_name(out)));
1046         x87_push(state, arch_register_get_index(out), x87_patch_insn(n, op));
1047         attr = get_ia32_attr(n);
1048         attr->x87[2] = out = &ia32_st_regs[0];
1049         DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
1050
1051         return 0;
1052 }  /* sim_load */
1053
1054 /**
1055  * Rewire all users of @p old_val to @new_val iff they are scheduled after @p store.
1056  *
1057  * @param store   The store
1058  * @param old_val The former value
1059  * @param new_val The new value
1060  */
1061 static void collect_and_rewire_users(ir_node *store, ir_node *old_val, ir_node *new_val) {
1062         const ir_edge_t *edge, *ne;
1063
1064         foreach_out_edge_safe(old_val, edge, ne) {
1065                 ir_node *user = get_edge_src_irn(edge);
1066
1067                 if (! user || user == store)
1068                         continue;
1069
1070                 /* if the user is scheduled after the store: rewire */
1071                 if (sched_is_scheduled(user) && sched_comes_after(store, user)) {
1072                         int i;
1073                         /* find the input of the user pointing to the old value */
1074                         for (i = get_irn_arity(user) - 1; i >= 0; i--) {
1075                                 if (get_irn_n(user, i) == old_val)
1076                                         set_irn_n(user, i, new_val);
1077                         }
1078                 }
1079         }
1080 }  /* collect_and_rewire_users */
1081
1082 /**
1083  * Simulate a virtual Store.
1084  *
1085  * @param state  the x87 state
1086  * @param n      the node that should be simulated (and patched)
1087  * @param env    the architecture environment
1088  * @param op     the x87 store opcode
1089  * @param op_p   the x87 store and pop opcode
1090  */
1091 static int sim_store(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op, ir_op *op_p) {
1092         ir_node               *val = get_irn_n(n, STORE_VAL_IDX);
1093         const arch_register_t *op2 = arch_get_irn_register(env, val);
1094         unsigned              live = vfp_live_args_after(state->sim, n, 0);
1095         int                   insn = 0;
1096         ia32_attr_t *attr;
1097         int op2_idx, depth;
1098         ir_mode *mode;
1099
1100         op2_idx = x87_on_stack(state, arch_register_get_index(op2));
1101         assert(op2_idx >= 0);
1102
1103         DB((dbg, LEVEL_1, ">>> %+F %s ->\n", n, arch_register_get_name(op2)));
1104
1105         mode  = get_ia32_ls_mode(n);
1106         depth = x87_get_depth(state);
1107
1108         /*
1109                 We can only store the tos to memory.
1110                 A store of mode_E with free registers
1111                 pushes value to tos, so skip it here.
1112         */
1113         if (! (mode == mode_E && depth < N_x87_REGS) && op2_idx != 0)
1114                 x87_create_fxch(state, n, op2_idx, STORE_VAL_IDX);
1115
1116         if (is_vfp_live(op2->index, live)) {
1117                 /*
1118                         Problem: fst doesn't support mode_E (spills), only fstp does
1119                         Solution:
1120                                 - stack not full: push value and fstp
1121                                 - stack full: fstp value and load again
1122                 */
1123                 if (mode == mode_E) {
1124                         if (depth < N_x87_REGS) {
1125                                 /* ok, we have a free register: push + fstp */
1126                                 x87_create_fpush(env, state, n, op2_idx, STORE_VAL_IDX);
1127                                 x87_pop(state);
1128                                 x87_patch_insn(n, op_p);
1129                         }
1130                         else {
1131                                 ir_node  *vfld, *mem, *block, *rproj, *mproj;
1132                                 ir_graph *irg;
1133
1134                                 /* stack full here: need fstp + load */
1135                                 x87_pop(state);
1136                                 x87_patch_insn(n, op_p);
1137
1138                                 block = get_nodes_block(n);
1139                                 irg   = get_irn_irg(n);
1140                                 vfld  = new_rd_ia32_vfld(NULL, irg, block, get_irn_n(n, 0), get_irn_n(n, 1), new_rd_NoMem(irg));
1141
1142                                 /* copy all attributes */
1143                                 set_ia32_frame_ent(vfld, get_ia32_frame_ent(n));
1144                                 if (is_ia32_use_frame(n))
1145                                         set_ia32_use_frame(vfld);
1146                                 set_ia32_am_flavour(vfld, get_ia32_am_flavour(n));
1147                                 set_ia32_op_type(vfld, ia32_am_Source);
1148                                 add_ia32_am_offs(vfld, get_ia32_am_offs(n));
1149                                 set_ia32_am_sc(vfld, get_ia32_am_sc(n));
1150                                 set_ia32_ls_mode(vfld, get_ia32_ls_mode(n));
1151
1152                                 rproj = new_r_Proj(irg, block, vfld, get_ia32_ls_mode(vfld), pn_ia32_vfld_res);
1153                                 mproj = new_r_Proj(irg, block, vfld, mode_M, pn_ia32_vfld_M);
1154                                 mem   = get_irn_Proj_for_mode(n, mode_M);
1155
1156                                 assert(mem && "Store memory not found");
1157
1158                                 arch_set_irn_register(env, rproj, op2);
1159
1160                                 /* reroute all former users of the store memory to the load memory */
1161                                 edges_reroute(mem, mproj, irg);
1162                                 /* set the memory input of the load to the store memory */
1163                                 set_irn_n(vfld, 2, mem);
1164
1165                                 sched_add_after(n, vfld);
1166                                 sched_add_after(vfld, rproj);
1167
1168                                 /* rewire all users, scheduled after the store, to the loaded value */
1169                                 collect_and_rewire_users(n, val, rproj);
1170
1171                                 insn = 1;
1172                         }
1173                 }
1174                 else {
1175                         /* mode != mode_E -> use normal fst */
1176                         x87_patch_insn(n, op);
1177                 }
1178         }
1179         else {
1180                 x87_pop(state);
1181                 x87_patch_insn(n, op_p);
1182         }
1183
1184         attr = get_ia32_attr(n);
1185         attr->x87[1] = op2 = &ia32_st_regs[0];
1186         DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
1187
1188         return insn;
1189 }  /* sim_store */
1190
1191 /**
1192  * Simulate a virtual Phi.
1193  * Just for cosmetic reasons change the mode of Phi nodes to mode_E.
1194  *
1195  * @param state  the x87 state
1196  * @param n      the node that should be simulated (and patched)
1197  * @param env    the architecture environment
1198  */
1199 static int sim_Phi(x87_state *state, ir_node *n, const arch_env_t *env) {
1200         ir_mode *mode = get_irn_mode(n);
1201
1202         if (mode_is_float(mode))
1203                 set_irn_mode(n, mode_E);
1204
1205         return 0;
1206 }  /* sim_Phi */
1207
1208
1209 #define _GEN_BINOP(op, rev) \
1210 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1211         exchange_tmpl tmpl = { op_ia32_##op, op_ia32_##rev, op_ia32_##op##p, op_ia32_##rev##p }; \
1212         return sim_binop(state, n, env, &tmpl); \
1213 }
1214
1215 #define GEN_BINOP(op)   _GEN_BINOP(op, op)
1216 #define GEN_BINOPR(op)  _GEN_BINOP(op, op##r)
1217
1218 #define GEN_LOAD2(op, nop) \
1219 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1220         return sim_load(state, n, env, op_ia32_##nop); \
1221 }
1222
1223 #define GEN_LOAD(op)    GEN_LOAD2(op, op)
1224
1225 #define GEN_UNOP(op) \
1226 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1227         return sim_unop(state, n, env, op_ia32_##op); \
1228 }
1229
1230 #define GEN_STORE(op) \
1231 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1232         return sim_store(state, n, env, op_ia32_##op, op_ia32_##op##p); \
1233 }
1234
1235 /* all stubs */
1236 GEN_BINOP(fadd)
1237 GEN_BINOPR(fsub)
1238 GEN_BINOP(fmul)
1239 GEN_BINOPR(fdiv)
1240
1241 GEN_UNOP(fabs)
1242 GEN_UNOP(fchs)
1243 GEN_UNOP(fsin)
1244 GEN_UNOP(fcos)
1245 GEN_UNOP(fsqrt)
1246
1247 GEN_LOAD(fld)
1248 GEN_LOAD(fild)
1249 GEN_LOAD(fldz)
1250 GEN_LOAD(fld1)
1251 GEN_LOAD2(fConst, fldConst)
1252
1253 GEN_STORE(fst)
1254 GEN_STORE(fist)
1255
1256 /**
1257  * Simulate a fCondJmp.
1258  *
1259  * @param state  the x87 state
1260  * @param n      the node that should be simulated (and patched)
1261  * @param env    the architecture environment
1262  */
1263 static int sim_fCondJmp(x87_state *state, ir_node *n, const arch_env_t *env) {
1264         int op2_idx, op1_idx = -1, pop_cnt = 0;
1265         ia32_attr_t *attr;
1266         ir_op *dst;
1267         const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_1));
1268         const arch_register_t *op2 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_2));
1269         unsigned live = vfp_live_args_after(state->sim, n, 0);
1270
1271         DB((dbg, LEVEL_1, ">>> %+F %s, %s\n", n,
1272                 arch_register_get_name(op1), arch_register_get_name(op2)));
1273         DEBUG_ONLY(vfp_dump_live(live));
1274
1275         op1_idx = x87_on_stack(state, op1->index);
1276         op2_idx = x87_on_stack(state, op2->index);
1277
1278         /* BEWARE: check for comp a,a cases, they might happen */
1279         if (op2->index != REG_VFP_NOREG) {
1280                 /* second operand is a vfp register */
1281
1282                 if (is_vfp_live(op2->index, live)) {
1283                         /* second operand is live */
1284
1285                         if (is_vfp_live(op1->index, live)) {
1286                                 /* both operands are live: move one of them to tos */
1287                                 if (op2_idx == 0) {
1288                                         XCHG(op2_idx, op1_idx);
1289                                         dst = op_ia32_fcomrJmp;
1290                                 }
1291                                 else if (op1_idx == 0) {
1292                                         dst = op_ia32_fcomJmp;
1293                                 }
1294                                 else {
1295                                         /* bring the first on top */
1296                                         x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1297                                         if (op1_idx == op2_idx)
1298                                                 op2_idx = 0;
1299                                         op1_idx = 0;
1300                                         dst     = op_ia32_fcomJmp;
1301                                 }
1302                         }
1303                         else {
1304                                 /* second live, first operand is dead here, bring it to tos.
1305                                    This means further, op1_idx != op2_idx. */
1306                                 if (op1_idx != 0) {
1307                                         x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1308                                         if (op2_idx == 0)
1309                                                 op2_idx = op1_idx;
1310                                 }
1311                                 op1_idx = 0;
1312                                 dst     = op_ia32_fcompJmp;
1313                                 pop_cnt = 1;
1314                         }
1315                 }
1316                 else {
1317                         /* second operand is dead */
1318                         if (is_vfp_live(op1->index, live)) {
1319                                 /* first operand is live: bring second to tos.
1320                                    This means further, op1_idx != op2_idx. */
1321                                 if (op2_idx != 0) {
1322                                         x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1323                                         if (op1_idx == 0)
1324                                                 op1_idx = op2_idx;
1325                                 }
1326                                 op2_idx = 0;
1327                                 dst     = op_ia32_fcomrpJmp;
1328                                 pop_cnt = 1;
1329                         }
1330                         else {
1331                                 /* both operands are dead here, check first for identity. */
1332                                 if (op1_idx == op2_idx) {
1333                                         /* identically, one one needed */
1334                                         if (op1_idx != 0) {
1335                                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1336                                                 op1_idx = op2_idx = 0;
1337                                         }
1338                                         dst     = op_ia32_fcompJmp;
1339                                         pop_cnt = 1;
1340                                 }
1341                                 /* different, move them to st and st(1) and pop both.
1342                                    The tricky part is to get one into st(1).*/
1343                                 else if (op2_idx == 1) {
1344                                         /* good, second operand is already in the right place, move the first */
1345                                         if (op1_idx != 0) {
1346                                                 /* bring the first on top */
1347                                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1348                                                 op1_idx = 0;
1349                                         }
1350                                         dst     = op_ia32_fcomppJmp;
1351                                         pop_cnt = 2;
1352                                 }
1353                                 else if (op1_idx == 1) {
1354                                         /* good, first operand is already in the right place, move the second */
1355                                         if (op2_idx != 0) {
1356                                                 /* bring the first on top */
1357                                                 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1358                                                 op2_idx = 0;
1359                                         }
1360                                         dst     = op_ia32_fcomrppJmp;
1361                                         pop_cnt = 2;
1362                                 }
1363                                 else {
1364                                         /* if one is already the TOS, we need two fxch */
1365                                         if (op1_idx == 0) {
1366                                                 /* first one is TOS, move to st(1) */
1367                                                 x87_create_fxch(state, n, 1, BINOP_IDX_1);
1368                                                 op1_idx = 1;
1369                                                 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1370                                                 op2_idx = 0;
1371                                                 dst     = op_ia32_fcomrppJmp;
1372                                                 pop_cnt = 2;
1373                                         }
1374                                         else if (op2_idx == 0) {
1375                                                 /* second one is TOS, move to st(1) */
1376                                                 x87_create_fxch(state, n, 1, BINOP_IDX_2);
1377                                                 op2_idx = 1;
1378                                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1379                                                 op1_idx = 0;
1380                                                 dst     = op_ia32_fcomrppJmp;
1381                                                 pop_cnt = 2;
1382                                         }
1383                                         else {
1384                                                 /* none of them is either TOS or st(1), 3 fxch needed */
1385                                                 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1386                                                 x87_create_fxch(state, n, 1, BINOP_IDX_2);
1387                                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1388                                                 op1_idx = 0;
1389                                                 op2_idx = 1;
1390                                                 dst     = op_ia32_fcomppJmp;
1391                                                 pop_cnt = 2;
1392                                         }
1393                                 }
1394                         }
1395                 }
1396         }
1397         else {
1398                 /* second operand is an address mode */
1399                 if (is_vfp_live(op1->index, live)) {
1400                         /* first operand is live: bring it to TOS */
1401                         if (op1_idx != 0) {
1402                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1403                                 op1_idx = 0;
1404                         }
1405                         dst = op_ia32_fcomJmp;
1406                 }
1407                 else {
1408                         /* first operand is dead: bring it to tos */
1409                         if (op1_idx != 0) {
1410                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1411                                 op1_idx = 0;
1412                         }
1413                 }
1414                 dst     = op_ia32_fcompJmp;
1415                 pop_cnt = 1;
1416         }
1417
1418         x87_patch_insn(n, dst);
1419         if (pop_cnt > 1)
1420                 x87_pop(state);
1421         if (pop_cnt > 0)
1422                 x87_pop(state);
1423
1424         /* patch the operation */
1425         attr = get_ia32_attr(n);
1426         attr->x87[1] = op1 = &ia32_st_regs[op1_idx];
1427         if (op2_idx >= 0)
1428                 attr->x87[2] = op2 = &ia32_st_regs[op2_idx];
1429
1430         if (op2_idx >= 0)
1431                 DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(n),
1432                         arch_register_get_name(op1), arch_register_get_name(op2)));
1433         else
1434                 DB((dbg, LEVEL_1, "<<< %s %s, [AM]\n", get_irn_opname(n),
1435                         arch_register_get_name(op1)));
1436
1437         return 0;
1438 }  /* sim_fCondJmp */
1439
1440 /**
1441  * Simulate a be_Copy.
1442  *
1443  * @param state  the x87 state
1444  * @param n      the node that should be simulated (and patched)
1445  * @param env    the architecture environment
1446  */
1447 static int sim_Copy(x87_state *state, ir_node *n, const arch_env_t *env) {
1448         ir_mode *mode = get_irn_mode(n);
1449
1450         if (mode_is_float(mode)) {
1451                 const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, 0));
1452                 const arch_register_t *out = arch_get_irn_register(env, n);
1453                 ir_node *node, *next;
1454                 ia32_attr_t *attr;
1455                 int op1_idx, out_idx;
1456                 unsigned live = vfp_live_args_after(state->sim, n, REGMASK(out));
1457
1458                 /* handle the infamous unknown value */
1459                 if (op1->index == REG_VFP_UKNWN) {
1460                         /* This happens before Phi nodes */
1461                         if (x87_state_is_empty(state)) {
1462                                 /* create some value */
1463                                 x87_patch_insn(n, op_ia32_fldz);
1464                                 attr = get_ia32_attr(n);
1465                                 attr->x87[2] = out = &ia32_st_regs[0];
1466                                 DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, out->name));
1467                         } else {
1468                                 /* just copy one */
1469                                 node = new_rd_ia32_fpush(get_irn_dbg_info(n), get_irn_irg(n), get_nodes_block(n), get_irn_n(n, 0), mode);
1470                                 arch_set_irn_register(env, node, out);
1471
1472                                 x87_push(state, arch_register_get_index(out), node);
1473
1474                                 attr = get_ia32_attr(node);
1475                                 attr->x87[0] = op1 =
1476                                 attr->x87[2] = out = &ia32_st_regs[0];
1477
1478                                 next = sched_next(n);
1479                                 sched_remove(n);
1480                                 exchange(n, node);
1481                                 sched_add_before(next, node);
1482                                 DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", node, op1->name, out->name));
1483                         }
1484                         return 0;
1485                 }
1486
1487                 op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1488
1489                 DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", n,
1490                         arch_register_get_name(op1), arch_register_get_name(out)));
1491                 DEBUG_ONLY(vfp_dump_live(live));
1492
1493                 if (is_vfp_live(op1->index, live)) {
1494                         /* operand is still live,a real copy */
1495                         node = new_rd_ia32_fpush(get_irn_dbg_info(n), get_irn_irg(n), get_nodes_block(n), get_irn_n(n, 0), mode);
1496                         arch_set_irn_register(env, node, out);
1497
1498                         x87_push(state, arch_register_get_index(out), node);
1499
1500                         attr = get_ia32_attr(node);
1501                         attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
1502                         attr->x87[2] = out = &ia32_st_regs[0];
1503
1504                         next = sched_next(n);
1505                         sched_remove(n);
1506                         exchange(n, node);
1507                         sched_add_before(next, node);
1508                         DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", node, op1->name, out->name));
1509                 }
1510                 else {
1511                         out_idx = x87_on_stack(state, arch_register_get_index(out));
1512
1513                         if (out_idx >= 0 && out_idx != op1_idx) {
1514                                 /* op1 must be killed and placed where out is */
1515                                 if (out_idx == 0) {
1516                                         /* best case, simple remove and rename */
1517                                         x87_patch_insn(n, op_ia32_Pop);
1518                                         attr = get_ia32_attr(n);
1519                                         attr->x87[0] = op1 = &ia32_st_regs[0];
1520
1521                                         x87_pop(state);
1522                                         x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
1523                                 }
1524                                 else {
1525                                         /* move op1 to tos, store and pop it */
1526                                         if (op1_idx != 0) {
1527                                                 x87_create_fxch(state, n, op1_idx, 0);
1528                                                 op1_idx = 0;
1529                                         }
1530                                         x87_patch_insn(n, op_ia32_Pop);
1531                                         attr = get_ia32_attr(n);
1532                                         attr->x87[0] = op1 = &ia32_st_regs[out_idx];
1533
1534                                         x87_pop(state);
1535                                         x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
1536                                 }
1537                                 DB((dbg, LEVEL_1, ">>> %+F %s\n", n, op1->name));
1538                         }
1539                         else {
1540                                 /* just a virtual copy */
1541                                 x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
1542                                 sched_remove(n);
1543                                 DB((dbg, LEVEL_1, ">>> KILLED %s\n", get_irn_opname(n)));
1544                                 exchange(n, get_unop_op(n));
1545                         }
1546                 }
1547         }
1548
1549         return 0;
1550 }  /* sim_Copy */
1551
1552 /**
1553  * Simulate a be_Call.
1554  *
1555  * @param state  the x87 state
1556  * @param n      the node that should be simulated
1557  * @param env    the architecture environment
1558  */
1559 static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *env) {
1560         ir_type *call_tp = be_Call_get_type(n);
1561
1562         /* at the begin of a call the x87 state should be empty */
1563         assert(state->depth == 0 && "stack not empty before call");
1564
1565         /*
1566          * If the called function returns a float, it is returned in st(0).
1567          * This even happens if the return value is NOT used.
1568          * Moreover, only one return result is supported.
1569          */
1570         if (get_method_n_ress(call_tp) > 0) {
1571                 ir_type *res_type = get_method_res_type(call_tp, 0);
1572                 ir_mode *mode     = get_type_mode(res_type);
1573
1574                 if (mode && mode_is_float(mode)) {
1575                         /*
1576                          * TODO: what to push here? The result might be unused and currently
1577                          * we have no possibility to detect this :-(
1578                          */
1579                         x87_push(state, 0, n);
1580                 }
1581         }
1582
1583         return 0;
1584 }  /* sim_Call */
1585
1586 /**
1587  * Simulate a be_Spill.
1588  *
1589  * @param state  the x87 state
1590  * @param n      the node that should be simulated (and patched)
1591  * @param env    the architecture environment
1592  *
1593  * Should not happen, spills are lowered before x87 simulator see them.
1594  */
1595 static int sim_Spill(x87_state *state, ir_node *n, const arch_env_t *env) {
1596         assert(0 && "Spill not lowered");
1597         return sim_fst(state, n, env);
1598 }  /* sim_Spill */
1599
1600 /**
1601  * Simulate a be_Reload.
1602  *
1603  * @param state  the x87 state
1604  * @param n      the node that should be simulated (and patched)
1605  * @param env    the architecture environment
1606  *
1607  * Should not happen, reloads are lowered before x87 simulator see them.
1608  */
1609 static int sim_Reload(x87_state *state, ir_node *n, const arch_env_t *env) {
1610         assert(0 && "Reload not lowered");
1611         return sim_fld(state, n, env);
1612 }  /* sim_Reload */
1613
1614 /**
1615  * Simulate a be_Return.
1616  *
1617  * @param state  the x87 state
1618  * @param n      the node that should be simulated (and patched)
1619  * @param env    the architecture environment
1620  */
1621 static int sim_Return(x87_state *state, ir_node *n, const arch_env_t *env) {
1622         int n_res = be_Return_get_n_rets(n);
1623         int i, n_float_res = 0;
1624
1625         /* only floating point return values must resist on stack */
1626         for (i = 0; i < n_res; ++i) {
1627                 ir_node *res = get_irn_n(n, be_pos_Return_val + i);
1628
1629                 if (mode_is_float(get_irn_mode(res)))
1630                         ++n_float_res;
1631         }
1632         assert(x87_get_depth(state) == n_float_res);
1633
1634         /* pop them virtually */
1635         for (i = n_float_res - 1; i >= 0; --i)
1636                 x87_pop(state);
1637
1638         return 0;
1639 }  /* sim_Return */
1640
1641 typedef struct _perm_data_t {
1642         const arch_register_t *in;
1643         const arch_register_t *out;
1644 } perm_data_t;
1645
1646 /**
1647  * Simulate a be_Perm.
1648  *
1649  * @param state  the x87 state
1650  * @param irn    the node that should be simulated (and patched)
1651  * @param env    the architecture environment
1652  */
1653 static int sim_Perm(x87_state *state, ir_node *irn, const arch_env_t *env) {
1654         int             i, n;
1655         ir_node         *pred = get_irn_n(irn, 0);
1656         int             *stack_pos;
1657         const ir_edge_t *edge;
1658
1659         /* handle only floating point Perms */
1660         if (! mode_is_float(get_irn_mode(pred)))
1661                 return 0;
1662
1663         DB((dbg, LEVEL_1, ">>> %+F\n", irn));
1664
1665         /* Perm is a pure virtual instruction on x87.
1666            All inputs must be on the FPU stack and are pairwise
1667            different from each other.
1668            So, all we need to do is to permutate the stack state. */
1669         n = get_irn_arity(irn);
1670         NEW_ARR_A(int, stack_pos, n);
1671
1672         /* collect old stack positions */
1673         for (i = 0; i < n; ++i) {
1674                 const arch_register_t *inreg = arch_get_irn_register(env, get_irn_n(irn, i));
1675                 int idx = x87_on_stack(state, inreg->index);
1676
1677                 assert(idx >= 0 && "Perm argument not on x87 stack");
1678
1679                 stack_pos[i] = idx;
1680         }
1681         /* now do the permutation */
1682         foreach_out_edge(irn, edge) {
1683                 ir_node               *proj = get_edge_src_irn(edge);
1684                 const arch_register_t *out  = arch_get_irn_register(env, proj);
1685                 long                  num   = get_Proj_proj(proj);
1686
1687                 assert(0 <= num && num < n && "More Proj's than Perm inputs");
1688                 x87_set_st(state, out->index, proj, stack_pos[(unsigned)num]);
1689         }
1690         DB((dbg, LEVEL_1, "<<< %+F\n", irn));
1691
1692         return 0;
1693 }  /* be_Perm */
1694
1695 /**
1696  * Kill any dead registers at block start by popping them from the stack.
1697  *
1698  * @param sim          the simulator handle
1699  * @param block        the current block
1700  * @param start_state  the x87 state at the begin of the block
1701  */
1702 static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *start_state) {
1703         x87_state *state = start_state;
1704         ir_node *first_insn = sched_first(block);
1705         ir_node *keep = NULL;
1706         unsigned live = vfp_live_args_after(sim, block, 0);
1707         unsigned kill_mask;
1708         int i, depth, num_pop;
1709
1710         kill_mask = 0;
1711         depth = x87_get_depth(state);
1712         for (i = depth - 1; i >= 0; --i) {
1713                 int reg = x87_get_st_reg(state, i);
1714
1715                 if (! is_vfp_live(reg, live))
1716                         kill_mask |= (1 << i);
1717         }
1718
1719         if (kill_mask) {
1720                 /* create a new state, will be changed */
1721                 state = x87_clone_state(sim, state);
1722
1723                 DB((dbg, LEVEL_1, "Killing deads:\n"));
1724                 DEBUG_ONLY(vfp_dump_live(live));
1725                 DEBUG_ONLY(x87_dump_stack(state));
1726
1727                 /* now kill registers */
1728                 while (kill_mask) {
1729                         /* we can only kill from TOS, so bring them up */
1730                         if (! (kill_mask & 1)) {
1731                                 /* search from behind, because we can to a double-pop */
1732                                 for (i = depth - 1; i >= 0; --i) {
1733                                         if (kill_mask & (1 << i)) {
1734                                                 kill_mask &= ~(1 << i);
1735                                                 kill_mask |= 1;
1736                                                 break;
1737                                         }
1738                                 }
1739
1740                                 if (keep)
1741                                         x87_set_st(state, -1, keep, i);
1742                                 keep = x87_create_fxch(state, first_insn, i, -1);
1743                         }
1744                         else if (! keep)
1745                                 keep = x87_get_st_node(state, 0);
1746
1747                         if ((kill_mask & 3) == 3) {
1748                                 /* we can do a double-pop */
1749                                 num_pop = 2;
1750                         }
1751                         else {
1752                                 /* only a single pop */
1753                                 num_pop = 1;
1754                         }
1755
1756                         depth -= num_pop;
1757                         kill_mask >>= num_pop;
1758                         keep = x87_create_fpop(sim->env, state, first_insn, num_pop, keep);
1759                 }
1760                 add_End_keepalive(get_irg_end(get_irn_irg(block)), keep);
1761         }
1762         return state;
1763 }  /* x87_kill_deads */
1764
1765 /**
1766  * Run a simulation and fix all virtual instructions for a block.
1767  *
1768  * @param sim          the simulator handle
1769  * @param block        the current block
1770  *
1771  * @return non-zero if simulation is complete,
1772  *         zero if the simulation must be rerun
1773  */
1774 static int x87_simulate_block(x87_simulator *sim, ir_node *block) {
1775         ir_node *n, *next;
1776         blk_state *bl_state = x87_get_bl_state(sim, block);
1777         x87_state *state = bl_state->begin;
1778         const ir_edge_t *edge;
1779         ir_node *start_block;
1780
1781         /* if we have no assigned start state, we must wait ... */
1782         if (! state)
1783                 return 0;
1784
1785         assert(bl_state->end == NULL);
1786
1787         DB((dbg, LEVEL_1, "Simulate %+F\n", block));
1788         DB((dbg, LEVEL_2, "State at Block begin:\n ")); DEBUG_ONLY(x87_dump_stack(state));
1789
1790         /* at block begin, kill all dead registers */
1791         state = x87_kill_deads(sim, block, state);
1792
1793         /* beware, n might changed */
1794         for (n = sched_first(block); !sched_is_end(n); n = next) {
1795                 ir_op *op = get_irn_op(n);
1796
1797                 next = sched_next(n);
1798                 if (op->ops.generic) {
1799                         int node_inserted;
1800                         sim_func func = (sim_func)op->ops.generic;
1801
1802                         /* have work to do */
1803                         if (state == bl_state->begin) {
1804                                 /* create a new state, will be changed */
1805                                 state = x87_clone_state(sim, state);
1806                         }
1807
1808                         /* simulate it */
1809                         node_inserted = (*func)(state, n, sim->env);
1810
1811                         /*
1812                                 sim_func might have added additional nodes after n,
1813                                 so update next node
1814                                 beware: n must not be changed by sim_func
1815                                 (i.e. removed from schedule) in this case
1816                         */
1817                         if (node_inserted)
1818                                 next = sched_next(n);
1819                 }
1820         }
1821
1822         start_block = get_irg_start_block(get_irn_irg(block));
1823
1824         /* check if the state must be shuffled */
1825         foreach_block_succ(block, edge) {
1826                 ir_node *succ = get_edge_src_irn(edge);
1827                 blk_state *succ_state = x87_get_bl_state(sim, succ);
1828
1829                 if (succ_state->begin && succ != start_block) {
1830                         /* There is already a begin state for this block, bad.
1831                            Do the necessary permutations.
1832                            Note that critical edges are removed, so this is always possible. */
1833                         x87_shuffle(sim, block, state, succ, succ_state->begin);
1834
1835                         /* Note further, that there can be only one such situation,
1836                            so we can break here. */
1837                         break;
1838                 }
1839         }
1840         bl_state->end = state;
1841
1842         /* now propagate the state to all successor blocks */
1843         foreach_block_succ(block, edge) {
1844                 ir_node *succ = get_edge_src_irn(edge);
1845                 blk_state *succ_state = x87_get_bl_state(sim, succ);
1846
1847                 if (! succ_state->begin)
1848                         succ_state->begin = state;
1849         }
1850
1851         DB((dbg, LEVEL_2, "State at Block end:\n ")); DEBUG_ONLY(x87_dump_stack(state));
1852
1853         return 1;
1854 }  /* x87_simulate_block */
1855
1856 /**
1857  * Create a new x87 simulator.
1858  *
1859  * @param sim   a simulator handle, will be initialized
1860  * @param irg   the current graph
1861  * @param env   the architecture environment
1862  */
1863 static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, const arch_env_t *env)
1864 {
1865         obstack_init(&sim->obst);
1866         sim->blk_states = pmap_create();
1867         sim->env        = env;
1868         sim->n_idx      = get_irg_last_idx(irg);
1869         sim->live       = obstack_alloc(&sim->obst, sizeof(*sim->live) * sim->n_idx);
1870
1871         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.x87");
1872
1873         DB((dbg, LEVEL_1, "--------------------------------\n"
1874                 "x87 Simulator started for %+F\n", irg));
1875
1876   /* set the generic function pointer of instruction we must simulate */
1877         clear_irp_opcodes_generic_func();
1878
1879 #define ASSOC(op)       (op_ ## op)->ops.generic = (op_func)(sim_##op)
1880 #define ASSOC_IA32(op)  (op_ia32_v ## op)->ops.generic = (op_func)(sim_##op)
1881 #define ASSOC_BE(op)    (op_be_ ## op)->ops.generic = (op_func)(sim_##op)
1882         ASSOC_IA32(fConst);
1883         ASSOC_IA32(fld);
1884         ASSOC_IA32(fild);
1885         ASSOC_IA32(fld1);
1886         ASSOC_IA32(fldz);
1887         ASSOC_IA32(fadd);
1888         ASSOC_IA32(fsub);
1889         ASSOC_IA32(fmul);
1890         ASSOC_IA32(fdiv);
1891         ASSOC_IA32(fldz);
1892         ASSOC_IA32(fabs);
1893         ASSOC_IA32(fchs);
1894         ASSOC_IA32(fsin);
1895         ASSOC_IA32(fcos);
1896         ASSOC_IA32(fsqrt);
1897         ASSOC_IA32(fist);
1898         ASSOC_IA32(fst);
1899         ASSOC_IA32(fCondJmp);
1900         ASSOC_BE(Copy);
1901         ASSOC_BE(Call);
1902         ASSOC_BE(Spill);
1903         ASSOC_BE(Reload);
1904         ASSOC_BE(Return);
1905         ASSOC_BE(Perm);
1906         ASSOC(Phi);
1907 #undef ASSOC_BE
1908 #undef ASSOC_IA32
1909 #undef ASSOC
1910 }  /* x87_init_simulator */
1911
1912 /**
1913  * Destroy a x87 simulator.
1914  *
1915  * @param sim  the simulator handle
1916  */
1917 static void x87_destroy_simulator(x87_simulator *sim) {
1918         pmap_destroy(sim->blk_states);
1919         obstack_free(&sim->obst, NULL);
1920         DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
1921 }  /* x87_destroy_simulator */
1922
1923 /**
1924  * Run a simulation and fix all virtual instructions for a graph.
1925  *
1926  * @param env       the architecture environment
1927  * @param irg       the current graph
1928  * @param blk_list  the block schedule list
1929  *
1930  * Needs a block-schedule.
1931  */
1932 void x87_simulate_graph(const arch_env_t *env, ir_graph *irg, ir_node **blk_list) {
1933         ir_node *block, *start_block;
1934         waitq *worklist;
1935         blk_state *bl_state;
1936         x87_simulator sim;
1937         int i, n;
1938         be_lv_t *lv;
1939
1940         /* create the simulator */
1941         x87_init_simulator(&sim, irg, env);
1942
1943         start_block = get_irg_start_block(irg);
1944         bl_state = x87_get_bl_state(&sim, start_block);
1945
1946         /* start with the empty state */
1947         bl_state->begin = empty;
1948         empty->sim      = &sim;
1949
1950         worklist = new_waitq();
1951
1952         /* Create the worklist for the schedule and calculate the liveness
1953            for all nodes. We must precalculate this info, because the
1954            simulator adds new nodes (and possible before Phi nodes) which
1955            let fail the old lazy calculation.
1956            On the other hand we reduce the computation amount due to
1957            precaching from O(n^2) to O(n) at the expense of O(n) cache memory.
1958          */
1959         lv = be_liveness(irg);
1960         for (i = 0, n = ARR_LEN(blk_list); i < n; ++i) {
1961                 update_liveness(&sim, lv, blk_list[i]);
1962                 waitq_put(worklist, blk_list[i]);
1963         }
1964         be_liveness_free(lv);
1965
1966         /* iterate */
1967         do {
1968                 block = waitq_get(worklist);
1969                 if (! x87_simulate_block(&sim, block)) {
1970                         waitq_put(worklist, block);
1971                         continue;
1972                 }
1973         } while (! pdeq_empty(worklist));
1974
1975         /* kill it */
1976         del_waitq(worklist);
1977         x87_destroy_simulator(&sim);
1978 }  /* x87_simulate_graph */