- support for Ftst instruction, AM support for x87 float
[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  * @return NO_NODE_ADDED
1373  */
1374 static int sim_FucomFnstsw(x87_state *state, ir_node *n) {
1375         int op1_idx;
1376         int op2_idx = -1;
1377         int pop_cnt = 0;
1378         ia32_x87_attr_t *attr = get_ia32_x87_attr(n);
1379         ir_op *dst;
1380         x87_simulator         *sim = state->sim;
1381         ir_node               *op1_node = get_irn_n(n, n_ia32_vFucomFnstsw_left);
1382         ir_node               *op2_node = get_irn_n(n, n_ia32_vFucomFnstsw_right);
1383         const arch_register_t *op1      = x87_get_irn_register(sim, op1_node);
1384         const arch_register_t *op2      = x87_get_irn_register(sim, op2_node);
1385         int reg_index_1 = arch_register_get_index(op1);
1386         int reg_index_2 = arch_register_get_index(op2);
1387         unsigned live = vfp_live_args_after(sim, n, 0);
1388         int                    flipped  = attr->attr.data.cmp_flipped;
1389         int xchg = 0;
1390
1391         DB((dbg, LEVEL_1, ">>> %+F %s, %s\n", n,
1392                 arch_register_get_name(op1), arch_register_get_name(op2)));
1393         DEBUG_ONLY(vfp_dump_live(live));
1394         DB((dbg, LEVEL_1, "Stack before: "));
1395         DEBUG_ONLY(x87_dump_stack(state));
1396
1397         op1_idx = x87_on_stack(state, reg_index_1);
1398         assert(op1_idx >= 0);
1399
1400         /* BEWARE: check for comp a,a cases, they might happen */
1401         if (reg_index_2 != REG_VFP_NOREG) {
1402                 /* second operand is a vfp register */
1403                 op2_idx = x87_on_stack(state, reg_index_2);
1404                 assert(op2_idx >= 0);
1405
1406                 if (is_vfp_live(arch_register_get_index(op2), live)) {
1407                         /* second operand is live */
1408
1409                         if (is_vfp_live(arch_register_get_index(op1), live)) {
1410                                 /* both operands are live */
1411
1412                                 if (op1_idx == 0) {
1413                                         /* res = tos X op */
1414                                         dst = op_ia32_FucomFnstsw;
1415                                 } else if (op2_idx == 0) {
1416                                         /* res = op X tos */
1417                                         dst     = op_ia32_FucomFnstsw;
1418                                         flipped = !flipped;
1419                                         xchg    = 1;
1420                                 } else {
1421                                         /* bring the first one to tos */
1422                                         x87_create_fxch(state, n, op1_idx);
1423                                         if (op2_idx == 0)
1424                                                 op2_idx = op1_idx;
1425                                         op1_idx = 0;
1426                                         /* res = tos X op */
1427                                         dst     = op_ia32_FucomFnstsw;
1428                                 }
1429                         } else {
1430                                 /* second live, first operand is dead here, bring it to tos.
1431                                    This means further, op1_idx != op2_idx. */
1432                                 assert(op1_idx != op2_idx);
1433                                 if (op1_idx != 0) {
1434                                         x87_create_fxch(state, n, op1_idx);
1435                                         if (op2_idx == 0)
1436                                                 op2_idx = op1_idx;
1437                                         op1_idx = 0;
1438                                 }
1439                                 /* res = tos X op, pop */
1440                                 dst     = op_ia32_FucompFnstsw;
1441                                 pop_cnt = 1;
1442                         }
1443                 } else {
1444                         /* second operand is dead */
1445                         if (is_vfp_live(arch_register_get_index(op1), live)) {
1446                                 /* first operand is live: bring second to tos.
1447                                    This means further, op1_idx != op2_idx. */
1448                                 assert(op1_idx != op2_idx);
1449                                 if (op2_idx != 0) {
1450                                         x87_create_fxch(state, n, op2_idx);
1451                                         if (op1_idx == 0)
1452                                                 op1_idx = op2_idx;
1453                                         op2_idx = 0;
1454                                 }
1455                                 /* res = op X tos, pop */
1456                                 dst     = op_ia32_FucompFnstsw;
1457                                 flipped = !flipped;
1458                                 xchg    = 1;
1459                                 pop_cnt = 1;
1460                         } else {
1461                                 /* both operands are dead here, check first for identity. */
1462                                 if (op1_idx == op2_idx) {
1463                                         /* identically, one pop needed */
1464                                         if (op1_idx != 0) {
1465                                                 x87_create_fxch(state, n, op1_idx);
1466                                                 op1_idx = 0;
1467                                                 op2_idx = 0;
1468                                         }
1469                                         /* res = tos X op, pop */
1470                                         dst     = op_ia32_FucompFnstsw;
1471                                         pop_cnt = 1;
1472                                 }
1473                                 /* different, move them to st and st(1) and pop both.
1474                                    The tricky part is to get one into st(1).*/
1475                                 else if (op2_idx == 1) {
1476                                         /* good, second operand is already in the right place, move the first */
1477                                         if (op1_idx != 0) {
1478                                                 /* bring the first on top */
1479                                                 x87_create_fxch(state, n, op1_idx);
1480                                                 assert(op2_idx != 0);
1481                                                 op1_idx = 0;
1482                                         }
1483                                         /* res = tos X op, pop, pop */
1484                                         dst     = op_ia32_FucomppFnstsw;
1485                                         pop_cnt = 2;
1486                                 } else if (op1_idx == 1) {
1487                                         /* good, first operand is already in the right place, move the second */
1488                                         if (op2_idx != 0) {
1489                                                 /* bring the first on top */
1490                                                 x87_create_fxch(state, n, op2_idx);
1491                                                 assert(op1_idx != 0);
1492                                                 op2_idx = 0;
1493                                         }
1494                                         /* res = op X tos, pop, pop */
1495                                         dst     = op_ia32_FucomppFnstsw;
1496                                         flipped = !flipped;
1497                                         xchg    = 1;
1498                                         pop_cnt = 2;
1499                                 } else {
1500                                         /* if one is already the TOS, we need two fxch */
1501                                         if (op1_idx == 0) {
1502                                                 /* first one is TOS, move to st(1) */
1503                                                 x87_create_fxch(state, n, 1);
1504                                                 assert(op2_idx != 1);
1505                                                 op1_idx = 1;
1506                                                 x87_create_fxch(state, n, op2_idx);
1507                                                 op2_idx = 0;
1508                                                 /* res = op X tos, pop, pop */
1509                                                 dst     = op_ia32_FucomppFnstsw;
1510                                                 flipped = !flipped;
1511                                                 xchg    = 1;
1512                                                 pop_cnt = 2;
1513                                         } else if (op2_idx == 0) {
1514                                                 /* second one is TOS, move to st(1) */
1515                                                 x87_create_fxch(state, n, 1);
1516                                                 assert(op1_idx != 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                                                 dst     = op_ia32_FucomppFnstsw;
1522                                                 pop_cnt = 2;
1523                                         } else {
1524                                                 /* none of them is either TOS or st(1), 3 fxch needed */
1525                                                 x87_create_fxch(state, n, op2_idx);
1526                                                 assert(op1_idx != 0);
1527                                                 x87_create_fxch(state, n, 1);
1528                                                 op2_idx = 1;
1529                                                 x87_create_fxch(state, n, op1_idx);
1530                                                 op1_idx = 0;
1531                                                 /* res = tos X op, pop, pop */
1532                                                 dst     = op_ia32_FucomppFnstsw;
1533                                                 pop_cnt = 2;
1534                                         }
1535                                 }
1536                         }
1537                 }
1538         } else {
1539                 /* second operand is an address mode */
1540                 if (is_vfp_live(arch_register_get_index(op1), live)) {
1541                         /* first operand is live: bring it to TOS */
1542                         if (op1_idx != 0) {
1543                                 x87_create_fxch(state, n, op1_idx);
1544                                 op1_idx = 0;
1545                         }
1546                         dst = op_ia32_FucomFnstsw;
1547                 } else {
1548                         /* first operand is dead: bring it to tos */
1549                         if (op1_idx != 0) {
1550                                 x87_create_fxch(state, n, op1_idx);
1551                                 op1_idx = 0;
1552                         }
1553                         dst = op_ia32_FucompFnstsw;
1554                         pop_cnt = 1;
1555                 }
1556         }
1557
1558         x87_patch_insn(n, dst);
1559         assert(pop_cnt < 3);
1560         if (pop_cnt >= 2)
1561                 x87_pop(state);
1562         if (pop_cnt >= 1)
1563                 x87_pop(state);
1564
1565         if(xchg) {
1566                 int tmp = op1_idx;
1567                 op1_idx = op2_idx;
1568                 op2_idx = tmp;
1569         }
1570
1571         /* patch the operation */
1572         op1 = &ia32_st_regs[op1_idx];
1573         attr->x87[0] = op1;
1574         if (op2_idx >= 0) {
1575                 op2 = &ia32_st_regs[op2_idx];
1576                 attr->x87[1] = op2;
1577         }
1578         attr->x87[2] = NULL;
1579         attr->attr.data.cmp_flipped = flipped;
1580
1581         if (op2_idx >= 0)
1582                 DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(n),
1583                         arch_register_get_name(op1), arch_register_get_name(op2)));
1584         else
1585                 DB((dbg, LEVEL_1, "<<< %s %s, [AM]\n", get_irn_opname(n),
1586                         arch_register_get_name(op1)));
1587
1588         return NO_NODE_ADDED;
1589 }
1590
1591 static int sim_Keep(x87_state *state, ir_node *node)
1592 {
1593         const ir_node         *op;
1594         const arch_register_t *op_reg;
1595         int                    reg_id;
1596         int                    op_stack_idx;
1597         unsigned               live;
1598         int                    i, arity;
1599         int                    node_added = NO_NODE_ADDED;
1600
1601         DB((dbg, LEVEL_1, ">>> %+F\n", node));
1602
1603         arity = get_irn_arity(node);
1604         for(i = 0; i < arity; ++i) {
1605                 op      = get_irn_n(node, i);
1606                 op_reg  = arch_get_irn_register(state->sim->arch_env, op);
1607                 if(arch_register_get_class(op_reg) != &ia32_reg_classes[CLASS_ia32_vfp])
1608                         continue;
1609
1610                 reg_id = arch_register_get_index(op_reg);
1611                 live   = vfp_live_args_after(state->sim, node, 0);
1612
1613                 op_stack_idx = x87_on_stack(state, reg_id);
1614                 if(op_stack_idx >= 0 && !is_vfp_live(reg_id, live)) {
1615                         x87_create_fpop(state, sched_next(node), 1);
1616                         node_added = NODE_ADDED;
1617                 }
1618         }
1619
1620         DB((dbg, LEVEL_1, "Stack after: "));
1621         DEBUG_ONLY(x87_dump_stack(state));
1622
1623         return node_added;
1624 }
1625
1626 static
1627 void keep_float_node_alive(x87_state *state, ir_node *node)
1628 {
1629         ir_graph                    *irg;
1630         ir_node                     *block;
1631         ir_node                     *in[1];
1632         ir_node                     *keep;
1633         const arch_register_class_t *cls;
1634
1635         irg    = get_irn_irg(node);
1636         block  = get_nodes_block(node);
1637         cls    = arch_get_irn_reg_class(state->sim->arch_env, node, -1);
1638         in[0]  = node;
1639         keep   = be_new_Keep(cls, irg, block, 1, in);
1640
1641         assert(sched_is_scheduled(node));
1642         sched_add_after(node, keep);
1643 }
1644
1645 /**
1646  * Create a copy of a node. Recreate the node if it's a constant.
1647  *
1648  * @param state  the x87 state
1649  * @param n      the node to be copied
1650  *
1651  * @return the copy of n
1652  */
1653 static ir_node *create_Copy(x87_state *state, ir_node *n) {
1654         x87_simulator *sim = state->sim;
1655         ir_graph *irg = get_irn_irg(n);
1656         dbg_info *n_dbg = get_irn_dbg_info(n);
1657         ir_mode *mode = get_irn_mode(n);
1658         ir_node *block = get_nodes_block(n);
1659         ir_node *pred = get_irn_n(n, 0);
1660         ir_node *(*cnstr)(dbg_info *, ir_graph *, ir_node *, ir_mode *) = NULL;
1661         ir_node *res;
1662         const arch_register_t *out;
1663         const arch_register_t *op1;
1664         ia32_x87_attr_t *attr;
1665
1666         /* Do not copy constants, recreate them. */
1667         switch (get_ia32_irn_opcode(pred)) {
1668         case iro_ia32_Unknown_VFP:
1669         case iro_ia32_fldz:
1670                 cnstr = new_rd_ia32_fldz;
1671                 break;
1672         case iro_ia32_fld1:
1673                 cnstr = new_rd_ia32_fld1;
1674                 break;
1675         case iro_ia32_fldpi:
1676                 cnstr = new_rd_ia32_fldpi;
1677                 break;
1678         case iro_ia32_fldl2e:
1679                 cnstr = new_rd_ia32_fldl2e;
1680                 break;
1681         case iro_ia32_fldl2t:
1682                 cnstr = new_rd_ia32_fldl2t;
1683                 break;
1684         case iro_ia32_fldlg2:
1685                 cnstr = new_rd_ia32_fldlg2;
1686                 break;
1687         case iro_ia32_fldln2:
1688                 cnstr = new_rd_ia32_fldln2;
1689                 break;
1690         default:
1691                 break;
1692         }
1693
1694         out = x87_get_irn_register(sim, n);
1695         op1 = x87_get_irn_register(sim, pred);
1696
1697         if (cnstr != NULL) {
1698                 /* copy a constant */
1699                 res = (*cnstr)(n_dbg, irg, block, mode);
1700
1701                 x87_push(state, arch_register_get_index(out), res);
1702
1703                 attr = get_ia32_x87_attr(res);
1704                 attr->x87[2] = &ia32_st_regs[0];
1705         } else {
1706                 int op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1707
1708                 res = new_rd_ia32_fpushCopy(n_dbg, irg, block, pred, mode);
1709
1710                 x87_push(state, arch_register_get_index(out), res);
1711
1712                 attr = get_ia32_x87_attr(res);
1713                 attr->x87[0] = &ia32_st_regs[op1_idx];
1714                 attr->x87[2] = &ia32_st_regs[0];
1715         }
1716         arch_set_irn_register(sim->arch_env, res, out);
1717
1718         return res;
1719 }  /* create_Copy */
1720
1721 /**
1722  * Simulate a be_Copy.
1723  *
1724  * @param state  the x87 state
1725  * @param n      the node that should be simulated (and patched)
1726  *
1727  * @return NO_NODE_ADDED
1728  */
1729 static int sim_Copy(x87_state *state, ir_node *n) {
1730         x87_simulator               *sim = state->sim;
1731         ir_node                     *pred;
1732         const arch_register_t       *out;
1733         const arch_register_t       *op1;
1734         const arch_register_class_t *class;
1735         ir_node                     *node, *next;
1736         ia32_x87_attr_t             *attr;
1737         int                         op1_idx, out_idx;
1738         unsigned                    live;
1739
1740         class = arch_get_irn_reg_class(sim->arch_env, n, -1);
1741         if (class->regs != ia32_vfp_regs)
1742                 return 0;
1743
1744         pred = get_irn_n(n, 0);
1745         out  = x87_get_irn_register(sim, n);
1746         op1  = x87_get_irn_register(sim, pred);
1747         live = vfp_live_args_after(sim, n, REGMASK(out));
1748
1749         DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", n,
1750                 arch_register_get_name(op1), arch_register_get_name(out)));
1751         DEBUG_ONLY(vfp_dump_live(live));
1752
1753         /* handle the infamous unknown value */
1754         if (arch_register_get_index(op1) == REG_VFP_UKNWN) {
1755                 /* Operand is still live, a real copy. We need here an fpush that can
1756                    hold a a register, so use the fpushCopy or recreate constants */
1757                 node = create_Copy(state, n);
1758
1759                 assert(is_ia32_fldz(node));
1760                 next = sched_next(n);
1761                 sched_remove(n);
1762                 exchange(n, node);
1763                 sched_add_before(next, node);
1764
1765                 DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name,
1766                     arch_get_irn_register(sim->arch_env, node)->name));
1767                 return NO_NODE_ADDED;
1768         }
1769
1770         op1_idx = x87_on_stack(state, arch_register_get_index(op1));
1771
1772         if (is_vfp_live(arch_register_get_index(op1), live)) {
1773                 ir_node *pred = get_irn_n(n, 0);
1774
1775                 /* Operand is still live, a real copy. We need here an fpush that can
1776                    hold a a register, so use the fpushCopy or recreate constants */
1777                 node = create_Copy(state, n);
1778
1779                 /* We have to make sure the old value doesn't go dead (which can happen
1780                  * when we recreate constants). As the simulator expected that value in
1781                  * the pred blocks. This is unfortunate as removing it would save us 1
1782                  * instruction, but we would have to rerun all the simulation to get
1783                  * this correct...
1784                  */
1785                 next = sched_next(n);
1786                 sched_remove(n);
1787                 exchange(n, node);
1788                 sched_add_before(next, node);
1789
1790                 if(get_irn_n_edges(pred) == 0) {
1791                         keep_float_node_alive(state, pred);
1792                 }
1793
1794                 DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name,
1795                     arch_get_irn_register(sim->arch_env, node)->name));
1796         } else {
1797                 out_idx = x87_on_stack(state, arch_register_get_index(out));
1798
1799                 if (out_idx >= 0 && out_idx != op1_idx) {
1800                         /* Matze: out already on stack? how can this happen? */
1801                         assert(0);
1802
1803                         /* op1 must be killed and placed where out is */
1804                         if (out_idx == 0) {
1805                                 /* best case, simple remove and rename */
1806                                 x87_patch_insn(n, op_ia32_Pop);
1807                                 attr = get_ia32_x87_attr(n);
1808                                 attr->x87[0] = op1 = &ia32_st_regs[0];
1809
1810                                 x87_pop(state);
1811                                 x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
1812                         } else {
1813                                 /* move op1 to tos, store and pop it */
1814                                 if (op1_idx != 0) {
1815                                         x87_create_fxch(state, n, op1_idx);
1816                                         op1_idx = 0;
1817                                 }
1818                                 x87_patch_insn(n, op_ia32_Pop);
1819                                 attr = get_ia32_x87_attr(n);
1820                                 attr->x87[0] = op1 = &ia32_st_regs[out_idx];
1821
1822                                 x87_pop(state);
1823                                 x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
1824                         }
1825                         DB((dbg, LEVEL_1, "<<< %+F %s\n", n, op1->name));
1826                 } else {
1827                         /* just a virtual copy */
1828                         x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
1829                         /* don't remove the node to keep the verifier quiet :),
1830                            the emitter won't emit any code for the node */
1831 #if 0
1832                         sched_remove(n);
1833                         DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n)));
1834                         exchange(n, get_unop_op(n));
1835 #endif
1836                 }
1837         }
1838         return NO_NODE_ADDED;
1839 }  /* sim_Copy */
1840
1841 /**
1842  * Returns the result proj of the call
1843  */
1844 static ir_node *get_call_result_proj(ir_node *call) {
1845         const ir_edge_t *edge;
1846
1847         /* search the result proj */
1848         foreach_out_edge(call, edge) {
1849                 ir_node *proj = get_edge_src_irn(edge);
1850                 long pn = get_Proj_proj(proj);
1851
1852                 if (pn == pn_be_Call_first_res) {
1853                         return proj;
1854                 }
1855         }
1856
1857         return NULL;
1858 }  /* get_call_result_proj */
1859
1860 /**
1861  * Simulate a be_Call.
1862  *
1863  * @param state      the x87 state
1864  * @param n          the node that should be simulated
1865  * @param arch_env   the architecture environment
1866  *
1867  * @return NO_NODE_ADDED
1868  */
1869 static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *arch_env)
1870 {
1871         ir_type *call_tp = be_Call_get_type(n);
1872         ir_type *res_type;
1873         ir_mode *mode;
1874         ir_node *resproj;
1875         const arch_register_t *reg;
1876         (void) arch_env;
1877
1878         DB((dbg, LEVEL_1, ">>> %+F\n", n));
1879
1880         /* at the begin of a call the x87 state should be empty */
1881         assert(state->depth == 0 && "stack not empty before call");
1882
1883         if (get_method_n_ress(call_tp) <= 0)
1884                 goto end_call;
1885
1886         /*
1887          * If the called function returns a float, it is returned in st(0).
1888          * This even happens if the return value is NOT used.
1889          * Moreover, only one return result is supported.
1890          */
1891         res_type = get_method_res_type(call_tp, 0);
1892         mode     = get_type_mode(res_type);
1893
1894         if (mode == NULL || !mode_is_float(mode))
1895                 goto end_call;
1896
1897         resproj = get_call_result_proj(n);
1898         assert(resproj != NULL);
1899
1900         reg = x87_get_irn_register(state->sim, resproj);
1901         x87_push(state, arch_register_get_index(reg), resproj);
1902
1903 end_call:
1904         DB((dbg, LEVEL_1, "Stack after: "));
1905         DEBUG_ONLY(x87_dump_stack(state));
1906
1907         return NO_NODE_ADDED;
1908 }  /* sim_Call */
1909
1910 /**
1911  * Simulate a be_Spill.
1912  *
1913  * @param state  the x87 state
1914  * @param n      the node that should be simulated (and patched)
1915  *
1916  * Should not happen, spills are lowered before x87 simulator see them.
1917  */
1918 static int sim_Spill(x87_state *state, ir_node *n) {
1919         assert(0 && "Spill not lowered");
1920         return sim_fst(state, n);
1921 }  /* sim_Spill */
1922
1923 /**
1924  * Simulate a be_Reload.
1925  *
1926  * @param state  the x87 state
1927  * @param n      the node that should be simulated (and patched)
1928  *
1929  * Should not happen, reloads are lowered before x87 simulator see them.
1930  */
1931 static int sim_Reload(x87_state *state, ir_node *n) {
1932         assert(0 && "Reload not lowered");
1933         return sim_fld(state, n);
1934 }  /* sim_Reload */
1935
1936 /**
1937  * Simulate a be_Return.
1938  *
1939  * @param state  the x87 state
1940  * @param n      the node that should be simulated (and patched)
1941  *
1942  * @return NO_NODE_ADDED
1943  */
1944 static int sim_Return(x87_state *state, ir_node *n) {
1945         int n_res = be_Return_get_n_rets(n);
1946         int i, n_float_res = 0;
1947
1948         /* only floating point return values must resist on stack */
1949         for (i = 0; i < n_res; ++i) {
1950                 ir_node *res = get_irn_n(n, be_pos_Return_val + i);
1951
1952                 if (mode_is_float(get_irn_mode(res)))
1953                         ++n_float_res;
1954         }
1955         assert(x87_get_depth(state) == n_float_res);
1956
1957         /* pop them virtually */
1958         for (i = n_float_res - 1; i >= 0; --i)
1959                 x87_pop(state);
1960
1961         return NO_NODE_ADDED;
1962 }  /* sim_Return */
1963
1964 typedef struct _perm_data_t {
1965         const arch_register_t *in;
1966         const arch_register_t *out;
1967 } perm_data_t;
1968
1969 /**
1970  * Simulate a be_Perm.
1971  *
1972  * @param state  the x87 state
1973  * @param irn    the node that should be simulated (and patched)
1974  *
1975  * @return NO_NODE_ADDED
1976  */
1977 static int sim_Perm(x87_state *state, ir_node *irn) {
1978         int             i, n;
1979         x87_simulator   *sim = state->sim;
1980         ir_node         *pred = get_irn_n(irn, 0);
1981         int             *stack_pos;
1982         const ir_edge_t *edge;
1983
1984         /* handle only floating point Perms */
1985         if (! mode_is_float(get_irn_mode(pred)))
1986                 return NO_NODE_ADDED;
1987
1988         DB((dbg, LEVEL_1, ">>> %+F\n", irn));
1989
1990         /* Perm is a pure virtual instruction on x87.
1991            All inputs must be on the FPU stack and are pairwise
1992            different from each other.
1993            So, all we need to do is to permutate the stack state. */
1994         n = get_irn_arity(irn);
1995         NEW_ARR_A(int, stack_pos, n);
1996
1997         /* collect old stack positions */
1998         for (i = 0; i < n; ++i) {
1999                 const arch_register_t *inreg = x87_get_irn_register(sim, get_irn_n(irn, i));
2000                 int idx = x87_on_stack(state, arch_register_get_index(inreg));
2001
2002                 assert(idx >= 0 && "Perm argument not on x87 stack");
2003
2004                 stack_pos[i] = idx;
2005         }
2006         /* now do the permutation */
2007         foreach_out_edge(irn, edge) {
2008                 ir_node               *proj = get_edge_src_irn(edge);
2009                 const arch_register_t *out  = x87_get_irn_register(sim, proj);
2010                 long                  num   = get_Proj_proj(proj);
2011
2012                 assert(0 <= num && num < n && "More Proj's than Perm inputs");
2013                 x87_set_st(state, arch_register_get_index(out), proj, stack_pos[(unsigned)num]);
2014         }
2015         DB((dbg, LEVEL_1, "<<< %+F\n", irn));
2016
2017         return NO_NODE_ADDED;
2018 }  /* sim_Perm */
2019
2020 static int sim_Barrier(x87_state *state, ir_node *node) {
2021         //const arch_env_t *arch_env = state->sim->arch_env;
2022         int i, arity;
2023
2024         /* materialize unknown if needed */
2025         arity = get_irn_arity(node);
2026         for(i = 0; i < arity; ++i) {
2027                 const arch_register_t       *reg;
2028                 ir_node                     *zero;
2029                 ir_node                     *block;
2030                 ia32_x87_attr_t             *attr;
2031                 ir_node                     *in    = get_irn_n(node, i);
2032
2033                 if(!is_ia32_Unknown_VFP(in))
2034                         continue;
2035
2036                 /* TODO: not completely correct... */
2037                 reg = &ia32_vfp_regs[REG_VFP_UKNWN];
2038
2039                 /* create a zero */
2040                 block = get_nodes_block(node);
2041                 zero  = new_rd_ia32_fldz(NULL, current_ir_graph, block, mode_E);
2042                 x87_push(state, arch_register_get_index(reg), zero);
2043
2044                 attr = get_ia32_x87_attr(zero);
2045                 attr->x87[2] = &ia32_st_regs[0];
2046
2047                 sched_add_before(node, zero);
2048
2049                 set_irn_n(node, i, zero);
2050         }
2051
2052         return NO_NODE_ADDED;
2053 }
2054
2055
2056 /**
2057  * Kill any dead registers at block start by popping them from the stack.
2058  *
2059  * @param sim          the simulator handle
2060  * @param block        the current block
2061  * @param start_state  the x87 state at the begin of the block
2062  *
2063  * @return the x87 state after dead register killed
2064  */
2065 static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *start_state) {
2066         x87_state *state = start_state;
2067         ir_node *first_insn = sched_first(block);
2068         ir_node *keep = NULL;
2069         unsigned live = vfp_live_args_after(sim, block, 0);
2070         unsigned kill_mask;
2071         int i, depth, num_pop;
2072
2073         kill_mask = 0;
2074         depth = x87_get_depth(state);
2075         for (i = depth - 1; i >= 0; --i) {
2076                 int reg = x87_get_st_reg(state, i);
2077
2078                 if (! is_vfp_live(reg, live))
2079                         kill_mask |= (1 << i);
2080         }
2081
2082         if (kill_mask) {
2083                 /* create a new state, will be changed */
2084                 state = x87_clone_state(sim, state);
2085
2086                 DB((dbg, LEVEL_1, "Killing deads:\n"));
2087                 DEBUG_ONLY(vfp_dump_live(live));
2088                 DEBUG_ONLY(x87_dump_stack(state));
2089
2090                 if (kill_mask != 0 && live == 0) {
2091                         int cpu = sim->isa->arch;
2092
2093                         /* special case: kill all registers */
2094                         if (ARCH_ATHLON(sim->isa->opt_arch) && ARCH_MMX(cpu)) {
2095                                 if (ARCH_AMD(cpu)) {
2096                                         /* use FEMMS on AMD processors to clear all */
2097                                         keep = new_rd_ia32_femms(NULL, get_irn_irg(block), block);
2098                                 } else {
2099                                         /* use EMMS to clear all */
2100                                         keep = new_rd_ia32_emms(NULL, get_irn_irg(block), block);
2101                                 }
2102                                 sched_add_before(first_insn, keep);
2103                                 keep_alive(keep);
2104                                 x87_emms(state);
2105                                 return state;
2106                         }
2107                 }
2108                 /* now kill registers */
2109                 while (kill_mask) {
2110                         /* we can only kill from TOS, so bring them up */
2111                         if (! (kill_mask & 1)) {
2112                                 /* search from behind, because we can to a double-pop */
2113                                 for (i = depth - 1; i >= 0; --i) {
2114                                         if (kill_mask & (1 << i)) {
2115                                                 kill_mask &= ~(1 << i);
2116                                                 kill_mask |= 1;
2117                                                 break;
2118                                         }
2119                                 }
2120
2121                                 if (keep)
2122                                         x87_set_st(state, -1, keep, i);
2123                                 x87_create_fxch(state, first_insn, i);
2124                         }
2125
2126                         if ((kill_mask & 3) == 3) {
2127                                 /* we can do a double-pop */
2128                                 num_pop = 2;
2129                         }
2130                         else {
2131                                 /* only a single pop */
2132                                 num_pop = 1;
2133                         }
2134
2135                         depth -= num_pop;
2136                         kill_mask >>= num_pop;
2137                         keep = x87_create_fpop(state, first_insn, num_pop);
2138                 }
2139                 keep_alive(keep);
2140         }
2141         return state;
2142 }  /* x87_kill_deads */
2143
2144 /**
2145  * If we have PhiEs with unknown operands then we have to make sure that some
2146  * value is actually put onto the stack.
2147  */
2148 static void fix_unknown_phis(x87_state *state, ir_node *block,
2149                              ir_node *pred_block, int pos)
2150 {
2151         ir_node *node, *op;
2152
2153         sched_foreach(block, node) {
2154                 ir_node               *zero;
2155                 const arch_register_t *reg;
2156                 ia32_x87_attr_t       *attr;
2157
2158                 if(!is_Phi(node))
2159                         break;
2160
2161                 op = get_Phi_pred(node, pos);
2162                 if(!is_ia32_Unknown_VFP(op))
2163                         continue;
2164
2165                 reg = arch_get_irn_register(state->sim->arch_env, node);
2166
2167                 /* create a zero at end of pred block */
2168                 zero = new_rd_ia32_fldz(NULL, current_ir_graph, pred_block, mode_E);
2169                 x87_push(state, arch_register_get_index(reg), zero);
2170
2171                 attr = get_ia32_x87_attr(zero);
2172                 attr->x87[2] = &ia32_st_regs[0];
2173
2174                 assert(is_ia32_fldz(zero));
2175                 sched_add_before(sched_last(pred_block), zero);
2176
2177                 set_Phi_pred(node, pos, zero);
2178         }
2179 }
2180
2181 /**
2182  * Run a simulation and fix all virtual instructions for a block.
2183  *
2184  * @param sim          the simulator handle
2185  * @param block        the current block
2186  */
2187 static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
2188         ir_node *n, *next;
2189         blk_state *bl_state = x87_get_bl_state(sim, block);
2190         x87_state *state = bl_state->begin;
2191         const ir_edge_t *edge;
2192         ir_node *start_block;
2193
2194         assert(state != NULL);
2195         /* already processed? */
2196         if (bl_state->end != NULL)
2197                 return;
2198
2199         DB((dbg, LEVEL_1, "Simulate %+F\n", block));
2200         DB((dbg, LEVEL_2, "State at Block begin:\n "));
2201         DEBUG_ONLY(x87_dump_stack(state));
2202
2203         /* at block begin, kill all dead registers */
2204         state = x87_kill_deads(sim, block, state);
2205         /* create a new state, will be changed */
2206         state = x87_clone_state(sim, state);
2207
2208         /* beware, n might change */
2209         for (n = sched_first(block); !sched_is_end(n); n = next) {
2210                 int node_inserted;
2211                 sim_func func;
2212                 ir_op *op = get_irn_op(n);
2213
2214                 next = sched_next(n);
2215                 if (op->ops.generic == NULL)
2216                         continue;
2217
2218                 func = (sim_func)op->ops.generic;
2219
2220                 /* simulate it */
2221                 node_inserted = (*func)(state, n);
2222
2223                 /*
2224                         sim_func might have added an additional node after n,
2225                         so update next node
2226                         beware: n must not be changed by sim_func
2227                         (i.e. removed from schedule) in this case
2228                 */
2229                 if (node_inserted != NO_NODE_ADDED)
2230                         next = sched_next(n);
2231         }
2232
2233         start_block = get_irg_start_block(get_irn_irg(block));
2234
2235         DB((dbg, LEVEL_2, "State at Block end:\n ")); DEBUG_ONLY(x87_dump_stack(state));
2236
2237         /* check if the state must be shuffled */
2238         foreach_block_succ(block, edge) {
2239                 ir_node *succ = get_edge_src_irn(edge);
2240                 blk_state *succ_state;
2241
2242                 if (succ == start_block)
2243                         continue;
2244
2245                 succ_state = x87_get_bl_state(sim, succ);
2246
2247                 fix_unknown_phis(state, succ, block, get_edge_src_pos(edge));
2248
2249                 if (succ_state->begin == NULL) {
2250                         DB((dbg, LEVEL_2, "Set begin state for succ %+F:\n", succ));
2251                         DEBUG_ONLY(x87_dump_stack(state));
2252                         succ_state->begin = state;
2253
2254                         waitq_put(sim->worklist, succ);
2255                 } else {
2256                         DB((dbg, LEVEL_2, "succ %+F already has a state, shuffling\n", succ));
2257                         /* There is already a begin state for the successor, bad.
2258                            Do the necessary permutations.
2259                            Note that critical edges are removed, so this is always possible:
2260                            If the successor has more than one possible input, then it must
2261                            be the only one.
2262                          */
2263                         x87_shuffle(sim, block, state, succ, succ_state->begin);
2264                 }
2265         }
2266         bl_state->end = state;
2267 }  /* x87_simulate_block */
2268
2269 /**
2270  * Create a new x87 simulator.
2271  *
2272  * @param sim       a simulator handle, will be initialized
2273  * @param irg       the current graph
2274  * @param arch_env  the architecture environment
2275  */
2276 static void x87_init_simulator(x87_simulator *sim, ir_graph *irg,
2277                                const arch_env_t *arch_env)
2278 {
2279         obstack_init(&sim->obst);
2280         sim->blk_states = pmap_create();
2281         sim->arch_env   = arch_env;
2282         sim->n_idx      = get_irg_last_idx(irg);
2283         sim->live       = obstack_alloc(&sim->obst, sizeof(*sim->live) * sim->n_idx);
2284         sim->isa        = (ia32_isa_t *)arch_env->isa;
2285
2286         DB((dbg, LEVEL_1, "--------------------------------\n"
2287                 "x87 Simulator started for %+F\n", irg));
2288
2289         /* set the generic function pointer of instruction we must simulate */
2290         clear_irp_opcodes_generic_func();
2291
2292 #define ASSOC(op)       (op_ ## op)->ops.generic = (op_func)(sim_##op)
2293 #define ASSOC_IA32(op)  (op_ia32_v ## op)->ops.generic = (op_func)(sim_##op)
2294 #define ASSOC_BE(op)    (op_be_ ## op)->ops.generic = (op_func)(sim_##op)
2295         ASSOC_IA32(fld);
2296         ASSOC_IA32(fild);
2297         ASSOC_IA32(fld1);
2298         ASSOC_IA32(fldz);
2299         ASSOC_IA32(fadd);
2300         ASSOC_IA32(fsub);
2301         ASSOC_IA32(fmul);
2302         ASSOC_IA32(fdiv);
2303         ASSOC_IA32(fprem);
2304         ASSOC_IA32(fabs);
2305         ASSOC_IA32(fchs);
2306         ASSOC_IA32(fist);
2307         ASSOC_IA32(fst);
2308         ASSOC_IA32(FucomFnstsw);
2309         ASSOC_IA32(FtstFnstsw);
2310         ASSOC_BE(Copy);
2311         ASSOC_BE(Call);
2312         ASSOC_BE(Spill);
2313         ASSOC_BE(Reload);
2314         ASSOC_BE(Return);
2315         ASSOC_BE(Perm);
2316         ASSOC_BE(Keep);
2317         ASSOC_BE(Barrier);
2318 #undef ASSOC_BE
2319 #undef ASSOC_IA32
2320 #undef ASSOC
2321 }  /* x87_init_simulator */
2322
2323 /**
2324  * Destroy a x87 simulator.
2325  *
2326  * @param sim  the simulator handle
2327  */
2328 static void x87_destroy_simulator(x87_simulator *sim) {
2329         pmap_destroy(sim->blk_states);
2330         obstack_free(&sim->obst, NULL);
2331         DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
2332 }  /* x87_destroy_simulator */
2333
2334 /**
2335  * Pre-block walker: calculate the liveness information for the block
2336  * and store it into the sim->live cache.
2337  */
2338 static void update_liveness_walker(ir_node *block, void *data) {
2339         x87_simulator *sim = data;
2340         update_liveness(sim, block);
2341 }  /* update_liveness_walker */
2342
2343 /**
2344  * Run a simulation and fix all virtual instructions for a graph.
2345  *
2346  * @param env       the architecture environment
2347  * @param irg       the current graph
2348  *
2349  * Needs a block-schedule.
2350  */
2351 void x87_simulate_graph(const arch_env_t *arch_env, be_irg_t *birg) {
2352         ir_node       *block, *start_block;
2353         blk_state     *bl_state;
2354         x87_simulator sim;
2355         ir_graph      *irg = be_get_birg_irg(birg);
2356
2357         /* create the simulator */
2358         x87_init_simulator(&sim, irg, arch_env);
2359
2360         start_block = get_irg_start_block(irg);
2361         bl_state    = x87_get_bl_state(&sim, start_block);
2362
2363         /* start with the empty state */
2364         bl_state->begin = empty;
2365         empty->sim      = &sim;
2366
2367         sim.worklist = new_waitq();
2368         waitq_put(sim.worklist, start_block);
2369
2370         be_assure_liveness(birg);
2371         sim.lv = be_get_birg_liveness(birg);
2372 //      sim.lv = be_liveness(be_get_birg_irg(birg));
2373         be_liveness_assure_sets(sim.lv);
2374
2375         /* Calculate the liveness for all nodes. We must precalculate this info,
2376          * because the simulator adds new nodes (possible before Phi nodes) which
2377          * would let a lazy calculation fail.
2378          * On the other hand we reduce the computation amount due to
2379          * precaching from O(n^2) to O(n) at the expense of O(n) cache memory.
2380          */
2381         irg_block_walk_graph(irg, update_liveness_walker, NULL, &sim);
2382
2383         /* iterate */
2384         do {
2385                 block = waitq_get(sim.worklist);
2386                 x87_simulate_block(&sim, block);
2387         } while (! waitq_empty(sim.worklist));
2388
2389         /* kill it */
2390         del_waitq(sim.worklist);
2391         x87_destroy_simulator(&sim);
2392 }  /* x87_simulate_graph */
2393
2394 void ia32_init_x87(void) {
2395         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.x87");
2396 }  /* ia32_init_x87 */