rename pnc_flipped to ins_permuted and change back non-fix of cmov yesterday
[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                    permuted = attr->attr.data.ins_permuted;
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                                         permuted = !permuted;
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                                 permuted = !permuted;
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                                         permuted = !permuted;
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                                                 permuted = !permuted;
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.ins_permuted = permuted;
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 -> ?\n", node, op1->name));
1804         } else {
1805                 out_idx = x87_on_stack(state, arch_register_get_index(out));
1806
1807                 if (out_idx >= 0 && out_idx != op1_idx) {
1808                         /* Matze: out already on stack? how can this happen? */
1809                         assert(0);
1810
1811                         /* op1 must be killed and placed where out is */
1812                         if (out_idx == 0) {
1813                                 /* best case, simple remove and rename */
1814                                 x87_patch_insn(n, op_ia32_Pop);
1815                                 attr = get_ia32_x87_attr(n);
1816                                 attr->x87[0] = op1 = &ia32_st_regs[0];
1817
1818                                 x87_pop(state);
1819                                 x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
1820                         } else {
1821                                 /* move op1 to tos, store and pop it */
1822                                 if (op1_idx != 0) {
1823                                         x87_create_fxch(state, n, op1_idx);
1824                                         op1_idx = 0;
1825                                 }
1826                                 x87_patch_insn(n, op_ia32_Pop);
1827                                 attr = get_ia32_x87_attr(n);
1828                                 attr->x87[0] = op1 = &ia32_st_regs[out_idx];
1829
1830                                 x87_pop(state);
1831                                 x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
1832                         }
1833                         DB((dbg, LEVEL_1, "<<< %+F %s\n", n, op1->name));
1834                 } else {
1835                         /* just a virtual copy */
1836                         x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
1837                         /* don't remove the node to keep the verifier quiet :),
1838                            the emitter won't emit any code for the node */
1839 #if 0
1840                         sched_remove(n);
1841                         DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n)));
1842                         exchange(n, get_unop_op(n));
1843 #endif
1844                 }
1845         }
1846         return NO_NODE_ADDED;
1847 }  /* sim_Copy */
1848
1849 /**
1850  * Returns the result proj of the call
1851  */
1852 static ir_node *get_call_result_proj(ir_node *call) {
1853         const ir_edge_t *edge;
1854
1855         /* search the result proj */
1856         foreach_out_edge(call, edge) {
1857                 ir_node *proj = get_edge_src_irn(edge);
1858                 long pn = get_Proj_proj(proj);
1859
1860                 if (pn == pn_be_Call_first_res) {
1861                         return proj;
1862                 }
1863         }
1864
1865         return NULL;
1866 }  /* get_call_result_proj */
1867
1868 /**
1869  * Simulate a be_Call.
1870  *
1871  * @param state      the x87 state
1872  * @param n          the node that should be simulated
1873  *
1874  * @return NO_NODE_ADDED
1875  */
1876 static int sim_Call(x87_state *state, ir_node *n)
1877 {
1878         ir_type *call_tp = be_Call_get_type(n);
1879         ir_type *res_type;
1880         ir_mode *mode;
1881         ir_node *resproj;
1882         const arch_register_t *reg;
1883
1884         DB((dbg, LEVEL_1, ">>> %+F\n", n));
1885
1886         /* at the begin of a call the x87 state should be empty */
1887         assert(state->depth == 0 && "stack not empty before call");
1888
1889         if (get_method_n_ress(call_tp) <= 0)
1890                 goto end_call;
1891
1892         /*
1893          * If the called function returns a float, it is returned in st(0).
1894          * This even happens if the return value is NOT used.
1895          * Moreover, only one return result is supported.
1896          */
1897         res_type = get_method_res_type(call_tp, 0);
1898         mode     = get_type_mode(res_type);
1899
1900         if (mode == NULL || !mode_is_float(mode))
1901                 goto end_call;
1902
1903         resproj = get_call_result_proj(n);
1904         assert(resproj != NULL);
1905
1906         reg = x87_get_irn_register(state->sim, resproj);
1907         x87_push(state, arch_register_get_index(reg), resproj);
1908
1909 end_call:
1910         DB((dbg, LEVEL_1, "Stack after: "));
1911         DEBUG_ONLY(x87_dump_stack(state));
1912
1913         return NO_NODE_ADDED;
1914 }  /* sim_Call */
1915
1916 /**
1917  * Simulate a be_Spill.
1918  *
1919  * @param state  the x87 state
1920  * @param n      the node that should be simulated (and patched)
1921  *
1922  * Should not happen, spills are lowered before x87 simulator see them.
1923  */
1924 static int sim_Spill(x87_state *state, ir_node *n) {
1925         assert(0 && "Spill not lowered");
1926         return sim_fst(state, n);
1927 }  /* sim_Spill */
1928
1929 /**
1930  * Simulate a be_Reload.
1931  *
1932  * @param state  the x87 state
1933  * @param n      the node that should be simulated (and patched)
1934  *
1935  * Should not happen, reloads are lowered before x87 simulator see them.
1936  */
1937 static int sim_Reload(x87_state *state, ir_node *n) {
1938         assert(0 && "Reload not lowered");
1939         return sim_fld(state, n);
1940 }  /* sim_Reload */
1941
1942 /**
1943  * Simulate a be_Return.
1944  *
1945  * @param state  the x87 state
1946  * @param n      the node that should be simulated (and patched)
1947  *
1948  * @return NO_NODE_ADDED
1949  */
1950 static int sim_Return(x87_state *state, ir_node *n) {
1951         int n_res = be_Return_get_n_rets(n);
1952         int i, n_float_res = 0;
1953
1954         /* only floating point return values must resist on stack */
1955         for (i = 0; i < n_res; ++i) {
1956                 ir_node *res = get_irn_n(n, be_pos_Return_val + i);
1957
1958                 if (mode_is_float(get_irn_mode(res)))
1959                         ++n_float_res;
1960         }
1961         assert(x87_get_depth(state) == n_float_res);
1962
1963         /* pop them virtually */
1964         for (i = n_float_res - 1; i >= 0; --i)
1965                 x87_pop(state);
1966
1967         return NO_NODE_ADDED;
1968 }  /* sim_Return */
1969
1970 typedef struct _perm_data_t {
1971         const arch_register_t *in;
1972         const arch_register_t *out;
1973 } perm_data_t;
1974
1975 /**
1976  * Simulate a be_Perm.
1977  *
1978  * @param state  the x87 state
1979  * @param irn    the node that should be simulated (and patched)
1980  *
1981  * @return NO_NODE_ADDED
1982  */
1983 static int sim_Perm(x87_state *state, ir_node *irn) {
1984         int             i, n;
1985         x87_simulator   *sim = state->sim;
1986         ir_node         *pred = get_irn_n(irn, 0);
1987         int             *stack_pos;
1988         const ir_edge_t *edge;
1989
1990         /* handle only floating point Perms */
1991         if (! mode_is_float(get_irn_mode(pred)))
1992                 return NO_NODE_ADDED;
1993
1994         DB((dbg, LEVEL_1, ">>> %+F\n", irn));
1995
1996         /* Perm is a pure virtual instruction on x87.
1997            All inputs must be on the FPU stack and are pairwise
1998            different from each other.
1999            So, all we need to do is to permutate the stack state. */
2000         n = get_irn_arity(irn);
2001         NEW_ARR_A(int, stack_pos, n);
2002
2003         /* collect old stack positions */
2004         for (i = 0; i < n; ++i) {
2005                 const arch_register_t *inreg = x87_get_irn_register(sim, get_irn_n(irn, i));
2006                 int idx = x87_on_stack(state, arch_register_get_index(inreg));
2007
2008                 assert(idx >= 0 && "Perm argument not on x87 stack");
2009
2010                 stack_pos[i] = idx;
2011         }
2012         /* now do the permutation */
2013         foreach_out_edge(irn, edge) {
2014                 ir_node               *proj = get_edge_src_irn(edge);
2015                 const arch_register_t *out  = x87_get_irn_register(sim, proj);
2016                 long                  num   = get_Proj_proj(proj);
2017
2018                 assert(0 <= num && num < n && "More Proj's than Perm inputs");
2019                 x87_set_st(state, arch_register_get_index(out), proj, stack_pos[(unsigned)num]);
2020         }
2021         DB((dbg, LEVEL_1, "<<< %+F\n", irn));
2022
2023         return NO_NODE_ADDED;
2024 }  /* sim_Perm */
2025
2026 static int sim_Barrier(x87_state *state, ir_node *node) {
2027         //const arch_env_t *arch_env = state->sim->arch_env;
2028         int i, arity;
2029
2030         /* materialize unknown if needed */
2031         arity = get_irn_arity(node);
2032         for(i = 0; i < arity; ++i) {
2033                 const arch_register_t       *reg;
2034                 ir_node                     *zero;
2035                 ir_node                     *block;
2036                 ia32_x87_attr_t             *attr;
2037                 ir_node                     *in    = get_irn_n(node, i);
2038
2039                 if(!is_ia32_Unknown_VFP(in))
2040                         continue;
2041
2042                 /* TODO: not completely correct... */
2043                 reg = &ia32_vfp_regs[REG_VFP_UKNWN];
2044
2045                 /* create a zero */
2046                 block = get_nodes_block(node);
2047                 zero  = new_rd_ia32_fldz(NULL, current_ir_graph, block, mode_E);
2048                 x87_push(state, arch_register_get_index(reg), zero);
2049
2050                 attr = get_ia32_x87_attr(zero);
2051                 attr->x87[2] = &ia32_st_regs[0];
2052
2053                 sched_add_before(node, zero);
2054
2055                 set_irn_n(node, i, zero);
2056         }
2057
2058         return NO_NODE_ADDED;
2059 }
2060
2061
2062 /**
2063  * Kill any dead registers at block start by popping them from the stack.
2064  *
2065  * @param sim          the simulator handle
2066  * @param block        the current block
2067  * @param start_state  the x87 state at the begin of the block
2068  *
2069  * @return the x87 state after dead register killed
2070  */
2071 static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *start_state) {
2072         x87_state *state = start_state;
2073         ir_node *first_insn = sched_first(block);
2074         ir_node *keep = NULL;
2075         unsigned live = vfp_live_args_after(sim, block, 0);
2076         unsigned kill_mask;
2077         int i, depth, num_pop;
2078
2079         kill_mask = 0;
2080         depth = x87_get_depth(state);
2081         for (i = depth - 1; i >= 0; --i) {
2082                 int reg = x87_get_st_reg(state, i);
2083
2084                 if (! is_vfp_live(reg, live))
2085                         kill_mask |= (1 << i);
2086         }
2087
2088         if (kill_mask) {
2089                 /* create a new state, will be changed */
2090                 state = x87_clone_state(sim, state);
2091
2092                 DB((dbg, LEVEL_1, "Killing deads:\n"));
2093                 DEBUG_ONLY(vfp_dump_live(live));
2094                 DEBUG_ONLY(x87_dump_stack(state));
2095
2096                 if (kill_mask != 0 && live == 0) {
2097                         int cpu = sim->isa->arch;
2098
2099                         /* special case: kill all registers */
2100                         if (ARCH_ATHLON(sim->isa->opt_arch) && ARCH_MMX(cpu)) {
2101                                 if (ARCH_AMD(cpu)) {
2102                                         /* use FEMMS on AMD processors to clear all */
2103                                         keep = new_rd_ia32_femms(NULL, get_irn_irg(block), block);
2104                                 } else {
2105                                         /* use EMMS to clear all */
2106                                         keep = new_rd_ia32_emms(NULL, get_irn_irg(block), block);
2107                                 }
2108                                 sched_add_before(first_insn, keep);
2109                                 keep_alive(keep);
2110                                 x87_emms(state);
2111                                 return state;
2112                         }
2113                 }
2114                 /* now kill registers */
2115                 while (kill_mask) {
2116                         /* we can only kill from TOS, so bring them up */
2117                         if (! (kill_mask & 1)) {
2118                                 /* search from behind, because we can to a double-pop */
2119                                 for (i = depth - 1; i >= 0; --i) {
2120                                         if (kill_mask & (1 << i)) {
2121                                                 kill_mask &= ~(1 << i);
2122                                                 kill_mask |= 1;
2123                                                 break;
2124                                         }
2125                                 }
2126
2127                                 if (keep)
2128                                         x87_set_st(state, -1, keep, i);
2129                                 x87_create_fxch(state, first_insn, i);
2130                         }
2131
2132                         if ((kill_mask & 3) == 3) {
2133                                 /* we can do a double-pop */
2134                                 num_pop = 2;
2135                         }
2136                         else {
2137                                 /* only a single pop */
2138                                 num_pop = 1;
2139                         }
2140
2141                         depth -= num_pop;
2142                         kill_mask >>= num_pop;
2143                         keep = x87_create_fpop(state, first_insn, num_pop);
2144                 }
2145                 keep_alive(keep);
2146         }
2147         return state;
2148 }  /* x87_kill_deads */
2149
2150 /**
2151  * If we have PhiEs with unknown operands then we have to make sure that some
2152  * value is actually put onto the stack.
2153  */
2154 static void fix_unknown_phis(x87_state *state, ir_node *block,
2155                              ir_node *pred_block, int pos)
2156 {
2157         ir_node *node, *op;
2158
2159         sched_foreach(block, node) {
2160                 ir_node               *zero;
2161                 const arch_register_t *reg;
2162                 ia32_x87_attr_t       *attr;
2163
2164                 if(!is_Phi(node))
2165                         break;
2166
2167                 op = get_Phi_pred(node, pos);
2168                 if(!is_ia32_Unknown_VFP(op))
2169                         continue;
2170
2171                 reg = arch_get_irn_register(state->sim->arch_env, node);
2172
2173                 /* create a zero at end of pred block */
2174                 zero = new_rd_ia32_fldz(NULL, current_ir_graph, pred_block, mode_E);
2175                 x87_push(state, arch_register_get_index(reg), zero);
2176
2177                 attr = get_ia32_x87_attr(zero);
2178                 attr->x87[2] = &ia32_st_regs[0];
2179
2180                 assert(is_ia32_fldz(zero));
2181                 sched_add_before(sched_last(pred_block), zero);
2182
2183                 set_Phi_pred(node, pos, zero);
2184         }
2185 }
2186
2187 /**
2188  * Run a simulation and fix all virtual instructions for a block.
2189  *
2190  * @param sim          the simulator handle
2191  * @param block        the current block
2192  */
2193 static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
2194         ir_node *n, *next;
2195         blk_state *bl_state = x87_get_bl_state(sim, block);
2196         x87_state *state = bl_state->begin;
2197         const ir_edge_t *edge;
2198         ir_node *start_block;
2199
2200         assert(state != NULL);
2201         /* already processed? */
2202         if (bl_state->end != NULL)
2203                 return;
2204
2205         DB((dbg, LEVEL_1, "Simulate %+F\n", block));
2206         DB((dbg, LEVEL_2, "State at Block begin:\n "));
2207         DEBUG_ONLY(x87_dump_stack(state));
2208
2209         /* at block begin, kill all dead registers */
2210         state = x87_kill_deads(sim, block, state);
2211         /* create a new state, will be changed */
2212         state = x87_clone_state(sim, state);
2213
2214         /* beware, n might change */
2215         for (n = sched_first(block); !sched_is_end(n); n = next) {
2216                 int node_inserted;
2217                 sim_func func;
2218                 ir_op *op = get_irn_op(n);
2219
2220                 next = sched_next(n);
2221                 if (op->ops.generic == NULL)
2222                         continue;
2223
2224                 func = (sim_func)op->ops.generic;
2225
2226                 /* simulate it */
2227                 node_inserted = (*func)(state, n);
2228
2229                 /*
2230                         sim_func might have added an additional node after n,
2231                         so update next node
2232                         beware: n must not be changed by sim_func
2233                         (i.e. removed from schedule) in this case
2234                 */
2235                 if (node_inserted != NO_NODE_ADDED)
2236                         next = sched_next(n);
2237         }
2238
2239         start_block = get_irg_start_block(get_irn_irg(block));
2240
2241         DB((dbg, LEVEL_2, "State at Block end:\n ")); DEBUG_ONLY(x87_dump_stack(state));
2242
2243         /* check if the state must be shuffled */
2244         foreach_block_succ(block, edge) {
2245                 ir_node *succ = get_edge_src_irn(edge);
2246                 blk_state *succ_state;
2247
2248                 if (succ == start_block)
2249                         continue;
2250
2251                 succ_state = x87_get_bl_state(sim, succ);
2252
2253                 fix_unknown_phis(state, succ, block, get_edge_src_pos(edge));
2254
2255                 if (succ_state->begin == NULL) {
2256                         DB((dbg, LEVEL_2, "Set begin state for succ %+F:\n", succ));
2257                         DEBUG_ONLY(x87_dump_stack(state));
2258                         succ_state->begin = state;
2259
2260                         waitq_put(sim->worklist, succ);
2261                 } else {
2262                         DB((dbg, LEVEL_2, "succ %+F already has a state, shuffling\n", succ));
2263                         /* There is already a begin state for the successor, bad.
2264                            Do the necessary permutations.
2265                            Note that critical edges are removed, so this is always possible:
2266                            If the successor has more than one possible input, then it must
2267                            be the only one.
2268                          */
2269                         x87_shuffle(sim, block, state, succ, succ_state->begin);
2270                 }
2271         }
2272         bl_state->end = state;
2273 }  /* x87_simulate_block */
2274
2275 static void register_sim(ir_op *op, sim_func func)
2276 {
2277         assert(op->ops.generic == NULL);
2278         op->ops.generic = (op_func) func;
2279 }
2280
2281 /**
2282  * Create a new x87 simulator.
2283  *
2284  * @param sim       a simulator handle, will be initialized
2285  * @param irg       the current graph
2286  * @param arch_env  the architecture environment
2287  */
2288 static void x87_init_simulator(x87_simulator *sim, ir_graph *irg,
2289                                const arch_env_t *arch_env)
2290 {
2291         obstack_init(&sim->obst);
2292         sim->blk_states = pmap_create();
2293         sim->arch_env   = arch_env;
2294         sim->n_idx      = get_irg_last_idx(irg);
2295         sim->live       = obstack_alloc(&sim->obst, sizeof(*sim->live) * sim->n_idx);
2296         sim->isa        = (ia32_isa_t *)arch_env->isa;
2297
2298         DB((dbg, LEVEL_1, "--------------------------------\n"
2299                 "x87 Simulator started for %+F\n", irg));
2300
2301         /* set the generic function pointer of instruction we must simulate */
2302         clear_irp_opcodes_generic_func();
2303
2304         register_sim(op_ia32_vfld,         sim_fld);
2305         register_sim(op_ia32_vfild,        sim_fild);
2306         register_sim(op_ia32_vfld1,        sim_fld1);
2307         register_sim(op_ia32_vfldz,        sim_fldz);
2308         register_sim(op_ia32_vfadd,        sim_fadd);
2309         register_sim(op_ia32_vfsub,        sim_fsub);
2310         register_sim(op_ia32_vfmul,        sim_fmul);
2311         register_sim(op_ia32_vfdiv,        sim_fdiv);
2312         register_sim(op_ia32_vfprem,       sim_fprem);
2313         register_sim(op_ia32_vfabs,        sim_fabs);
2314         register_sim(op_ia32_vfchs,        sim_fchs);
2315         register_sim(op_ia32_vfist,        sim_fist);
2316         register_sim(op_ia32_vfst,         sim_fst);
2317         register_sim(op_ia32_vFtstFnstsw,  sim_FtstFnstsw);
2318         register_sim(op_ia32_vFucomFnstsw, sim_Fucom);
2319         register_sim(op_ia32_vFucomi,      sim_Fucom);
2320         register_sim(op_be_Copy,           sim_Copy);
2321         register_sim(op_be_Call,           sim_Call);
2322         register_sim(op_be_Spill,          sim_Spill);
2323         register_sim(op_be_Reload,         sim_Reload);
2324         register_sim(op_be_Return,         sim_Return);
2325         register_sim(op_be_Perm,           sim_Perm);
2326         register_sim(op_be_Keep,           sim_Keep);
2327         register_sim(op_be_Barrier,        sim_Barrier);
2328 }  /* x87_init_simulator */
2329
2330 /**
2331  * Destroy a x87 simulator.
2332  *
2333  * @param sim  the simulator handle
2334  */
2335 static void x87_destroy_simulator(x87_simulator *sim) {
2336         pmap_destroy(sim->blk_states);
2337         obstack_free(&sim->obst, NULL);
2338         DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
2339 }  /* x87_destroy_simulator */
2340
2341 /**
2342  * Pre-block walker: calculate the liveness information for the block
2343  * and store it into the sim->live cache.
2344  */
2345 static void update_liveness_walker(ir_node *block, void *data) {
2346         x87_simulator *sim = data;
2347         update_liveness(sim, block);
2348 }  /* update_liveness_walker */
2349
2350 /**
2351  * Run a simulation and fix all virtual instructions for a graph.
2352  *
2353  * @param env       the architecture environment
2354  * @param irg       the current graph
2355  *
2356  * Needs a block-schedule.
2357  */
2358 void x87_simulate_graph(const arch_env_t *arch_env, be_irg_t *birg) {
2359         ir_node       *block, *start_block;
2360         blk_state     *bl_state;
2361         x87_simulator sim;
2362         ir_graph      *irg = be_get_birg_irg(birg);
2363
2364         /* create the simulator */
2365         x87_init_simulator(&sim, irg, arch_env);
2366
2367         start_block = get_irg_start_block(irg);
2368         bl_state    = x87_get_bl_state(&sim, start_block);
2369
2370         /* start with the empty state */
2371         bl_state->begin = empty;
2372         empty->sim      = &sim;
2373
2374         sim.worklist = new_waitq();
2375         waitq_put(sim.worklist, start_block);
2376
2377         be_assure_liveness(birg);
2378         sim.lv = be_get_birg_liveness(birg);
2379 //      sim.lv = be_liveness(be_get_birg_irg(birg));
2380         be_liveness_assure_sets(sim.lv);
2381
2382         /* Calculate the liveness for all nodes. We must precalculate this info,
2383          * because the simulator adds new nodes (possible before Phi nodes) which
2384          * would let a lazy calculation fail.
2385          * On the other hand we reduce the computation amount due to
2386          * precaching from O(n^2) to O(n) at the expense of O(n) cache memory.
2387          */
2388         irg_block_walk_graph(irg, update_liveness_walker, NULL, &sim);
2389
2390         /* iterate */
2391         do {
2392                 block = waitq_get(sim.worklist);
2393                 x87_simulate_block(&sim, block);
2394         } while (! waitq_empty(sim.worklist));
2395
2396         /* kill it */
2397         del_waitq(sim.worklist);
2398         x87_destroy_simulator(&sim);
2399 }  /* x87_simulate_graph */
2400
2401 void ia32_init_x87(void) {
2402         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.x87");
2403 }  /* ia32_init_x87 */