- Improved addressmode optimisation for conv nodes
[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, get_tarval_mode(tv)));
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) && tv && (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 && (get_ia32_op_type(const_op) == ia32_Const)) {
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, mode_Iu);
1020                 add_irn_dep(edx_node, be_abi_get_start_barrier(env->cg->birg->abi));
1021                 set_ia32_Const_type(edx_node, ia32_Const);
1022                 set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
1023         }
1024
1025         res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, dm_flav);
1026         set_ia32_n_res(res, 2);
1027
1028         /* Only one proj is used -> We must add a second proj and */
1029         /* connect this one to a Keep node to eat up the second   */
1030         /* destroyed register.                                    */
1031         /* We also renumber the Firm projs into ia32 projs.       */
1032
1033         switch (get_irn_opcode(irn)) {
1034                 case iro_Div:
1035                         ia32_renumber_Proj(projs, pn_Div_M, pn_ia32_DivMod_M);
1036                         ia32_renumber_Proj(projs, pn_Div_res, pn_ia32_DivMod_div_res);
1037                         /* add Proj-Keep for mod res */
1038                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_DivMod_mod_res);
1039                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1040                         break;
1041                 case iro_Mod:
1042                         ia32_renumber_Proj(projs, pn_Mod_M, pn_ia32_DivMod_M);
1043                         ia32_renumber_Proj(projs, pn_Mod_res, pn_ia32_DivMod_mod_res);
1044                         /* add Proj-Keep for div res */
1045                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_DivMod_div_res);
1046                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1047                         break;
1048                 case iro_DivMod:
1049                         /* check, which Proj-Keep, we need to add */
1050                         proj_div = get_proj_for_pn(irn, pn_DivMod_res_div);
1051                         proj_mod = get_proj_for_pn(irn, pn_DivMod_res_mod);
1052
1053                         /* BEWARE: renumber after getting original projs */
1054                         ia32_renumber_Proj(projs, pn_DivMod_M, pn_ia32_DivMod_M);
1055
1056                         if (proj_div && proj_mod) {
1057                                 /* we have both results used: simply renumber */
1058                                 ia32_renumber_Proj(projs, pn_DivMod_res_div, pn_ia32_DivMod_div_res);
1059                                 ia32_renumber_Proj(projs, pn_DivMod_res_mod, pn_ia32_DivMod_mod_res);
1060                         }
1061                         else if (! proj_div && ! proj_mod) {
1062                                 assert(0 && "Missing DivMod result proj");
1063                         }
1064                         else if (! proj_div) {
1065                                 /* We have only mod result: add div res Proj-Keep */
1066                                 ia32_renumber_Proj(projs, pn_DivMod_res_mod, pn_ia32_DivMod_mod_res);
1067                                 in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_DivMod_div_res);
1068                                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1069                         }
1070                         else {
1071                                 /* We have only div result: add mod res Proj-Keep */
1072                                 ia32_renumber_Proj(projs, pn_DivMod_res_div, pn_ia32_DivMod_div_res);
1073                                 in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_DivMod_mod_res);
1074                                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
1075                         }
1076                         break;
1077                 default:
1078                         assert(0 && "Div, Mod, or DivMod expected.");
1079                         break;
1080         }
1081
1082         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1083         set_ia32_res_mode(res, mode);
1084
1085         return res;
1086 }
1087
1088
1089 /**
1090  * Wrapper for generate_DivMod. Sets flavour_Mod.
1091  *
1092  * @param env      The transformation environment
1093  */
1094 static ir_node *gen_Mod(ia32_transform_env_t *env) {
1095         return generate_DivMod(env, get_Mod_left(env->irn), get_Mod_right(env->irn), flavour_Mod);
1096 }
1097
1098 /**
1099  * Wrapper for generate_DivMod. Sets flavour_Div.
1100  *
1101  * @param env      The transformation environment
1102  */
1103 static ir_node *gen_Div(ia32_transform_env_t *env) {
1104         return generate_DivMod(env, get_Div_left(env->irn), get_Div_right(env->irn), flavour_Div);
1105 }
1106
1107 /**
1108  * Wrapper for generate_DivMod. Sets flavour_DivMod.
1109  */
1110 static ir_node *gen_DivMod(ia32_transform_env_t *env) {
1111         return generate_DivMod(env, get_DivMod_left(env->irn), get_DivMod_right(env->irn), flavour_DivMod);
1112 }
1113
1114
1115
1116 /**
1117  * Creates an ia32 floating Div.
1118  *
1119  * @param env   The transformation environment
1120  * @return The created ia32 xDiv node
1121  */
1122 static ir_node *gen_Quot(ia32_transform_env_t *env) {
1123         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1124         ir_node *new_op;
1125         ir_node *nomem = new_rd_NoMem(env->irg);
1126         ir_node *op1   = get_Quot_left(env->irn);
1127         ir_node *op2   = get_Quot_right(env->irn);
1128         ir_mode *mode  = get_irn_mode(get_proj_for_pn(env->irn, pn_Quot_res));
1129         ir_node *projs[pn_Quot_max];
1130         /* BEWARE: Projs will be renumbered, so retrieve res Proj here */
1131
1132         ia32_collect_Projs(env->irn, projs, pn_Quot_max);
1133
1134         FP_USED(env->cg);
1135         if (USE_SSE2(env->cg)) {
1136                 if (is_ia32_xConst(op2)) {
1137                         new_op = new_rd_ia32_xDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, noreg, nomem);
1138                         set_ia32_am_support(new_op, ia32_am_None);
1139                         set_ia32_Immop_attr(new_op, op2);
1140                 }
1141                 else {
1142                         new_op = new_rd_ia32_xDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem);
1143                         set_ia32_am_support(new_op, ia32_am_Source);
1144                 }
1145                 ia32_renumber_Proj(projs, pn_Quot_M, pn_ia32_xDiv_M);
1146                 ia32_renumber_Proj(projs, pn_Quot_res, pn_ia32_xDiv_res);
1147         }
1148         else {
1149                 new_op = new_rd_ia32_vfdiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem);
1150                 set_ia32_am_support(new_op, ia32_am_Source);
1151                 ia32_renumber_Proj(projs, pn_Quot_M, pn_ia32_vfdiv_M);
1152                 ia32_renumber_Proj(projs, pn_Quot_res, pn_ia32_vfdiv_res);
1153         }
1154         set_ia32_res_mode(new_op, mode);
1155         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1156         return new_op;
1157 }
1158
1159
1160
1161 /**
1162  * Creates an ia32 Shl.
1163  *
1164  * @param env   The transformation environment
1165  * @return The created ia32 Shl node
1166  */
1167 static ir_node *gen_Shl(ia32_transform_env_t *env) {
1168         return gen_shift_binop(env, get_Shl_left(env->irn), get_Shl_right(env->irn), new_rd_ia32_Shl);
1169 }
1170
1171
1172
1173 /**
1174  * Creates an ia32 Shr.
1175  *
1176  * @param env   The transformation environment
1177  * @return The created ia32 Shr node
1178  */
1179 static ir_node *gen_Shr(ia32_transform_env_t *env) {
1180         return gen_shift_binop(env, get_Shr_left(env->irn), get_Shr_right(env->irn), new_rd_ia32_Shr);
1181 }
1182
1183
1184
1185 /**
1186  * Creates an ia32 Shrs.
1187  *
1188  * @param env   The transformation environment
1189  * @return The created ia32 Shrs node
1190  */
1191 static ir_node *gen_Shrs(ia32_transform_env_t *env) {
1192         return gen_shift_binop(env, get_Shrs_left(env->irn), get_Shrs_right(env->irn), new_rd_ia32_Shrs);
1193 }
1194
1195
1196
1197 /**
1198  * Creates an ia32 RotL.
1199  *
1200  * @param env   The transformation environment
1201  * @param op1   The first operator
1202  * @param op2   The second operator
1203  * @return The created ia32 RotL node
1204  */
1205 static ir_node *gen_RotL(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
1206         return gen_shift_binop(env, op1, op2, new_rd_ia32_RotL);
1207 }
1208
1209
1210
1211 /**
1212  * Creates an ia32 RotR.
1213  * NOTE: There is no RotR with immediate because this would always be a RotL
1214  *       "imm-mode_size_bits" which can be pre-calculated.
1215  *
1216  * @param env   The transformation environment
1217  * @param op1   The first operator
1218  * @param op2   The second operator
1219  * @return The created ia32 RotR node
1220  */
1221 static ir_node *gen_RotR(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
1222         return gen_shift_binop(env, op1, op2, new_rd_ia32_RotR);
1223 }
1224
1225
1226
1227 /**
1228  * Creates an ia32 RotR or RotL (depending on the found pattern).
1229  *
1230  * @param env   The transformation environment
1231  * @return The created ia32 RotL or RotR node
1232  */
1233 static ir_node *gen_Rot(ia32_transform_env_t *env) {
1234         ir_node *rotate = NULL;
1235         ir_node *op1    = get_Rot_left(env->irn);
1236         ir_node *op2    = get_Rot_right(env->irn);
1237
1238         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1239                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1240                  that means we can create a RotR instead of an Add and a RotL */
1241
1242         if (is_Proj(op2)) {
1243                 ir_node *pred = get_Proj_pred(op2);
1244
1245                 if (is_ia32_Add(pred)) {
1246                         ir_node *pred_pred = get_irn_n(pred, 2);
1247                         tarval  *tv        = get_ia32_Immop_tarval(pred);
1248                         long     bits      = get_mode_size_bits(env->mode);
1249
1250                         if (is_Proj(pred_pred)) {
1251                                 pred_pred = get_Proj_pred(pred_pred);
1252                         }
1253
1254                         if (is_ia32_Minus(pred_pred) &&
1255                                 tarval_is_long(tv)       &&
1256                                 get_tarval_long(tv) == bits)
1257                         {
1258                                 DB((env->mod, LEVEL_1, "RotL into RotR ... "));
1259                                 rotate = gen_RotR(env, op1, get_irn_n(pred_pred, 2));
1260                         }
1261
1262                 }
1263         }
1264
1265         if (!rotate) {
1266                 rotate = gen_RotL(env, op1, op2);
1267         }
1268
1269         return rotate;
1270 }
1271
1272
1273
1274 /**
1275  * Transforms a Minus node.
1276  *
1277  * @param env   The transformation environment
1278  * @param op    The Minus operand
1279  * @return The created ia32 Minus node
1280  */
1281 ir_node *gen_Minus_ex(ia32_transform_env_t *env, ir_node *op) {
1282         ident   *name;
1283         ir_node *new_op;
1284         int      size;
1285
1286         if (mode_is_float(env->mode)) {
1287                 FP_USED(env->cg);
1288                 if (USE_SSE2(env->cg)) {
1289                         ir_node *noreg_gp = ia32_new_NoReg_gp(env->cg);
1290                         ir_node *noreg_fp = ia32_new_NoReg_fp(env->cg);
1291                         ir_node *nomem    = new_rd_NoMem(env->irg);
1292
1293                         new_op = new_rd_ia32_xEor(env->dbg, env->irg, env->block, noreg_gp, noreg_gp, op, noreg_fp, nomem);
1294
1295                         size   = get_mode_size_bits(env->mode);
1296                         name   = gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1297
1298                         set_ia32_am_sc(new_op, name);
1299
1300                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1301
1302                         set_ia32_res_mode(new_op, env->mode);
1303                         set_ia32_op_type(new_op, ia32_AddrModeS);
1304                         set_ia32_ls_mode(new_op, env->mode);
1305
1306                         new_op = new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, pn_ia32_xEor_res);
1307                 }
1308                 else {
1309                         new_op = new_rd_ia32_vfchs(env->dbg, env->irg, env->block, op, env->mode);
1310                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1311                 }
1312         }
1313         else {
1314                 new_op = gen_unop(env, op, new_rd_ia32_Minus);
1315         }
1316
1317         return new_op;
1318 }
1319
1320 /**
1321  * Transforms a Minus node.
1322  *
1323  * @param env   The transformation environment
1324  * @return The created ia32 Minus node
1325  */
1326 static ir_node *gen_Minus(ia32_transform_env_t *env) {
1327         return gen_Minus_ex(env, get_Minus_op(env->irn));
1328 }
1329
1330
1331 /**
1332  * Transforms a Not node.
1333  *
1334  * @param env   The transformation environment
1335  * @return The created ia32 Not node
1336  */
1337 static ir_node *gen_Not(ia32_transform_env_t *env) {
1338         assert (! mode_is_float(env->mode));
1339         return gen_unop(env, get_Not_op(env->irn), new_rd_ia32_Not);
1340 }
1341
1342
1343
1344 /**
1345  * Transforms an Abs node.
1346  *
1347  * @param env   The transformation environment
1348  * @return The created ia32 Abs node
1349  */
1350 static ir_node *gen_Abs(ia32_transform_env_t *env) {
1351         ir_node  *res, *p_eax, *p_edx;
1352         dbg_info *dbg      = env->dbg;
1353         ir_mode  *mode     = env->mode;
1354         ir_graph *irg      = env->irg;
1355         ir_node  *block    = env->block;
1356         ir_node  *noreg_gp = ia32_new_NoReg_gp(env->cg);
1357         ir_node  *noreg_fp = ia32_new_NoReg_fp(env->cg);
1358         ir_node  *nomem    = new_NoMem();
1359         ir_node  *op       = get_Abs_op(env->irn);
1360         int       size;
1361         ident    *name;
1362
1363         if (mode_is_float(mode)) {
1364                 FP_USED(env->cg);
1365                 if (USE_SSE2(env->cg)) {
1366                         res = new_rd_ia32_xAnd(dbg,irg, block, noreg_gp, noreg_gp, op, noreg_fp, nomem);
1367
1368                         size   = get_mode_size_bits(mode);
1369                         name   = gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1370
1371                         set_ia32_am_sc(res, name);
1372
1373                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1374
1375                         set_ia32_res_mode(res, mode);
1376                         set_ia32_op_type(res, ia32_AddrModeS);
1377                         set_ia32_ls_mode(res, env->mode);
1378
1379                         res = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_xAnd_res);
1380                 }
1381                 else {
1382                         res = new_rd_ia32_vfabs(dbg, irg, block, op, mode);
1383                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1384                 }
1385         }
1386         else {
1387                 res   = new_rd_ia32_Cdq(dbg, irg, block, op);
1388                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1389                 set_ia32_res_mode(res, mode);
1390
1391                 p_eax = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Cdq_EAX);
1392                 p_edx = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Cdq_EDX);
1393
1394                 res   = new_rd_ia32_Eor(dbg, irg, block, noreg_gp, noreg_gp, p_eax, p_edx, nomem);
1395                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1396                 set_ia32_res_mode(res, mode);
1397
1398                 res   = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Eor_res);
1399
1400                 res   = new_rd_ia32_Sub(dbg, irg, block, noreg_gp, noreg_gp, res, p_edx, nomem);
1401                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1402                 set_ia32_res_mode(res, mode);
1403
1404                 res   = new_rd_Proj(dbg, irg, block, res, mode, pn_ia32_Sub_res);
1405         }
1406
1407         return res;
1408 }
1409
1410
1411
1412 /**
1413  * Transforms a Load.
1414  *
1415  * @param env   The transformation environment
1416  * @return the created ia32 Load node
1417  */
1418 static ir_node *gen_Load(ia32_transform_env_t *env) {
1419         ir_node *node  = env->irn;
1420         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1421         ir_node *ptr   = get_Load_ptr(node);
1422         ir_node *lptr  = ptr;
1423         ir_mode *mode  = get_Load_mode(node);
1424         int     is_imm = 0;
1425         ir_node *new_op;
1426         ia32_am_flavour_t am_flav = ia32_am_B;
1427         ir_node *projs[pn_Load_max];
1428
1429         ia32_collect_Projs(env->irn, projs, pn_Load_max);
1430
1431         /*
1432                 check for special case: the loaded value might not be used (optimized, volatile, ...)
1433                 we add a Proj + Keep for volatile loads and ignore all other cases
1434         */
1435         if (! get_proj_for_pn(node, pn_Load_res) && get_Load_volatility(node) == volatility_is_volatile) {
1436                 /* add a result proj and a Keep to produce a pseudo use */
1437                 ir_node *proj = new_r_Proj(env->irg, env->block, node, mode, pn_ia32_Load_res);
1438                 be_new_Keep(arch_get_irn_reg_class(env->cg->arch_env, proj, -1), env->irg, env->block, 1, &proj);
1439         }
1440
1441         /* address might be a constant (symconst or absolute address) */
1442         if (is_ia32_Const(ptr)) {
1443                 lptr   = noreg;
1444                 is_imm = 1;
1445         }
1446
1447         if (mode_is_float(mode)) {
1448                 FP_USED(env->cg);
1449                 if (USE_SSE2(env->cg)) {
1450                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node));
1451                         ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_xLoad_M);
1452                         ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_xLoad_res);
1453                 }
1454                 else {
1455                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node));
1456                         ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_vfld_M);
1457                         ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_vfld_res);
1458                 }
1459         }
1460         else {
1461                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, lptr, noreg, get_Load_mem(node));
1462                 ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_Load_M);
1463                 ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_Load_res);
1464         }
1465
1466         /* base is an constant address */
1467         if (is_imm) {
1468                 if (get_ia32_op_type(ptr) == ia32_SymConst) {
1469                         set_ia32_am_sc(new_op, get_ia32_id_cnst(ptr));
1470                         am_flav = ia32_am_N;
1471                 }
1472                 else {
1473                         add_ia32_am_offs(new_op, get_ia32_cnst(ptr));
1474                         am_flav = ia32_am_O;
1475                 }
1476                 /* add dependency to barrier, if we are in start block */
1477                 if (get_irg_start_block(env->irg) == env->block)
1478                         add_irn_dep(new_op, be_abi_get_start_barrier(env->cg->birg->abi));
1479         }
1480
1481         set_ia32_am_support(new_op, ia32_am_Source);
1482         set_ia32_op_type(new_op, ia32_AddrModeS);
1483         set_ia32_am_flavour(new_op, am_flav);
1484         set_ia32_ls_mode(new_op, mode);
1485
1486         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1487
1488         return new_op;
1489 }
1490
1491
1492
1493 /**
1494  * Transforms a Store.
1495  *
1496  * @param env   The transformation environment
1497  * @return the created ia32 Store node
1498  */
1499 static ir_node *gen_Store(ia32_transform_env_t *env) {
1500         ir_node *node    = env->irn;
1501         ir_node *noreg   = ia32_new_NoReg_gp(env->cg);
1502         ir_node *val     = get_Store_value(node);
1503         ir_node *ptr     = get_Store_ptr(node);
1504         ir_node *sptr    = ptr;
1505         ir_node *mem     = get_Store_mem(node);
1506         ir_mode *mode    = get_irn_mode(val);
1507         ir_node *sval    = val;
1508         int      is_imm  = 0;
1509         ir_node *new_op;
1510         ia32_am_flavour_t am_flav = ia32_am_B;
1511         ia32_immop_type_t immop   = ia32_ImmNone;
1512         ir_node *projs[pn_Store_max];
1513
1514         ia32_collect_Projs(env->irn, projs, pn_Store_max);
1515
1516         if (! mode_is_float(mode)) {
1517                 /* in case of storing a const (but not a symconst) -> make it an attribute */
1518                 if (is_ia32_Cnst(val)) {
1519                         switch (get_ia32_op_type(val)) {
1520                         case ia32_Const:
1521                                 immop = ia32_ImmConst;
1522                                 break;
1523                         case ia32_SymConst:
1524                                 immop = ia32_ImmSymConst;
1525                                 break;
1526                         default:
1527                                 assert(0 && "unsupported Const type");
1528                         }
1529                         sval = noreg;
1530                 }
1531         }
1532
1533         /* address might be a constant (symconst or absolute address) */
1534         if (is_ia32_Const(ptr)) {
1535                 sptr   = noreg;
1536                 is_imm = 1;
1537         }
1538
1539         if (mode_is_float(mode)) {
1540                 FP_USED(env->cg);
1541                 if (USE_SSE2(env->cg)) {
1542                         new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
1543                         ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_xStore_M);
1544                 }
1545                 else {
1546                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
1547                         ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_vfst_M);
1548                 }
1549         }
1550         else if (get_mode_size_bits(mode) == 8) {
1551                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
1552                 ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_Store8Bit_M);
1553         }
1554         else {
1555                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
1556                 ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_Store_M);
1557         }
1558
1559         /* stored const is an attribute (saves a register) */
1560         if (! mode_is_float(mode) && is_ia32_Cnst(val)) {
1561                 set_ia32_Immop_attr(new_op, val);
1562         }
1563
1564         /* base is an constant address */
1565         if (is_imm) {
1566                 if (get_ia32_op_type(ptr) == ia32_SymConst) {
1567                         set_ia32_am_sc(new_op, get_ia32_id_cnst(ptr));
1568                         am_flav = ia32_am_N;
1569                 }
1570                 else {
1571                         add_ia32_am_offs(new_op, get_ia32_cnst(ptr));
1572                         am_flav = ia32_am_O;
1573                 }
1574         }
1575
1576         set_ia32_am_support(new_op, ia32_am_Dest);
1577         set_ia32_op_type(new_op, ia32_AddrModeD);
1578         set_ia32_am_flavour(new_op, am_flav);
1579         set_ia32_ls_mode(new_op, mode);
1580         set_ia32_immop_type(new_op, immop);
1581
1582         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1583
1584         return new_op;
1585 }
1586
1587
1588
1589 /**
1590  * Transforms a Cond -> Proj[b] -> Cmp into a CondJmp, CondJmp_i or TestJmp
1591  *
1592  * @param env   The transformation environment
1593  * @return The transformed node.
1594  */
1595 static ir_node *gen_Cond(ia32_transform_env_t *env) {
1596         dbg_info *dbg      = env->dbg;
1597         ir_graph *irg      = env->irg;
1598         ir_node  *block    = env->block;
1599         ir_node  *node     = env->irn;
1600         ir_node  *sel      = get_Cond_selector(node);
1601         ir_mode  *sel_mode = get_irn_mode(sel);
1602         ir_node  *res      = NULL;
1603         ir_node  *pred     = NULL;
1604         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
1605         ir_node  *cmp_a, *cmp_b, *cnst, *expr;
1606
1607         if (is_Proj(sel) && sel_mode == mode_b) {
1608                 ir_node  *nomem = new_NoMem();
1609                 pn_Cmp pnc = get_Proj_proj(sel);
1610
1611                 pred  = get_Proj_pred(sel);
1612
1613                 /* get both compare operators */
1614                 cmp_a = get_Cmp_left(pred);
1615                 cmp_b = get_Cmp_right(pred);
1616
1617                 /* check if we can use a CondJmp with immediate */
1618                 cnst = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(cmp_a, cmp_b) : NULL;
1619                 expr = get_expr_op(cmp_a, cmp_b);
1620
1621                 if (cnst && expr) {
1622                         /* immop has to be the right operand, we might need to flip pnc */
1623                         if(cnst != cmp_b) {
1624                                 pnc = get_inversed_pnc(pnc);
1625                         }
1626
1627                         if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_is_int(get_irn_mode(expr))) {
1628                                 if (get_ia32_op_type(cnst) == ia32_Const &&
1629                                         classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL)
1630                                 {
1631                                         /* a Cmp A =/!= 0 */
1632                                         ir_node    *op1  = expr;
1633                                         ir_node    *op2  = expr;
1634                                         ir_node    *and  = skip_Proj(expr);
1635                                         const char *cnst = NULL;
1636
1637                                         /* check, if expr is an only once used And operation */
1638                                         if (get_irn_n_edges(expr) == 1 && is_ia32_And(and)) {
1639                                                 op1 = get_irn_n(and, 2);
1640                                                 op2 = get_irn_n(and, 3);
1641
1642                                                 cnst = (is_ia32_ImmConst(and) || is_ia32_ImmSymConst(and)) ? get_ia32_cnst(and) : NULL;
1643                                         }
1644                                         res = new_rd_ia32_TestJmp(dbg, irg, block, op1, op2);
1645                                         set_ia32_pncode(res, pnc);
1646                                         set_ia32_res_mode(res, get_irn_mode(op1));
1647
1648                                         if (cnst) {
1649                                                 copy_ia32_Immop_attr(res, and);
1650                                         }
1651
1652                                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1653                                         return res;
1654                                 }
1655                         }
1656
1657                         if (mode_is_float(get_irn_mode(expr))) {
1658                                 FP_USED(env->cg);
1659                                 if (USE_SSE2(env->cg))
1660                                         res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem);
1661                                 else {
1662                                         assert(0);
1663                                 }
1664                         }
1665                         else {
1666                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem);
1667                         }
1668                         set_ia32_Immop_attr(res, cnst);
1669                         set_ia32_res_mode(res, get_irn_mode(expr));
1670                 }
1671                 else {
1672                         if (mode_is_float(get_irn_mode(cmp_a))) {
1673                                 FP_USED(env->cg);
1674                                 if (USE_SSE2(env->cg))
1675                                         res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1676                                 else {
1677                                         ir_node *proj_eax;
1678                                         res = new_rd_ia32_vfCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1679                                         proj_eax = new_r_Proj(irg, block, res, mode_Is, pn_ia32_vfCondJmp_temp_reg_eax);
1680                                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, &proj_eax);
1681                                 }
1682                         }
1683                         else {
1684                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1685                                 set_ia32_commutative(res);
1686                         }
1687                         set_ia32_res_mode(res, get_irn_mode(cmp_a));
1688                 }
1689
1690                 set_ia32_pncode(res, pnc);
1691                 //set_ia32_am_support(res, ia32_am_Source);
1692         }
1693         else {
1694                 /* determine the smallest switch case value */
1695                 int switch_min = INT_MAX;
1696                 const ir_edge_t *edge;
1697                 char buf[64];
1698
1699                 foreach_out_edge(node, edge) {
1700                         int pn = get_Proj_proj(get_edge_src_irn(edge));
1701                         switch_min = pn < switch_min ? pn : switch_min;
1702                 }
1703
1704                 if (switch_min) {
1705                         /* if smallest switch case is not 0 we need an additional sub */
1706                         snprintf(buf, sizeof(buf), "%d", switch_min);
1707                         res = new_rd_ia32_Lea(dbg, irg, block, sel, noreg, mode_Is);
1708                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1709                         sub_ia32_am_offs(res, buf);
1710                         set_ia32_am_flavour(res, ia32_am_OB);
1711                         set_ia32_am_support(res, ia32_am_Source);
1712                         set_ia32_op_type(res, ia32_AddrModeS);
1713                 }
1714
1715                 res = new_rd_ia32_SwitchJmp(dbg, irg, block, switch_min ? res : sel, mode_T);
1716                 set_ia32_pncode(res, get_Cond_defaultProj(node));
1717                 set_ia32_res_mode(res, get_irn_mode(sel));
1718         }
1719
1720         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1721         return res;
1722 }
1723
1724
1725
1726 /**
1727  * Transforms a CopyB node.
1728  *
1729  * @param env   The transformation environment
1730  * @return The transformed node.
1731  */
1732 static ir_node *gen_CopyB(ia32_transform_env_t *env) {
1733         ir_node  *res      = NULL;
1734         dbg_info *dbg      = env->dbg;
1735         ir_graph *irg      = env->irg;
1736         ir_node  *block    = env->block;
1737         ir_node  *node     = env->irn;
1738         ir_node  *src      = get_CopyB_src(node);
1739         ir_node  *dst      = get_CopyB_dst(node);
1740         ir_node  *mem      = get_CopyB_mem(node);
1741         int      size      = get_type_size_bytes(get_CopyB_type(node));
1742         ir_mode  *dst_mode = get_irn_mode(dst);
1743         ir_mode  *src_mode = get_irn_mode(src);
1744         int      rem;
1745         ir_node  *in[3];
1746         ir_node  *projs[pn_CopyB_max];
1747
1748         ia32_collect_Projs(env->irn, projs, pn_CopyB_max);
1749
1750         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
1751         /* then we need the size explicitly in ECX.                    */
1752         if (size >= 32 * 4) {
1753                 rem = size & 0x3; /* size % 4 */
1754                 size >>= 2;
1755
1756                 res = new_rd_ia32_Const(dbg, irg, block, mode_Is);
1757                 add_irn_dep(res, be_abi_get_start_barrier(env->cg->birg->abi));
1758                 set_ia32_op_type(res, ia32_Const);
1759                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1760
1761                 res = new_rd_ia32_CopyB(dbg, irg, block, dst, src, res, mem);
1762                 set_ia32_Immop_tarval(res, new_tarval_from_long(rem, mode_Is));
1763
1764                 /* ok: now attach Proj's because rep movsd will destroy esi, edi and ecx */
1765                 in[0] = new_r_Proj(irg, block, res, dst_mode, pn_ia32_CopyB_DST);
1766                 in[1] = new_r_Proj(irg, block, res, src_mode, pn_ia32_CopyB_SRC);
1767                 in[2] = new_r_Proj(irg, block, res, mode_Is, pn_ia32_CopyB_CNT);
1768                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 3, in);
1769
1770                 ia32_renumber_Proj(projs, pn_CopyB_M_regular, pn_ia32_CopyB_M);
1771         }
1772         else {
1773                 res = new_rd_ia32_CopyB_i(dbg, irg, block, dst, src, mem);
1774                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1775                 set_ia32_immop_type(res, ia32_ImmConst);
1776
1777                 /* ok: now attach Proj's because movsd will destroy esi and edi */
1778                 in[0] = new_r_Proj(irg, block, res, dst_mode, pn_ia32_CopyB_i_DST);
1779                 in[1] = new_r_Proj(irg, block, res, src_mode, pn_ia32_CopyB_i_SRC);
1780                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 2, in);
1781
1782                 ia32_renumber_Proj(projs, pn_CopyB_M_regular, pn_ia32_CopyB_i_M);
1783         }
1784
1785         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1786
1787         return res;
1788 }
1789
1790
1791
1792 /**
1793  * Transforms a Mux node into CMov.
1794  *
1795  * @param env   The transformation environment
1796  * @return The transformed node.
1797  */
1798 static ir_node *gen_Mux(ia32_transform_env_t *env) {
1799 #if 0
1800         ir_node *node   = env->irn;
1801         ir_node *new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, \
1802                 get_Mux_sel(node), get_Mux_false(node), get_Mux_true(node), env->mode);
1803
1804         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1805
1806         return new_op;
1807 #endif
1808         return NULL;
1809 }
1810
1811 typedef ir_node *cmov_func_t(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *cmp_a, ir_node *cmp_b, \
1812                              ir_node *psi_true, ir_node *psi_default, ir_mode *mode);
1813
1814 /**
1815  * Transforms a Psi node into CMov.
1816  *
1817  * @param env   The transformation environment
1818  * @return The transformed node.
1819  */
1820 static ir_node *gen_Psi(ia32_transform_env_t *env) {
1821         ia32_code_gen_t *cg   = env->cg;
1822         dbg_info *dbg         = env->dbg;
1823         ir_graph *irg         = env->irg;
1824         ir_mode  *mode        = env->mode;
1825         ir_node  *block       = env->block;
1826         ir_node  *node        = env->irn;
1827         ir_node  *cmp_proj    = get_Mux_sel(node);
1828         ir_node  *psi_true    = get_Psi_val(node, 0);
1829         ir_node  *psi_default = get_Psi_default(node);
1830         ir_node  *noreg       = ia32_new_NoReg_gp(cg);
1831         ir_node  *nomem       = new_rd_NoMem(irg);
1832         ir_node  *cmp, *cmp_a, *cmp_b, *and1, *and2, *new_op = NULL;
1833         int      pnc;
1834
1835         assert(get_irn_mode(cmp_proj) == mode_b && "Condition for Psi must have mode_b");
1836
1837         cmp   = get_Proj_pred(cmp_proj);
1838         cmp_a = get_Cmp_left(cmp);
1839         cmp_b = get_Cmp_right(cmp);
1840         pnc   = get_Proj_proj(cmp_proj);
1841
1842         if (mode_is_float(mode)) {
1843                 /* floating point psi */
1844                 FP_USED(cg);
1845
1846                 /* 1st case: compare operands are float too */
1847                 if (USE_SSE2(cg)) {
1848                         /* psi(cmp(a, b), t, f) can be done as: */
1849                         /* tmp = cmp a, b                       */
1850                         /* tmp2 = t and tmp                     */
1851                         /* tmp3 = f and not tmp                 */
1852                         /* res  = tmp2 or tmp3                  */
1853
1854                         /* in case the compare operands are int, we move them into xmm register */
1855                         if (! mode_is_float(get_irn_mode(cmp_a))) {
1856                                 cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_a, node, mode_D);
1857                                 cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_b, node, mode_D);
1858
1859                                 pnc |= 8;  /* transform integer compare to fp compare */
1860                         }
1861
1862                         new_op = new_rd_ia32_xCmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1863                         set_ia32_pncode(new_op, pnc);
1864                         set_ia32_am_support(new_op, ia32_am_Source);
1865                         set_ia32_res_mode(new_op, mode);
1866                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1867                         new_op = new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_xCmp_res);
1868
1869                         and1 = new_rd_ia32_xAnd(dbg, irg, block, noreg, noreg, psi_true, new_op, nomem);
1870                         set_ia32_am_support(and1, ia32_am_None);
1871                         set_ia32_res_mode(and1, mode);
1872                         set_ia32_commutative(and1);
1873                         SET_IA32_ORIG_NODE(and1, ia32_get_old_node_name(cg, node));
1874                         and1 = new_rd_Proj(dbg, irg, block, and1, mode, pn_ia32_xAnd_res);
1875
1876                         and2 = new_rd_ia32_xAndNot(dbg, irg, block, noreg, noreg, new_op, psi_default, nomem);
1877                         set_ia32_am_support(and2, ia32_am_None);
1878                         set_ia32_res_mode(and2, mode);
1879                         set_ia32_commutative(and2);
1880                         SET_IA32_ORIG_NODE(and2, ia32_get_old_node_name(cg, node));
1881                         and2 = new_rd_Proj(dbg, irg, block, and2, mode, pn_ia32_xAndNot_res);
1882
1883                         new_op = new_rd_ia32_xOr(dbg, irg, block, noreg, noreg, and1, and2, nomem);
1884                         set_ia32_am_support(new_op, ia32_am_None);
1885                         set_ia32_res_mode(new_op, mode);
1886                         set_ia32_commutative(new_op);
1887                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1888                         new_op = new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_xOr_res);
1889                 }
1890                 else {
1891                         /* x87 FPU */
1892                         new_op = new_rd_ia32_vfCMov(dbg, irg, block, cmp_a, cmp_b, psi_true, psi_default, mode);
1893                         set_ia32_pncode(new_op, pnc);
1894                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1895                 }
1896         }
1897         else {
1898                 /* integer psi */
1899                 construct_binop_func *set_func  = NULL;
1900                 cmov_func_t          *cmov_func = NULL;
1901
1902                 if (mode_is_float(get_irn_mode(cmp_a))) {
1903                         /* 1st case: compare operands are floats */
1904                         FP_USED(cg);
1905
1906                         if (USE_SSE2(cg)) {
1907                                 /* SSE FPU */
1908                                 set_func  = new_rd_ia32_xCmpSet;
1909                                 cmov_func = new_rd_ia32_xCmpCMov;
1910                         }
1911                         else {
1912                                 /* x87 FPU */
1913                                 set_func  = new_rd_ia32_vfCmpSet;
1914                                 cmov_func = new_rd_ia32_vfCmpCMov;
1915                         }
1916
1917                         pnc &= 7; /* fp compare -> int compare */
1918                 }
1919                 else {
1920                         /* 2nd case: compare operand are integer too */
1921                         set_func  = new_rd_ia32_CmpSet;
1922                         cmov_func = new_rd_ia32_CmpCMov;
1923                 }
1924
1925                 /* create the nodes */
1926
1927                 /* check for special case first: And/Or -- Cmp with 0 -- Psi */
1928                 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)))) {
1929                         if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) {
1930                                 /* first case for SETcc: default is 0, set to 1 iff condition is true */
1931                                 new_op = new_rd_ia32_PsiCondSet(dbg, irg, block, cmp_a, mode);
1932                                 set_ia32_pncode(new_op, pnc);
1933                         }
1934                         else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) {
1935                                 /* second case for SETcc: default is 1, set to 0 iff condition is true: */
1936                                 /*                        we invert condition and set default to 0      */
1937                                 new_op = new_rd_ia32_PsiCondSet(dbg, irg, block, cmp_a, mode);
1938                                 set_ia32_pncode(new_op, get_inversed_pnc(pnc));
1939                         }
1940                         else {
1941                                 /* otherwise: use CMOVcc */
1942                                 new_op = new_rd_ia32_PsiCondCMov(dbg, irg, block, cmp_a, psi_true, psi_default, mode);
1943                                 set_ia32_pncode(new_op, pnc);
1944                         }
1945
1946                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1947                 }
1948                 else {
1949                         env->irn = cmp;
1950                         if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) {
1951                                 /* first case for SETcc: default is 0, set to 1 iff condition is true */
1952                                 new_op = gen_binop(env, cmp_a, cmp_b, set_func);
1953                                 set_ia32_pncode(get_Proj_pred(new_op), pnc);
1954                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
1955                         }
1956                         else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) {
1957                                 /* second case for SETcc: default is 1, set to 0 iff condition is true: */
1958                                 /*                        we invert condition and set default to 0      */
1959                                 new_op = gen_binop(env, cmp_a, cmp_b, set_func);
1960                                 set_ia32_pncode(get_Proj_pred(new_op), get_inversed_pnc(pnc));
1961                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
1962                         }
1963                         else {
1964                                 /* otherwise: use CMOVcc */
1965                                 new_op = cmov_func(dbg, irg, block, cmp_a, cmp_b, psi_true, psi_default, mode);
1966                                 set_ia32_pncode(new_op, pnc);
1967                                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1968                         }
1969                 }
1970         }
1971
1972         return new_op;
1973 }
1974
1975
1976 /**
1977  * Following conversion rules apply:
1978  *
1979  *  INT -> INT
1980  * ============
1981  *  1) n bit -> m bit   n > m (downscale)
1982  *     a) target is signed:    movsx
1983  *     b) target is unsigned:  and with lower bits sets
1984  *  2) n bit -> m bit   n == m   (sign change)
1985  *     always ignored
1986  *  3) n bit -> m bit   n < m (upscale)
1987  *     a) source is signed:    movsx
1988  *     b) source is unsigned:  and with lower bits sets
1989  *
1990  *  INT -> FLOAT
1991  * ==============
1992  *  SSE(1/2) convert to float or double (cvtsi2ss/sd)
1993  *
1994  *  FLOAT -> INT
1995  * ==============
1996  *  SSE(1/2) convert from float or double to 32bit int (cvtss/sd2si)
1997  *  if target mode < 32bit: additional INT -> INT conversion (see above)
1998  *
1999  *  FLOAT -> FLOAT
2000  * ================
2001  *  SSE(1/2) convert from float or double to double or float (cvtss/sd2sd/ss)
2002  *  x87 is mode_E internally, conversions happen only at load and store
2003  *  in non-strict semantic
2004  */
2005
2006 /**
2007  * Create a conversion from x87 state register to general purpose.
2008  */
2009 static ir_node *gen_x87_fp_to_gp(ia32_transform_env_t *env, ir_mode *tgt_mode) {
2010         ia32_code_gen_t *cg    = env->cg;
2011         entity          *ent   = cg->fp_to_gp;
2012         ir_graph        *irg   = env->irg;
2013         ir_node         *block = env->block;
2014         ir_node         *noreg = ia32_new_NoReg_gp(env->cg);
2015         ir_node         *op    = get_Conv_op(env->irn);
2016         ir_node         *fist, *mem, *load;
2017
2018         if (! ent) {
2019                 int size = get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_vfp].mode);
2020                 ent = cg->fp_to_gp =
2021                         frame_alloc_area(get_irg_frame_type(env->irg), size, 16, 0);
2022         }
2023
2024         /* do a fist */
2025         fist = new_rd_ia32_vfist(env->dbg, irg, block, get_irg_frame(irg), noreg, op, get_irg_no_mem(irg));
2026
2027         set_ia32_frame_ent(fist, ent);
2028         set_ia32_use_frame(fist);
2029         set_ia32_am_support(fist, ia32_am_Dest);
2030         set_ia32_op_type(fist, ia32_AddrModeD);
2031         set_ia32_am_flavour(fist, ia32_B);
2032         set_ia32_ls_mode(fist, mode_F);
2033
2034         mem  = new_r_Proj(irg, block, fist, mode_M, pn_ia32_vfist_M);
2035
2036         /* do a Load */
2037         load = new_rd_ia32_Load(env->dbg, irg, block, get_irg_frame(irg), noreg, mem);
2038
2039         set_ia32_frame_ent(load, ent);
2040         set_ia32_use_frame(load);
2041         set_ia32_am_support(load, ia32_am_Source);
2042         set_ia32_op_type(load, ia32_AddrModeS);
2043         set_ia32_am_flavour(load, ia32_B);
2044         set_ia32_ls_mode(load, tgt_mode);
2045
2046         return new_r_Proj(irg, block, load, tgt_mode, pn_ia32_Load_res);
2047 }
2048
2049 /**
2050  * Create a conversion from x87 state register to general purpose.
2051  */
2052 static ir_node *gen_x87_gp_to_fp(ia32_transform_env_t *env, ir_mode *src_mode) {
2053         ia32_code_gen_t *cg = env->cg;
2054         entity   *ent = cg->gp_to_fp;
2055         ir_graph *irg = env->irg;
2056         ir_node  *block = env->block;
2057         ir_node  *noreg = ia32_new_NoReg_gp(env->cg);
2058         ir_node  *nomem = get_irg_no_mem(irg);
2059         ir_node  *op = get_Conv_op(env->irn);
2060         ir_node  *fild, *store, *mem;
2061         int src_bits;
2062
2063         if (! ent) {
2064                 int size = get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_gp].mode);
2065                 ent = cg->gp_to_fp =
2066                         frame_alloc_area(get_irg_frame_type(env->irg), size, size, 0);
2067         }
2068
2069         /* first convert to 32 bit */
2070         src_bits = get_mode_size_bits(src_mode);
2071         if (src_bits == 8) {
2072                 op = new_rd_ia32_Conv_I2I8Bit(env->dbg, irg, block, noreg, noreg, op, nomem);
2073                 op = new_r_Proj(irg, block, op, mode_Is, 0);
2074         }
2075         else if (src_bits < 32) {
2076                 op = new_rd_ia32_Conv_I2I(env->dbg, irg, block, noreg, noreg, op, nomem);
2077                 op = new_r_Proj(irg, block, op, mode_Is, 0);
2078         }
2079
2080         /* do a store */
2081         store = new_rd_ia32_Store(env->dbg, irg, block, get_irg_frame(irg), noreg, op, nomem);
2082
2083         set_ia32_frame_ent(store, ent);
2084         set_ia32_use_frame(store);
2085
2086         set_ia32_am_support(store, ia32_am_Dest);
2087         set_ia32_op_type(store, ia32_AddrModeD);
2088         set_ia32_am_flavour(store, ia32_B);
2089         set_ia32_ls_mode(store, mode_Is);
2090
2091         mem = new_r_Proj(irg, block, store, mode_M, pn_ia32_Store_M);
2092
2093         /* do a fild */
2094         fild = new_rd_ia32_vfild(env->dbg, irg, block, get_irg_frame(irg), noreg, mem);
2095
2096         set_ia32_frame_ent(fild, ent);
2097         set_ia32_use_frame(fild);
2098         set_ia32_am_support(fild, ia32_am_Source);
2099         set_ia32_op_type(fild, ia32_AddrModeS);
2100         set_ia32_am_flavour(fild, ia32_B);
2101         set_ia32_ls_mode(fild, mode_F);
2102
2103         return new_r_Proj(irg, block, fild, mode_F, pn_ia32_vfild_res);
2104 }
2105
2106 /**
2107  * Transforms a Conv node.
2108  *
2109  * @param env   The transformation environment
2110  * @return The created ia32 Conv node
2111  */
2112 static ir_node *gen_Conv(ia32_transform_env_t *env) {
2113         dbg_info *dbg      = env->dbg;
2114         ir_graph *irg      = env->irg;
2115         ir_node  *op       = get_Conv_op(env->irn);
2116         ir_mode  *src_mode = get_irn_mode(op);
2117         ir_mode  *tgt_mode = env->mode;
2118         int      src_bits  = get_mode_size_bits(src_mode);
2119         int      tgt_bits  = get_mode_size_bits(tgt_mode);
2120         int      pn        = -1;
2121         int      kill      = 0;
2122         ir_node  *block    = env->block;
2123         ir_node  *new_op   = NULL;
2124         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
2125         ir_node  *nomem    = new_rd_NoMem(irg);
2126         ir_node  *proj;
2127         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
2128
2129         if (src_mode == tgt_mode) {
2130                 /* this can happen when changing mode_P to mode_Is */
2131                 DB((mod, LEVEL_1, "killed Conv(mode, mode) ..."));
2132                 edges_reroute(env->irn, op, irg);
2133         }
2134         else if (mode_is_float(src_mode)) {
2135                 /* we convert from float ... */
2136                 if (mode_is_float(tgt_mode)) {
2137                         /* ... to float */
2138                         if (USE_SSE2(env->cg)) {
2139                                 DB((mod, LEVEL_1, "create Conv(float, float) ..."));
2140                                 new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem);
2141                                 pn     = pn_ia32_Conv_FP2FP_res;
2142                         }
2143                         else {
2144                                 DB((mod, LEVEL_1, "killed Conv(float, float) ..."));
2145                                 /*
2146                                         remark: we create a intermediate conv here, so modes will be spread correctly
2147                                         these convs will be killed later
2148                                 */
2149                                 new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem);
2150                                 pn     = pn_ia32_Conv_FP2FP_res;
2151                                 kill   = 1;
2152                         }
2153                 }
2154                 else {
2155                         /* ... to int */
2156                         DB((mod, LEVEL_1, "create Conv(float, int) ..."));
2157                         if (USE_SSE2(env->cg)) {
2158                                 new_op = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, op, nomem);
2159                                 pn     = pn_ia32_Conv_FP2I_res;
2160                         }
2161                         else
2162                                 return gen_x87_fp_to_gp(env, tgt_mode);
2163
2164                         /* if target mode is not int: add an additional downscale convert */
2165                         if (tgt_bits < 32) {
2166                                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2167                                 set_ia32_am_support(new_op, ia32_am_Source);
2168                                 set_ia32_tgt_mode(new_op, mode_Is);
2169                                 set_ia32_src_mode(new_op, src_mode);
2170
2171                                 proj = new_rd_Proj(dbg, irg, block, new_op, mode_Is, pn_ia32_Conv_FP2I_res);
2172
2173                                 if (tgt_bits == 8 || src_bits == 8) {
2174                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, proj, nomem);
2175                                         pn     = pn_ia32_Conv_I2I8Bit_res;
2176                                 }
2177                                 else {
2178                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, proj, nomem);
2179                                         pn     = pn_ia32_Conv_I2I_res;
2180                                 }
2181                                 src_mode = mode_Is;
2182                         }
2183                 }
2184         }
2185         else {
2186                 /* we convert from int ... */
2187                 if (mode_is_float(tgt_mode)) {
2188                         FP_USED(env->cg);
2189                         /* ... to float */
2190                         DB((mod, LEVEL_1, "create Conv(int, float) ..."));
2191                         if (USE_SSE2(env->cg)) {
2192                                 new_op = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, op, nomem);
2193                                 pn     = pn_ia32_Conv_I2FP_res;
2194                         }
2195                         else
2196                                 return gen_x87_gp_to_fp(env, src_mode);
2197                 }
2198                 else {
2199                         /* ... to int */
2200                         if (get_mode_size_bits(src_mode) == tgt_bits) {
2201                                 DB((mod, LEVEL_1, "omitting equal size Conv(%+F, %+F) ...", src_mode, tgt_mode));
2202                                 /*
2203                                         remark: we create a intermediate conv here, so modes will be spread correctly
2204                                         these convs will be killed later
2205                                 */
2206                                 new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem);
2207                                 pn     = pn_ia32_Conv_I2I_res;
2208                                 kill   = 1;
2209                         }
2210                         else {
2211                                 DB((mod, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode));
2212                                 if (tgt_bits == 8 || src_bits == 8) {
2213                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, op, nomem);
2214                                         pn     = pn_ia32_Conv_I2I8Bit_res;
2215                                 }
2216                                 else {
2217                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem);
2218                                         pn     = pn_ia32_Conv_I2I_res;
2219                                 }
2220                         }
2221                 }
2222         }
2223
2224         if (new_op) {
2225                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2226                 set_ia32_tgt_mode(new_op, tgt_mode);
2227                 set_ia32_src_mode(new_op, src_mode);
2228
2229                 if(tgt_bits >= src_bits)
2230                         set_ia32_am_support(new_op, ia32_am_Source);
2231
2232                 new_op = new_rd_Proj(dbg, irg, block, new_op, tgt_mode, pn);
2233
2234                 if (kill)
2235                         nodeset_insert(env->cg->kill_conv, new_op);
2236         }
2237
2238         return new_op;
2239 }
2240
2241
2242
2243 /********************************************
2244  *  _                          _
2245  * | |                        | |
2246  * | |__   ___ _ __   ___   __| | ___  ___
2247  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
2248  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
2249  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
2250  *
2251  ********************************************/
2252
2253 static ir_node *gen_be_StackParam(ia32_transform_env_t *env) {
2254         ir_node *new_op = NULL;
2255         ir_node *node   = env->irn;
2256         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2257         ir_node *mem    = new_rd_NoMem(env->irg);
2258         ir_node *ptr    = get_irn_n(node, 0);
2259         entity  *ent    = arch_get_frame_entity(env->cg->arch_env, node);
2260         ir_mode *mode   = env->mode;
2261         long    pn_res;
2262
2263         if (mode_is_float(mode)) {
2264                 FP_USED(env->cg);
2265                 if (USE_SSE2(env->cg)) {
2266                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
2267                         pn_res = pn_ia32_xLoad_res;
2268                 }
2269                 else {
2270                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
2271                         pn_res = pn_ia32_vfld_res;
2272                 }
2273         }
2274         else {
2275                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
2276                 pn_res = pn_ia32_Load_res;
2277         }
2278
2279         set_ia32_frame_ent(new_op, ent);
2280         set_ia32_use_frame(new_op);
2281
2282         set_ia32_am_support(new_op, ia32_am_Source);
2283         set_ia32_op_type(new_op, ia32_AddrModeS);
2284         set_ia32_am_flavour(new_op, ia32_B);
2285         set_ia32_ls_mode(new_op, mode);
2286         set_ia32_flags(new_op, get_ia32_flags(new_op) | arch_irn_flags_rematerializable);
2287
2288         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2289
2290         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_res);
2291 }
2292
2293 /**
2294  * Transforms a FrameAddr into an ia32 Add.
2295  */
2296 static ir_node *gen_be_FrameAddr(ia32_transform_env_t *env) {
2297         ir_node *new_op = NULL;
2298         ir_node *node   = env->irn;
2299         ir_node *op     = get_irn_n(node, 0);
2300         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2301         ir_node *nomem  = new_rd_NoMem(env->irg);
2302
2303         new_op = new_rd_ia32_Add(env->dbg, env->irg, env->block, noreg, noreg, op, noreg, nomem);
2304         set_ia32_frame_ent(new_op, arch_get_frame_entity(env->cg->arch_env, node));
2305         set_ia32_am_support(new_op, ia32_am_Full);
2306         set_ia32_use_frame(new_op);
2307         set_ia32_immop_type(new_op, ia32_ImmConst);
2308         set_ia32_commutative(new_op);
2309
2310         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2311
2312         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, pn_ia32_Add_res);
2313 }
2314
2315 /**
2316  * Transforms a FrameLoad into an ia32 Load.
2317  */
2318 static ir_node *gen_be_FrameLoad(ia32_transform_env_t *env) {
2319         ir_node *new_op = NULL;
2320         ir_node *node   = env->irn;
2321         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2322         ir_node *mem    = get_irn_n(node, 0);
2323         ir_node *ptr    = get_irn_n(node, 1);
2324         entity  *ent    = arch_get_frame_entity(env->cg->arch_env, node);
2325         ir_mode *mode   = get_type_mode(get_entity_type(ent));
2326         ir_node *projs[pn_Load_max];
2327
2328         ia32_collect_Projs(env->irn, projs, pn_Load_max);
2329
2330         if (mode_is_float(mode)) {
2331                 FP_USED(env->cg);
2332                 if (USE_SSE2(env->cg)) {
2333                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
2334                         ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_xLoad_M);
2335                         ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_xLoad_res);
2336                 }
2337                 else {
2338                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
2339                         ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_vfld_M);
2340                         ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_vfld_res);
2341                 }
2342         }
2343         else {
2344                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
2345                 ia32_renumber_Proj(projs, pn_Load_M, pn_ia32_Load_M);
2346                 ia32_renumber_Proj(projs, pn_Load_res, pn_ia32_Load_res);
2347         }
2348
2349         set_ia32_frame_ent(new_op, ent);
2350         set_ia32_use_frame(new_op);
2351
2352         set_ia32_am_support(new_op, ia32_am_Source);
2353         set_ia32_op_type(new_op, ia32_AddrModeS);
2354         set_ia32_am_flavour(new_op, ia32_B);
2355         set_ia32_ls_mode(new_op, mode);
2356
2357         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2358
2359         return new_op;
2360 }
2361
2362
2363 /**
2364  * Transforms a FrameStore into an ia32 Store.
2365  */
2366 static ir_node *gen_be_FrameStore(ia32_transform_env_t *env) {
2367         ir_node *new_op = NULL;
2368         ir_node *node   = env->irn;
2369         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2370         ir_node *mem    = get_irn_n(node, 0);
2371         ir_node *ptr    = get_irn_n(node, 1);
2372         ir_node *val    = get_irn_n(node, 2);
2373         entity  *ent    = arch_get_frame_entity(env->cg->arch_env, node);
2374         ir_mode *mode   = get_irn_mode(val);
2375         ir_node *projs[pn_Store_max];
2376
2377         ia32_collect_Projs(env->irn, projs, pn_Store_max);
2378
2379         if (mode_is_float(mode)) {
2380                 FP_USED(env->cg);
2381                 if (USE_SSE2(env->cg)) {
2382                         new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2383                         ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_xStore_M);
2384                 }
2385                 else {
2386                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2387                         ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_vfst_M);
2388                 }
2389         }
2390         else if (get_mode_size_bits(mode) == 8) {
2391                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2392                 ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_Store8Bit_M);
2393         }
2394         else {
2395                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2396                 ia32_renumber_Proj(projs, pn_Store_M, pn_ia32_Store_M);
2397         }
2398
2399         set_ia32_frame_ent(new_op, ent);
2400         set_ia32_use_frame(new_op);
2401
2402         set_ia32_am_support(new_op, ia32_am_Dest);
2403         set_ia32_op_type(new_op, ia32_AddrModeD);
2404         set_ia32_am_flavour(new_op, ia32_B);
2405         set_ia32_ls_mode(new_op, mode);
2406
2407         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2408
2409         return new_op;
2410 }
2411
2412 /**
2413  * In case SSE is used we need to copy the result from FPU TOS.
2414  */
2415 static ir_node *gen_be_Call(ia32_transform_env_t *env) {
2416         ir_node *call_res = get_proj_for_pn(env->irn, pn_be_Call_first_res);
2417         ir_node *call_mem = get_proj_for_pn(env->irn, pn_be_Call_M_regular);
2418         ir_mode *mode;
2419
2420         if (! call_res || ! USE_SSE2(env->cg))
2421                 return NULL;
2422
2423         mode = get_irn_mode(call_res);
2424
2425         /* in case there is no memory output: create one to serialize the copy FPU -> SSE */
2426         if (! call_mem)
2427                 call_mem = new_r_Proj(env->irg, env->block, env->irn, mode_M, pn_be_Call_M_regular);
2428
2429         if (mode_is_float(mode)) {
2430                 /* store st(0) onto stack */
2431                 ir_node *frame = get_irg_frame(env->irg);
2432                 ir_node *fstp  = new_rd_ia32_GetST0(env->dbg, env->irg, env->block, frame, call_mem);
2433                 ir_node *mproj = new_r_Proj(env->irg, env->block, fstp, mode_M, pn_ia32_GetST0_M);
2434                 entity  *ent   = frame_alloc_area(get_irg_frame_type(env->irg), get_mode_size_bytes(mode), 16, 0);
2435                 ir_node *sse_load, *p, *bad, *keep;
2436                 ir_node **in_keep;
2437                 int     keep_arity, i;
2438
2439                 set_ia32_ls_mode(fstp, mode);
2440                 set_ia32_op_type(fstp, ia32_AddrModeD);
2441                 set_ia32_use_frame(fstp);
2442                 set_ia32_frame_ent(fstp, ent);
2443                 set_ia32_am_flavour(fstp, ia32_B);
2444                 set_ia32_am_support(fstp, ia32_am_Dest);
2445
2446                 /* load into SSE register */
2447                 sse_load = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, frame, ia32_new_NoReg_gp(env->cg), mproj);
2448                 set_ia32_ls_mode(sse_load, mode);
2449                 set_ia32_op_type(sse_load, ia32_AddrModeS);
2450                 set_ia32_use_frame(sse_load);
2451                 set_ia32_frame_ent(sse_load, ent);
2452                 set_ia32_am_flavour(sse_load, ia32_B);
2453                 set_ia32_am_support(sse_load, ia32_am_Source);
2454                 sse_load = new_r_Proj(env->irg, env->block, sse_load, mode, pn_ia32_xLoad_res);
2455
2456                 /* reroute all users of the result proj to the sse load */
2457                 edges_reroute(call_res, sse_load, env->irg);
2458
2459                 /* now: create new Keep whith all former ins and one additional in - the result Proj */
2460
2461                 /* get a Proj representing a caller save register */
2462                 p = get_proj_for_pn(env->irn, pn_be_Call_first_res + 1);
2463                 assert(is_Proj(p) && "Proj expected.");
2464
2465                 /* user of the the proj is the Keep */
2466                 p = get_edge_src_irn(get_irn_out_edge_first(p));
2467                 assert(be_is_Keep(p) && "Keep expected.");
2468
2469                 /* copy in array of the old keep and set the result proj as additional in */
2470                 keep_arity = get_irn_arity(p) + 1;
2471                 NEW_ARR_A(ir_node *, in_keep, keep_arity);
2472                 in_keep[keep_arity - 1] = call_res;
2473                 for (i = 0; i < keep_arity - 1; ++i)
2474                         in_keep[i] = get_irn_n(p, i);
2475
2476                 /* create new keep and set the in class requirements properly */
2477                 keep = be_new_Keep(NULL, env->irg, env->block, keep_arity, in_keep);
2478                 for(i = 0; i < keep_arity; ++i) {
2479                         const arch_register_class_t *cls = arch_get_irn_reg_class(env->cg->arch_env, in_keep[i], -1);
2480                         be_node_set_reg_class(keep, i, cls);
2481                 }
2482
2483                 /* kill the old keep */
2484                 bad = get_irg_bad(env->irg);
2485                 for (i = 0; i < keep_arity - 1; i++)
2486                         set_irn_n(p, i, bad);
2487                 remove_End_keepalive(get_irg_end(env->irg), p);
2488         }
2489
2490         return NULL;
2491 }
2492
2493 /**
2494  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
2495  */
2496 static ir_node *gen_be_Return(ia32_transform_env_t *env) {
2497         ir_node *ret_val = get_irn_n(env->irn, be_pos_Return_val);
2498         ir_node *ret_mem = get_irn_n(env->irn, be_pos_Return_mem);
2499         entity *ent      = get_irg_entity(get_irn_irg(ret_val));
2500         ir_type *tp      = get_entity_type(ent);
2501
2502         if (be_Return_get_n_rets(env->irn) < 1 || ! ret_val || ! USE_SSE2(env->cg))
2503                 return NULL;
2504
2505         if (get_method_n_ress(tp) == 1) {
2506                 ir_type *res_type = get_method_res_type(tp, 0);
2507                 ir_mode *mode;
2508
2509                 if (is_Primitive_type(res_type)) {
2510                         mode = get_type_mode(res_type);
2511                         if (mode_is_float(mode)) {
2512                                 ir_node *frame;
2513                                 entity  *ent;
2514                                 ir_node *sse_store, *fld, *mproj, *barrier;
2515                                 int     pn_ret_val = get_Proj_proj(ret_val);
2516                                 int     pn_ret_mem = get_Proj_proj(ret_mem);
2517
2518                                 /* get the Barrier */
2519                                 barrier = get_Proj_pred(ret_val);
2520
2521                                 /* get result input of the Barrier */
2522                                 ret_val = get_irn_n(barrier, pn_ret_val);
2523
2524                                 /* get memory input of the Barrier */
2525                                 ret_mem = get_irn_n(barrier, pn_ret_mem);
2526
2527                                 frame = get_irg_frame(env->irg);
2528                                 ent   = frame_alloc_area(get_irg_frame_type(env->irg), get_mode_size_bytes(mode), 16, 0);
2529
2530                                 /* store xmm0 onto stack */
2531                                 sse_store = new_rd_ia32_xStoreSimple(env->dbg, env->irg, env->block, frame, ret_val, ret_mem);
2532                                 set_ia32_ls_mode(sse_store, mode);
2533                                 set_ia32_op_type(sse_store, ia32_AddrModeD);
2534                                 set_ia32_use_frame(sse_store);
2535                                 set_ia32_frame_ent(sse_store, ent);
2536                                 set_ia32_am_flavour(sse_store, ia32_B);
2537                                 set_ia32_am_support(sse_store, ia32_am_Dest);
2538                                 sse_store = new_r_Proj(env->irg, env->block, sse_store, mode_M, pn_ia32_xStore_M);
2539
2540                                 /* load into st0 */
2541                                 fld = new_rd_ia32_SetST0(env->dbg, env->irg, env->block, frame, sse_store);
2542                                 set_ia32_ls_mode(fld, mode);
2543                                 set_ia32_op_type(fld, ia32_AddrModeS);
2544                                 set_ia32_use_frame(fld);
2545                                 set_ia32_frame_ent(fld, ent);
2546                                 set_ia32_am_flavour(fld, ia32_B);
2547                                 set_ia32_am_support(fld, ia32_am_Source);
2548                                 mproj = new_r_Proj(env->irg, env->block, fld, mode_M, pn_ia32_SetST0_M);
2549                                 fld   = new_r_Proj(env->irg, env->block, fld, mode, pn_ia32_SetST0_res);
2550                                 arch_set_irn_register(env->cg->arch_env, fld, &ia32_vfp_regs[REG_VF0]);
2551
2552                                 /* set new return value */
2553                                 set_irn_n(barrier, pn_ret_val, fld);
2554                                 set_irn_n(barrier, pn_ret_mem, mproj);
2555                         }
2556                 }
2557         }
2558
2559         return NULL;
2560 }
2561
2562 /**
2563  * Transform a be_AddSP into an ia32_AddSP. Eat up const sizes.
2564  */
2565 static ir_node *gen_be_AddSP(ia32_transform_env_t *env) {
2566         ir_node *new_op;
2567         const ir_edge_t *edge;
2568         ir_node *sz = get_irn_n(env->irn, be_pos_AddSP_size);
2569         ir_node *sp = get_irn_n(env->irn, be_pos_AddSP_old_sp);
2570
2571         new_op = new_rd_ia32_AddSP(env->dbg, env->irg, env->block, sp, sz);
2572
2573         if (is_ia32_Const(sz)) {
2574                 set_ia32_Immop_attr(new_op, sz);
2575                 set_irn_n(new_op, 1, ia32_new_NoReg_gp(env->cg));
2576         }
2577         else if (is_ia32_Load(sz) && get_ia32_am_flavour(sz) == ia32_O) {
2578                 set_ia32_immop_type(new_op, ia32_ImmSymConst);
2579                 set_ia32_op_type(new_op, ia32_AddrModeS);
2580                 set_ia32_am_sc(new_op, get_ia32_am_sc(sz));
2581                 add_ia32_am_offs(new_op, get_ia32_am_offs(sz));
2582                 set_irn_n(new_op, 1, ia32_new_NoReg_gp(env->cg));
2583         }
2584
2585         /* fix proj nums */
2586         foreach_out_edge(env->irn, edge) {
2587                 ir_node *proj = get_edge_src_irn(edge);
2588
2589                 assert(is_Proj(proj));
2590
2591                 if (get_Proj_proj(proj) == pn_be_AddSP_res) {
2592                         /* the node is not yet exchanged: we need to set the register manually */
2593                         ia32_attr_t *attr = get_ia32_attr(new_op);
2594                         attr->slots[pn_ia32_AddSP_stack] = &ia32_gp_regs[REG_ESP];
2595                         set_Proj_proj(proj, pn_ia32_AddSP_stack);
2596                 }
2597                 else if (get_Proj_proj(proj) == pn_be_AddSP_M) {
2598                         set_Proj_proj(proj, pn_ia32_AddSP_M);
2599                 }
2600                 else {
2601                         assert(0);
2602                 }
2603         }
2604
2605         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2606
2607         return new_op;
2608 }
2609
2610 /**
2611  * Transform a be_SubSP into an ia32_SubSP. Eat up const sizes.
2612  */
2613 static ir_node *gen_be_SubSP(ia32_transform_env_t *env) {
2614         ir_node *new_op;
2615         const ir_edge_t *edge;
2616         ir_node *sz = get_irn_n(env->irn, be_pos_SubSP_size);
2617         ir_node *sp = get_irn_n(env->irn, be_pos_SubSP_old_sp);
2618
2619         new_op = new_rd_ia32_SubSP(env->dbg, env->irg, env->block, sp, sz);
2620
2621         if (is_ia32_Const(sz)) {
2622                 set_ia32_Immop_attr(new_op, sz);
2623                 set_irn_n(new_op, 1, ia32_new_NoReg_gp(env->cg));
2624         }
2625         else if (is_ia32_Load(sz) && get_ia32_am_flavour(sz) == ia32_O) {
2626                 set_ia32_immop_type(new_op, ia32_ImmSymConst);
2627                 set_ia32_op_type(new_op, ia32_AddrModeS);
2628                 set_ia32_am_sc(new_op, get_ia32_am_sc(sz));
2629                 add_ia32_am_offs(new_op, get_ia32_am_offs(sz));
2630                 set_irn_n(new_op, 1, ia32_new_NoReg_gp(env->cg));
2631         }
2632
2633         /* fix proj nums */
2634         foreach_out_edge(env->irn, edge) {
2635                 ir_node *proj = get_edge_src_irn(edge);
2636
2637                 assert(is_Proj(proj));
2638
2639                 if (get_Proj_proj(proj) == pn_be_SubSP_res) {
2640                         /* the node is not yet exchanged: we need to set the register manually */
2641                         ia32_attr_t *attr = get_ia32_attr(new_op);
2642                         attr->slots[pn_ia32_SubSP_stack] = &ia32_gp_regs[REG_ESP];
2643                         set_Proj_proj(proj, pn_ia32_SubSP_stack);
2644                 }
2645                 else if (get_Proj_proj(proj) == pn_be_SubSP_M) {
2646                         set_Proj_proj(proj, pn_ia32_SubSP_M);
2647                 }
2648                 else {
2649                         assert(0);
2650                 }
2651         }
2652
2653         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2654
2655         return new_op;
2656 }
2657
2658 /**
2659  * This function just sets the register for the Unknown node
2660  * as this is not done during register allocation because Unknown
2661  * is an "ignore" node.
2662  */
2663 static ir_node *gen_Unknown(ia32_transform_env_t *env) {
2664         ir_mode *mode = env->mode;
2665         ir_node *irn  = env->irn;
2666
2667         if (mode_is_float(mode)) {
2668                 if (USE_SSE2(env->cg))
2669                         arch_set_irn_register(env->cg->arch_env, irn, &ia32_xmm_regs[REG_XMM_UKNWN]);
2670                 else
2671                         arch_set_irn_register(env->cg->arch_env, irn, &ia32_vfp_regs[REG_VFP_UKNWN]);
2672         }
2673         else if (mode_is_int(mode) || mode_is_reference(mode) || mode_is_character(mode)) {
2674                 arch_set_irn_register(env->cg->arch_env, irn, &ia32_gp_regs[REG_GP_UKNWN]);
2675         }
2676         else {
2677                 assert(0 && "unsupported Unknown-Mode");
2678         }
2679
2680         return NULL;
2681 }
2682
2683 /**********************************************************************
2684  *  _                                _                   _
2685  * | |                              | |                 | |
2686  * | | _____      _____ _ __ ___  __| |  _ __   ___   __| | ___  ___
2687  * | |/ _ \ \ /\ / / _ \ '__/ _ \/ _` | | '_ \ / _ \ / _` |/ _ \/ __|
2688  * | | (_) \ V  V /  __/ | |  __/ (_| | | | | | (_) | (_| |  __/\__ \
2689  * |_|\___/ \_/\_/ \___|_|  \___|\__,_| |_| |_|\___/ \__,_|\___||___/
2690  *
2691  **********************************************************************/
2692
2693 /* These nodes are created in intrinsic lowering (64bit -> 32bit) */
2694
2695 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
2696                                      ir_node *mem);
2697
2698 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
2699                                       ir_node *val, ir_node *mem);
2700
2701 /**
2702  * Transforms a lowered Load into a "real" one.
2703  */
2704 static ir_node *gen_lowered_Load(ia32_transform_env_t *env, construct_load_func func, char fp_unit) {
2705         ir_node *node  = env->irn;
2706         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
2707         ir_mode *mode  = get_ia32_ls_mode(node);
2708         ir_node *new_op;
2709         char    *am_offs;
2710         ia32_am_flavour_t am_flav = ia32_B;
2711
2712         /*
2713                 Could be that we have SSE2 unit, but due to 64Bit Div/Conv
2714                 lowering we have x87 nodes, so we need to enforce simulation.
2715         */
2716         if (mode_is_float(mode)) {
2717                 FP_USED(env->cg);
2718                 if (fp_unit == fp_x87)
2719                         FORCE_x87(env->cg);
2720         }
2721
2722         new_op  = func(env->dbg, env->irg, env->block, get_irn_n(node, 0), noreg, get_irn_n(node, 1));
2723         am_offs = get_ia32_am_offs(node);
2724
2725         if (am_offs) {
2726                 am_flav |= ia32_O;
2727                 add_ia32_am_offs(new_op, am_offs);
2728         }
2729
2730         set_ia32_am_support(new_op, ia32_am_Source);
2731         set_ia32_op_type(new_op, ia32_AddrModeS);
2732         set_ia32_am_flavour(new_op, am_flav);
2733         set_ia32_ls_mode(new_op, mode);
2734         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
2735         set_ia32_use_frame(new_op);
2736
2737         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2738
2739         return new_op;
2740 }
2741
2742 /**
2743 * Transforms a lowered Store into a "real" one.
2744 */
2745 static ir_node *gen_lowered_Store(ia32_transform_env_t *env, construct_store_func func, char fp_unit) {
2746         ir_node *node  = env->irn;
2747         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
2748         ir_mode *mode  = get_ia32_ls_mode(node);
2749         ir_node *new_op;
2750         char    *am_offs;
2751         ia32_am_flavour_t am_flav = ia32_B;
2752
2753         /*
2754                 Could be that we have SSE2 unit, but due to 64Bit Div/Conv
2755                 lowering we have x87 nodes, so we need to enforce simulation.
2756         */
2757         if (mode_is_float(mode)) {
2758                 FP_USED(env->cg);
2759                 if (fp_unit == fp_x87)
2760                         FORCE_x87(env->cg);
2761         }
2762
2763         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));
2764
2765         if ((am_offs = get_ia32_am_offs(node)) != NULL) {
2766                 am_flav |= ia32_O;
2767                 add_ia32_am_offs(new_op, am_offs);
2768         }
2769
2770         set_ia32_am_support(new_op, ia32_am_Dest);
2771         set_ia32_op_type(new_op, ia32_AddrModeD);
2772         set_ia32_am_flavour(new_op, am_flav);
2773         set_ia32_ls_mode(new_op, mode);
2774         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
2775         set_ia32_use_frame(new_op);
2776
2777         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2778
2779         return new_op;
2780 }
2781
2782
2783 /**
2784  * Transforms an ia32_l_XXX into a "real" XXX node
2785  *
2786  * @param env   The transformation environment
2787  * @return the created ia32 XXX node
2788  */
2789 #define GEN_LOWERED_OP(op)                                                                            \
2790         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                      \
2791                 if (mode_is_float(env->mode))                                                                 \
2792                         FP_USED(env->cg);                                                                         \
2793                 return gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2794         }
2795
2796 #define GEN_LOWERED_x87_OP(op)                                                                          \
2797         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                        \
2798                 ir_node *new_op;                                                                                \
2799                 FORCE_x87(env->cg);                                                                             \
2800                 new_op = gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2801                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_None);                                       \
2802                 return new_op;                                                                                  \
2803         }
2804
2805 #define GEN_LOWERED_UNOP(op)                                           \
2806         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {       \
2807                 return gen_unop(env, get_unop_op(env->irn), new_rd_ia32_##op); \
2808         }
2809
2810 #define GEN_LOWERED_SHIFT_OP(op)                                                                            \
2811         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                            \
2812                 return gen_shift_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2813         }
2814
2815 #define GEN_LOWERED_LOAD(op, fp_unit)                            \
2816         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) { \
2817                 return gen_lowered_Load(env, new_rd_ia32_##op, fp_unit); \
2818         }
2819
2820 #define GEN_LOWERED_STORE(op, fp_unit)                           \
2821         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) { \
2822         return gen_lowered_Store(env, new_rd_ia32_##op, fp_unit);    \
2823 }
2824
2825 GEN_LOWERED_OP(AddC)
2826 GEN_LOWERED_OP(Add)
2827 GEN_LOWERED_OP(SubC)
2828 GEN_LOWERED_OP(Sub)
2829 GEN_LOWERED_OP(Mul)
2830 GEN_LOWERED_OP(Eor)
2831 GEN_LOWERED_x87_OP(vfdiv)
2832 GEN_LOWERED_x87_OP(vfmul)
2833 GEN_LOWERED_x87_OP(vfsub)
2834
2835 GEN_LOWERED_UNOP(Minus)
2836
2837 GEN_LOWERED_LOAD(vfild, fp_x87)
2838 GEN_LOWERED_LOAD(Load, fp_none)
2839 GEN_LOWERED_STORE(vfist, fp_x87)
2840 GEN_LOWERED_STORE(Store, fp_none)
2841
2842 /**
2843  * Transforms a l_MulS into a "real" MulS node.
2844  *
2845  * @param env   The transformation environment
2846  * @return the created ia32 MulS node
2847  */
2848 static ir_node *gen_ia32_l_MulS(ia32_transform_env_t *env) {
2849
2850         /* l_MulS is already a mode_T node, so we create the MulS in the normal way   */
2851         /* and then skip the result Proj, because all needed Projs are already there. */
2852
2853         ir_node *new_op = gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_MulS);
2854         ir_node *muls   = get_Proj_pred(new_op);
2855         ir_node *proj;
2856
2857         /* MulS cannot have AM for destination */
2858         if (get_ia32_am_support(muls) != ia32_am_None)
2859                 set_ia32_am_support(muls, ia32_am_Source);
2860
2861         /* check if EAX and EDX proj exist, add missing one */
2862         proj = get_proj_for_pn(env->irn, pn_ia32_MulS_EAX);
2863         if (! proj) {
2864                 proj = new_r_Proj(env->irg, env->block, muls, get_ia32_res_mode(env->irn), pn_ia32_MulS_EAX);
2865                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], env->irg, env->block, 1, &proj);
2866         }
2867         proj = get_proj_for_pn(env->irn, pn_ia32_MulS_EDX);
2868         if (! proj) {
2869                 proj = new_r_Proj(env->irg, env->block, muls, get_ia32_res_mode(env->irn), pn_ia32_MulS_EDX);
2870                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], env->irg, env->block, 1, &proj);
2871         }
2872
2873         return muls;
2874 }
2875
2876 GEN_LOWERED_SHIFT_OP(Shl)
2877 GEN_LOWERED_SHIFT_OP(Shr)
2878 GEN_LOWERED_SHIFT_OP(Shrs)
2879
2880 /**
2881  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
2882  * op1 - target to be shifted
2883  * op2 - contains bits to be shifted into target
2884  * op3 - shift count
2885  * Only op3 can be an immediate.
2886  */
2887 static ir_node *gen_lowered_64bit_shifts(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, ir_node *count) {
2888         ir_node           *new_op = NULL;
2889         ir_mode           *mode   = env->mode;
2890         dbg_info          *dbg    = env->dbg;
2891         ir_graph          *irg    = env->irg;
2892         ir_node           *block  = env->block;
2893         ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
2894         ir_node           *nomem  = new_NoMem();
2895         ir_node           *imm_op;
2896         tarval            *tv;
2897         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
2898
2899         assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");
2900
2901         /* Check if immediate optimization is on and */
2902         /* if it's an operation with immediate.      */
2903         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, count) : NULL;
2904
2905         /* Limit imm_op within range imm8 */
2906         if (imm_op) {
2907                 tv = get_ia32_Immop_tarval(imm_op);
2908
2909                 if (tv) {
2910                         tv = tarval_mod(tv, new_tarval_from_long(32, mode_Iu));
2911                         set_ia32_Immop_tarval(imm_op, tv);
2912                 }
2913                 else {
2914                         imm_op = NULL;
2915                 }
2916         }
2917
2918         /* integer operations */
2919         if (imm_op) {
2920                 /* This is ShiftD with const */
2921                 DB((mod, LEVEL_1, "ShiftD with immediate ..."));
2922
2923                 if (is_ia32_l_ShlD(env->irn))
2924                         new_op = new_rd_ia32_ShlD(dbg, irg, block, noreg, noreg, op1, op2, noreg, nomem);
2925                 else
2926                         new_op = new_rd_ia32_ShrD(dbg, irg, block, noreg, noreg, op1, op2, noreg, nomem);
2927                 set_ia32_Immop_attr(new_op, imm_op);
2928         }
2929         else {
2930                 /* This is a normal ShiftD */
2931                 DB((mod, LEVEL_1, "ShiftD binop ..."));
2932                 if (is_ia32_l_ShlD(env->irn))
2933                         new_op = new_rd_ia32_ShlD(dbg, irg, block, noreg, noreg, op1, op2, count, nomem);
2934                 else
2935                         new_op = new_rd_ia32_ShrD(dbg, irg, block, noreg, noreg, op1, op2, count, nomem);
2936         }
2937
2938         /* set AM support */
2939         set_ia32_am_support(new_op, ia32_am_Dest);
2940
2941         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2942
2943         set_ia32_res_mode(new_op, mode);
2944         set_ia32_emit_cl(new_op);
2945
2946         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
2947 }
2948
2949 static ir_node *gen_ia32_l_ShlD(ia32_transform_env_t *env) {
2950         return gen_lowered_64bit_shifts(env, get_irn_n(env->irn, 0), get_irn_n(env->irn, 1), get_irn_n(env->irn, 2));
2951 }
2952
2953 static ir_node *gen_ia32_l_ShrD(ia32_transform_env_t *env) {
2954         return gen_lowered_64bit_shifts(env, get_irn_n(env->irn, 0), get_irn_n(env->irn, 1), get_irn_n(env->irn, 2));
2955 }
2956
2957 /**
2958  * In case SSE Unit is used, the node is transformed into a vfst + xLoad.
2959  */
2960 static ir_node *gen_ia32_l_X87toSSE(ia32_transform_env_t *env) {
2961         ia32_code_gen_t *cg  = env->cg;
2962         ir_node         *res = NULL;
2963         ir_node         *ptr = get_irn_n(env->irn, 0);
2964         ir_node         *val = get_irn_n(env->irn, 1);
2965         ir_node         *mem = get_irn_n(env->irn, 2);
2966
2967         if (USE_SSE2(cg)) {
2968                 ir_node *noreg = ia32_new_NoReg_gp(cg);
2969
2970                 /* Store x87 -> MEM */
2971                 res = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2972                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
2973                 set_ia32_use_frame(res);
2974                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
2975                 set_ia32_am_support(res, ia32_am_Dest);
2976                 set_ia32_am_flavour(res, ia32_B);
2977                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_vfst_M);
2978
2979                 /* Load MEM -> SSE */
2980                 res = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, res);
2981                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
2982                 set_ia32_use_frame(res);
2983                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
2984                 set_ia32_am_support(res, ia32_am_Source);
2985                 set_ia32_am_flavour(res, ia32_B);
2986                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, get_ia32_ls_mode(env->irn), pn_ia32_xLoad_res);
2987         }
2988         else {
2989                 /* SSE unit is not used -> skip this node. */
2990                 int i;
2991
2992                 edges_reroute(env->irn, val, env->irg);
2993                 for (i = get_irn_arity(env->irn) - 1; i >= 0; i--)
2994                         set_irn_n(env->irn, i, get_irg_bad(env->irg));
2995         }
2996
2997         return res;
2998 }
2999
3000 /**
3001  * In case SSE Unit is used, the node is transformed into a xStore + vfld.
3002  */
3003 static ir_node *gen_ia32_l_SSEtoX87(ia32_transform_env_t *env) {
3004         ia32_code_gen_t *cg  = env->cg;
3005         ir_node         *res = NULL;
3006         ir_node         *ptr = get_irn_n(env->irn, 0);
3007         ir_node         *val = get_irn_n(env->irn, 1);
3008         ir_node         *mem = get_irn_n(env->irn, 2);
3009
3010         if (USE_SSE2(cg)) {
3011                 ir_node *noreg = ia32_new_NoReg_gp(cg);
3012
3013                 /* Store SSE -> MEM */
3014                 res = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
3015                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
3016                 set_ia32_use_frame(res);
3017                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
3018                 set_ia32_am_support(res, ia32_am_Dest);
3019                 set_ia32_am_flavour(res, ia32_B);
3020                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_xStore_M);
3021
3022                 /* Load MEM -> x87 */
3023                 res = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
3024                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
3025                 set_ia32_use_frame(res);
3026                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
3027                 set_ia32_am_support(res, ia32_am_Source);
3028                 set_ia32_am_flavour(res, ia32_B);
3029                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, get_ia32_ls_mode(env->irn), pn_ia32_vfld_res);
3030         }
3031         else {
3032                 /* SSE unit is not used -> skip this node. */
3033                 int i;
3034
3035                 edges_reroute(env->irn, val, env->irg);
3036                 for (i = get_irn_arity(env->irn) - 1; i >= 0; i--)
3037                         set_irn_n(env->irn, i, get_irg_bad(env->irg));
3038         }
3039
3040         return res;
3041 }
3042
3043 /*********************************************************
3044  *                  _             _      _
3045  *                 (_)           | |    (_)
3046  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
3047  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
3048  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
3049  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
3050  *
3051  *********************************************************/
3052
3053 /**
3054  * the BAD transformer.
3055  */
3056 static ir_node *bad_transform(ia32_transform_env_t *env) {
3057         ir_fprintf(stderr, "Not implemented: %+F\n", env->irn);
3058         assert(0);
3059         return NULL;
3060 }
3061
3062 /**
3063  * Enters all transform functions into the generic pointer
3064  */
3065 void ia32_register_transformers(void) {
3066         ir_op *op_Max, *op_Min, *op_Mulh;
3067
3068         /* first clear the generic function pointer for all ops */
3069         clear_irp_opcodes_generic_func();
3070
3071 #define GEN(a)   op_##a->ops.generic = (op_func)gen_##a
3072 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
3073 #define IGN(a)
3074
3075         GEN(Add);
3076         GEN(Sub);
3077         GEN(Mul);
3078         GEN(And);
3079         GEN(Or);
3080         GEN(Eor);
3081
3082         GEN(Shl);
3083         GEN(Shr);
3084         GEN(Shrs);
3085         GEN(Rot);
3086
3087         GEN(Quot);
3088
3089         GEN(Div);
3090         GEN(Mod);
3091         GEN(DivMod);
3092
3093         GEN(Minus);
3094         GEN(Conv);
3095         GEN(Abs);
3096         GEN(Not);
3097
3098         GEN(Load);
3099         GEN(Store);
3100         GEN(Cond);
3101
3102         GEN(CopyB);
3103         GEN(Mux);
3104         GEN(Psi);
3105
3106         /* transform ops from intrinsic lowering */
3107         GEN(ia32_l_Add);
3108         GEN(ia32_l_AddC);
3109         GEN(ia32_l_Sub);
3110         GEN(ia32_l_SubC);
3111         GEN(ia32_l_Minus);
3112         GEN(ia32_l_Mul);
3113         GEN(ia32_l_Eor);
3114         GEN(ia32_l_MulS);
3115         GEN(ia32_l_Shl);
3116         GEN(ia32_l_Shr);
3117         GEN(ia32_l_Shrs);
3118         GEN(ia32_l_ShlD);
3119         GEN(ia32_l_ShrD);
3120         GEN(ia32_l_vfdiv);
3121         GEN(ia32_l_vfmul);
3122         GEN(ia32_l_vfsub);
3123         GEN(ia32_l_vfild);
3124         GEN(ia32_l_Load);
3125         GEN(ia32_l_vfist);
3126         GEN(ia32_l_Store);
3127         GEN(ia32_l_X87toSSE);
3128         GEN(ia32_l_SSEtoX87);
3129
3130         IGN(Call);
3131         IGN(Alloc);
3132
3133         IGN(Proj);
3134         IGN(Block);
3135         IGN(Start);
3136         IGN(End);
3137         IGN(NoMem);
3138         IGN(Phi);
3139         IGN(IJmp);
3140         IGN(Break);
3141         IGN(Cmp);
3142
3143         /* constant transformation happens earlier */
3144         IGN(Const);
3145         IGN(SymConst);
3146         IGN(Sync);
3147
3148         /* we should never see these nodes */
3149         BAD(Raise);
3150         BAD(Sel);
3151         BAD(InstOf);
3152         BAD(Cast);
3153         BAD(Free);
3154         BAD(Tuple);
3155         BAD(Id);
3156         BAD(Bad);
3157         BAD(Confirm);
3158         BAD(Filter);
3159         BAD(CallBegin);
3160         BAD(EndReg);
3161         BAD(EndExcept);
3162
3163         /* handle generic backend nodes */
3164         GEN(be_FrameAddr);
3165         GEN(be_Call);
3166         GEN(be_Return);
3167         GEN(be_FrameLoad);
3168         GEN(be_FrameStore);
3169         GEN(be_StackParam);
3170         GEN(be_AddSP);
3171         GEN(be_SubSP);
3172
3173         /* set the register for all Unknown nodes */
3174         GEN(Unknown);
3175
3176         op_Max = get_op_Max();
3177         if (op_Max)
3178                 GEN(Max);
3179         op_Min = get_op_Min();
3180         if (op_Min)
3181                 GEN(Min);
3182         op_Mulh = get_op_Mulh();
3183         if (op_Mulh)
3184                 GEN(Mulh);
3185
3186 #undef GEN
3187 #undef BAD
3188 #undef IGN
3189 }
3190
3191 typedef ir_node *(transform_func)(ia32_transform_env_t *env);
3192
3193 /**
3194  * Transforms the given firm node (and maybe some other related nodes)
3195  * into one or more assembler nodes.
3196  *
3197  * @param node    the firm node
3198  * @param env     the debug module
3199  */
3200 void ia32_transform_node(ir_node *node, void *env) {
3201         ia32_code_gen_t *cg = (ia32_code_gen_t *)env;
3202         ir_op *op           = get_irn_op(node);
3203         ir_node *asm_node   = NULL;
3204         int i;
3205
3206         if (is_Block(node))
3207                 return;
3208
3209         /* link arguments pointing to Unknown to the UNKNOWN Proj */
3210         for (i = get_irn_arity(node) - 1; i >= 0; i--) {
3211                 if (is_Unknown(get_irn_n(node, i)))
3212                         set_irn_n(node, i, be_get_unknown_for_mode(cg, get_irn_mode(get_irn_n(node, i))));
3213         }
3214
3215         DBG((cg->mod, LEVEL_1, "check %+F ... ", node));
3216         if (op->ops.generic) {
3217                 ia32_transform_env_t  tenv;
3218                 transform_func *transform = (transform_func *)op->ops.generic;
3219
3220                 tenv.block = get_nodes_block(node);
3221                 tenv.dbg   = get_irn_dbg_info(node);
3222                 tenv.irg   = current_ir_graph;
3223                 tenv.irn   = node;
3224                 tenv.mode  = get_irn_mode(node);
3225                 tenv.cg    = cg;
3226                 DEBUG_ONLY(tenv.mod = cg->mod;)
3227
3228                 asm_node = (*transform)(&tenv);
3229         }
3230
3231         /* exchange nodes if a new one was generated */
3232         if (asm_node) {
3233                 exchange(node, asm_node);
3234                 DB((cg->mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
3235         }
3236         else {
3237                 DB((cg->mod, LEVEL_1, "ignored\n"));
3238         }
3239 }
3240
3241 /**
3242  * Transforms a psi condition.
3243  */
3244 static void transform_psi_cond(ir_node *cond, ir_mode *mode, ia32_code_gen_t *cg) {
3245         int i;
3246
3247         /* if the mode is target mode, we have already seen this part of the tree */
3248         if (get_irn_mode(cond) == mode)
3249                 return;
3250
3251         assert(get_irn_mode(cond) == mode_b && "logical operator for condition must be mode_b");
3252
3253         set_irn_mode(cond, mode);
3254
3255         for (i = get_irn_arity(cond) - 1; i >= 0; i--) {
3256                 ir_node *in = get_irn_n(cond, i);
3257
3258                 /* if in is a compare: transform into Set/xCmp */
3259                 if (is_Proj(in)) {
3260                         ir_node  *new_op = NULL;
3261                         ir_node  *cmp    = get_Proj_pred(in);
3262                         ir_node  *cmp_a  = get_Cmp_left(cmp);
3263                         ir_node  *cmp_b  = get_Cmp_right(cmp);
3264                         dbg_info *dbg    = get_irn_dbg_info(cmp);
3265                         ir_graph *irg    = get_irn_irg(cmp);
3266                         ir_node  *block  = get_nodes_block(cmp);
3267                         ir_node  *noreg  = ia32_new_NoReg_gp(cg);
3268                         ir_node  *nomem  = new_rd_NoMem(irg);
3269                         int      pnc     = get_Proj_proj(in);
3270
3271                         /* this is a compare */
3272                         if (mode_is_float(mode)) {
3273                                 /* Psi is float, we need a floating point compare */
3274
3275                                 if (USE_SSE2(cg)) {
3276                                         ir_mode *m = get_irn_mode(cmp_a);
3277                                         /* SSE FPU */
3278                                         if (! mode_is_float(m)) {
3279                                                 cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_a, cmp_a, mode);
3280                                                 cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_b, cmp_b, mode);
3281                                         }
3282                                         else if (m == mode_F) {
3283                                                 /* we convert cmp values always to double, to get correct bitmask with cmpsd */
3284                                                 cmp_a = gen_sse_conv_f2d(cg, dbg, irg, block, cmp_a, cmp_a);
3285                                                 cmp_b = gen_sse_conv_f2d(cg, dbg, irg, block, cmp_b, cmp_b);
3286                                         }
3287
3288                                         new_op = new_rd_ia32_xCmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
3289                                         set_ia32_pncode(new_op, pnc);
3290                                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, cmp));
3291                                 }
3292                                 else {
3293                                         /* x87 FPU */
3294                                         assert(0);
3295                                 }
3296                         }
3297                         else {
3298                                 /* integer Psi */
3299                                 ia32_transform_env_t tenv;
3300                                 construct_binop_func *set_func  = NULL;
3301
3302                                 if (mode_is_float(get_irn_mode(cmp_a))) {
3303                                         /* 1st case: compare operands are floats */
3304                                         FP_USED(cg);
3305
3306                                         if (USE_SSE2(cg)) {
3307                                                 /* SSE FPU */
3308                                                 set_func  = new_rd_ia32_xCmpSet;
3309                                         }
3310                                         else {
3311                                                 /* x87 FPU */
3312                                                 set_func  = new_rd_ia32_vfCmpSet;
3313                                         }
3314
3315                                         pnc &= 7; /* fp compare -> int compare */
3316                                 }
3317                                 else {
3318                                         /* 2nd case: compare operand are integer too */
3319                                         set_func  = new_rd_ia32_CmpSet;
3320                                 }
3321
3322                                 tenv.block = block;
3323                                 tenv.cg    = cg;
3324                                 tenv.dbg   = dbg;
3325                                 tenv.irg   = irg;
3326                                 tenv.irn   = cmp;
3327                                 tenv.mode  = mode;
3328                                 tenv.mod   = cg->mod;
3329
3330                                 new_op = gen_binop(&tenv, cmp_a, cmp_b, set_func);
3331                                 set_ia32_pncode(get_Proj_pred(new_op), pnc);
3332                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
3333                         }
3334
3335                         /* the the new compare as in */
3336                         set_irn_n(cond, i, new_op);
3337                 }
3338                 else {
3339                         /* another complex condition */
3340                         transform_psi_cond(in, mode, cg);
3341                 }
3342         }
3343 }
3344
3345 /**
3346  * The Psi selector can be a tree of compares combined with "And"s and "Or"s.
3347  * We create a Set node, respectively a xCmp in case the Psi is a float, for each
3348  * compare, which causes the compare result to be stores in a register.  The
3349  * "And"s and "Or"s are transformed later, we just have to set their mode right.
3350  */
3351 void ia32_transform_psi_cond_tree(ir_node *node, void *env) {
3352         ia32_code_gen_t *cg = env;
3353         ir_node         *psi_sel, *new_cmp, *block;
3354         ir_graph        *irg;
3355         ir_mode         *mode;
3356
3357         /* check for Psi */
3358         if (get_irn_opcode(node) != iro_Psi)
3359                 return;
3360
3361         psi_sel = get_Psi_cond(node, 0);
3362
3363         /* if psi_cond is a cmp: do nothing, this case is covered by gen_Psi */
3364         if (is_Proj(psi_sel))
3365                 return;
3366
3367         //mode = get_irn_mode(node);
3368         mode = mode_Iu;
3369
3370         transform_psi_cond(psi_sel, mode, cg);
3371
3372         irg   = get_irn_irg(node);
3373         block = get_nodes_block(node);
3374
3375         /* we need to compare the evaluated condition tree with 0 */
3376         mode  = get_irn_mode(node);
3377         if (mode_is_float(mode)) {
3378                 psi_sel = gen_sse_conv_int2float(cg, NULL, irg, block, psi_sel, NULL, mode);
3379                 /* BEWARE: new_r_Const_long works for floating point as well */
3380                 new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode, 0));
3381                 new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Ne);
3382         }
3383         else {
3384                 new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode_Iu, 0));
3385                 new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Gt | pn_Cmp_Lt);
3386         }
3387
3388         set_Psi_cond(node, 0, new_cmp);
3389 }