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