rebuild edges after backend transform phase
[libfirm] / ir / be / ia32 / ia32_transform.c
1 /**
2  * This file implements the IR transformation from firm into ia32-Firm.
3  * @author Christian Wuerdig
4  * $Id$
5  */
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <limits.h>
11
12 #include "irargs_t.h"
13 #include "irnode_t.h"
14 #include "irgraph_t.h"
15 #include "irmode_t.h"
16 #include "iropt_t.h"
17 #include "irop_t.h"
18 #include "irprog_t.h"
19 #include "iredges_t.h"
20 #include "irgmod.h"
21 #include "irvrfy.h"
22 #include "ircons.h"
23 #include "irgwalk.h"
24 #include "dbginfo.h"
25 #include "irprintf.h"
26 #include "debug.h"
27 #include "irdom.h"
28 #include "type.h"
29 #include "entity.h"
30 #include "archop.h"     /* we need this for Min and Max nodes */
31 #include "error.h"
32 #include "cgana.h"
33 #include "irouts.h"
34 #include "trouts.h"
35 #include "irhooks.h"
36
37 #include "../benode_t.h"
38 #include "../besched.h"
39 #include "../beabi.h"
40 #include "../beutil.h"
41
42 #include "bearch_ia32_t.h"
43 #include "ia32_nodes_attr.h"
44 #include "ia32_transform.h"
45 #include "ia32_new_nodes.h"
46 #include "ia32_map_regs.h"
47 #include "ia32_dbg_stat.h"
48 #include "ia32_optimize.h"
49 #include "ia32_util.h"
50
51 #include "gen_ia32_regalloc_if.h"
52
53 #define SFP_SIGN "0x80000000"
54 #define DFP_SIGN "0x8000000000000000"
55 #define SFP_ABS  "0x7FFFFFFF"
56 #define DFP_ABS  "0x7FFFFFFFFFFFFFFF"
57
58 #define TP_SFP_SIGN "ia32_sfp_sign"
59 #define TP_DFP_SIGN "ia32_dfp_sign"
60 #define TP_SFP_ABS  "ia32_sfp_abs"
61 #define TP_DFP_ABS  "ia32_dfp_abs"
62
63 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
64 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
65 #define ENT_SFP_ABS  "IA32_SFP_ABS"
66 #define ENT_DFP_ABS  "IA32_DFP_ABS"
67
68 typedef struct ia32_transform_env_t {
69         ir_graph          *irg;        /**< The irg, the node should be created in */
70         ia32_code_gen_t   *cg;         /**< The code generator */
71         int               visited;     /**< visited count that indicates whether a
72                                             node is already transformed */
73         pdeq              *worklist;   /**< worklist of nodes that still need to be
74                                                                         transformed */
75         ir_node          **old_anchors;/**< the list of anchors nodes in the old irg*/
76         DEBUG_ONLY(firm_dbg_module_t *mod;) /**< The firm debugger */
77 } ia32_transform_env_t;
78
79 extern ir_op *get_op_Mulh(void);
80
81 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
82         ir_node *block, ir_node *base, ir_node *index, ir_node *op1,
83         ir_node *op2, ir_node *mem);
84
85 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
86         ir_node *block, ir_node *base, ir_node *index, ir_node *op,
87         ir_node *mem);
88
89 typedef ir_node *(transform_func)(ia32_transform_env_t *env, ir_node *node);
90
91 /****************************************************************************************************
92  *                  _        _                        __                           _   _
93  *                 | |      | |                      / _|                         | | (_)
94  *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
95  * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
96  * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
97  * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
98  *
99  ****************************************************************************************************/
100
101 static ir_node *duplicate_node(ia32_transform_env_t *env, ir_node *node);
102 static ir_node *transform_node(ia32_transform_env_t *env, ir_node *node);
103 static void duplicate_deps(ia32_transform_env_t *env, ir_node *old_node,
104                            ir_node *new_node);
105
106 static INLINE void set_new_node(ir_node *old_node, ir_node *new_node)
107 {
108         set_irn_link(old_node, new_node);
109 }
110
111 static INLINE ir_node *get_new_node(ir_node *old_node)
112 {
113         assert(irn_visited(old_node));
114         return (ir_node*) get_irn_link(old_node);
115 }
116
117 /**
118  * Returns 1 if irn is a Const representing 0, 0 otherwise
119  */
120 static INLINE int is_ia32_Const_0(ir_node *irn) {
121         return (is_ia32_irn(irn) && get_ia32_op_type(irn) == ia32_Const) ?
122                 classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_NULL : 0;
123 }
124
125 /**
126  * Returns 1 if irn is a Const representing 1, 0 otherwise
127  */
128 static INLINE int is_ia32_Const_1(ir_node *irn) {
129         return (is_ia32_irn(irn) && get_ia32_op_type(irn) == ia32_Const) ?
130                 classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_ONE : 0;
131 }
132
133 /**
134  * Collects all Projs of a node into the node array. Index is the projnum.
135  * BEWARE: The caller has to assure the appropriate array size!
136  */
137 static void ia32_collect_Projs(ir_node *irn, ir_node **projs, int size) {
138         const ir_edge_t *edge;
139         assert(get_irn_mode(irn) == mode_T && "need mode_T");
140
141         memset(projs, 0, size * sizeof(projs[0]));
142
143         foreach_out_edge(irn, edge) {
144                 ir_node *proj = get_edge_src_irn(edge);
145                 int proj_proj = get_Proj_proj(proj);
146                 assert(proj_proj < size);
147                 projs[proj_proj] = proj;
148         }
149 }
150
151 /**
152  * Renumbers the proj having pn_old in the array tp pn_new
153  * and removes the proj from the array.
154  */
155 static INLINE void ia32_renumber_Proj(ir_node **projs, long pn_old, long pn_new) {
156         fprintf(stderr, "Warning: renumber_Proj used!\n");
157         if (projs[pn_old]) {
158                 set_Proj_proj(projs[pn_old], pn_new);
159                 projs[pn_old] = NULL;
160         }
161 }
162
163 /**
164  * creates a unique ident by adding a number to a tag
165  *
166  * @param tag   the tag string, must contain a %d if a number
167  *              should be added
168  */
169 static ident *unique_id(const char *tag)
170 {
171         static unsigned id = 0;
172         char str[256];
173
174         snprintf(str, sizeof(str), tag, ++id);
175         return new_id_from_str(str);
176 }
177
178 /**
179  * Get a primitive type for a mode.
180  */
181 static ir_type *get_prim_type(pmap *types, ir_mode *mode)
182 {
183         pmap_entry *e = pmap_find(types, mode);
184         ir_type *res;
185
186         if (! e) {
187                 char buf[64];
188                 snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode));
189                 res = new_type_primitive(new_id_from_str(buf), mode);
190                 pmap_insert(types, mode, res);
191         }
192         else
193                 res = e->value;
194         return res;
195 }
196
197 /**
198  * Get an entity that is initialized with a tarval
199  */
200 static ir_entity *get_entity_for_tv(ia32_code_gen_t *cg, ir_node *cnst)
201 {
202         tarval *tv    = get_Const_tarval(cnst);
203         pmap_entry *e = pmap_find(cg->isa->tv_ent, tv);
204         ir_entity *res;
205         ir_graph *rem;
206
207         if (! e) {
208                 ir_mode *mode = get_irn_mode(cnst);
209                 ir_type *tp = get_Const_type(cnst);
210                 if (tp == firm_unknown_type)
211                         tp = get_prim_type(cg->isa->types, mode);
212
213                 res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
214
215                 set_entity_ld_ident(res, get_entity_ident(res));
216                 set_entity_visibility(res, visibility_local);
217                 set_entity_variability(res, variability_constant);
218                 set_entity_allocation(res, allocation_static);
219
220                  /* we create a new entity here: It's initialization must resist on the
221                     const code irg */
222                 rem = current_ir_graph;
223                 current_ir_graph = get_const_code_irg();
224                 set_atomic_ent_value(res, new_Const_type(tv, tp));
225                 current_ir_graph = rem;
226
227                 pmap_insert(cg->isa->tv_ent, tv, res);
228         }
229         else
230                 res = e->value;
231         return res;
232 }
233
234 /**
235  * Transforms a Const.
236  *
237  * @param mod     the debug module
238  * @param block   the block the new node should belong to
239  * @param node    the ir Const node
240  * @param mode    mode of the Const
241  * @return the created ia32 Const node
242  */
243 static ir_node *gen_Const(ia32_transform_env_t *env, ir_node *node) {
244         ir_graph        *irg   = env->irg;
245         dbg_info        *dbg   = get_irn_dbg_info(node);
246         ir_mode         *mode  = get_irn_mode(node);
247         ir_node         *block = transform_node(env, get_nodes_block(node));
248
249         if (mode_is_float(mode)) {
250                 ir_node *res = NULL;
251                 ir_entity *floatent;
252                 ir_node *noreg = ia32_new_NoReg_gp(env->cg);
253                 ir_node *nomem = new_NoMem();
254                 ir_node *load;
255
256                 FP_USED(env->cg);
257                 if (! USE_SSE2(env->cg)) {
258                         cnst_classify_t clss = classify_Const(node);
259
260                         if (clss == CNST_NULL) {
261                                 load = new_rd_ia32_vfldz(dbg, irg, block);
262                                 res = load;
263                         } else if (clss == CNST_ONE) {
264                                 load = new_rd_ia32_vfld1(dbg, irg, block);
265                                 res = load;
266                         } else {
267                                 floatent = get_entity_for_tv(env->cg, node);
268
269                                 load      = new_rd_ia32_vfld(dbg, irg, block, noreg, noreg, nomem);
270                                 set_ia32_am_support(load, ia32_am_Source);
271                                 set_ia32_op_type(load, ia32_AddrModeS);
272                                 set_ia32_am_flavour(load, ia32_am_N);
273                                 set_ia32_am_sc(load, ia32_get_ent_ident(floatent));
274                                 res       = new_r_Proj(irg, block, load, mode_D, pn_ia32_vfld_res);
275                         }
276                 } else {
277                         floatent = get_entity_for_tv(env->cg, node);
278
279                         load      = new_rd_ia32_xLoad(dbg, irg, block, noreg, noreg, nomem);
280                         set_ia32_am_support(load, ia32_am_Source);
281                         set_ia32_op_type(load, ia32_AddrModeS);
282                         set_ia32_am_flavour(load, ia32_am_N);
283                         set_ia32_am_sc(load, ia32_get_ent_ident(floatent));
284                         res = new_r_Proj(irg, block, load, mode_D, pn_ia32_xLoad_res);
285                 }
286
287                 set_ia32_ls_mode(load, mode);
288                 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env->cg, node));
289
290                 /* Const Nodes before the initial IncSP are a bad idea, because
291                  * they could be spilled and we have no SP ready at that point yet
292                  */
293                 if (get_irg_start_block(irg) == block) {
294                         add_irn_dep(load, get_irg_frame(irg));
295                 }
296
297                 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env->cg, node));
298                 return res;
299         } else {
300                 ir_node *cnst = new_rd_ia32_Const(dbg, irg, block);
301
302                 /* see above */
303                 if (get_irg_start_block(irg) == block) {
304                         add_irn_dep(cnst, get_irg_frame(irg));
305                 }
306
307                 set_ia32_Const_attr(cnst, node);
308                 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env->cg, node));
309                 return cnst;
310         }
311
312         assert(0);
313         return new_r_Bad(irg);
314 }
315
316 /**
317  * Transforms a SymConst.
318  *
319  * @param mod     the debug module
320  * @param block   the block the new node should belong to
321  * @param node    the ir SymConst node
322  * @param mode    mode of the SymConst
323  * @return the created ia32 Const node
324  */
325 static ir_node *gen_SymConst(ia32_transform_env_t *env, ir_node *node) {
326         ir_graph *irg   = env->irg;
327         dbg_info *dbg   = get_irn_dbg_info(node);
328         ir_mode  *mode  = get_irn_mode(node);
329         ir_node  *block = transform_node(env, get_nodes_block(node));
330         ir_node  *cnst;
331
332         if (mode_is_float(mode)) {
333                 FP_USED(env->cg);
334                 if (USE_SSE2(env->cg))
335                         cnst = new_rd_ia32_xConst(dbg, irg, block);
336                 else
337                         cnst = new_rd_ia32_vfConst(dbg, irg, block);
338                 set_ia32_ls_mode(cnst, mode);
339         } else {
340                 cnst = new_rd_ia32_Const(dbg, irg, block);
341         }
342
343         /* Const Nodes before the initial IncSP are a bad idea, because
344          * they could be spilled and we have no SP ready at that point yet
345          */
346         if (get_irg_start_block(irg) == block) {
347                 add_irn_dep(cnst, get_irg_frame(irg));
348         }
349
350         set_ia32_Const_attr(cnst, node);
351         SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env->cg, node));
352
353         return cnst;
354 }
355
356 /**
357  * SSE convert of an integer node into a floating point node.
358  */
359 static ir_node *gen_sse_conv_int2float(ia32_code_gen_t *cg, dbg_info *dbg,
360                                        ir_graph *irg, ir_node *block,
361                                        ir_node *in, ir_node *old_node, ir_mode *tgt_mode)
362 {
363         ir_node *noreg = ia32_new_NoReg_gp(cg);
364         ir_node *nomem = new_rd_NoMem(irg);
365         ir_node *old_pred = get_Cmp_left(old_node);
366         ir_mode *in_mode = get_irn_mode(old_pred);
367         int in_bits = get_mode_size_bits(in_mode);
368
369         ir_node *conv = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, in, nomem);
370         set_ia32_ls_mode(conv, tgt_mode);
371         if(in_bits == 32) {
372                 set_ia32_am_support(conv, ia32_am_Source);
373         }
374         SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node));
375
376         return conv;
377 }
378
379 /**
380 * SSE convert of an float node into a double node.
381 */
382 static ir_node *gen_sse_conv_f2d(ia32_code_gen_t *cg, dbg_info *dbg,
383                                  ir_graph *irg, ir_node *block,
384                                  ir_node *in, ir_node *old_node)
385 {
386         ir_node *noreg = ia32_new_NoReg_gp(cg);
387         ir_node *nomem = new_rd_NoMem(irg);
388
389         ir_node *conv = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, in, nomem);
390         set_ia32_am_support(conv, ia32_am_Source);
391         set_ia32_ls_mode(conv, mode_D);
392         SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node));
393
394         return conv;
395 }
396
397 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
398 ident *ia32_gen_fp_known_const(ia32_known_const_t kct) {
399         static const struct {
400                 const char *tp_name;
401                 const char *ent_name;
402                 const char *cnst_str;
403         } names [ia32_known_const_max] = {
404                 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN },        /* ia32_SSIGN */
405                 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN },        /* ia32_DSIGN */
406                 { TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS },         /* ia32_SABS */
407                 { TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS }          /* ia32_DABS */
408         };
409         static ir_entity *ent_cache[ia32_known_const_max];
410
411         const char    *tp_name, *ent_name, *cnst_str;
412         ir_type       *tp;
413         ir_node       *cnst;
414         ir_graph      *rem;
415         ir_entity     *ent;
416         tarval        *tv;
417         ir_mode       *mode;
418
419         ent_name = names[kct].ent_name;
420         if (! ent_cache[kct]) {
421                 tp_name  = names[kct].tp_name;
422                 cnst_str = names[kct].cnst_str;
423
424                 mode = kct == ia32_SSIGN || kct == ia32_SABS ? mode_Iu : mode_Lu;
425                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
426                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
427                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
428
429                 set_entity_ld_ident(ent, get_entity_ident(ent));
430                 set_entity_visibility(ent, visibility_local);
431                 set_entity_variability(ent, variability_constant);
432                 set_entity_allocation(ent, allocation_static);
433
434                 /* we create a new entity here: It's initialization must resist on the
435                     const code irg */
436                 rem = current_ir_graph;
437                 current_ir_graph = get_const_code_irg();
438                 cnst = new_Const(mode, tv);
439                 current_ir_graph = rem;
440
441                 set_atomic_ent_value(ent, cnst);
442
443                 /* cache the entry */
444                 ent_cache[kct] = ent;
445         }
446
447         return get_entity_ident(ent_cache[kct]);
448 }
449
450 #ifndef NDEBUG
451 /**
452  * Prints the old node name on cg obst and returns a pointer to it.
453  */
454 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
455         ia32_isa_t *isa = (ia32_isa_t *)cg->arch_env->isa;
456
457         lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
458         obstack_1grow(isa->name_obst, 0);
459         return obstack_finish(isa->name_obst);
460 }
461 #endif /* NDEBUG */
462
463 /* determine if one operator is an Imm */
464 static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
465         if (op1)
466                 return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
467         else return is_ia32_Cnst(op2) ? op2 : NULL;
468 }
469
470 /* determine if one operator is not an Imm */
471 static ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
472         return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
473 }
474
475 static void fold_immediate(ia32_transform_env_t *env, ir_node *node, int in1, int in2) {
476         ir_node *left;
477         ir_node *right;
478
479         if(! (env->cg->opt & IA32_OPT_IMMOPS))
480                 return;
481
482         left = get_irn_n(node, in1);
483         right = get_irn_n(node, in2);
484         if(!is_ia32_Cnst(right) && is_ia32_Cnst(left)) {
485                 /* we can only set right operand to immediate */
486                 if(!is_ia32_commutative(node))
487                         return;
488                 /* exchange left/right */
489                 set_irn_n(node, in1, right);
490                 set_irn_n(node, in2, ia32_get_admissible_noreg(env->cg, node, in2));
491                 set_ia32_Immop_attr(node, left);
492         } else if(is_ia32_Cnst(right)) {
493                 set_irn_n(node, in2, ia32_get_admissible_noreg(env->cg, node, in2));
494                 set_ia32_Immop_attr(node, right);
495         } else {
496                 return;
497         }
498
499         set_ia32_am_support(node, get_ia32_am_support(node) & ~ia32_am_Source);
500 }
501
502 /**
503  * Construct a standard binary operation, set AM and immediate if required.
504  *
505  * @param env   The transformation environment
506  * @param op1   The first operand
507  * @param op2   The second operand
508  * @param func  The node constructor function
509  * @return The constructed ia32 node.
510  */
511 static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *node,
512                           ir_node *op1, ir_node *op2,
513                           construct_binop_func *func) {
514         ir_node  *new_node = NULL;
515         ir_graph *irg      = env->irg;
516         dbg_info *dbg      = get_irn_dbg_info(node);
517         ir_node  *block    = transform_node(env, get_nodes_block(node));
518         ir_node  *noreg_gp = ia32_new_NoReg_gp(env->cg);
519         ir_node  *nomem    = new_NoMem();
520         ir_node  *new_op1  = transform_node(env, op1);
521         ir_node  *new_op2  = transform_node(env, op2);
522
523         new_node = func(dbg, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, nomem);
524         if(func == new_rd_ia32_Mul) {
525                 set_ia32_am_support(new_node, ia32_am_Source);
526         } else {
527                 set_ia32_am_support(new_node, ia32_am_Full);
528         }
529
530         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env->cg, node));
531         if (is_op_commutative(get_irn_op(node))) {
532                 set_ia32_commutative(new_node);
533         }
534         fold_immediate(env, new_node, 2, 3);
535
536         return new_node;
537 }
538
539 /**
540  * Construct a standard binary operation, set AM and immediate if required.
541  *
542  * @param env   The transformation environment
543  * @param op1   The first operand
544  * @param op2   The second operand
545  * @param func  The node constructor function
546  * @return The constructed ia32 node.
547  */
548 static ir_node *gen_binop_float(ia32_transform_env_t *env, ir_node *node,
549                                 ir_node *op1, ir_node *op2,
550                                 construct_binop_func *func)
551 {
552         ir_node  *new_node = NULL;
553         dbg_info *dbg      = get_irn_dbg_info(node);
554         ir_graph *irg      = env->irg;
555         ir_mode  *mode     = get_irn_mode(node);
556         ir_node  *block    = transform_node(env, get_nodes_block(node));
557         ir_node  *noreg_gp = ia32_new_NoReg_gp(env->cg);
558         ir_node  *nomem    = new_NoMem();
559         ir_node  *new_op1  = transform_node(env, op1);
560         ir_node  *new_op2  = transform_node(env, op2);
561
562         new_node = func(dbg, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, nomem);
563         set_ia32_am_support(new_node, ia32_am_Source);
564         if (is_op_commutative(get_irn_op(node))) {
565                 set_ia32_commutative(new_node);
566         }
567         if (USE_SSE2(env->cg)) {
568                 set_ia32_ls_mode(new_node, mode);
569         }
570
571         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env->cg, node));
572
573         return new_node;
574 }
575
576
577 /**
578  * Construct a shift/rotate binary operation, sets AM and immediate if required.
579  *
580  * @param env   The transformation environment
581  * @param op1   The first operand
582  * @param op2   The second operand
583  * @param func  The node constructor function
584  * @return The constructed ia32 node.
585  */
586 static ir_node *gen_shift_binop(ia32_transform_env_t *env, ir_node *node,
587                                 ir_node *op1, ir_node *op2,
588                                 construct_binop_func *func) {
589         ir_node    *new_op  = NULL;
590         ir_mode    *mode    = get_irn_mode(node);
591         dbg_info   *dbg     = get_irn_dbg_info(node);
592         ir_graph   *irg     = env->irg;
593         ir_node    *block   = transform_node(env, get_nodes_block(node));
594         ir_node    *noreg   = ia32_new_NoReg_gp(env->cg);
595         ir_node    *nomem   = new_NoMem();
596         ir_node    *expr_op;
597         ir_node    *imm_op;
598         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
599         ir_node    *new_op1 = transform_node(env, op1);
600         ir_node    *new_op2 = transform_node(env, op2);
601         tarval     *tv;
602
603         assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");
604
605         /* Check if immediate optimization is on and */
606         /* if it's an operation with immediate.      */
607         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, new_op2) : NULL;
608         expr_op = get_expr_op(new_op1, new_op2);
609
610         assert((expr_op || imm_op) && "invalid operands");
611
612         if (!expr_op) {
613                 /* We have two consts here: not yet supported */
614                 imm_op = NULL;
615         }
616
617         /* Limit imm_op within range imm8 */
618         if (imm_op) {
619                 tv = get_ia32_Immop_tarval(imm_op);
620
621                 if (tv) {
622                         tv = tarval_mod(tv, new_tarval_from_long(32, get_tarval_mode(tv)));
623                         set_ia32_Immop_tarval(imm_op, tv);
624                 }
625                 else {
626                         imm_op = NULL;
627                 }
628         }
629
630         /* integer operations */
631         if (imm_op) {
632                 /* This is shift/rot with const */
633                 DB((mod, LEVEL_1, "Shift/Rot with immediate ..."));
634
635                 new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
636                 set_ia32_Immop_attr(new_op, imm_op);
637         } else {
638                 /* This is a normal shift/rot */
639                 DB((mod, LEVEL_1, "Shift/Rot binop ..."));
640                 new_op = func(dbg, irg, block, noreg, noreg, new_op1, new_op2, nomem);
641         }
642
643         /* set AM support */
644         set_ia32_am_support(new_op, ia32_am_Dest);
645
646         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
647
648         set_ia32_emit_cl(new_op);
649
650         return new_op;
651 }
652
653
654 /**
655  * Construct a standard unary operation, set AM and immediate if required.
656  *
657  * @param env   The transformation environment
658  * @param op    The operand
659  * @param func  The node constructor function
660  * @return The constructed ia32 node.
661  */
662 static ir_node *gen_unop(ia32_transform_env_t *env, ir_node *node, ir_node *op,
663                          construct_unop_func *func) {
664         ir_node           *new_node = NULL;
665         ir_graph          *irg    = env->irg;
666         dbg_info          *dbg    = get_irn_dbg_info(node);
667         ir_node           *block  = transform_node(env, get_nodes_block(node));
668         ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
669         ir_node           *nomem  = new_NoMem();
670         ir_node           *new_op = transform_node(env, op);
671         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
672
673         new_node = func(dbg, irg, block, noreg, noreg, new_op, nomem);
674         DB((mod, LEVEL_1, "INT unop ..."));
675         set_ia32_am_support(new_node, ia32_am_Dest);
676
677         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env->cg, node));
678
679         return new_node;
680 }
681
682
683 /**
684  * Creates an ia32 Add with immediate.
685  *
686  * @param env       The transformation environment
687  * @param expr_op   The expression operator
688  * @param const_op  The constant
689  * @return the created ia32 Add node
690  */
691 static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *node,
692                             ir_node *expr_op, ir_node *const_op) {
693         ir_node                *new_op     = NULL;
694         tarval                 *tv         = get_ia32_Immop_tarval(const_op);
695         ir_graph               *irg        = env->irg;
696         dbg_info               *dbg        = get_irn_dbg_info(node);
697         ir_node                *block      = transform_node(env, get_nodes_block(node));
698         ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
699         ir_node                *nomem      = new_NoMem();
700         int                     normal_add = 1;
701         tarval_classification_t class_tv, class_negtv;
702         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
703
704         /* try to optimize to inc/dec  */
705         if ((env->cg->opt & IA32_OPT_INCDEC) && tv && (get_ia32_op_type(const_op) == ia32_Const)) {
706                 /* optimize tarvals */
707                 class_tv    = classify_tarval(tv);
708                 class_negtv = classify_tarval(tarval_neg(tv));
709
710                 if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
711                         DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
712                         new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
713                         normal_add = 0;
714                 }
715                 else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
716                         DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
717                         new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
718                         normal_add = 0;
719                 }
720         }
721
722         if (normal_add) {
723                 new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
724                 set_ia32_Immop_attr(new_op, const_op);
725                 set_ia32_commutative(new_op);
726         }
727
728         return new_op;
729 }
730
731 /**
732  * Creates an ia32 Add.
733  *
734  * @param env   The transformation environment
735  * @return the created ia32 Add node
736  */
737 static ir_node *gen_Add(ia32_transform_env_t *env, ir_node *node) {
738         ir_node  *new_op = NULL;
739         ir_graph *irg    = env->irg;
740         dbg_info *dbg    = get_irn_dbg_info(node);
741         ir_mode  *mode   = get_irn_mode(node);
742         ir_node  *block  = transform_node(env, get_nodes_block(node));
743         ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
744         ir_node  *nomem  = new_NoMem();
745         ir_node  *expr_op, *imm_op;
746         ir_node  *op1    = get_Add_left(node);
747         ir_node  *op2    = get_Add_right(node);
748         ir_node  *new_op1 = transform_node(env, op1);
749         ir_node  *new_op2 = transform_node(env, op2);
750
751         /* Check if immediate optimization is on and */
752         /* if it's an operation with immediate.      */
753         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(new_op1, new_op2) : NULL;
754         expr_op = get_expr_op(new_op1, new_op2);
755
756         assert((expr_op || imm_op) && "invalid operands");
757
758         if (mode_is_float(mode)) {
759                 FP_USED(env->cg);
760                 if (USE_SSE2(env->cg))
761                         return gen_binop_float(env, node, op1, op2, new_rd_ia32_xAdd);
762                 else
763                         return gen_binop_float(env, node, op1, op2, new_rd_ia32_vfadd);
764         }
765         else {
766                 /* integer ADD */
767                 if (!expr_op) {
768                         /* No expr_op means, that we have two const - one symconst and */
769                         /* one tarval or another symconst - because this case is not   */
770                         /* covered by constant folding                                 */
771                         /* We need to check for:                                       */
772                         /*  1) symconst + const    -> becomes a LEA                    */
773                         /*  2) symconst + symconst -> becomes a const + LEA as the elf */
774                         /*        linker doesn't support two symconsts                 */
775
776                         if (get_ia32_op_type(new_op1) == ia32_SymConst
777                                 && get_ia32_op_type(new_op2) == ia32_SymConst) {
778                                 /* this is the 2nd case */
779                                 new_op = new_rd_ia32_Lea(dbg, irg, block, new_op1, noreg);
780                                 set_ia32_am_sc(new_op, get_ia32_id_cnst(new_op2));
781                                 set_ia32_am_flavour(new_op, ia32_am_OB);
782                                 set_ia32_am_support(new_op, ia32_am_Source);
783                                 set_ia32_op_type(new_op, ia32_AddrModeS);
784
785                                 DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
786                         } else {
787                                 /* this is the 1st case */
788                                 if (get_ia32_op_type(new_op1) == ia32_SymConst) {
789                                         tarval *tv = get_ia32_cnst_tv(new_op2);
790                                         long offs = get_tarval_long(tv);
791
792                                         new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg);
793                                         DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
794
795                                         set_ia32_am_sc(new_op, get_ia32_id_cnst(new_op1));
796                                         add_ia32_am_offs_int(new_op, offs);
797                                         set_ia32_am_flavour(new_op, ia32_am_O);
798                                         set_ia32_am_support(new_op, ia32_am_Source);
799                                         set_ia32_op_type(new_op, ia32_AddrModeS);
800                                 } else if (get_ia32_op_type(new_op2) == ia32_SymConst) {
801                                         tarval *tv = get_ia32_cnst_tv(new_op1);
802                                         long offs = get_tarval_long(tv);
803
804                                         new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg);
805                                         DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
806
807                                         add_ia32_am_offs_int(new_op, offs);
808                                         set_ia32_am_sc(new_op, get_ia32_id_cnst(new_op2));
809                                         set_ia32_am_flavour(new_op, ia32_am_O);
810                                         set_ia32_am_support(new_op, ia32_am_Source);
811                                         set_ia32_op_type(new_op, ia32_AddrModeS);
812                                 } else {
813                                         tarval *tv1 = get_ia32_cnst_tv(new_op1);
814                                         tarval *tv2 = get_ia32_cnst_tv(new_op2);
815                                         tarval *restv = tarval_add(tv1, tv2);
816
817                                         DEBUG_ONLY(ir_fprintf(stderr, "Warning: add with 2 consts not folded: %+F\n", node));
818
819                                         new_op = new_rd_ia32_Const(dbg, irg, block);
820                                         set_ia32_Const_tarval(new_op, restv);
821                                         DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
822                                 }
823                         }
824
825                         return new_op;
826                 }
827                 else if (imm_op) {
828                         /* This is expr + const */
829                         new_op = gen_imm_Add(env, node, expr_op, imm_op);
830
831                         /* set AM support */
832                         set_ia32_am_support(new_op, ia32_am_Dest);
833                 }
834                 else {
835                         /* This is a normal add */
836                         new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, new_op1, new_op2, nomem);
837
838                         /* set AM support */
839                         set_ia32_am_support(new_op, ia32_am_Full);
840                         set_ia32_commutative(new_op);
841                 }
842         }
843
844         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
845
846         return new_op;
847 }
848
849
850
851 /**
852  * Creates an ia32 Mul.
853  *
854  * @param env   The transformation environment
855  * @return the created ia32 Mul node
856  */
857 static ir_node *gen_Mul(ia32_transform_env_t *env, ir_node *node) {
858         ir_node *op1 = get_Mul_left(node);
859         ir_node *op2 = get_Mul_right(node);
860         ir_node *new_op;
861         ir_mode *mode = get_irn_mode(node);
862
863         if (mode_is_float(mode)) {
864                 FP_USED(env->cg);
865                 if (USE_SSE2(env->cg))
866                         new_op = gen_binop_float(env, node, op1, op2, new_rd_ia32_xMul);
867                 else
868                         new_op = gen_binop_float(env, node, op1, op2, new_rd_ia32_vfmul);
869         }
870         else {
871                 new_op = gen_binop(env, node, op1, op2, new_rd_ia32_Mul);
872         }
873
874         return new_op;
875 }
876
877
878
879 /**
880  * Creates an ia32 Mulh.
881  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
882  * this result while Mul returns the lower 32 bit.
883  *
884  * @param env   The transformation environment
885  * @return the created ia32 Mulh node
886  */
887 static ir_node *gen_Mulh(ia32_transform_env_t *env, ir_node *node) {
888         ir_graph    *irg = env->irg;
889         dbg_info    *dbg = get_irn_dbg_info(node);
890         ir_node   *block = transform_node(env, get_nodes_block(node));
891         ir_node     *op1 = get_irn_n(node, 0);
892         ir_node     *op2 = get_irn_n(node, 1);
893         ir_node *new_op1 = transform_node(env, op1);
894         ir_node *new_op2 = transform_node(env, op2);
895         ir_node   *noreg = ia32_new_NoReg_gp(env->cg);
896         ir_node *proj_EAX, *proj_EDX, *mulh;
897         ir_mode *mode = get_irn_mode(node);
898         ir_node *in[1];
899
900         assert(!mode_is_float(mode) && "Mulh with float not supported");
901         mulh = new_rd_ia32_Mulh(dbg, irg, block, noreg, noreg, new_op1, new_op2, new_NoMem());
902         set_ia32_commutative(mulh);
903         set_ia32_am_support(mulh, ia32_am_Source);
904
905         /* imediates are not supported, so no fold_immediate */
906         proj_EAX = new_rd_Proj(dbg, irg, block, mulh, mode_Iu, pn_EAX);
907         proj_EDX = new_rd_Proj(dbg, irg, block, mulh, mode_Iu, pn_EDX);
908
909         /* keep EAX */
910         in[0] = proj_EAX;
911         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in);
912
913         return proj_EDX;
914 }
915
916
917
918 /**
919  * Creates an ia32 And.
920  *
921  * @param env   The transformation environment
922  * @return The created ia32 And node
923  */
924 static ir_node *gen_And(ia32_transform_env_t *env, ir_node *node) {
925         ir_node *op1 = get_And_left(node);
926         ir_node *op2 = get_And_right(node);
927         ir_mode *mode = get_irn_mode(node);
928
929         assert (! mode_is_float(mode));
930         return gen_binop(env, node, op1, op2, new_rd_ia32_And);
931 }
932
933
934
935 /**
936  * Creates an ia32 Or.
937  *
938  * @param env   The transformation environment
939  * @return The created ia32 Or node
940  */
941 static ir_node *gen_Or(ia32_transform_env_t *env, ir_node *node) {
942         ir_node *op1 = get_Or_left(node);
943         ir_node *op2 = get_Or_right(node);
944         ir_mode *mode = get_irn_mode(node);
945
946         assert (! mode_is_float(mode));
947         return gen_binop(env, node, op1, op2, new_rd_ia32_Or);
948 }
949
950
951
952 /**
953  * Creates an ia32 Eor.
954  *
955  * @param env   The transformation environment
956  * @return The created ia32 Eor node
957  */
958 static ir_node *gen_Eor(ia32_transform_env_t *env, ir_node *node) {
959         ir_node *op1 = get_Eor_left(node);
960         ir_node *op2 = get_Eor_right(node);
961         ir_mode *mode = get_irn_mode(node);
962
963         assert(! mode_is_float(mode));
964         return gen_binop(env, node, op1, op2, new_rd_ia32_Eor);
965 }
966
967
968
969 /**
970  * Creates an ia32 Max.
971  *
972  * @param env      The transformation environment
973  * @return the created ia32 Max node
974  */
975 static ir_node *gen_Max(ia32_transform_env_t *env, ir_node *node) {
976         ir_graph *irg = env->irg;
977         ir_node *new_op;
978         ir_mode *mode = get_irn_mode(node);
979         dbg_info *dbg = get_irn_dbg_info(node);
980         ir_node *block = transform_node(env, get_nodes_block(node));
981         ir_node *op1 = get_irn_n(node, 0);
982         ir_node *op2 = get_irn_n(node, 1);
983         ir_node *new_op1 = transform_node(env, op1);
984         ir_node *new_op2 = transform_node(env, op2);
985         ir_mode *op_mode = get_irn_mode(op1);
986
987         assert(get_mode_size_bits(mode) == 32);
988
989         if (mode_is_float(mode)) {
990                 FP_USED(env->cg);
991                 if (USE_SSE2(env->cg))
992                         new_op = gen_binop_float(env, node, new_op1, new_op2, new_rd_ia32_xMax);
993                 else {
994                         assert(0);
995                 }
996         }
997         else {
998                 long pnc = pn_Cmp_Gt;
999                 if(!mode_is_signed(op_mode)) {
1000                         pnc |= ia32_pn_Cmp_Unsigned;
1001                 }
1002                 new_op = new_rd_ia32_CmpCMov(dbg, irg, block, new_op1, new_op2, new_op1, new_op2);
1003                 set_ia32_pncode(new_op, pnc);
1004                 set_ia32_am_support(new_op, ia32_am_None);
1005         }
1006         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1007
1008         return new_op;
1009 }
1010
1011 /**
1012  * Creates an ia32 Min.
1013  *
1014  * @param env      The transformation environment
1015  * @return the created ia32 Min node
1016  */
1017 static ir_node *gen_Min(ia32_transform_env_t *env, ir_node *node) {
1018         ir_graph *irg = env->irg;
1019         ir_node *new_op;
1020         ir_mode *mode = get_irn_mode(node);
1021         dbg_info *dbg = get_irn_dbg_info(node);
1022         ir_node *block = transform_node(env, get_nodes_block(node));
1023         ir_node *op1 = get_irn_n(node, 0);
1024         ir_node *op2 = get_irn_n(node, 1);
1025         ir_node *new_op1 = transform_node(env, op1);
1026         ir_node *new_op2 = transform_node(env, op2);
1027         ir_mode *op_mode = get_irn_mode(op1);
1028
1029         assert(get_mode_size_bits(mode) == 32);
1030
1031         if (mode_is_float(mode)) {
1032                 FP_USED(env->cg);
1033                 if (USE_SSE2(env->cg))
1034                         new_op = gen_binop_float(env, node, op1, op2, new_rd_ia32_xMin);
1035                 else {
1036                         assert(0);
1037                 }
1038         }
1039         else {
1040                 long pnc = pn_Cmp_Lt;
1041                 if(!mode_is_signed(op_mode)) {
1042                         pnc |= ia32_pn_Cmp_Unsigned;
1043                 }
1044                 new_op = new_rd_ia32_CmpCMov(dbg, irg, block, new_op1, new_op2, new_op1, new_op2);
1045                 set_ia32_pncode(new_op, pnc);
1046                 set_ia32_am_support(new_op, ia32_am_None);
1047         }
1048         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1049
1050         return new_op;
1051 }
1052
1053
1054
1055 /**
1056  * Creates an ia32 Sub with immediate.
1057  *
1058  * @param env        The transformation environment
1059  * @param expr_op    The first operator
1060  * @param const_op   The constant operator
1061  * @return The created ia32 Sub node
1062  */
1063 static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *node,
1064                             ir_node *expr_op, ir_node *const_op) {
1065         ir_node                *new_op     = NULL;
1066         tarval                 *tv         = get_ia32_Immop_tarval(const_op);
1067         ir_graph               *irg        = env->irg;
1068         dbg_info               *dbg        = get_irn_dbg_info(node);
1069         ir_node                *block      = transform_node(env, get_nodes_block(node));
1070         ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
1071         ir_node                *nomem      = new_NoMem();
1072         int                     normal_sub = 1;
1073         tarval_classification_t class_tv, class_negtv;
1074         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
1075
1076         /* try to optimize to inc/dec  */
1077         if ((env->cg->opt & IA32_OPT_INCDEC) && tv && (get_ia32_op_type(const_op) == ia32_Const)) {
1078                 /* optimize tarvals */
1079                 class_tv    = classify_tarval(tv);
1080                 class_negtv = classify_tarval(tarval_neg(tv));
1081
1082                 if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
1083                         DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
1084                         new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
1085                         normal_sub = 0;
1086                 }
1087                 else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
1088                         DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
1089                         new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
1090                         normal_sub = 0;
1091                 }
1092         }
1093
1094         if (normal_sub) {
1095                 new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
1096                 set_ia32_Immop_attr(new_op, const_op);
1097         }
1098
1099         return new_op;
1100 }
1101
1102 /**
1103  * Creates an ia32 Sub.
1104  *
1105  * @param env   The transformation environment
1106  * @return The created ia32 Sub node
1107  */
1108 static ir_node *gen_Sub(ia32_transform_env_t *env, ir_node *node) {
1109         ir_node  *new_op = NULL;
1110         ir_graph *irg    = env->irg;
1111         dbg_info *dbg    = get_irn_dbg_info(node);
1112         ir_mode  *mode   = get_irn_mode(node);
1113         ir_node  *block  = transform_node(env, get_nodes_block(node));
1114         ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
1115         ir_node  *nomem  = new_NoMem();
1116         ir_node  *op1    = get_Sub_left(node);
1117         ir_node  *op2    = get_Sub_right(node);
1118         ir_node *new_op1 = transform_node(env, op1);
1119         ir_node *new_op2 = transform_node(env, op2);
1120         ir_node  *expr_op, *imm_op;
1121
1122         /* Check if immediate optimization is on and */
1123         /* if it's an operation with immediate.      */
1124         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, new_op2) : NULL;
1125         expr_op = get_expr_op(new_op1, new_op2);
1126
1127         assert((expr_op || imm_op) && "invalid operands");
1128
1129         if (mode_is_float(mode)) {
1130                 FP_USED(env->cg);
1131                 if (USE_SSE2(env->cg))
1132                         return gen_binop_float(env, node, op1, op2, new_rd_ia32_xSub);
1133                 else
1134                         return gen_binop_float(env, node, op1, op2, new_rd_ia32_vfsub);
1135         } else {
1136                 /* integer SUB */
1137                 if (! expr_op) {
1138                         /* No expr_op means, that we have two const - one symconst and */
1139                         /* one tarval or another symconst - because this case is not   */
1140                         /* covered by constant folding                                 */
1141                         /* We need to check for:                                       */
1142                         /*  1) symconst - const    -> becomes a LEA                    */
1143                         /*  2) symconst - symconst -> becomes a const - LEA as the elf */
1144                         /*        linker doesn't support two symconsts                 */
1145
1146                         if (get_ia32_op_type(new_op1) == ia32_SymConst
1147                                         && get_ia32_op_type(new_op2) == ia32_SymConst) {
1148                                 /* this is the 2nd case */
1149                                 new_op = new_rd_ia32_Lea(dbg, irg, block, new_op1, noreg);
1150                                 set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
1151                                 set_ia32_am_sc_sign(new_op);
1152                                 set_ia32_am_flavour(new_op, ia32_am_OB);
1153
1154                                 DBG_OPT_LEA3(op1, op2, node, new_op);
1155                         } else {
1156                                 /* this is the 1st case */
1157                                 new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg);
1158
1159                                 DBG_OPT_LEA3(op1, op2, node, new_op);
1160
1161                                 if (get_ia32_op_type(new_op1) == ia32_SymConst) {
1162                                         tarval *tv = get_ia32_cnst_tv(new_op2);
1163                                         long offs = get_tarval_long(tv);
1164
1165                                         set_ia32_am_sc(new_op, get_ia32_id_cnst(new_op1));
1166                                         add_ia32_am_offs_int(new_op, -offs);
1167                                         set_ia32_am_flavour(new_op, ia32_am_O);
1168                                         set_ia32_am_support(new_op, ia32_am_Source);
1169                                         set_ia32_op_type(new_op, ia32_AddrModeS);
1170                                 } else if (get_ia32_op_type(new_op2) == ia32_SymConst) {
1171                                         tarval *tv = get_ia32_cnst_tv(new_op1);
1172                                         long offs = get_tarval_long(tv);
1173
1174                                         add_ia32_am_offs_int(new_op, offs);
1175                                         set_ia32_am_sc(new_op, get_ia32_id_cnst(new_op2));
1176                                         set_ia32_am_sc_sign(new_op);
1177                                         set_ia32_am_flavour(new_op, ia32_am_O);
1178                                         set_ia32_am_support(new_op, ia32_am_Source);
1179                                         set_ia32_op_type(new_op, ia32_AddrModeS);
1180                                 } else {
1181                                         tarval *tv1 = get_ia32_cnst_tv(new_op1);
1182                                         tarval *tv2 = get_ia32_cnst_tv(new_op2);
1183                                         tarval *restv = tarval_sub(tv1, tv2);
1184
1185                                         DEBUG_ONLY(ir_fprintf(stderr, "Warning: sub with 2 consts not folded: %+F\n", node));
1186
1187                                         new_op = new_rd_ia32_Const(dbg, irg, block);
1188                                         set_ia32_Const_tarval(new_op, restv);
1189                                         DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
1190                                 }
1191                         }
1192
1193                         return new_op;
1194                 } else if (imm_op) {
1195                         /* This is expr - const */
1196                         new_op = gen_imm_Sub(env, node, expr_op, imm_op);
1197
1198                         /* set AM support */
1199                         set_ia32_am_support(new_op, ia32_am_Dest);
1200                 } else {
1201                         /* This is a normal sub */
1202                         new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, new_op1, new_op2, nomem);
1203
1204                         /* set AM support */
1205                         set_ia32_am_support(new_op, ia32_am_Full);
1206                 }
1207         }
1208
1209         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1210
1211         return new_op;
1212 }
1213
1214
1215
1216 /**
1217  * Generates an ia32 DivMod with additional infrastructure for the
1218  * register allocator if needed.
1219  *
1220  * @param env      The transformation environment
1221  * @param dividend -no comment- :)
1222  * @param divisor  -no comment- :)
1223  * @param dm_flav  flavour_Div/Mod/DivMod
1224  * @return The created ia32 DivMod node
1225  */
1226 static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *node,
1227                                 ir_node *dividend, ir_node *divisor,
1228                                 ia32_op_flavour_t dm_flav) {
1229         ir_graph *irg   = env->irg;
1230         dbg_info *dbg   = get_irn_dbg_info(node);
1231         ir_mode  *mode  = get_irn_mode(node);
1232         ir_node  *block = transform_node(env, get_nodes_block(node));
1233         ir_node  *res, *proj_div, *proj_mod;
1234         ir_node  *edx_node, *cltd;
1235         ir_node  *in_keep[1];
1236         ir_node  *mem, *new_mem;
1237         ir_node  *projs[pn_DivMod_max];
1238         ir_node *new_dividend = transform_node(env, dividend);
1239         ir_node *new_divisor = transform_node(env, divisor);
1240
1241         ia32_collect_Projs(node, projs, pn_DivMod_max);
1242
1243         switch (dm_flav) {
1244                 case flavour_Div:
1245                         mem  = get_Div_mem(node);
1246                         mode = get_irn_mode(be_get_Proj_for_pn(node, pn_Div_res));
1247                         break;
1248                 case flavour_Mod:
1249                         mem  = get_Mod_mem(node);
1250                         mode = get_irn_mode(be_get_Proj_for_pn(node, pn_Mod_res));
1251                         break;
1252                 case flavour_DivMod:
1253                         mem      = get_DivMod_mem(node);
1254                         proj_div = be_get_Proj_for_pn(node, pn_DivMod_res_div);
1255                         proj_mod = be_get_Proj_for_pn(node, pn_DivMod_res_mod);
1256                         mode     = proj_div ? get_irn_mode(proj_div) : get_irn_mode(proj_mod);
1257                         break;
1258                 default:
1259                         assert(0);
1260         }
1261         new_mem = transform_node(env, mem);
1262
1263         if (mode_is_signed(mode)) {
1264                 /* in signed mode, we need to sign extend the dividend */
1265                 cltd     = new_rd_ia32_Cdq(dbg, irg, block, new_dividend);
1266                 new_dividend = new_rd_Proj(dbg, irg, block, cltd, mode_Iu, pn_ia32_Cdq_EAX);
1267                 edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Iu, pn_ia32_Cdq_EDX);
1268         }
1269         else {
1270                 edx_node = new_rd_ia32_Const(dbg, irg, block);
1271                 add_irn_dep(edx_node, be_abi_get_start_barrier(env->cg->birg->abi));
1272                 set_ia32_Const_type(edx_node, ia32_Const);
1273                 set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
1274         }
1275
1276         if(mode_is_signed(mode)) {
1277                 res = new_rd_ia32_IDiv(dbg, irg, block, new_dividend, new_divisor, edx_node, new_mem, dm_flav);
1278         } else {
1279                 res = new_rd_ia32_Div(dbg, irg, block, new_dividend, new_divisor, edx_node, new_mem, dm_flav);
1280         }
1281         set_ia32_n_res(res, 2);
1282
1283         /* Only one proj is used -> We must add a second proj and */
1284         /* connect this one to a Keep node to eat up the second   */
1285         /* destroyed register.                                    */
1286         /* We also renumber the Firm projs into ia32 projs.       */
1287
1288         switch (get_irn_opcode(node)) {
1289                 case iro_Div:
1290                         /* add Proj-Keep for mod res */
1291                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Iu, pn_ia32_Div_mod_res);
1292                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1293                         break;
1294                 case iro_Mod:
1295                         /* add Proj-Keep for div res */
1296                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Iu, pn_ia32_Div_div_res);
1297                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1298                         break;
1299                 case iro_DivMod:
1300                         /* check, which Proj-Keep, we need to add */
1301                         proj_div = be_get_Proj_for_pn(node, pn_DivMod_res_div);
1302                         proj_mod = be_get_Proj_for_pn(node, pn_DivMod_res_mod);
1303
1304                         if (proj_div && proj_mod) {
1305                                 /* nothing to be done */
1306                         }
1307                         else if (! proj_div && ! proj_mod) {
1308                                 assert(0 && "Missing DivMod result proj");
1309                         }
1310                         else if (! proj_div) {
1311                                 /* We have only mod result: add div res Proj-Keep */
1312                                 in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Iu, pn_ia32_Div_div_res);
1313                                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1314                         }
1315                         else {
1316                                 /* We have only div result: add mod res Proj-Keep */
1317                                 in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Iu, pn_ia32_Div_mod_res);
1318                                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1319                         }
1320                         break;
1321                 default:
1322                         assert(0 && "Div, Mod, or DivMod expected.");
1323                         break;
1324         }
1325
1326         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1327
1328         return res;
1329 }
1330
1331
1332 /**
1333  * Wrapper for generate_DivMod. Sets flavour_Mod.
1334  *
1335  * @param env      The transformation environment
1336  */
1337 static ir_node *gen_Mod(ia32_transform_env_t *env, ir_node *node) {
1338         return generate_DivMod(env, node, get_Mod_left(node),
1339                                get_Mod_right(node), flavour_Mod);
1340 }
1341
1342 /**
1343  * Wrapper for generate_DivMod. Sets flavour_Div.
1344  *
1345  * @param env      The transformation environment
1346  */
1347 static ir_node *gen_Div(ia32_transform_env_t *env, ir_node *node) {
1348         return generate_DivMod(env, node, get_Div_left(node),
1349                                get_Div_right(node), flavour_Div);
1350 }
1351
1352 /**
1353  * Wrapper for generate_DivMod. Sets flavour_DivMod.
1354  */
1355 static ir_node *gen_DivMod(ia32_transform_env_t *env, ir_node *node) {
1356         return generate_DivMod(env, node, get_DivMod_left(node),
1357                                get_DivMod_right(node), flavour_DivMod);
1358 }
1359
1360
1361
1362 /**
1363  * Creates an ia32 floating Div.
1364  *
1365  * @param env   The transformation environment
1366  * @return The created ia32 xDiv node
1367  */
1368 static ir_node *gen_Quot(ia32_transform_env_t *env, ir_node *node) {
1369         ir_graph *irg = env->irg;
1370         dbg_info *dbg = get_irn_dbg_info(node);
1371         ir_node *block = transform_node(env, get_nodes_block(node));
1372         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1373         ir_node *new_op;
1374         ir_node *nomem = new_rd_NoMem(env->irg);
1375         ir_node *op1   = get_Quot_left(node);
1376         ir_node *op2   = get_Quot_right(node);
1377         ir_node *new_op1 = transform_node(env, op1);
1378         ir_node *new_op2 = transform_node(env, op2);
1379
1380         FP_USED(env->cg);
1381         if (USE_SSE2(env->cg)) {
1382                 ir_mode *mode = get_irn_mode(op1);
1383                 if (is_ia32_xConst(new_op2)) {
1384                         new_op = new_rd_ia32_xDiv(dbg, irg, block, noreg, noreg, new_op1, noreg, nomem);
1385                         set_ia32_am_support(new_op, ia32_am_None);
1386                         set_ia32_Immop_attr(new_op, new_op2);
1387                 } else {
1388                         new_op = new_rd_ia32_xDiv(dbg, irg, block, noreg, noreg, new_op1, new_op2, nomem);
1389                         // Matze: disabled for now, spillslot coalescer fails
1390                         //set_ia32_am_support(new_op, ia32_am_Source);
1391                 }
1392                 set_ia32_ls_mode(new_op, mode);
1393         } else {
1394                 new_op = new_rd_ia32_vfdiv(dbg, irg, block, noreg, noreg, new_op1, new_op2, nomem);
1395                 // Matze: disabled for now (spillslot coalescer fails)
1396                 //set_ia32_am_support(new_op, ia32_am_Source);
1397         }
1398         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1399         return new_op;
1400 }
1401
1402
1403 /**
1404  * Creates an ia32 Shl.
1405  *
1406  * @param env   The transformation environment
1407  * @return The created ia32 Shl node
1408  */
1409 static ir_node *gen_Shl(ia32_transform_env_t *env, ir_node *node) {
1410         return gen_shift_binop(env, node, get_Shl_left(node), get_Shl_right(node),
1411                                new_rd_ia32_Shl);
1412 }
1413
1414
1415
1416 /**
1417  * Creates an ia32 Shr.
1418  *
1419  * @param env   The transformation environment
1420  * @return The created ia32 Shr node
1421  */
1422 static ir_node *gen_Shr(ia32_transform_env_t *env, ir_node *node) {
1423         return gen_shift_binop(env, node, get_Shr_left(node),
1424                                get_Shr_right(node), new_rd_ia32_Shr);
1425 }
1426
1427
1428
1429 /**
1430  * Creates an ia32 Shrs.
1431  *
1432  * @param env   The transformation environment
1433  * @return The created ia32 Shrs node
1434  */
1435 static ir_node *gen_Shrs(ia32_transform_env_t *env, ir_node *node) {
1436         return gen_shift_binop(env, node, get_Shrs_left(node),
1437                                get_Shrs_right(node), new_rd_ia32_Shrs);
1438 }
1439
1440
1441
1442 /**
1443  * Creates an ia32 RotL.
1444  *
1445  * @param env   The transformation environment
1446  * @param op1   The first operator
1447  * @param op2   The second operator
1448  * @return The created ia32 RotL node
1449  */
1450 static ir_node *gen_RotL(ia32_transform_env_t *env, ir_node *node,
1451                          ir_node *op1, ir_node *op2) {
1452         return gen_shift_binop(env, node, op1, op2, new_rd_ia32_RotL);
1453 }
1454
1455
1456
1457 /**
1458  * Creates an ia32 RotR.
1459  * NOTE: There is no RotR with immediate because this would always be a RotL
1460  *       "imm-mode_size_bits" which can be pre-calculated.
1461  *
1462  * @param env   The transformation environment
1463  * @param op1   The first operator
1464  * @param op2   The second operator
1465  * @return The created ia32 RotR node
1466  */
1467 static ir_node *gen_RotR(ia32_transform_env_t *env, ir_node *node, ir_node *op1,
1468                          ir_node *op2) {
1469         return gen_shift_binop(env, node, op1, op2, new_rd_ia32_RotR);
1470 }
1471
1472
1473
1474 /**
1475  * Creates an ia32 RotR or RotL (depending on the found pattern).
1476  *
1477  * @param env   The transformation environment
1478  * @return The created ia32 RotL or RotR node
1479  */
1480 static ir_node *gen_Rot(ia32_transform_env_t *env, ir_node *node) {
1481         ir_node *rotate = NULL;
1482         ir_node *op1    = get_Rot_left(node);
1483         ir_node *op2    = get_Rot_right(node);
1484
1485         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1486                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1487                  that means we can create a RotR instead of an Add and a RotL */
1488
1489         if (is_Proj(op2)) {
1490                 ir_node *pred = get_Proj_pred(op2);
1491
1492                 if (is_ia32_Add(pred)) {
1493                         ir_node *pred_pred = get_irn_n(pred, 2);
1494                         tarval  *tv        = get_ia32_Immop_tarval(pred);
1495                         ir_mode *mode      = get_irn_mode(node);
1496                         long     bits      = get_mode_size_bits(mode);
1497
1498                         if (is_Proj(pred_pred)) {
1499                                 pred_pred = get_Proj_pred(pred_pred);
1500                         }
1501
1502                         if (is_ia32_Minus(pred_pred) &&
1503                                 tarval_is_long(tv)       &&
1504                                 get_tarval_long(tv) == bits)
1505                         {
1506                                 DB((env->mod, LEVEL_1, "RotL into RotR ... "));
1507                                 rotate = gen_RotR(env, node, op1, get_irn_n(pred_pred, 2));
1508                         }
1509
1510                 }
1511         }
1512
1513         if (!rotate) {
1514                 rotate = gen_RotL(env, node, op1, op2);
1515         }
1516
1517         return rotate;
1518 }
1519
1520
1521
1522 /**
1523  * Transforms a Minus node.
1524  *
1525  * @param env   The transformation environment
1526  * @param op    The Minus operand
1527  * @return The created ia32 Minus node
1528  */
1529 ir_node *gen_Minus_ex(ia32_transform_env_t *env, ir_node *node, ir_node *op) {
1530         ident   *name;
1531         ir_node *res;
1532         ir_graph *irg = env->irg;
1533         dbg_info *dbg = get_irn_dbg_info(node);
1534         ir_node *block = transform_node(env, get_nodes_block(node));
1535         ir_mode *mode = get_irn_mode(node);
1536         int      size;
1537
1538         if (mode_is_float(mode)) {
1539                 ir_node *new_op = transform_node(env, op);
1540                 FP_USED(env->cg);
1541                 if (USE_SSE2(env->cg)) {
1542                         ir_node *noreg_gp = ia32_new_NoReg_gp(env->cg);
1543                         ir_node *noreg_fp = ia32_new_NoReg_fp(env->cg);
1544                         ir_node *nomem    = new_rd_NoMem(irg);
1545
1546                         res = new_rd_ia32_xEor(dbg, irg, block, noreg_gp, noreg_gp, new_op, noreg_fp, nomem);
1547
1548                         size   = get_mode_size_bits(mode);
1549                         name   = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1550
1551                         set_ia32_am_sc(res, name);
1552                         set_ia32_op_type(res, ia32_AddrModeS);
1553                         set_ia32_ls_mode(res, mode);
1554                 } else {
1555                         res = new_rd_ia32_vfchs(dbg, irg, block, new_op);
1556                 }
1557         } else {
1558                 res = gen_unop(env, node, op, new_rd_ia32_Minus);
1559         }
1560
1561         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1562
1563         return res;
1564 }
1565
1566 /**
1567  * Transforms a Minus node.
1568  *
1569  * @param env   The transformation environment
1570  * @return The created ia32 Minus node
1571  */
1572 static ir_node *gen_Minus(ia32_transform_env_t *env, ir_node *node) {
1573         return gen_Minus_ex(env, node, get_Minus_op(node));
1574 }
1575
1576
1577 /**
1578  * Transforms a Not node.
1579  *
1580  * @param env   The transformation environment
1581  * @return The created ia32 Not node
1582  */
1583 static ir_node *gen_Not(ia32_transform_env_t *env, ir_node *node) {
1584         ir_mode *mode = get_irn_mode(node);
1585         ir_node *op = get_Not_op(node);
1586
1587         assert (! mode_is_float(mode));
1588         return gen_unop(env, node, op, new_rd_ia32_Not);
1589 }
1590
1591
1592
1593 /**
1594  * Transforms an Abs node.
1595  *
1596  * @param env   The transformation environment
1597  * @return The created ia32 Abs node
1598  */
1599 static ir_node *gen_Abs(ia32_transform_env_t *env, ir_node *node) {
1600         ir_node  *res, *p_eax, *p_edx;
1601         ir_graph *irg      = env->irg;
1602         dbg_info *dbg      = get_irn_dbg_info(node);
1603         ir_node  *block    = transform_node(env, get_nodes_block(node));
1604         ir_mode  *mode     = get_irn_mode(node);
1605         ir_node  *noreg_gp = ia32_new_NoReg_gp(env->cg);
1606         ir_node  *noreg_fp = ia32_new_NoReg_fp(env->cg);
1607         ir_node  *nomem    = new_NoMem();
1608         ir_node  *op       = get_Abs_op(node);
1609         ir_node  *new_op   = transform_node(env, op);
1610         int       size;
1611         ident    *name;
1612
1613         if (mode_is_float(mode)) {
1614                 FP_USED(env->cg);
1615                 if (USE_SSE2(env->cg)) {
1616                         res = new_rd_ia32_xAnd(dbg,irg, block, noreg_gp, noreg_gp, new_op, noreg_fp, nomem);
1617
1618                         size   = get_mode_size_bits(mode);
1619                         name   = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1620
1621                         set_ia32_am_sc(res, name);
1622
1623                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1624
1625                         set_ia32_op_type(res, ia32_AddrModeS);
1626                         set_ia32_ls_mode(res, mode);
1627                 }
1628                 else {
1629                         res = new_rd_ia32_vfabs(dbg, irg, block, new_op);
1630                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1631                 }
1632         }
1633         else {
1634                 res   = new_rd_ia32_Cdq(dbg, irg, block, new_op);
1635                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1636
1637                 p_eax = new_rd_Proj(dbg, irg, block, res, mode_Iu, pn_EAX);
1638                 p_edx = new_rd_Proj(dbg, irg, block, res, mode_Iu, pn_EDX);
1639
1640                 res   = new_rd_ia32_Eor(dbg, irg, block, noreg_gp, noreg_gp, p_eax, p_edx, nomem);
1641                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1642
1643                 res   = new_rd_ia32_Sub(dbg, irg, block, noreg_gp, noreg_gp, res, p_edx, nomem);
1644                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1645         }
1646
1647         return res;
1648 }
1649
1650
1651
1652 /**
1653  * Transforms a Load.
1654  *
1655  * @param env   The transformation environment
1656  * @return the created ia32 Load node
1657  */
1658 static ir_node *gen_Load(ia32_transform_env_t *env, ir_node *node) {
1659         ir_graph *irg  = env->irg;
1660         dbg_info *dbg  = get_irn_dbg_info(node);
1661         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1662         ir_mode *mode  = get_Load_mode(node);
1663         ir_node *block = transform_node(env, get_nodes_block(node));
1664         ir_node *ptr   = get_Load_ptr(node);
1665         ir_node *new_ptr = transform_node(env, ptr);
1666         ir_node *lptr  = new_ptr;
1667         ir_node *mem   = get_Load_mem(node);
1668         ir_node *new_mem = transform_node(env, mem);
1669         int     is_imm = 0;
1670         ir_node *new_op;
1671         ia32_am_flavour_t am_flav = ia32_am_B;
1672         ir_node *projs[pn_Load_max];
1673
1674         ia32_collect_Projs(node, projs, pn_Load_max);
1675
1676         /*
1677                 check for special case: the loaded value might not be used (optimized, volatile, ...)
1678                 we add a Proj + Keep for volatile loads and ignore all other cases
1679         */
1680         if (! be_get_Proj_for_pn(node, pn_Load_res) && get_Load_volatility(node) == volatility_is_volatile) {
1681                 /* add a result proj and a Keep to produce a pseudo use */
1682                 ir_node *proj = new_r_Proj(irg, block, node, mode_Iu, pn_ia32_Load_res);
1683                 be_new_Keep(arch_get_irn_reg_class(env->cg->arch_env, proj, -1), irg, block, 1, &proj);
1684         }
1685
1686         /* address might be a constant (symconst or absolute address) */
1687         if (is_ia32_Const(new_ptr)) {
1688                 lptr   = noreg;
1689                 is_imm = 1;
1690         }
1691
1692         if (mode_is_float(mode)) {
1693                 FP_USED(env->cg);
1694                 if (USE_SSE2(env->cg)) {
1695                         new_op = new_rd_ia32_xLoad(dbg, irg, block, lptr, noreg, new_mem);
1696                 } else {
1697                         new_op = new_rd_ia32_vfld(dbg, irg, block, lptr, noreg, new_mem);
1698                 }
1699         } else {
1700                 new_op = new_rd_ia32_Load(dbg, irg, block, lptr, noreg, new_mem);
1701         }
1702
1703         /* base is a constant address */
1704         if (is_imm) {
1705                 if (get_ia32_op_type(new_ptr) == ia32_SymConst) {
1706                         set_ia32_am_sc(new_op, get_ia32_id_cnst(new_ptr));
1707                         am_flav = ia32_am_N;
1708                 } else {
1709                         tarval *tv = get_ia32_cnst_tv(new_ptr);
1710                         long offs = get_tarval_long(tv);
1711
1712                         add_ia32_am_offs_int(new_op, offs);
1713                         am_flav = ia32_am_O;
1714                 }
1715         }
1716
1717         set_ia32_am_support(new_op, ia32_am_Source);
1718         set_ia32_op_type(new_op, ia32_AddrModeS);
1719         set_ia32_am_flavour(new_op, am_flav);
1720         set_ia32_ls_mode(new_op, mode);
1721
1722         /* make sure we are scheduled behind the intial IncSP/Barrier
1723          * to avoid spills being placed before it
1724          */
1725         if(block == get_irg_start_block(irg)) {
1726                 add_irn_dep(new_op, get_irg_frame(irg));
1727         }
1728
1729         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1730
1731         return new_op;
1732 }
1733
1734
1735
1736 /**
1737  * Transforms a Store.
1738  *
1739  * @param env   The transformation environment
1740  * @return the created ia32 Store node
1741  */
1742 static ir_node *gen_Store(ia32_transform_env_t *env, ir_node *node) {
1743         ir_graph *irg    = env->irg;
1744         dbg_info *dbg    = get_irn_dbg_info(node);
1745         ir_node *block   = transform_node(env, get_nodes_block(node));
1746         ir_node *noreg   = ia32_new_NoReg_gp(env->cg);
1747         ir_node *ptr     = get_Store_ptr(node);
1748         ir_node *new_ptr = transform_node(env, ptr);
1749         ir_node *sptr    = new_ptr;
1750         ir_node *val     = get_Store_value(node);
1751         ir_node *new_val = transform_node(env, val);
1752         ir_node *mem     = get_Store_mem(node);
1753         ir_node *new_mem = transform_node(env, mem);
1754         ir_mode *mode    = get_irn_mode(val);
1755         ir_node *sval    = new_val;
1756         int      is_imm  = 0;
1757         ir_node *new_op;
1758         ia32_am_flavour_t am_flav = ia32_am_B;
1759         ia32_immop_type_t immop   = ia32_ImmNone;
1760
1761         if (! mode_is_float(mode)) {
1762                 /* in case of storing a const (but not a symconst) -> make it an attribute */
1763                 if (is_ia32_Cnst(new_val)) {
1764                         switch (get_ia32_op_type(new_val)) {
1765                         case ia32_Const:
1766                                 immop = ia32_ImmConst;
1767                                 break;
1768                         case ia32_SymConst:
1769                                 immop = ia32_ImmSymConst;
1770                                 break;
1771                         default:
1772                                 assert(0 && "unsupported Const type");
1773                         }
1774                         sval = noreg;
1775                 }
1776         }
1777
1778         /* address might be a constant (symconst or absolute address) */
1779         if (is_ia32_Const(new_ptr)) {
1780                 sptr   = noreg;
1781                 is_imm = 1;
1782         }
1783
1784         if (mode_is_float(mode)) {
1785                 FP_USED(env->cg);
1786                 if (USE_SSE2(env->cg)) {
1787                         new_op = new_rd_ia32_xStore(dbg, irg, block, sptr, noreg, sval, new_mem);
1788                 }
1789                 else {
1790                         new_op = new_rd_ia32_vfst(dbg, irg, block, sptr, noreg, sval, new_mem);
1791                 }
1792         }
1793         else if (get_mode_size_bits(mode) == 8) {
1794                 new_op = new_rd_ia32_Store8Bit(dbg, irg, block, sptr, noreg, sval, new_mem);
1795         }
1796         else {
1797                 new_op = new_rd_ia32_Store(dbg, irg, block, sptr, noreg, sval, new_mem);
1798         }
1799
1800         /* stored const is an immediate value */
1801         if (! mode_is_float(mode) && is_ia32_Cnst(new_val)) {
1802                 set_ia32_Immop_attr(new_op, new_val);
1803         }
1804
1805         /* base is an constant address */
1806         if (is_imm) {
1807                 if (get_ia32_op_type(new_ptr) == ia32_SymConst) {
1808                         set_ia32_am_sc(new_op, get_ia32_id_cnst(new_ptr));
1809                         am_flav = ia32_am_N;
1810                 }
1811                 else {
1812                         tarval *tv = get_ia32_cnst_tv(new_ptr);
1813                         long offs = get_tarval_long(tv);
1814
1815                         add_ia32_am_offs_int(new_op, offs);
1816                         am_flav = ia32_am_O;
1817                 }
1818         }
1819
1820         set_ia32_am_support(new_op, ia32_am_Dest);
1821         set_ia32_op_type(new_op, ia32_AddrModeD);
1822         set_ia32_am_flavour(new_op, am_flav);
1823         set_ia32_ls_mode(new_op, mode);
1824         set_ia32_immop_type(new_op, immop);
1825
1826         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1827
1828         return new_op;
1829 }
1830
1831
1832
1833 /**
1834  * Transforms a Cond -> Proj[b] -> Cmp into a CondJmp, CondJmp_i or TestJmp
1835  *
1836  * @param env   The transformation environment
1837  * @return The transformed node.
1838  */
1839 static ir_node *gen_Cond(ia32_transform_env_t *env, ir_node *node) {
1840         ir_graph *irg      = env->irg;
1841         dbg_info *dbg      = get_irn_dbg_info(node);
1842         ir_node  *block    = transform_node(env, get_nodes_block(node));
1843         ir_node  *sel      = get_Cond_selector(node);
1844         ir_mode  *sel_mode = get_irn_mode(sel);
1845         ir_node  *res      = NULL;
1846         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
1847         ir_node  *cnst, *expr;
1848
1849         if (is_Proj(sel) && sel_mode == mode_b) {
1850                 ir_node *nomem = new_NoMem();
1851                 ir_node *pred = get_Proj_pred(sel);
1852                 ir_node *cmp_a = get_Cmp_left(pred);
1853                 ir_node *new_cmp_a = transform_node(env, cmp_a);
1854                 ir_node *cmp_b = get_Cmp_right(pred);
1855                 ir_node *new_cmp_b = transform_node(env, cmp_b);
1856                 ir_mode *cmp_mode = get_irn_mode(cmp_a);
1857
1858                 int pnc = get_Proj_proj(sel);
1859                 if(mode_is_float(cmp_mode) || !mode_is_signed(cmp_mode)) {
1860                         pnc |= ia32_pn_Cmp_Unsigned;
1861                 }
1862
1863                 /* check if we can use a CondJmp with immediate */
1864                 cnst = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(new_cmp_a, new_cmp_b) : NULL;
1865                 expr = get_expr_op(new_cmp_a, new_cmp_b);
1866
1867                 if (cnst != NULL && expr != NULL) {
1868                         /* immop has to be the right operand, we might need to flip pnc */
1869                         if(cnst != new_cmp_b) {
1870                                 pnc = get_inversed_pnc(pnc);
1871                         }
1872
1873                         if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_is_int(get_irn_mode(expr))) {
1874                                 if (get_ia32_op_type(cnst) == ia32_Const &&
1875                                         classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL)
1876                                 {
1877                                         /* a Cmp A =/!= 0 */
1878                                         ir_node    *op1  = expr;
1879                                         ir_node    *op2  = expr;
1880                                         const char *cnst = NULL;
1881
1882                                         /* check, if expr is an only once used And operation */
1883                                         if (is_ia32_And(expr) && get_irn_n_edges(expr)) {
1884                                                 op1 = get_irn_n(expr, 2);
1885                                                 op2 = get_irn_n(expr, 3);
1886
1887                                                 cnst = (is_ia32_ImmConst(expr) || is_ia32_ImmSymConst(expr)) ? get_ia32_cnst(expr) : NULL;
1888                                         }
1889                                         res = new_rd_ia32_TestJmp(dbg, irg, block, op1, op2);
1890                                         set_ia32_pncode(res, pnc);
1891
1892                                         if (cnst) {
1893                                                 copy_ia32_Immop_attr(res, expr);
1894                                         }
1895
1896                                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1897                                         return res;
1898                                 }
1899                         }
1900
1901                         if (mode_is_float(cmp_mode)) {
1902                                 FP_USED(env->cg);
1903                                 if (USE_SSE2(env->cg)) {
1904                                         res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem);
1905                                         set_ia32_ls_mode(res, cmp_mode);
1906                                 } else {
1907                                         assert(0);
1908                                 }
1909                         }
1910                         else {
1911                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem);
1912                         }
1913                         set_ia32_Immop_attr(res, cnst);
1914                 }
1915                 else {
1916                         ir_mode *cmp_mode = get_irn_mode(cmp_a);
1917
1918                         if (mode_is_float(cmp_mode)) {
1919                                 FP_USED(env->cg);
1920                                 if (USE_SSE2(env->cg)) {
1921                                         res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1922                                         set_ia32_ls_mode(res, cmp_mode);
1923                                 } else {
1924                                         ir_node *proj_eax;
1925                                         res = new_rd_ia32_vfCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1926                                         proj_eax = new_r_Proj(irg, block, res, mode_Iu, pn_ia32_vfCondJmp_temp_reg_eax);
1927                                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, &proj_eax);
1928                                 }
1929                         }
1930                         else {
1931                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1932                                 set_ia32_commutative(res);
1933                         }
1934                 }
1935
1936                 set_ia32_pncode(res, pnc);
1937                 // Matze: disabled for now, because the default collect_spills_walker
1938                 // is not able to detect the mode of the spilled value
1939                 // moreover, the lea optimize phase freely exchanges left/right
1940                 // without updating the pnc
1941                 //set_ia32_am_support(res, ia32_am_Source);
1942         }
1943         else {
1944                 /* determine the smallest switch case value */
1945                 int switch_min = INT_MAX;
1946                 const ir_edge_t *edge;
1947                 ir_node *new_sel = transform_node(env, sel);
1948
1949                 foreach_out_edge(node, edge) {
1950                         int pn = get_Proj_proj(get_edge_src_irn(edge));
1951                         switch_min = pn < switch_min ? pn : switch_min;
1952                 }
1953
1954                 if (switch_min) {
1955                         /* if smallest switch case is not 0 we need an additional sub */
1956                         res = new_rd_ia32_Lea(dbg, irg, block, new_sel, noreg);
1957                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1958                         add_ia32_am_offs_int(res, -switch_min);
1959                         set_ia32_am_flavour(res, ia32_am_OB);
1960                         set_ia32_am_support(res, ia32_am_Source);
1961                         set_ia32_op_type(res, ia32_AddrModeS);
1962                 }
1963
1964                 res = new_rd_ia32_SwitchJmp(dbg, irg, block, switch_min ? res : new_sel, mode_T);
1965                 set_ia32_pncode(res, get_Cond_defaultProj(node));
1966         }
1967
1968         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
1969         return res;
1970 }
1971
1972
1973
1974 /**
1975  * Transforms a CopyB node.
1976  *
1977  * @param env   The transformation environment
1978  * @return The transformed node.
1979  */
1980 static ir_node *gen_CopyB(ia32_transform_env_t *env, ir_node *node) {
1981         ir_node  *res      = NULL;
1982         ir_graph *irg      = env->irg;
1983         dbg_info *dbg      = get_irn_dbg_info(node);
1984         ir_node  *block    = transform_node(env, get_nodes_block(node));
1985         ir_node  *src      = get_CopyB_src(node);
1986         ir_node  *new_src  = transform_node(env, src);
1987         ir_node  *dst      = get_CopyB_dst(node);
1988         ir_node  *new_dst  = transform_node(env, dst);
1989         ir_node  *mem      = get_CopyB_mem(node);
1990         ir_node  *new_mem  = transform_node(env, mem);
1991         int      size      = get_type_size_bytes(get_CopyB_type(node));
1992         ir_mode  *dst_mode = get_irn_mode(dst);
1993         ir_mode  *src_mode = get_irn_mode(src);
1994         int      rem;
1995         ir_node  *in[3];
1996
1997         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
1998         /* then we need the size explicitly in ECX.                    */
1999         if (size >= 32 * 4) {
2000                 rem = size & 0x3; /* size % 4 */
2001                 size >>= 2;
2002
2003                 res = new_rd_ia32_Const(dbg, irg, block);
2004                 add_irn_dep(res, be_abi_get_start_barrier(env->cg->birg->abi));
2005                 set_ia32_op_type(res, ia32_Const);
2006                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
2007
2008                 res = new_rd_ia32_CopyB(dbg, irg, block, new_dst, new_src, res, new_mem);
2009                 set_ia32_Immop_tarval(res, new_tarval_from_long(rem, mode_Is));
2010
2011                 /* ok: now attach Proj's because rep movsd will destroy esi, edi and ecx */
2012                 in[0] = new_r_Proj(irg, block, res, dst_mode, pn_ia32_CopyB_DST);
2013                 in[1] = new_r_Proj(irg, block, res, src_mode, pn_ia32_CopyB_SRC);
2014                 in[2] = new_r_Proj(irg, block, res, mode_Iu, pn_ia32_CopyB_CNT);
2015                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 3, in);
2016         }
2017         else {
2018                 res = new_rd_ia32_CopyB_i(dbg, irg, block, new_dst, new_src, new_mem);
2019                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
2020                 set_ia32_immop_type(res, ia32_ImmConst);
2021
2022                 /* ok: now attach Proj's because movsd will destroy esi and edi */
2023                 in[0] = new_r_Proj(irg, block, res, dst_mode, pn_ia32_CopyB_i_DST);
2024                 in[1] = new_r_Proj(irg, block, res, src_mode, pn_ia32_CopyB_i_SRC);
2025                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 2, in);
2026         }
2027
2028         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
2029
2030         return res;
2031 }
2032
2033
2034 #if 0
2035 /**
2036  * Transforms a Mux node into CMov.
2037  *
2038  * @param env   The transformation environment
2039  * @return The transformed node.
2040  */
2041 static ir_node *gen_Mux(ia32_transform_env_t *env, ir_node *node) {
2042         ir_node *new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, \
2043                 get_Mux_sel(node), get_Mux_false(node), get_Mux_true(node), env->mode);
2044
2045         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2046
2047         return new_op;
2048 }
2049 #endif
2050
2051 typedef ir_node *cmov_func_t(dbg_info *db, ir_graph *irg, ir_node *block,
2052                              ir_node *cmp_a, ir_node *cmp_b, ir_node *psi_true,
2053                              ir_node *psi_default);
2054
2055 /**
2056  * Transforms a Psi node into CMov.
2057  *
2058  * @param env   The transformation environment
2059  * @return The transformed node.
2060  */
2061 static ir_node *gen_Psi(ia32_transform_env_t *env, ir_node *node) {
2062         ia32_code_gen_t *cg   = env->cg;
2063         ir_graph *irg         = env->irg;
2064         dbg_info *dbg         = get_irn_dbg_info(node);
2065         ir_mode  *mode        = get_irn_mode(node);
2066         ir_node  *block       = transform_node(env, get_nodes_block(node));
2067         ir_node  *cmp_proj    = get_Mux_sel(node);
2068         ir_node  *psi_true    = get_Psi_val(node, 0);
2069         ir_node  *psi_default = get_Psi_default(node);
2070         ir_node  *new_psi_true = transform_node(env, psi_true);
2071         ir_node  *new_psi_default = transform_node(env, psi_default);
2072         ir_node  *noreg       = ia32_new_NoReg_gp(cg);
2073         ir_node  *nomem       = new_rd_NoMem(irg);
2074         ir_node  *cmp, *cmp_a, *cmp_b, *and1, *and2, *new_op = NULL;
2075         ir_node  *new_cmp_a, *new_cmp_b;
2076         ir_mode  *cmp_mode;
2077         int      pnc;
2078
2079         assert(get_irn_mode(cmp_proj) == mode_b && "Condition for Psi must have mode_b");
2080
2081         cmp   = get_Proj_pred(cmp_proj);
2082         cmp_a = get_Cmp_left(cmp);
2083         cmp_b = get_Cmp_right(cmp);
2084         cmp_mode = get_irn_mode(cmp_a);
2085         new_cmp_a = transform_node(env, cmp_a);
2086         new_cmp_b = transform_node(env, cmp_b);
2087
2088         pnc   = get_Proj_proj(cmp_proj);
2089         if (mode_is_float(cmp_mode) || !mode_is_signed(cmp_mode)) {
2090                 pnc |= ia32_pn_Cmp_Unsigned;
2091         }
2092
2093         if (mode_is_float(mode)) {
2094                 /* floating point psi */
2095                 FP_USED(cg);
2096
2097                 /* 1st case: compare operands are float too */
2098                 if (USE_SSE2(cg)) {
2099                         /* psi(cmp(a, b), t, f) can be done as: */
2100                         /* tmp = cmp a, b                       */
2101                         /* tmp2 = t and tmp                     */
2102                         /* tmp3 = f and not tmp                 */
2103                         /* res  = tmp2 or tmp3                  */
2104
2105                         /* in case the compare operands are int, we move them into xmm register */
2106                         if (! mode_is_float(get_irn_mode(cmp_a))) {
2107                                 new_cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, new_cmp_a, node, mode_D);
2108                                 new_cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, new_cmp_b, node, mode_D);
2109
2110                                 pnc |= 8;  /* transform integer compare to fp compare */
2111                         }
2112
2113                         new_op = new_rd_ia32_xCmp(dbg, irg, block, noreg, noreg, new_cmp_a, new_cmp_b, nomem);
2114                         set_ia32_pncode(new_op, pnc);
2115                         set_ia32_am_support(new_op, ia32_am_Source);
2116                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
2117
2118                         and1 = new_rd_ia32_xAnd(dbg, irg, block, noreg, noreg, new_psi_true, new_op, nomem);
2119                         set_ia32_am_support(and1, ia32_am_None);
2120                         set_ia32_commutative(and1);
2121                         SET_IA32_ORIG_NODE(and1, ia32_get_old_node_name(cg, node));
2122
2123                         and2 = new_rd_ia32_xAndNot(dbg, irg, block, noreg, noreg, new_op, new_psi_default, nomem);
2124                         set_ia32_am_support(and2, ia32_am_None);
2125                         set_ia32_commutative(and2);
2126                         SET_IA32_ORIG_NODE(and2, ia32_get_old_node_name(cg, node));
2127
2128                         new_op = new_rd_ia32_xOr(dbg, irg, block, noreg, noreg, and1, and2, nomem);
2129                         set_ia32_am_support(new_op, ia32_am_None);
2130                         set_ia32_commutative(new_op);
2131                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
2132                 }
2133                 else {
2134                         /* x87 FPU */
2135                         new_op = new_rd_ia32_vfCMov(dbg, irg, block, new_cmp_a, new_cmp_b, new_psi_true, new_psi_default);
2136                         set_ia32_pncode(new_op, pnc);
2137                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2138                 }
2139         }
2140         else {
2141                 /* integer psi */
2142                 construct_binop_func *set_func  = NULL;
2143                 cmov_func_t          *cmov_func = NULL;
2144
2145                 if (mode_is_float(get_irn_mode(cmp_a))) {
2146                         /* 1st case: compare operands are floats */
2147                         FP_USED(cg);
2148
2149                         if (USE_SSE2(cg)) {
2150                                 /* SSE FPU */
2151                                 set_func  = new_rd_ia32_xCmpSet;
2152                                 cmov_func = new_rd_ia32_xCmpCMov;
2153                         }
2154                         else {
2155                                 /* x87 FPU */
2156                                 set_func  = new_rd_ia32_vfCmpSet;
2157                                 cmov_func = new_rd_ia32_vfCmpCMov;
2158                         }
2159
2160                         pnc &= ~0x8; /* fp compare -> int compare */
2161                 }
2162                 else {
2163                         /* 2nd case: compare operand are integer too */
2164                         set_func  = new_rd_ia32_CmpSet;
2165                         cmov_func = new_rd_ia32_CmpCMov;
2166                 }
2167
2168                 /* check for special case first: And/Or -- Cmp with 0 -- Psi */
2169                 if (is_ia32_Const_0(new_cmp_b) && is_Proj(new_cmp_a) && (is_ia32_And(get_Proj_pred(new_cmp_a)) || is_ia32_Or(get_Proj_pred(new_cmp_a)))) {
2170                         if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) {
2171                                 /* first case for SETcc: default is 0, set to 1 iff condition is true */
2172                                 new_op = new_rd_ia32_PsiCondSet(dbg, irg, block, new_cmp_a);
2173                                 set_ia32_pncode(new_op, pnc);
2174                         }
2175                         else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) {
2176                                 /* second case for SETcc: default is 1, set to 0 iff condition is true: */
2177                                 /*                        we invert condition and set default to 0      */
2178                                 new_op = new_rd_ia32_PsiCondSet(dbg, irg, block, new_cmp_a);
2179                                 set_ia32_pncode(new_op, get_inversed_pnc(pnc));
2180                         }
2181                         else {
2182                                 /* otherwise: use CMOVcc */
2183                                 new_op = new_rd_ia32_PsiCondCMov(dbg, irg, block, new_cmp_a, new_psi_true, new_psi_default);
2184                                 set_ia32_pncode(new_op, pnc);
2185                         }
2186
2187                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
2188                 }
2189                 else {
2190                         if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) {
2191                                 /* first case for SETcc: default is 0, set to 1 iff condition is true */
2192                                 new_op = gen_binop(env, node, cmp_a, cmp_b, set_func);
2193                                 set_ia32_pncode(new_op, pnc);
2194                                 set_ia32_am_support(new_op, ia32_am_Source);
2195                         }
2196                         else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) {
2197                                 /* second case for SETcc: default is 1, set to 0 iff condition is true: */
2198                                 /*                        we invert condition and set default to 0      */
2199                                 new_op = gen_binop(env, node, cmp_a, cmp_b, set_func);
2200                                 set_ia32_pncode(new_op, get_inversed_pnc(pnc));
2201                                 set_ia32_am_support(new_op, ia32_am_Source);
2202                         }
2203                         else {
2204                                 /* otherwise: use CMOVcc */
2205                                 new_op = cmov_func(dbg, irg, block, new_cmp_a, new_cmp_b, new_psi_true, new_psi_default);
2206                                 set_ia32_pncode(new_op, pnc);
2207                                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
2208                         }
2209                 }
2210         }
2211
2212         return new_op;
2213 }
2214
2215
2216 /**
2217  * Following conversion rules apply:
2218  *
2219  *  INT -> INT
2220  * ============
2221  *  1) n bit -> m bit   n > m (downscale)
2222  *     always ignored
2223  *  2) n bit -> m bit   n == m   (sign change)
2224  *     always ignored
2225  *  3) n bit -> m bit   n < m (upscale)
2226  *     a) source is signed:    movsx
2227  *     b) source is unsigned:  and with lower bits sets
2228  *
2229  *  INT -> FLOAT
2230  * ==============
2231  *  SSE(1/2) convert to float or double (cvtsi2ss/sd)
2232  *
2233  *  FLOAT -> INT
2234  * ==============
2235  *  SSE(1/2) convert from float or double to 32bit int (cvtss/sd2si)
2236  *
2237  *  FLOAT -> FLOAT
2238  * ================
2239  *  SSE(1/2) convert from float or double to double or float (cvtss/sd2sd/ss)
2240  *  x87 is mode_E internally, conversions happen only at load and store
2241  *  in non-strict semantic
2242  */
2243
2244 /**
2245  * Create a conversion from x87 state register to general purpose.
2246  */
2247 static ir_node *gen_x87_fp_to_gp(ia32_transform_env_t *env, ir_node *node) {
2248         ia32_code_gen_t *cg    = env->cg;
2249         ir_graph        *irg   = env->irg;
2250         dbg_info        *dbg   = get_irn_dbg_info(node);
2251         ir_node         *block = transform_node(env, get_nodes_block(node));
2252         ir_node         *noreg = ia32_new_NoReg_gp(env->cg);
2253         ir_node         *op    = get_Conv_op(node);
2254         ir_node         *new_op = transform_node(env, op);
2255         ir_node         *fist, *load;
2256
2257         /* do a fist */
2258         fist = new_rd_ia32_vfist(dbg, irg, block, get_irg_frame(irg), noreg, new_op, new_NoMem());
2259
2260         set_ia32_use_frame(fist);
2261         set_ia32_am_support(fist, ia32_am_Dest);
2262         set_ia32_op_type(fist, ia32_AddrModeD);
2263         set_ia32_am_flavour(fist, ia32_am_B);
2264         set_ia32_ls_mode(fist, mode_Iu);
2265         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
2266
2267         /* do a Load */
2268         load = new_rd_ia32_Load(dbg, irg, block, get_irg_frame(irg), noreg, fist);
2269
2270         set_ia32_use_frame(load);
2271         set_ia32_am_support(load, ia32_am_Source);
2272         set_ia32_op_type(load, ia32_AddrModeS);
2273         set_ia32_am_flavour(load, ia32_am_B);
2274         set_ia32_ls_mode(load, mode_Iu);
2275         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
2276
2277         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
2278 }
2279
2280 /**
2281  * Create a conversion from general purpose to x87 register
2282  */
2283 static ir_node *gen_x87_gp_to_fp(ia32_transform_env_t *env, ir_node *node, ir_mode *src_mode) {
2284         ia32_code_gen_t *cg = env->cg;
2285         ir_graph  *irg    = env->irg;
2286         dbg_info  *dbg    = get_irn_dbg_info(node);
2287         ir_mode   *mode   = get_irn_mode(node);
2288         ir_node   *block  = transform_node(env, get_nodes_block(node));
2289         ir_node   *noreg  = ia32_new_NoReg_gp(env->cg);
2290         ir_node   *nomem  = new_NoMem();
2291         ir_node   *op     = get_Conv_op(node);
2292         ir_node   *new_op = transform_node(env, op);
2293         ir_node   *fild, *store;
2294         int       src_bits;
2295
2296         /* first convert to 32 bit if necessary */
2297         src_bits = get_mode_size_bits(src_mode);
2298         if (src_bits == 8) {
2299                 new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, new_op, nomem);
2300                 set_ia32_am_support(new_op, ia32_am_Source);
2301                 set_ia32_ls_mode(new_op, src_mode);
2302                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
2303         } else if (src_bits < 32) {
2304                 new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, new_op, nomem);
2305                 set_ia32_am_support(new_op, ia32_am_Source);
2306                 set_ia32_ls_mode(new_op, src_mode);
2307                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
2308         }
2309
2310         /* do a store */
2311         store = new_rd_ia32_Store(dbg, irg, block, get_irg_frame(irg), noreg, new_op, nomem);
2312
2313         set_ia32_use_frame(store);
2314         set_ia32_am_support(store, ia32_am_Dest);
2315         set_ia32_op_type(store, ia32_AddrModeD);
2316         set_ia32_am_flavour(store, ia32_am_OB);
2317         set_ia32_ls_mode(store, mode_Iu);
2318
2319         /* do a fild */
2320         fild = new_rd_ia32_vfild(dbg, irg, block, get_irg_frame(irg), noreg, store);
2321
2322         set_ia32_use_frame(fild);
2323         set_ia32_am_support(fild, ia32_am_Source);
2324         set_ia32_op_type(fild, ia32_AddrModeS);
2325         set_ia32_am_flavour(fild, ia32_am_OB);
2326         set_ia32_ls_mode(fild, mode);
2327
2328         return new_r_Proj(irg, block, fild, mode_F, pn_ia32_vfild_res);
2329 }
2330
2331 /**
2332  * Transforms a Conv node.
2333  *
2334  * @param env   The transformation environment
2335  * @return The created ia32 Conv node
2336  */
2337 static ir_node *gen_Conv(ia32_transform_env_t *env, ir_node *node) {
2338         ir_graph *irg      = env->irg;
2339         dbg_info *dbg      = get_irn_dbg_info(node);
2340         ir_node  *op       = get_Conv_op(node);
2341         ir_mode  *src_mode = get_irn_mode(op);
2342         ir_mode  *tgt_mode = get_irn_mode(node);
2343         int      src_bits  = get_mode_size_bits(src_mode);
2344         int      tgt_bits  = get_mode_size_bits(tgt_mode);
2345         ir_node  *block    = transform_node(env, get_nodes_block(node));
2346         ir_node  *res;
2347         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
2348         ir_node  *nomem    = new_rd_NoMem(irg);
2349         ir_node  *new_op   = transform_node(env, op);
2350         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
2351
2352         if (src_mode == tgt_mode) {
2353                 /* this should be optimized already, but who knows... */
2354                 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
2355                 DB((mod, LEVEL_1, "killed Conv(mode, mode) ..."));
2356                 return new_op;
2357         }
2358
2359         if (mode_is_float(src_mode)) {
2360                 /* we convert from float ... */
2361                 if (mode_is_float(tgt_mode)) {
2362                         /* ... to float */
2363                         if (USE_SSE2(env->cg)) {
2364                                 DB((mod, LEVEL_1, "create Conv(float, float) ..."));
2365                                 res = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, new_op, nomem);
2366                                 set_ia32_ls_mode(res, tgt_mode);
2367                         } else {
2368                                 // Matze: TODO what about strict convs?
2369                                 DB((mod, LEVEL_1, "killed Conv(float, float) ..."));
2370                                 return new_op;
2371                         }
2372                 } else {
2373                         /* ... to int */
2374                         DB((mod, LEVEL_1, "create Conv(float, int) ..."));
2375                         if (USE_SSE2(env->cg)) {
2376                                 res = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, new_op, nomem);
2377                                 set_ia32_ls_mode(res, src_mode);
2378                         } else {
2379                                 return gen_x87_fp_to_gp(env, node);
2380                         }
2381                 }
2382         } else {
2383                 /* we convert from int ... */
2384                 if (mode_is_float(tgt_mode)) {
2385                         FP_USED(env->cg);
2386                         /* ... to float */
2387                         DB((mod, LEVEL_1, "create Conv(int, float) ..."));
2388                         if (USE_SSE2(env->cg)) {
2389                                 res = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, new_op, nomem);
2390                                 set_ia32_ls_mode(res, tgt_mode);
2391                                 if(src_bits == 32) {
2392                                         set_ia32_am_support(res, ia32_am_Source);
2393                                 }
2394                         } else {
2395                                 return gen_x87_gp_to_fp(env, node, src_mode);
2396                         }
2397                 }
2398                 else {
2399                         ir_mode *smaller_mode;
2400                         int smaller_bits;
2401
2402                         if (src_bits == tgt_bits) {
2403                                 DB((mod, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...", src_mode, tgt_mode));
2404                                 return new_op;
2405                         }
2406
2407                         if(src_bits < tgt_bits) {
2408                                 smaller_mode = src_mode;
2409                                 smaller_bits = src_bits;
2410                         } else {
2411                                 smaller_mode = tgt_mode;
2412                                 smaller_bits = tgt_bits;
2413                         }
2414
2415                         // The following is not correct, we can't change the mode,
2416                         // maybe others are using the load too
2417                         // better move this to a separate phase!
2418 #if 0
2419                         /* ... to int */
2420                         if(is_Proj(new_op)) {
2421                                 /* load operations do already sign/zero extend, so we have
2422                                  * nothing left to do */
2423                                 ir_node *pred = get_Proj_pred(new_op);
2424                                 if(is_ia32_Load(pred)) {
2425                                         set_ia32_ls_mode(pred, smaller_mode);
2426                                         return new_op;
2427                                 }
2428                         }
2429 #endif
2430
2431                         DB((mod, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode));
2432                         if (smaller_bits == 8) {
2433                                 res = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, new_op, nomem);
2434                                 set_ia32_ls_mode(res, smaller_mode);
2435                         } else {
2436                                 res = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, new_op, nomem);
2437                                 set_ia32_ls_mode(res, smaller_mode);
2438                         }
2439                         set_ia32_am_support(res, ia32_am_Source);
2440                 }
2441         }
2442
2443         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
2444
2445         return res;
2446 }
2447
2448
2449
2450 /********************************************
2451  *  _                          _
2452  * | |                        | |
2453  * | |__   ___ _ __   ___   __| | ___  ___
2454  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
2455  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
2456  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
2457  *
2458  ********************************************/
2459
2460 static ir_node *gen_be_StackParam(ia32_transform_env_t *env, ir_node *node) {
2461         ir_node   *new_op = NULL;
2462         ir_graph  *irg    = env->irg;
2463         dbg_info  *dbg    = get_irn_dbg_info(node);
2464         ir_node   *block  = transform_node(env, get_nodes_block(node));
2465         ir_node   *noreg  = ia32_new_NoReg_gp(env->cg);
2466         ir_node   *nomem  = new_rd_NoMem(env->irg);
2467         ir_node   *ptr    = get_irn_n(node, 0);
2468         ir_node  *new_ptr = transform_node(env, ptr);
2469         ir_entity *ent    = arch_get_frame_entity(env->cg->arch_env, node);
2470         ir_mode   *load_mode = get_irn_mode(node);
2471         ir_mode   *proj_mode;
2472         long      pn_res;
2473
2474         if (mode_is_float(load_mode)) {
2475                 FP_USED(env->cg);
2476                 if (USE_SSE2(env->cg)) {
2477                         new_op = new_rd_ia32_xLoad(dbg, irg, block, new_ptr, noreg, nomem);
2478                         pn_res = pn_ia32_xLoad_res;
2479                 } else {
2480                         new_op = new_rd_ia32_vfld(dbg, irg, block, new_ptr, noreg, nomem);
2481                         pn_res = pn_ia32_vfld_res;
2482                 }
2483
2484                 proj_mode = mode_D;
2485         } else {
2486                 new_op = new_rd_ia32_Load(dbg, irg, block, new_ptr, noreg, nomem);
2487                 proj_mode = mode_Iu;
2488                 pn_res = pn_ia32_Load_res;
2489         }
2490
2491         set_ia32_frame_ent(new_op, ent);
2492         set_ia32_use_frame(new_op);
2493
2494         set_ia32_am_support(new_op, ia32_am_Source);
2495         set_ia32_op_type(new_op, ia32_AddrModeS);
2496         set_ia32_am_flavour(new_op, ia32_am_B);
2497         set_ia32_ls_mode(new_op, load_mode);
2498         set_ia32_flags(new_op, get_ia32_flags(new_op) | arch_irn_flags_rematerializable);
2499
2500         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2501
2502         return new_rd_Proj(dbg, irg, block, new_op, proj_mode, pn_res);
2503 }
2504
2505 /**
2506  * Transforms a FrameAddr into an ia32 Add.
2507  */
2508 static ir_node *gen_be_FrameAddr(ia32_transform_env_t *env, ir_node *node) {
2509         ir_graph *irg   = env->irg;
2510         dbg_info *dbg   = get_irn_dbg_info(node);
2511         ir_node *block  = transform_node(env, get_nodes_block(node));
2512         ir_node *op     = get_irn_n(node, 0);
2513         ir_node *new_op = transform_node(env, op);
2514         ir_node *res;
2515         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2516
2517         res = new_rd_ia32_Lea(dbg, irg, block, new_op, noreg);
2518         set_ia32_frame_ent(res, arch_get_frame_entity(env->cg->arch_env, node));
2519         set_ia32_am_support(res, ia32_am_Full);
2520         set_ia32_use_frame(res);
2521         set_ia32_am_flavour(res, ia32_am_OB);
2522
2523         //set_ia32_immop_type(res, ia32_ImmConst);
2524         //set_ia32_commutative(res);
2525
2526         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, node));
2527
2528         return res;
2529 }
2530
2531 /**
2532  * Transforms a FrameLoad into an ia32 Load.
2533  */
2534 static ir_node *gen_be_FrameLoad(ia32_transform_env_t *env, ir_node *node) {
2535         ir_node   *new_op  = NULL;
2536         ir_graph  *irg     = env->irg;
2537         dbg_info  *dbg     = get_irn_dbg_info(node);
2538         ir_node   *block   = transform_node(env, get_nodes_block(node));
2539         ir_node   *noreg   = ia32_new_NoReg_gp(env->cg);
2540         ir_node   *mem     = get_irn_n(node, 0);
2541         ir_node   *ptr     = get_irn_n(node, 1);
2542         ir_node   *new_mem = transform_node(env, mem);
2543         ir_node   *new_ptr = transform_node(env, ptr);
2544         ir_entity *ent     = arch_get_frame_entity(env->cg->arch_env, node);
2545         ir_mode   *mode    = get_type_mode(get_entity_type(ent));
2546         ir_node   *projs[pn_Load_max];
2547
2548         ia32_collect_Projs(node, projs, pn_Load_max);
2549
2550         if (mode_is_float(mode)) {
2551                 FP_USED(env->cg);
2552                 if (USE_SSE2(env->cg)) {
2553                         new_op = new_rd_ia32_xLoad(dbg, irg, block, new_ptr, noreg, new_mem);
2554                 }
2555                 else {
2556                         new_op = new_rd_ia32_vfld(dbg, irg, block, new_ptr, noreg, new_mem);
2557                 }
2558         }
2559         else {
2560                 new_op = new_rd_ia32_Load(dbg, irg, block, new_ptr, noreg, new_mem);
2561         }
2562
2563         set_ia32_frame_ent(new_op, ent);
2564         set_ia32_use_frame(new_op);
2565
2566         set_ia32_am_support(new_op, ia32_am_Source);
2567         set_ia32_op_type(new_op, ia32_AddrModeS);
2568         set_ia32_am_flavour(new_op, ia32_am_B);
2569         set_ia32_ls_mode(new_op, mode);
2570
2571         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2572
2573         return new_op;
2574 }
2575
2576
2577 /**
2578  * Transforms a FrameStore into an ia32 Store.
2579  */
2580 static ir_node *gen_be_FrameStore(ia32_transform_env_t *env, ir_node *node) {
2581         ir_node   *new_op  = NULL;
2582         ir_graph  *irg     = env->irg;
2583         dbg_info  *dbg     = get_irn_dbg_info(node);
2584         ir_node   *block   = transform_node(env, get_nodes_block(node));
2585         ir_node   *noreg   = ia32_new_NoReg_gp(env->cg);
2586         ir_node   *mem     = get_irn_n(node, 0);
2587         ir_node   *ptr     = get_irn_n(node, 1);
2588         ir_node   *val     = get_irn_n(node, 2);
2589         ir_node   *new_mem = transform_node(env, mem);
2590         ir_node   *new_ptr = transform_node(env, ptr);
2591         ir_node   *new_val = transform_node(env, val);
2592         ir_entity *ent     = arch_get_frame_entity(env->cg->arch_env, node);
2593         ir_mode   *mode    = get_irn_mode(val);
2594
2595         if (mode_is_float(mode)) {
2596                 FP_USED(env->cg);
2597                 if (USE_SSE2(env->cg)) {
2598                         new_op = new_rd_ia32_xStore(dbg, irg, block, new_ptr, noreg, new_val, new_mem);
2599                 }
2600                 else {
2601                         new_op = new_rd_ia32_vfst(dbg, irg, block, new_ptr, noreg, new_val, new_mem);
2602                 }
2603         }
2604         else if (get_mode_size_bits(mode) == 8) {
2605                 new_op = new_rd_ia32_Store8Bit(dbg, irg, block, new_ptr, noreg, new_val, new_mem);
2606         }
2607         else {
2608                 new_op = new_rd_ia32_Store(dbg, irg, block, new_ptr, noreg, new_val, new_mem);
2609         }
2610
2611         set_ia32_frame_ent(new_op, ent);
2612         set_ia32_use_frame(new_op);
2613
2614         set_ia32_am_support(new_op, ia32_am_Dest);
2615         set_ia32_op_type(new_op, ia32_AddrModeD);
2616         set_ia32_am_flavour(new_op, ia32_am_B);
2617         set_ia32_ls_mode(new_op, mode);
2618
2619         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2620
2621         return new_op;
2622 }
2623
2624 /**
2625  * In case SSE is used we need to copy the result from FPU TOS.
2626  */
2627 static ir_node *gen_be_Call(ia32_transform_env_t *env, ir_node *node) {
2628         ir_graph *irg = env->irg;
2629         dbg_info *dbg = get_irn_dbg_info(node);
2630         ir_node *block = transform_node(env, get_nodes_block(node));
2631         ir_node *call_res = be_get_Proj_for_pn(node, pn_be_Call_first_res);
2632         ir_node *call_mem = be_get_Proj_for_pn(node, pn_be_Call_M_regular);
2633         ir_mode *mode;
2634         ir_node *nomem = new_NoMem();
2635         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
2636
2637         if (! call_res || ! USE_SSE2(env->cg)) {
2638                 return duplicate_node(env, node);
2639         }
2640
2641         mode = get_irn_mode(call_res);
2642
2643         /* in case there is no memory output: create one to serialize the copy FPU -> SSE */
2644         if (call_mem == NULL)
2645                 call_mem = new_rd_Proj(dbg, irg, block, node, mode_M, pn_be_Call_M_regular);
2646
2647         if (mode_is_float(mode)) {
2648                 /* store st(0) onto stack */
2649                 ir_node   *frame = get_irg_frame(irg);
2650                 ir_node   *fstp  = new_rd_ia32_GetST0(dbg, irg, block, frame, noreg, nomem);
2651                 ir_entity *ent   = frame_alloc_area(get_irg_frame_type(irg), get_mode_size_bytes(mode), 16, 0);
2652                 ir_node   *sse_load, *p, *bad, *keep;
2653                 ir_node   *mproj;
2654                 ir_node   **in_keep;
2655                 int       keep_arity, i;
2656
2657                 // Matze: TODO, fix this for new transform code...
2658                 assert(0);
2659
2660                 set_ia32_ls_mode(fstp, mode);
2661                 set_ia32_op_type(fstp, ia32_AddrModeD);
2662                 set_ia32_use_frame(fstp);
2663                 set_ia32_frame_ent(fstp, ent);
2664                 set_ia32_am_flavour(fstp, ia32_am_B);
2665                 set_ia32_am_support(fstp, ia32_am_Dest);
2666
2667                 /* load into SSE register */
2668                 sse_load = new_rd_ia32_xLoad(dbg, irg, block, frame, ia32_new_NoReg_gp(env->cg), fstp);
2669                 set_ia32_ls_mode(sse_load, mode);
2670                 set_ia32_op_type(sse_load, ia32_AddrModeS);
2671                 set_ia32_use_frame(sse_load);
2672                 set_ia32_frame_ent(sse_load, ent);
2673                 set_ia32_am_flavour(sse_load, ia32_am_B);
2674                 set_ia32_am_support(sse_load, ia32_am_Source);
2675                 mproj    = new_rd_Proj(dbg, irg, block, sse_load, mode_M, pn_ia32_xLoad_M);
2676                 sse_load = new_rd_Proj(dbg, irg, block, sse_load, mode, pn_ia32_xLoad_res);
2677
2678                 /* reroute all users of the result proj to the sse load */
2679                 edges_reroute(call_res, sse_load, irg);
2680                 edges_reroute_kind(call_res, sse_load,  EDGE_KIND_DEP, irg);
2681
2682                 /* reroute all users of the old call memory to the sse load memory */
2683                 edges_reroute(call_mem, mproj, irg);
2684                 edges_reroute_kind(call_mem, mproj, EDGE_KIND_DEP, irg);
2685
2686                 /* now, we can set the old call mem as input of GetST0 */
2687                 set_irn_n(fstp, 1, call_mem);
2688
2689                 /* now: create new Keep whith all former ins and one additional in - the result Proj */
2690
2691                 /* get a Proj representing a caller save register */
2692                 p = be_get_Proj_for_pn(node, pn_be_Call_first_res + 1);
2693                 assert(is_Proj(p) && "Proj expected.");
2694
2695                 /* user of the the proj is the Keep */
2696                 p = get_edge_src_irn(get_irn_out_edge_first(p));
2697                 assert(be_is_Keep(p) && "Keep expected.");
2698
2699                 /* copy in array of the old keep and set the result proj as additional in */
2700                 keep_arity = get_irn_arity(p) + 1;
2701                 NEW_ARR_A(ir_node *, in_keep, keep_arity);
2702                 in_keep[keep_arity - 1] = call_res;
2703                 for (i = 0; i < keep_arity - 1; ++i)
2704                         in_keep[i] = get_irn_n(p, i);
2705
2706                 /* create new keep and set the in class requirements properly */
2707                 keep = be_new_Keep(NULL, irg, block, keep_arity, in_keep);
2708                 for(i = 0; i < keep_arity; ++i) {
2709                         const arch_register_class_t *cls = arch_get_irn_reg_class(env->cg->arch_env, in_keep[i], -1);
2710                         be_node_set_reg_class(keep, i, cls);
2711                 }
2712
2713                 /* kill the old keep */
2714                 bad = get_irg_bad(irg);
2715                 for (i = 0; i < keep_arity - 1; i++)
2716                         set_irn_n(p, i, bad);
2717                 remove_End_keepalive(get_irg_end(irg), p);
2718         }
2719
2720         return duplicate_node(env, node);
2721 }
2722
2723 /**
2724  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
2725  */
2726 static ir_node *gen_be_Return(ia32_transform_env_t *env, ir_node *node) {
2727         ir_graph  *irg     = env->irg;
2728         dbg_info  *dbg;
2729         ir_node   *block;
2730         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
2731         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
2732         ir_entity *ent     = get_irg_entity(irg);
2733         ir_type   *tp      = get_entity_type(ent);
2734         ir_type   *res_type;
2735         ir_mode   *mode;
2736         ir_node *frame, *sse_store, *fld, *mproj, *barrier;
2737         ir_node *new_barrier, *new_frame, *new_ret_val, *new_ret_mem;
2738         ir_node  **in;
2739         int pn_ret_val, pn_ret_mem, arity, i;
2740
2741         assert(ret_val != NULL);
2742         if (be_Return_get_n_rets(node) < 1 || ! USE_SSE2(env->cg)) {
2743                 return duplicate_node(env, node);
2744         }
2745
2746         res_type = get_method_res_type(tp, 0);
2747
2748         if (!is_Primitive_type(res_type)) {
2749                 return duplicate_node(env, node);
2750         }
2751
2752         mode = get_type_mode(res_type);
2753         if (!mode_is_float(mode)) {
2754                 return duplicate_node(env, node);
2755         }
2756
2757         assert(get_method_n_ress(tp) == 1);
2758         mode = mode_D;
2759
2760         pn_ret_val = get_Proj_proj(ret_val);
2761         pn_ret_mem = get_Proj_proj(ret_mem);
2762
2763         /* get the Barrier */
2764         barrier = get_Proj_pred(ret_val);
2765
2766         /* get result input of the Barrier */
2767         ret_val = get_irn_n(barrier, pn_ret_val);
2768         new_ret_val = transform_node(env, ret_val);
2769
2770         /* get memory input of the Barrier */
2771         ret_mem = get_irn_n(barrier, pn_ret_mem);
2772         new_ret_mem = transform_node(env, ret_mem);
2773
2774         frame = get_irg_frame(irg);
2775         new_frame = transform_node(env, frame);
2776
2777         dbg = get_irn_dbg_info(barrier);
2778         block = transform_node(env, get_nodes_block(barrier));
2779
2780         /* store xmm0 onto stack */
2781         sse_store = new_rd_ia32_xStoreSimple(dbg, irg, block, new_frame, new_ret_val, new_ret_mem);
2782         set_ia32_ls_mode(sse_store, mode);
2783         set_ia32_op_type(sse_store, ia32_AddrModeD);
2784         set_ia32_use_frame(sse_store);
2785         set_ia32_am_flavour(sse_store, ia32_am_B);
2786         set_ia32_am_support(sse_store, ia32_am_Dest);
2787
2788         /* load into st0 */
2789         fld = new_rd_ia32_SetST0(dbg, irg, block, new_frame, sse_store);
2790         set_ia32_ls_mode(fld, mode);
2791         set_ia32_op_type(fld, ia32_AddrModeS);
2792         set_ia32_use_frame(fld);
2793         set_ia32_am_flavour(fld, ia32_am_B);
2794         set_ia32_am_support(fld, ia32_am_Source);
2795
2796         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_SetST0_M);
2797         fld   = new_r_Proj(irg, block, fld, mode_D, pn_ia32_SetST0_res);
2798         arch_set_irn_register(env->cg->arch_env, fld, &ia32_vfp_regs[REG_VF0]);
2799
2800         /* create a new barrier */
2801         arity = get_irn_arity(barrier);
2802         in = alloca(arity * sizeof(in[0]));
2803         for(i = 0; i < arity; ++i) {
2804                 ir_node *new_in;
2805                 if(i == pn_ret_val) {
2806                         new_in = fld;
2807                 } else if(i == pn_ret_mem) {
2808                         new_in = mproj;
2809                 } else {
2810                         ir_node *in = get_irn_n(barrier, i);
2811                         new_in = transform_node(env, in);
2812                 }
2813                 in[i] = new_in;
2814         }
2815
2816         new_barrier = new_ir_node(dbg, irg, block,
2817                                   get_irn_op(barrier), get_irn_mode(barrier),
2818                                   arity, in);
2819         copy_node_attr(barrier, new_barrier);
2820         duplicate_deps(env, barrier, new_barrier);
2821         set_new_node(barrier, new_barrier);
2822         mark_irn_visited(barrier);
2823
2824         /* transform normally */
2825         return duplicate_node(env, node);
2826 }
2827
2828 /**
2829  * Transform a be_AddSP into an ia32_AddSP. Eat up const sizes.
2830  */
2831 static ir_node *gen_be_AddSP(ia32_transform_env_t *env, ir_node *node) {
2832         ir_node *new_op;
2833         ir_graph *irg = env->irg;
2834         dbg_info *dbg = get_irn_dbg_info(node);
2835         ir_node *block = transform_node(env, get_nodes_block(node));
2836         ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
2837         ir_node *new_sz = transform_node(env, sz);
2838         ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
2839         ir_node *new_sp = transform_node(env, sp);
2840
2841         new_op = new_rd_ia32_AddSP(dbg, irg, block, new_sp, new_sz);
2842         fold_immediate(env, new_op, 0, 1);
2843
2844         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2845
2846         return new_op;
2847 }
2848
2849 /**
2850  * Transform a be_SubSP into an ia32_SubSP. Eat up const sizes.
2851  */
2852 static ir_node *gen_be_SubSP(ia32_transform_env_t *env, ir_node *node) {
2853         ir_node *new_op;
2854         ir_graph *irg = env->irg;
2855         dbg_info *dbg = get_irn_dbg_info(node);
2856         ir_node *block = transform_node(env, get_nodes_block(node));
2857         ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
2858         ir_node *new_sz = transform_node(env, sz);
2859         ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
2860         ir_node *new_sp = transform_node(env, sp);
2861
2862         new_op = new_rd_ia32_SubSP(dbg, irg, block, new_sp, new_sz);
2863         fold_immediate(env, new_op, 0, 1);
2864
2865         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2866
2867         return new_op;
2868 }
2869
2870 /**
2871  * This function just sets the register for the Unknown node
2872  * as this is not done during register allocation because Unknown
2873  * is an "ignore" node.
2874  */
2875 static ir_node *gen_Unknown(ia32_transform_env_t *env, ir_node *node) {
2876         ir_mode *mode = get_irn_mode(node);
2877
2878         if (mode_is_float(mode)) {
2879                 if (USE_SSE2(env->cg))
2880                         return ia32_new_Unknown_xmm(env->cg);
2881                 else
2882                         return ia32_new_Unknown_vfp(env->cg);
2883         } else if (mode_is_int(mode) || mode_is_reference(mode)) {
2884                 return ia32_new_Unknown_gp(env->cg);
2885         } else {
2886                 assert(0 && "unsupported Unknown-Mode");
2887         }
2888
2889         return NULL;
2890 }
2891
2892 /**
2893  * Change some phi modes
2894  */
2895 static ir_node *gen_Phi(ia32_transform_env_t *env, ir_node *node) {
2896         ir_graph *irg = env->irg;
2897         dbg_info *dbg = get_irn_dbg_info(node);
2898         ir_mode *mode = get_irn_mode(node);
2899         ir_node *block = transform_node(env, get_nodes_block(node));
2900         ir_node *phi;
2901         int i, arity;
2902
2903         if(mode_is_int(mode) || mode_is_reference(mode)) {
2904                 // we shouldn't have any 64bit stuff around anymore
2905                 assert(get_mode_size_bits(mode) <= 32);
2906                 // all integer operations are on 32bit registers now
2907                 mode = mode_Iu;
2908         } else if(mode_is_float(mode)) {
2909                 assert(mode == mode_D || mode == mode_F);
2910                 // all float operations are on mode_D registers
2911                 mode = mode_D;
2912         }
2913
2914         /* phi nodes allow loops, so we use the old arguments for now
2915          * and fix this later */
2916         phi = new_ir_node(dbg, irg, block, op_Phi, mode, get_irn_arity(node),
2917                           get_irn_in(node) + 1);
2918         copy_node_attr(node, phi);
2919         duplicate_deps(env, node, phi);
2920
2921         set_new_node(node, phi);
2922
2923         /* put the preds in the worklist */
2924         arity = get_irn_arity(node);
2925         for(i = 0; i < arity; ++i) {
2926                 ir_node *pred = get_irn_n(node, i);
2927                 pdeq_putr(env->worklist, pred);
2928         }
2929
2930         return phi;
2931 }
2932
2933 /**********************************************************************
2934  *  _                                _                   _
2935  * | |                              | |                 | |
2936  * | | _____      _____ _ __ ___  __| |  _ __   ___   __| | ___  ___
2937  * | |/ _ \ \ /\ / / _ \ '__/ _ \/ _` | | '_ \ / _ \ / _` |/ _ \/ __|
2938  * | | (_) \ V  V /  __/ | |  __/ (_| | | | | | (_) | (_| |  __/\__ \
2939  * |_|\___/ \_/\_/ \___|_|  \___|\__,_| |_| |_|\___/ \__,_|\___||___/
2940  *
2941  **********************************************************************/
2942
2943 /* These nodes are created in intrinsic lowering (64bit -> 32bit) */
2944
2945 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
2946                                      ir_node *mem);
2947
2948 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
2949                                       ir_node *val, ir_node *mem);
2950
2951 /**
2952  * Transforms a lowered Load into a "real" one.
2953  */
2954 static ir_node *gen_lowered_Load(ia32_transform_env_t *env, ir_node *node, construct_load_func func, char fp_unit) {
2955         ir_graph *irg  = env->irg;
2956         dbg_info *dbg  = get_irn_dbg_info(node);
2957         ir_node *block = transform_node(env, get_nodes_block(node));
2958         ir_mode *mode  = get_ia32_ls_mode(node);
2959         ir_node *new_op;
2960         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
2961         ir_node *ptr   = get_irn_n(node, 0);
2962         ir_node *mem   = get_irn_n(node, 1);
2963         ir_node *new_ptr = transform_node(env, ptr);
2964         ir_node *new_mem = transform_node(env, mem);
2965
2966         /*
2967                 Could be that we have SSE2 unit, but due to 64Bit Div/Conv
2968                 lowering we have x87 nodes, so we need to enforce simulation.
2969         */
2970         if (mode_is_float(mode)) {
2971                 FP_USED(env->cg);
2972                 if (fp_unit == fp_x87)
2973                         FORCE_x87(env->cg);
2974         }
2975
2976         new_op  = func(dbg, irg, block, new_ptr, noreg, new_mem);
2977
2978         set_ia32_am_support(new_op, ia32_am_Source);
2979         set_ia32_op_type(new_op, ia32_AddrModeS);
2980         set_ia32_am_flavour(new_op, ia32_am_OB);
2981         set_ia32_am_offs_int(new_op, 0);
2982         set_ia32_am_scale(new_op, 1);
2983         set_ia32_am_sc(new_op, get_ia32_am_sc(node));
2984         if(is_ia32_am_sc_sign(node))
2985                 set_ia32_am_sc_sign(new_op);
2986         set_ia32_ls_mode(new_op, get_ia32_ls_mode(node));
2987         if(is_ia32_use_frame(node)) {
2988                 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
2989                 set_ia32_use_frame(new_op);
2990         }
2991
2992         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2993
2994         return new_op;
2995 }
2996
2997 /**
2998 * Transforms a lowered Store into a "real" one.
2999 */
3000 static ir_node *gen_lowered_Store(ia32_transform_env_t *env, ir_node *node, construct_store_func func, char fp_unit) {
3001         ir_graph *irg  = env->irg;
3002         dbg_info *dbg  = get_irn_dbg_info(node);
3003         ir_node *block = transform_node(env, get_nodes_block(node));
3004         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
3005         ir_mode *mode  = get_ia32_ls_mode(node);
3006         ir_node *new_op;
3007         long am_offs;
3008         ia32_am_flavour_t am_flav = ia32_B;
3009         ir_node *ptr = get_irn_n(node, 0);
3010         ir_node *val = get_irn_n(node, 1);
3011         ir_node *mem = get_irn_n(node, 2);
3012         ir_node *new_ptr = transform_node(env, ptr);
3013         ir_node *new_val = transform_node(env, val);
3014         ir_node *new_mem = transform_node(env, mem);
3015
3016         /*
3017                 Could be that we have SSE2 unit, but due to 64Bit Div/Conv
3018                 lowering we have x87 nodes, so we need to enforce simulation.
3019         */
3020         if (mode_is_float(mode)) {
3021                 FP_USED(env->cg);
3022                 if (fp_unit == fp_x87)
3023                         FORCE_x87(env->cg);
3024         }
3025
3026         new_op = func(dbg, irg, block, new_ptr, noreg, new_val, new_mem);
3027
3028         if ((am_offs = get_ia32_am_offs_int(node)) != 0) {
3029                 am_flav |= ia32_O;
3030                 add_ia32_am_offs_int(new_op, am_offs);
3031         }
3032
3033         set_ia32_am_support(new_op, ia32_am_Dest);
3034         set_ia32_op_type(new_op, ia32_AddrModeD);
3035         set_ia32_am_flavour(new_op, am_flav);
3036         set_ia32_ls_mode(new_op, mode);
3037         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3038         set_ia32_use_frame(new_op);
3039
3040         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
3041
3042         return new_op;
3043 }
3044
3045
3046 /**
3047  * Transforms an ia32_l_XXX into a "real" XXX node
3048  *
3049  * @param env   The transformation environment
3050  * @return the created ia32 XXX node
3051  */
3052 #define GEN_LOWERED_OP(op)                                                     \
3053         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env, ir_node *node) {\
3054                 ir_mode *mode = get_irn_mode(node);                                    \
3055                 if (mode_is_float(mode))                                               \
3056                         FP_USED(env->cg);                                                  \
3057                 return gen_binop(env, node, get_binop_left(node),                      \
3058                                  get_binop_right(node), new_rd_ia32_##op);             \
3059         }
3060
3061 #define GEN_LOWERED_x87_OP(op)                                                 \
3062         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env, ir_node *node) {\
3063                 ir_node *new_op;                                                       \
3064                 FORCE_x87(env->cg);                                                    \
3065                 new_op = gen_binop_float(env, node, get_binop_left(node),              \
3066                                          get_binop_right(node), new_rd_ia32_##op);     \
3067                 return new_op;                                                         \
3068         }
3069
3070 #define GEN_LOWERED_UNOP(op)                                                   \
3071         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env, ir_node *node) {\
3072                 return gen_unop(env, node, get_unop_op(node), new_rd_ia32_##op);       \
3073         }
3074
3075 #define GEN_LOWERED_SHIFT_OP(op)                                               \
3076         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env, ir_node *node) {\
3077                 return gen_shift_binop(env, node, get_binop_left(node),                \
3078                                        get_binop_right(node), new_rd_ia32_##op);       \
3079         }
3080
3081 #define GEN_LOWERED_LOAD(op, fp_unit)                                          \
3082         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env, ir_node *node) {\
3083                 return gen_lowered_Load(env, node, new_rd_ia32_##op, fp_unit);         \
3084         }
3085
3086 #define GEN_LOWERED_STORE(op, fp_unit)                                         \
3087         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env, ir_node *node) {\
3088                 return gen_lowered_Store(env, node, new_rd_ia32_##op, fp_unit);        \
3089         }
3090
3091 GEN_LOWERED_OP(AddC)
3092 GEN_LOWERED_OP(Add)
3093 GEN_LOWERED_OP(SubC)
3094 GEN_LOWERED_OP(Sub)
3095 GEN_LOWERED_OP(Mul)
3096 GEN_LOWERED_OP(Eor)
3097 GEN_LOWERED_x87_OP(vfprem)
3098 GEN_LOWERED_x87_OP(vfmul)
3099 GEN_LOWERED_x87_OP(vfsub)
3100
3101 GEN_LOWERED_UNOP(Minus)
3102
3103 GEN_LOWERED_LOAD(vfild, fp_x87)
3104 GEN_LOWERED_LOAD(Load, fp_none)
3105 GEN_LOWERED_STORE(vfist, fp_x87)
3106 GEN_LOWERED_STORE(Store, fp_none)
3107
3108 static ir_node *gen_ia32_l_vfdiv(ia32_transform_env_t *env, ir_node *node) {
3109         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
3110         ir_graph *irg = env->irg;
3111         dbg_info *dbg = get_irn_dbg_info(node);
3112         ir_node *block = transform_node(env, get_nodes_block(node));
3113         ir_node *left = get_binop_left(node);
3114         ir_node *right = get_binop_right(node);
3115         ir_node *new_left = transform_node(env, left);
3116         ir_node *new_right = transform_node(env, right);
3117         ir_node *vfdiv;
3118
3119         vfdiv = new_rd_ia32_vfdiv(dbg, irg, block, noreg, noreg, new_left, new_right, new_NoMem());
3120         clear_ia32_commutative(vfdiv);
3121         set_ia32_am_support(vfdiv, ia32_am_Source);
3122         fold_immediate(env, vfdiv, 2, 3);
3123
3124         SET_IA32_ORIG_NODE(vfdiv, ia32_get_old_node_name(env->cg, node));
3125
3126         FORCE_x87(env->cg);
3127
3128         return vfdiv;
3129 }
3130
3131 /**
3132  * Transforms a l_MulS into a "real" MulS node.
3133  *
3134  * @param env   The transformation environment
3135  * @return the created ia32 MulS node
3136  */
3137 static ir_node *gen_ia32_l_MulS(ia32_transform_env_t *env, ir_node *node) {
3138         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
3139         ir_graph *irg = env->irg;
3140         dbg_info *dbg = get_irn_dbg_info(node);
3141         ir_node *block = transform_node(env, get_nodes_block(node));
3142         ir_node *left = get_binop_left(node);
3143         ir_node *right = get_binop_right(node);
3144         ir_node *in[2];
3145
3146         /* l_MulS is already a mode_T node, so we create the MulS in the normal way   */
3147         /* and then skip the result Proj, because all needed Projs are already there. */
3148
3149         ir_node *muls = new_rd_ia32_MulS(dbg, irg, block, noreg, noreg, left, right, new_NoMem());
3150         clear_ia32_commutative(muls);
3151         set_ia32_am_support(muls, ia32_am_Source);
3152         fold_immediate(env, muls, 2, 3);
3153
3154         /* check if EAX and EDX proj exist, add missing one */
3155         in[0] = new_rd_Proj(dbg, irg, block, muls, mode_Iu, pn_EAX);
3156         in[1] = new_rd_Proj(dbg, irg, block, muls, mode_Iu, pn_EDX);
3157         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 2, in);
3158
3159         SET_IA32_ORIG_NODE(muls, ia32_get_old_node_name(env->cg, node));
3160
3161         return muls;
3162 }
3163
3164 GEN_LOWERED_SHIFT_OP(Shl)
3165 GEN_LOWERED_SHIFT_OP(Shr)
3166 GEN_LOWERED_SHIFT_OP(Shrs)
3167
3168 /**
3169  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3170  * op1 - target to be shifted
3171  * op2 - contains bits to be shifted into target
3172  * op3 - shift count
3173  * Only op3 can be an immediate.
3174  */
3175 static ir_node *gen_lowered_64bit_shifts(ia32_transform_env_t *env, ir_node *node,
3176                                          ir_node *op1, ir_node *op2,
3177                                          ir_node *count) {
3178         ir_node   *new_op = NULL;
3179         ir_graph  *irg    = env->irg;
3180         ir_mode   *mode   = get_irn_mode(node);
3181         dbg_info  *dbg    = get_irn_dbg_info(node);
3182         ir_node   *block  = transform_node(env, get_nodes_block(node));
3183         ir_node   *noreg  = ia32_new_NoReg_gp(env->cg);
3184         ir_node   *nomem  = new_NoMem();
3185         ir_node   *imm_op;
3186         ir_node   *new_op1 = transform_node(env, op1);
3187         ir_node   *new_op2 = transform_node(env, op2);
3188         ir_node   *new_count = transform_node(env, count);
3189         tarval    *tv;
3190         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
3191
3192         assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");
3193
3194         /* Check if immediate optimization is on and */
3195         /* if it's an operation with immediate.      */
3196         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, new_count) : NULL;
3197
3198         /* Limit imm_op within range imm8 */
3199         if (imm_op) {
3200                 tv = get_ia32_Immop_tarval(imm_op);
3201
3202                 if (tv) {
3203                         tv = tarval_mod(tv, new_tarval_from_long(32, get_tarval_mode(tv)));
3204                         set_ia32_Immop_tarval(imm_op, tv);
3205                 }
3206                 else {
3207                         imm_op = NULL;
3208                 }
3209         }
3210
3211         /* integer operations */
3212         if (imm_op) {
3213                 /* This is ShiftD with const */
3214                 DB((mod, LEVEL_1, "ShiftD with immediate ..."));
3215
3216                 if (is_ia32_l_ShlD(node))
3217                         new_op = new_rd_ia32_ShlD(dbg, irg, block, noreg, noreg,
3218                                                   new_op1, new_op2, noreg, nomem);
3219                 else
3220                         new_op = new_rd_ia32_ShrD(dbg, irg, block, noreg, noreg,
3221                                                   new_op1, new_op2, noreg, nomem);
3222                 set_ia32_Immop_attr(new_op, imm_op);
3223         }
3224         else {
3225                 /* This is a normal ShiftD */
3226                 DB((mod, LEVEL_1, "ShiftD binop ..."));
3227                 if (is_ia32_l_ShlD(node))
3228                         new_op = new_rd_ia32_ShlD(dbg, irg, block, noreg, noreg,
3229                                                   new_op1, new_op2, new_count, nomem);
3230                 else
3231                         new_op = new_rd_ia32_ShrD(dbg, irg, block, noreg, noreg,
3232                                                   new_op1, new_op2, new_count, nomem);
3233         }
3234
3235         /* set AM support */
3236         // Matze: node has unsupported format (6inputs)
3237         //set_ia32_am_support(new_op, ia32_am_Dest);
3238
3239         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
3240
3241         set_ia32_emit_cl(new_op);
3242
3243         return new_op;
3244 }
3245
3246 static ir_node *gen_ia32_l_ShlD(ia32_transform_env_t *env, ir_node *node) {
3247         return gen_lowered_64bit_shifts(env, node, get_irn_n(node, 0),
3248                                         get_irn_n(node, 1), get_irn_n(node, 2));
3249 }
3250
3251 static ir_node *gen_ia32_l_ShrD(ia32_transform_env_t *env, ir_node *node) {
3252         return gen_lowered_64bit_shifts(env, node, get_irn_n(node, 0),
3253                                         get_irn_n(node, 1), get_irn_n(node, 2));
3254 }
3255
3256 /**
3257  * In case SSE Unit is used, the node is transformed into a vfst + xLoad.
3258  */
3259 static ir_node *gen_ia32_l_X87toSSE(ia32_transform_env_t *env, ir_node *node) {
3260         ia32_code_gen_t *cg  = env->cg;
3261         ir_node         *res = NULL;
3262         ir_graph        *irg = env->irg;
3263         dbg_info        *dbg = get_irn_dbg_info(node);
3264         ir_node       *block = transform_node(env, get_nodes_block(node));
3265         ir_node         *ptr = get_irn_n(node, 0);
3266         ir_node         *val = get_irn_n(node, 1);
3267         ir_node     *new_val = transform_node(env, val);
3268         ir_node         *mem = get_irn_n(node, 2);
3269         ir_node *noreg, *new_ptr, *new_mem;
3270
3271         if (USE_SSE2(cg)) {
3272                 return new_val;
3273         }
3274
3275         noreg = ia32_new_NoReg_gp(cg);
3276         new_mem = transform_node(env, mem);
3277         new_ptr = transform_node(env, ptr);
3278
3279         /* Store x87 -> MEM */
3280         res = new_rd_ia32_vfst(dbg, irg, block, new_ptr, noreg, new_val, new_mem);
3281         set_ia32_frame_ent(res, get_ia32_frame_ent(node));
3282         set_ia32_use_frame(res);
3283         set_ia32_ls_mode(res, get_ia32_ls_mode(node));
3284         set_ia32_am_support(res, ia32_am_Dest);
3285         set_ia32_am_flavour(res, ia32_B);
3286         set_ia32_op_type(res, ia32_AddrModeD);
3287
3288         /* Load MEM -> SSE */
3289         res = new_rd_ia32_xLoad(dbg, irg, block, new_ptr, noreg, res);
3290         set_ia32_frame_ent(res, get_ia32_frame_ent(node));
3291         set_ia32_use_frame(res);
3292         set_ia32_ls_mode(res, get_ia32_ls_mode(node));
3293         set_ia32_am_support(res, ia32_am_Source);
3294         set_ia32_am_flavour(res, ia32_B);
3295         set_ia32_op_type(res, ia32_AddrModeS);
3296         res = new_rd_Proj(dbg, irg, block, res, mode_D, pn_ia32_xLoad_res);
3297
3298         return res;
3299 }
3300
3301 /**
3302  * In case SSE Unit is used, the node is transformed into a xStore + vfld.
3303  */
3304 static ir_node *gen_ia32_l_SSEtoX87(ia32_transform_env_t *env, ir_node *node) {
3305         ia32_code_gen_t *cg     = env->cg;
3306         ir_graph        *irg    = env->irg;
3307         dbg_info        *dbg    = get_irn_dbg_info(node);
3308         ir_node         *block  = transform_node(env, get_nodes_block(node));
3309         ir_node         *res    = NULL;
3310         ir_node         *ptr    = get_irn_n(node, 0);
3311         ir_node         *val    = get_irn_n(node, 1);
3312         ir_node         *mem    = get_irn_n(node, 2);
3313         ir_entity       *fent   = get_ia32_frame_ent(node);
3314         ir_mode         *lsmode = get_ia32_ls_mode(node);
3315         ir_node        *new_val = transform_node(env, val);
3316         ir_node *noreg, *new_ptr, *new_mem;
3317         int             offs    = 0;
3318
3319         if (!USE_SSE2(cg)) {
3320                 /* SSE unit is not used -> skip this node. */
3321                 return new_val;
3322         }
3323
3324         noreg = ia32_new_NoReg_gp(cg);
3325         new_val = transform_node(env, val);
3326         new_ptr = transform_node(env, ptr);
3327         new_mem = transform_node(env, mem);
3328
3329         /* Store SSE -> MEM */
3330         if (is_ia32_xLoad(skip_Proj(new_val))) {
3331                 ir_node *ld = skip_Proj(new_val);
3332
3333                 /* we can vfld the value directly into the fpu */
3334                 fent = get_ia32_frame_ent(ld);
3335                 ptr  = get_irn_n(ld, 0);
3336                 offs = get_ia32_am_offs_int(ld);
3337         } else {
3338                 res = new_rd_ia32_xStore(dbg, irg, block, new_ptr, noreg, new_val, new_mem);
3339                 set_ia32_frame_ent(res, fent);
3340                 set_ia32_use_frame(res);
3341                 set_ia32_ls_mode(res, lsmode);
3342                 set_ia32_am_support(res, ia32_am_Dest);
3343                 set_ia32_am_flavour(res, ia32_B);
3344                 set_ia32_op_type(res, ia32_AddrModeD);
3345                 mem = res;
3346         }
3347
3348         /* Load MEM -> x87 */
3349         res = new_rd_ia32_vfld(dbg, irg, block, new_ptr, noreg, new_mem);
3350         set_ia32_frame_ent(res, fent);
3351         set_ia32_use_frame(res);
3352         set_ia32_ls_mode(res, lsmode);
3353         add_ia32_am_offs_int(res, offs);
3354         set_ia32_am_support(res, ia32_am_Source);
3355         set_ia32_am_flavour(res, ia32_B);
3356         set_ia32_op_type(res, ia32_AddrModeS);
3357         res = new_rd_Proj(dbg, irg, block, res, lsmode, pn_ia32_vfld_res);
3358
3359         return res;
3360 }
3361
3362 /*********************************************************
3363  *                  _             _      _
3364  *                 (_)           | |    (_)
3365  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
3366  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
3367  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
3368  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
3369  *
3370  *********************************************************/
3371
3372 /**
3373  * the BAD transformer.
3374  */
3375 static ir_node *bad_transform(ia32_transform_env_t *env, ir_node *node) {
3376         panic("No transform function for %+F available.\n", node);
3377         return NULL;
3378 }
3379
3380 static ir_node *gen_End(ia32_transform_env_t *env, ir_node *node) {
3381         /* end has to be duplicated manually because we need a dynamic in array */
3382         ir_graph *irg = env->irg;
3383         dbg_info *dbg = get_irn_dbg_info(node);
3384         ir_node *block = transform_node(env, get_nodes_block(node));
3385         int i, arity;
3386         ir_node *new_end;
3387
3388         new_end = new_ir_node(dbg, irg, block, op_End, mode_X, -1, NULL);
3389         copy_node_attr(node, new_end);
3390         duplicate_deps(env, node, new_end);
3391
3392         set_irg_end(irg, new_end);
3393         set_new_node(new_end, new_end);
3394
3395         /* transform preds */
3396         arity = get_irn_arity(node);
3397         for(i = 0; i < arity; ++i) {
3398                 ir_node *in = get_irn_n(node, i);
3399                 ir_node *new_in = transform_node(env, in);
3400
3401                 add_End_keepalive(new_end, new_in);
3402         }
3403
3404         return new_end;
3405 }
3406
3407 static ir_node *gen_Block(ia32_transform_env_t *env, ir_node *node) {
3408         ir_graph *irg = env->irg;
3409         dbg_info *dbg = get_irn_dbg_info(node);
3410         ir_node *start_block = env->old_anchors[anchor_start_block];
3411         ir_node *block;
3412         int i, arity;
3413
3414         /*
3415          * We replace the ProjX from the start node with a jump,
3416          * so the startblock has no preds anymore now
3417          */
3418         if(node == start_block) {
3419                 return new_rd_Block(dbg, irg, 0, NULL);
3420         }
3421
3422         /* we use the old blocks for now, because jumps allow cycles in the graph
3423          * we have to fix this later */
3424         block = new_ir_node(dbg, irg, NULL, get_irn_op(node), get_irn_mode(node),
3425                             get_irn_arity(node), get_irn_in(node) + 1);
3426         copy_node_attr(node, block);
3427
3428 #ifdef DEBUG_libfirm
3429         block->node_nr = node->node_nr;
3430 #endif
3431         set_new_node(node, block);
3432
3433         /* put the preds in the worklist */
3434         arity = get_irn_arity(node);
3435         for(i = 0; i < arity; ++i) {
3436                 ir_node *in = get_irn_n(node, i);
3437                 pdeq_putr(env->worklist, in);
3438         }
3439
3440         return block;
3441 }
3442
3443 static ir_node *gen_Proj_be_AddSP(ia32_transform_env_t *env, ir_node *node) {
3444         ir_graph *irg = env->irg;
3445         ir_node *block = transform_node(env, get_nodes_block(node));
3446         dbg_info *dbg = get_irn_dbg_info(node);
3447         ir_node *pred = get_Proj_pred(node);
3448         ir_node *new_pred = transform_node(env, pred);
3449         int proj      = get_Proj_proj(node);
3450
3451         if(proj == pn_be_AddSP_res) {
3452                 ir_node *res = new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_AddSP_stack);
3453                 arch_set_irn_register(env->cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3454                 return res;
3455         } else if(proj == pn_be_AddSP_M) {
3456                 return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3457         }
3458
3459         assert(0);
3460         return new_rd_Unknown(irg, get_irn_mode(node));
3461 }
3462
3463 static ir_node *gen_Proj_be_SubSP(ia32_transform_env_t *env, ir_node *node) {
3464         ir_graph *irg = env->irg;
3465         ir_node *block = transform_node(env, get_nodes_block(node));
3466         dbg_info *dbg = get_irn_dbg_info(node);
3467         ir_node *pred = get_Proj_pred(node);
3468         ir_node *new_pred = transform_node(env, pred);
3469         int proj      = get_Proj_proj(node);
3470
3471         if(proj == pn_be_SubSP_res) {
3472                 ir_node *res = new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_AddSP_stack);
3473                 arch_set_irn_register(env->cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3474                 return res;
3475         } else if(proj == pn_be_SubSP_M) {
3476                 return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3477         }
3478
3479         assert(0);
3480         return new_rd_Unknown(irg, get_irn_mode(node));
3481 }
3482
3483 static ir_node *gen_Proj_Load(ia32_transform_env_t *env, ir_node *node) {
3484         ir_graph *irg = env->irg;
3485         ir_node *block = transform_node(env, get_nodes_block(node));
3486         dbg_info *dbg = get_irn_dbg_info(node);
3487         ir_node *pred = get_Proj_pred(node);
3488         ir_node *new_pred = transform_node(env, pred);
3489         int proj      = get_Proj_proj(node);
3490
3491         /* renumber the proj */
3492         if(is_ia32_Load(new_pred)) {
3493                 if(proj == pn_Load_res) {
3494                         return new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
3495                 } else if(proj == pn_Load_M) {
3496                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_Load_M);
3497                 }
3498         } else if(is_ia32_xLoad(new_pred)) {
3499                 if(proj == pn_Load_res) {
3500                         return new_rd_Proj(dbg, irg, block, new_pred, mode_D, pn_ia32_xLoad_res);
3501                 } else if(proj == pn_Load_M) {
3502                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
3503                 }
3504         } else if(is_ia32_vfld(new_pred)) {
3505                 if(proj == pn_Load_res) {
3506                         return new_rd_Proj(dbg, irg, block, new_pred, mode_D, pn_ia32_vfld_res);
3507                 } else if(proj == pn_Load_M) {
3508                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
3509                 }
3510         }
3511
3512         assert(0);
3513         return new_rd_Unknown(irg, get_irn_mode(node));
3514 }
3515
3516 static ir_node *gen_Proj_DivMod(ia32_transform_env_t *env, ir_node *node) {
3517         ir_graph *irg = env->irg;
3518         dbg_info *dbg = get_irn_dbg_info(node);
3519         ir_node *block = transform_node(env, get_nodes_block(node));
3520         ir_mode *mode = get_irn_mode(node);
3521
3522         ir_node *pred = get_Proj_pred(node);
3523         ir_node *new_pred = transform_node(env, pred);
3524         int proj = get_Proj_proj(node);
3525
3526         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
3527
3528         switch(get_irn_opcode(pred)) {
3529         case iro_Div:
3530                 switch(proj) {
3531                 case pn_Div_M:
3532                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_Div_M);
3533                 case pn_Div_res:
3534                         return new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
3535                 default:
3536                         break;
3537                 }
3538                 break;
3539         case iro_Mod:
3540                 switch(proj) {
3541                 case pn_Mod_M:
3542                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_Div_M);
3543                 case pn_Mod_res:
3544                         return new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
3545                 default:
3546                         break;
3547                 }
3548                 break;
3549         case iro_DivMod:
3550                 switch(proj) {
3551                 case pn_DivMod_M:
3552                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_Div_M);
3553                 case pn_DivMod_res_div:
3554                         return new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
3555                 case pn_DivMod_res_mod:
3556                         return new_rd_Proj(dbg, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
3557                 default:
3558                         break;
3559                 }
3560                 break;
3561         default:
3562                 break;
3563         }
3564
3565         assert(0);
3566         return new_rd_Unknown(irg, mode);
3567 }
3568
3569 static ir_node *gen_Proj_CopyB(ia32_transform_env_t *env, ir_node *node)
3570 {
3571         ir_graph *irg = env->irg;
3572         dbg_info *dbg = get_irn_dbg_info(node);
3573         ir_node *block = transform_node(env, get_nodes_block(node));
3574         ir_mode *mode = get_irn_mode(node);
3575
3576         ir_node *pred = get_Proj_pred(node);
3577         ir_node *new_pred = transform_node(env, pred);
3578         int proj = get_Proj_proj(node);
3579
3580         switch(proj) {
3581         case pn_CopyB_M_regular:
3582                 if(is_ia32_CopyB_i(new_pred)) {
3583                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M,
3584                                            pn_ia32_CopyB_i_M);
3585                 } else if(is_ia32_CopyB(new_pred)) {
3586                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M,
3587                                            pn_ia32_CopyB_M);
3588                 }
3589                 break;
3590         default:
3591                 break;
3592         }
3593
3594         assert(0);
3595         return new_rd_Unknown(irg, mode);
3596 }
3597
3598 static ir_node *gen_Proj_l_vfdiv(ia32_transform_env_t *env, ir_node *node)
3599 {
3600         ir_graph *irg = env->irg;
3601         dbg_info *dbg = get_irn_dbg_info(node);
3602         ir_node *block = transform_node(env, get_nodes_block(node));
3603         ir_mode *mode = get_irn_mode(node);
3604
3605         ir_node *pred = get_Proj_pred(node);
3606         ir_node *new_pred = transform_node(env, pred);
3607         int proj = get_Proj_proj(node);
3608
3609         switch(proj) {
3610         case pn_ia32_l_vfdiv_M:
3611                 return new_rd_Proj(dbg, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
3612         case pn_ia32_l_vfdiv_res:
3613                 return new_rd_Proj(dbg, irg, block, new_pred, mode_D, pn_ia32_vfdiv_res);
3614         default:
3615                 assert(0);
3616         }
3617
3618         return new_rd_Unknown(irg, mode);
3619 }
3620
3621 static ir_node *gen_Proj_Quot(ia32_transform_env_t *env, ir_node *node)
3622 {
3623         ir_graph *irg = env->irg;
3624         dbg_info *dbg = get_irn_dbg_info(node);
3625         ir_node *block = transform_node(env, get_nodes_block(node));
3626         ir_mode *mode = get_irn_mode(node);
3627
3628         ir_node *pred = get_Proj_pred(node);
3629         ir_node *new_pred = transform_node(env, pred);
3630         int proj = get_Proj_proj(node);
3631
3632         switch(proj) {
3633         case pn_Quot_M:
3634                 if(is_ia32_xDiv(new_pred)) {
3635                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M,
3636                                            pn_ia32_xDiv_M);
3637                 } else if(is_ia32_vfdiv(new_pred)) {
3638                         return new_rd_Proj(dbg, irg, block, new_pred, mode_M,
3639                                            pn_ia32_vfdiv_M);
3640                 }
3641                 break;
3642         case pn_Quot_res:
3643                 if(is_ia32_xDiv(new_pred)) {
3644                         return new_rd_Proj(dbg, irg, block, new_pred, mode,
3645                                            pn_ia32_xDiv_res);
3646                 } else if(is_ia32_vfdiv(new_pred)) {
3647                         return new_rd_Proj(dbg, irg, block, new_pred, mode,
3648                                            pn_ia32_vfdiv_res);
3649                 }
3650                 break;
3651         default:
3652                 break;
3653         }
3654
3655         assert(0);
3656         return new_rd_Unknown(irg, mode);
3657 }
3658
3659 static ir_node *gen_Proj(ia32_transform_env_t *env, ir_node *node) {
3660         ir_graph *irg = env->irg;
3661         dbg_info *dbg = get_irn_dbg_info(node);
3662         ir_node *pred = get_Proj_pred(node);
3663         int proj = get_Proj_proj(node);
3664
3665         if(is_Store(pred) || be_is_FrameStore(pred)) {
3666                 if(proj == pn_Store_M) {
3667                         return transform_node(env, pred);
3668                 } else {
3669                         assert(0);
3670                         return new_r_Bad(irg);
3671                 }
3672         } else if(is_Load(pred) || be_is_FrameLoad(pred)) {
3673                 return gen_Proj_Load(env, node);
3674         } else if(is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
3675                 return gen_Proj_DivMod(env, node);
3676         } else if(is_CopyB(pred)) {
3677                 return gen_Proj_CopyB(env, node);
3678         } else if(is_Quot(pred)) {
3679                 return gen_Proj_Quot(env, node);
3680         } else if(is_ia32_l_vfdiv(pred)) {
3681                 return gen_Proj_l_vfdiv(env, node);
3682         } else if(be_is_SubSP(pred)) {
3683                 return gen_Proj_be_SubSP(env, node);
3684         } else if(be_is_AddSP(pred)) {
3685                 return gen_Proj_be_AddSP(env, node);
3686         } else if(get_irn_op(pred) == op_Start && proj == pn_Start_X_initial_exec) {
3687                 ir_node *block = get_nodes_block(pred);
3688                 ir_node *jump;
3689
3690                 block = transform_node(env, block);
3691                 // we exchange the ProjX with a jump
3692                 jump = new_rd_Jmp(dbg, irg, block);
3693                 ir_fprintf(stderr, "created jump: %+F\n", jump);
3694                 return jump;
3695         }
3696
3697         return duplicate_node(env, node);
3698 }
3699
3700 /**
3701  * Enters all transform functions into the generic pointer
3702  */
3703 static void register_transformers(void) {
3704         ir_op *op_Max, *op_Min, *op_Mulh;
3705
3706         /* first clear the generic function pointer for all ops */
3707         clear_irp_opcodes_generic_func();
3708
3709 #define GEN(a)   { transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
3710 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
3711
3712         GEN(Add);
3713         GEN(Sub);
3714         GEN(Mul);
3715         GEN(And);
3716         GEN(Or);
3717         GEN(Eor);
3718
3719         GEN(Shl);
3720         GEN(Shr);
3721         GEN(Shrs);
3722         GEN(Rot);
3723
3724         GEN(Quot);
3725
3726         GEN(Div);
3727         GEN(Mod);
3728         GEN(DivMod);
3729
3730         GEN(Minus);
3731         GEN(Conv);
3732         GEN(Abs);
3733         GEN(Not);
3734
3735         GEN(Load);
3736         GEN(Store);
3737         GEN(Cond);
3738
3739         GEN(CopyB);
3740         //GEN(Mux);
3741         BAD(Mux);
3742         GEN(Psi);
3743         GEN(Proj);
3744         GEN(Phi);
3745
3746         GEN(Block);
3747         GEN(End);
3748
3749         /* transform ops from intrinsic lowering */
3750         GEN(ia32_l_Add);
3751         GEN(ia32_l_AddC);
3752         GEN(ia32_l_Sub);
3753         GEN(ia32_l_SubC);
3754         GEN(ia32_l_Minus);
3755         GEN(ia32_l_Mul);
3756         GEN(ia32_l_Eor);
3757         GEN(ia32_l_MulS);
3758         GEN(ia32_l_Shl);
3759         GEN(ia32_l_Shr);
3760         GEN(ia32_l_Shrs);
3761         GEN(ia32_l_ShlD);
3762         GEN(ia32_l_ShrD);
3763         GEN(ia32_l_vfdiv);
3764         GEN(ia32_l_vfprem);
3765         GEN(ia32_l_vfmul);
3766         GEN(ia32_l_vfsub);
3767         GEN(ia32_l_vfild);
3768         GEN(ia32_l_Load);
3769         GEN(ia32_l_vfist);
3770         GEN(ia32_l_Store);
3771         GEN(ia32_l_X87toSSE);
3772         GEN(ia32_l_SSEtoX87);
3773
3774         GEN(Const);
3775         GEN(SymConst);
3776
3777         /* we should never see these nodes */
3778         BAD(Raise);
3779         BAD(Sel);
3780         BAD(InstOf);
3781         BAD(Cast);
3782         BAD(Free);
3783         BAD(Tuple);
3784         BAD(Id);
3785         //BAD(Bad);
3786         BAD(Confirm);
3787         BAD(Filter);
3788         BAD(CallBegin);
3789         BAD(EndReg);
3790         BAD(EndExcept);
3791
3792         /* handle generic backend nodes */
3793         GEN(be_FrameAddr);
3794         GEN(be_Call);
3795         GEN(be_Return);
3796         GEN(be_FrameLoad);
3797         GEN(be_FrameStore);
3798         GEN(be_StackParam);
3799         GEN(be_AddSP);
3800         GEN(be_SubSP);
3801
3802         /* set the register for all Unknown nodes */
3803         GEN(Unknown);
3804
3805         op_Max = get_op_Max();
3806         if (op_Max)
3807                 GEN(Max);
3808         op_Min = get_op_Min();
3809         if (op_Min)
3810                 GEN(Min);
3811         op_Mulh = get_op_Mulh();
3812         if (op_Mulh)
3813                 GEN(Mulh);
3814
3815 #undef GEN
3816 #undef BAD
3817 }
3818
3819 static void duplicate_deps(ia32_transform_env_t *env, ir_node *old_node,
3820                            ir_node *new_node)
3821 {
3822         int i;
3823         int deps = get_irn_deps(old_node);
3824
3825         for(i = 0; i < deps; ++i) {
3826                 ir_node *dep = get_irn_dep(old_node, i);
3827                 ir_node *new_dep = transform_node(env, dep);
3828
3829                 add_irn_dep(new_node, new_dep);
3830         }
3831 }
3832
3833 static ir_node *duplicate_node(ia32_transform_env_t *env, ir_node *node)
3834 {
3835         ir_graph *irg = env->irg;
3836         dbg_info *dbg = get_irn_dbg_info(node);
3837         ir_mode *mode = get_irn_mode(node);
3838         ir_op     *op = get_irn_op(node);
3839         ir_node *block;
3840         ir_node *new_node;
3841         int i, arity;
3842         ir_node **ins;
3843
3844         block = transform_node(env, get_nodes_block(node));
3845
3846         arity = get_irn_arity(node);
3847         ins = alloca(arity * sizeof(ins[0]));
3848         for(i = 0; i < arity; ++i) {
3849                 ir_node *in = get_irn_n(node, i);
3850                 ins[i] = transform_node(env, in);
3851         }
3852
3853         new_node = new_ir_node(dbg, irg, block,
3854                                op, mode, arity, ins);
3855         copy_node_attr(node, new_node);
3856         duplicate_deps(env, node, new_node);
3857
3858         return new_node;
3859 }
3860
3861 static ir_node *transform_node(ia32_transform_env_t *env, ir_node *node)
3862 {
3863         ir_node *new_node;
3864         ir_op   *op = get_irn_op(node);
3865
3866         if(irn_visited(node)) {
3867                 assert(get_new_node(node) != NULL);
3868                 return get_new_node(node);
3869         }
3870
3871         mark_irn_visited(node);
3872         DEBUG_ONLY(set_new_node(node, NULL));
3873
3874         if (op->ops.generic) {
3875                 transform_func *transform = (transform_func *)op->ops.generic;
3876
3877                 new_node = (*transform)(env, node);
3878                 assert(new_node != NULL);
3879         } else {
3880                 new_node = duplicate_node(env, node);
3881         }
3882         //ir_fprintf(stderr, "%+F -> %+F\n", node, new_node);
3883
3884         set_new_node(node, new_node);
3885         mark_irn_visited(new_node);
3886         hook_dead_node_elim_subst(current_ir_graph, node, new_node);
3887         return new_node;
3888 }
3889
3890 static void fix_loops(ia32_transform_env_t *env, ir_node *node)
3891 {
3892         int i, arity;
3893
3894         if(irn_visited(node))
3895                 return;
3896         mark_irn_visited(node);
3897
3898         assert(node_is_in_irgs_storage(env->irg, node));
3899
3900         if(!is_Block(node)) {
3901                 ir_node *block = get_nodes_block(node);
3902                 ir_node *new_block = (ir_node*) get_irn_link(block);
3903
3904                 if(new_block != NULL) {
3905                         set_nodes_block(node, new_block);
3906                         block = new_block;
3907                 }
3908
3909                 fix_loops(env, block);
3910         }
3911
3912         arity = get_irn_arity(node);
3913         for(i = 0; i < arity; ++i) {
3914                 ir_node *in = get_irn_n(node, i);
3915                 ir_node *new = (ir_node*) get_irn_link(in);
3916
3917                 if(new != NULL && new != in) {
3918                         set_irn_n(node, i, new);
3919                         in = new;
3920                 }
3921
3922                 fix_loops(env, in);
3923         }
3924
3925         arity = get_irn_deps(node);
3926         for(i = 0; i < arity; ++i) {
3927                 ir_node *in = get_irn_dep(node, i);
3928                 ir_node *new = (ir_node*) get_irn_link(in);
3929
3930                 if(new != NULL && new != in) {
3931                         set_irn_dep(node, i, new);
3932                         in = new;
3933                 }
3934
3935                 fix_loops(env, in);
3936         }
3937 }
3938
3939 static void pre_transform_node(ir_node **place, ia32_transform_env_t *env)
3940 {
3941         if(*place == NULL)
3942                 return;
3943
3944         *place = transform_node(env, *place);
3945 }
3946
3947 static void transform_nodes(ia32_code_gen_t *cg)
3948 {
3949         int i;
3950         ir_graph *irg = cg->irg;
3951         ir_node *old_end;
3952         ia32_transform_env_t env;
3953
3954         hook_dead_node_elim(irg, 1);
3955
3956         inc_irg_visited(irg);
3957
3958         env.irg = irg;
3959         env.cg = cg;
3960         env.visited = get_irg_visited(irg);
3961         env.worklist = new_pdeq();
3962         env.old_anchors = alloca(anchor_max * sizeof(env.old_anchors[0]));
3963         DEBUG_ONLY(env.mod = cg->mod);
3964
3965         old_end = get_irg_end(irg);
3966
3967         /* put all anchor nodes in the worklist */
3968         for(i = 0; i < anchor_max; ++i) {
3969                 ir_node *anchor = irg->anchors[i];
3970                 if(anchor == NULL)
3971                         continue;
3972                 pdeq_putr(env.worklist, anchor);
3973
3974                 // remember anchor
3975                 env.old_anchors[i] = anchor;
3976                 // and set it to NULL to make sure we don't accidently use it
3977                 irg->anchors[i] = NULL;
3978         }
3979
3980         // pre transform some anchors (so they are available in the other transform
3981         // functions)
3982         set_irg_bad(irg, transform_node(&env, env.old_anchors[anchor_bad]));
3983         set_irg_no_mem(irg, transform_node(&env, env.old_anchors[anchor_no_mem]));
3984         set_irg_start_block(irg, transform_node(&env, env.old_anchors[anchor_start_block]));
3985         set_irg_start(irg, transform_node(&env, env.old_anchors[anchor_start]));
3986         set_irg_frame(irg, transform_node(&env, env.old_anchors[anchor_frame]));
3987
3988         pre_transform_node(&cg->unknown_gp, &env);
3989         pre_transform_node(&cg->unknown_vfp, &env);
3990         pre_transform_node(&cg->unknown_xmm, &env);
3991         pre_transform_node(&cg->noreg_gp, &env);
3992         pre_transform_node(&cg->noreg_vfp, &env);
3993         pre_transform_node(&cg->noreg_xmm, &env);
3994
3995         /* process worklist (this should transform all nodes in the graph) */
3996         while(!pdeq_empty(env.worklist)) {
3997                 ir_node *node = pdeq_getl(env.worklist);
3998                 transform_node(&env, node);
3999         }
4000
4001         /* fix loops and set new anchors*/
4002         inc_irg_visited(irg);
4003         for(i = 0; i < anchor_max; ++i) {
4004                 ir_node *anchor = env.old_anchors[i];
4005                 if(anchor == NULL)
4006                         continue;
4007
4008                 anchor = get_irn_link(anchor);
4009                 fix_loops(&env, anchor);
4010                 assert(irg->anchors[i] == NULL || irg->anchors[i] == anchor);
4011                 irg->anchors[i] = anchor;
4012         }
4013
4014         del_pdeq(env.worklist);
4015         free_End(old_end);
4016         hook_dead_node_elim(irg, 0);
4017 }
4018
4019 void ia32_transform_graph(ia32_code_gen_t *cg)
4020 {
4021         ir_graph *irg = cg->irg;
4022         be_irg_t *birg = cg->birg;
4023         ir_graph *old_current_ir_graph = current_ir_graph;
4024         int old_interprocedural_view = get_interprocedural_view();
4025         struct obstack *old_obst = NULL;
4026         struct obstack *new_obst = NULL;
4027
4028         current_ir_graph = irg;
4029         set_interprocedural_view(0);
4030         register_transformers();
4031
4032         /* most analysis info is wrong after transformation */
4033         free_callee_info(irg);
4034         free_irg_outs(irg);
4035         irg->outs_state = outs_none;
4036         free_trouts();
4037         free_loop_information(irg);
4038         set_irg_doms_inconsistent(irg);
4039         be_invalidate_liveness(birg);
4040         be_invalidate_dom_front(birg);
4041
4042         /* create a new obstack */
4043         old_obst = irg->obst;
4044         new_obst = xmalloc(sizeof(*new_obst));
4045         obstack_init(new_obst);
4046         irg->obst = new_obst;
4047         irg->last_node_idx = 0;
4048
4049         /* create new value table for CSE */
4050         del_identities(irg->value_table);
4051         irg->value_table = new_identities();
4052
4053         /* do the main transformation */
4054         transform_nodes(cg);
4055
4056         /* we don't want the globals anchor anymore */
4057         set_irg_globals(irg, new_r_Bad(irg));
4058
4059         /* free the old obstack */
4060         obstack_free(old_obst, 0);
4061         xfree(old_obst);
4062
4063         /* restore state */
4064         current_ir_graph = old_current_ir_graph;
4065         set_interprocedural_view(old_interprocedural_view);
4066
4067         /* recalculate edges */
4068         edges_deactivate(irg);
4069         edges_activate(irg);
4070 }
4071
4072 /**
4073  * Transforms a psi condition.
4074  */
4075 static void transform_psi_cond(ir_node *cond, ir_mode *mode, ia32_code_gen_t *cg) {
4076         int i;
4077
4078         /* if the mode is target mode, we have already seen this part of the tree */
4079         if (get_irn_mode(cond) == mode)
4080                 return;
4081
4082         assert(get_irn_mode(cond) == mode_b && "logical operator for condition must be mode_b");
4083
4084         set_irn_mode(cond, mode);
4085
4086         for (i = get_irn_arity(cond) - 1; i >= 0; i--) {
4087                 ir_node *in = get_irn_n(cond, i);
4088
4089                 /* if in is a compare: transform into Set/xCmp */
4090                 if (is_Proj(in)) {
4091                         ir_node  *new_op = NULL;
4092                         ir_node  *cmp    = get_Proj_pred(in);
4093                         ir_node  *cmp_a  = get_Cmp_left(cmp);
4094                         ir_node  *cmp_b  = get_Cmp_right(cmp);
4095                         dbg_info *dbg    = get_irn_dbg_info(cmp);
4096                         ir_graph *irg    = get_irn_irg(cmp);
4097                         ir_node  *block  = get_nodes_block(cmp);
4098                         ir_node  *noreg  = ia32_new_NoReg_gp(cg);
4099                         ir_node  *nomem  = new_rd_NoMem(irg);
4100                         int      pnc     = get_Proj_proj(in);
4101
4102                         /* this is a compare */
4103                         if (mode_is_float(mode)) {
4104                                 /* Psi is float, we need a floating point compare */
4105
4106                                 if (USE_SSE2(cg)) {
4107                                         ir_mode *m = get_irn_mode(cmp_a);
4108                                         /* SSE FPU */
4109                                         if (! mode_is_float(m)) {
4110                                                 cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_a, cmp_a, mode);
4111                                                 cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_b, cmp_b, mode);
4112                                         }
4113                                         else if (m == mode_F) {
4114                                                 /* we convert cmp values always to double, to get correct bitmask with cmpsd */
4115                                                 cmp_a = gen_sse_conv_f2d(cg, dbg, irg, block, cmp_a, cmp_a);
4116                                                 cmp_b = gen_sse_conv_f2d(cg, dbg, irg, block, cmp_b, cmp_b);
4117                                         }
4118
4119                                         new_op = new_rd_ia32_xCmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
4120                                         set_ia32_pncode(new_op, pnc);
4121                                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, cmp));
4122                                 }
4123                                 else {
4124                                         /* x87 FPU */
4125                                         assert(0);
4126                                 }
4127                         }
4128                         else {
4129                                 /* integer Psi */
4130                                 construct_binop_func *set_func  = NULL;
4131
4132                                 if (mode_is_float(get_irn_mode(cmp_a))) {
4133                                         /* 1st case: compare operands are floats */
4134                                         FP_USED(cg);
4135
4136                                         if (USE_SSE2(cg)) {
4137                                                 /* SSE FPU */
4138                                                 set_func  = new_rd_ia32_xCmpSet;
4139                                         }
4140                                         else {
4141                                                 /* x87 FPU */
4142                                                 set_func  = new_rd_ia32_vfCmpSet;
4143                                         }
4144
4145                                         pnc &= 7; /* fp compare -> int compare */
4146                                 }
4147                                 else {
4148                                         /* 2nd case: compare operand are integer too */
4149                                         set_func  = new_rd_ia32_CmpSet;
4150                                 }
4151
4152                                 new_op = set_func(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
4153                                 if(!mode_is_signed(mode))
4154                                         pnc |= ia32_pn_Cmp_Unsigned;
4155
4156                                 set_ia32_pncode(new_op, pnc);
4157                                 set_ia32_am_support(new_op, ia32_am_Source);
4158                         }
4159
4160                         /* the the new compare as in */
4161                         set_irn_n(cond, i, new_op);
4162                 }
4163                 else {
4164                         /* another complex condition */
4165                         transform_psi_cond(in, mode, cg);
4166                 }
4167         }
4168 }
4169
4170 /**
4171  * The Psi selector can be a tree of compares combined with "And"s and "Or"s.
4172  * We create a Set node, respectively a xCmp in case the Psi is a float, for each
4173  * compare, which causes the compare result to be stores in a register.  The
4174  * "And"s and "Or"s are transformed later, we just have to set their mode right.
4175  */
4176 void ia32_transform_psi_cond_tree(ir_node *node, void *env) {
4177         ia32_code_gen_t *cg = env;
4178         ir_node         *psi_sel, *new_cmp, *block;
4179         ir_graph        *irg;
4180         ir_mode         *mode;
4181
4182         /* check for Psi */
4183         if (get_irn_opcode(node) != iro_Psi)
4184                 return;
4185
4186         psi_sel = get_Psi_cond(node, 0);
4187
4188         /* if psi_cond is a cmp: do nothing, this case is covered by gen_Psi */
4189         if (is_Proj(psi_sel))
4190                 return;
4191
4192         //mode = get_irn_mode(node);
4193         // TODO this is probably wrong...
4194         mode = mode_Iu;
4195
4196         transform_psi_cond(psi_sel, mode, cg);
4197
4198         irg   = get_irn_irg(node);
4199         block = get_nodes_block(node);
4200
4201         /* we need to compare the evaluated condition tree with 0 */
4202         mode  = get_irn_mode(node);
4203         if (mode_is_float(mode)) {
4204                 psi_sel = gen_sse_conv_int2float(cg, NULL, irg, block, psi_sel, NULL, mode);
4205                 /* BEWARE: new_r_Const_long works for floating point as well */
4206                 new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode, 0));
4207                 new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Ne);
4208         }
4209         else {
4210                 new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode_Iu, 0));
4211                 new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Gt | pn_Cmp_Lt);
4212         }
4213
4214         set_Psi_cond(node, 0, new_cmp);
4215 }