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