1a0976cdf1c2a0da5d6c27136a13ac6a3db6235d
[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_attr_t     *attr;
449
450         fxch = new_rd_ia32_fxch(NULL, get_irn_irg(block), block, mode_E);
451         attr = get_ia32_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 void keep_float_node_alive(x87_state *state, ir_node *node)
1510 {
1511         ir_graph                    *irg;
1512         ir_node                     *block;
1513         ir_node                     *in[1];
1514         ir_node                     *keep;
1515         const arch_register_class_t *cls;
1516
1517         irg    = get_irn_irg(node);
1518         block  = get_nodes_block(node);
1519         cls    = arch_get_irn_reg_class(state->sim->arch_env, node, -1);
1520         in[0]  = node;
1521         keep   = be_new_Keep(cls, irg, block, 1, in);
1522
1523         assert(sched_is_scheduled(node));
1524         sched_add_after(node, keep);
1525 }
1526
1527 /**
1528  * Create a copy of a node. Recreate the node if it's a constant.
1529  *
1530  * @param state  the x87 state
1531  * @param n      the node to be copied
1532  *
1533  * @return the copy of n
1534  */
1535 static ir_node *create_Copy(x87_state *state, ir_node *n) {
1536         x87_simulator *sim = state->sim;
1537         ir_graph *irg = get_irn_irg(n);
1538         dbg_info *n_dbg = get_irn_dbg_info(n);
1539         ir_mode *mode = get_irn_mode(n);
1540         ir_node *block = get_nodes_block(n);
1541         ir_node *pred = get_irn_n(n, 0);
1542         ir_node *(*cnstr)(dbg_info *, ir_graph *, ir_node *, ir_mode *) = NULL;
1543         ir_node *res;
1544         const arch_register_t *out;
1545         const arch_register_t *op1;
1546         ia32_attr_t *attr;
1547
1548         /* Do not copy constants, recreate them. */
1549         switch (get_ia32_irn_opcode(pred)) {
1550         case iro_ia32_Unknown_VFP:
1551         case iro_ia32_fldz:
1552                 cnstr = new_rd_ia32_fldz;
1553                 break;
1554         case iro_ia32_fld1:
1555                 cnstr = new_rd_ia32_fld1;
1556                 break;
1557         case iro_ia32_fldpi:
1558                 cnstr = new_rd_ia32_fldpi;
1559                 break;
1560         case iro_ia32_fldl2e:
1561                 cnstr = new_rd_ia32_fldl2e;
1562                 break;
1563         case iro_ia32_fldl2t:
1564                 cnstr = new_rd_ia32_fldl2t;
1565                 break;
1566         case iro_ia32_fldlg2:
1567                 cnstr = new_rd_ia32_fldlg2;
1568                 break;
1569         case iro_ia32_fldln2:
1570                 cnstr = new_rd_ia32_fldln2;
1571                 break;
1572         default:
1573                 break;
1574         }
1575
1576         out = x87_get_irn_register(sim, n);
1577         op1 = x87_get_irn_register(sim, pred);
1578
1579         if (cnstr != NULL) {
1580                 /* copy a constant */
1581                 res = (*cnstr)(n_dbg, irg, block, mode);
1582
1583                 x87_push(state, arch_register_get_index(out), res);
1584
1585                 attr = get_ia32_attr(res);
1586                 attr->x87[2] = &ia32_st_regs[0];
1587         } else {
1588                 int op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1589
1590                 res = new_rd_ia32_fpushCopy(n_dbg, irg, block, pred, mode);
1591
1592                 x87_push(state, arch_register_get_index(out), res);
1593
1594                 attr = get_ia32_attr(res);
1595                 attr->x87[0] = &ia32_st_regs[op1_idx];
1596                 attr->x87[2] = &ia32_st_regs[0];
1597         }
1598         arch_set_irn_register(sim->arch_env, res, out);
1599
1600         return res;
1601 }  /* create_Copy */
1602
1603 /**
1604  * Simulate a be_Copy.
1605  *
1606  * @param state  the x87 state
1607  * @param n      the node that should be simulated (and patched)
1608  *
1609  * @return NO_NODE_ADDED
1610  */
1611 static int sim_Copy(x87_state *state, ir_node *n) {
1612         x87_simulator         *sim;
1613         ir_node               *pred;
1614         const arch_register_t *out;
1615         const arch_register_t *op1;
1616         ir_node               *node, *next;
1617         ia32_attr_t           *attr;
1618         int                   op1_idx, out_idx;
1619         unsigned              live;
1620
1621         ir_mode *mode = get_irn_mode(n);
1622
1623         if (!mode_is_float(mode))
1624                 return 0;
1625
1626         sim = state->sim;
1627         pred = get_irn_n(n, 0);
1628         out = x87_get_irn_register(sim, n);
1629         op1 = x87_get_irn_register(sim, pred);
1630         live = vfp_live_args_after(sim, n, REGMASK(out));
1631
1632         DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", n,
1633                 arch_register_get_name(op1), arch_register_get_name(out)));
1634         DEBUG_ONLY(vfp_dump_live(live));
1635
1636         /* handle the infamous unknown value */
1637         if (arch_register_get_index(op1) == REG_VFP_UKNWN) {
1638                 /* Operand is still live, a real copy. We need here an fpush that can
1639                    hold a a register, so use the fpushCopy or recreate constants */
1640                 node = create_Copy(state, n);
1641
1642                 assert(is_ia32_fldz(node));
1643                 next = sched_next(n);
1644                 sched_remove(n);
1645                 exchange(n, node);
1646                 sched_add_before(next, node);
1647
1648                 DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name,
1649                     arch_get_irn_register(sim->arch_env, node)->name));
1650                 return NO_NODE_ADDED;
1651         }
1652
1653         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1654
1655         if (is_vfp_live(arch_register_get_index(op1), live)) {
1656                 ir_node *pred = get_irn_n(n, 0);
1657
1658                 /* Operand is still live, a real copy. We need here an fpush that can
1659                    hold a a register, so use the fpushCopy or recreate constants */
1660                 node = create_Copy(state, n);
1661
1662                 /* We have to make sure the old value doesn't go dead (which can happen
1663                  * when we recreate constants). As the simulator expected that value in
1664                  * the pred blocks. This is unfortunate as removing it would save us 1
1665                  * instruction, but we would have to rerun all the simulation to get
1666                  * this correct...
1667                  */
1668                 next = sched_next(n);
1669                 sched_remove(n);
1670                 exchange(n, node);
1671                 sched_add_before(next, node);
1672
1673                 if(get_irn_n_edges(pred) == 0) {
1674                         keep_float_node_alive(state, pred);
1675                 }
1676
1677                 DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name,
1678                     arch_get_irn_register(sim->arch_env, node)->name));
1679         } else {
1680                 out_idx = x87_on_stack(state, arch_register_get_index(out));
1681
1682                 if (out_idx >= 0 && out_idx != op1_idx) {
1683                         /* Matze: out already on stack? how can this happen? */
1684                         assert(0);
1685
1686                         /* op1 must be killed and placed where out is */
1687                         if (out_idx == 0) {
1688                                 /* best case, simple remove and rename */
1689                                 x87_patch_insn(n, op_ia32_Pop);
1690                                 attr = get_ia32_attr(n);
1691                                 attr->x87[0] = op1 = &ia32_st_regs[0];
1692
1693                                 x87_pop(state);
1694                                 x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
1695                         } else {
1696                                 /* move op1 to tos, store and pop it */
1697                                 if (op1_idx != 0) {
1698                                         x87_create_fxch(state, n, op1_idx, 0);
1699                                         op1_idx = 0;
1700                                 }
1701                                 x87_patch_insn(n, op_ia32_Pop);
1702                                 attr = get_ia32_attr(n);
1703                                 attr->x87[0] = op1 = &ia32_st_regs[out_idx];
1704
1705                                 x87_pop(state);
1706                                 x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
1707                         }
1708                         DB((dbg, LEVEL_1, "<<< %+F %s\n", n, op1->name));
1709                 } else {
1710                         /* just a virtual copy */
1711                         x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
1712                         /* don't remove the node to keep the verifier quiet :),
1713                            the emitter won't emit any code for the node */
1714 #if 0
1715                         sched_remove(n);
1716                         DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n)));
1717                         exchange(n, get_unop_op(n));
1718 #endif
1719                 }
1720         }
1721         return NO_NODE_ADDED;
1722 }  /* sim_Copy */
1723
1724 /**
1725  * Returns the result proj of the call, or NULL if the result is not used
1726  */
1727 static ir_node *get_call_result_proj(ir_node *call) {
1728         const ir_edge_t *edge;
1729         ir_node *resproj = NULL;
1730
1731         /* search the result proj */
1732         foreach_out_edge(call, edge) {
1733                 ir_node *proj = get_edge_src_irn(edge);
1734                 long pn = get_Proj_proj(proj);
1735
1736                 if (pn == pn_be_Call_first_res) {
1737                         resproj = proj;
1738                         break;
1739                 }
1740         }
1741         if (resproj == NULL) {
1742                 return NULL;
1743         }
1744
1745         /* the result proj is connected to a Keep and maybe other nodes */
1746         foreach_out_edge(resproj, edge) {
1747                 ir_node *pred = get_edge_src_irn(edge);
1748                 if (!be_is_Keep(pred)) {
1749                         return resproj;
1750                 }
1751         }
1752
1753         /* only be_Keep found, so result is not used */
1754         return NULL;
1755 }  /* get_call_result_proj */
1756
1757 /**
1758  * Simulate a be_Call.
1759  *
1760  * @param state      the x87 state
1761  * @param n          the node that should be simulated
1762  * @param arch_env   the architecture environment
1763  *
1764  * @return NO_NODE_ADDED
1765  */
1766 static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *arch_env) {
1767         ir_type *call_tp = be_Call_get_type(n);
1768         ir_type *res_type;
1769         ir_mode *mode;
1770         ir_node *resproj;
1771         const arch_register_t *reg;
1772
1773         /* at the begin of a call the x87 state should be empty */
1774         assert(state->depth == 0 && "stack not empty before call");
1775
1776         if (get_method_n_ress(call_tp) <= 0)
1777                 return NO_NODE_ADDED;
1778
1779         /*
1780          * If the called function returns a float, it is returned in st(0).
1781          * This even happens if the return value is NOT used.
1782          * Moreover, only one return result is supported.
1783          */
1784         res_type = get_method_res_type(call_tp, 0);
1785         mode     = get_type_mode(res_type);
1786
1787         if (mode == NULL || !mode_is_float(mode))
1788                 return NO_NODE_ADDED;
1789
1790         resproj = get_call_result_proj(n);
1791         if (resproj == NULL)
1792                 return NO_NODE_ADDED;
1793
1794         reg = x87_get_irn_register(state->sim, resproj);
1795         x87_push(state, arch_register_get_index(reg), resproj);
1796
1797         return NO_NODE_ADDED;
1798 }  /* sim_Call */
1799
1800 /**
1801  * Simulate a be_Spill.
1802  *
1803  * @param state  the x87 state
1804  * @param n      the node that should be simulated (and patched)
1805  *
1806  * Should not happen, spills are lowered before x87 simulator see them.
1807  */
1808 static int sim_Spill(x87_state *state, ir_node *n) {
1809         assert(0 && "Spill not lowered");
1810         return sim_fst(state, n);
1811 }  /* sim_Spill */
1812
1813 /**
1814  * Simulate a be_Reload.
1815  *
1816  * @param state  the x87 state
1817  * @param n      the node that should be simulated (and patched)
1818  *
1819  * Should not happen, reloads are lowered before x87 simulator see them.
1820  */
1821 static int sim_Reload(x87_state *state, ir_node *n) {
1822         assert(0 && "Reload not lowered");
1823         return sim_fld(state, n);
1824 }  /* sim_Reload */
1825
1826 /**
1827  * Simulate a be_Return.
1828  *
1829  * @param state  the x87 state
1830  * @param n      the node that should be simulated (and patched)
1831  *
1832  * @return NO_NODE_ADDED
1833  */
1834 static int sim_Return(x87_state *state, ir_node *n) {
1835         int n_res = be_Return_get_n_rets(n);
1836         int i, n_float_res = 0;
1837
1838         /* only floating point return values must resist on stack */
1839         for (i = 0; i < n_res; ++i) {
1840                 ir_node *res = get_irn_n(n, be_pos_Return_val + i);
1841
1842                 if (mode_is_float(get_irn_mode(res)))
1843                         ++n_float_res;
1844         }
1845         assert(x87_get_depth(state) == n_float_res);
1846
1847         /* pop them virtually */
1848         for (i = n_float_res - 1; i >= 0; --i)
1849                 x87_pop(state);
1850
1851         return NO_NODE_ADDED;
1852 }  /* sim_Return */
1853
1854 typedef struct _perm_data_t {
1855         const arch_register_t *in;
1856         const arch_register_t *out;
1857 } perm_data_t;
1858
1859 /**
1860  * Simulate a be_Perm.
1861  *
1862  * @param state  the x87 state
1863  * @param irn    the node that should be simulated (and patched)
1864  *
1865  * @return NO_NODE_ADDED
1866  */
1867 static int sim_Perm(x87_state *state, ir_node *irn) {
1868         int             i, n;
1869         x87_simulator   *sim = state->sim;
1870         ir_node         *pred = get_irn_n(irn, 0);
1871         int             *stack_pos;
1872         const ir_edge_t *edge;
1873
1874         /* handle only floating point Perms */
1875         if (! mode_is_float(get_irn_mode(pred)))
1876                 return NO_NODE_ADDED;
1877
1878         DB((dbg, LEVEL_1, ">>> %+F\n", irn));
1879
1880         /* Perm is a pure virtual instruction on x87.
1881            All inputs must be on the FPU stack and are pairwise
1882            different from each other.
1883            So, all we need to do is to permutate the stack state. */
1884         n = get_irn_arity(irn);
1885         NEW_ARR_A(int, stack_pos, n);
1886
1887         /* collect old stack positions */
1888         for (i = 0; i < n; ++i) {
1889                 const arch_register_t *inreg = x87_get_irn_register(sim, get_irn_n(irn, i));
1890                 int idx = x87_on_stack(state, arch_register_get_index(inreg));
1891
1892                 assert(idx >= 0 && "Perm argument not on x87 stack");
1893
1894                 stack_pos[i] = idx;
1895         }
1896         /* now do the permutation */
1897         foreach_out_edge(irn, edge) {
1898                 ir_node               *proj = get_edge_src_irn(edge);
1899                 const arch_register_t *out  = x87_get_irn_register(sim, proj);
1900                 long                  num   = get_Proj_proj(proj);
1901
1902                 assert(0 <= num && num < n && "More Proj's than Perm inputs");
1903                 x87_set_st(state, arch_register_get_index(out), proj, stack_pos[(unsigned)num]);
1904         }
1905         DB((dbg, LEVEL_1, "<<< %+F\n", irn));
1906
1907         return NO_NODE_ADDED;
1908 }  /* sim_Perm */
1909
1910 /**
1911  * Kill any dead registers at block start by popping them from the stack.
1912  *
1913  * @param sim          the simulator handle
1914  * @param block        the current block
1915  * @param start_state  the x87 state at the begin of the block
1916  *
1917  * @return the x87 state after dead register killed
1918  */
1919 static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *start_state) {
1920         x87_state *state = start_state;
1921         ir_node *first_insn = sched_first(block);
1922         ir_node *keep = NULL;
1923         unsigned live = vfp_live_args_after(sim, block, 0);
1924         unsigned kill_mask;
1925         int i, depth, num_pop;
1926
1927         kill_mask = 0;
1928         depth = x87_get_depth(state);
1929         for (i = depth - 1; i >= 0; --i) {
1930                 int reg = x87_get_st_reg(state, i);
1931
1932                 if (! is_vfp_live(reg, live))
1933                         kill_mask |= (1 << i);
1934         }
1935
1936         if (kill_mask) {
1937                 /* create a new state, will be changed */
1938                 state = x87_clone_state(sim, state);
1939
1940                 DB((dbg, LEVEL_1, "Killing deads:\n"));
1941                 DEBUG_ONLY(vfp_dump_live(live));
1942                 DEBUG_ONLY(x87_dump_stack(state));
1943
1944                 /* now kill registers */
1945                 while (kill_mask) {
1946                         /* we can only kill from TOS, so bring them up */
1947                         if (! (kill_mask & 1)) {
1948                                 /* search from behind, because we can to a double-pop */
1949                                 for (i = depth - 1; i >= 0; --i) {
1950                                         if (kill_mask & (1 << i)) {
1951                                                 kill_mask &= ~(1 << i);
1952                                                 kill_mask |= 1;
1953                                                 break;
1954                                         }
1955                                 }
1956
1957                                 if (keep)
1958                                         x87_set_st(state, -1, keep, i);
1959                                 x87_create_fxch(state, first_insn, i, -1);
1960                         }
1961
1962                         if ((kill_mask & 3) == 3) {
1963                                 /* we can do a double-pop */
1964                                 num_pop = 2;
1965                         }
1966                         else {
1967                                 /* only a single pop */
1968                                 num_pop = 1;
1969                         }
1970
1971                         depth -= num_pop;
1972                         kill_mask >>= num_pop;
1973                         keep = x87_create_fpop(state, first_insn, num_pop);
1974                 }
1975                 keep_alive(keep);
1976         }
1977         return state;
1978 }  /* x87_kill_deads */
1979
1980 /**
1981  * Run a simulation and fix all virtual instructions for a block.
1982  *
1983  * @param sim          the simulator handle
1984  * @param block        the current block
1985  */
1986 static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
1987         ir_node *n, *next;
1988         blk_state *bl_state = x87_get_bl_state(sim, block);
1989         x87_state *state = bl_state->begin;
1990         const ir_edge_t *edge;
1991         ir_node *start_block;
1992
1993         assert(state != NULL);
1994         /* already processed? */
1995         if (bl_state->end != NULL)
1996                 return;
1997
1998         DB((dbg, LEVEL_1, "Simulate %+F\n", block));
1999         DB((dbg, LEVEL_2, "State at Block begin:\n "));
2000         DEBUG_ONLY(x87_dump_stack(state));
2001
2002         /* at block begin, kill all dead registers */
2003         state = x87_kill_deads(sim, block, state);
2004
2005         /* beware, n might change */
2006         for (n = sched_first(block); !sched_is_end(n); n = next) {
2007                 int node_inserted;
2008                 sim_func func;
2009                 ir_op *op = get_irn_op(n);
2010
2011                 next = sched_next(n);
2012                 if (op->ops.generic == NULL)
2013                         continue;
2014
2015                 func = (sim_func)op->ops.generic;
2016
2017                 /* have work to do */
2018                 if (state == bl_state->begin) {
2019                         /* create a new state, will be changed */
2020                         state = x87_clone_state(sim, state);
2021                 }
2022
2023                 /* simulate it */
2024                 node_inserted = (*func)(state, n);
2025
2026                 /*
2027                         sim_func might have added an additional node after n,
2028                         so update next node
2029                         beware: n must not be changed by sim_func
2030                         (i.e. removed from schedule) in this case
2031                 */
2032                 if (node_inserted != NO_NODE_ADDED)
2033                         next = sched_next(n);
2034         }
2035
2036         start_block = get_irg_start_block(get_irn_irg(block));
2037
2038         /* check if the state must be shuffled */
2039         foreach_block_succ(block, edge) {
2040                 ir_node *succ = get_edge_src_irn(edge);
2041                 blk_state *succ_state;
2042
2043                 if (succ == start_block)
2044                         continue;
2045
2046                 succ_state = x87_get_bl_state(sim, succ);
2047
2048                 if (succ_state->begin == NULL) {
2049                         succ_state->begin = state;
2050                         waitq_put(sim->worklist, succ);
2051                 } else {
2052                         /* There is already a begin state for the successor, bad.
2053                            Do the necessary permutations.
2054                            Note that critical edges are removed, so this is always possible:
2055                            If the successor has more than one possible input, then it must
2056                            be the only one.
2057                          */
2058                         x87_shuffle(sim, block, state, succ, succ_state->begin);
2059                 }
2060         }
2061         bl_state->end = state;
2062
2063         DB((dbg, LEVEL_2, "State at Block end:\n ")); DEBUG_ONLY(x87_dump_stack(state));
2064 }  /* x87_simulate_block */
2065
2066 /**
2067  * Create a new x87 simulator.
2068  *
2069  * @param sim       a simulator handle, will be initialized
2070  * @param irg       the current graph
2071  * @param arch_env  the architecture environment
2072  */
2073 static void x87_init_simulator(x87_simulator *sim, ir_graph *irg,
2074                                const arch_env_t *arch_env)
2075 {
2076         obstack_init(&sim->obst);
2077         sim->blk_states = pmap_create();
2078         sim->arch_env   = arch_env;
2079         sim->n_idx      = get_irg_last_idx(irg);
2080         sim->live       = obstack_alloc(&sim->obst, sizeof(*sim->live) * sim->n_idx);
2081
2082         DB((dbg, LEVEL_1, "--------------------------------\n"
2083                 "x87 Simulator started for %+F\n", irg));
2084
2085         /* set the generic function pointer of instruction we must simulate */
2086         clear_irp_opcodes_generic_func();
2087
2088 #define ASSOC(op)       (op_ ## op)->ops.generic = (op_func)(sim_##op)
2089 #define ASSOC_IA32(op)  (op_ia32_v ## op)->ops.generic = (op_func)(sim_##op)
2090 #define ASSOC_BE(op)    (op_be_ ## op)->ops.generic = (op_func)(sim_##op)
2091         ASSOC_IA32(fld);
2092         ASSOC_IA32(fild);
2093         ASSOC_IA32(fld1);
2094         ASSOC_IA32(fldz);
2095         ASSOC_IA32(fadd);
2096         ASSOC_IA32(fsub);
2097         ASSOC_IA32(fmul);
2098         ASSOC_IA32(fdiv);
2099         ASSOC_IA32(fprem);
2100         ASSOC_IA32(fabs);
2101         ASSOC_IA32(fchs);
2102         ASSOC_IA32(fsin);
2103         ASSOC_IA32(fcos);
2104         ASSOC_IA32(fsqrt);
2105         ASSOC_IA32(fist);
2106         ASSOC_IA32(fst);
2107         ASSOC_IA32(fCondJmp);
2108         ASSOC_BE(Copy);
2109         ASSOC_BE(Call);
2110         ASSOC_BE(Spill);
2111         ASSOC_BE(Reload);
2112         ASSOC_BE(Return);
2113         ASSOC_BE(Perm);
2114         ASSOC(Phi);
2115 #undef ASSOC_BE
2116 #undef ASSOC_IA32
2117 #undef ASSOC
2118 }  /* x87_init_simulator */
2119
2120 /**
2121  * Destroy a x87 simulator.
2122  *
2123  * @param sim  the simulator handle
2124  */
2125 static void x87_destroy_simulator(x87_simulator *sim) {
2126         pmap_destroy(sim->blk_states);
2127         obstack_free(&sim->obst, NULL);
2128         DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
2129 }  /* x87_destroy_simulator */
2130
2131 /**
2132  * Pre-block walker: calculate the liveness information for the block
2133  * and store it into the sim->live cache.
2134  */
2135 static void update_liveness_walker(ir_node *block, void *data) {
2136         x87_simulator *sim = data;
2137         update_liveness(sim, block);
2138 }  /* update_liveness_walker */
2139
2140 /**
2141  * Run a simulation and fix all virtual instructions for a graph.
2142  *
2143  * @param env       the architecture environment
2144  * @param irg       the current graph
2145  *
2146  * Needs a block-schedule.
2147  */
2148 void x87_simulate_graph(const arch_env_t *arch_env, be_irg_t *birg) {
2149         ir_node       *block, *start_block;
2150         blk_state     *bl_state;
2151         x87_simulator sim;
2152         ir_graph      *irg = be_get_birg_irg(birg);
2153
2154         /* create the simulator */
2155         x87_init_simulator(&sim, irg, arch_env);
2156
2157         start_block = get_irg_start_block(irg);
2158         bl_state = x87_get_bl_state(&sim, start_block);
2159
2160         /* start with the empty state */
2161         bl_state->begin = empty;
2162         empty->sim      = &sim;
2163
2164         sim.worklist = new_waitq();
2165         waitq_put(sim.worklist, start_block);
2166
2167         be_invalidate_liveness(birg);
2168         be_assure_liveness(birg);
2169         sim.lv = be_get_birg_liveness(birg);
2170
2171         /* Calculate the liveness for all nodes. We must precalculate this info,
2172          * because the simulator adds new nodes (possible before Phi nodes) which
2173          * would let a lazy calculation fail.
2174          * On the other hand we reduce the computation amount due to
2175          * precaching from O(n^2) to O(n) at the expense of O(n) cache memory.
2176          */
2177         irg_block_walk_graph(irg, update_liveness_walker, NULL, &sim);
2178
2179         /* iterate */
2180         do {
2181                 block = waitq_get(sim.worklist);
2182                 x87_simulate_block(&sim, block);
2183         } while (! waitq_empty(sim.worklist));
2184
2185         /* kill it */
2186         del_waitq(sim.worklist);
2187         x87_destroy_simulator(&sim);
2188 }  /* x87_simulate_graph */
2189
2190 void ia32_init_x87(void) {
2191         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.x87");
2192 }  /* ia32_init_x87 */