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