Adapted to new liveness
[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 const 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         const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
755         ir_node *irn;
756         unsigned live;
757
758         live = vfp_liveness_end_of_block(sim, bl);
759
760         sched_foreach_reverse(bl, irn) {
761                 /*
762                  * If we encounter the node we want to insert the Perm after,
763                  * exit immediately, so that this node is still live
764                  */
765                 if (irn == pos)
766                         return live;
767
768                 live = vfp_liveness_transfer(sim->env, irn, live);
769         }
770
771         return live;
772 }
773
774 /**
775  * Returns true if a register is live in a set.
776  *
777  * @param reg_idx  the vfp register index
778  * @param live     a live bitset
779  */
780 static unsigned is_vfp_live(int reg_idx, unsigned live) {
781         return live & (1 << reg_idx);
782 }
783
784 #ifdef DEBUG_libfirm
785 /**
786  * Dump liveness info.
787  *
788  * @param live  the live bitset
789  */
790 static void vfp_dump_live(unsigned live) {
791         int i;
792
793         DB((dbg, LEVEL_2, "Live registers here: \n"));
794         for (i = 0; i < 8; ++i) {
795                 if (live & (1 << i)) {
796                         DB((dbg, LEVEL_2, " vf%d", i));
797                 }
798         }
799         DB((dbg, LEVEL_2, "\n"));
800 }
801 #endif /* DEBUG_libfirm */
802
803 /* --------------------------------- simulators ---------------------------------------- */
804
805 #define XCHG(a, b) do { int t = (a); (a) = (b); (b) = t; } while (0)
806
807 /**
808  * Simulate a virtual binop.
809  *
810  * @param state  the x87 state
811  * @param n      the node that should be simulated (and patched)
812  * @param env    the architecture environment
813  * @param tmpl   the template containing the 4 possible x87 opcodes
814  */
815 static int sim_binop(x87_state *state, ir_node *n, const arch_env_t *env, const exchange_tmpl *tmpl) {
816         int op2_idx, op1_idx = -1;
817         int out_idx, do_pop =0;
818         ia32_attr_t *attr;
819         ir_op *dst;
820         const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_1));
821         const arch_register_t *op2 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_2));
822         const arch_register_t *out = arch_get_irn_register(env, n);
823         unsigned live = vfp_liveness_nodes_live_at(state->sim, n);
824
825         DB((dbg, LEVEL_1, ">>> %s %s, %s -> %s\n", get_irn_opname(n),
826                 arch_register_get_name(op1), arch_register_get_name(op2),
827                 arch_register_get_name(out)));
828         DEBUG_ONLY(vfp_dump_live(live));
829
830         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
831         op2_idx = x87_on_stack(state, arch_register_get_index(op2));
832
833         if (op2->index != REG_VFP_NOREG) {
834                 /* second operand is a vfp register */
835
836                 if (is_vfp_live(op2->index, live)) {
837                         /* Second operand is live. */
838
839                         if (is_vfp_live(op1->index, live)) {
840                                 /* Both operands are live: push the first one.
841                                    This works even for op1 == op2. */
842                                 x87_create_fpush(env, state, n, op2_idx, BINOP_IDX_2, 0);
843                                 out_idx = op2_idx = 0;
844                                 ++op1_idx;
845                                 dst = tmpl->normal_op;
846                                 do_pop = 0;
847                         }
848                         else {
849                                 /* Second live, first operand is dead here, bring it to tos. */
850                                 if (op1_idx != 0) {
851                                         x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
852                                         if (op2_idx == 0)
853                                                 op2_idx = op1_idx;
854                                 }
855                                 op1_idx = out_idx = 0;
856                                 dst = tmpl->normal_op;
857                                 do_pop = 0;
858                         }
859                 }
860                 else {
861                         /* Second operand is dead. */
862                         if (is_vfp_live(op1->index, live)) {
863                                 /* First operand is live: bring second to tos. */
864                                 if (op2_idx != 0) {
865                                         x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
866                                         if (op1_idx == 0)
867                                                 op1_idx = op2_idx;
868                                 }
869                                 op2_idx = out_idx = 0;
870                                 dst = tmpl->normal_op;
871                                 do_pop = 0;
872                         }
873                         else {
874                                 /* Both operands are dead here, pop them from the stack. */
875                                 if (op2_idx == 0) {
876                                         out_idx = op1_idx;
877                                         XCHG(op2_idx, op1_idx);
878                                         if (op1_idx == op2_idx) {
879                                                 /* Both are identically, no pop needed. */
880                                                 dst = tmpl->reverse_op;
881                                                 do_pop = 0;
882                                         }
883                                         else {
884                                                 dst = tmpl->reverse_pop_op;
885                                                 do_pop = 1;
886                                         }
887                                 }
888                                 else if (op1_idx == 0) {
889                                         out_idx = op2_idx;
890                                         if (op1_idx == op2_idx) {
891                                                 /* Both are identically, no pop needed. */
892                                                 dst = tmpl->normal_op;
893                                                 do_pop = 0;
894                                         }
895                                         else {
896                                                 dst = tmpl->normal_pop_op;
897                                                 do_pop = 1;
898                                         }
899                                 }
900                                 else {
901                                         /* Bring the first on top. */
902                                         x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
903                                         if (op1_idx == op2_idx) {
904                                                 /* Both are identically, no pop needed. */
905                                                 out_idx = op1_idx = op2_idx = 0;
906                                                 dst = tmpl->normal_op;
907                                                 do_pop = 0;
908                                         }
909                                         else {
910                                                 op1_idx = 0;
911                                                 out_idx = op2_idx;
912                                                 dst = tmpl->normal_pop_op;
913                                                 do_pop = 1;
914                                         }
915                                 }
916                         }
917                 }
918         }
919         else {
920                 /* second operand is an address mode */
921                 if (is_vfp_live(op1->index, live)) {
922                         /* first operand is live: push it here */
923                         x87_create_fpush(env, state, n, op1_idx, BINOP_IDX_1, 0);
924                 }
925                 else {
926                         /* first operand is dead: bring it to tos */
927                         if (op1_idx != 0)
928                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
929                 }
930                 op1_idx = out_idx = 0;
931                 dst = tmpl->normal_op;
932                 do_pop = 0;
933         }
934
935         x87_set_st(state, arch_register_get_index(out), x87_patch_insn(n, dst), out_idx);
936         if (do_pop)
937                 x87_pop(state);
938
939         /* patch the operation */
940         attr = get_ia32_attr(n);
941         attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
942         if (op2_idx >= 0)
943                 attr->x87[1] = op2 = &ia32_st_regs[op2_idx];
944         attr->x87[2] = out = &ia32_st_regs[out_idx];
945
946         if (op2_idx > 0)
947                 DB((dbg, LEVEL_1, "<<< %s %s, %s -> %s\n", get_irn_opname(n),
948                         arch_register_get_name(op1), arch_register_get_name(op2),
949                         arch_register_get_name(out)));
950         else
951                 DB((dbg, LEVEL_1, "<<< %s %s, [AM] -> %s\n", get_irn_opname(n),
952                         arch_register_get_name(op1),
953                         arch_register_get_name(out)));
954
955         return 0;
956 }
957
958 /**
959  * Simulate a virtual Unop.
960  *
961  * @param state  the x87 state
962  * @param n      the node that should be simulated (and patched)
963  * @param env    the architecture environment
964  * @param op     the x87 opcode that will replace n's opcode
965  */
966 static int sim_unop(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op) {
967         int op1_idx, out_idx;
968         const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, UNOP_IDX));
969         const arch_register_t *out = arch_get_irn_register(env, n);
970         ia32_attr_t *attr;
971         unsigned live = vfp_liveness_nodes_live_at(state->sim, n);
972
973         DB((dbg, LEVEL_1, ">>> %s -> %s\n", get_irn_opname(n), out->name));
974         DEBUG_ONLY(vfp_dump_live(live));
975
976         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
977
978         if (is_vfp_live(op1->index, live)) {
979                 /* push the operand here */
980                 x87_create_fpush(env, state, n, op1_idx, UNOP_IDX, 0);
981         }
982         else {
983                 /* operand is dead, bring it to tos */
984                 if (op1_idx != 0)
985                         x87_create_fxch(state, n, op1_idx, UNOP_IDX);
986         }
987
988         x87_set_tos(state, arch_register_get_index(out), x87_patch_insn(n, op));
989         op1_idx = out_idx = 0;
990         attr = get_ia32_attr(n);
991         attr->x87[0] = op1 = &ia32_st_regs[0];
992         attr->x87[2] = out = &ia32_st_regs[0];
993         DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), out->name));
994
995         return 0;
996 }
997
998 /**
999  * Simulate a virtual Load instruction.
1000  *
1001  * @param state  the x87 state
1002  * @param n      the node that should be simulated (and patched)
1003  * @param env    the architecture environment
1004  * @param op     the x87 opcode that will replace n's opcode
1005  */
1006 static int sim_load(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op) {
1007         const arch_register_t *out = arch_get_irn_register(env, n);
1008         ia32_attr_t *attr;
1009
1010         DB((dbg, LEVEL_1, ">>> %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
1011         x87_push(state, arch_register_get_index(out), x87_patch_insn(n, op), 0);
1012         attr = get_ia32_attr(n);
1013         attr->x87[2] = out = &ia32_st_regs[0];
1014         DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
1015
1016         return 0;
1017 }
1018
1019 /**
1020  * Rewire all users of @p old_val to @new_val iff they are scheduled after @p store.
1021  *
1022  * @param store   The store
1023  * @param old_val The former value
1024  * @param new_val The new value
1025  */
1026 static void collect_and_rewire_users(ir_node *store, ir_node *old_val, ir_node *new_val) {
1027         const ir_edge_t *edge, *ne;
1028
1029         foreach_out_edge_safe(old_val, edge, ne) {
1030                 ir_node *user = get_edge_src_irn(edge);
1031
1032                 if (! user || user == store)
1033                         continue;
1034
1035                 /* if the user is scheduled after the store: rewire */
1036                 if (sched_is_scheduled(user) && sched_comes_after(store, user)) {
1037                         int i;
1038                         /* find the input of the user pointing to the old value */
1039                         for (i = get_irn_arity(user) - 1; i >= 0; i--) {
1040                                 if (get_irn_n(user, i) == old_val)
1041                                         set_irn_n(user, i, new_val);
1042                         }
1043                 }
1044         }
1045 }
1046
1047 /**
1048  * Simulate a virtual Store.
1049  *
1050  * @param state  the x87 state
1051  * @param n      the node that should be simulated (and patched)
1052  * @param env    the architecture environment
1053  * @param op     the x87 store opcode
1054  * @param op_p   the x87 store and pop opcode
1055  */
1056 static int sim_store(x87_state *state, ir_node *n, const arch_env_t *env, ir_op *op, ir_op *op_p) {
1057         ir_node               *val = get_irn_n(n, STORE_VAL_IDX);
1058         const arch_register_t *op2 = arch_get_irn_register(env, val);
1059         unsigned              live = vfp_liveness_nodes_live_at(state->sim, n);
1060         int                   insn = 0;
1061         ia32_attr_t *attr;
1062         int op2_idx, depth;
1063         ir_mode *mode;
1064
1065         op2_idx = x87_on_stack(state, arch_register_get_index(op2));
1066         assert(op2_idx >= 0);
1067
1068         DB((dbg, LEVEL_1, ">>> %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
1069
1070         mode  = get_ia32_ls_mode(n);
1071         depth = x87_get_depth(state);
1072
1073         /*
1074                 We can only store the tos to memory.
1075                 A store of mode_E with free registers
1076                 pushes value to tos, so skip it here.
1077         */
1078         if (! (mode == mode_E && depth < N_x87_REGS) && op2_idx != 0)
1079                 x87_create_fxch(state, n, op2_idx, STORE_VAL_IDX);
1080
1081         if (is_vfp_live(op2->index, live)) {
1082                 /*
1083                         Problem: fst doesn't support mode_E (spills), only fstp does
1084                         Solution:
1085                                 - stack not full: push value and fstp
1086                                 - stack full: fstp value and load again
1087                 */
1088                 if (mode == mode_E) {
1089                         if (depth < N_x87_REGS) {
1090                                 /* ok, we have a free register: push + fstp */
1091                                 x87_create_fpush(env, state, n, op2_idx, STORE_VAL_IDX, 1);
1092                                 x87_pop(state);
1093                                 x87_patch_insn(n, op_p);
1094                         }
1095                         else {
1096                                 ir_node  *vfld, *mem, *block, *rproj, *mproj;
1097                                 ir_graph *irg;
1098
1099                                 /* stack full here: need fstp + load */
1100                                 x87_pop(state);
1101                                 x87_patch_insn(n, op_p);
1102
1103                                 block = get_nodes_block(n);
1104                                 irg   = get_irn_irg(n);
1105                                 vfld  = new_rd_ia32_vfld(NULL, irg, block, get_irn_n(n, 0), get_irn_n(n, 1), new_rd_NoMem(irg));
1106
1107                                 /* copy all attributes */
1108                                 set_ia32_frame_ent(vfld, get_ia32_frame_ent(n));
1109                                 if (is_ia32_use_frame(n))
1110                                         set_ia32_use_frame(vfld);
1111                                 set_ia32_am_flavour(vfld, get_ia32_am_flavour(n));
1112                                 set_ia32_op_type(vfld, ia32_am_Source);
1113                                 add_ia32_am_offs(vfld, get_ia32_am_offs(n));
1114                                 set_ia32_am_sc(vfld, get_ia32_am_sc(n));
1115                                 set_ia32_ls_mode(vfld, get_ia32_ls_mode(n));
1116
1117                                 rproj = new_r_Proj(irg, block, vfld, get_ia32_ls_mode(vfld), pn_ia32_vfld_res);
1118                                 mproj = new_r_Proj(irg, block, vfld, mode_M, pn_ia32_vfld_M);
1119                                 mem   = get_irn_Proj_for_mode(n, mode_M);
1120
1121                                 assert(mem && "Store memory not found");
1122
1123                                 arch_set_irn_register(env, rproj, op2);
1124
1125                                 /* reroute all former users of the store memory to the load memory */
1126                                 edges_reroute(mem, mproj, irg);
1127                                 /* set the memory input of the load to the store memory */
1128                                 set_irn_n(vfld, 2, mem);
1129
1130                                 sched_add_after(n, vfld);
1131                                 sched_add_after(vfld, rproj);
1132
1133                                 /* rewire all users, scheduled after the store, to the loaded value */
1134                                 collect_and_rewire_users(n, val, rproj);
1135
1136                                 insn = 1;
1137                         }
1138                 }
1139                 else {
1140                         /* mode != mode_E -> use normal fst */
1141                         x87_patch_insn(n, op);
1142                 }
1143         }
1144         else {
1145                 x87_pop(state);
1146                 x87_patch_insn(n, op_p);
1147         }
1148
1149         attr = get_ia32_attr(n);
1150         attr->x87[1] = op2 = &ia32_st_regs[0];
1151         DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
1152
1153         return insn;
1154 }
1155
1156 /**
1157  * Simulate a virtual Phi.
1158  * Just for cosmetic reasons change the mode of Phi nodes to mode_E.
1159  *
1160  * @param state  the x87 state
1161  * @param n      the node that should be simulated (and patched)
1162  * @param env    the architecture environment
1163  */
1164 static int sim_Phi(x87_state *state, ir_node *n, const arch_env_t *env) {
1165         ir_mode *mode = get_irn_mode(n);
1166
1167         if (mode_is_float(mode))
1168                 set_irn_mode(n, mode_E);
1169
1170         return 0;
1171 }
1172
1173
1174 #define _GEN_BINOP(op, rev) \
1175 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1176         exchange_tmpl tmpl = { op_ia32_##op, op_ia32_##rev, op_ia32_##op##p, op_ia32_##rev##p }; \
1177         return sim_binop(state, n, env, &tmpl); \
1178 }
1179
1180 #define GEN_BINOP(op)   _GEN_BINOP(op, op)
1181 #define GEN_BINOPR(op)  _GEN_BINOP(op, op##r)
1182
1183 #define GEN_LOAD2(op, nop) \
1184 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1185         return sim_load(state, n, env, op_ia32_##nop); \
1186 }
1187
1188 #define GEN_LOAD(op)    GEN_LOAD2(op, op)
1189
1190 #define GEN_UNOP(op) \
1191 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1192         return sim_unop(state, n, env, op_ia32_##op); \
1193 }
1194
1195 #define GEN_STORE(op) \
1196 static int sim_##op(x87_state *state, ir_node *n, const arch_env_t *env) { \
1197         return sim_store(state, n, env, op_ia32_##op, op_ia32_##op##p); \
1198 }
1199
1200 /* all stubs */
1201 GEN_BINOP(fadd)
1202 GEN_BINOPR(fsub)
1203 GEN_BINOP(fmul)
1204 GEN_BINOPR(fdiv)
1205
1206 GEN_UNOP(fabs)
1207 GEN_UNOP(fchs)
1208 GEN_UNOP(fsin)
1209 GEN_UNOP(fcos)
1210 GEN_UNOP(fsqrt)
1211
1212 GEN_LOAD(fld)
1213 GEN_LOAD(fild)
1214 GEN_LOAD(fldz)
1215 GEN_LOAD(fld1)
1216 GEN_LOAD2(fConst, fldConst)
1217
1218 GEN_STORE(fst)
1219 GEN_STORE(fist)
1220
1221 /**
1222  * Simulate a fCondJmp.
1223  *
1224  * @param state  the x87 state
1225  * @param n      the node that should be simulated (and patched)
1226  * @param env    the architecture environment
1227  */
1228 static int sim_fCondJmp(x87_state *state, ir_node *n, const arch_env_t *env) {
1229         int op2_idx, op1_idx = -1, pop_cnt = 0;
1230         ia32_attr_t *attr;
1231         ir_op *dst;
1232         const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_1));
1233         const arch_register_t *op2 = arch_get_irn_register(env, get_irn_n(n, BINOP_IDX_2));
1234         unsigned live = vfp_liveness_nodes_live_at(state->sim, n);
1235
1236         DB((dbg, LEVEL_1, ">>> %s %s, %s\n", get_irn_opname(n),
1237                 arch_register_get_name(op1), arch_register_get_name(op2)));
1238         DEBUG_ONLY(vfp_dump_live(live));
1239
1240         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1241         op2_idx = x87_on_stack(state, arch_register_get_index(op2));
1242
1243         /* BEWARE: check for comp a,a cases, they might happen */
1244         if (op2->index != REG_VFP_NOREG) {
1245                 /* second operand is a vfp register */
1246
1247                 if (is_vfp_live(op2->index, live)) {
1248                         /* second operand is live */
1249
1250                         if (is_vfp_live(op1->index, live)) {
1251                                 /* both operands are live: move one of them to tos */
1252                                 if (op2_idx == 0) {
1253                                         XCHG(op2_idx, op1_idx);
1254                                         dst = op_ia32_fcomrJmp;
1255                                 }
1256                                 else if (op1_idx == 0) {
1257                                         dst = op_ia32_fcomJmp;
1258                                 }
1259                                 else {
1260                                         /* bring the first on top */
1261                                         x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1262                                         if (op1_idx == op2_idx)
1263                                                 op2_idx = 0;
1264                                         op1_idx = 0;
1265                                         dst     = op_ia32_fcomJmp;
1266                                 }
1267                         }
1268                         else {
1269                                 /* second live, first operand is dead here, bring it to tos.
1270                                    This means further, op1_idx != op2_idx. */
1271                                 if (op1_idx != 0) {
1272                                         x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1273                                         if (op2_idx == 0)
1274                                                 op2_idx = op1_idx;
1275                                 }
1276                                 op1_idx = 0;
1277                                 dst     = op_ia32_fcompJmp;
1278                                 pop_cnt = 1;
1279                         }
1280                 }
1281                 else {
1282                         /* second operand is dead */
1283                         if (is_vfp_live(op1->index, live)) {
1284                                 /* first operand is live: bring second to tos.
1285                                    This means further, op1_idx != op2_idx. */
1286                                 if (op2_idx != 0) {
1287                                         x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1288                                         if (op1_idx == 0)
1289                                                 op1_idx = op2_idx;
1290                                 }
1291                                 op2_idx = 0;
1292                                 dst     = op_ia32_fcomrpJmp;
1293                                 pop_cnt = 1;
1294                         }
1295                         else {
1296                                 /* both operands are dead here, check first for identity. */
1297                                 if (op1_idx == op2_idx) {
1298                                         /* identically, one one needed */
1299                                         if (op1_idx != 0) {
1300                                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1301                                                 op1_idx = op2_idx = 0;
1302                                         }
1303                                         dst     = op_ia32_fcompJmp;
1304                                         pop_cnt = 1;
1305                                 }
1306                                 /* different, move them to st and st(1) and pop both.
1307                                    The tricky part is to get one into st(1).*/
1308                                 else if (op2_idx == 1) {
1309                                         /* good, second operand is already in the right place, move the first */
1310                                         if (op1_idx != 0) {
1311                                                 /* bring the first on top */
1312                                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1313                                                 op1_idx = 0;
1314                                         }
1315                                         dst     = op_ia32_fcomppJmp;
1316                                         pop_cnt = 2;
1317                                 }
1318                                 else if (op1_idx == 1) {
1319                                         /* good, first operand is already in the right place, move the second */
1320                                         if (op2_idx != 0) {
1321                                                 /* bring the first on top */
1322                                                 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1323                                                 op2_idx = 0;
1324                                         }
1325                                         dst     = op_ia32_fcomrppJmp;
1326                                         pop_cnt = 2;
1327                                 }
1328                                 else {
1329                                         /* if one is already the TOS, we need two fxch */
1330                                         if (op1_idx == 0) {
1331                                                 /* first one is TOS, move to st(1) */
1332                                                 x87_create_fxch(state, n, 1, BINOP_IDX_1);
1333                                                 op1_idx = 1;
1334                                                 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1335                                                 op2_idx = 0;
1336                                                 dst     = op_ia32_fcomrppJmp;
1337                                                 pop_cnt = 2;
1338                                         }
1339                                         else if (op2_idx == 0) {
1340                                                 /* second one is TOS, move to st(1) */
1341                                                 x87_create_fxch(state, n, 1, BINOP_IDX_2);
1342                                                 op2_idx = 1;
1343                                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1344                                                 op1_idx = 0;
1345                                                 dst     = op_ia32_fcomrppJmp;
1346                                                 pop_cnt = 2;
1347                                         }
1348                                         else {
1349                                                 /* none of them is either TOS or st(1), 3 fxch needed */
1350                                                 x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
1351                                                 x87_create_fxch(state, n, 1, BINOP_IDX_2);
1352                                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1353                                                 op1_idx = 0;
1354                                                 op2_idx = 1;
1355                                                 dst     = op_ia32_fcomppJmp;
1356                                                 pop_cnt = 2;
1357                                         }
1358                                 }
1359                         }
1360                 }
1361         }
1362         else {
1363                 /* second operand is an address mode */
1364                 if (is_vfp_live(op1->index, live)) {
1365                         /* first operand is live: bring it to TOS */
1366                         if (op1_idx != 0) {
1367                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1368                                 op1_idx = 0;
1369                         }
1370                         dst = op_ia32_fcomJmp;
1371                 }
1372                 else {
1373                         /* first operand is dead: bring it to tos */
1374                         if (op1_idx != 0) {
1375                                 x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
1376                                 op1_idx = 0;
1377                         }
1378                 }
1379                 dst     = op_ia32_fcompJmp;
1380                 pop_cnt = 1;
1381         }
1382
1383         x87_patch_insn(n, dst);
1384         if (pop_cnt > 1)
1385                 x87_pop(state);
1386         if (pop_cnt > 0)
1387                 x87_pop(state);
1388
1389         /* patch the operation */
1390         attr = get_ia32_attr(n);
1391         attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
1392         if (op2_idx >= 0)
1393                 attr->x87[1] = op2 = &ia32_st_regs[op2_idx];
1394
1395         if (op2_idx >= 0)
1396                 DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(n),
1397                         arch_register_get_name(op1), arch_register_get_name(op2)));
1398         else
1399                 DB((dbg, LEVEL_1, "<<< %s %s, [AM]\n", get_irn_opname(n),
1400                         arch_register_get_name(op1)));
1401
1402         return 0;
1403 }
1404
1405 /**
1406  * Simulate a be_Copy.
1407  *
1408  * @param state  the x87 state
1409  * @param n      the node that should be simulated (and patched)
1410  * @param env    the architecture environment
1411  */
1412 static int sim_Copy(x87_state *state, ir_node *n, const arch_env_t *env) {
1413         ir_mode *mode = get_irn_mode(n);
1414
1415         if (mode_is_float(mode)) {
1416                 const arch_register_t *op1 = arch_get_irn_register(env, get_irn_n(n, 0));
1417                 const arch_register_t *out = arch_get_irn_register(env, n);
1418                 ir_node *node, *next;
1419                 ia32_attr_t *attr;
1420                 int op1_idx, out_idx;
1421                 unsigned live = vfp_liveness_nodes_live_at(state->sim, n);
1422
1423                 op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1424
1425                 DB((dbg, LEVEL_1, ">>> %s %s -> %s\n", get_irn_opname(n),
1426                         arch_register_get_name(op1), arch_register_get_name(out)));
1427                 DEBUG_ONLY(vfp_dump_live(live));
1428
1429                 if (is_vfp_live(op1->index, live)) {
1430                         /* operand is still live,a real copy */
1431                         node = new_rd_ia32_fpush(get_irn_dbg_info(n), get_irn_irg(n), get_nodes_block(n), get_irn_n(n, 0), mode);
1432                         arch_set_irn_register(env, node, out);
1433
1434                         x87_push(state, arch_register_get_index(out), node, 0);
1435
1436                         attr = get_ia32_attr(node);
1437                         attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
1438                         attr->x87[2] = out = &ia32_st_regs[0];
1439
1440                         next = sched_next(n);
1441                         sched_remove(n);
1442                         exchange(n, node);
1443                         sched_add_before(next, node);
1444                         DB((dbg, LEVEL_1, ">>> %s %s -> %s\n", get_irn_opname(node), op1->name, out->name));
1445                 }
1446                 else {
1447                         out_idx = x87_on_stack(state, arch_register_get_index(out));
1448
1449                         if (out_idx >= 0 && out_idx != op1_idx) {
1450                                 /* op1 must be killed and placed where out is */
1451                                 if (out_idx == 0) {
1452                                         /* best case, simple remove and rename */
1453                                         x87_patch_insn(n, op_ia32_Pop);
1454                                         attr = get_ia32_attr(n);
1455                                         attr->x87[0] = op1 = &ia32_st_regs[0];
1456
1457                                         x87_pop(state);
1458                                         x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
1459                                 }
1460                                 else {
1461                                         /* move op1 to tos, store and pop it */
1462                                         if (op1_idx != 0) {
1463                                                 x87_create_fxch(state, n, op1_idx, 0);
1464                                                 op1_idx = 0;
1465                                         }
1466                                         x87_patch_insn(n, op_ia32_Pop);
1467                                         attr = get_ia32_attr(n);
1468                                         attr->x87[0] = op1 = &ia32_st_regs[out_idx];
1469
1470                                         x87_pop(state);
1471                                         x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
1472                                 }
1473                                 DB((dbg, LEVEL_1, ">>> %s %s\n", get_irn_opname(n), op1->name));
1474                         }
1475                         else {
1476                                 /* just a virtual copy */
1477                                 x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
1478                                 sched_remove(n);
1479                                 DB((dbg, LEVEL_1, ">>> KILLED %s\n", get_irn_opname(n)));
1480                                 exchange(n, get_unop_op(n));
1481                         }
1482                 }
1483         }
1484
1485         return 0;
1486 }
1487
1488 /**
1489  * Simulate a be_Call.
1490  *
1491  * @param state  the x87 state
1492  * @param n      the node that should be simulated
1493  * @param env    the architecture environment
1494  */
1495 static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *env) {
1496         ir_type *call_tp = be_Call_get_type(n);
1497
1498         /* at the begin of a call the x87 state should be empty */
1499         assert(state->depth == 0 && "stack not empty before call");
1500
1501         /*
1502          * If the called function returns a float, it is returned in st(0).
1503          * This even happens if the return value is NOT used.
1504          * Moreover, only one return result is supported.
1505          */
1506         if (get_method_n_ress(call_tp) > 0) {
1507                 ir_type *res_type = get_method_res_type(call_tp, 0);
1508                 ir_mode *mode     = get_type_mode(res_type);
1509
1510                 if (mode && mode_is_float(mode)) {
1511                         /*
1512                          * TODO: what to push here? The result might be unused and currently
1513                          * we have no possibility to detect this :-(
1514                          */
1515                         x87_push(state, 0, n, 0);
1516                 }
1517         }
1518
1519         return 0;
1520 }
1521
1522 /**
1523  * Simulate a be_Spill.
1524  *
1525  * @param state  the x87 state
1526  * @param n      the node that should be simulated (and patched)
1527  * @param env    the architecture environment
1528  *
1529  * Should not happen, spills are lowered before x87 simulator see them.
1530  */
1531 static int sim_Spill(x87_state *state, ir_node *n, const arch_env_t *env) {
1532         assert(0 && "Spill not lowered");
1533         return sim_fst(state, n, env);
1534 }
1535
1536 /**
1537  * Simulate a be_Reload.
1538  *
1539  * @param state  the x87 state
1540  * @param n      the node that should be simulated (and patched)
1541  * @param env    the architecture environment
1542  *
1543  * Should not happen, reloads are lowered before x87 simulator see them.
1544  */
1545 static int sim_Reload(x87_state *state, ir_node *n, const arch_env_t *env) {
1546         assert(0 && "Reload not lowered");
1547         return sim_fld(state, n, env);
1548 }
1549
1550 /**
1551  * Simulate a be_Return.
1552  *
1553  * @param state  the x87 state
1554  * @param n      the node that should be simulated (and patched)
1555  * @param env    the architecture environment
1556  */
1557 static int sim_Return(x87_state *state, ir_node *n, const arch_env_t *env) {
1558         int n_res = be_Return_get_n_rets(n);
1559         int i, n_float_res = 0;
1560
1561         /* only floating point return values must resist on stack */
1562         for (i = 0; i < n_res; ++i) {
1563                 ir_node *res = get_irn_n(n, be_pos_Return_val + i);
1564
1565                 if (mode_is_float(get_irn_mode(res)))
1566                         ++n_float_res;
1567         }
1568         assert(x87_get_depth(state) == n_float_res);
1569
1570         /* pop them virtually */
1571         for (i = n_float_res - 1; i >= 0; --i)
1572                 x87_pop(state);
1573
1574         return 0;
1575 }
1576
1577 /**
1578  * Kill any dead registers at block start by popping them from the stack.
1579  *
1580  * @param sim          the simulator handle
1581  * @param block        the current block
1582  * @param start_state  the x87 state at the begin of the block
1583  */
1584 static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *start_state) {
1585         x87_state *state = start_state;
1586         ir_node *first_insn = sched_first(block);
1587         ir_node *keep = NULL;
1588         unsigned live = vfp_liveness_nodes_live_at(sim, block);
1589         unsigned kill_mask;
1590         int i, depth, num_pop;
1591
1592         kill_mask = 0;
1593         depth = x87_get_depth(state);
1594         for (i = depth - 1; i >= 0; --i) {
1595                 int reg = x87_get_st_reg(state, i);
1596
1597                 if (! is_vfp_live(reg, live))
1598                         kill_mask |= (1 << i);
1599         }
1600
1601         if (kill_mask) {
1602                 /* create a new state, will be changed */
1603                 state = x87_clone_state(sim, state);
1604
1605                 DB((dbg, LEVEL_1, "Killing deads:\n"));
1606                 DEBUG_ONLY(vfp_dump_live(live));
1607                 DEBUG_ONLY(x87_dump_stack(state));
1608
1609                 /* now kill registers */
1610                 while (kill_mask) {
1611                         /* we can only kill from TOS, so bring them up */
1612                         if (! (kill_mask & 1)) {
1613                                 /* search from behind, because we can to a double-pop */
1614                                 for (i = depth - 1; i >= 0; --i) {
1615                                         if (kill_mask & (1 << i)) {
1616                                                 kill_mask &= ~(1 << i);
1617                                                 kill_mask |= 1;
1618                                                 break;
1619                                         }
1620                                 }
1621
1622                                 if (keep)
1623                                         x87_set_st(state, -1, keep, i);
1624                                 keep = x87_create_fxch(state, first_insn, i, -1);
1625                         }
1626                         else if (! keep)
1627                                 keep = x87_get_st_node(state, 0);
1628
1629                         if ((kill_mask & 3) == 3) {
1630                                 /* we can do a double-pop */
1631                                 num_pop = 2;
1632                         }
1633                         else {
1634                                 /* only a single pop */
1635                                 num_pop = 1;
1636                         }
1637
1638                         depth -= num_pop;
1639                         kill_mask >>= num_pop;
1640                         keep = x87_create_fpop(sim->env, state, first_insn, num_pop, keep);
1641                 }
1642                 add_End_keepalive(get_irg_end(get_irn_irg(block)), keep);
1643         }
1644         return state;
1645 }
1646
1647 /**
1648  * Run a simulation and fix all virtual instructions for a block.
1649  *
1650  * @param sim          the simulator handle
1651  * @param block        the current block
1652  *
1653  * @return non-zero if simulation is complete,
1654  *         zero if the simulation must be rerun
1655  */
1656 static int x87_simulate_block(x87_simulator *sim, ir_node *block) {
1657         ir_node *n, *next;
1658         blk_state *bl_state = x87_get_bl_state(sim, block);
1659         x87_state *state = bl_state->begin;
1660         const ir_edge_t *edge;
1661         ir_node *start_block;
1662
1663         /* if we have no assigned start state, we must wait ... */
1664         if (! state)
1665                 return 0;
1666
1667         assert(bl_state->end == NULL);
1668
1669         DB((dbg, LEVEL_1, "Simulate %+F\n", block));
1670
1671         /* at block begin, kill all dead registers */
1672         state = x87_kill_deads(sim, block, state);
1673
1674         /* beware, n might changed */
1675         for (n = sched_first(block); !sched_is_end(n); n = next) {
1676                 ir_op *op = get_irn_op(n);
1677
1678                 next = sched_next(n);
1679                 if (op->ops.generic) {
1680                         int node_inserted;
1681                         sim_func func = (sim_func)op->ops.generic;
1682
1683                         /* have work to do */
1684                         if (state == bl_state->begin) {
1685                                 /* create a new state, will be changed */
1686                                 state = x87_clone_state(sim, state);
1687                         }
1688
1689                         /* simulate it */
1690                         node_inserted = (*func)(state, n, sim->env);
1691
1692                         /*
1693                                 sim_func might have added additional nodes after n,
1694                                 so update next node
1695                                 beware: n must not be changed by sim_func
1696                                 (i.e. removed from schedule) in this case
1697                         */
1698                         if (node_inserted)
1699                                 next = sched_next(n);
1700                 }
1701         }
1702
1703         start_block = get_irg_start_block(get_irn_irg(block));
1704
1705         /* check if the state must be shuffled */
1706         foreach_block_succ(block, edge) {
1707                 ir_node *succ = get_edge_src_irn(edge);
1708                 blk_state *succ_state = x87_get_bl_state(sim, succ);
1709
1710                 if (succ_state->begin && succ != start_block) {
1711                         /* There is already a begin state for this block, bad.
1712                            Do the necessary permutations.
1713                            Note that critical edges are removed, so this is always possible. */
1714                         x87_shuffle(sim, block, state, succ, succ_state->begin);
1715
1716                         /* Note further, that there can be only one such situation,
1717                            so we can break here. */
1718                         break;
1719                 }
1720         }
1721         bl_state->end = state;
1722
1723         /* now propagate the state to all successor blocks */
1724         foreach_block_succ(block, edge) {
1725                 ir_node *succ = get_edge_src_irn(edge);
1726                 blk_state *succ_state = x87_get_bl_state(sim, succ);
1727
1728                 if (! succ_state->begin)
1729                         succ_state->begin = state;
1730         }
1731
1732         return 1;
1733 }
1734
1735 /**
1736  * Create a new x87 simulator.
1737  *
1738  * @param sim   a simulator handle, will be initialized
1739  * @param irg   the current graph
1740  * @param env   the architecture environment
1741  */
1742 static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, const arch_env_t *env) {
1743         obstack_init(&sim->obst);
1744         sim->blk_states = pmap_create();
1745         sim->env        = env;
1746         sim->lv         = be_liveness(irg);
1747
1748         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.x87");
1749
1750         DB((dbg, LEVEL_1, "--------------------------------\n"
1751                 "x87 Simulator started for %+F\n", irg));
1752
1753   /* set the generic function pointer of instruction we must simulate */
1754         clear_irp_opcodes_generic_func();
1755
1756 #define ASSOC(op)       (op_ ## op)->ops.generic = (op_func)(sim_##op)
1757 #define ASSOC_IA32(op)  (op_ia32_v ## op)->ops.generic = (op_func)(sim_##op)
1758 #define ASSOC_BE(op)    (op_be_ ## op)->ops.generic = (op_func)(sim_##op)
1759         ASSOC_IA32(fConst);
1760         ASSOC_IA32(fld);
1761         ASSOC_IA32(fild);
1762         ASSOC_IA32(fld1);
1763         ASSOC_IA32(fldz);
1764         ASSOC_IA32(fadd);
1765         ASSOC_IA32(fsub);
1766         ASSOC_IA32(fmul);
1767         ASSOC_IA32(fdiv);
1768         ASSOC_IA32(fldz);
1769         ASSOC_IA32(fabs);
1770         ASSOC_IA32(fchs);
1771         ASSOC_IA32(fsin);
1772         ASSOC_IA32(fcos);
1773         ASSOC_IA32(fsqrt);
1774         ASSOC_IA32(fist);
1775         ASSOC_IA32(fst);
1776         ASSOC_IA32(fCondJmp);
1777         ASSOC_BE(Copy);
1778         ASSOC_BE(Call);
1779         ASSOC_BE(Spill);
1780         ASSOC_BE(Reload);
1781         ASSOC_BE(Return);
1782         ASSOC(Phi);
1783 #undef ASSOC_BE
1784 #undef ASSOC_IA32
1785 #undef ASSOC
1786 }
1787
1788 /**
1789  * Destroy a x87 simulator.
1790  *
1791  * @param sim  the simulator handle
1792  */
1793 static void x87_destroy_simulator(x87_simulator *sim) {
1794         pmap_destroy(sim->blk_states);
1795         obstack_free(&sim->obst, NULL);
1796         be_liveness_free(sim->lv);
1797         DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
1798 }
1799
1800 /**
1801  * Run a simulation and fix all virtual instructions for a graph.
1802  *
1803  * @param env       the architecture environment
1804  * @param irg       the current graph
1805  * @param blk_list  the block schedule list
1806  *
1807  * Needs a block-schedule.
1808  */
1809 void x87_simulate_graph(const arch_env_t *env, ir_graph *irg, ir_node **blk_list) {
1810         ir_node *block, *start_block;
1811         pdeq *worklist;
1812         blk_state *bl_state;
1813         x87_simulator sim;
1814         int i;
1815
1816         /* create the simulator */
1817         x87_init_simulator(&sim, irg, env);
1818
1819         start_block = get_irg_start_block(irg);
1820         bl_state = x87_get_bl_state(&sim, start_block);
1821
1822         /* start with the empty state */
1823         bl_state->begin = empty;
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 }