support for fucom(p)i
[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  * Empty the fpu stack
313  *
314  * @param state     the x87 state
315  */
316 static void x87_emms(x87_state *state) {
317         state->depth = 0;
318         state->tos   = 0;
319 }
320
321 /**
322  * Returns the block state of a block.
323  *
324  * @param sim    the x87 simulator handle
325  * @param block  the current block
326  *
327  * @return the block state
328  */
329 static blk_state *x87_get_bl_state(x87_simulator *sim, ir_node *block) {
330         pmap_entry *entry = pmap_find(sim->blk_states, block);
331
332         if (! entry) {
333                 blk_state *bl_state = obstack_alloc(&sim->obst, sizeof(*bl_state));
334                 bl_state->begin = NULL;
335                 bl_state->end   = NULL;
336
337                 pmap_insert(sim->blk_states, block, bl_state);
338                 return bl_state;
339         }
340
341         return PTR_TO_BLKSTATE(entry->value);
342 }  /* x87_get_bl_state */
343
344 /**
345  * Creates a new x87 state.
346  *
347  * @param sim    the x87 simulator handle
348  *
349  * @return a new x87 state
350  */
351 static x87_state *x87_alloc_state(x87_simulator *sim) {
352         x87_state *res = obstack_alloc(&sim->obst, sizeof(*res));
353
354         res->sim = sim;
355         return res;
356 }  /* x87_alloc_state */
357
358 /**
359  * Clone a x87 state.
360  *
361  * @param sim    the x87 simulator handle
362  * @param src    the x87 state that will be cloned
363  *
364  * @return a cloned copy of the src state
365  */
366 static x87_state *x87_clone_state(x87_simulator *sim, const x87_state *src) {
367         x87_state *res = x87_alloc_state(sim);
368
369         memcpy(res, src, sizeof(*res));
370         return res;
371 }  /* x87_clone_state */
372
373 /**
374  * Patch a virtual instruction into a x87 one and return
375  * the node representing the result value.
376  *
377  * @param n   the IR node to patch
378  * @param op  the x87 opcode to patch in
379  */
380 static ir_node *x87_patch_insn(ir_node *n, ir_op *op) {
381         ir_mode *mode = get_irn_mode(n);
382         ir_node *res = n;
383
384         set_irn_op(n, op);
385
386         if (mode == mode_T) {
387                 /* patch all Proj's */
388                 const ir_edge_t *edge;
389
390                 foreach_out_edge(n, edge) {
391                         ir_node *proj = get_edge_src_irn(edge);
392                         if (is_Proj(proj)) {
393                                 mode = get_irn_mode(proj);
394                                 if (mode_is_float(mode)) {
395                                         res = proj;
396                                         set_irn_mode(proj, mode_E);
397                                 }
398                         }
399                 }
400         } else if (mode_is_float(mode))
401                 set_irn_mode(n, mode_E);
402         return res;
403 }  /* x87_patch_insn */
404
405 /**
406  * Returns the first Proj of a mode_T node having a given mode.
407  *
408  * @param n  the mode_T node
409  * @param m  the desired mode of the Proj
410  * @return The first Proj of mode @p m found or NULL.
411  */
412 static ir_node *get_irn_Proj_for_mode(ir_node *n, ir_mode *m) {
413         const ir_edge_t *edge;
414
415         assert(get_irn_mode(n) == mode_T && "Need mode_T node");
416
417         foreach_out_edge(n, edge) {
418                 ir_node *proj = get_edge_src_irn(edge);
419                 if (get_irn_mode(proj) == m)
420                         return proj;
421         }
422
423         return NULL;
424 }  /* get_irn_Proj_for_mode */
425
426 /**
427  * Wrap the arch_* function here so we can check for errors.
428  */
429 static INLINE const arch_register_t *x87_get_irn_register(x87_simulator *sim, const ir_node *irn) {
430         const arch_register_t *res;
431
432         res = arch_get_irn_register(sim->arch_env, irn);
433         assert(res->reg_class->regs == ia32_vfp_regs);
434         return res;
435 }  /* x87_get_irn_register */
436
437 /* -------------- x87 perm --------------- */
438
439 /**
440  * Creates a fxch for shuffle.
441  *
442  * @param state     the x87 state
443  * @param pos       parameter for fxch
444  * @param block     the block were fxch is inserted
445  *
446  * Creates a new fxch node and reroute the user of the old node
447  * to the fxch.
448  *
449  * @return the fxch node
450  */
451 static ir_node *x87_fxch_shuffle(x87_state *state, int pos, ir_node *block) {
452         ir_node         *fxch;
453         ia32_x87_attr_t *attr;
454
455         fxch = new_rd_ia32_fxch(NULL, get_irn_irg(block), block);
456         attr = get_ia32_x87_attr(fxch);
457         attr->x87[0] = &ia32_st_regs[pos];
458         attr->x87[2] = &ia32_st_regs[0];
459
460         keep_alive(fxch);
461
462         x87_fxch(state, pos);
463         return fxch;
464 }  /* x87_fxch_shuffle */
465
466 /**
467  * Calculate the necessary permutations to reach dst_state.
468  *
469  * These permutations are done with fxch instructions and placed
470  * at the end of the block.
471  *
472  * Note that critical edges are removed here, so we need only
473  * a shuffle if the current block has only one successor.
474  *
475  * @param sim        the simulator handle
476  * @param block      the current block
477  * @param state      the current x87 stack state, might be modified
478  * @param dst_block  the destination block
479  * @param dst_state  destination state
480  *
481  * @return state
482  */
483 static x87_state *x87_shuffle(x87_simulator *sim, ir_node *block,
484                               x87_state *state, ir_node *dst_block,
485                               const x87_state *dst_state)
486 {
487         int      i, n_cycles, k, ri;
488         unsigned cycles[4], all_mask;
489         char     cycle_idx[4][8];
490         ir_node  *fxch, *before, *after;
491         (void) sim;
492         (void) dst_block;
493
494         assert(state->depth == dst_state->depth);
495
496         /* Some mathematics here:
497            If we have a cycle of length n that includes the tos,
498            we need n-1 exchange operations.
499            We can always add the tos and restore it, so we need
500            n+1 exchange operations for a cycle not containing the tos.
501            So, the maximum of needed operations is for a cycle of 7
502            not including the tos == 8.
503            This is the same number of ops we would need for using stores,
504            so exchange is cheaper (we save the loads).
505            On the other hand, we might need an additional exchange
506            in the next block to bring one operand on top, so the
507            number of ops in the first case is identical.
508            Further, no more than 4 cycles can exists (4 x 2).
509         */
510         all_mask = (1 << (state->depth)) - 1;
511
512         for (n_cycles = 0; all_mask; ++n_cycles) {
513                 int src_idx, dst_idx;
514
515                 /* find the first free slot */
516                 for (i = 0; i < state->depth; ++i) {
517                         if (all_mask & (1 << i)) {
518                                 all_mask &= ~(1 << i);
519
520                                 /* check if there are differences here */
521                                 if (x87_get_st_reg(state, i) != x87_get_st_reg(dst_state, i))
522                                         break;
523                         }
524                 }
525
526                 if (! all_mask) {
527                         /* no more cycles found */
528                         break;
529                 }
530
531                 k = 0;
532                 cycles[n_cycles] = (1 << i);
533                 cycle_idx[n_cycles][k++] = i;
534                 for (src_idx = i; ; src_idx = dst_idx) {
535                         dst_idx = x87_on_stack(dst_state, x87_get_st_reg(state, src_idx));
536
537                         if ((all_mask & (1 << dst_idx)) == 0)
538                                 break;
539
540                         cycle_idx[n_cycles][k++] = dst_idx;
541                         cycles[n_cycles] |=  (1 << dst_idx);
542                         all_mask       &= ~(1 << dst_idx);
543                 }
544                 cycle_idx[n_cycles][k] = -1;
545         }
546
547         if (n_cycles <= 0) {
548                 /* no permutation needed */
549                 return state;
550         }
551
552         /* Hmm: permutation needed */
553         DB((dbg, LEVEL_2, "\n%+F needs permutation: from\n", block));
554         DEBUG_ONLY(x87_dump_stack(state));
555         DB((dbg, LEVEL_2, "                  to\n"));
556         DEBUG_ONLY(x87_dump_stack(dst_state));
557
558
559 #ifdef DEBUG_libfirm
560         DB((dbg, LEVEL_2, "Need %d cycles\n", n_cycles));
561         for (ri = 0; ri < n_cycles; ++ri) {
562                 DB((dbg, LEVEL_2, " Ring %d:\n ", ri));
563                 for (k = 0; cycle_idx[ri][k] != -1; ++k)
564                         DB((dbg, LEVEL_2, " st%d ->", cycle_idx[ri][k]));
565                 DB((dbg, LEVEL_2, "\n"));
566         }
567 #endif
568
569         after = NULL;
570
571         /*
572          * Find the place node must be insert.
573          * We have only one successor block, so the last instruction should
574          * be a jump.
575          */
576         before = sched_last(block);
577         assert(is_cfop(before));
578
579         /* now do the permutations */
580         for (ri = 0; ri < n_cycles; ++ri) {
581                 if ((cycles[ri] & 1) == 0) {
582                         /* this cycle does not include the tos */
583                         fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block);
584                         if (after)
585                                 sched_add_after(after, fxch);
586                         else
587                                 sched_add_before(before, fxch);
588                         after = fxch;
589                 }
590                 for (k = 1; cycle_idx[ri][k] != -1; ++k) {
591                         fxch = x87_fxch_shuffle(state, cycle_idx[ri][k], block);
592                         if (after)
593                                 sched_add_after(after, fxch);
594                         else
595                                 sched_add_before(before, fxch);
596                         after = fxch;
597                 }
598                 if ((cycles[ri] & 1) == 0) {
599                         /* this cycle does not include the tos */
600                         fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block);
601                         sched_add_after(after, fxch);
602                 }
603         }
604         return state;
605 }  /* x87_shuffle */
606
607 /**
608  * Create a fxch node before another node.
609  *
610  * @param state   the x87 state
611  * @param n       the node after the fxch
612  * @param pos     exchange st(pos) with st(0)
613  *
614  * @return the fxch
615  */
616 static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos)
617 {
618         ir_node         *fxch;
619         ia32_x87_attr_t *attr;
620         ir_graph        *irg = get_irn_irg(n);
621         ir_node         *block = get_nodes_block(n);
622
623         x87_fxch(state, pos);
624
625         fxch = new_rd_ia32_fxch(NULL, irg, block);
626         attr = get_ia32_x87_attr(fxch);
627         attr->x87[0] = &ia32_st_regs[pos];
628         attr->x87[2] = &ia32_st_regs[0];
629
630         keep_alive(fxch);
631
632         sched_add_before(n, fxch);
633         DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fxch), attr->x87[0]->name, attr->x87[2]->name));
634         return fxch;
635 }  /* x87_create_fxch */
636
637 /**
638  * Create a fpush before node n.
639  *
640  * @param state     the x87 state
641  * @param n         the node after the fpush
642  * @param pos       push st(pos) on stack
643  * @param op_idx    replace input op_idx of n with the fpush result
644  */
645 static void x87_create_fpush(x87_state *state, ir_node *n, int pos, int op_idx) {
646         ir_node               *fpush, *pred = get_irn_n(n, op_idx);
647         ia32_x87_attr_t       *attr;
648         const arch_register_t *out = x87_get_irn_register(state->sim, pred);
649
650         x87_push_dbl(state, arch_register_get_index(out), pred);
651
652         fpush = new_rd_ia32_fpush(NULL, get_irn_irg(n), get_nodes_block(n));
653         attr  = get_ia32_x87_attr(fpush);
654         attr->x87[0] = &ia32_st_regs[pos];
655         attr->x87[2] = &ia32_st_regs[0];
656
657         keep_alive(fpush);
658         sched_add_before(n, fpush);
659
660         DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fpush), attr->x87[0]->name, attr->x87[2]->name));
661 }  /* x87_create_fpush */
662
663 /**
664  * Create a fpop before node n.
665  *
666  * @param state   the x87 state
667  * @param n       the node after the fpop
668  * @param num     pop 1 or 2 values
669  *
670  * @return the fpop node
671  */
672 static ir_node *x87_create_fpop(x87_state *state, ir_node *n, int num)
673 {
674         ir_node *fpop;
675         ia32_x87_attr_t *attr;
676         int cpu = state->sim->isa->opt_arch;
677
678         while (num > 0) {
679                 x87_pop(state);
680                 if (ARCH_ATHLON(cpu))
681                         fpop = new_rd_ia32_ffreep(NULL, get_irn_irg(n), get_nodes_block(n));
682                 else
683                         fpop = new_rd_ia32_fpop(NULL, get_irn_irg(n), get_nodes_block(n));
684                 attr = get_ia32_x87_attr(fpop);
685                 attr->x87[0] = &ia32_st_regs[0];
686                 attr->x87[1] = &ia32_st_regs[0];
687                 attr->x87[2] = &ia32_st_regs[0];
688
689                 keep_alive(fpop);
690                 sched_add_before(n, fpop);
691                 DB((dbg, LEVEL_1, "<<< %s %s\n", get_irn_opname(fpop), attr->x87[0]->name));
692
693                 --num;
694         }
695         return fpop;
696 }  /* x87_create_fpop */
697
698 /**
699  * Creates an fldz before node n
700  *
701  * @param state   the x87 state
702  * @param n       the node after the fldz
703  *
704  * @return the fldz node
705  */
706 static ir_node *x87_create_fldz(x87_state *state, ir_node *n, int regidx) {
707         ir_graph *irg = get_irn_irg(n);
708         ir_node *block = get_nodes_block(n);
709         ir_node *fldz;
710
711         fldz = new_rd_ia32_fldz(NULL, irg, block, mode_E);
712
713         sched_add_before(n, fldz);
714         DB((dbg, LEVEL_1, "<<< %s\n", get_irn_opname(fldz)));
715         keep_alive(fldz);
716
717         x87_push(state, regidx, fldz);
718
719         return fldz;
720 }
721
722 /* --------------------------------- liveness ------------------------------------------ */
723
724 /**
725  * The liveness transfer function.
726  * Updates a live set over a single step from a given node to its predecessor.
727  * Everything defined at the node is removed from the set, the uses of the node get inserted.
728  *
729  * @param sim      The simulator handle.
730  * @param irn      The node at which liveness should be computed.
731  * @param live     The bitset of registers live before @p irn. This set gets modified by updating it to
732  *                 the registers live after irn.
733  *
734  * @return The live bitset.
735  */
736 static vfp_liveness vfp_liveness_transfer(x87_simulator *sim, ir_node *irn, vfp_liveness live)
737 {
738         int i, n;
739         const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
740         const arch_env_t *arch_env = sim->arch_env;
741
742         if (get_irn_mode(irn) == mode_T) {
743                 const ir_edge_t *edge;
744
745                 foreach_out_edge(irn, edge) {
746                         ir_node *proj = get_edge_src_irn(edge);
747
748                         if (arch_irn_consider_in_reg_alloc(arch_env, cls, proj)) {
749                                 const arch_register_t *reg = x87_get_irn_register(sim, proj);
750                                 live &= ~(1 << arch_register_get_index(reg));
751                         }
752                 }
753         }
754
755         if (arch_irn_consider_in_reg_alloc(arch_env, cls, irn)) {
756                 const arch_register_t *reg = x87_get_irn_register(sim, irn);
757                 live &= ~(1 << arch_register_get_index(reg));
758         }
759
760         for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
761                 ir_node *op = get_irn_n(irn, i);
762
763                 if (mode_is_float(get_irn_mode(op)) && arch_irn_consider_in_reg_alloc(arch_env, cls, op)) {
764                         const arch_register_t *reg = x87_get_irn_register(sim, op);
765                         live |= 1 << arch_register_get_index(reg);
766                 }
767         }
768         return live;
769 }  /* vfp_liveness_transfer */
770
771 /**
772  * Put all live virtual registers at the end of a block into a bitset.
773  *
774  * @param sim      the simulator handle
775  * @param lv       the liveness information
776  * @param bl       the block
777  *
778  * @return The live bitset at the end of this block
779  */
780 static vfp_liveness vfp_liveness_end_of_block(x87_simulator *sim, const ir_node *block)
781 {
782         int i;
783         vfp_liveness live = 0;
784         const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
785         const arch_env_t *arch_env = sim->arch_env;
786         const be_lv_t *lv = sim->lv;
787
788         be_lv_foreach(lv, block, be_lv_state_end, i) {
789                 const arch_register_t *reg;
790                 const ir_node *node = be_lv_get_irn(lv, block, i);
791                 if (!arch_irn_consider_in_reg_alloc(arch_env, cls, node))
792                         continue;
793
794                 reg = x87_get_irn_register(sim, node);
795                 live |= 1 << arch_register_get_index(reg);
796         }
797
798         return live;
799 }  /* vfp_liveness_end_of_block */
800
801 /** get the register mask from an arch_register */
802 #define REGMASK(reg)    (1 << (arch_register_get_index(reg)))
803
804 /**
805  * Return a bitset of argument registers which are live at the end of a node.
806  *
807  * @param sim    the simulator handle
808  * @param pos    the node
809  * @param kill   kill mask for the output registers
810  *
811  * @return The live bitset.
812  */
813 static unsigned vfp_live_args_after(x87_simulator *sim, const ir_node *pos, unsigned kill)
814 {
815         unsigned idx = get_irn_idx(pos);
816
817         assert(idx < sim->n_idx);
818         return sim->live[idx] & ~kill;
819 }  /* vfp_live_args_after */
820
821 /**
822  * Calculate the liveness for a whole block and cache it.
823  *
824  * @param sim   the simulator handle
825  * @param lv    the liveness handle
826  * @param block the block
827  */
828 static void update_liveness(x87_simulator *sim, ir_node *block) {
829         vfp_liveness live = vfp_liveness_end_of_block(sim, block);
830         unsigned idx;
831         ir_node *irn;
832
833         /* now iterate through the block backward and cache the results */
834         sched_foreach_reverse(block, irn) {
835                 /* stop at the first Phi: this produces the live-in */
836                 if (is_Phi(irn))
837                         break;
838
839                 idx = get_irn_idx(irn);
840                 sim->live[idx] = live;
841
842                 live = vfp_liveness_transfer(sim, irn, live);
843         }
844         idx = get_irn_idx(block);
845         sim->live[idx] = live;
846 }  /* update_liveness */
847
848 /**
849  * Returns true if a register is live in a set.
850  *
851  * @param reg_idx  the vfp register index
852  * @param live     a live bitset
853  */
854 #define is_vfp_live(reg_idx, live) ((live) & (1 << (reg_idx)))
855
856 #ifdef DEBUG_libfirm
857 /**
858  * Dump liveness info.
859  *
860  * @param live  the live bitset
861  */
862 static void vfp_dump_live(vfp_liveness live) {
863         int i;
864
865         DB((dbg, LEVEL_2, "Live after: "));
866         for (i = 0; i < 8; ++i) {
867                 if (live & (1 << i)) {
868                         DB((dbg, LEVEL_2, "vf%d ", i));
869                 }
870         }
871         DB((dbg, LEVEL_2, "\n"));
872 }  /* vfp_dump_live */
873 #endif /* DEBUG_libfirm */
874
875 /* --------------------------------- simulators ---------------------------------------- */
876
877 #define XCHG(a, b) do { int t = (a); (a) = (b); (b) = t; } while (0)
878
879 /* Pseudocode:
880
881
882
883
884
885
886 */
887
888 /**
889  * Simulate a virtual binop.
890  *
891  * @param state  the x87 state
892  * @param n      the node that should be simulated (and patched)
893  * @param tmpl   the template containing the 4 possible x87 opcodes
894  *
895  * @return NO_NODE_ADDED
896  */
897 static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
898         int op2_idx = 0, op1_idx;
899         int out_idx, do_pop = 0;
900         ia32_x87_attr_t *attr;
901         ir_node *patched_insn;
902         ir_op *dst;
903         x87_simulator         *sim     = state->sim;
904         ir_node               *op1     = get_irn_n(n, n_ia32_binary_left);
905         ir_node               *op2     = get_irn_n(n, n_ia32_binary_right);
906         const arch_register_t *op1_reg = x87_get_irn_register(sim, op1);
907         const arch_register_t *op2_reg = x87_get_irn_register(sim, op2);
908         const arch_register_t *out     = x87_get_irn_register(sim, n);
909         int reg_index_1                = arch_register_get_index(op1_reg);
910         int reg_index_2                = arch_register_get_index(op2_reg);
911         vfp_liveness           live    = vfp_live_args_after(sim, n, REGMASK(out));
912         int                    op1_live_after;
913         int                    op2_live_after;
914
915         DB((dbg, LEVEL_1, ">>> %+F %s, %s -> %s\n", n,
916                 arch_register_get_name(op1_reg), arch_register_get_name(op2_reg),
917                 arch_register_get_name(out)));
918         DEBUG_ONLY(vfp_dump_live(live));
919         DB((dbg, LEVEL_1, "Stack before: "));
920         DEBUG_ONLY(x87_dump_stack(state));
921
922         if(reg_index_1 == REG_VFP_UKNWN) {
923                 op1_idx        = 0;
924                 op1_live_after = 1;
925         } else {
926                 op1_idx = x87_on_stack(state, reg_index_1);
927                 assert(op1_idx >= 0);
928                 op1_live_after = is_vfp_live(arch_register_get_index(op1_reg), live);
929         }
930
931         if (reg_index_2 != REG_VFP_NOREG) {
932                 if(reg_index_2 == REG_VFP_UKNWN) {
933                         op2_idx        = 0;
934                         op2_live_after = 1;
935                 } else {
936                         /* second operand is a vfp register */
937                         op2_idx = x87_on_stack(state, reg_index_2);
938                         assert(op2_idx >= 0);
939                         op2_live_after
940                                 = is_vfp_live(arch_register_get_index(op2_reg), live);
941                 }
942
943                 if (op2_live_after) {
944                         /* Second operand is live. */
945
946                         if (op1_live_after) {
947                                 /* Both operands are live: push the first one.
948                                    This works even for op1 == op2. */
949                                 x87_create_fpush(state, n, op1_idx, n_ia32_binary_right);
950                                 /* now do fxxx (tos=tos X op) */
951                                 op1_idx = 0;
952                                 op2_idx += 1;
953                                 out_idx = 0;
954                                 dst = tmpl->normal_op;
955                         } else {
956                                 /* Second live, first operand is dead here, bring it to tos. */
957                                 if (op1_idx != 0) {
958                                         x87_create_fxch(state, n, op1_idx);
959                                         if (op2_idx == 0)
960                                                 op2_idx = op1_idx;
961                                         op1_idx = 0;
962                                 }
963                                 /* now do fxxx (tos=tos X op) */
964                                 out_idx = 0;
965                                 dst = tmpl->normal_op;
966                         }
967                 } else {
968                         /* Second operand is dead. */
969                         if (op1_live_after) {
970                                 /* First operand is live: bring second to tos. */
971                                 if (op2_idx != 0) {
972                                         x87_create_fxch(state, n, op2_idx);
973                                         if (op1_idx == 0)
974                                                 op1_idx = op2_idx;
975                                         op2_idx = 0;
976                                 }
977                                 /* now do fxxxr (tos = op X tos) */
978                                 out_idx = 0;
979                                 dst = tmpl->reverse_op;
980                         } else {
981                                 /* Both operands are dead here, pop them from the stack. */
982                                 if (op2_idx == 0) {
983                                         if (op1_idx == 0) {
984                                                 /* Both are identically and on tos, no pop needed. */
985                                                 /* here fxxx (tos = tos X tos) */
986                                                 dst = tmpl->normal_op;
987                                                 out_idx = 0;
988                                         } else {
989                                                 /* now do fxxxp (op = op X tos, pop) */
990                                                 dst = tmpl->normal_pop_op;
991                                                 do_pop = 1;
992                                                 out_idx = op1_idx;
993                                         }
994                                 } else if (op1_idx == 0) {
995                                         assert(op1_idx != op2_idx);
996                                         /* now do fxxxrp (op = tos X op, pop) */
997                                         dst = tmpl->reverse_pop_op;
998                                         do_pop = 1;
999                                         out_idx = op2_idx;
1000                                 } else {
1001                                         /* Bring the second on top. */
1002                                         x87_create_fxch(state, n, op2_idx);
1003                                         if (op1_idx == op2_idx) {
1004                                                 /* Both are identically and on tos now, no pop needed. */
1005                                                 op1_idx = 0;
1006                                                 op2_idx = 0;
1007                                                 /* use fxxx (tos = tos X tos) */
1008                                                 dst = tmpl->normal_op;
1009                                                 out_idx = 0;
1010                                         } else {
1011                                                 /* op2 is on tos now */
1012                                                 op2_idx = 0;
1013                                                 /* use fxxxp (op = op X tos, pop) */
1014                                                 dst = tmpl->normal_pop_op;
1015                                                 out_idx = op1_idx;
1016                                                 do_pop = 1;
1017                                         }
1018                                 }
1019                         }
1020                 }
1021         } else {
1022                 /* second operand is an address mode */
1023                 if (op1_live_after) {
1024                         /* first operand is live: push it here */
1025                         x87_create_fpush(state, n, op1_idx, n_ia32_binary_left);
1026                         op1_idx = 0;
1027                         /* use fxxx (tos = tos X mem) */
1028                         dst = tmpl->normal_op;
1029                         out_idx = 0;
1030                 } else {
1031                         /* first operand is dead: bring it to tos */
1032                         if (op1_idx != 0) {
1033                                 x87_create_fxch(state, n, op1_idx);
1034                                 op1_idx = 0;
1035                         }
1036
1037                         /* use fxxxp (tos = tos X mem) */
1038                         dst = tmpl->normal_op;
1039                         out_idx = 0;
1040                 }
1041         }
1042
1043         patched_insn = x87_patch_insn(n, dst);
1044         x87_set_st(state, arch_register_get_index(out), patched_insn, out_idx);
1045         if (do_pop) {
1046                 x87_pop(state);
1047         }
1048
1049         /* patch the operation */
1050         attr = get_ia32_x87_attr(n);
1051         attr->x87[0] = op1_reg = &ia32_st_regs[op1_idx];
1052         if (reg_index_2 != REG_VFP_NOREG) {
1053                 attr->x87[1] = op2_reg = &ia32_st_regs[op2_idx];
1054         }
1055         attr->x87[2] = out = &ia32_st_regs[out_idx];
1056
1057         if (reg_index_2 != REG_VFP_NOREG) {
1058                 DB((dbg, LEVEL_1, "<<< %s %s, %s -> %s\n", get_irn_opname(n),
1059                         arch_register_get_name(op1_reg), arch_register_get_name(op2_reg),
1060                         arch_register_get_name(out)));
1061         } else {
1062                 DB((dbg, LEVEL_1, "<<< %s %s, [AM] -> %s\n", get_irn_opname(n),
1063                         arch_register_get_name(op1_reg),
1064                         arch_register_get_name(out)));
1065         }
1066
1067         return NO_NODE_ADDED;
1068 }  /* sim_binop */
1069
1070 /**
1071  * Simulate a virtual Unop.
1072  *
1073  * @param state  the x87 state
1074  * @param n      the node that should be simulated (and patched)
1075  * @param op     the x87 opcode that will replace n's opcode
1076  *
1077  * @return NO_NODE_ADDED
1078  */
1079 static int sim_unop(x87_state *state, ir_node *n, ir_op *op) {
1080         int op1_idx, out_idx;
1081         x87_simulator         *sim = state->sim;
1082         const arch_register_t *op1 = x87_get_irn_register(sim, get_irn_n(n, UNOP_IDX));
1083         const arch_register_t *out = x87_get_irn_register(sim, n);
1084         ia32_x87_attr_t *attr;
1085         unsigned live = vfp_live_args_after(sim, n, REGMASK(out));
1086
1087         DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, out->name));
1088         DEBUG_ONLY(vfp_dump_live(live));
1089
1090         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1091
1092         if (is_vfp_live(arch_register_get_index(op1), live)) {
1093                 /* push the operand here */
1094                 x87_create_fpush(state, n, op1_idx, UNOP_IDX);
1095                 op1_idx = 0;
1096         }
1097         else {
1098                 /* operand is dead, bring it to tos */
1099                 if (op1_idx != 0) {
1100                         x87_create_fxch(state, n, op1_idx);
1101                         op1_idx = 0;
1102                 }
1103         }
1104
1105         x87_set_tos(state, arch_register_get_index(out), x87_patch_insn(n, op));
1106         out_idx = 0;
1107         attr = get_ia32_x87_attr(n);
1108         attr->x87[0] = op1 = &ia32_st_regs[0];
1109         attr->x87[2] = out = &ia32_st_regs[0];
1110         DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), out->name));
1111
1112         return NO_NODE_ADDED;
1113 }  /* sim_unop */
1114
1115 /**
1116  * Simulate a virtual Load instruction.
1117  *
1118  * @param state  the x87 state
1119  * @param n      the node that should be simulated (and patched)
1120  * @param op     the x87 opcode that will replace n's opcode
1121  *
1122  * @return NO_NODE_ADDED
1123  */
1124 static int sim_load(x87_state *state, ir_node *n, ir_op *op) {
1125         const arch_register_t *out = x87_get_irn_register(state->sim, n);
1126         ia32_x87_attr_t *attr;
1127
1128         DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, arch_register_get_name(out)));
1129         x87_push(state, arch_register_get_index(out), x87_patch_insn(n, op));
1130         assert(out == x87_get_irn_register(state->sim, n));
1131         attr = get_ia32_x87_attr(n);
1132         attr->x87[2] = out = &ia32_st_regs[0];
1133         DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
1134
1135         return NO_NODE_ADDED;
1136 }  /* sim_load */
1137
1138 /**
1139  * Rewire all users of @p old_val to @new_val iff they are scheduled after @p store.
1140  *
1141  * @param store   The store
1142  * @param old_val The former value
1143  * @param new_val The new value
1144  */
1145 static void collect_and_rewire_users(ir_node *store, ir_node *old_val, ir_node *new_val) {
1146         const ir_edge_t *edge, *ne;
1147
1148         foreach_out_edge_safe(old_val, edge, ne) {
1149                 ir_node *user = get_edge_src_irn(edge);
1150
1151                 if (! user || user == store)
1152                         continue;
1153
1154                 /* if the user is scheduled after the store: rewire */
1155                 if (sched_is_scheduled(user) && sched_comes_after(store, user)) {
1156                         int i;
1157                         /* find the input of the user pointing to the old value */
1158                         for (i = get_irn_arity(user) - 1; i >= 0; i--) {
1159                                 if (get_irn_n(user, i) == old_val)
1160                                         set_irn_n(user, i, new_val);
1161                         }
1162                 }
1163         }
1164 }  /* collect_and_rewire_users */
1165
1166 /**
1167  * Simulate a virtual Store.
1168  *
1169  * @param state  the x87 state
1170  * @param n      the node that should be simulated (and patched)
1171  * @param op     the x87 store opcode
1172  * @param op_p   the x87 store and pop opcode
1173  */
1174 static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) {
1175         x87_simulator         *sim = state->sim;
1176         ir_node               *val = get_irn_n(n, n_ia32_vfst_val);
1177         const arch_register_t *op2 = x87_get_irn_register(sim, val);
1178         unsigned              live = vfp_live_args_after(sim, n, 0);
1179         int                   insn = NO_NODE_ADDED;
1180         ia32_x87_attr_t *attr;
1181         int op2_reg_idx, op2_idx, depth;
1182         int live_after_node;
1183         ir_mode *mode;
1184
1185         op2_reg_idx = arch_register_get_index(op2);
1186         if (op2_reg_idx == REG_VFP_UKNWN) {
1187                 /* just take any value from stack */
1188                 if(state->depth > 0) {
1189                         op2_idx = 0;
1190                         DEBUG_ONLY(op2 = NULL);
1191                         live_after_node = 1;
1192                 } else {
1193                         /* produce a new value which we will consume immediately */
1194                         x87_create_fldz(state, n, op2_reg_idx);
1195                         live_after_node = 0;
1196                         op2_idx = x87_on_stack(state, op2_reg_idx);
1197                         assert(op2_idx >= 0);
1198                 }
1199         } else {
1200                 op2_idx = x87_on_stack(state, op2_reg_idx);
1201                 live_after_node = is_vfp_live(arch_register_get_index(op2), live);
1202                 DB((dbg, LEVEL_1, ">>> %+F %s ->\n", n, arch_register_get_name(op2)));
1203                 assert(op2_idx >= 0);
1204         }
1205
1206         mode  = get_ia32_ls_mode(n);
1207         depth = x87_get_depth(state);
1208
1209         if (live_after_node) {
1210                 /*
1211                         Problem: fst doesn't support mode_E (spills), only fstp does
1212                         Solution:
1213                                 - stack not full: push value and fstp
1214                                 - stack full: fstp value and load again
1215                 */
1216                 if (mode == mode_E || mode == mode_Ls) {
1217                         if (depth < N_x87_REGS) {
1218                                 /* ok, we have a free register: push + fstp */
1219                                 x87_create_fpush(state, n, op2_idx, n_ia32_vfst_val);
1220                                 x87_pop(state);
1221                                 x87_patch_insn(n, op_p);
1222                         } else {
1223                                 ir_node  *vfld, *mem, *block, *rproj, *mproj;
1224                                 ir_graph *irg;
1225
1226                                 /* stack full here: need fstp + load */
1227                                 x87_pop(state);
1228                                 x87_patch_insn(n, op_p);
1229
1230                                 block = get_nodes_block(n);
1231                                 irg   = get_irn_irg(n);
1232                                 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));
1233
1234                                 /* copy all attributes */
1235                                 set_ia32_frame_ent(vfld, get_ia32_frame_ent(n));
1236                                 if (is_ia32_use_frame(n))
1237                                         set_ia32_use_frame(vfld);
1238                                 set_ia32_op_type(vfld, ia32_am_Source);
1239                                 add_ia32_am_offs_int(vfld, get_ia32_am_offs_int(n));
1240                                 set_ia32_am_sc(vfld, get_ia32_am_sc(n));
1241                                 set_ia32_ls_mode(vfld, get_ia32_ls_mode(n));
1242
1243                                 rproj = new_r_Proj(irg, block, vfld, get_ia32_ls_mode(vfld), pn_ia32_vfld_res);
1244                                 mproj = new_r_Proj(irg, block, vfld, mode_M, pn_ia32_vfld_M);
1245                                 mem   = get_irn_Proj_for_mode(n, mode_M);
1246
1247                                 assert(mem && "Store memory not found");
1248
1249                                 arch_set_irn_register(sim->arch_env, rproj, op2);
1250
1251                                 /* reroute all former users of the store memory to the load memory */
1252                                 edges_reroute(mem, mproj, irg);
1253                                 /* set the memory input of the load to the store memory */
1254                                 set_irn_n(vfld, n_ia32_vfld_mem, mem);
1255
1256                                 sched_add_after(n, vfld);
1257                                 sched_add_after(vfld, rproj);
1258
1259                                 /* rewire all users, scheduled after the store, to the loaded value */
1260                                 collect_and_rewire_users(n, val, rproj);
1261
1262                                 insn = NODE_ADDED;
1263                         }
1264                 } else {
1265                         /* we can only store the tos to memory */
1266                         if (op2_idx != 0)
1267                                 x87_create_fxch(state, n, op2_idx);
1268
1269                         /* mode != mode_E -> use normal fst */
1270                         x87_patch_insn(n, op);
1271                 }
1272         } else {
1273                 /* we can only store the tos to memory */
1274                 if (op2_idx != 0)
1275                         x87_create_fxch(state, n, op2_idx);
1276
1277                 x87_pop(state);
1278                 x87_patch_insn(n, op_p);
1279         }
1280
1281         attr = get_ia32_x87_attr(n);
1282         attr->x87[1] = op2 = &ia32_st_regs[0];
1283         DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
1284
1285         return insn;
1286 }  /* sim_store */
1287
1288 #define _GEN_BINOP(op, rev) \
1289 static int sim_##op(x87_state *state, ir_node *n) { \
1290         exchange_tmpl tmpl = { op_ia32_##op, op_ia32_##rev, op_ia32_##op##p, op_ia32_##rev##p }; \
1291         return sim_binop(state, n, &tmpl); \
1292 }
1293
1294 #define GEN_BINOP(op)   _GEN_BINOP(op, op)
1295 #define GEN_BINOPR(op)  _GEN_BINOP(op, op##r)
1296
1297 #define GEN_LOAD2(op, nop) \
1298 static int sim_##op(x87_state *state, ir_node *n) { \
1299         return sim_load(state, n, op_ia32_##nop); \
1300 }
1301
1302 #define GEN_LOAD(op)    GEN_LOAD2(op, op)
1303
1304 #define GEN_UNOP(op) \
1305 static int sim_##op(x87_state *state, ir_node *n) { \
1306         return sim_unop(state, n, op_ia32_##op); \
1307 }
1308
1309 #define GEN_STORE(op) \
1310 static int sim_##op(x87_state *state, ir_node *n) { \
1311         return sim_store(state, n, op_ia32_##op, op_ia32_##op##p); \
1312 }
1313
1314 /* all stubs */
1315 GEN_BINOP(fadd)
1316 GEN_BINOPR(fsub)
1317 GEN_BINOP(fmul)
1318 GEN_BINOPR(fdiv)
1319 GEN_BINOP(fprem)
1320
1321 GEN_UNOP(fabs)
1322 GEN_UNOP(fchs)
1323
1324 GEN_LOAD(fld)
1325 GEN_LOAD(fild)
1326 GEN_LOAD(fldz)
1327 GEN_LOAD(fld1)
1328
1329 GEN_STORE(fst)
1330 GEN_STORE(fist)
1331
1332 static int sim_FtstFnstsw(x87_state *state, ir_node *n) {
1333         x87_simulator         *sim         = state->sim;
1334         ia32_x87_attr_t       *attr        = get_ia32_x87_attr(n);
1335         ir_node               *op1_node    = get_irn_n(n, n_ia32_vFtstFnstsw_left);
1336         const arch_register_t *reg1        = x87_get_irn_register(sim, op1_node);
1337         int                    reg_index_1 = arch_register_get_index(reg1);
1338         int                    op1_idx     = x87_on_stack(state, reg_index_1);
1339         unsigned               live        = vfp_live_args_after(sim, n, 0);
1340
1341         DB((dbg, LEVEL_1, ">>> %+F %s\n", n, arch_register_get_name(reg1)));
1342         DEBUG_ONLY(vfp_dump_live(live));
1343         DB((dbg, LEVEL_1, "Stack before: "));
1344         DEBUG_ONLY(x87_dump_stack(state));
1345         assert(op1_idx >= 0);
1346
1347         if (op1_idx != 0) {
1348                 /* bring the value to tos */
1349                 x87_create_fxch(state, n, op1_idx);
1350                 op1_idx = 0;
1351         }
1352
1353         /* patch the operation */
1354         x87_patch_insn(n, op_ia32_FtstFnstsw);
1355         reg1 = &ia32_st_regs[op1_idx];
1356         attr->x87[0] = reg1;
1357         attr->x87[1] = NULL;
1358         attr->x87[2] = NULL;
1359
1360         if(!is_vfp_live(reg_index_1, live)) {
1361                 x87_create_fpop(state, sched_next(n), 1);
1362                 return NODE_ADDED;
1363         }
1364
1365         return NO_NODE_ADDED;
1366 }
1367
1368 /**
1369  * @param state  the x87 state
1370  * @param n      the node that should be simulated (and patched)
1371  */
1372 static int sim_Fucom(x87_state *state, ir_node *n) {
1373         int op1_idx;
1374         int op2_idx = -1;
1375         ia32_x87_attr_t *attr = get_ia32_x87_attr(n);
1376         ir_op *dst;
1377         x87_simulator         *sim = state->sim;
1378         ir_node               *op1_node = get_irn_n(n, n_ia32_vFucomFnstsw_left);
1379         ir_node               *op2_node = get_irn_n(n, n_ia32_vFucomFnstsw_right);
1380         const arch_register_t *op1      = x87_get_irn_register(sim, op1_node);
1381         const arch_register_t *op2      = x87_get_irn_register(sim, op2_node);
1382         int reg_index_1 = arch_register_get_index(op1);
1383         int reg_index_2 = arch_register_get_index(op2);
1384         unsigned live = vfp_live_args_after(sim, n, 0);
1385         int                    flipped  = attr->attr.data.cmp_flipped;
1386         int xchg = 0;
1387         int pops = 0;
1388         int node_added = NO_NODE_ADDED;
1389
1390         DB((dbg, LEVEL_1, ">>> %+F %s, %s\n", n,
1391                 arch_register_get_name(op1), arch_register_get_name(op2)));
1392         DEBUG_ONLY(vfp_dump_live(live));
1393         DB((dbg, LEVEL_1, "Stack before: "));
1394         DEBUG_ONLY(x87_dump_stack(state));
1395
1396         op1_idx = x87_on_stack(state, reg_index_1);
1397         assert(op1_idx >= 0);
1398
1399         /* BEWARE: check for comp a,a cases, they might happen */
1400         if (reg_index_2 != REG_VFP_NOREG) {
1401                 /* second operand is a vfp register */
1402                 op2_idx = x87_on_stack(state, reg_index_2);
1403                 assert(op2_idx >= 0);
1404
1405                 if (is_vfp_live(reg_index_2, live)) {
1406                         /* second operand is live */
1407
1408                         if (is_vfp_live(reg_index_1, live)) {
1409                                 /* both operands are live */
1410
1411                                 if (op1_idx == 0) {
1412                                         /* res = tos X op */
1413                                 } else if (op2_idx == 0) {
1414                                         /* res = op X tos */
1415                                         flipped = !flipped;
1416                                         xchg    = 1;
1417                                 } else {
1418                                         /* bring the first one to tos */
1419                                         x87_create_fxch(state, n, op1_idx);
1420                                         if (op2_idx == 0)
1421                                                 op2_idx = op1_idx;
1422                                         op1_idx = 0;
1423                                         /* res = tos X op */
1424                                 }
1425                         } else {
1426                                 /* second live, first operand is dead here, bring it to tos.
1427                                    This means further, op1_idx != op2_idx. */
1428                                 assert(op1_idx != op2_idx);
1429                                 if (op1_idx != 0) {
1430                                         x87_create_fxch(state, n, op1_idx);
1431                                         if (op2_idx == 0)
1432                                                 op2_idx = op1_idx;
1433                                         op1_idx = 0;
1434                                 }
1435                                 /* res = tos X op, pop */
1436                                 pops = 1;
1437                         }
1438                 } else {
1439                         /* second operand is dead */
1440                         if (is_vfp_live(reg_index_1, live)) {
1441                                 /* first operand is live: bring second to tos.
1442                                    This means further, op1_idx != op2_idx. */
1443                                 assert(op1_idx != op2_idx);
1444                                 if (op2_idx != 0) {
1445                                         x87_create_fxch(state, n, op2_idx);
1446                                         if (op1_idx == 0)
1447                                                 op1_idx = op2_idx;
1448                                         op2_idx = 0;
1449                                 }
1450                                 /* res = op X tos, pop */
1451                                 pops    = 1;
1452                                 flipped = !flipped;
1453                                 xchg    = 1;
1454                         } else {
1455                                 /* both operands are dead here, check first for identity. */
1456                                 if (op1_idx == op2_idx) {
1457                                         /* identically, one pop needed */
1458                                         if (op1_idx != 0) {
1459                                                 x87_create_fxch(state, n, op1_idx);
1460                                                 op1_idx = 0;
1461                                                 op2_idx = 0;
1462                                         }
1463                                         /* res = tos X op, pop */
1464                                         pops    = 1;
1465                                 }
1466                                 /* different, move them to st and st(1) and pop both.
1467                                    The tricky part is to get one into st(1).*/
1468                                 else if (op2_idx == 1) {
1469                                         /* good, second operand is already in the right place, move the first */
1470                                         if (op1_idx != 0) {
1471                                                 /* bring the first on top */
1472                                                 x87_create_fxch(state, n, op1_idx);
1473                                                 assert(op2_idx != 0);
1474                                                 op1_idx = 0;
1475                                         }
1476                                         /* res = tos X op, pop, pop */
1477                                         pops = 2;
1478                                 } else if (op1_idx == 1) {
1479                                         /* good, first operand is already in the right place, move the second */
1480                                         if (op2_idx != 0) {
1481                                                 /* bring the first on top */
1482                                                 x87_create_fxch(state, n, op2_idx);
1483                                                 assert(op1_idx != 0);
1484                                                 op2_idx = 0;
1485                                         }
1486                                         /* res = op X tos, pop, pop */
1487                                         flipped = !flipped;
1488                                         xchg    = 1;
1489                                         pops    = 2;
1490                                 } else {
1491                                         /* if one is already the TOS, we need two fxch */
1492                                         if (op1_idx == 0) {
1493                                                 /* first one is TOS, move to st(1) */
1494                                                 x87_create_fxch(state, n, 1);
1495                                                 assert(op2_idx != 1);
1496                                                 op1_idx = 1;
1497                                                 x87_create_fxch(state, n, op2_idx);
1498                                                 op2_idx = 0;
1499                                                 /* res = op X tos, pop, pop */
1500                                                 pops    = 2;
1501                                                 flipped = !flipped;
1502                                                 xchg    = 1;
1503                                         } else if (op2_idx == 0) {
1504                                                 /* second one is TOS, move to st(1) */
1505                                                 x87_create_fxch(state, n, 1);
1506                                                 assert(op1_idx != 1);
1507                                                 op2_idx = 1;
1508                                                 x87_create_fxch(state, n, op1_idx);
1509                                                 op1_idx = 0;
1510                                                 /* res = tos X op, pop, pop */
1511                                                 pops    = 2;
1512                                         } else {
1513                                                 /* none of them is either TOS or st(1), 3 fxch needed */
1514                                                 x87_create_fxch(state, n, op2_idx);
1515                                                 assert(op1_idx != 0);
1516                                                 x87_create_fxch(state, n, 1);
1517                                                 op2_idx = 1;
1518                                                 x87_create_fxch(state, n, op1_idx);
1519                                                 op1_idx = 0;
1520                                                 /* res = tos X op, pop, pop */
1521                                                 pops    = 2;
1522                                         }
1523                                 }
1524                         }
1525                 }
1526         } else {
1527                 /* second operand is an address mode */
1528                 if (is_vfp_live(reg_index_1, live)) {
1529                         /* first operand is live: bring it to TOS */
1530                         if (op1_idx != 0) {
1531                                 x87_create_fxch(state, n, op1_idx);
1532                                 op1_idx = 0;
1533                         }
1534                 } else {
1535                         /* first operand is dead: bring it to tos */
1536                         if (op1_idx != 0) {
1537                                 x87_create_fxch(state, n, op1_idx);
1538                                 op1_idx = 0;
1539                         }
1540                         pops = 1;
1541                 }
1542         }
1543
1544         /* patch the operation */
1545         if(is_ia32_vFucomFnstsw(n)) {
1546                 int i;
1547
1548                 switch(pops) {
1549                 case 0: dst = op_ia32_FucomFnstsw; break;
1550                 case 1: dst = op_ia32_FucompFnstsw; break;
1551                 case 2: dst = op_ia32_FucomppFnstsw; break;
1552                 default: panic("invalid popcount in sim_Fucom");
1553                 }
1554
1555                 for(i = 0; i < pops; ++i) {
1556                         x87_pop(state);
1557                 }
1558         } else if(is_ia32_vFucomi(n)) {
1559                 switch(pops) {
1560                 case 0: dst = op_ia32_Fucomi; break;
1561                 case 1: dst = op_ia32_Fucompi; x87_pop(state); break;
1562                 case 2:
1563                         dst = op_ia32_Fucompi;
1564                         x87_pop(state);
1565                         x87_create_fpop(state, sched_next(n), 1);
1566                         node_added = NODE_ADDED;
1567                         break;
1568                 default: panic("invalid popcount in sim_Fucom");
1569                 }
1570         } else {
1571                 panic("invalid operation %+F in sim_FucomFnstsw", n);
1572         }
1573
1574         x87_patch_insn(n, dst);
1575         if(xchg) {
1576                 int tmp = op1_idx;
1577                 op1_idx = op2_idx;
1578                 op2_idx = tmp;
1579         }
1580
1581         op1 = &ia32_st_regs[op1_idx];
1582         attr->x87[0] = op1;
1583         if (op2_idx >= 0) {
1584                 op2 = &ia32_st_regs[op2_idx];
1585                 attr->x87[1] = op2;
1586         }
1587         attr->x87[2] = NULL;
1588         attr->attr.data.cmp_flipped = flipped;
1589
1590         if (op2_idx >= 0)
1591                 DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(n),
1592                         arch_register_get_name(op1), arch_register_get_name(op2)));
1593         else
1594                 DB((dbg, LEVEL_1, "<<< %s %s, [AM]\n", get_irn_opname(n),
1595                         arch_register_get_name(op1)));
1596
1597         return node_added;
1598 }
1599
1600 static int sim_Keep(x87_state *state, ir_node *node)
1601 {
1602         const ir_node         *op;
1603         const arch_register_t *op_reg;
1604         int                    reg_id;
1605         int                    op_stack_idx;
1606         unsigned               live;
1607         int                    i, arity;
1608         int                    node_added = NO_NODE_ADDED;
1609
1610         DB((dbg, LEVEL_1, ">>> %+F\n", node));
1611
1612         arity = get_irn_arity(node);
1613         for(i = 0; i < arity; ++i) {
1614                 op      = get_irn_n(node, i);
1615                 op_reg  = arch_get_irn_register(state->sim->arch_env, op);
1616                 if(arch_register_get_class(op_reg) != &ia32_reg_classes[CLASS_ia32_vfp])
1617                         continue;
1618
1619                 reg_id = arch_register_get_index(op_reg);
1620                 live   = vfp_live_args_after(state->sim, node, 0);
1621
1622                 op_stack_idx = x87_on_stack(state, reg_id);
1623                 if(op_stack_idx >= 0 && !is_vfp_live(reg_id, live)) {
1624                         x87_create_fpop(state, sched_next(node), 1);
1625                         node_added = NODE_ADDED;
1626                 }
1627         }
1628
1629         DB((dbg, LEVEL_1, "Stack after: "));
1630         DEBUG_ONLY(x87_dump_stack(state));
1631
1632         return node_added;
1633 }
1634
1635 static
1636 void keep_float_node_alive(x87_state *state, ir_node *node)
1637 {
1638         ir_graph                    *irg;
1639         ir_node                     *block;
1640         ir_node                     *in[1];
1641         ir_node                     *keep;
1642         const arch_register_class_t *cls;
1643
1644         irg    = get_irn_irg(node);
1645         block  = get_nodes_block(node);
1646         cls    = arch_get_irn_reg_class(state->sim->arch_env, node, -1);
1647         in[0]  = node;
1648         keep   = be_new_Keep(cls, irg, block, 1, in);
1649
1650         assert(sched_is_scheduled(node));
1651         sched_add_after(node, keep);
1652 }
1653
1654 /**
1655  * Create a copy of a node. Recreate the node if it's a constant.
1656  *
1657  * @param state  the x87 state
1658  * @param n      the node to be copied
1659  *
1660  * @return the copy of n
1661  */
1662 static ir_node *create_Copy(x87_state *state, ir_node *n) {
1663         x87_simulator *sim = state->sim;
1664         ir_graph *irg = get_irn_irg(n);
1665         dbg_info *n_dbg = get_irn_dbg_info(n);
1666         ir_mode *mode = get_irn_mode(n);
1667         ir_node *block = get_nodes_block(n);
1668         ir_node *pred = get_irn_n(n, 0);
1669         ir_node *(*cnstr)(dbg_info *, ir_graph *, ir_node *, ir_mode *) = NULL;
1670         ir_node *res;
1671         const arch_register_t *out;
1672         const arch_register_t *op1;
1673         ia32_x87_attr_t *attr;
1674
1675         /* Do not copy constants, recreate them. */
1676         switch (get_ia32_irn_opcode(pred)) {
1677         case iro_ia32_Unknown_VFP:
1678         case iro_ia32_fldz:
1679                 cnstr = new_rd_ia32_fldz;
1680                 break;
1681         case iro_ia32_fld1:
1682                 cnstr = new_rd_ia32_fld1;
1683                 break;
1684         case iro_ia32_fldpi:
1685                 cnstr = new_rd_ia32_fldpi;
1686                 break;
1687         case iro_ia32_fldl2e:
1688                 cnstr = new_rd_ia32_fldl2e;
1689                 break;
1690         case iro_ia32_fldl2t:
1691                 cnstr = new_rd_ia32_fldl2t;
1692                 break;
1693         case iro_ia32_fldlg2:
1694                 cnstr = new_rd_ia32_fldlg2;
1695                 break;
1696         case iro_ia32_fldln2:
1697                 cnstr = new_rd_ia32_fldln2;
1698                 break;
1699         default:
1700                 break;
1701         }
1702
1703         out = x87_get_irn_register(sim, n);
1704         op1 = x87_get_irn_register(sim, pred);
1705
1706         if (cnstr != NULL) {
1707                 /* copy a constant */
1708                 res = (*cnstr)(n_dbg, irg, block, mode);
1709
1710                 x87_push(state, arch_register_get_index(out), res);
1711
1712                 attr = get_ia32_x87_attr(res);
1713                 attr->x87[2] = &ia32_st_regs[0];
1714         } else {
1715                 int op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1716
1717                 res = new_rd_ia32_fpushCopy(n_dbg, irg, block, pred, mode);
1718
1719                 x87_push(state, arch_register_get_index(out), res);
1720
1721                 attr = get_ia32_x87_attr(res);
1722                 attr->x87[0] = &ia32_st_regs[op1_idx];
1723                 attr->x87[2] = &ia32_st_regs[0];
1724         }
1725         arch_set_irn_register(sim->arch_env, res, out);
1726
1727         return res;
1728 }  /* create_Copy */
1729
1730 /**
1731  * Simulate a be_Copy.
1732  *
1733  * @param state  the x87 state
1734  * @param n      the node that should be simulated (and patched)
1735  *
1736  * @return NO_NODE_ADDED
1737  */
1738 static int sim_Copy(x87_state *state, ir_node *n) {
1739         x87_simulator               *sim = state->sim;
1740         ir_node                     *pred;
1741         const arch_register_t       *out;
1742         const arch_register_t       *op1;
1743         const arch_register_class_t *class;
1744         ir_node                     *node, *next;
1745         ia32_x87_attr_t             *attr;
1746         int                         op1_idx, out_idx;
1747         unsigned                    live;
1748
1749         class = arch_get_irn_reg_class(sim->arch_env, n, -1);
1750         if (class->regs != ia32_vfp_regs)
1751                 return 0;
1752
1753         pred = get_irn_n(n, 0);
1754         out  = x87_get_irn_register(sim, n);
1755         op1  = x87_get_irn_register(sim, pred);
1756         live = vfp_live_args_after(sim, n, REGMASK(out));
1757
1758         DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", n,
1759                 arch_register_get_name(op1), arch_register_get_name(out)));
1760         DEBUG_ONLY(vfp_dump_live(live));
1761
1762         /* handle the infamous unknown value */
1763         if (arch_register_get_index(op1) == REG_VFP_UKNWN) {
1764                 /* Operand is still live, a real copy. We need here an fpush that can
1765                    hold a a register, so use the fpushCopy or recreate constants */
1766                 node = create_Copy(state, n);
1767
1768                 assert(is_ia32_fldz(node));
1769                 next = sched_next(n);
1770                 sched_remove(n);
1771                 exchange(n, node);
1772                 sched_add_before(next, node);
1773
1774                 DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name,
1775                     arch_get_irn_register(sim->arch_env, node)->name));
1776                 return NO_NODE_ADDED;
1777         }
1778
1779         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1780
1781         if (is_vfp_live(arch_register_get_index(op1), live)) {
1782                 ir_node *pred = get_irn_n(n, 0);
1783
1784                 /* Operand is still live, a real copy. We need here an fpush that can
1785                    hold a a register, so use the fpushCopy or recreate constants */
1786                 node = create_Copy(state, n);
1787
1788                 /* We have to make sure the old value doesn't go dead (which can happen
1789                  * when we recreate constants). As the simulator expected that value in
1790                  * the pred blocks. This is unfortunate as removing it would save us 1
1791                  * instruction, but we would have to rerun all the simulation to get
1792                  * this correct...
1793                  */
1794                 next = sched_next(n);
1795                 sched_remove(n);
1796                 exchange(n, node);
1797                 sched_add_before(next, node);
1798
1799                 if(get_irn_n_edges(pred) == 0) {
1800                         keep_float_node_alive(state, pred);
1801                 }
1802
1803                 DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name,
1804                     arch_get_irn_register(sim->arch_env, node)->name));
1805         } else {
1806                 out_idx = x87_on_stack(state, arch_register_get_index(out));
1807
1808                 if (out_idx >= 0 && out_idx != op1_idx) {
1809                         /* Matze: out already on stack? how can this happen? */
1810                         assert(0);
1811
1812                         /* op1 must be killed and placed where out is */
1813                         if (out_idx == 0) {
1814                                 /* best case, simple remove and rename */
1815                                 x87_patch_insn(n, op_ia32_Pop);
1816                                 attr = get_ia32_x87_attr(n);
1817                                 attr->x87[0] = op1 = &ia32_st_regs[0];
1818
1819                                 x87_pop(state);
1820                                 x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
1821                         } else {
1822                                 /* move op1 to tos, store and pop it */
1823                                 if (op1_idx != 0) {
1824                                         x87_create_fxch(state, n, op1_idx);
1825                                         op1_idx = 0;
1826                                 }
1827                                 x87_patch_insn(n, op_ia32_Pop);
1828                                 attr = get_ia32_x87_attr(n);
1829                                 attr->x87[0] = op1 = &ia32_st_regs[out_idx];
1830
1831                                 x87_pop(state);
1832                                 x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
1833                         }
1834                         DB((dbg, LEVEL_1, "<<< %+F %s\n", n, op1->name));
1835                 } else {
1836                         /* just a virtual copy */
1837                         x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
1838                         /* don't remove the node to keep the verifier quiet :),
1839                            the emitter won't emit any code for the node */
1840 #if 0
1841                         sched_remove(n);
1842                         DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n)));
1843                         exchange(n, get_unop_op(n));
1844 #endif
1845                 }
1846         }
1847         return NO_NODE_ADDED;
1848 }  /* sim_Copy */
1849
1850 /**
1851  * Returns the result proj of the call
1852  */
1853 static ir_node *get_call_result_proj(ir_node *call) {
1854         const ir_edge_t *edge;
1855
1856         /* search the result proj */
1857         foreach_out_edge(call, edge) {
1858                 ir_node *proj = get_edge_src_irn(edge);
1859                 long pn = get_Proj_proj(proj);
1860
1861                 if (pn == pn_be_Call_first_res) {
1862                         return proj;
1863                 }
1864         }
1865
1866         return NULL;
1867 }  /* get_call_result_proj */
1868
1869 /**
1870  * Simulate a be_Call.
1871  *
1872  * @param state      the x87 state
1873  * @param n          the node that should be simulated
1874  *
1875  * @return NO_NODE_ADDED
1876  */
1877 static int sim_Call(x87_state *state, ir_node *n)
1878 {
1879         ir_type *call_tp = be_Call_get_type(n);
1880         ir_type *res_type;
1881         ir_mode *mode;
1882         ir_node *resproj;
1883         const arch_register_t *reg;
1884
1885         DB((dbg, LEVEL_1, ">>> %+F\n", n));
1886
1887         /* at the begin of a call the x87 state should be empty */
1888         assert(state->depth == 0 && "stack not empty before call");
1889
1890         if (get_method_n_ress(call_tp) <= 0)
1891                 goto end_call;
1892
1893         /*
1894          * If the called function returns a float, it is returned in st(0).
1895          * This even happens if the return value is NOT used.
1896          * Moreover, only one return result is supported.
1897          */
1898         res_type = get_method_res_type(call_tp, 0);
1899         mode     = get_type_mode(res_type);
1900
1901         if (mode == NULL || !mode_is_float(mode))
1902                 goto end_call;
1903
1904         resproj = get_call_result_proj(n);
1905         assert(resproj != NULL);
1906
1907         reg = x87_get_irn_register(state->sim, resproj);
1908         x87_push(state, arch_register_get_index(reg), resproj);
1909
1910 end_call:
1911         DB((dbg, LEVEL_1, "Stack after: "));
1912         DEBUG_ONLY(x87_dump_stack(state));
1913
1914         return NO_NODE_ADDED;
1915 }  /* sim_Call */
1916
1917 /**
1918  * Simulate a be_Spill.
1919  *
1920  * @param state  the x87 state
1921  * @param n      the node that should be simulated (and patched)
1922  *
1923  * Should not happen, spills are lowered before x87 simulator see them.
1924  */
1925 static int sim_Spill(x87_state *state, ir_node *n) {
1926         assert(0 && "Spill not lowered");
1927         return sim_fst(state, n);
1928 }  /* sim_Spill */
1929
1930 /**
1931  * Simulate a be_Reload.
1932  *
1933  * @param state  the x87 state
1934  * @param n      the node that should be simulated (and patched)
1935  *
1936  * Should not happen, reloads are lowered before x87 simulator see them.
1937  */
1938 static int sim_Reload(x87_state *state, ir_node *n) {
1939         assert(0 && "Reload not lowered");
1940         return sim_fld(state, n);
1941 }  /* sim_Reload */
1942
1943 /**
1944  * Simulate a be_Return.
1945  *
1946  * @param state  the x87 state
1947  * @param n      the node that should be simulated (and patched)
1948  *
1949  * @return NO_NODE_ADDED
1950  */
1951 static int sim_Return(x87_state *state, ir_node *n) {
1952         int n_res = be_Return_get_n_rets(n);
1953         int i, n_float_res = 0;
1954
1955         /* only floating point return values must resist on stack */
1956         for (i = 0; i < n_res; ++i) {
1957                 ir_node *res = get_irn_n(n, be_pos_Return_val + i);
1958
1959                 if (mode_is_float(get_irn_mode(res)))
1960                         ++n_float_res;
1961         }
1962         assert(x87_get_depth(state) == n_float_res);
1963
1964         /* pop them virtually */
1965         for (i = n_float_res - 1; i >= 0; --i)
1966                 x87_pop(state);
1967
1968         return NO_NODE_ADDED;
1969 }  /* sim_Return */
1970
1971 typedef struct _perm_data_t {
1972         const arch_register_t *in;
1973         const arch_register_t *out;
1974 } perm_data_t;
1975
1976 /**
1977  * Simulate a be_Perm.
1978  *
1979  * @param state  the x87 state
1980  * @param irn    the node that should be simulated (and patched)
1981  *
1982  * @return NO_NODE_ADDED
1983  */
1984 static int sim_Perm(x87_state *state, ir_node *irn) {
1985         int             i, n;
1986         x87_simulator   *sim = state->sim;
1987         ir_node         *pred = get_irn_n(irn, 0);
1988         int             *stack_pos;
1989         const ir_edge_t *edge;
1990
1991         /* handle only floating point Perms */
1992         if (! mode_is_float(get_irn_mode(pred)))
1993                 return NO_NODE_ADDED;
1994
1995         DB((dbg, LEVEL_1, ">>> %+F\n", irn));
1996
1997         /* Perm is a pure virtual instruction on x87.
1998            All inputs must be on the FPU stack and are pairwise
1999            different from each other.
2000            So, all we need to do is to permutate the stack state. */
2001         n = get_irn_arity(irn);
2002         NEW_ARR_A(int, stack_pos, n);
2003
2004         /* collect old stack positions */
2005         for (i = 0; i < n; ++i) {
2006                 const arch_register_t *inreg = x87_get_irn_register(sim, get_irn_n(irn, i));
2007                 int idx = x87_on_stack(state, arch_register_get_index(inreg));
2008
2009                 assert(idx >= 0 && "Perm argument not on x87 stack");
2010
2011                 stack_pos[i] = idx;
2012         }
2013         /* now do the permutation */
2014         foreach_out_edge(irn, edge) {
2015                 ir_node               *proj = get_edge_src_irn(edge);
2016                 const arch_register_t *out  = x87_get_irn_register(sim, proj);
2017                 long                  num   = get_Proj_proj(proj);
2018
2019                 assert(0 <= num && num < n && "More Proj's than Perm inputs");
2020                 x87_set_st(state, arch_register_get_index(out), proj, stack_pos[(unsigned)num]);
2021         }
2022         DB((dbg, LEVEL_1, "<<< %+F\n", irn));
2023
2024         return NO_NODE_ADDED;
2025 }  /* sim_Perm */
2026
2027 static int sim_Barrier(x87_state *state, ir_node *node) {
2028         //const arch_env_t *arch_env = state->sim->arch_env;
2029         int i, arity;
2030
2031         /* materialize unknown if needed */
2032         arity = get_irn_arity(node);
2033         for(i = 0; i < arity; ++i) {
2034                 const arch_register_t       *reg;
2035                 ir_node                     *zero;
2036                 ir_node                     *block;
2037                 ia32_x87_attr_t             *attr;
2038                 ir_node                     *in    = get_irn_n(node, i);
2039
2040                 if(!is_ia32_Unknown_VFP(in))
2041                         continue;
2042
2043                 /* TODO: not completely correct... */
2044                 reg = &ia32_vfp_regs[REG_VFP_UKNWN];
2045
2046                 /* create a zero */
2047                 block = get_nodes_block(node);
2048                 zero  = new_rd_ia32_fldz(NULL, current_ir_graph, block, mode_E);
2049                 x87_push(state, arch_register_get_index(reg), zero);
2050
2051                 attr = get_ia32_x87_attr(zero);
2052                 attr->x87[2] = &ia32_st_regs[0];
2053
2054                 sched_add_before(node, zero);
2055
2056                 set_irn_n(node, i, zero);
2057         }
2058
2059         return NO_NODE_ADDED;
2060 }
2061
2062
2063 /**
2064  * Kill any dead registers at block start by popping them from the stack.
2065  *
2066  * @param sim          the simulator handle
2067  * @param block        the current block
2068  * @param start_state  the x87 state at the begin of the block
2069  *
2070  * @return the x87 state after dead register killed
2071  */
2072 static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *start_state) {
2073         x87_state *state = start_state;
2074         ir_node *first_insn = sched_first(block);
2075         ir_node *keep = NULL;
2076         unsigned live = vfp_live_args_after(sim, block, 0);
2077         unsigned kill_mask;
2078         int i, depth, num_pop;
2079
2080         kill_mask = 0;
2081         depth = x87_get_depth(state);
2082         for (i = depth - 1; i >= 0; --i) {
2083                 int reg = x87_get_st_reg(state, i);
2084
2085                 if (! is_vfp_live(reg, live))
2086                         kill_mask |= (1 << i);
2087         }
2088
2089         if (kill_mask) {
2090                 /* create a new state, will be changed */
2091                 state = x87_clone_state(sim, state);
2092
2093                 DB((dbg, LEVEL_1, "Killing deads:\n"));
2094                 DEBUG_ONLY(vfp_dump_live(live));
2095                 DEBUG_ONLY(x87_dump_stack(state));
2096
2097                 if (kill_mask != 0 && live == 0) {
2098                         int cpu = sim->isa->arch;
2099
2100                         /* special case: kill all registers */
2101                         if (ARCH_ATHLON(sim->isa->opt_arch) && ARCH_MMX(cpu)) {
2102                                 if (ARCH_AMD(cpu)) {
2103                                         /* use FEMMS on AMD processors to clear all */
2104                                         keep = new_rd_ia32_femms(NULL, get_irn_irg(block), block);
2105                                 } else {
2106                                         /* use EMMS to clear all */
2107                                         keep = new_rd_ia32_emms(NULL, get_irn_irg(block), block);
2108                                 }
2109                                 sched_add_before(first_insn, keep);
2110                                 keep_alive(keep);
2111                                 x87_emms(state);
2112                                 return state;
2113                         }
2114                 }
2115                 /* now kill registers */
2116                 while (kill_mask) {
2117                         /* we can only kill from TOS, so bring them up */
2118                         if (! (kill_mask & 1)) {
2119                                 /* search from behind, because we can to a double-pop */
2120                                 for (i = depth - 1; i >= 0; --i) {
2121                                         if (kill_mask & (1 << i)) {
2122                                                 kill_mask &= ~(1 << i);
2123                                                 kill_mask |= 1;
2124                                                 break;
2125                                         }
2126                                 }
2127
2128                                 if (keep)
2129                                         x87_set_st(state, -1, keep, i);
2130                                 x87_create_fxch(state, first_insn, i);
2131                         }
2132
2133                         if ((kill_mask & 3) == 3) {
2134                                 /* we can do a double-pop */
2135                                 num_pop = 2;
2136                         }
2137                         else {
2138                                 /* only a single pop */
2139                                 num_pop = 1;
2140                         }
2141
2142                         depth -= num_pop;
2143                         kill_mask >>= num_pop;
2144                         keep = x87_create_fpop(state, first_insn, num_pop);
2145                 }
2146                 keep_alive(keep);
2147         }
2148         return state;
2149 }  /* x87_kill_deads */
2150
2151 /**
2152  * If we have PhiEs with unknown operands then we have to make sure that some
2153  * value is actually put onto the stack.
2154  */
2155 static void fix_unknown_phis(x87_state *state, ir_node *block,
2156                              ir_node *pred_block, int pos)
2157 {
2158         ir_node *node, *op;
2159
2160         sched_foreach(block, node) {
2161                 ir_node               *zero;
2162                 const arch_register_t *reg;
2163                 ia32_x87_attr_t       *attr;
2164
2165                 if(!is_Phi(node))
2166                         break;
2167
2168                 op = get_Phi_pred(node, pos);
2169                 if(!is_ia32_Unknown_VFP(op))
2170                         continue;
2171
2172                 reg = arch_get_irn_register(state->sim->arch_env, node);
2173
2174                 /* create a zero at end of pred block */
2175                 zero = new_rd_ia32_fldz(NULL, current_ir_graph, pred_block, mode_E);
2176                 x87_push(state, arch_register_get_index(reg), zero);
2177
2178                 attr = get_ia32_x87_attr(zero);
2179                 attr->x87[2] = &ia32_st_regs[0];
2180
2181                 assert(is_ia32_fldz(zero));
2182                 sched_add_before(sched_last(pred_block), zero);
2183
2184                 set_Phi_pred(node, pos, zero);
2185         }
2186 }
2187
2188 /**
2189  * Run a simulation and fix all virtual instructions for a block.
2190  *
2191  * @param sim          the simulator handle
2192  * @param block        the current block
2193  */
2194 static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
2195         ir_node *n, *next;
2196         blk_state *bl_state = x87_get_bl_state(sim, block);
2197         x87_state *state = bl_state->begin;
2198         const ir_edge_t *edge;
2199         ir_node *start_block;
2200
2201         assert(state != NULL);
2202         /* already processed? */
2203         if (bl_state->end != NULL)
2204                 return;
2205
2206         DB((dbg, LEVEL_1, "Simulate %+F\n", block));
2207         DB((dbg, LEVEL_2, "State at Block begin:\n "));
2208         DEBUG_ONLY(x87_dump_stack(state));
2209
2210         /* at block begin, kill all dead registers */
2211         state = x87_kill_deads(sim, block, state);
2212         /* create a new state, will be changed */
2213         state = x87_clone_state(sim, state);
2214
2215         /* beware, n might change */
2216         for (n = sched_first(block); !sched_is_end(n); n = next) {
2217                 int node_inserted;
2218                 sim_func func;
2219                 ir_op *op = get_irn_op(n);
2220
2221                 next = sched_next(n);
2222                 if (op->ops.generic == NULL)
2223                         continue;
2224
2225                 func = (sim_func)op->ops.generic;
2226
2227                 /* simulate it */
2228                 node_inserted = (*func)(state, n);
2229
2230                 /*
2231                         sim_func might have added an additional node after n,
2232                         so update next node
2233                         beware: n must not be changed by sim_func
2234                         (i.e. removed from schedule) in this case
2235                 */
2236                 if (node_inserted != NO_NODE_ADDED)
2237                         next = sched_next(n);
2238         }
2239
2240         start_block = get_irg_start_block(get_irn_irg(block));
2241
2242         DB((dbg, LEVEL_2, "State at Block end:\n ")); DEBUG_ONLY(x87_dump_stack(state));
2243
2244         /* check if the state must be shuffled */
2245         foreach_block_succ(block, edge) {
2246                 ir_node *succ = get_edge_src_irn(edge);
2247                 blk_state *succ_state;
2248
2249                 if (succ == start_block)
2250                         continue;
2251
2252                 succ_state = x87_get_bl_state(sim, succ);
2253
2254                 fix_unknown_phis(state, succ, block, get_edge_src_pos(edge));
2255
2256                 if (succ_state->begin == NULL) {
2257                         DB((dbg, LEVEL_2, "Set begin state for succ %+F:\n", succ));
2258                         DEBUG_ONLY(x87_dump_stack(state));
2259                         succ_state->begin = state;
2260
2261                         waitq_put(sim->worklist, succ);
2262                 } else {
2263                         DB((dbg, LEVEL_2, "succ %+F already has a state, shuffling\n", succ));
2264                         /* There is already a begin state for the successor, bad.
2265                            Do the necessary permutations.
2266                            Note that critical edges are removed, so this is always possible:
2267                            If the successor has more than one possible input, then it must
2268                            be the only one.
2269                          */
2270                         x87_shuffle(sim, block, state, succ, succ_state->begin);
2271                 }
2272         }
2273         bl_state->end = state;
2274 }  /* x87_simulate_block */
2275
2276 static void register_sim(ir_op *op, sim_func func)
2277 {
2278         assert(op->ops.generic == NULL);
2279         op->ops.generic = (op_func) func;
2280 }
2281
2282 /**
2283  * Create a new x87 simulator.
2284  *
2285  * @param sim       a simulator handle, will be initialized
2286  * @param irg       the current graph
2287  * @param arch_env  the architecture environment
2288  */
2289 static void x87_init_simulator(x87_simulator *sim, ir_graph *irg,
2290                                const arch_env_t *arch_env)
2291 {
2292         obstack_init(&sim->obst);
2293         sim->blk_states = pmap_create();
2294         sim->arch_env   = arch_env;
2295         sim->n_idx      = get_irg_last_idx(irg);
2296         sim->live       = obstack_alloc(&sim->obst, sizeof(*sim->live) * sim->n_idx);
2297         sim->isa        = (ia32_isa_t *)arch_env->isa;
2298
2299         DB((dbg, LEVEL_1, "--------------------------------\n"
2300                 "x87 Simulator started for %+F\n", irg));
2301
2302         /* set the generic function pointer of instruction we must simulate */
2303         clear_irp_opcodes_generic_func();
2304
2305         register_sim(op_ia32_vfld,         sim_fld);
2306         register_sim(op_ia32_vfild,        sim_fild);
2307         register_sim(op_ia32_vfld1,        sim_fld1);
2308         register_sim(op_ia32_vfldz,        sim_fldz);
2309         register_sim(op_ia32_vfadd,        sim_fadd);
2310         register_sim(op_ia32_vfsub,        sim_fsub);
2311         register_sim(op_ia32_vfmul,        sim_fmul);
2312         register_sim(op_ia32_vfdiv,        sim_fdiv);
2313         register_sim(op_ia32_vfprem,       sim_fprem);
2314         register_sim(op_ia32_vfabs,        sim_fabs);
2315         register_sim(op_ia32_vfchs,        sim_fchs);
2316         register_sim(op_ia32_vfist,        sim_fist);
2317         register_sim(op_ia32_vfst,         sim_fst);
2318         register_sim(op_ia32_vFtstFnstsw,  sim_FtstFnstsw);
2319         register_sim(op_ia32_vFucomFnstsw, sim_Fucom);
2320         register_sim(op_ia32_vFucomi,      sim_Fucom);
2321         register_sim(op_be_Copy,           sim_Copy);
2322         register_sim(op_be_Call,           sim_Call);
2323         register_sim(op_be_Spill,          sim_Spill);
2324         register_sim(op_be_Reload,         sim_Reload);
2325         register_sim(op_be_Return,         sim_Return);
2326         register_sim(op_be_Perm,           sim_Perm);
2327         register_sim(op_be_Keep,           sim_Keep);
2328         register_sim(op_be_Barrier,        sim_Barrier);
2329 }  /* x87_init_simulator */
2330
2331 /**
2332  * Destroy a x87 simulator.
2333  *
2334  * @param sim  the simulator handle
2335  */
2336 static void x87_destroy_simulator(x87_simulator *sim) {
2337         pmap_destroy(sim->blk_states);
2338         obstack_free(&sim->obst, NULL);
2339         DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
2340 }  /* x87_destroy_simulator */
2341
2342 /**
2343  * Pre-block walker: calculate the liveness information for the block
2344  * and store it into the sim->live cache.
2345  */
2346 static void update_liveness_walker(ir_node *block, void *data) {
2347         x87_simulator *sim = data;
2348         update_liveness(sim, block);
2349 }  /* update_liveness_walker */
2350
2351 /**
2352  * Run a simulation and fix all virtual instructions for a graph.
2353  *
2354  * @param env       the architecture environment
2355  * @param irg       the current graph
2356  *
2357  * Needs a block-schedule.
2358  */
2359 void x87_simulate_graph(const arch_env_t *arch_env, be_irg_t *birg) {
2360         ir_node       *block, *start_block;
2361         blk_state     *bl_state;
2362         x87_simulator sim;
2363         ir_graph      *irg = be_get_birg_irg(birg);
2364
2365         /* create the simulator */
2366         x87_init_simulator(&sim, irg, arch_env);
2367
2368         start_block = get_irg_start_block(irg);
2369         bl_state    = x87_get_bl_state(&sim, start_block);
2370
2371         /* start with the empty state */
2372         bl_state->begin = empty;
2373         empty->sim      = &sim;
2374
2375         sim.worklist = new_waitq();
2376         waitq_put(sim.worklist, start_block);
2377
2378         be_assure_liveness(birg);
2379         sim.lv = be_get_birg_liveness(birg);
2380 //      sim.lv = be_liveness(be_get_birg_irg(birg));
2381         be_liveness_assure_sets(sim.lv);
2382
2383         /* Calculate the liveness for all nodes. We must precalculate this info,
2384          * because the simulator adds new nodes (possible before Phi nodes) which
2385          * would let a lazy calculation fail.
2386          * On the other hand we reduce the computation amount due to
2387          * precaching from O(n^2) to O(n) at the expense of O(n) cache memory.
2388          */
2389         irg_block_walk_graph(irg, update_liveness_walker, NULL, &sim);
2390
2391         /* iterate */
2392         do {
2393                 block = waitq_get(sim.worklist);
2394                 x87_simulate_block(&sim, block);
2395         } while (! waitq_empty(sim.worklist));
2396
2397         /* kill it */
2398         del_waitq(sim.worklist);
2399         x87_destroy_simulator(&sim);
2400 }  /* x87_simulate_graph */
2401
2402 void ia32_init_x87(void) {
2403         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.x87");
2404 }  /* ia32_init_x87 */