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