972b0c326f6d2566b5099591df374b160a1c1720
[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
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include <limits.h>
12
13 #include "irargs_t.h"
14 #include "irnode_t.h"
15 #include "irgraph_t.h"
16 #include "irmode_t.h"
17 #include "iropt_t.h"
18 #include "irop_t.h"
19 #include "irprog_t.h"
20 #include "iredges_t.h"
21 #include "irgmod.h"
22 #include "irvrfy.h"
23 #include "ircons.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
32 #include "../benode_t.h"
33 #include "../besched.h"
34 #include "../beabi.h"
35
36 #include "bearch_ia32_t.h"
37 #include "ia32_nodes_attr.h"
38 #include "ia32_transform.h"
39 #include "ia32_new_nodes.h"
40 #include "ia32_map_regs.h"
41 #include "ia32_dbg_stat.h"
42 #include "ia32_optimize.h"
43 #include "ia32_util.h"
44
45 #include "gen_ia32_regalloc_if.h"
46
47 #define SFP_SIGN "0x80000000"
48 #define DFP_SIGN "0x8000000000000000"
49 #define SFP_ABS  "0x7FFFFFFF"
50 #define DFP_ABS  "0x7FFFFFFFFFFFFFFF"
51
52 #define TP_SFP_SIGN "ia32_sfp_sign"
53 #define TP_DFP_SIGN "ia32_dfp_sign"
54 #define TP_SFP_ABS  "ia32_sfp_abs"
55 #define TP_DFP_ABS  "ia32_dfp_abs"
56
57 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
58 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
59 #define ENT_SFP_ABS  "IA32_SFP_ABS"
60 #define ENT_DFP_ABS  "IA32_DFP_ABS"
61
62 extern ir_op *get_op_Mulh(void);
63
64 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
65                                                                           ir_node *op1, ir_node *op2, ir_node *mem);
66
67 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
68                                                                          ir_node *op, ir_node *mem);
69
70 typedef enum {
71         ia32_SSIGN, ia32_DSIGN, ia32_SABS, ia32_DABS, ia32_known_const_max
72 } ia32_known_const_t;
73
74 /****************************************************************************************************
75  *                  _        _                        __                           _   _
76  *                 | |      | |                      / _|                         | | (_)
77  *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
78  * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
79  * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
80  * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
81  *
82  ****************************************************************************************************/
83
84 /**
85  * Returns 1 if irn is a Const representing 0, 0 otherwise
86  */
87 static INLINE int is_ia32_Const_0(ir_node *irn) {
88         return (is_ia32_irn(irn) && get_ia32_op_type(irn) == ia32_Const) ?
89                 classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_NULL : 0;
90 }
91
92 /**
93  * Returns 1 if irn is a Const representing 1, 0 otherwise
94  */
95 static INLINE int is_ia32_Const_1(ir_node *irn) {
96         return (is_ia32_irn(irn) && get_ia32_op_type(irn) == ia32_Const) ?
97                 classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_ONE : 0;
98 }
99
100 /**
101  * Returns the Proj representing the UNKNOWN register for given mode.
102  */
103 static ir_node *be_get_unknown_for_mode(ia32_code_gen_t *cg, ir_mode *mode) {
104         be_abi_irg_t          *babi       = cg->birg->abi;
105         const arch_register_t *unknwn_reg = NULL;
106
107         if (mode_is_float(mode)) {
108                 unknwn_reg = USE_SSE2(cg) ? &ia32_xmm_regs[REG_XMM_UKNWN] : &ia32_vfp_regs[REG_VFP_UKNWN];
109         }
110         else {
111                 unknwn_reg = &ia32_gp_regs[REG_GP_UKNWN];
112         }
113
114         return be_abi_get_callee_save_irn(babi, unknwn_reg);
115 }
116
117 /**
118  * Gets the Proj with number pn from irn.
119  */
120 static ir_node *get_proj_for_pn(const ir_node *irn, long pn) {
121         const ir_edge_t *edge;
122         ir_node   *proj;
123         assert(get_irn_mode(irn) == mode_T && "need mode_T");
124
125         foreach_out_edge(irn, edge) {
126                 proj = get_edge_src_irn(edge);
127
128                 if (get_Proj_proj(proj) == pn)
129                         return proj;
130         }
131
132         return NULL;
133 }
134
135 /**
136  * Collects all Projs of a node into the node array. Index is the projnum.
137  * BEWARE: The caller has to assure the appropriate array size!
138  */
139 static void ia32_collect_Projs(ir_node *irn, ir_node **projs, int size) {
140         const ir_edge_t *edge;
141         ir_node         *proj;
142         assert(get_irn_mode(irn) == mode_T && "need mode_T");
143
144         memset(projs, 0, size * sizeof(projs[0]));
145
146         foreach_out_edge(irn, edge) {
147                 proj                       = get_edge_src_irn(edge);
148                 projs[get_Proj_proj(proj)] = proj;
149         }
150 }
151
152 /**
153  * Renumbers the proj having pn_old in the array tp pn_new
154  * and removes the proj from the array.
155  */
156 static INLINE void ia32_renumber_Proj(ir_node **projs, long pn_old, long pn_new) {
157         if (projs[pn_old]) {
158                 set_Proj_proj(projs[pn_old], pn_new);
159                 projs[pn_old] = NULL;
160         }
161 }
162
163 /**
164  * SSE convert of an integer node into a floating point node.
165  */
166 static ir_node *gen_sse_conv_int2float(ia32_code_gen_t *cg, dbg_info *dbg, ir_graph *irg, ir_node *block,
167                                        ir_node *in, ir_node *old_node, ir_mode *tgt_mode)
168 {
169         ir_node *noreg = ia32_new_NoReg_gp(cg);
170         ir_node *nomem = new_rd_NoMem(irg);
171
172         ir_node *conv = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, in, nomem);
173         set_ia32_src_mode(conv, get_irn_mode(in));
174         set_ia32_tgt_mode(conv, tgt_mode);
175         set_ia32_am_support(conv, ia32_am_Source);
176         SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node));
177
178         return new_rd_Proj(dbg, irg, block, conv, tgt_mode, pn_ia32_Conv_I2FP_res);
179 }
180
181 /**
182 * SSE convert of an float node into a double node.
183 */
184 static ir_node *gen_sse_conv_f2d(ia32_code_gen_t *cg, dbg_info *dbg, ir_graph *irg, ir_node *block,
185                                                                            ir_node *in, ir_node *old_node)
186 {
187         ir_node *noreg = ia32_new_NoReg_gp(cg);
188         ir_node *nomem = new_rd_NoMem(irg);
189
190         ir_node *conv = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, in, nomem);
191         set_ia32_src_mode(conv, mode_F);
192         set_ia32_tgt_mode(conv, mode_D);
193         set_ia32_am_support(conv, ia32_am_Source);
194         SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node));
195
196         return new_rd_Proj(dbg, irg, block, conv, mode_D, pn_ia32_Conv_FP2FP_res);
197 }
198
199 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
200 static ident *gen_fp_known_const(ia32_known_const_t kct) {
201         static const struct {
202                 const char *tp_name;
203                 const char *ent_name;
204                 const char *cnst_str;
205         } names [ia32_known_const_max] = {
206                 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN },        /* ia32_SSIGN */
207                 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN },        /* ia32_DSIGN */
208                 { TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS },         /* ia32_SABS */
209                 { TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS }          /* ia32_DABS */
210         };
211         static entity *ent_cache[ia32_known_const_max];
212
213         const char    *tp_name, *ent_name, *cnst_str;
214         ir_type       *tp;
215         ir_node       *cnst;
216         ir_graph      *rem;
217         entity        *ent;
218         tarval        *tv;
219         ir_mode       *mode;
220
221         ent_name = names[kct].ent_name;
222         if (! ent_cache[kct]) {
223                 tp_name  = names[kct].tp_name;
224                 cnst_str = names[kct].cnst_str;
225
226                 mode = kct == ia32_SSIGN || kct == ia32_SABS ? mode_Iu : mode_Lu;
227                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
228                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
229                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
230
231                 set_entity_ld_ident(ent, get_entity_ident(ent));
232                 set_entity_visibility(ent, visibility_local);
233                 set_entity_variability(ent, variability_constant);
234                 set_entity_allocation(ent, allocation_static);
235
236                 /* we create a new entity here: It's initialization must resist on the
237                     const code irg */
238                 rem = current_ir_graph;
239                 current_ir_graph = get_const_code_irg();
240                 cnst = new_Const(mode, tv);
241                 current_ir_graph = rem;
242
243                 set_atomic_ent_value(ent, cnst);
244
245                 /* cache the entry */
246                 ent_cache[kct] = ent;
247         }
248
249         return get_entity_ident(ent_cache[kct]);
250 }
251
252 #ifndef NDEBUG
253 /**
254  * Prints the old node name on cg obst and returns a pointer to it.
255  */
256 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
257         ia32_isa_t *isa = (ia32_isa_t *)cg->arch_env->isa;
258
259         lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
260         obstack_1grow(isa->name_obst, 0);
261         isa->name_obst_size += obstack_object_size(isa->name_obst);
262         return obstack_finish(isa->name_obst);
263 }
264 #endif /* NDEBUG */
265
266 /* determine if one operator is an Imm */
267 static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
268         if (op1)
269                 return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
270         else return is_ia32_Cnst(op2) ? op2 : NULL;
271 }
272
273 /* determine if one operator is not an Imm */
274 static ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
275         return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
276 }
277
278
279 /**
280  * Construct a standard binary operation, set AM and immediate if required.
281  *
282  * @param env   The transformation environment
283  * @param op1   The first operand
284  * @param op2   The second operand
285  * @param func  The node constructor function
286  * @return The constructed ia32 node.
287  */
288 static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, construct_binop_func *func) {
289         ir_node  *new_op   = NULL;
290         ir_mode  *mode     = env->mode;
291         dbg_info *dbg      = env->dbg;
292         ir_graph *irg      = env->irg;
293         ir_node  *block    = env->block;
294         ir_node  *noreg_gp = ia32_new_NoReg_gp(env->cg);
295         ir_node  *noreg_fp = ia32_new_NoReg_fp(env->cg);
296         ir_node  *nomem    = new_NoMem();
297         int      is_mul    = 0;
298         ir_node  *expr_op, *imm_op;
299         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
300
301         /* Check if immediate optimization is on and */
302         /* if it's an operation with immediate.      */
303         /* Mul/MulS/Mulh don't support immediates    */
304         if (! (env->cg->opt & IA32_OPT_IMMOPS) ||
305                 func == new_rd_ia32_Mul            ||
306                 func == new_rd_ia32_Mulh           ||
307                 func == new_rd_ia32_MulS)
308         {
309                 expr_op = op1;
310                 imm_op  = NULL;
311                 /* immediate operations are requested, but we are here: it a mul */
312                 if (env->cg->opt & IA32_OPT_IMMOPS)
313                         is_mul = 1;
314         }
315         else if (is_op_commutative(get_irn_op(env->irn))) {
316                 imm_op  = get_immediate_op(op1, op2);
317                 expr_op = get_expr_op(op1, op2);
318         }
319         else {
320                 imm_op  = get_immediate_op(NULL, op2);
321                 expr_op = get_expr_op(op1, op2);
322         }
323
324         assert((expr_op || imm_op) && "invalid operands");
325
326         if (!expr_op) {
327                 /* We have two consts here: not yet supported */
328                 imm_op = NULL;
329         }
330
331         if (mode_is_float(mode)) {
332                 /* floating point operations */
333                 if (imm_op) {
334                         DB((mod, LEVEL_1, "FP with immediate ..."));
335                         new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem);
336                         set_ia32_Immop_attr(new_op, imm_op);
337                         set_ia32_am_support(new_op, ia32_am_None);
338                 }
339                 else {
340                         DB((mod, LEVEL_1, "FP binop ..."));
341                         new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
342                         set_ia32_am_support(new_op, ia32_am_Source);
343                 }
344                 set_ia32_ls_mode(new_op, mode);
345         }
346         else {
347                 /* integer operations */
348                 if (imm_op) {
349                         /* This is expr + const */
350                         DB((mod, LEVEL_1, "INT with immediate ..."));
351                         new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem);
352                         set_ia32_Immop_attr(new_op, imm_op);
353
354                         /* set AM support */
355                         set_ia32_am_support(new_op, ia32_am_Dest);
356                 }
357                 else {
358                         DB((mod, LEVEL_1, "INT binop ..."));
359                         /* This is a normal operation */
360                         new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
361
362                         /* set AM support */
363                         set_ia32_am_support(new_op, ia32_am_Full);
364                 }
365
366                 /* Muls can only have AM source */
367                 if (is_mul)
368                         set_ia32_am_support(new_op, ia32_am_Source);
369         }
370
371         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
372
373         set_ia32_res_mode(new_op, mode);
374
375         if (is_op_commutative(get_irn_op(env->irn))) {
376                 set_ia32_commutative(new_op);
377         }
378
379         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
380 }
381
382
383
384 /**
385  * Construct a shift/rotate binary operation, sets AM and immediate if required.
386  *
387  * @param env   The transformation environment
388  * @param op1   The first operand
389  * @param op2   The second operand
390  * @param func  The node constructor function
391  * @return The constructed ia32 node.
392  */
393 static ir_node *gen_shift_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, construct_binop_func *func) {
394         ir_node           *new_op = NULL;
395         ir_mode           *mode   = env->mode;
396         dbg_info          *dbg    = env->dbg;
397         ir_graph          *irg    = env->irg;
398         ir_node           *block  = env->block;
399         ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
400         ir_node           *nomem  = new_NoMem();
401         ir_node           *expr_op, *imm_op;
402         tarval            *tv;
403         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
404
405         assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");
406
407         /* Check if immediate optimization is on and */
408         /* if it's an operation with immediate.      */
409         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
410         expr_op = get_expr_op(op1, op2);
411
412         assert((expr_op || imm_op) && "invalid operands");
413
414         if (!expr_op) {
415                 /* We have two consts here: not yet supported */
416                 imm_op = NULL;
417         }
418
419         /* Limit imm_op within range imm8 */
420         if (imm_op) {
421                 tv = get_ia32_Immop_tarval(imm_op);
422
423                 if (tv) {
424                         tv = tarval_mod(tv, new_tarval_from_long(32, mode_Iu));
425                         set_ia32_Immop_tarval(imm_op, tv);
426                 }
427                 else {
428                         imm_op = NULL;
429                 }
430         }
431
432         /* integer operations */
433         if (imm_op) {
434                 /* This is shift/rot with const */
435                 DB((mod, LEVEL_1, "Shift/Rot with immediate ..."));
436
437                 new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
438                 set_ia32_Immop_attr(new_op, imm_op);
439         }
440         else {
441                 /* This is a normal shift/rot */
442                 DB((mod, LEVEL_1, "Shift/Rot binop ..."));
443                 new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem);
444         }
445
446         /* set AM support */
447         set_ia32_am_support(new_op, ia32_am_Dest);
448
449         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
450
451         set_ia32_res_mode(new_op, mode);
452         set_ia32_emit_cl(new_op);
453
454         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
455 }
456
457
458 /**
459  * Construct a standard unary operation, set AM and immediate if required.
460  *
461  * @param env   The transformation environment
462  * @param op    The operand
463  * @param func  The node constructor function
464  * @return The constructed ia32 node.
465  */
466 static ir_node *gen_unop(ia32_transform_env_t *env, ir_node *op, construct_unop_func *func) {
467         ir_node           *new_op = NULL;
468         ir_mode           *mode   = env->mode;
469         dbg_info          *dbg    = env->dbg;
470         ir_graph          *irg    = env->irg;
471         ir_node           *block  = env->block;
472         ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
473         ir_node           *nomem  = new_NoMem();
474         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
475
476         new_op = func(dbg, irg, block, noreg, noreg, op, nomem);
477
478         if (mode_is_float(mode)) {
479                 DB((mod, LEVEL_1, "FP unop ..."));
480                 /* floating point operations don't support implicit store */
481                 set_ia32_am_support(new_op, ia32_am_None);
482         }
483         else {
484                 DB((mod, LEVEL_1, "INT unop ..."));
485                 set_ia32_am_support(new_op, ia32_am_Dest);
486         }
487
488         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
489
490         set_ia32_res_mode(new_op, mode);
491
492         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
493 }
494
495
496
497 /**
498  * Creates an ia32 Add with immediate.
499  *
500  * @param env       The transformation environment
501  * @param expr_op   The expression operator
502  * @param const_op  The constant
503  * @return the created ia32 Add node
504  */
505 static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
506         ir_node                *new_op     = NULL;
507         tarval                 *tv         = get_ia32_Immop_tarval(const_op);
508         dbg_info               *dbg        = env->dbg;
509         ir_graph               *irg        = env->irg;
510         ir_node                *block      = env->block;
511         ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
512         ir_node                *nomem      = new_NoMem();
513         int                     normal_add = 1;
514         tarval_classification_t class_tv, class_negtv;
515         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
516
517         /* try to optimize to inc/dec  */
518         if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) {
519                 /* optimize tarvals */
520                 class_tv    = classify_tarval(tv);
521                 class_negtv = classify_tarval(tarval_neg(tv));
522
523                 if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
524                         DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
525                         new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
526                         normal_add = 0;
527                 }
528                 else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
529                         DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
530                         new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
531                         normal_add = 0;
532                 }
533         }
534
535         if (normal_add) {
536                 new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
537                 set_ia32_Immop_attr(new_op, const_op);
538                 set_ia32_commutative(new_op);
539         }
540
541         return new_op;
542 }
543
544 /**
545  * Creates an ia32 Add.
546  *
547  * @param env   The transformation environment
548  * @return the created ia32 Add node
549  */
550 static ir_node *gen_Add(ia32_transform_env_t *env) {
551         ir_node  *new_op = NULL;
552         dbg_info *dbg    = env->dbg;
553         ir_mode  *mode   = env->mode;
554         ir_graph *irg    = env->irg;
555         ir_node  *block  = env->block;
556         ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
557         ir_node  *nomem  = new_NoMem();
558         ir_node  *expr_op, *imm_op;
559         ir_node  *op1    = get_Add_left(env->irn);
560         ir_node  *op2    = get_Add_right(env->irn);
561
562         /* Check if immediate optimization is on and */
563         /* if it's an operation with immediate.      */
564         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(op1, op2) : NULL;
565         expr_op = get_expr_op(op1, op2);
566
567         assert((expr_op || imm_op) && "invalid operands");
568
569         if (mode_is_float(mode)) {
570                 FP_USED(env->cg);
571                 if (USE_SSE2(env->cg))
572                         return gen_binop(env, op1, op2, new_rd_ia32_xAdd);
573                 else
574                         return gen_binop(env, op1, op2, new_rd_ia32_vfadd);
575         }
576         else {
577                 /* integer ADD */
578                 if (!expr_op) {
579                         /* No expr_op means, that we have two const - one symconst and */
580                         /* one tarval or another symconst - because this case is not   */
581                         /* covered by constant folding                                 */
582                         /* We need to check for:                                       */
583                         /*  1) symconst + const    -> becomes a LEA                    */
584                         /*  2) symconst + symconst -> becomes a const + LEA as the elf */
585                         /*        linker doesn't support two symconsts                 */
586
587                         if (get_ia32_op_type(op1) == ia32_SymConst && get_ia32_op_type(op2) == ia32_SymConst) {
588                                 /* this is the 2nd case */
589                                 new_op = new_rd_ia32_Lea(dbg, irg, block, op1, noreg, mode);
590                                 set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
591                                 set_ia32_am_flavour(new_op, ia32_am_OB);
592
593                                 DBG_OPT_LEA3(op1, op2, env->irn, new_op);
594                         }
595                         else {
596                                 /* this is the 1st case */
597                                 new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);
598
599                                 DBG_OPT_LEA3(op1, op2, env->irn, new_op);
600
601                                 if (get_ia32_op_type(op1) == ia32_SymConst) {
602                                         set_ia32_am_sc(new_op, get_ia32_id_cnst(op1));
603                                         add_ia32_am_offs(new_op, get_ia32_cnst(op2));
604                                 }
605                                 else {
606                                         add_ia32_am_offs(new_op, get_ia32_cnst(op1));
607                                         set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
608                                 }
609                                 set_ia32_am_flavour(new_op, ia32_am_O);
610                         }
611
612                         /* set AM support */
613                         set_ia32_am_support(new_op, ia32_am_Source);
614                         set_ia32_op_type(new_op, ia32_AddrModeS);
615
616                         /* Lea doesn't need a Proj */
617                         return new_op;
618                 }
619                 else if (imm_op) {
620                         /* This is expr + const */
621                         new_op = gen_imm_Add(env, expr_op, imm_op);
622
623                         /* set AM support */
624                         set_ia32_am_support(new_op, ia32_am_Dest);
625                 }
626                 else {
627                         /* This is a normal add */
628                         new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem);
629
630                         /* set AM support */
631                         set_ia32_am_support(new_op, ia32_am_Full);
632                         set_ia32_commutative(new_op);
633                 }
634         }
635
636         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
637
638         set_ia32_res_mode(new_op, mode);
639
640         return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Add_res);
641 }
642
643
644
645 /**
646  * Creates an ia32 Mul.
647  *
648  * @param env   The transformation environment
649  * @return the created ia32 Mul node
650  */
651 static ir_node *gen_Mul(ia32_transform_env_t *env) {
652         ir_node *op1 = get_Mul_left(env->irn);
653         ir_node *op2 = get_Mul_right(env->irn);
654         ir_node *new_op;
655
656         if (mode_is_float(env->mode)) {
657                 FP_USED(env->cg);
658                 if (USE_SSE2(env->cg))
659                         new_op = gen_binop(env, op1, op2, new_rd_ia32_xMul);
660                 else
661                         new_op = gen_binop(env, op1, op2, new_rd_ia32_vfmul);
662         }
663         else {
664                 new_op = gen_binop(env, op1, op2, new_rd_ia32_Mul);
665         }
666
667         return new_op;
668 }
669
670
671
672 /**
673  * Creates an ia32 Mulh.
674  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
675  * this result while Mul returns the lower 32 bit.
676  *
677  * @param env   The transformation environment
678  * @return the created ia32 Mulh node
679  */
680 static ir_node *gen_Mulh(ia32_transform_env_t *env) {
681         ir_node *op1 = get_irn_n(env->irn, 0);
682         ir_node *op2 = get_irn_n(env->irn, 1);
683         ir_node *proj_EAX, *proj_EDX, *mulh;
684         ir_node *in[1];
685
686         assert(!mode_is_float(env->mode) && "Mulh with float not supported");
687         proj_EAX = gen_binop(env, op1, op2, new_rd_ia32_Mulh);
688         mulh     = get_Proj_pred(proj_EAX);
689         proj_EDX = new_rd_Proj(env->dbg, env->irg, env->block, mulh, env->mode, pn_EDX);
690
691         /* to be on the save side */
692         set_Proj_proj(proj_EAX, pn_EAX);
693
694         if (is_ia32_ImmConst(mulh) || is_ia32_ImmSymConst(mulh)) {
695                 /* Mulh with const cannot have AM */
696                 set_ia32_am_support(mulh, ia32_am_None);
697         }
698         else {
699                 /* Mulh cannot have AM for destination */
700                 set_ia32_am_support(mulh, ia32_am_Source);
701         }
702
703         in[0] = proj_EAX;
704
705         /* keep EAX */
706         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], env->irg, env->block, 1, in);
707
708         return proj_EDX;
709 }
710
711
712
713 /**
714  * Creates an ia32 And.
715  *
716  * @param env   The transformation environment
717  * @return The created ia32 And node
718  */
719 static ir_node *gen_And(ia32_transform_env_t *env) {
720         ir_node *op1 = get_And_left(env->irn);
721         ir_node *op2 = get_And_right(env->irn);
722
723         assert (! mode_is_float(env->mode));
724         return gen_binop(env, op1, op2, new_rd_ia32_And);
725 }
726
727
728
729 /**
730  * Creates an ia32 Or.
731  *
732  * @param env   The transformation environment
733  * @return The created ia32 Or node
734  */
735 static ir_node *gen_Or(ia32_transform_env_t *env) {
736         ir_node *op1 = get_Or_left(env->irn);
737         ir_node *op2 = get_Or_right(env->irn);
738
739         assert (! mode_is_float(env->mode));
740         return gen_binop(env, op1, op2, new_rd_ia32_Or);
741 }
742
743
744
745 /**
746  * Creates an ia32 Eor.
747  *
748  * @param env   The transformation environment
749  * @return The created ia32 Eor node
750  */
751 static ir_node *gen_Eor(ia32_transform_env_t *env) {
752         ir_node *op1 = get_Eor_left(env->irn);
753         ir_node *op2 = get_Eor_right(env->irn);
754
755         assert(! mode_is_float(env->mode));
756         return gen_binop(env, op1, op2, new_rd_ia32_Eor);
757 }
758
759
760
761 /**
762  * Creates an ia32 Max.
763  *
764  * @param env      The transformation environment
765  * @return the created ia32 Max node
766  */
767 static ir_node *gen_Max(ia32_transform_env_t *env) {
768         ir_node *op1 = get_irn_n(env->irn, 0);
769         ir_node *op2 = get_irn_n(env->irn, 1);
770         ir_node *new_op;
771
772         if (mode_is_float(env->mode)) {
773                 FP_USED(env->cg);
774                 if (USE_SSE2(env->cg))
775                         new_op = gen_binop(env, op1, op2, new_rd_ia32_xMax);
776                 else {
777                         assert(0);
778                 }
779         }
780         else {
781                 new_op = new_rd_ia32_Max(env->dbg, env->irg, env->block, op1, op2, env->mode);
782                 set_ia32_am_support(new_op, ia32_am_None);
783                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
784         }
785
786         return new_op;
787 }
788
789
790
791 /**
792  * Creates an ia32 Min.
793  *
794  * @param env      The transformation environment
795  * @return the created ia32 Min node
796  */
797 static ir_node *gen_Min(ia32_transform_env_t *env) {
798         ir_node *op1 = get_irn_n(env->irn, 0);
799         ir_node *op2 = get_irn_n(env->irn, 1);
800         ir_node *new_op;
801
802         if (mode_is_float(env->mode)) {
803                 FP_USED(env->cg);
804                 if (USE_SSE2(env->cg))
805                         new_op = gen_binop(env, op1, op2, new_rd_ia32_xMin);
806                 else {
807                         assert(0);
808                 }
809         }
810         else {
811                 new_op = new_rd_ia32_Min(env->dbg, env->irg, env->block, op1, op2, env->mode);
812                 set_ia32_am_support(new_op, ia32_am_None);
813                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
814         }
815
816         return new_op;
817 }
818
819
820
821 /**
822  * Creates an ia32 Sub with immediate.
823  *
824  * @param env        The transformation environment
825  * @param expr_op    The first operator
826  * @param const_op   The constant operator
827  * @return The created ia32 Sub node
828  */
829 static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
830         ir_node                *new_op     = NULL;
831         tarval                 *tv         = get_ia32_Immop_tarval(const_op);
832         dbg_info               *dbg        = env->dbg;
833         ir_graph               *irg        = env->irg;
834         ir_node                *block      = env->block;
835         ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
836         ir_node                *nomem      = new_NoMem();
837         int                     normal_sub = 1;
838         tarval_classification_t class_tv, class_negtv;
839         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
840
841         /* try to optimize to inc/dec  */
842         if ((env->cg->opt & IA32_OPT_INCDEC) && tv) {
843                 /* optimize tarvals */
844                 class_tv    = classify_tarval(tv);
845                 class_negtv = classify_tarval(tarval_neg(tv));
846
847                 if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
848                         DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
849                         new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
850                         normal_sub = 0;
851                 }
852                 else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
853                         DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
854                         new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
855                         normal_sub = 0;
856                 }
857         }
858
859         if (normal_sub) {
860                 new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
861                 set_ia32_Immop_attr(new_op, const_op);
862         }
863
864         return new_op;
865 }
866
867 /**
868  * Creates an ia32 Sub.
869  *
870  * @param env   The transformation environment
871  * @return The created ia32 Sub node
872  */
873 static ir_node *gen_Sub(ia32_transform_env_t *env) {
874         ir_node  *new_op = NULL;
875         dbg_info *dbg    = env->dbg;
876         ir_mode  *mode   = env->mode;
877         ir_graph *irg    = env->irg;
878         ir_node  *block  = env->block;
879         ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
880         ir_node  *nomem  = new_NoMem();
881         ir_node  *op1    = get_Sub_left(env->irn);
882         ir_node  *op2    = get_Sub_right(env->irn);
883         ir_node  *expr_op, *imm_op;
884
885         /* Check if immediate optimization is on and */
886         /* if it's an operation with immediate.      */
887         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
888         expr_op = get_expr_op(op1, op2);
889
890         assert((expr_op || imm_op) && "invalid operands");
891
892         if (mode_is_float(mode)) {
893                 FP_USED(env->cg);
894                 if (USE_SSE2(env->cg))
895                         return gen_binop(env, op1, op2, new_rd_ia32_xSub);
896                 else
897                         return gen_binop(env, op1, op2, new_rd_ia32_vfsub);
898         }
899         else {
900                 /* integer SUB */
901                 if (! expr_op) {
902                         /* No expr_op means, that we have two const - one symconst and */
903                         /* one tarval or another symconst - because this case is not   */
904                         /* covered by constant folding                                 */
905                         /* We need to check for:                                       */
906                         /*  1) symconst - const    -> becomes a LEA                    */
907                         /*  2) symconst - symconst -> becomes a const - LEA as the elf */
908                         /*        linker doesn't support two symconsts                 */
909
910                         if (get_ia32_op_type(op1) == ia32_SymConst && get_ia32_op_type(op2) == ia32_SymConst) {
911                                 /* this is the 2nd case */
912                                 new_op = new_rd_ia32_Lea(dbg, irg, block, op1, noreg, mode);
913                                 set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
914                                 set_ia32_am_sc_sign(new_op);
915                                 set_ia32_am_flavour(new_op, ia32_am_OB);
916
917                                 DBG_OPT_LEA3(op1, op2, env->irn, new_op);
918                         }
919                         else {
920                                 /* this is the 1st case */
921                                 new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);
922
923                                 DBG_OPT_LEA3(op1, op2, env->irn, new_op);
924
925                                 if (get_ia32_op_type(op1) == ia32_SymConst) {
926                                         set_ia32_am_sc(new_op, get_ia32_id_cnst(op1));
927                                         sub_ia32_am_offs(new_op, get_ia32_cnst(op2));
928                                 }
929                                 else {
930                                         add_ia32_am_offs(new_op, get_ia32_cnst(op1));
931                                         set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
932                                         set_ia32_am_sc_sign(new_op);
933                                 }
934                                 set_ia32_am_flavour(new_op, ia32_am_O);
935                         }
936
937                         /* set AM support */
938                         set_ia32_am_support(new_op, ia32_am_Source);
939                         set_ia32_op_type(new_op, ia32_AddrModeS);
940
941                         /* Lea doesn't need a Proj */
942                         return new_op;
943                 }
944                 else if (imm_op) {
945                         /* This is expr - const */
946                         new_op = gen_imm_Sub(env, expr_op, imm_op);
947
948                         /* set AM support */
949                         set_ia32_am_support(new_op, ia32_am_Dest);
950                 }
951                 else {
952                         /* This is a normal sub */
953                         new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem);
954
955                         /* set AM support */
956                         set_ia32_am_support(new_op, ia32_am_Full);
957                 }
958         }
959
960         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
961
962         set_ia32_res_mode(new_op, mode);
963
964         return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Sub_res);
965 }
966
967
968
969 /**
970  * Generates an ia32 DivMod with additional infrastructure for the
971  * register allocator if needed.
972  *
973  * @param env      The transformation environment
974  * @param dividend -no comment- :)
975  * @param divisor  -no comment- :)
976  * @param dm_flav  flavour_Div/Mod/DivMod
977  * @return The created ia32 DivMod node
978  */
979 static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir_node *divisor, ia32_op_flavour_t dm_flav) {
980         ir_node  *res, *proj_div, *proj_mod;
981         ir_node  *edx_node, *cltd;
982         ir_node  *in_keep[1];
983         dbg_info *dbg   = env->dbg;
984         ir_graph *irg   = env->irg;
985         ir_node  *block = env->block;
986         ir_mode  *mode  = env->mode;
987         ir_node  *irn   = env->irn;
988         ir_node  *mem;
989         ir_node  *projs[pn_DivMod_max];
990
991         ia32_collect_Projs(irn, projs, pn_DivMod_max);
992
993         switch (dm_flav) {
994                 case flavour_Div:
995                         mem  = get_Div_mem(irn);
996                         mode = get_irn_mode(get_proj_for_pn(irn, pn_Div_res));
997                         break;
998                 case flavour_Mod:
999                         mem  = get_Mod_mem(irn);
1000                         mode = get_irn_mode(get_proj_for_pn(irn, pn_Mod_res));
1001                         break;
1002                 case flavour_DivMod:
1003                         mem      = get_DivMod_mem(irn);
1004                         proj_div = get_proj_for_pn(irn, pn_DivMod_res_div);
1005                         proj_mod = get_proj_for_pn(irn, pn_DivMod_res_mod);
1006                         mode     = proj_div ? get_irn_mode(proj_div) : get_irn_mode(proj_mod);
1007                         break;
1008                 default:
1009                         assert(0);
1010         }
1011
1012         if (mode_is_signed(mode)) {
1013                 /* in signed mode, we need to sign extend the dividend */
1014                 cltd     = new_rd_ia32_Cdq(dbg, irg, block, dividend);
1015                 dividend = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_ia32_Cdq_EAX);
1016                 edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_ia32_Cdq_EDX);
1017         }
1018         else {
1019                 edx_node = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Iu);
1020                 set_ia32_Const_type(edx_node, ia32_Const);
1021                 set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
1022         }
1023
1024         res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, dm_flav);
1025         set_ia32_n_res(res, 2);
1026
1027         /* Only one proj is used -> We must add a second proj and */
1028         /* connect this one to a Keep node to eat up the second   */
1029         /* destroyed register.                                    */
1030         /* We also renumber the Firm projs into ia32 projs.       */
1031
1032         switch (get_irn_opcode(irn)) {
1033                 case iro_Div:
1034                         ia32_renumber_Proj(projs, pn_Div_M, pn_ia32_DivMod_M);
1035                         ia32_renumber_Proj(projs, pn_Div_res, pn_ia32_DivMod_div_res);
1036                         /* add Proj-Keep for mod res */
1037                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_DivMod_mod_res);
1038                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1039                         break;
1040                 case iro_Mod:
1041                         ia32_renumber_Proj(projs, pn_Mod_M, pn_ia32_DivMod_M);
1042                         ia32_renumber_Proj(projs, pn_Mod_res, pn_ia32_DivMod_mod_res);
1043                         /* add Proj-Keep for div res */
1044                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_DivMod_div_res);
1045                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1046                         break;
1047                 case iro_DivMod:
1048                         /* check, which Proj-Keep, we need to add */
1049                         proj_div = get_proj_for_pn(irn, pn_DivMod_res_div);
1050                         proj_mod = get_proj_for_pn(irn, pn_DivMod_res_mod);
1051
1052                         /* BEWARE: renumber after getting original projs */
1053                         ia32_renumber_Proj(projs, pn_DivMod_M, pn_ia32_DivMod_M);
1054
1055                         if (proj_div && proj_mod) {
1056                                 /* we have both results used: simply renumber */
1057                                 ia32_renumber_Proj(projs, pn_DivMod_res_div, pn_ia32_DivMod_div_res);
1058                                 ia32_renumber_Proj(projs, pn_DivMod_res_mod, pn_ia32_DivMod_mod_res);
1059                         }
1060                         else if (! proj_div && ! proj_mod) {
1061                                 assert(0 && "Missing DivMod result proj");
1062                         }
1063                         else if (! proj_div) {
1064                                 /* We have only mod result: add div res Proj-Keep */
1065                                 ia32_renumber_Proj(projs, pn_DivMod_res_mod, pn_ia32_DivMod_mod_res);
1066                                 in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_DivMod_div_res);
1067                                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1068                         }
1069                         else {
1070                                 /* We have only div result: add mod res Proj-Keep */
1071                                 ia32_renumber_Proj(projs, pn_DivMod_res_div, pn_ia32_DivMod_div_res);
1072                                 in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_DivMod_mod_res);
1073                                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1074                         }
1075                         break;
1076                 default:
1077                         assert(0 && "Div, Mod, or DivMod expected.");
1078                         break;
1079         }
1080
1081         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1082         set_ia32_res_mode(res, mode);
1083
1084         return res;
1085 }
1086
1087
1088 /**
1089  * Wrapper for generate_DivMod. Sets flavour_Mod.
1090  *
1091  * @param env      The transformation environment
1092  */
1093 static ir_node *gen_Mod(ia32_transform_env_t *env) {
1094         return generate_DivMod(env, get_Mod_left(env->irn), get_Mod_right(env->irn), flavour_Mod);
1095 }
1096
1097 /**
1098  * Wrapper for generate_DivMod. Sets flavour_Div.
1099  *
1100  * @param env      The transformation environment
1101  */
1102 static ir_node *gen_Div(ia32_transform_env_t *env) {
1103         return generate_DivMod(env, get_Div_left(env->irn), get_Div_right(env->irn), flavour_Div);
1104 }
1105
1106 /**
1107  * Wrapper for generate_DivMod. Sets flavour_DivMod.
1108  */
1109 static ir_node *gen_DivMod(ia32_transform_env_t *env) {
1110         return generate_DivMod(env, get_DivMod_left(env->irn), get_DivMod_right(env->irn), flavour_DivMod);
1111 }
1112
1113
1114
1115 /**
1116  * Creates an ia32 floating Div.
1117  *
1118  * @param env   The transformation environment
1119  * @return The created ia32 xDiv node
1120  */
1121 static ir_node *gen_Quot(ia32_transform_env_t *env) {
1122         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1123         ir_node *new_op;
1124         ir_node *nomem = new_rd_NoMem(env->irg);
1125         ir_node *op1   = get_Quot_left(env->irn);
1126         ir_node *op2   = get_Quot_right(env->irn);
1127         ir_mode *mode  = get_irn_mode(get_proj_for_pn(env->irn, pn_Quot_res));
1128         ir_node *projs[pn_Quot_max];
1129         /* BEWARE: Projs will be renumbered, so retrieve res Proj here */
1130
1131         ia32_collect_Projs(env->irn, projs, pn_Quot_max);
1132
1133         FP_USED(env->cg);
1134         if (USE_SSE2(env->cg)) {
1135                 if (is_ia32_xConst(op2)) {
1136                         new_op = new_rd_ia32_xDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, noreg, nomem);
1137                         set_ia32_am_support(new_op, ia32_am_None);
1138                         set_ia32_Immop_attr(new_op, op2);
1139                 }
1140                 else {
1141                         new_op = new_rd_ia32_xDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem);
1142                         set_ia32_am_support(new_op, ia32_am_Source);
1143                 }
1144                 ia32_renumber_Proj(projs, pn_Quot_M, pn_ia32_xDiv_M);
1145                 ia32_renumber_Proj(projs, pn_Quot_res, pn_ia32_xDiv_res);
1146         }
1147         else {
1148                 new_op = new_rd_ia32_vfdiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem);
1149                 set_ia32_am_support(new_op, ia32_am_Source);
1150                 ia32_renumber_Proj(projs, pn_Quot_M, pn_ia32_vfdiv_M);
1151                 ia32_renumber_Proj(projs, pn_Quot_res, pn_ia32_vfdiv_res);
1152         }
1153         set_ia32_res_mode(new_op, mode);
1154         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1155         return new_op;
1156 }
1157
1158
1159
1160 /**
1161  * Creates an ia32 Shl.
1162  *
1163  * @param env   The transformation environment
1164  * @return The created ia32 Shl node
1165  */
1166 static ir_node *gen_Shl(ia32_transform_env_t *env) {
1167         return gen_shift_binop(env, get_Shl_left(env->irn), get_Shl_right(env->irn), new_rd_ia32_Shl);
1168 }
1169
1170
1171
1172 /**
1173  * Creates an ia32 Shr.
1174  *
1175  * @param env   The transformation environment
1176  * @return The created ia32 Shr node
1177  */
1178 static ir_node *gen_Shr(ia32_transform_env_t *env) {
1179         return gen_shift_binop(env, get_Shr_left(env->irn), get_Shr_right(env->irn), new_rd_ia32_Shr);
1180 }
1181
1182
1183
1184 /**
1185  * Creates an ia32 Shrs.
1186  *
1187  * @param env   The transformation environment
1188  * @return The created ia32 Shrs node
1189  */
1190 static ir_node *gen_Shrs(ia32_transform_env_t *env) {
1191         return gen_shift_binop(env, get_Shrs_left(env->irn), get_Shrs_right(env->irn), new_rd_ia32_Shrs);
1192 }
1193
1194
1195
1196 /**
1197  * Creates an ia32 RotL.
1198  *
1199  * @param env   The transformation environment
1200  * @param op1   The first operator
1201  * @param op2   The second operator
1202  * @return The created ia32 RotL node
1203  */
1204 static ir_node *gen_RotL(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
1205         return gen_shift_binop(env, op1, op2, new_rd_ia32_RotL);
1206 }
1207
1208
1209
1210 /**
1211  * Creates an ia32 RotR.
1212  * NOTE: There is no RotR with immediate because this would always be a RotL
1213  *       "imm-mode_size_bits" which can be pre-calculated.
1214  *
1215  * @param env   The transformation environment
1216  * @param op1   The first operator
1217  * @param op2   The second operator
1218  * @return The created ia32 RotR node
1219  */
1220 static ir_node *gen_RotR(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
1221         return gen_shift_binop(env, op1, op2, new_rd_ia32_RotR);
1222 }
1223
1224
1225
1226 /**
1227  * Creates an ia32 RotR or RotL (depending on the found pattern).
1228  *
1229  * @param env   The transformation environment
1230  * @return The created ia32 RotL or RotR node
1231  */
1232 static ir_node *gen_Rot(ia32_transform_env_t *env) {
1233         ir_node *rotate = NULL;
1234         ir_node *op1    = get_Rot_left(env->irn);
1235         ir_node *op2    = get_Rot_right(env->irn);
1236
1237         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1238                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1239                  that means we can create a RotR instead of an Add and a RotL */
1240
1241         if (is_Proj(op2)) {
1242                 ir_node *pred = get_Proj_pred(op2);
1243
1244                 if (is_ia32_Add(pred)) {
1245                         ir_node *pred_pred = get_irn_n(pred, 2);
1246                         tarval  *tv        = get_ia32_Immop_tarval(pred);
1247                         long     bits      = get_mode_size_bits(env->mode);
1248
1249                         if (is_Proj(pred_pred)) {
1250                                 pred_pred = get_Proj_pred(pred_pred);
1251                         }
1252
1253                         if (is_ia32_Minus(pred_pred) &&
1254                                 tarval_is_long(tv)       &&
1255                                 get_tarval_long(tv) == bits)
1256                         {
1257                                 DB((env->mod, LEVEL_1, "RotL into RotR ... "));
1258                                 rotate = gen_RotR(env, op1, get_irn_n(pred_pred, 2));
1259                         }
1260
1261                 }
1262         }
1263
1264         if (!rotate) {
1265                 rotate = gen_RotL(env, op1, op2);
1266         }
1267
1268         return rotate;
1269 }
1270
1271
1272
1273 /**
1274  * Transforms a Minus node.
1275  *
1276  * @param env   The transformation environment
1277  * @param op    The Minus operand
1278  * @return The created ia32 Minus node
1279  */
1280 ir_node *gen_Minus_ex(ia32_transform_env_t *env, ir_node *op) {
1281         ident   *name;
1282         ir_node *new_op;
1283         int      size;
1284
1285         if (mode_is_float(env->mode)) {
1286                 FP_USED(env->cg);
1287                 if (USE_SSE2(env->cg)) {
1288                         ir_node *noreg_gp = ia32_new_NoReg_gp(env->cg);
1289                         ir_node *noreg_fp = ia32_new_NoReg_fp(env->cg);
1290                         ir_node *nomem    = new_rd_NoMem(env->irg);
1291
1292                         new_op = new_rd_ia32_xEor(env->dbg, env->irg, env->block, noreg_gp, noreg_gp, op, noreg_fp, nomem);
1293
1294                         size   = get_mode_size_bits(env->mode);
1295                         name   = gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1296
1297                         set_ia32_am_sc(new_op, name);
1298
1299                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1300
1301                         set_ia32_res_mode(new_op, env->mode);
1302                         set_ia32_op_type(new_op, ia32_AddrModeS);
1303                         set_ia32_ls_mode(new_op, env->mode);
1304
1305                         new_op = new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, pn_ia32_xEor_res);
1306                 }
1307                 else {
1308                         new_op = new_rd_ia32_vfchs(env->dbg, env->irg, env->block, op, env->mode);
1309                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1310                 }
1311         }
1312         else {
1313                 new_op = gen_unop(env, op, new_rd_ia32_Minus);
1314         }
1315
1316         return new_op;
1317 }
1318
1319 /**
1320  * Transforms a Minus node.
1321  *
1322  * @param env   The transformation environment
1323  * @return The created ia32 Minus node
1324  */
1325 static ir_node *gen_Minus(ia32_transform_env_t *env) {
1326         return gen_Minus_ex(env, get_Minus_op(env->irn));
1327 }
1328
1329
1330 /**
1331  * Transforms a Not node.
1332  *
1333  * @param env   The transformation environment
1334  * @return The created ia32 Not node
1335  */
1336 static ir_node *gen_Not(ia32_transform_env_t *env) {
1337         assert (! mode_is_float(env->mode));
1338         return gen_unop(env, get_Not_op(env->irn), new_rd_ia32_Not);
1339 }
1340
1341
1342
1343 /**
1344  * Transforms an Abs node.
1345  *
1346  * @param env   The transformation environment
1347  * @return The created ia32 Abs node
1348  */
1349 static ir_node *gen_Abs(ia32_transform_env_t *env) {
1350         ir_node  *res, *p_eax, *p_edx;
1351         dbg_info *dbg      = env->dbg;
1352         ir_mode  *mode     = env->mode;
1353         ir_graph *irg      = env->irg;
1354         ir_node  *block    = env->block;
1355         ir_node  *noreg_gp = ia32_new_NoReg_gp(env->cg);
1356         ir_node  *noreg_fp = ia32_new_NoReg_fp(env->cg);
1357         ir_node  *nomem    = new_NoMem();
1358         ir_node  *op       = get_Abs_op(env->irn);
1359         int       size;
1360         ident    *name;
1361
1362         if (mode_is_float(mode)) {
1363                 FP_USED(env->cg);
1364                 if (USE_SSE2(env->cg)) {
1365                         res = new_rd_ia32_xAnd(dbg,irg, block, noreg_gp, noreg_gp, op, noreg_fp, nomem);
1366
1367                         size   = get_mode_size_bits(mode);
1368                         name   = gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1369
1370                         set_ia32_am_sc(res, name);
1371
1372                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1373
1374                         set_ia32_res_mode(res, mode);
1375                         set_ia32_op_type(res, ia32_AddrModeS);
1376                         set_ia32_ls_mode(res, env->mode);
1377
1378                         res = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_xAnd_res);
1379                 }
1380                 else {
1381                         res = new_rd_ia32_vfabs(dbg, irg, block, op, mode);
1382                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1383                 }
1384         }
1385         else {
1386                 res   = new_rd_ia32_Cdq(dbg, irg, block, op);
1387                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1388                 set_ia32_res_mode(res, mode);
1389
1390                 p_eax = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Cdq_EAX);
1391                 p_edx = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Cdq_EDX);
1392
1393                 res   = new_rd_ia32_Eor(dbg, irg, block, noreg_gp, noreg_gp, p_eax, p_edx, nomem);
1394                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1395                 set_ia32_res_mode(res, mode);
1396
1397                 res   = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Eor_res);
1398
1399                 res   = new_rd_ia32_Sub(dbg, irg, block, noreg_gp, noreg_gp, res, p_edx, nomem);
1400                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1401                 set_ia32_res_mode(res, mode);
1402
1403                 res   = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Sub_res);
1404         }
1405
1406         return res;
1407 }
1408
1409
1410
1411 /**
1412  * Transforms a Load.
1413  *
1414  * @param env   The transformation environment
1415  * @return the created ia32 Load node
1416  */
1417 static ir_node *gen_Load(ia32_transform_env_t *env) {
1418         ir_node *node  = env->irn;
1419         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1420         ir_node *ptr   = get_Load_ptr(node);
1421         ir_node *lptr  = ptr;
1422         ir_mode *mode  = get_Load_mode(node);
1423         int     is_imm = 0;
1424         ir_node *new_op;
1425         ia32_am_flavour_t am_flav = ia32_am_B;
1426         ir_node *projs[pn_Load_max];
1427
1428         ia32_collect_Projs(env->irn, projs, pn_Load_max);
1429
1430         /* address might be a constant (symconst or absolute address) */
1431         if (is_ia32_Const(ptr)) {
1432                 lptr   = noreg;
1433                 is_imm = 1;
1434         }
1435
1436         if (mode_is_float(mode)) {
1437                 FP_USED(env->cg);
1438                 if (USE_SSE2(env->cg)) {
1439                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node));
1440                         ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_xLoad_M);
1441                         ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_xLoad_res);
1442                 }
1443                 else {
1444                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node));
1445                         ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_vfld_M);
1446                         ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_vfld_res);
1447                 }
1448         }
1449         else {
1450                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node));
1451                 ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_Load_M);
1452                 ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_Load_res);
1453         }
1454
1455         /* base is an constant address */
1456         if (is_imm) {
1457                 if (get_ia32_op_type(ptr) == ia32_SymConst) {
1458                         set_ia32_am_sc(new_op, get_ia32_id_cnst(ptr));
1459                         am_flav = ia32_am_N;
1460                 }
1461                 else {
1462                         add_ia32_am_offs(new_op, get_ia32_cnst(ptr));
1463                         am_flav = ia32_am_O;
1464                 }
1465         }
1466
1467         set_ia32_am_support(new_op, ia32_am_Source);
1468         set_ia32_op_type(new_op, ia32_AddrModeS);
1469         set_ia32_am_flavour(new_op, am_flav);
1470         set_ia32_ls_mode(new_op, mode);
1471
1472         /*
1473                 check for special case: the loaded value might not be used (optimized, volatile, ...)
1474                 we add a Proj + Keep for volatile loads and ignore all other cases
1475         */
1476         if (! get_proj_for_pn(node, pn_Load_res) && get_Load_volatility(node) == volatility_is_volatile) {
1477                 /* add a result proj and a Keep to produce a pseudo use */
1478                 ir_node *proj = new_r_Proj(env->irg, env->block, new_op, mode, pn_ia32_Load_res);
1479                 be_new_Keep(arch_get_irn_reg_class(env->cg->arch_env, proj, -1), env->irg, env->block, 1, &proj);
1480         }
1481
1482         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1483
1484         return new_op;
1485 }
1486
1487
1488
1489 /**
1490  * Transforms a Store.
1491  *
1492  * @param env   The transformation environment
1493  * @return the created ia32 Store node
1494  */
1495 static ir_node *gen_Store(ia32_transform_env_t *env) {
1496         ir_node *node    = env->irn;
1497         ir_node *noreg   = ia32_new_NoReg_gp(env->cg);
1498         ir_node *val     = get_Store_value(node);
1499         ir_node *ptr     = get_Store_ptr(node);
1500         ir_node *sptr    = ptr;
1501         ir_node *mem     = get_Store_mem(node);
1502         ir_mode *mode    = get_irn_mode(val);
1503         ir_node *sval    = val;
1504         int      is_imm  = 0;
1505         ir_node *new_op;
1506         ia32_am_flavour_t am_flav = ia32_am_B;
1507         ia32_immop_type_t immop   = ia32_ImmNone;
1508         ir_node *projs[pn_Store_max];
1509
1510         ia32_collect_Projs(env->irn, projs, pn_Store_max);
1511
1512         if (! mode_is_float(mode)) {
1513                 /* in case of storing a const (but not a symconst) -> make it an attribute */
1514                 if (is_ia32_Cnst(val)) {
1515                         switch (get_ia32_op_type(val)) {
1516                         case ia32_Const:
1517                                 immop = ia32_ImmConst;
1518                                 break;
1519                         case ia32_SymConst:
1520                                 immop = ia32_ImmSymConst;
1521                                 break;
1522                         default:
1523                                 assert(0 && "unsupported Const type");
1524                         }
1525                         sval = noreg;
1526                 }
1527         }
1528
1529         /* address might be a constant (symconst or absolute address) */
1530         if (is_ia32_Const(ptr)) {
1531                 sptr   = noreg;
1532                 is_imm = 1;
1533         }
1534
1535         if (mode_is_float(mode)) {
1536                 FP_USED(env->cg);
1537                 if (USE_SSE2(env->cg)) {
1538                         new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
1539                         ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_xStore_M);
1540                 }
1541                 else {
1542                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
1543                         ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_vfst_M);
1544                 }
1545         }
1546         else if (get_mode_size_bits(mode) == 8) {
1547                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
1548                 ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_Store8Bit_M);
1549         }
1550         else {
1551                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
1552                 ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_Store_M);
1553         }
1554
1555         /* stored const is an attribute (saves a register) */
1556         if (! mode_is_float(mode) && is_ia32_Cnst(val)) {
1557                 set_ia32_Immop_attr(new_op, val);
1558         }
1559
1560         /* base is an constant address */
1561         if (is_imm) {
1562                 if (get_ia32_op_type(ptr) == ia32_SymConst) {
1563                         set_ia32_am_sc(new_op, get_ia32_id_cnst(ptr));
1564                         am_flav = ia32_am_N;
1565                 }
1566                 else {
1567                         add_ia32_am_offs(new_op, get_ia32_cnst(ptr));
1568                         am_flav = ia32_am_O;
1569                 }
1570         }
1571
1572         set_ia32_am_support(new_op, ia32_am_Dest);
1573         set_ia32_op_type(new_op, ia32_AddrModeD);
1574         set_ia32_am_flavour(new_op, am_flav);
1575         set_ia32_ls_mode(new_op, mode);
1576         set_ia32_immop_type(new_op, immop);
1577
1578         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1579
1580         return new_op;
1581 }
1582
1583
1584
1585 /**
1586  * Transforms a Cond -> Proj[b] -> Cmp into a CondJmp, CondJmp_i or TestJmp
1587  *
1588  * @param env   The transformation environment
1589  * @return The transformed node.
1590  */
1591 static ir_node *gen_Cond(ia32_transform_env_t *env) {
1592         dbg_info *dbg      = env->dbg;
1593         ir_graph *irg      = env->irg;
1594         ir_node  *block    = env->block;
1595         ir_node  *node     = env->irn;
1596         ir_node  *sel      = get_Cond_selector(node);
1597         ir_mode  *sel_mode = get_irn_mode(sel);
1598         ir_node  *res      = NULL;
1599         ir_node  *pred     = NULL;
1600         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
1601         ir_node  *cmp_a, *cmp_b, *cnst, *expr;
1602
1603         if (is_Proj(sel) && sel_mode == mode_b) {
1604                 ir_node  *nomem = new_NoMem();
1605                 pn_Cmp pnc = get_Proj_proj(sel);
1606
1607                 pred  = get_Proj_pred(sel);
1608
1609                 /* get both compare operators */
1610                 cmp_a = get_Cmp_left(pred);
1611                 cmp_b = get_Cmp_right(pred);
1612
1613                 /* check if we can use a CondJmp with immediate */
1614                 cnst = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(cmp_a, cmp_b) : NULL;
1615                 expr = get_expr_op(cmp_a, cmp_b);
1616
1617                 if (cnst && expr) {
1618                         /* immop has to be the right operand, we might need to flip pnc */
1619                         if(cnst != cmp_b) {
1620                                 pnc = get_inversed_pnc(pnc);
1621                         }
1622
1623                         if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_is_int(get_irn_mode(expr))) {
1624                                 if (get_ia32_op_type(cnst) == ia32_Const &&
1625                                         classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL)
1626                                 {
1627                                         /* a Cmp A =/!= 0 */
1628                                         ir_node    *op1  = expr;
1629                                         ir_node    *op2  = expr;
1630                                         ir_node    *and  = skip_Proj(expr);
1631                                         const char *cnst = NULL;
1632
1633                                         /* check, if expr is an only once used And operation */
1634                                         if (get_irn_n_edges(expr) == 1 && is_ia32_And(and)) {
1635                                                 op1 = get_irn_n(and, 2);
1636                                                 op2 = get_irn_n(and, 3);
1637
1638                                                 cnst = (is_ia32_ImmConst(and) || is_ia32_ImmSymConst(and)) ? get_ia32_cnst(and) : NULL;
1639                                         }
1640                                         res = new_rd_ia32_TestJmp(dbg, irg, block, op1, op2);
1641                                         set_ia32_pncode(res, pnc);
1642                                         set_ia32_res_mode(res, get_irn_mode(op1));
1643
1644                                         if (cnst) {
1645                                                 copy_ia32_Immop_attr(res, and);
1646                                         }
1647
1648                                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1649                                         return res;
1650                                 }
1651                         }
1652
1653                         if (mode_is_float(get_irn_mode(expr))) {
1654                                 FP_USED(env->cg);
1655                                 if (USE_SSE2(env->cg))
1656                                         res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem);
1657                                 else {
1658                                         assert(0);
1659                                 }
1660                         }
1661                         else {
1662                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem);
1663                         }
1664                         set_ia32_Immop_attr(res, cnst);
1665                         set_ia32_res_mode(res, get_irn_mode(expr));
1666                 }
1667                 else {
1668                         if (mode_is_float(get_irn_mode(cmp_a))) {
1669                                 FP_USED(env->cg);
1670                                 if (USE_SSE2(env->cg))
1671                                         res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1672                                 else {
1673                                         ir_node *proj_eax;
1674                                         res = new_rd_ia32_vfCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1675                                         proj_eax = new_r_Proj(irg, block, res, mode_Is, pn_ia32_vfCondJmp_temp_reg_eax);
1676                                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, &proj_eax);
1677                                 }
1678                         }
1679                         else {
1680                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1681                                 set_ia32_commutative(res);
1682                         }
1683                         set_ia32_res_mode(res, get_irn_mode(cmp_a));
1684                 }
1685
1686                 set_ia32_pncode(res, pnc);
1687                 //set_ia32_am_support(res, ia32_am_Source);
1688         }
1689         else {
1690                 /* determine the smallest switch case value */
1691                 int switch_min = INT_MAX;
1692                 const ir_edge_t *edge;
1693                 char buf[64];
1694
1695                 foreach_out_edge(node, edge) {
1696                         int pn = get_Proj_proj(get_edge_src_irn(edge));
1697                         switch_min = pn < switch_min ? pn : switch_min;
1698                 }
1699
1700                 if (switch_min) {
1701                         /* if smallest switch case is not 0 we need an additional sub */
1702                         snprintf(buf, sizeof(buf), "%d", switch_min);
1703                         res = new_rd_ia32_Lea(dbg, irg, block, sel, noreg, mode_Is);
1704                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1705                         sub_ia32_am_offs(res, buf);
1706                         set_ia32_am_flavour(res, ia32_am_OB);
1707                         set_ia32_am_support(res, ia32_am_Source);
1708                         set_ia32_op_type(res, ia32_AddrModeS);
1709                 }
1710
1711                 res = new_rd_ia32_SwitchJmp(dbg, irg, block, switch_min ? res : sel, mode_T);
1712                 set_ia32_pncode(res, get_Cond_defaultProj(node));
1713                 set_ia32_res_mode(res, get_irn_mode(sel));
1714         }
1715
1716         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1717         return res;
1718 }
1719
1720
1721
1722 /**
1723  * Transforms a CopyB node.
1724  *
1725  * @param env   The transformation environment
1726  * @return The transformed node.
1727  */
1728 static ir_node *gen_CopyB(ia32_transform_env_t *env) {
1729         ir_node  *res      = NULL;
1730         dbg_info *dbg      = env->dbg;
1731         ir_graph *irg      = env->irg;
1732         ir_node  *block    = env->block;
1733         ir_node  *node     = env->irn;
1734         ir_node  *src      = get_CopyB_src(node);
1735         ir_node  *dst      = get_CopyB_dst(node);
1736         ir_node  *mem      = get_CopyB_mem(node);
1737         int      size      = get_type_size_bytes(get_CopyB_type(node));
1738         ir_mode  *dst_mode = get_irn_mode(dst);
1739         ir_mode  *src_mode = get_irn_mode(src);
1740         int      rem;
1741         ir_node  *in[3];
1742         ir_node  *projs[pn_CopyB_max];
1743
1744         ia32_collect_Projs(env->irn, projs, pn_CopyB_max);
1745
1746         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
1747         /* then we need the size explicitly in ECX.                    */
1748         if (size >= 32 * 4) {
1749                 rem = size & 0x3; /* size % 4 */
1750                 size >>= 2;
1751
1752                 res = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Is);
1753                 set_ia32_op_type(res, ia32_Const);
1754                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1755
1756                 res = new_rd_ia32_CopyB(dbg, irg, block, dst, src, res, mem);
1757                 set_ia32_Immop_tarval(res, new_tarval_from_long(rem, mode_Is));
1758
1759                 /* ok: now attach Proj's because rep movsd will destroy esi, edi and ecx */
1760                 in[0] = new_r_Proj(irg, block, res, dst_mode, pn_ia32_CopyB_DST);
1761                 in[1] = new_r_Proj(irg, block, res, src_mode, pn_ia32_CopyB_SRC);
1762                 in[2] = new_r_Proj(irg, block, res, mode_Is, pn_ia32_CopyB_CNT);
1763                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 3, in);
1764
1765                 ia32_renumber_Proj(projs, pn_CopyB_M_regular, pn_ia32_CopyB_M);
1766         }
1767         else {
1768                 res = new_rd_ia32_CopyB_i(dbg, irg, block, dst, src, mem);
1769                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1770                 set_ia32_immop_type(res, ia32_ImmConst);
1771
1772                 /* ok: now attach Proj's because movsd will destroy esi and edi */
1773                 in[0] = new_r_Proj(irg, block, res, dst_mode, pn_ia32_CopyB_i_DST);
1774                 in[1] = new_r_Proj(irg, block, res, src_mode, pn_ia32_CopyB_i_SRC);
1775                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 2, in);
1776
1777                 ia32_renumber_Proj(projs, pn_CopyB_M_regular, pn_ia32_CopyB_i_M);
1778         }
1779
1780         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1781
1782         return res;
1783 }
1784
1785
1786
1787 /**
1788  * Transforms a Mux node into CMov.
1789  *
1790  * @param env   The transformation environment
1791  * @return The transformed node.
1792  */
1793 static ir_node *gen_Mux(ia32_transform_env_t *env) {
1794 #if 0
1795         ir_node *node   = env->irn;
1796         ir_node *new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, \
1797                 get_Mux_sel(node), get_Mux_false(node), get_Mux_true(node), env->mode);
1798
1799         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1800
1801         return new_op;
1802 #endif
1803         return NULL;
1804 }
1805
1806 typedef ir_node *cmov_func_t(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *cmp_a, ir_node *cmp_b, \
1807                              ir_node *psi_true, ir_node *psi_default, ir_mode *mode);
1808
1809 /**
1810  * Transforms a Psi node into CMov.
1811  *
1812  * @param env   The transformation environment
1813  * @return The transformed node.
1814  */
1815 static ir_node *gen_Psi(ia32_transform_env_t *env) {
1816         ia32_code_gen_t *cg   = env->cg;
1817         dbg_info *dbg         = env->dbg;
1818         ir_graph *irg         = env->irg;
1819         ir_mode  *mode        = env->mode;
1820         ir_node  *block       = env->block;
1821         ir_node  *node        = env->irn;
1822         ir_node  *cmp_proj    = get_Mux_sel(node);
1823         ir_node  *psi_true    = get_Psi_val(node, 0);
1824         ir_node  *psi_default = get_Psi_default(node);
1825         ir_node  *noreg       = ia32_new_NoReg_gp(cg);
1826         ir_node  *nomem       = new_rd_NoMem(irg);
1827         ir_node  *cmp, *cmp_a, *cmp_b, *and1, *and2, *new_op = NULL;
1828         int      pnc;
1829
1830         assert(get_irn_mode(cmp_proj) == mode_b && "Condition for Psi must have mode_b");
1831
1832         cmp   = get_Proj_pred(cmp_proj);
1833         cmp_a = get_Cmp_left(cmp);
1834         cmp_b = get_Cmp_right(cmp);
1835         pnc   = get_Proj_proj(cmp_proj);
1836
1837         if (mode_is_float(mode)) {
1838                 /* floating point psi */
1839                 FP_USED(cg);
1840
1841                 /* 1st case: compare operands are float too */
1842                 if (USE_SSE2(cg)) {
1843                         /* psi(cmp(a, b), t, f) can be done as: */
1844                         /* tmp = cmp a, b                       */
1845                         /* tmp2 = t and tmp                     */
1846                         /* tmp3 = f and not tmp                 */
1847                         /* res  = tmp2 or tmp3                  */
1848
1849                         /* in case the compare operands are int, we move them into xmm register */
1850                         if (! mode_is_float(get_irn_mode(cmp_a))) {
1851                                 cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_a, node, mode_D);
1852                                 cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_b, node, mode_D);
1853
1854                                 pnc |= 8;  /* transform integer compare to fp compare */
1855                         }
1856
1857                         new_op = new_rd_ia32_xCmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1858                         set_ia32_pncode(new_op, pnc);
1859                         set_ia32_am_support(new_op, ia32_am_Source);
1860                         set_ia32_res_mode(new_op, mode);
1861                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1862                         new_op = new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_xCmp_res);
1863
1864                         and1 = new_rd_ia32_xAnd(dbg, irg, block, noreg, noreg, psi_true, new_op, nomem);
1865                         set_ia32_am_support(and1, ia32_am_None);
1866                         set_ia32_res_mode(and1, mode);
1867                         set_ia32_commutative(and1);
1868                         SET_IA32_ORIG_NODE(and1, ia32_get_old_node_name(cg, node));
1869                         and1 = new_rd_Proj(dbg, irg, block, and1, mode, pn_ia32_xAnd_res);
1870
1871                         and2 = new_rd_ia32_xAndNot(dbg, irg, block, noreg, noreg, new_op, psi_default, nomem);
1872                         set_ia32_am_support(and2, ia32_am_None);
1873                         set_ia32_res_mode(and2, mode);
1874                         set_ia32_commutative(and2);
1875                         SET_IA32_ORIG_NODE(and2, ia32_get_old_node_name(cg, node));
1876                         and2 = new_rd_Proj(dbg, irg, block, and2, mode, pn_ia32_xAndNot_res);
1877
1878                         new_op = new_rd_ia32_xOr(dbg, irg, block, noreg, noreg, and1, and2, nomem);
1879                         set_ia32_am_support(new_op, ia32_am_None);
1880                         set_ia32_res_mode(new_op, mode);
1881                         set_ia32_commutative(new_op);
1882                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1883                         new_op = new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_xOr_res);
1884                 }
1885                 else {
1886                         /* x87 FPU */
1887                         new_op = new_rd_ia32_vfCMov(dbg, irg, block, cmp_a, cmp_b, psi_true, psi_default, mode);
1888                         set_ia32_pncode(new_op, pnc);
1889                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1890                 }
1891         }
1892         else {
1893                 /* integer psi */
1894                 construct_binop_func *set_func  = NULL;
1895                 cmov_func_t          *cmov_func = NULL;
1896
1897                 if (mode_is_float(get_irn_mode(cmp_a))) {
1898                         /* 1st case: compare operands are floats */
1899                         FP_USED(cg);
1900
1901                         if (USE_SSE2(cg)) {
1902                                 /* SSE FPU */
1903                                 set_func  = new_rd_ia32_xCmpSet;
1904                                 cmov_func = new_rd_ia32_xCmpCMov;
1905                         }
1906                         else {
1907                                 /* x87 FPU */
1908                                 set_func  = new_rd_ia32_vfCmpSet;
1909                                 cmov_func = new_rd_ia32_vfCmpCMov;
1910                         }
1911
1912                         pnc &= 7; /* fp compare -> int compare */
1913                 }
1914                 else {
1915                         /* 2nd case: compare operand are integer too */
1916                         set_func  = new_rd_ia32_CmpSet;
1917                         cmov_func = new_rd_ia32_CmpCMov;
1918                 }
1919
1920                 /* create the nodes */
1921
1922                 /* check for special case first: And/Or -- Cmp with 0 -- Psi */
1923                 if (is_ia32_Const_0(cmp_b) && is_Proj(cmp_a) && (is_ia32_And(get_Proj_pred(cmp_a)) || is_ia32_Or(get_Proj_pred(cmp_a)))) {
1924                         if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) {
1925                                 /* first case for SETcc: default is 0, set to 1 iff condition is true */
1926                                 new_op = new_rd_ia32_PsiCondSet(dbg, irg, block, cmp_a, mode);
1927                                 set_ia32_pncode(new_op, pnc);
1928                         }
1929                         else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) {
1930                                 /* second case for SETcc: default is 1, set to 0 iff condition is true: */
1931                                 /*                        we invert condition and set default to 0      */
1932                                 new_op = new_rd_ia32_PsiCondSet(dbg, irg, block, cmp_a, mode);
1933                                 set_ia32_pncode(new_op, get_inversed_pnc(pnc));
1934                         }
1935                         else {
1936                                 /* otherwise: use CMOVcc */
1937                                 new_op = new_rd_ia32_PsiCondCMov(dbg, irg, block, cmp_a, psi_true, psi_default, mode);
1938                                 set_ia32_pncode(new_op, pnc);
1939                         }
1940
1941                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1942                 }
1943                 else {
1944                         env->irn = cmp;
1945                         if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) {
1946                                 /* first case for SETcc: default is 0, set to 1 iff condition is true */
1947                                 new_op = gen_binop(env, cmp_a, cmp_b, set_func);
1948                                 set_ia32_pncode(get_Proj_pred(new_op), pnc);
1949                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
1950                         }
1951                         else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) {
1952                                 /* second case for SETcc: default is 1, set to 0 iff condition is true: */
1953                                 /*                        we invert condition and set default to 0      */
1954                                 new_op = gen_binop(env, cmp_a, cmp_b, set_func);
1955                                 set_ia32_pncode(get_Proj_pred(new_op), get_inversed_pnc(pnc));
1956                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
1957                         }
1958                         else {
1959                                 /* otherwise: use CMOVcc */
1960                                 new_op = cmov_func(dbg, irg, block, cmp_a, cmp_b, psi_true, psi_default, mode);
1961                                 set_ia32_pncode(new_op, pnc);
1962                                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1963                         }
1964                 }
1965         }
1966
1967         return new_op;
1968 }
1969
1970
1971 /**
1972  * Following conversion rules apply:
1973  *
1974  *  INT -> INT
1975  * ============
1976  *  1) n bit -> m bit   n > m (downscale)
1977  *     a) target is signed:    movsx
1978  *     b) target is unsigned:  and with lower bits sets
1979  *  2) n bit -> m bit   n == m   (sign change)
1980  *     always ignored
1981  *  3) n bit -> m bit   n < m (upscale)
1982  *     a) source is signed:    movsx
1983  *     b) source is unsigned:  and with lower bits sets
1984  *
1985  *  INT -> FLOAT
1986  * ==============
1987  *  SSE(1/2) convert to float or double (cvtsi2ss/sd)
1988  *
1989  *  FLOAT -> INT
1990  * ==============
1991  *  SSE(1/2) convert from float or double to 32bit int (cvtss/sd2si)
1992  *  if target mode < 32bit: additional INT -> INT conversion (see above)
1993  *
1994  *  FLOAT -> FLOAT
1995  * ================
1996  *  SSE(1/2) convert from float or double to double or float (cvtss/sd2sd/ss)
1997  *  x87 is mode_E internally, conversions happen only at load and store
1998  *  in non-strict semantic
1999  */
2000
2001 /**
2002  * Create a conversion from x87 state register to general purpose.
2003  */
2004 static ir_node *gen_x87_fp_to_gp(ia32_transform_env_t *env, ir_mode *tgt_mode) {
2005         ia32_code_gen_t *cg    = env->cg;
2006         entity          *ent   = cg->fp_to_gp;
2007         ir_graph        *irg   = env->irg;
2008         ir_node         *block = env->block;
2009         ir_node         *noreg = ia32_new_NoReg_gp(env->cg);
2010         ir_node         *op    = get_Conv_op(env->irn);
2011         ir_node         *fist, *mem, *load;
2012
2013         if (! ent) {
2014                 int size = get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_vfp].mode);
2015                 ent = cg->fp_to_gp =
2016                         frame_alloc_area(get_irg_frame_type(env->irg), size, 16, 0);
2017         }
2018
2019         /* do a fist */
2020         fist = new_rd_ia32_vfist(env->dbg, irg, block, get_irg_frame(irg), noreg, op, get_irg_no_mem(irg));
2021
2022         set_ia32_frame_ent(fist, ent);
2023         set_ia32_use_frame(fist);
2024         set_ia32_am_support(fist, ia32_am_Dest);
2025         set_ia32_op_type(fist, ia32_AddrModeD);
2026         set_ia32_am_flavour(fist, ia32_B);
2027         set_ia32_ls_mode(fist, mode_F);
2028
2029         mem  = new_r_Proj(irg, block, fist, mode_M, pn_ia32_vfist_M);
2030
2031         /* do a Load */
2032         load = new_rd_ia32_Load(env->dbg, irg, block, get_irg_frame(irg), noreg, mem);
2033
2034         set_ia32_frame_ent(load, ent);
2035         set_ia32_use_frame(load);
2036         set_ia32_am_support(load, ia32_am_Source);
2037         set_ia32_op_type(load, ia32_AddrModeS);
2038         set_ia32_am_flavour(load, ia32_B);
2039         set_ia32_ls_mode(load, tgt_mode);
2040
2041         return new_r_Proj(irg, block, load, tgt_mode, pn_ia32_Load_res);
2042 }
2043
2044 /**
2045  * Create a conversion from x87 state register to general purpose.
2046  */
2047 static ir_node *gen_x87_gp_to_fp(ia32_transform_env_t *env, ir_mode *src_mode) {
2048         ia32_code_gen_t *cg = env->cg;
2049         entity   *ent = cg->gp_to_fp;
2050         ir_graph *irg = env->irg;
2051         ir_node  *block = env->block;
2052         ir_node  *noreg = ia32_new_NoReg_gp(env->cg);
2053         ir_node  *nomem = get_irg_no_mem(irg);
2054         ir_node  *op = get_Conv_op(env->irn);
2055         ir_node  *fild, *store, *mem;
2056         int src_bits;
2057
2058         if (! ent) {
2059                 int size = get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_gp].mode);
2060                 ent = cg->gp_to_fp =
2061                         frame_alloc_area(get_irg_frame_type(env->irg), size, size, 0);
2062         }
2063
2064         /* first convert to 32 bit */
2065         src_bits = get_mode_size_bits(src_mode);
2066         if (src_bits == 8) {
2067                 op = new_rd_ia32_Conv_I2I8Bit(env->dbg, irg, block, noreg, noreg, op, nomem);
2068                 op = new_r_Proj(irg, block, op, mode_Is, 0);
2069         }
2070         else if (src_bits < 32) {
2071                 op = new_rd_ia32_Conv_I2I(env->dbg, irg, block, noreg, noreg, op, nomem);
2072                 op = new_r_Proj(irg, block, op, mode_Is, 0);
2073         }
2074
2075         /* do a store */
2076         store = new_rd_ia32_Store(env->dbg, irg, block, get_irg_frame(irg), noreg, op, nomem);
2077
2078         set_ia32_frame_ent(store, ent);
2079         set_ia32_use_frame(store);
2080
2081         set_ia32_am_support(store, ia32_am_Dest);
2082         set_ia32_op_type(store, ia32_AddrModeD);
2083         set_ia32_am_flavour(store, ia32_B);
2084         set_ia32_ls_mode(store, mode_Is);
2085
2086         mem = new_r_Proj(irg, block, store, mode_M, pn_ia32_Store_M);
2087
2088         /* do a fild */
2089         fild = new_rd_ia32_vfild(env->dbg, irg, block, get_irg_frame(irg), noreg, mem);
2090
2091         set_ia32_frame_ent(fild, ent);
2092         set_ia32_use_frame(fild);
2093         set_ia32_am_support(fild, ia32_am_Source);
2094         set_ia32_op_type(fild, ia32_AddrModeS);
2095         set_ia32_am_flavour(fild, ia32_B);
2096         set_ia32_ls_mode(fild, mode_F);
2097
2098         return new_r_Proj(irg, block, fild, mode_F, pn_ia32_vfild_res);
2099 }
2100
2101 /**
2102  * Transforms a Conv node.
2103  *
2104  * @param env   The transformation environment
2105  * @return The created ia32 Conv node
2106  */
2107 static ir_node *gen_Conv(ia32_transform_env_t *env) {
2108         dbg_info *dbg      = env->dbg;
2109         ir_graph *irg      = env->irg;
2110         ir_node  *op       = get_Conv_op(env->irn);
2111         ir_mode  *src_mode = get_irn_mode(op);
2112         ir_mode  *tgt_mode = env->mode;
2113         int      src_bits  = get_mode_size_bits(src_mode);
2114         int      tgt_bits  = get_mode_size_bits(tgt_mode);
2115         int      pn        = -1;
2116         int      kill      = 0;
2117         ir_node  *block    = env->block;
2118         ir_node  *new_op   = NULL;
2119         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
2120         ir_node  *nomem    = new_rd_NoMem(irg);
2121         ir_node  *proj;
2122         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
2123
2124         if (src_mode == tgt_mode) {
2125                 /* this can happen when changing mode_P to mode_Is */
2126                 DB((mod, LEVEL_1, "killed Conv(mode, mode) ..."));
2127                 edges_reroute(env->irn, op, irg);
2128         }
2129         else if (mode_is_float(src_mode)) {
2130                 /* we convert from float ... */
2131                 if (mode_is_float(tgt_mode)) {
2132                         /* ... to float */
2133                         if (USE_SSE2(env->cg)) {
2134                                 DB((mod, LEVEL_1, "create Conv(float, float) ..."));
2135                                 new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem);
2136                                 pn     = pn_ia32_Conv_FP2FP_res;
2137                         }
2138                         else {
2139                                 DB((mod, LEVEL_1, "killed Conv(float, float) ..."));
2140                                 /*
2141                                         remark: we create a intermediate conv here, so modes will be spread correctly
2142                                         these convs will be killed later
2143                                 */
2144                                 new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem);
2145                                 pn     = pn_ia32_Conv_FP2FP_res;
2146                                 kill   = 1;
2147                         }
2148                 }
2149                 else {
2150                         /* ... to int */
2151                         DB((mod, LEVEL_1, "create Conv(float, int) ..."));
2152                         if (USE_SSE2(env->cg)) {
2153                                 new_op = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, op, nomem);
2154                                 pn     = pn_ia32_Conv_FP2I_res;
2155                         }
2156                         else
2157                                 return gen_x87_fp_to_gp(env, tgt_mode);
2158
2159                         /* if target mode is not int: add an additional downscale convert */
2160                         if (tgt_bits < 32) {
2161                                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2162                                 set_ia32_am_support(new_op, ia32_am_Source);
2163                                 set_ia32_tgt_mode(new_op, mode_Is);
2164                                 set_ia32_src_mode(new_op, src_mode);
2165
2166                                 proj = new_rd_Proj(dbg, irg, block, new_op, mode_Is, pn_ia32_Conv_FP2I_res);
2167
2168                                 if (tgt_bits == 8 || src_bits == 8) {
2169                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, proj, nomem);
2170                                         pn     = pn_ia32_Conv_I2I8Bit_res;
2171                                 }
2172                                 else {
2173                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, proj, nomem);
2174                                         pn     = pn_ia32_Conv_I2I_res;
2175                                 }
2176                                 src_mode = mode_Is;
2177                         }
2178                 }
2179         }
2180         else {
2181                 /* we convert from int ... */
2182                 if (mode_is_float(tgt_mode)) {
2183                         FP_USED(env->cg);
2184                         /* ... to float */
2185                         DB((mod, LEVEL_1, "create Conv(int, float) ..."));
2186                         if (USE_SSE2(env->cg)) {
2187                                 new_op = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, op, nomem);
2188                                 pn     = pn_ia32_Conv_I2FP_res;
2189                         }
2190                         else
2191                                 return gen_x87_gp_to_fp(env, src_mode);
2192                 }
2193                 else {
2194                         /* ... to int */
2195                         if (get_mode_size_bits(src_mode) == tgt_bits) {
2196                                 DB((mod, LEVEL_1, "omitting equal size Conv(%+F, %+F) ...", src_mode, tgt_mode));
2197                                 /*
2198                                         remark: we create a intermediate conv here, so modes will be spread correctly
2199                                         these convs will be killed later
2200                                 */
2201                                 new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem);
2202                                 pn     = pn_ia32_Conv_I2I_res;
2203                                 kill   = 1;
2204                         }
2205                         else {
2206                                 DB((mod, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode));
2207                                 if (tgt_bits == 8 || src_bits == 8) {
2208                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, op, nomem);
2209                                         pn     = pn_ia32_Conv_I2I8Bit_res;
2210                                 }
2211                                 else {
2212                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem);
2213                                         pn     = pn_ia32_Conv_I2I_res;
2214                                 }
2215                         }
2216                 }
2217         }
2218
2219         if (new_op) {
2220                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2221                 set_ia32_tgt_mode(new_op, tgt_mode);
2222                 set_ia32_src_mode(new_op, src_mode);
2223
2224                 set_ia32_am_support(new_op, ia32_am_Source);
2225
2226                 new_op = new_rd_Proj(dbg, irg, block, new_op, tgt_mode, pn);
2227
2228                 if (kill)
2229                         nodeset_insert(env->cg->kill_conv, new_op);
2230         }
2231
2232         return new_op;
2233 }
2234
2235
2236
2237 /********************************************
2238  *  _                          _
2239  * | |                        | |
2240  * | |__   ___ _ __   ___   __| | ___  ___
2241  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
2242  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
2243  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
2244  *
2245  ********************************************/
2246
2247 static ir_node *gen_be_StackParam(ia32_transform_env_t *env) {
2248         ir_node *new_op = NULL;
2249         ir_node *node   = env->irn;
2250         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2251         ir_node *mem    = new_rd_NoMem(env->irg);
2252         ir_node *ptr    = get_irn_n(node, 0);
2253         entity  *ent    = arch_get_frame_entity(env->cg->arch_env, node);
2254         ir_mode *mode   = env->mode;
2255         long    pn_res;
2256
2257         if (mode_is_float(mode)) {
2258                 FP_USED(env->cg);
2259                 if (USE_SSE2(env->cg)) {
2260                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
2261                         pn_res = pn_ia32_xLoad_res;
2262                 }
2263                 else {
2264                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
2265                         pn_res = pn_ia32_vfld_res;
2266                 }
2267         }
2268         else {
2269                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
2270                 pn_res = pn_ia32_Load_res;
2271         }
2272
2273         set_ia32_frame_ent(new_op, ent);
2274         set_ia32_use_frame(new_op);
2275
2276         set_ia32_am_support(new_op, ia32_am_Source);
2277         set_ia32_op_type(new_op, ia32_AddrModeS);
2278         set_ia32_am_flavour(new_op, ia32_B);
2279         set_ia32_ls_mode(new_op, mode);
2280         set_ia32_flags(new_op, get_ia32_flags(new_op) | arch_irn_flags_rematerializable);
2281
2282         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2283
2284         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_res);
2285 }
2286
2287 /**
2288  * Transforms a FrameAddr into an ia32 Add.
2289  */
2290 static ir_node *gen_be_FrameAddr(ia32_transform_env_t *env) {
2291         ir_node *new_op = NULL;
2292         ir_node *node   = env->irn;
2293         ir_node *op     = get_irn_n(node, 0);
2294         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2295         ir_node *nomem  = new_rd_NoMem(env->irg);
2296
2297         new_op = new_rd_ia32_Add(env->dbg, env->irg, env->block, noreg, noreg, op, noreg, nomem);
2298         set_ia32_frame_ent(new_op, arch_get_frame_entity(env->cg->arch_env, node));
2299         set_ia32_am_support(new_op, ia32_am_Full);
2300         set_ia32_use_frame(new_op);
2301         set_ia32_immop_type(new_op, ia32_ImmConst);
2302         set_ia32_commutative(new_op);
2303
2304         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2305
2306         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, pn_ia32_Add_res);
2307 }
2308
2309 /**
2310  * Transforms a FrameLoad into an ia32 Load.
2311  */
2312 static ir_node *gen_be_FrameLoad(ia32_transform_env_t *env) {
2313         ir_node *new_op = NULL;
2314         ir_node *node   = env->irn;
2315         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2316         ir_node *mem    = get_irn_n(node, 0);
2317         ir_node *ptr    = get_irn_n(node, 1);
2318         entity  *ent    = arch_get_frame_entity(env->cg->arch_env, node);
2319         ir_mode *mode   = get_type_mode(get_entity_type(ent));
2320         ir_node *projs[pn_Load_max];
2321
2322         ia32_collect_Projs(env->irn, projs, pn_Load_max);
2323
2324         if (mode_is_float(mode)) {
2325                 FP_USED(env->cg);
2326                 if (USE_SSE2(env->cg)) {
2327                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
2328                         ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_xLoad_M);
2329                         ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_xLoad_res);
2330                 }
2331                 else {
2332                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
2333                         ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_vfld_M);
2334                         ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_vfld_res);
2335                 }
2336         }
2337         else {
2338                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
2339                 ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_Load_M);
2340                 ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_Load_res);
2341         }
2342
2343         set_ia32_frame_ent(new_op, ent);
2344         set_ia32_use_frame(new_op);
2345
2346         set_ia32_am_support(new_op, ia32_am_Source);
2347         set_ia32_op_type(new_op, ia32_AddrModeS);
2348         set_ia32_am_flavour(new_op, ia32_B);
2349         set_ia32_ls_mode(new_op, mode);
2350
2351         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2352
2353         return new_op;
2354 }
2355
2356
2357 /**
2358  * Transforms a FrameStore into an ia32 Store.
2359  */
2360 static ir_node *gen_be_FrameStore(ia32_transform_env_t *env) {
2361         ir_node *new_op = NULL;
2362         ir_node *node   = env->irn;
2363         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2364         ir_node *mem    = get_irn_n(node, 0);
2365         ir_node *ptr    = get_irn_n(node, 1);
2366         ir_node *val    = get_irn_n(node, 2);
2367         entity  *ent    = arch_get_frame_entity(env->cg->arch_env, node);
2368         ir_mode *mode   = get_irn_mode(val);
2369         ir_node *projs[pn_Store_max];
2370
2371         ia32_collect_Projs(env->irn, projs, pn_Store_max);
2372
2373         if (mode_is_float(mode)) {
2374                 FP_USED(env->cg);
2375                 if (USE_SSE2(env->cg)) {
2376                         new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2377                         ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_xStore_M);
2378                 }
2379                 else {
2380                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2381                         ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_vfst_M);
2382                 }
2383         }
2384         else if (get_mode_size_bits(mode) == 8) {
2385                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2386                 ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_Store8Bit_M);
2387         }
2388         else {
2389                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2390                 ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_Store_M);
2391         }
2392
2393         set_ia32_frame_ent(new_op, ent);
2394         set_ia32_use_frame(new_op);
2395
2396         set_ia32_am_support(new_op, ia32_am_Dest);
2397         set_ia32_op_type(new_op, ia32_AddrModeD);
2398         set_ia32_am_flavour(new_op, ia32_B);
2399         set_ia32_ls_mode(new_op, mode);
2400
2401         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2402
2403         return new_op;
2404 }
2405
2406 /**
2407  * In case SSE is used we need to copy the result from FPU TOS.
2408  */
2409 static ir_node *gen_be_Call(ia32_transform_env_t *env) {
2410         ir_node *call_res = get_proj_for_pn(env->irn, pn_be_Call_first_res);
2411         ir_node *call_mem = get_proj_for_pn(env->irn, pn_be_Call_M_regular);
2412         ir_mode *mode;
2413
2414         if (! call_res || ! USE_SSE2(env->cg))
2415                 return NULL;
2416
2417         mode = get_irn_mode(call_res);
2418
2419         /* in case there is no memory output: create one to serialize the copy FPU -> SSE */
2420         if (! call_mem)
2421                 call_mem = new_r_Proj(env->irg, env->block, env->irn, mode_M, pn_be_Call_M_regular);
2422
2423         if (mode_is_float(mode)) {
2424                 /* store st(0) onto stack */
2425                 ir_node *frame = get_irg_frame(env->irg);
2426                 ir_node *fstp  = new_rd_ia32_GetST0(env->dbg, env->irg, env->block, frame, call_mem);
2427                 ir_node *mproj = new_r_Proj(env->irg, env->block, fstp, mode_M, pn_ia32_GetST0_M);
2428                 entity  *ent   = frame_alloc_area(get_irg_frame_type(env->irg), get_mode_size_bytes(mode), 16, 0);
2429                 ir_node *sse_load, *p, *bad, *keep;
2430                 ir_node **in_keep;
2431                 int     keep_arity, i;
2432
2433                 set_ia32_ls_mode(fstp, mode);
2434                 set_ia32_op_type(fstp, ia32_AddrModeD);
2435                 set_ia32_use_frame(fstp);
2436                 set_ia32_frame_ent(fstp, ent);
2437                 set_ia32_am_flavour(fstp, ia32_B);
2438                 set_ia32_am_support(fstp, ia32_am_Dest);
2439
2440                 /* load into SSE register */
2441                 sse_load = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, frame, ia32_new_NoReg_gp(env->cg), mproj);
2442                 set_ia32_ls_mode(sse_load, mode);
2443                 set_ia32_op_type(sse_load, ia32_AddrModeS);
2444                 set_ia32_use_frame(sse_load);
2445                 set_ia32_frame_ent(sse_load, ent);
2446                 set_ia32_am_flavour(sse_load, ia32_B);
2447                 set_ia32_am_support(sse_load, ia32_am_Source);
2448                 sse_load = new_r_Proj(env->irg, env->block, sse_load, mode, pn_ia32_xLoad_res);
2449
2450                 /* reroute all users of the result proj to the sse load */
2451                 edges_reroute(call_res, sse_load, env->irg);
2452
2453                 /* now: create new Keep whith all former ins and one additional in - the result Proj */
2454
2455                 /* get a Proj representing a caller save register */
2456                 p = get_proj_for_pn(env->irn, pn_be_Call_first_res + 1);
2457                 assert(is_Proj(p) && "Proj expected.");
2458
2459                 /* user of the the proj is the Keep */
2460                 p = get_edge_src_irn(get_irn_out_edge_first(p));
2461                 assert(be_is_Keep(p) && "Keep expected.");
2462
2463                 /* copy in array of the old keep and set the result proj as additional in */
2464                 keep_arity = get_irn_arity(p) + 1;
2465                 NEW_ARR_A(ir_node *, in_keep, keep_arity);
2466                 in_keep[keep_arity - 1] = call_res;
2467                 for (i = 0; i < keep_arity - 1; ++i)
2468                         in_keep[i] = get_irn_n(p, i);
2469
2470                 /* create new keep and set the in class requirements properly */
2471                 keep = be_new_Keep(NULL, env->irg, env->block, keep_arity, in_keep);
2472                 for(i = 0; i < keep_arity; ++i) {
2473                         const arch_register_class_t *cls = arch_get_irn_reg_class(env->cg->arch_env, in_keep[i], -1);
2474                         be_node_set_reg_class(keep, i, cls);
2475                 }
2476
2477                 /* kill the old keep */
2478                 bad = get_irg_bad(env->irg);
2479                 for (i = 0; i < keep_arity - 1; i++)
2480                         set_irn_n(p, i, bad);
2481                 remove_End_keepalive(get_irg_end(env->irg), p);
2482         }
2483
2484         return NULL;
2485 }
2486
2487 /**
2488  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
2489  */
2490 static ir_node *gen_be_Return(ia32_transform_env_t *env) {
2491         ir_node *ret_val = get_irn_n(env->irn, be_pos_Return_val);
2492         ir_node *ret_mem = get_irn_n(env->irn, be_pos_Return_mem);
2493         entity *ent      = get_irg_entity(get_irn_irg(ret_val));
2494         ir_type *tp      = get_entity_type(ent);
2495
2496         if (be_Return_get_n_rets(env->irn) < 1 || ! ret_val || ! USE_SSE2(env->cg))
2497                 return NULL;
2498
2499         if (get_method_n_ress(tp) == 1) {
2500                 ir_type *res_type = get_method_res_type(tp, 0);
2501                 ir_mode *mode;
2502
2503                 if (is_Primitive_type(res_type)) {
2504                         mode = get_type_mode(res_type);
2505                         if (mode_is_float(mode)) {
2506                                 ir_node *frame;
2507                                 entity  *ent;
2508                                 ir_node *sse_store, *fld, *mproj, *barrier;
2509                                 int     pn_ret_val = get_Proj_proj(ret_val);
2510                                 int     pn_ret_mem = get_Proj_proj(ret_mem);
2511
2512                                 /* get the Barrier */
2513                                 barrier = get_Proj_pred(ret_val);
2514
2515                                 /* get result input of the Barrier */
2516                                 ret_val = get_irn_n(barrier, pn_ret_val);
2517
2518                                 /* get memory input of the Barrier */
2519                                 ret_mem = get_irn_n(barrier, pn_ret_mem);
2520
2521                                 frame = get_irg_frame(env->irg);
2522                                 ent   = frame_alloc_area(get_irg_frame_type(env->irg), get_mode_size_bytes(mode), 16, 0);
2523
2524                                 /* store xmm0 onto stack */
2525                                 sse_store = new_rd_ia32_xStoreSimple(env->dbg, env->irg, env->block, frame, ret_val, ret_mem);
2526                                 set_ia32_ls_mode(sse_store, mode);
2527                                 set_ia32_op_type(sse_store, ia32_AddrModeD);
2528                                 set_ia32_use_frame(sse_store);
2529                                 set_ia32_frame_ent(sse_store, ent);
2530                                 set_ia32_am_flavour(sse_store, ia32_B);
2531                                 set_ia32_am_support(sse_store, ia32_am_Dest);
2532                                 sse_store = new_r_Proj(env->irg, env->block, sse_store, mode_M, pn_ia32_xStore_M);
2533
2534                                 /* load into st0 */
2535                                 fld = new_rd_ia32_SetST0(env->dbg, env->irg, env->block, frame, sse_store);
2536                                 set_ia32_ls_mode(fld, mode);
2537                                 set_ia32_op_type(fld, ia32_AddrModeS);
2538                                 set_ia32_use_frame(fld);
2539                                 set_ia32_frame_ent(fld, ent);
2540                                 set_ia32_am_flavour(fld, ia32_B);
2541                                 set_ia32_am_support(fld, ia32_am_Source);
2542                                 mproj = new_r_Proj(env->irg, env->block, fld, mode_M, pn_ia32_SetST0_M);
2543                                 fld   = new_r_Proj(env->irg, env->block, fld, mode, pn_ia32_SetST0_res);
2544                                 arch_set_irn_register(env->cg->arch_env, fld, &ia32_vfp_regs[REG_VF0]);
2545
2546                                 /* set new return value */
2547                                 set_irn_n(barrier, pn_ret_val, fld);
2548                                 set_irn_n(barrier, pn_ret_mem, mproj);
2549                         }
2550                 }
2551         }
2552
2553         return NULL;
2554 }
2555
2556 /**
2557  * Transform a be_AddSP into an ia32_AddSP. Eat up const sizes.
2558  */
2559 static ir_node *gen_be_AddSP(ia32_transform_env_t *env) {
2560         ir_node *new_op;
2561         const ir_edge_t *edge;
2562         ir_node *sz = get_irn_n(env->irn, be_pos_AddSP_size);
2563         ir_node *sp = get_irn_n(env->irn, be_pos_AddSP_old_sp);
2564
2565         new_op = new_rd_ia32_AddSP(env->dbg, env->irg, env->block, sp, sz);
2566
2567         if (is_ia32_Const(sz)) {
2568                 set_ia32_Immop_attr(new_op, sz);
2569                 set_irn_n(new_op, 1, ia32_new_NoReg_gp(env->cg));
2570         }
2571         else if (is_ia32_Load(sz) && get_ia32_am_flavour(sz) == ia32_O) {
2572                 set_ia32_immop_type(new_op, ia32_ImmSymConst);
2573                 set_ia32_op_type(new_op, ia32_AddrModeS);
2574                 set_ia32_am_sc(new_op, get_ia32_am_sc(sz));
2575                 add_ia32_am_offs(new_op, get_ia32_am_offs(sz));
2576                 set_irn_n(new_op, 1, ia32_new_NoReg_gp(env->cg));
2577         }
2578
2579         /* fix proj nums */
2580         foreach_out_edge(env->irn, edge) {
2581                 ir_node *proj = get_edge_src_irn(edge);
2582
2583                 assert(is_Proj(proj));
2584
2585                 if (get_Proj_proj(proj) == pn_be_AddSP_res) {
2586                         /* the node is not yet exchanged: we need to set the register manually */
2587                         ia32_attr_t *attr = get_ia32_attr(new_op);
2588                         attr->slots[pn_ia32_AddSP_stack] = &ia32_gp_regs[REG_ESP];
2589                         set_Proj_proj(proj, pn_ia32_AddSP_stack);
2590                 }
2591                 else if (get_Proj_proj(proj) == pn_be_AddSP_M) {
2592                         set_Proj_proj(proj, pn_ia32_AddSP_M);
2593                 }
2594                 else {
2595                         assert(0);
2596                 }
2597         }
2598
2599         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2600
2601         return new_op;
2602 }
2603
2604 /**
2605  * Transform a be_SubSP into an ia32_SubSP. Eat up const sizes.
2606  */
2607 static ir_node *gen_be_SubSP(ia32_transform_env_t *env) {
2608         ir_node *new_op;
2609         const ir_edge_t *edge;
2610         ir_node *sz = get_irn_n(env->irn, be_pos_SubSP_size);
2611         ir_node *sp = get_irn_n(env->irn, be_pos_SubSP_old_sp);
2612
2613         new_op = new_rd_ia32_SubSP(env->dbg, env->irg, env->block, sp, sz);
2614
2615         if (is_ia32_Const(sz)) {
2616                 set_ia32_Immop_attr(new_op, sz);
2617                 set_irn_n(new_op, 1, ia32_new_NoReg_gp(env->cg));
2618         }
2619         else if (is_ia32_Load(sz) && get_ia32_am_flavour(sz) == ia32_O) {
2620                 set_ia32_immop_type(new_op, ia32_ImmSymConst);
2621                 set_ia32_op_type(new_op, ia32_AddrModeS);
2622                 set_ia32_am_sc(new_op, get_ia32_am_sc(sz));
2623                 add_ia32_am_offs(new_op, get_ia32_am_offs(sz));
2624                 set_irn_n(new_op, 1, ia32_new_NoReg_gp(env->cg));
2625         }
2626
2627         /* fix proj nums */
2628         foreach_out_edge(env->irn, edge) {
2629                 ir_node *proj = get_edge_src_irn(edge);
2630
2631                 assert(is_Proj(proj));
2632
2633                 if (get_Proj_proj(proj) == pn_be_SubSP_res) {
2634                         /* the node is not yet exchanged: we need to set the register manually */
2635                         ia32_attr_t *attr = get_ia32_attr(new_op);
2636                         attr->slots[pn_ia32_SubSP_stack] = &ia32_gp_regs[REG_ESP];
2637                         set_Proj_proj(proj, pn_ia32_SubSP_stack);
2638                 }
2639                 else if (get_Proj_proj(proj) == pn_be_SubSP_M) {
2640                         set_Proj_proj(proj, pn_ia32_SubSP_M);
2641                 }
2642                 else {
2643                         assert(0);
2644                 }
2645         }
2646
2647         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2648
2649         return new_op;
2650 }
2651
2652 /**
2653  * This function just sets the register for the Unknown node
2654  * as this is not done during register allocation because Unknown
2655  * is an "ignore" node.
2656  */
2657 static ir_node *gen_Unknown(ia32_transform_env_t *env) {
2658         ir_mode *mode = env->mode;
2659         ir_node *irn  = env->irn;
2660
2661         if (mode_is_float(mode)) {
2662                 if (USE_SSE2(env->cg))
2663                         arch_set_irn_register(env->cg->arch_env, irn, &ia32_xmm_regs[REG_XMM_UKNWN]);
2664                 else
2665                         arch_set_irn_register(env->cg->arch_env, irn, &ia32_vfp_regs[REG_VFP_UKNWN]);
2666         }
2667         else if (mode_is_int(mode) || mode_is_reference(mode) || mode_is_character(mode)) {
2668                 arch_set_irn_register(env->cg->arch_env, irn, &ia32_gp_regs[REG_GP_UKNWN]);
2669         }
2670         else {
2671                 assert(0 && "unsupported Unknown-Mode");
2672         }
2673
2674         return NULL;
2675 }
2676
2677 /**********************************************************************
2678  *  _                                _                   _
2679  * | |                              | |                 | |
2680  * | | _____      _____ _ __ ___  __| |  _ __   ___   __| | ___  ___
2681  * | |/ _ \ \ /\ / / _ \ '__/ _ \/ _` | | '_ \ / _ \ / _` |/ _ \/ __|
2682  * | | (_) \ V  V /  __/ | |  __/ (_| | | | | | (_) | (_| |  __/\__ \
2683  * |_|\___/ \_/\_/ \___|_|  \___|\__,_| |_| |_|\___/ \__,_|\___||___/
2684  *
2685  **********************************************************************/
2686
2687 /* These nodes are created in intrinsic lowering (64bit -> 32bit) */
2688
2689 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
2690                                      ir_node *mem);
2691
2692 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
2693                                       ir_node *val, ir_node *mem);
2694
2695 /**
2696  * Transforms a lowered Load into a "real" one.
2697  */
2698 static ir_node *gen_lowered_Load(ia32_transform_env_t *env, construct_load_func func, char fp_unit) {
2699         ir_node *node  = env->irn;
2700         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
2701         ir_mode *mode  = get_ia32_ls_mode(node);
2702         ir_node *new_op;
2703         char    *am_offs;
2704         ia32_am_flavour_t am_flav = ia32_B;
2705
2706         /*
2707                 Could be that we have SSE2 unit, but due to 64Bit Div/Conv
2708                 lowering we have x87 nodes, so we need to enforce simulation.
2709         */
2710         if (mode_is_float(mode)) {
2711                 FP_USED(env->cg);
2712                 if (fp_unit == fp_x87)
2713                         FORCE_x87(env->cg);
2714         }
2715
2716         new_op  = func(env->dbg, env->irg, env->block, get_irn_n(node, 0), noreg, get_irn_n(node, 1));
2717         am_offs = get_ia32_am_offs(node);
2718
2719         if (am_offs) {
2720                 am_flav |= ia32_O;
2721                 add_ia32_am_offs(new_op, am_offs);
2722         }
2723
2724         set_ia32_am_support(new_op, ia32_am_Source);
2725         set_ia32_op_type(new_op, ia32_AddrModeS);
2726         set_ia32_am_flavour(new_op, am_flav);
2727         set_ia32_ls_mode(new_op, mode);
2728         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
2729         set_ia32_use_frame(new_op);
2730
2731         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2732
2733         return new_op;
2734 }
2735
2736 /**
2737 * Transforms a lowered Store into a "real" one.
2738 */
2739 static ir_node *gen_lowered_Store(ia32_transform_env_t *env, construct_store_func func, char fp_unit) {
2740         ir_node *node  = env->irn;
2741         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
2742         ir_mode *mode  = get_ia32_ls_mode(node);
2743         ir_node *new_op;
2744         char    *am_offs;
2745         ia32_am_flavour_t am_flav = ia32_B;
2746
2747         /*
2748                 Could be that we have SSE2 unit, but due to 64Bit Div/Conv
2749                 lowering we have x87 nodes, so we need to enforce simulation.
2750         */
2751         if (mode_is_float(mode)) {
2752                 FP_USED(env->cg);
2753                 if (fp_unit == fp_x87)
2754                         FORCE_x87(env->cg);
2755         }
2756
2757         new_op = func(env->dbg, env->irg, env->block, get_irn_n(node, 0), noreg, get_irn_n(node, 1), get_irn_n(node, 2));
2758
2759         if ((am_offs = get_ia32_am_offs(node)) != NULL) {
2760                 am_flav |= ia32_O;
2761                 add_ia32_am_offs(new_op, am_offs);
2762         }
2763
2764         set_ia32_am_support(new_op, ia32_am_Dest);
2765         set_ia32_op_type(new_op, ia32_AddrModeD);
2766         set_ia32_am_flavour(new_op, am_flav);
2767         set_ia32_ls_mode(new_op, mode);
2768         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
2769         set_ia32_use_frame(new_op);
2770
2771         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2772
2773         return new_op;
2774 }
2775
2776
2777 /**
2778  * Transforms an ia32_l_XXX into a "real" XXX node
2779  *
2780  * @param env   The transformation environment
2781  * @return the created ia32 XXX node
2782  */
2783 #define GEN_LOWERED_OP(op)                                                                            \
2784         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                      \
2785                 if (mode_is_float(env->mode))                                                                 \
2786                         FP_USED(env->cg);                                                                         \
2787                 return gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2788         }
2789
2790 #define GEN_LOWERED_x87_OP(op)                                                                          \
2791         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                        \
2792                 ir_node *new_op;                                                                                \
2793                 FORCE_x87(env->cg);                                                                             \
2794                 new_op = gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2795                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_None);                                       \
2796                 return new_op;                                                                                  \
2797         }
2798
2799 #define GEN_LOWERED_UNOP(op)                                           \
2800         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {       \
2801                 return gen_unop(env, get_unop_op(env->irn), new_rd_ia32_##op); \
2802         }
2803
2804 #define GEN_LOWERED_SHIFT_OP(op)                                                                            \
2805         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                            \
2806                 return gen_shift_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2807         }
2808
2809 #define GEN_LOWERED_LOAD(op, fp_unit)                            \
2810         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) { \
2811                 return gen_lowered_Load(env, new_rd_ia32_##op, fp_unit); \
2812         }
2813
2814 #define GEN_LOWERED_STORE(op, fp_unit)                           \
2815         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) { \
2816         return gen_lowered_Store(env, new_rd_ia32_##op, fp_unit);    \
2817 }
2818
2819 GEN_LOWERED_OP(AddC)
2820 GEN_LOWERED_OP(Add)
2821 GEN_LOWERED_OP(SubC)
2822 GEN_LOWERED_OP(Sub)
2823 GEN_LOWERED_OP(Mul)
2824 GEN_LOWERED_OP(Eor)
2825 GEN_LOWERED_x87_OP(vfdiv)
2826 GEN_LOWERED_x87_OP(vfmul)
2827 GEN_LOWERED_x87_OP(vfsub)
2828
2829 GEN_LOWERED_UNOP(Minus)
2830
2831 GEN_LOWERED_LOAD(vfild, fp_x87)
2832 GEN_LOWERED_LOAD(Load, fp_none)
2833 GEN_LOWERED_STORE(vfist, fp_x87)
2834 GEN_LOWERED_STORE(Store, fp_none)
2835
2836 /**
2837  * Transforms a l_MulS into a "real" MulS node.
2838  *
2839  * @param env   The transformation environment
2840  * @return the created ia32 MulS node
2841  */
2842 static ir_node *gen_ia32_l_MulS(ia32_transform_env_t *env) {
2843
2844         /* l_MulS is already a mode_T node, so we create the MulS in the normal way   */
2845         /* and then skip the result Proj, because all needed Projs are already there. */
2846
2847         ir_node *new_op = gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_MulS);
2848         ir_node *muls   = get_Proj_pred(new_op);
2849
2850         /* MulS cannot have AM for destination */
2851         if (get_ia32_am_support(muls) != ia32_am_None)
2852                 set_ia32_am_support(muls, ia32_am_Source);
2853
2854         return muls;
2855 }
2856
2857 GEN_LOWERED_SHIFT_OP(Shl)
2858 GEN_LOWERED_SHIFT_OP(Shr)
2859 GEN_LOWERED_SHIFT_OP(Shrs)
2860
2861 /**
2862  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
2863  * op1 - target to be shifted
2864  * op2 - contains bits to be shifted into target
2865  * op3 - shift count
2866  * Only op3 can be an immediate.
2867  */
2868 static ir_node *gen_lowered_64bit_shifts(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, ir_node *count) {
2869         ir_node           *new_op = NULL;
2870         ir_mode           *mode   = env->mode;
2871         dbg_info          *dbg    = env->dbg;
2872         ir_graph          *irg    = env->irg;
2873         ir_node           *block  = env->block;
2874         ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
2875         ir_node           *nomem  = new_NoMem();
2876         ir_node           *imm_op;
2877         tarval            *tv;
2878         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
2879
2880         assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");
2881
2882         /* Check if immediate optimization is on and */
2883         /* if it's an operation with immediate.      */
2884         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, count) : NULL;
2885
2886         /* Limit imm_op within range imm8 */
2887         if (imm_op) {
2888                 tv = get_ia32_Immop_tarval(imm_op);
2889
2890                 if (tv) {
2891                         tv = tarval_mod(tv, new_tarval_from_long(32, mode_Iu));
2892                         set_ia32_Immop_tarval(imm_op, tv);
2893                 }
2894                 else {
2895                         imm_op = NULL;
2896                 }
2897         }
2898
2899         /* integer operations */
2900         if (imm_op) {
2901                 /* This is ShiftD with const */
2902                 DB((mod, LEVEL_1, "ShiftD with immediate ..."));
2903
2904                 if (is_ia32_l_ShlD(env->irn))
2905                         new_op = new_rd_ia32_ShlD(dbg, irg, block, noreg, noreg, op1, op2, noreg, nomem);
2906                 else
2907                         new_op = new_rd_ia32_ShrD(dbg, irg, block, noreg, noreg, op1, op2, noreg, nomem);
2908                 set_ia32_Immop_attr(new_op, imm_op);
2909         }
2910         else {
2911                 /* This is a normal ShiftD */
2912                 DB((mod, LEVEL_1, "ShiftD binop ..."));
2913                 if (is_ia32_l_ShlD(env->irn))
2914                         new_op = new_rd_ia32_ShlD(dbg, irg, block, noreg, noreg, op1, op2, count, nomem);
2915                 else
2916                         new_op = new_rd_ia32_ShrD(dbg, irg, block, noreg, noreg, op1, op2, count, nomem);
2917         }
2918
2919         /* set AM support */
2920         set_ia32_am_support(new_op, ia32_am_Dest);
2921
2922         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2923
2924         set_ia32_res_mode(new_op, mode);
2925         set_ia32_emit_cl(new_op);
2926
2927         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
2928 }
2929
2930 static ir_node *gen_ia32_l_ShlD(ia32_transform_env_t *env) {
2931         return gen_lowered_64bit_shifts(env, get_irn_n(env->irn, 0), get_irn_n(env->irn, 1), get_irn_n(env->irn, 2));
2932 }
2933
2934 static ir_node *gen_ia32_l_ShrD(ia32_transform_env_t *env) {
2935         return gen_lowered_64bit_shifts(env, get_irn_n(env->irn, 0), get_irn_n(env->irn, 1), get_irn_n(env->irn, 2));
2936 }
2937
2938 /**
2939  * In case SSE Unit is used, the node is transformed into a vfst + xLoad.
2940  */
2941 static ir_node *gen_ia32_l_X87toSSE(ia32_transform_env_t *env) {
2942         ia32_code_gen_t *cg  = env->cg;
2943         ir_node         *res = NULL;
2944         ir_node         *ptr = get_irn_n(env->irn, 0);
2945         ir_node         *val = get_irn_n(env->irn, 1);
2946         ir_node         *mem = get_irn_n(env->irn, 2);
2947
2948         if (USE_SSE2(cg)) {
2949                 ir_node *noreg = ia32_new_NoReg_gp(cg);
2950
2951                 /* Store x87 -> MEM */
2952                 res = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2953                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
2954                 set_ia32_use_frame(res);
2955                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
2956                 set_ia32_am_support(res, ia32_am_Dest);
2957                 set_ia32_am_flavour(res, ia32_B);
2958                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_vfst_M);
2959
2960                 /* Load MEM -> SSE */
2961                 res = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, res);
2962                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
2963                 set_ia32_use_frame(res);
2964                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
2965                 set_ia32_am_support(res, ia32_am_Source);
2966                 set_ia32_am_flavour(res, ia32_B);
2967                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, get_ia32_ls_mode(env->irn), pn_ia32_xLoad_res);
2968         }
2969         else {
2970                 /* SSE unit is not used -> skip this node. */
2971                 int i;
2972
2973                 edges_reroute(env->irn, val, env->irg);
2974                 for (i = get_irn_arity(env->irn) - 1; i >= 0; i--)
2975                         set_irn_n(env->irn, i, get_irg_bad(env->irg));
2976         }
2977
2978         return res;
2979 }
2980
2981 /**
2982  * In case SSE Unit is used, the node is transformed into a xStore + vfld.
2983  */
2984 static ir_node *gen_ia32_l_SSEtoX87(ia32_transform_env_t *env) {
2985         ia32_code_gen_t *cg  = env->cg;
2986         ir_node         *res = NULL;
2987         ir_node         *ptr = get_irn_n(env->irn, 0);
2988         ir_node         *val = get_irn_n(env->irn, 1);
2989         ir_node         *mem = get_irn_n(env->irn, 2);
2990
2991         if (USE_SSE2(cg)) {
2992                 ir_node *noreg = ia32_new_NoReg_gp(cg);
2993
2994                 /* Store SSE -> MEM */
2995                 res = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2996                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
2997                 set_ia32_use_frame(res);
2998                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
2999                 set_ia32_am_support(res, ia32_am_Dest);
3000                 set_ia32_am_flavour(res, ia32_B);
3001                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_xStore_M);
3002
3003                 /* Load MEM -> x87 */
3004                 res = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
3005                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
3006                 set_ia32_use_frame(res);
3007                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
3008                 set_ia32_am_support(res, ia32_am_Source);
3009                 set_ia32_am_flavour(res, ia32_B);
3010                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, get_ia32_ls_mode(env->irn), pn_ia32_vfld_res);
3011         }
3012         else {
3013                 /* SSE unit is not used -> skip this node. */
3014                 int i;
3015
3016                 edges_reroute(env->irn, val, env->irg);
3017                 for (i = get_irn_arity(env->irn) - 1; i >= 0; i--)
3018                         set_irn_n(env->irn, i, get_irg_bad(env->irg));
3019         }
3020
3021         return res;
3022 }
3023
3024 /*********************************************************
3025  *                  _             _      _
3026  *                 (_)           | |    (_)
3027  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
3028  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
3029  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
3030  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
3031  *
3032  *********************************************************/
3033
3034 /**
3035  * the BAD transformer.
3036  */
3037 static ir_node *bad_transform(ia32_transform_env_t *env) {
3038         ir_fprintf(stderr, "Not implemented: %+F\n", env->irn);
3039         assert(0);
3040         return NULL;
3041 }
3042
3043 /**
3044  * Enters all transform functions into the generic pointer
3045  */
3046 void ia32_register_transformers(void) {
3047         ir_op *op_Max, *op_Min, *op_Mulh;
3048
3049         /* first clear the generic function pointer for all ops */
3050         clear_irp_opcodes_generic_func();
3051
3052 #define GEN(a)   op_##a->ops.generic = (op_func)gen_##a
3053 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
3054 #define IGN(a)
3055
3056         GEN(Add);
3057         GEN(Sub);
3058         GEN(Mul);
3059         GEN(And);
3060         GEN(Or);
3061         GEN(Eor);
3062
3063         GEN(Shl);
3064         GEN(Shr);
3065         GEN(Shrs);
3066         GEN(Rot);
3067
3068         GEN(Quot);
3069
3070         GEN(Div);
3071         GEN(Mod);
3072         GEN(DivMod);
3073
3074         GEN(Minus);
3075         GEN(Conv);
3076         GEN(Abs);
3077         GEN(Not);
3078
3079         GEN(Load);
3080         GEN(Store);
3081         GEN(Cond);
3082
3083         GEN(CopyB);
3084         GEN(Mux);
3085         GEN(Psi);
3086
3087         /* transform ops from intrinsic lowering */
3088         GEN(ia32_l_Add);
3089         GEN(ia32_l_AddC);
3090         GEN(ia32_l_Sub);
3091         GEN(ia32_l_SubC);
3092         GEN(ia32_l_Minus);
3093         GEN(ia32_l_Mul);
3094         GEN(ia32_l_Eor);
3095         GEN(ia32_l_MulS);
3096         GEN(ia32_l_Shl);
3097         GEN(ia32_l_Shr);
3098         GEN(ia32_l_Shrs);
3099         GEN(ia32_l_ShlD);
3100         GEN(ia32_l_ShrD);
3101         GEN(ia32_l_vfdiv);
3102         GEN(ia32_l_vfmul);
3103         GEN(ia32_l_vfsub);
3104         GEN(ia32_l_vfild);
3105         GEN(ia32_l_Load);
3106         GEN(ia32_l_vfist);
3107         GEN(ia32_l_Store);
3108         GEN(ia32_l_X87toSSE);
3109         GEN(ia32_l_SSEtoX87);
3110
3111         IGN(Call);
3112         IGN(Alloc);
3113
3114         IGN(Proj);
3115         IGN(Block);
3116         IGN(Start);
3117         IGN(End);
3118         IGN(NoMem);
3119         IGN(Phi);
3120         IGN(IJmp);
3121         IGN(Break);
3122         IGN(Cmp);
3123
3124         /* constant transformation happens earlier */
3125         IGN(Const);
3126         IGN(SymConst);
3127         IGN(Sync);
3128
3129         /* we should never see these nodes */
3130         BAD(Raise);
3131         BAD(Sel);
3132         BAD(InstOf);
3133         BAD(Cast);
3134         BAD(Free);
3135         BAD(Tuple);
3136         BAD(Id);
3137         BAD(Bad);
3138         BAD(Confirm);
3139         BAD(Filter);
3140         BAD(CallBegin);
3141         BAD(EndReg);
3142         BAD(EndExcept);
3143
3144         /* handle generic backend nodes */
3145         GEN(be_FrameAddr);
3146         GEN(be_Call);
3147         GEN(be_Return);
3148         GEN(be_FrameLoad);
3149         GEN(be_FrameStore);
3150         GEN(be_StackParam);
3151         GEN(be_AddSP);
3152         GEN(be_SubSP);
3153
3154         /* set the register for all Unknown nodes */
3155         GEN(Unknown);
3156
3157         op_Max = get_op_Max();
3158         if (op_Max)
3159                 GEN(Max);
3160         op_Min = get_op_Min();
3161         if (op_Min)
3162                 GEN(Min);
3163         op_Mulh = get_op_Mulh();
3164         if (op_Mulh)
3165                 GEN(Mulh);
3166
3167 #undef GEN
3168 #undef BAD
3169 #undef IGN
3170 }
3171
3172 typedef ir_node *(transform_func)(ia32_transform_env_t *env);
3173
3174 /**
3175  * Transforms the given firm node (and maybe some other related nodes)
3176  * into one or more assembler nodes.
3177  *
3178  * @param node    the firm node
3179  * @param env     the debug module
3180  */
3181 void ia32_transform_node(ir_node *node, void *env) {
3182         ia32_code_gen_t *cg = (ia32_code_gen_t *)env;
3183         ir_op *op           = get_irn_op(node);
3184         ir_node *asm_node   = NULL;
3185         int i;
3186
3187         if (is_Block(node))
3188                 return;
3189
3190         /* link arguments pointing to Unknown to the UNKNOWN Proj */
3191         for (i = get_irn_arity(node) - 1; i >= 0; i--) {
3192                 if (is_Unknown(get_irn_n(node, i)))
3193                         set_irn_n(node, i, be_get_unknown_for_mode(cg, get_irn_mode(get_irn_n(node, i))));
3194         }
3195
3196         DBG((cg->mod, LEVEL_1, "check %+F ... ", node));
3197         if (op->ops.generic) {
3198                 ia32_transform_env_t  tenv;
3199                 transform_func *transform = (transform_func *)op->ops.generic;
3200
3201                 tenv.block = get_nodes_block(node);
3202                 tenv.dbg   = get_irn_dbg_info(node);
3203                 tenv.irg   = current_ir_graph;
3204                 tenv.irn   = node;
3205                 tenv.mode  = get_irn_mode(node);
3206                 tenv.cg    = cg;
3207                 DEBUG_ONLY(tenv.mod = cg->mod;)
3208
3209                 asm_node = (*transform)(&tenv);
3210         }
3211
3212         /* exchange nodes if a new one was generated */
3213         if (asm_node) {
3214                 exchange(node, asm_node);
3215                 DB((cg->mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
3216         }
3217         else {
3218                 DB((cg->mod, LEVEL_1, "ignored\n"));
3219         }
3220 }
3221
3222 /**
3223  * Transforms a psi condition.
3224  */
3225 static void transform_psi_cond(ir_node *cond, ir_mode *mode, ia32_code_gen_t *cg) {
3226         int i;
3227
3228         /* if the mode is target mode, we have already seen this part of the tree */
3229         if (get_irn_mode(cond) == mode)
3230                 return;
3231
3232         assert(get_irn_mode(cond) == mode_b && "logical operator for condition must be mode_b");
3233
3234         set_irn_mode(cond, mode);
3235
3236         for (i = get_irn_arity(cond) - 1; i >= 0; i--) {
3237                 ir_node *in = get_irn_n(cond, i);
3238
3239                 /* if in is a compare: transform into Set/xCmp */
3240                 if (is_Proj(in)) {
3241                         ir_node  *new_op = NULL;
3242                         ir_node  *cmp    = get_Proj_pred(in);
3243                         ir_node  *cmp_a  = get_Cmp_left(cmp);
3244                         ir_node  *cmp_b  = get_Cmp_right(cmp);
3245                         dbg_info *dbg    = get_irn_dbg_info(cmp);
3246                         ir_graph *irg    = get_irn_irg(cmp);
3247                         ir_node  *block  = get_nodes_block(cmp);
3248                         ir_node  *noreg  = ia32_new_NoReg_gp(cg);
3249                         ir_node  *nomem  = new_rd_NoMem(irg);
3250                         int      pnc     = get_Proj_proj(in);
3251
3252                         /* this is a compare */
3253                         if (mode_is_float(mode)) {
3254                                 /* Psi is float, we need a floating point compare */
3255
3256                                 if (USE_SSE2(cg)) {
3257                                         ir_mode *m = get_irn_mode(cmp_a);
3258                                         /* SSE FPU */
3259                                         if (! mode_is_float(m)) {
3260                                                 cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_a, cmp_a, mode);
3261                                                 cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_b, cmp_b, mode);
3262                                         }
3263                                         else if (m == mode_F) {
3264                                                 /* we convert cmp values always to double, to get correct bitmask with cmpsd */
3265                                                 cmp_a = gen_sse_conv_f2d(cg, dbg, irg, block, cmp_a, cmp_a);
3266                                                 cmp_b = gen_sse_conv_f2d(cg, dbg, irg, block, cmp_b, cmp_b);
3267                                         }
3268
3269                                         new_op = new_rd_ia32_xCmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
3270                                         set_ia32_pncode(new_op, pnc);
3271                                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, cmp));
3272                                 }
3273                                 else {
3274                                         /* x87 FPU */
3275                                         assert(0);
3276                                 }
3277                         }
3278                         else {
3279                                 /* integer Psi */
3280                                 ia32_transform_env_t tenv;
3281                                 construct_binop_func *set_func  = NULL;
3282
3283                                 if (mode_is_float(get_irn_mode(cmp_a))) {
3284                                         /* 1st case: compare operands are floats */
3285                                         FP_USED(cg);
3286
3287                                         if (USE_SSE2(cg)) {
3288                                                 /* SSE FPU */
3289                                                 set_func  = new_rd_ia32_xCmpSet;
3290                                         }
3291                                         else {
3292                                                 /* x87 FPU */
3293                                                 set_func  = new_rd_ia32_vfCmpSet;
3294                                         }
3295
3296                                         pnc &= 7; /* fp compare -> int compare */
3297                                 }
3298                                 else {
3299                                         /* 2nd case: compare operand are integer too */
3300                                         set_func  = new_rd_ia32_CmpSet;
3301                                 }
3302
3303                                 tenv.block = block;
3304                                 tenv.cg    = cg;
3305                                 tenv.dbg   = dbg;
3306                                 tenv.irg   = irg;
3307                                 tenv.irn   = cmp;
3308                                 tenv.mode  = mode;
3309                                 tenv.mod   = cg->mod;
3310
3311                                 new_op = gen_binop(&tenv, cmp_a, cmp_b, set_func);
3312                                 set_ia32_pncode(get_Proj_pred(new_op), pnc);
3313                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
3314                         }
3315
3316                         /* the the new compare as in */
3317                         set_irn_n(cond, i, new_op);
3318                 }
3319                 else {
3320                         /* another complex condition */
3321                         transform_psi_cond(in, mode, cg);
3322                 }
3323         }
3324 }
3325
3326 /**
3327  * The Psi selector can be a tree of compares combined with "And"s and "Or"s.
3328  * We create a Set node, respectively a xCmp in case the Psi is a float, for each
3329  * compare, which causes the compare result to be stores in a register.  The
3330  * "And"s and "Or"s are transformed later, we just have to set their mode right.
3331  */
3332 void ia32_transform_psi_cond_tree(ir_node *node, void *env) {
3333         ia32_code_gen_t *cg = env;
3334         ir_node         *psi_sel, *new_cmp, *block;
3335         ir_graph        *irg;
3336         ir_mode         *mode;
3337
3338         /* check for Psi */
3339         if (get_irn_opcode(node) != iro_Psi)
3340                 return;
3341
3342         psi_sel = get_Psi_cond(node, 0);
3343
3344         /* if psi_cond is a cmp: do nothing, this case is covered by gen_Psi */
3345         if (is_Proj(psi_sel))
3346                 return;
3347
3348         //mode = get_irn_mode(node);
3349         mode = mode_Iu;
3350
3351         transform_psi_cond(psi_sel, mode, cg);
3352
3353         irg   = get_irn_irg(node);
3354         block = get_nodes_block(node);
3355
3356         /* we need to compare the evaluated condition tree with 0 */
3357         mode  = get_irn_mode(node);
3358         if (mode_is_float(mode)) {
3359                 psi_sel = gen_sse_conv_int2float(cg, NULL, irg, block, psi_sel, NULL, mode);
3360                 /* BEWARE: new_r_Const_long works for floating point as well */
3361                 new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode, 0));
3362                 new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Ne);
3363         }
3364         else {
3365                 new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode_Iu, 0));
3366                 new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Gt | pn_Cmp_Lt);
3367         }
3368
3369         set_Psi_cond(node, 0, new_cmp);
3370 }