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