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