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