use the correct mode for DIV
[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, 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, 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);
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 (get_ia32_op_type(cnst) == ia32_Const &&
1491                                         classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL)
1492                                 {
1493                                         /* a Cmp A =/!= 0 */
1494                                         ir_node    *op1  = expr;
1495                                         ir_node    *op2  = expr;
1496                                         ir_node    *and  = skip_Proj(expr);
1497                                         const char *cnst = NULL;
1498
1499                                         /* check, if expr is an only once used And operation */
1500                                         if (get_irn_n_edges(expr) == 1 && is_ia32_And(and)) {
1501                                                 op1 = get_irn_n(and, 2);
1502                                                 op2 = get_irn_n(and, 3);
1503
1504                                                 cnst = (is_ia32_ImmConst(and) || is_ia32_ImmSymConst(and)) ? get_ia32_cnst(and) : NULL;
1505                                         }
1506                                         res = new_rd_ia32_TestJmp(dbg, irg, block, op1, op2);
1507                                         set_ia32_pncode(res, get_Proj_proj(sel));
1508                                         set_ia32_res_mode(res, get_irn_mode(op1));
1509
1510                                         if (cnst) {
1511                                                 copy_ia32_Immop_attr(res, and);
1512                                         }
1513
1514                                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1515                                         return res;
1516                                 }
1517                         }
1518
1519                         if (mode_is_float(get_irn_mode(expr))) {
1520                                 FP_USED(env->cg);
1521                                 if (USE_SSE2(env->cg))
1522                                         res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem);
1523                                 else {
1524                                         assert(0);
1525                                 }
1526                         }
1527                         else {
1528                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem);
1529                         }
1530                         set_ia32_Immop_attr(res, cnst);
1531                         set_ia32_res_mode(res, get_irn_mode(expr));
1532                 }
1533                 else {
1534                         if (mode_is_float(get_irn_mode(cmp_a))) {
1535                                 FP_USED(env->cg);
1536                                 if (USE_SSE2(env->cg))
1537                                         res = new_rd_ia32_xCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1538                                 else {
1539                                         ir_node *proj_eax;
1540                                         res = new_rd_ia32_vfCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1541                                         proj_eax = new_r_Proj(irg, block, res, mode_Is, pn_ia32_vfCondJmp_temp_reg_eax);
1542                                         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, &proj_eax);
1543                                 }
1544                         }
1545                         else {
1546                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1547                                 set_ia32_commutative(res);
1548                         }
1549                         set_ia32_res_mode(res, get_irn_mode(cmp_a));
1550                 }
1551
1552                 set_ia32_pncode(res, get_Proj_proj(sel));
1553                 //set_ia32_am_support(res, ia32_am_Source);
1554         }
1555         else {
1556                 /* determine the smallest switch case value */
1557                 int switch_min = INT_MAX;
1558                 const ir_edge_t *edge;
1559                 char buf[64];
1560
1561                 foreach_out_edge(node, edge) {
1562                         int pn = get_Proj_proj(get_edge_src_irn(edge));
1563                         switch_min = pn < switch_min ? pn : switch_min;
1564                 }
1565
1566                 if (switch_min) {
1567                         /* if smallest switch case is not 0 we need an additional sub */
1568                         snprintf(buf, sizeof(buf), "%d", switch_min);
1569                         res = new_rd_ia32_Lea(dbg, irg, block, sel, noreg, mode_Is);
1570                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1571                         sub_ia32_am_offs(res, buf);
1572                         set_ia32_am_flavour(res, ia32_am_OB);
1573                         set_ia32_am_support(res, ia32_am_Source);
1574                         set_ia32_op_type(res, ia32_AddrModeS);
1575                 }
1576
1577                 res = new_rd_ia32_SwitchJmp(dbg, irg, block, switch_min ? res : sel, mode_T);
1578                 set_ia32_pncode(res, get_Cond_defaultProj(node));
1579                 set_ia32_res_mode(res, get_irn_mode(sel));
1580         }
1581
1582         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1583         return res;
1584 }
1585
1586
1587
1588 /**
1589  * Transforms a CopyB node.
1590  *
1591  * @param env   The transformation environment
1592  * @return The transformed node.
1593  */
1594 static ir_node *gen_CopyB(ia32_transform_env_t *env) {
1595         ir_node  *res   = NULL;
1596         dbg_info *dbg   = env->dbg;
1597         ir_graph *irg   = env->irg;
1598         ir_mode  *mode  = env->mode;
1599         ir_node  *block = env->block;
1600         ir_node  *node  = env->irn;
1601         ir_node  *src   = get_CopyB_src(node);
1602         ir_node  *dst   = get_CopyB_dst(node);
1603         ir_node  *mem   = get_CopyB_mem(node);
1604         int       size  = get_type_size_bytes(get_CopyB_type(node));
1605         int       rem;
1606
1607         /* If we have to copy more than 16 bytes, we use REP MOVSx and */
1608         /* then we need the size explicitly in ECX.                    */
1609         if (size >= 16 * 4) {
1610                 rem = size & 0x3; /* size % 4 */
1611                 size >>= 2;
1612
1613                 res = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Is);
1614                 set_ia32_op_type(res, ia32_Const);
1615                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1616
1617                 res = new_rd_ia32_CopyB(dbg, irg, block, dst, src, res, mem, mode);
1618                 set_ia32_Immop_tarval(res, new_tarval_from_long(rem, mode_Is));
1619         }
1620         else {
1621                 res = new_rd_ia32_CopyB_i(dbg, irg, block, dst, src, mem, mode);
1622                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1623                 set_ia32_immop_type(res, ia32_ImmConst);
1624         }
1625
1626         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
1627
1628         return res;
1629 }
1630
1631
1632
1633 /**
1634  * Transforms a Mux node into CMov.
1635  *
1636  * @param env   The transformation environment
1637  * @return The transformed node.
1638  */
1639 static ir_node *gen_Mux(ia32_transform_env_t *env) {
1640 #if 0
1641         ir_node *node   = env->irn;
1642         ir_node *new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, \
1643                 get_Mux_sel(node), get_Mux_false(node), get_Mux_true(node), env->mode);
1644
1645         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1646
1647         return new_op;
1648 #endif
1649         return NULL;
1650 }
1651
1652 typedef ir_node *cmov_func_t(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *cmp_a, ir_node *cmp_b, \
1653                              ir_node *psi_true, ir_node *psi_default, ir_mode *mode);
1654
1655 /**
1656  * Transforms a Psi node into CMov.
1657  *
1658  * @param env   The transformation environment
1659  * @return The transformed node.
1660  */
1661 static ir_node *gen_Psi(ia32_transform_env_t *env) {
1662         ia32_code_gen_t *cg   = env->cg;
1663         dbg_info *dbg         = env->dbg;
1664         ir_graph *irg         = env->irg;
1665         ir_mode  *mode        = env->mode;
1666         ir_node  *block       = env->block;
1667         ir_node  *node        = env->irn;
1668         ir_node  *cmp_proj    = get_Mux_sel(node);
1669         ir_node  *psi_true    = get_Psi_val(node, 0);
1670         ir_node  *psi_default = get_Psi_default(node);
1671         ir_node  *noreg       = ia32_new_NoReg_gp(cg);
1672         ir_node  *nomem       = new_rd_NoMem(irg);
1673         ir_node  *cmp, *cmp_a, *cmp_b, *and1, *and2, *new_op = NULL;
1674         int      pnc;
1675
1676         assert(get_irn_mode(cmp_proj) == mode_b && "Condition for Psi must have mode_b");
1677
1678         cmp   = get_Proj_pred(cmp_proj);
1679         cmp_a = get_Cmp_left(cmp);
1680         cmp_b = get_Cmp_right(cmp);
1681         pnc   = get_Proj_proj(cmp_proj);
1682
1683         if (mode_is_float(mode)) {
1684                 /* floating point psi */
1685                 FP_USED(cg);
1686
1687                 /* 1st case: compare operands are float too */
1688                 if (USE_SSE2(cg)) {
1689                         /* psi(cmp(a, b), t, f) can be done as: */
1690                         /* tmp = cmp a, b                       */
1691                         /* tmp2 = t and tmp                     */
1692                         /* tmp3 = f and not tmp                 */
1693                         /* res  = tmp2 or tmp3                  */
1694
1695                         /* in case the compare operands are int, we move them into xmm register */
1696                         if (! mode_is_float(get_irn_mode(cmp_a))) {
1697                                 cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_a, node, mode_D);
1698                                 cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_b, node, mode_D);
1699
1700                                 pnc |= 8;  /* transform integer compare to fp compare */
1701                         }
1702
1703                         new_op = new_rd_ia32_xCmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
1704                         set_ia32_pncode(new_op, pnc);
1705                         set_ia32_am_support(new_op, ia32_am_Source);
1706                         set_ia32_res_mode(new_op, mode);
1707                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1708                         new_op = new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_xCmp_res);
1709
1710                         and1 = new_rd_ia32_xAnd(dbg, irg, block, noreg, noreg, psi_true, new_op, nomem);
1711                         set_ia32_am_support(and1, ia32_am_Source);
1712                         set_ia32_res_mode(and1, mode);
1713                         SET_IA32_ORIG_NODE(and1, ia32_get_old_node_name(cg, node));
1714                         and1 = new_rd_Proj(dbg, irg, block, and1, mode, pn_ia32_xAnd_res);
1715
1716                         and2 = new_rd_ia32_xAndNot(dbg, irg, block, noreg, noreg, new_op, psi_default, nomem);
1717                         set_ia32_am_support(and2, ia32_am_Source);
1718                         set_ia32_res_mode(and2, mode);
1719                         SET_IA32_ORIG_NODE(and2, ia32_get_old_node_name(cg, node));
1720                         and2 = new_rd_Proj(dbg, irg, block, and2, mode, pn_ia32_xAndNot_res);
1721
1722                         new_op = new_rd_ia32_xOr(dbg, irg, block, noreg, noreg, and1, and2, nomem);
1723                         set_ia32_am_support(new_op, ia32_am_Source);
1724                         set_ia32_res_mode(new_op, mode);
1725                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1726                         new_op = new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_xOr_res);
1727                 }
1728                 else {
1729                         /* x87 FPU */
1730                         new_op = new_rd_ia32_vfCMov(dbg, irg, block, cmp_a, cmp_b, psi_true, psi_default, mode);
1731                         set_ia32_pncode(new_op, pnc);
1732                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
1733                 }
1734         }
1735         else {
1736                 /* integer psi */
1737                 construct_binop_func *set_func  = NULL;
1738                 cmov_func_t          *cmov_func = NULL;
1739
1740                 if (mode_is_float(get_irn_mode(cmp_a))) {
1741                         /* 1st case: compare operands are floats */
1742                         FP_USED(cg);
1743
1744                         if (USE_SSE2(cg)) {
1745                                 /* SSE FPU */
1746                                 set_func  = new_rd_ia32_xCmpSet;
1747                                 cmov_func = new_rd_ia32_xCmpCMov;
1748                         }
1749                         else {
1750                                 /* x87 FPU */
1751                                 set_func  = new_rd_ia32_vfCmpSet;
1752                                 cmov_func = new_rd_ia32_vfCmpCMov;
1753                         }
1754
1755                         pnc &= 7; /* fp compare -> int compare */
1756                 }
1757                 else {
1758                         /* 2nd case: compare operand are integer too */
1759                         set_func  = new_rd_ia32_CmpSet;
1760                         cmov_func = new_rd_ia32_CmpCMov;
1761                 }
1762
1763                 /* create the nodes */
1764
1765                 /* check for special case first: And/Or -- Cmp with 0 -- Psi */
1766                 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)))) {
1767                         if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) {
1768                                 /* first case for SETcc: default is 0, set to 1 iff condition is true */
1769                                 new_op = new_rd_ia32_PsiCondSet(dbg, irg, block, cmp_a, mode);
1770                                 set_ia32_pncode(new_op, pnc);
1771                         }
1772                         else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) {
1773                                 /* second case for SETcc: default is 1, set to 0 iff condition is true: */
1774                                 /*                        we invert condition and set default to 0      */
1775                                 new_op = new_rd_ia32_PsiCondSet(dbg, irg, block, cmp_a, mode);
1776                                 set_ia32_pncode(new_op, get_inversed_pnc(pnc));
1777                         }
1778                         else {
1779                                 /* otherwise: use CMOVcc */
1780                                 new_op = new_rd_ia32_PsiCondCMov(dbg, irg, block, cmp_a, psi_true, psi_default, mode);
1781                                 set_ia32_pncode(new_op, pnc);
1782                         }
1783
1784                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1785                 }
1786                 else {
1787                         env->irn = cmp;
1788                         if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) {
1789                                 /* first case for SETcc: default is 0, set to 1 iff condition is true */
1790                                 new_op = gen_binop(env, cmp_a, cmp_b, set_func);
1791                                 set_ia32_pncode(get_Proj_pred(new_op), pnc);
1792                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
1793                         }
1794                         else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) {
1795                                 /* second case for SETcc: default is 1, set to 0 iff condition is true: */
1796                                 /*                        we invert condition and set default to 0      */
1797                                 new_op = gen_binop(env, cmp_a, cmp_b, set_func);
1798                                 set_ia32_pncode(get_Proj_pred(new_op), get_inversed_pnc(pnc));
1799                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
1800                         }
1801                         else {
1802                                 /* otherwise: use CMOVcc */
1803                                 new_op = cmov_func(dbg, irg, block, cmp_a, cmp_b, psi_true, psi_default, mode);
1804                                 set_ia32_pncode(new_op, pnc);
1805                                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1806                         }
1807                 }
1808         }
1809
1810         return new_op;
1811 }
1812
1813
1814 /**
1815  * Following conversion rules apply:
1816  *
1817  *  INT -> INT
1818  * ============
1819  *  1) n bit -> m bit   n > m (downscale)
1820  *     a) target is signed:    movsx
1821  *     b) target is unsigned:  and with lower bits sets
1822  *  2) n bit -> m bit   n == m   (sign change)
1823  *     always ignored
1824  *  3) n bit -> m bit   n < m (upscale)
1825  *     a) source is signed:    movsx
1826  *     b) source is unsigned:  and with lower bits sets
1827  *
1828  *  INT -> FLOAT
1829  * ==============
1830  *  SSE(1/2) convert to float or double (cvtsi2ss/sd)
1831  *
1832  *  FLOAT -> INT
1833  * ==============
1834  *  SSE(1/2) convert from float or double to 32bit int (cvtss/sd2si)
1835  *  if target mode < 32bit: additional INT -> INT conversion (see above)
1836  *
1837  *  FLOAT -> FLOAT
1838  * ================
1839  *  SSE(1/2) convert from float or double to double or float (cvtss/sd2sd/ss)
1840  *  x87 is mode_E internally, conversions happen only at load and store
1841  *  in non-strict semantic
1842  */
1843
1844 /**
1845  * Create a conversion from x87 state register to general purpose.
1846  */
1847 static ir_node *gen_x87_fp_to_gp(ia32_transform_env_t *env, ir_mode *tgt_mode) {
1848         ia32_code_gen_t *cg = env->cg;
1849         entity   *ent = cg->fp_to_gp;
1850         ir_graph *irg = env->irg;
1851         ir_node  *block = env->block;
1852         ir_node  *noreg = ia32_new_NoReg_gp(env->cg);
1853         ir_node  *op = get_Conv_op(env->irn);
1854         ir_node  *fist, *mem, *load;
1855
1856         if (! ent) {
1857                 int size = get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_vfp].mode);
1858                 ent = cg->fp_to_gp =
1859                         frame_alloc_area(get_irg_frame_type(env->irg), size, 16, 0);
1860         }
1861
1862         /* do a fist */
1863         fist = new_rd_ia32_vfist(env->dbg, irg, block, get_irg_frame(irg), noreg, op, get_irg_no_mem(irg));
1864
1865         set_ia32_frame_ent(fist, ent);
1866         set_ia32_use_frame(fist);
1867         set_ia32_am_support(fist, ia32_am_Dest);
1868         set_ia32_op_type(fist, ia32_AddrModeD);
1869         set_ia32_am_flavour(fist, ia32_B);
1870         set_ia32_ls_mode(fist, mode_F);
1871
1872         mem  = new_r_Proj(irg, block, fist, mode_M, pn_ia32_vfist_M);
1873
1874         /* do a Load */
1875         load = new_rd_ia32_Load(env->dbg, irg, block, get_irg_frame(irg), noreg, mem);
1876
1877         set_ia32_frame_ent(load, ent);
1878         set_ia32_use_frame(load);
1879         set_ia32_am_support(load, ia32_am_Source);
1880         set_ia32_op_type(load, ia32_AddrModeS);
1881         set_ia32_am_flavour(load, ia32_B);
1882         set_ia32_ls_mode(load, tgt_mode);
1883
1884         return new_r_Proj(irg, block, load, tgt_mode, pn_ia32_Load_res);
1885 }
1886
1887 /**
1888  * Create a conversion from x87 state register to general purpose.
1889  */
1890 static ir_node *gen_x87_gp_to_fp(ia32_transform_env_t *env, ir_mode *src_mode) {
1891         ia32_code_gen_t *cg = env->cg;
1892         entity   *ent = cg->gp_to_fp;
1893         ir_graph *irg = env->irg;
1894         ir_node  *block = env->block;
1895         ir_node  *noreg = ia32_new_NoReg_gp(env->cg);
1896         ir_node  *nomem = get_irg_no_mem(irg);
1897         ir_node  *op = get_Conv_op(env->irn);
1898         ir_node  *fild, *store, *mem;
1899         int src_bits;
1900
1901         if (! ent) {
1902                 int size = get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_gp].mode);
1903                 ent = cg->gp_to_fp =
1904                         frame_alloc_area(get_irg_frame_type(env->irg), size, size, 0);
1905         }
1906
1907         /* first convert to 32 bit */
1908         src_bits = get_mode_size_bits(src_mode);
1909         if (src_bits == 8) {
1910                 op = new_rd_ia32_Conv_I2I8Bit(env->dbg, irg, block, noreg, noreg, op, nomem);
1911                 op = new_r_Proj(irg, block, op, mode_Is, 0);
1912         }
1913         else if (src_bits < 32) {
1914                 op = new_rd_ia32_Conv_I2I(env->dbg, irg, block, noreg, noreg, op, nomem);
1915                 op = new_r_Proj(irg, block, op, mode_Is, 0);
1916         }
1917
1918         /* do a store */
1919         store = new_rd_ia32_Store(env->dbg, irg, block, get_irg_frame(irg), noreg, op, nomem);
1920
1921         set_ia32_frame_ent(store, ent);
1922         set_ia32_use_frame(store);
1923
1924         set_ia32_am_support(store, ia32_am_Dest);
1925         set_ia32_op_type(store, ia32_AddrModeD);
1926         set_ia32_am_flavour(store, ia32_B);
1927         set_ia32_ls_mode(store, mode_Is);
1928
1929         mem = new_r_Proj(irg, block, store, mode_M, 0);
1930
1931         /* do a fild */
1932         fild = new_rd_ia32_vfild(env->dbg, irg, block, get_irg_frame(irg), noreg, mem);
1933
1934         set_ia32_frame_ent(fild, ent);
1935         set_ia32_use_frame(fild);
1936         set_ia32_am_support(fild, ia32_am_Source);
1937         set_ia32_op_type(fild, ia32_AddrModeS);
1938         set_ia32_am_flavour(fild, ia32_B);
1939         set_ia32_ls_mode(fild, mode_F);
1940
1941         return new_r_Proj(irg, block, fild, mode_F, 0);
1942 }
1943
1944 /**
1945  * Transforms a Conv node.
1946  *
1947  * @param env   The transformation environment
1948  * @return The created ia32 Conv node
1949  */
1950 static ir_node *gen_Conv(ia32_transform_env_t *env) {
1951         dbg_info *dbg      = env->dbg;
1952         ir_graph *irg      = env->irg;
1953         ir_node  *op       = get_Conv_op(env->irn);
1954         ir_mode  *src_mode = get_irn_mode(op);
1955         ir_mode  *tgt_mode = env->mode;
1956         int      src_bits  = get_mode_size_bits(src_mode);
1957         int      tgt_bits  = get_mode_size_bits(tgt_mode);
1958         int      pn        = -1;
1959         ir_node  *block    = env->block;
1960         ir_node  *new_op   = NULL;
1961         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
1962         ir_node  *nomem    = new_rd_NoMem(irg);
1963         ir_node  *proj;
1964         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
1965
1966         if (src_mode == tgt_mode) {
1967                 /* this can happen when changing mode_P to mode_Is */
1968                 DB((mod, LEVEL_1, "killed Conv(mode, mode) ..."));
1969                 edges_reroute(env->irn, op, irg);
1970         }
1971         else if (mode_is_float(src_mode)) {
1972                 /* we convert from float ... */
1973                 if (mode_is_float(tgt_mode)) {
1974                         /* ... to float */
1975                         if (USE_SSE2(env->cg)) {
1976                                 DB((mod, LEVEL_1, "create Conv(float, float) ..."));
1977                                 new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem);
1978                                 pn     = pn_ia32_Conv_FP2FP_res;
1979                         }
1980                         else {
1981                                 DB((mod, LEVEL_1, "killed Conv(float, float) ..."));
1982                                 edges_reroute(env->irn, op, irg);
1983                         }
1984                 }
1985                 else {
1986                         /* ... to int */
1987                         DB((mod, LEVEL_1, "create Conv(float, int) ..."));
1988                         if (USE_SSE2(env->cg)) {
1989                                 new_op = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, op, nomem);
1990                                 pn     = pn_ia32_Conv_FP2I_res;
1991                         }
1992                         else
1993                                 return gen_x87_fp_to_gp(env, tgt_mode);
1994
1995                         /* if target mode is not int: add an additional downscale convert */
1996                         if (tgt_bits < 32) {
1997                                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1998                                 set_ia32_am_support(new_op, ia32_am_Source);
1999                                 set_ia32_tgt_mode(new_op, tgt_mode);
2000                                 set_ia32_src_mode(new_op, src_mode);
2001
2002                                 proj = new_rd_Proj(dbg, irg, block, new_op, mode_Is, pn_ia32_Conv_FP2I_res);
2003
2004                                 if (tgt_bits == 8 || src_bits == 8) {
2005                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, proj, nomem);
2006                                         pn     = pn_ia32_Conv_I2I8Bit_res;
2007                                 }
2008                                 else {
2009                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, proj, nomem);
2010                                         pn     = pn_ia32_Conv_I2I_res;
2011                                 }
2012                         }
2013                 }
2014         }
2015         else {
2016                 /* we convert from int ... */
2017                 if (mode_is_float(tgt_mode)) {
2018                         FP_USED(env->cg);
2019                         /* ... to float */
2020                         DB((mod, LEVEL_1, "create Conv(int, float) ..."));
2021                         if (USE_SSE2(env->cg)) {
2022                                 new_op = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, op, nomem);
2023                                 pn     = pn_ia32_Conv_I2FP_res;
2024                         }
2025                         else
2026                                 return gen_x87_gp_to_fp(env, src_mode);
2027                 }
2028                 else {
2029                         /* ... to int */
2030                         if (get_mode_size_bits(src_mode) == tgt_bits) {
2031                                 DB((mod, LEVEL_1, "omitting equal size Conv(%+F, %+F) ...", src_mode, tgt_mode));
2032                                 edges_reroute(env->irn, op, irg);
2033                         }
2034                         else {
2035                                 DB((mod, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode));
2036                                 if (tgt_bits == 8 || src_bits == 8) {
2037                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, op, nomem);
2038                                         pn     = pn_ia32_Conv_I2I8Bit_res;
2039                                 }
2040                                 else {
2041                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem);
2042                                         pn     = pn_ia32_Conv_I2I_res;
2043                                 }
2044                         }
2045                 }
2046         }
2047
2048         if (new_op) {
2049                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2050                 set_ia32_tgt_mode(new_op, tgt_mode);
2051                 set_ia32_src_mode(new_op, src_mode);
2052
2053                 set_ia32_am_support(new_op, ia32_am_Source);
2054
2055                 new_op = new_rd_Proj(dbg, irg, block, new_op, tgt_mode, pn);
2056         }
2057
2058         return new_op;
2059 }
2060
2061
2062
2063 /********************************************
2064  *  _                          _
2065  * | |                        | |
2066  * | |__   ___ _ __   ___   __| | ___  ___
2067  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
2068  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
2069  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
2070  *
2071  ********************************************/
2072
2073  /**
2074   * Decides in which block the transformed StackParam should be placed.
2075   * If the StackParam has more than one user, the dominator block of
2076   * the users will be returned. In case of only one user, this is either
2077   * the user block or, in case of a Phi, the predecessor block of the Phi.
2078   */
2079  static ir_node *get_block_transformed_stack_param(ir_node *irn) {
2080          ir_node *dom_bl = NULL;
2081
2082          if (get_irn_n_edges(irn) == 1) {
2083                  ir_node *src = get_edge_src_irn(get_irn_out_edge_first(irn));
2084
2085                  if (! is_Phi(src)) {
2086                          dom_bl = get_nodes_block(src);
2087                  }
2088                  else {
2089                          /* Determine on which in position of the Phi the irn is */
2090                          /* and get the corresponding cfg predecessor block.     */
2091
2092                          int i  = get_irn_pred_pos(src, irn);
2093                          assert(i >= 0 && "kaputt");
2094                          dom_bl = get_Block_cfgpred_block(get_nodes_block(src), i);
2095                  }
2096          }
2097          else {
2098                  dom_bl = node_users_smallest_common_dominator(irn, 1);
2099          }
2100
2101          assert(dom_bl && "dominator block not found");
2102
2103          return dom_bl;
2104  }
2105
2106 static ir_node *gen_be_StackParam(ia32_transform_env_t *env) {
2107         ir_node *new_op = NULL;
2108         ir_node *node   = env->irn;
2109         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2110         ir_node *mem    = new_rd_NoMem(env->irg);
2111         ir_node *ptr    = get_irn_n(node, 0);
2112         entity  *ent    = be_get_frame_entity(node);
2113         ir_mode *mode   = env->mode;
2114
2115         /* choose the block where to place the load */
2116         env->block = get_block_transformed_stack_param(node);
2117
2118         if (mode_is_float(mode)) {
2119                 FP_USED(env->cg);
2120                 if (USE_SSE2(env->cg))
2121                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
2122                 else
2123                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
2124         }
2125         else {
2126                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
2127         }
2128
2129         set_ia32_frame_ent(new_op, ent);
2130         set_ia32_use_frame(new_op);
2131
2132         set_ia32_am_support(new_op, ia32_am_Source);
2133         set_ia32_op_type(new_op, ia32_AddrModeS);
2134         set_ia32_am_flavour(new_op, ia32_B);
2135         set_ia32_ls_mode(new_op, mode);
2136
2137         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2138
2139         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_ia32_Load_res);
2140 }
2141
2142 /**
2143  * Transforms a FrameAddr into an ia32 Add.
2144  */
2145 static ir_node *gen_be_FrameAddr(ia32_transform_env_t *env) {
2146         ir_node *new_op = NULL;
2147         ir_node *node   = env->irn;
2148         ir_node *op     = get_irn_n(node, 0);
2149         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2150         ir_node *nomem  = new_rd_NoMem(env->irg);
2151
2152         new_op = new_rd_ia32_Add(env->dbg, env->irg, env->block, noreg, noreg, op, noreg, nomem);
2153         set_ia32_frame_ent(new_op, be_get_frame_entity(node));
2154         set_ia32_am_support(new_op, ia32_am_Full);
2155         set_ia32_use_frame(new_op);
2156         set_ia32_immop_type(new_op, ia32_ImmConst);
2157         set_ia32_commutative(new_op);
2158
2159         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2160
2161         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, pn_ia32_Add_res);
2162 }
2163
2164 /**
2165  * Transforms a FrameLoad into an ia32 Load.
2166  */
2167 static ir_node *gen_be_FrameLoad(ia32_transform_env_t *env) {
2168         ir_node *new_op = NULL;
2169         ir_node *node   = env->irn;
2170         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2171         ir_node *mem    = get_irn_n(node, 0);
2172         ir_node *ptr    = get_irn_n(node, 1);
2173         entity  *ent    = be_get_frame_entity(node);
2174         ir_mode *mode   = get_type_mode(get_entity_type(ent));
2175
2176         if (mode_is_float(mode)) {
2177                 FP_USED(env->cg);
2178                 if (USE_SSE2(env->cg))
2179                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
2180                 else
2181                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
2182         }
2183         else
2184                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
2185
2186         set_ia32_frame_ent(new_op, ent);
2187         set_ia32_use_frame(new_op);
2188
2189         set_ia32_am_support(new_op, ia32_am_Source);
2190         set_ia32_op_type(new_op, ia32_AddrModeS);
2191         set_ia32_am_flavour(new_op, ia32_B);
2192         set_ia32_ls_mode(new_op, mode);
2193
2194         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2195
2196         return new_op;
2197 }
2198
2199
2200 /**
2201  * Transforms a FrameStore into an ia32 Store.
2202  */
2203 static ir_node *gen_be_FrameStore(ia32_transform_env_t *env) {
2204         ir_node *new_op = NULL;
2205         ir_node *node   = env->irn;
2206         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
2207         ir_node *mem    = get_irn_n(node, 0);
2208         ir_node *ptr    = get_irn_n(node, 1);
2209         ir_node *val    = get_irn_n(node, 2);
2210         entity  *ent    = be_get_frame_entity(node);
2211         ir_mode *mode   = get_irn_mode(val);
2212
2213         if (mode_is_float(mode)) {
2214                 FP_USED(env->cg);
2215                 if (USE_SSE2(env->cg))
2216                         new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2217                 else
2218                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2219         }
2220         else if (get_mode_size_bits(mode) == 8) {
2221                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2222         }
2223         else {
2224                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
2225         }
2226
2227         set_ia32_frame_ent(new_op, ent);
2228         set_ia32_use_frame(new_op);
2229
2230         set_ia32_am_support(new_op, ia32_am_Dest);
2231         set_ia32_op_type(new_op, ia32_AddrModeD);
2232         set_ia32_am_flavour(new_op, ia32_B);
2233         set_ia32_ls_mode(new_op, mode);
2234
2235         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2236
2237         return new_op;
2238 }
2239
2240 /**
2241  * This function just sets the register for the Unknown node
2242  * as this is not done during register allocation because Unknown
2243  * is an "ignore" node.
2244  */
2245 static ir_node *gen_Unknown(ia32_transform_env_t *env) {
2246         ir_mode *mode = env->mode;
2247         ir_node *irn  = env->irn;
2248
2249         if (mode_is_float(mode)) {
2250                 if (USE_SSE2(env->cg))
2251                         arch_set_irn_register(env->cg->arch_env, irn, &ia32_xmm_regs[REG_XMM_UKNWN]);
2252                 else
2253                         arch_set_irn_register(env->cg->arch_env, irn, &ia32_vfp_regs[REG_VFP_UKNWN]);
2254         }
2255         else if (mode_is_int(mode) || mode_is_reference(mode)) {
2256                 arch_set_irn_register(env->cg->arch_env, irn, &ia32_gp_regs[REG_GP_UKNWN]);
2257         }
2258         else {
2259                 assert(0 && "unsupported Unknown-Mode");
2260         }
2261
2262         return NULL;
2263 }
2264
2265 /**********************************************************************
2266  *  _                                _                   _
2267  * | |                              | |                 | |
2268  * | | _____      _____ _ __ ___  __| |  _ __   ___   __| | ___  ___
2269  * | |/ _ \ \ /\ / / _ \ '__/ _ \/ _` | | '_ \ / _ \ / _` |/ _ \/ __|
2270  * | | (_) \ V  V /  __/ | |  __/ (_| | | | | | (_) | (_| |  __/\__ \
2271  * |_|\___/ \_/\_/ \___|_|  \___|\__,_| |_| |_|\___/ \__,_|\___||___/
2272  *
2273  **********************************************************************/
2274
2275 /* These nodes are created in intrinsic lowering (64bit -> 32bit) */
2276
2277 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
2278                                      ir_node *mem);
2279
2280 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
2281                                       ir_node *val, ir_node *mem);
2282
2283 /**
2284  * Transforms a lowered Load into a "real" one.
2285  */
2286 static ir_node *gen_lowered_Load(ia32_transform_env_t *env, construct_load_func func, char fp_unit) {
2287         ir_node *node  = env->irn;
2288         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
2289         ir_mode *mode  = get_ia32_ls_mode(node);
2290         ir_node *new_op;
2291         char    *am_offs;
2292         ia32_am_flavour_t am_flav = ia32_B;
2293
2294         /*
2295                 Could be that we have SSE2 unit, but due to 64Bit Div/Conv
2296                 lowering we have x87 nodes, so we need to enforce simulation.
2297         */
2298         if (mode_is_float(mode)) {
2299                 FP_USED(env->cg);
2300                 if (fp_unit == fp_x87)
2301                         FORCE_x87(env->cg);
2302         }
2303
2304         new_op  = func(env->dbg, env->irg, env->block, get_irn_n(node, 0), noreg, get_irn_n(node, 1));
2305         am_offs = get_ia32_am_offs(node);
2306
2307         if (am_offs) {
2308                 am_flav |= ia32_O;
2309                 add_ia32_am_offs(new_op, am_offs);
2310         }
2311
2312         set_ia32_am_support(new_op, ia32_am_Source);
2313         set_ia32_op_type(new_op, ia32_AddrModeS);
2314         set_ia32_am_flavour(new_op, am_flav);
2315         set_ia32_ls_mode(new_op, mode);
2316         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
2317         set_ia32_use_frame(new_op);
2318
2319         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2320
2321         return new_op;
2322 }
2323
2324 /**
2325 * Transforms a lowered Store into a "real" one.
2326 */
2327 static ir_node *gen_lowered_Store(ia32_transform_env_t *env, construct_store_func func, char fp_unit) {
2328         ir_node *node  = env->irn;
2329         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
2330         ir_mode *mode  = get_ia32_ls_mode(node);
2331         ir_node *new_op;
2332         char    *am_offs;
2333         ia32_am_flavour_t am_flav = ia32_B;
2334
2335         /*
2336                 Could be that we have SSE2 unit, but due to 64Bit Div/Conv
2337                 lowering we have x87 nodes, so we need to enforce simulation.
2338         */
2339         if (mode_is_float(mode)) {
2340                 FP_USED(env->cg);
2341                 if (fp_unit == fp_x87)
2342                         FORCE_x87(env->cg);
2343         }
2344
2345         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));
2346
2347         if (am_offs = get_ia32_am_offs(node)) {
2348                 am_flav |= ia32_O;
2349                 add_ia32_am_offs(new_op, am_offs);
2350         }
2351
2352         set_ia32_am_support(new_op, ia32_am_Dest);
2353         set_ia32_op_type(new_op, ia32_AddrModeD);
2354         set_ia32_am_flavour(new_op, am_flav);
2355         set_ia32_ls_mode(new_op, mode);
2356         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
2357         set_ia32_use_frame(new_op);
2358
2359         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
2360
2361         return new_op;
2362 }
2363
2364
2365 /**
2366  * Transforms an ia32_l_XXX into a "real" XXX node
2367  *
2368  * @param env   The transformation environment
2369  * @return the created ia32 XXX node
2370  */
2371 #define GEN_LOWERED_OP(op)                                                                            \
2372         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                      \
2373                 if (mode_is_float(env->mode))                                                                 \
2374                         FP_USED(env->cg);                                                                         \
2375                 return gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2376         }
2377
2378 #define GEN_LOWERED_x87_OP(op)                                                                          \
2379         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                        \
2380                 ir_node *new_op;                                                                                \
2381                 FORCE_x87(env->cg);                                                                             \
2382                 new_op = gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2383                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_None);                                       \
2384                 return new_op;                                                                                  \
2385         }
2386
2387 #define GEN_LOWERED_UNOP(op)                                           \
2388         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {       \
2389                 return gen_unop(env, get_unop_op(env->irn), new_rd_ia32_##op); \
2390         }
2391
2392 #define GEN_LOWERED_SHIFT_OP(op)                                                                            \
2393         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) {                                            \
2394                 return gen_shift_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_##op); \
2395         }
2396
2397 #define GEN_LOWERED_LOAD(op, fp_unit)                            \
2398         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) { \
2399                 return gen_lowered_Load(env, new_rd_ia32_##op, fp_unit); \
2400         }
2401
2402 #define GEN_LOWERED_STORE(op, fp_unit)                           \
2403         static ir_node *gen_ia32_l_##op(ia32_transform_env_t *env) { \
2404         return gen_lowered_Store(env, new_rd_ia32_##op, fp_unit);    \
2405 }
2406
2407 GEN_LOWERED_OP(AddC)
2408 GEN_LOWERED_OP(Add)
2409 GEN_LOWERED_OP(SubC)
2410 GEN_LOWERED_OP(Sub)
2411 GEN_LOWERED_OP(Mul)
2412 GEN_LOWERED_OP(Eor)
2413 GEN_LOWERED_x87_OP(vfdiv)
2414 GEN_LOWERED_x87_OP(vfmul)
2415 GEN_LOWERED_x87_OP(vfsub)
2416
2417 GEN_LOWERED_UNOP(Minus)
2418
2419 GEN_LOWERED_LOAD(vfild, fp_x87)
2420 GEN_LOWERED_LOAD(Load, fp_none)
2421 GEN_LOWERED_STORE(vfist, fp_x87)
2422 GEN_LOWERED_STORE(Store, fp_none)
2423
2424 /**
2425  * Transforms a l_MulS into a "real" MulS node.
2426  *
2427  * @param env   The transformation environment
2428  * @return the created ia32 MulS node
2429  */
2430 static ir_node *gen_ia32_l_MulS(ia32_transform_env_t *env) {
2431
2432         /* l_MulS is already a mode_T node, so we create the MulS in the normal way   */
2433         /* and then skip the result Proj, because all needed Projs are already there. */
2434
2435         ir_node *new_op = gen_binop(env, get_binop_left(env->irn), get_binop_right(env->irn), new_rd_ia32_MulS);
2436         ir_node *muls   = get_Proj_pred(new_op);
2437
2438         /* MulS cannot have AM for destination */
2439         if (get_ia32_am_support(muls) != ia32_am_None)
2440                 set_ia32_am_support(muls, ia32_am_Source);
2441
2442         return muls;
2443 }
2444
2445 GEN_LOWERED_SHIFT_OP(Shl)
2446 GEN_LOWERED_SHIFT_OP(Shr)
2447 GEN_LOWERED_SHIFT_OP(Shrs)
2448
2449 /**
2450  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
2451  * op1 - target to be shifted
2452  * op2 - contains bits to be shifted into target
2453  * op3 - shift count
2454  * Only op3 can be an immediate.
2455  */
2456 static ir_node *gen_lowered_64bit_shifts(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, ir_node *count) {
2457         ir_node           *new_op = NULL;
2458         ir_mode           *mode   = env->mode;
2459         dbg_info          *dbg    = env->dbg;
2460         ir_graph          *irg    = env->irg;
2461         ir_node           *block  = env->block;
2462         ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
2463         ir_node           *nomem  = new_NoMem();
2464         ir_node           *imm_op;
2465         tarval            *tv;
2466         DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
2467
2468         assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");
2469
2470         /* Check if immediate optimization is on and */
2471         /* if it's an operation with immediate.      */
2472         imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, count) : NULL;
2473
2474         /* Limit imm_op within range imm8 */
2475         if (imm_op) {
2476                 tv = get_ia32_Immop_tarval(imm_op);
2477
2478                 if (tv) {
2479                         tv = tarval_mod(tv, new_tarval_from_long(32, mode_Iu));
2480                         set_ia32_Immop_tarval(imm_op, tv);
2481                 }
2482                 else {
2483                         imm_op = NULL;
2484                 }
2485         }
2486
2487         /* integer operations */
2488         if (imm_op) {
2489                 /* This is ShiftD with const */
2490                 DB((mod, LEVEL_1, "ShiftD with immediate ..."));
2491
2492                 if (is_ia32_l_ShlD(env->irn))
2493                         new_op = new_rd_ia32_ShlD(dbg, irg, block, noreg, noreg, op1, op2, noreg, nomem);
2494                 else
2495                         new_op = new_rd_ia32_ShrD(dbg, irg, block, noreg, noreg, op1, op2, noreg, nomem);
2496                 set_ia32_Immop_attr(new_op, imm_op);
2497         }
2498         else {
2499                 /* This is a normal ShiftD */
2500                 DB((mod, LEVEL_1, "ShiftD binop ..."));
2501                 if (is_ia32_l_ShlD(env->irn))
2502                         new_op = new_rd_ia32_ShlD(dbg, irg, block, noreg, noreg, op1, op2, count, nomem);
2503                 else
2504                         new_op = new_rd_ia32_ShrD(dbg, irg, block, noreg, noreg, op1, op2, count, nomem);
2505         }
2506
2507         /* set AM support */
2508         set_ia32_am_support(new_op, ia32_am_Dest);
2509
2510         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
2511
2512         set_ia32_res_mode(new_op, mode);
2513         set_ia32_emit_cl(new_op);
2514
2515         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
2516 }
2517
2518 static ir_node *gen_ia32_l_ShlD(ia32_transform_env_t *env) {
2519         return gen_lowered_64bit_shifts(env, get_irn_n(env->irn, 0), get_irn_n(env->irn, 1), get_irn_n(env->irn, 2));
2520 }
2521
2522 static ir_node *gen_ia32_l_ShrD(ia32_transform_env_t *env) {
2523         return gen_lowered_64bit_shifts(env, get_irn_n(env->irn, 0), get_irn_n(env->irn, 1), get_irn_n(env->irn, 2));
2524 }
2525
2526 /**
2527  * In case SSE Unit is used, the node is transformed into a vfst + xLoad.
2528  */
2529 static ir_node *gen_ia32_l_X87toSSE(ia32_transform_env_t *env) {
2530         ia32_code_gen_t *cg  = env->cg;
2531         ir_node         *res = NULL;
2532         ir_node         *ptr = get_irn_n(env->irn, 0);
2533         ir_node         *val = get_irn_n(env->irn, 1);
2534         ir_node         *mem = get_irn_n(env->irn, 2);
2535
2536         if (USE_SSE2(cg)) {
2537                 ir_node *noreg = ia32_new_NoReg_gp(cg);
2538
2539                 /* Store x87 -> MEM */
2540                 res = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem);
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_Dest);
2545                 set_ia32_am_flavour(res, ia32_B);
2546                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_vfst_M);
2547
2548                 /* Load MEM -> SSE */
2549                 res = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, res);
2550                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
2551                 set_ia32_use_frame(res);
2552                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
2553                 set_ia32_am_support(res, ia32_am_Source);
2554                 set_ia32_am_flavour(res, ia32_B);
2555                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, get_ia32_ls_mode(env->irn), pn_ia32_xLoad_res);
2556         }
2557         else {
2558                 /* SSE unit is not used -> skip this node. */
2559                 int i;
2560
2561                 edges_reroute(env->irn, val, env->irg);
2562                 for (i = get_irn_arity(env->irn) - 1; i >= 0; i--)
2563                         set_irn_n(env->irn, i, get_irg_bad(env->irg));
2564         }
2565
2566         return res;
2567 }
2568
2569 /**
2570  * In case SSE Unit is used, the node is transformed into a xStore + vfld.
2571  */
2572 static ir_node *gen_ia32_l_SSEtoX87(ia32_transform_env_t *env) {
2573         ia32_code_gen_t *cg  = env->cg;
2574         ir_node         *res = NULL;
2575         ir_node         *ptr = get_irn_n(env->irn, 0);
2576         ir_node         *val = get_irn_n(env->irn, 1);
2577         ir_node         *mem = get_irn_n(env->irn, 2);
2578
2579         if (USE_SSE2(cg)) {
2580                 ir_node *noreg = ia32_new_NoReg_gp(cg);
2581
2582                 /* Store SSE -> MEM */
2583                 res = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, 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_Dest);
2588                 set_ia32_am_flavour(res, ia32_B);
2589                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, mode_M, pn_ia32_xStore_M);
2590
2591                 /* Load MEM -> x87 */
2592                 res = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
2593                 set_ia32_frame_ent(res, get_ia32_frame_ent(env->irn));
2594                 set_ia32_use_frame(res);
2595                 set_ia32_ls_mode(res, get_ia32_ls_mode(env->irn));
2596                 set_ia32_am_support(res, ia32_am_Source);
2597                 set_ia32_am_flavour(res, ia32_B);
2598                 res = new_rd_Proj(env->dbg, env->irg, env->block, res, get_ia32_ls_mode(env->irn), pn_ia32_vfld_res);
2599         }
2600         else {
2601                 /* SSE unit is not used -> skip this node. */
2602                 int i;
2603
2604                 edges_reroute(env->irn, val, env->irg);
2605                 for (i = get_irn_arity(env->irn) - 1; i >= 0; i--)
2606                         set_irn_n(env->irn, i, get_irg_bad(env->irg));
2607         }
2608
2609         return res;
2610 }
2611
2612 /*********************************************************
2613  *                  _             _      _
2614  *                 (_)           | |    (_)
2615  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
2616  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
2617  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
2618  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
2619  *
2620  *********************************************************/
2621
2622 /**
2623  * Transforms a Sub or xSub into Neg--Add iff OUT_REG == SRC2_REG.
2624  * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
2625  */
2626 void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
2627         ia32_transform_env_t tenv;
2628         ir_node *in1, *in2, *noreg, *nomem, *res;
2629         const arch_register_t *in1_reg, *in2_reg, *out_reg, **slots;
2630
2631         /* Return if AM node or not a Sub or xSub */
2632         if (get_ia32_op_type(irn) != ia32_Normal || !(is_ia32_Sub(irn) || is_ia32_xSub(irn)))
2633                 return;
2634
2635         noreg   = ia32_new_NoReg_gp(cg);
2636         nomem   = new_rd_NoMem(cg->irg);
2637         in1     = get_irn_n(irn, 2);
2638         in2     = get_irn_n(irn, 3);
2639         in1_reg = arch_get_irn_register(cg->arch_env, in1);
2640         in2_reg = arch_get_irn_register(cg->arch_env, in2);
2641         out_reg = get_ia32_out_reg(irn, 0);
2642
2643         tenv.block    = get_nodes_block(irn);
2644         tenv.dbg      = get_irn_dbg_info(irn);
2645         tenv.irg      = cg->irg;
2646         tenv.irn      = irn;
2647         tenv.mode     = get_ia32_res_mode(irn);
2648         tenv.cg       = cg;
2649         DEBUG_ONLY(tenv.mod      = cg->mod;)
2650
2651         /* in case of sub and OUT == SRC2 we can transform the sequence into neg src2 -- add */
2652         if (REGS_ARE_EQUAL(out_reg, in2_reg)) {
2653                 /* generate the neg src2 */
2654                 res = gen_Minus_ex(&tenv, in2);
2655                 arch_set_irn_register(cg->arch_env, res, in2_reg);
2656
2657                 /* add to schedule */
2658                 sched_add_before(irn, res);
2659
2660                 /* generate the add */
2661                 if (mode_is_float(tenv.mode)) {
2662                         res = new_rd_ia32_xAdd(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem);
2663                         set_ia32_am_support(res, ia32_am_Source);
2664                 }
2665                 else {
2666                         res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem);
2667                         set_ia32_am_support(res, ia32_am_Full);
2668                         set_ia32_commutative(res);
2669                 }
2670             set_ia32_res_mode(res, tenv.mode);
2671
2672                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(tenv.cg, irn));
2673                 /* copy register */
2674                 slots    = get_ia32_slots(res);
2675                 slots[0] = in2_reg;
2676
2677                 /* add to schedule */
2678                 sched_add_before(irn, res);
2679
2680                 /* remove the old sub */
2681                 sched_remove(irn);
2682
2683                 DBG_OPT_SUB2NEGADD(irn, res);
2684
2685                 /* exchange the add and the sub */
2686                 exchange(irn, res);
2687         }
2688 }
2689
2690 /**
2691  * Transforms a LEA into an Add if possible
2692  * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
2693  */
2694 void ia32_transform_lea_to_add(ir_node *irn, ia32_code_gen_t *cg) {
2695         ia32_am_flavour_t am_flav;
2696         int               imm = 0;
2697         ir_node          *res = NULL;
2698         ir_node          *nomem, *noreg, *base, *index, *op1, *op2;
2699         char             *offs;
2700         ia32_transform_env_t tenv;
2701         const arch_register_t *out_reg, *base_reg, *index_reg;
2702
2703         /* must be a LEA */
2704         if (! is_ia32_Lea(irn))
2705                 return;
2706
2707         am_flav = get_ia32_am_flavour(irn);
2708
2709         if (get_ia32_am_sc(irn))
2710                 return;
2711
2712         /* only some LEAs can be transformed to an Add */
2713         if (am_flav != ia32_am_B && am_flav != ia32_am_OB && am_flav != ia32_am_OI && am_flav != ia32_am_BI)
2714                 return;
2715
2716         noreg = ia32_new_NoReg_gp(cg);
2717         nomem = new_rd_NoMem(cg->irg);
2718         op1   = noreg;
2719         op2   = noreg;
2720         base  = get_irn_n(irn, 0);
2721         index = get_irn_n(irn,1);
2722
2723         offs  = get_ia32_am_offs(irn);
2724
2725         /* offset has a explicit sign -> we need to skip + */
2726         if (offs && offs[0] == '+')
2727                 offs++;
2728
2729         out_reg   = arch_get_irn_register(cg->arch_env, irn);
2730         base_reg  = arch_get_irn_register(cg->arch_env, base);
2731         index_reg = arch_get_irn_register(cg->arch_env, index);
2732
2733         tenv.block = get_nodes_block(irn);
2734         tenv.dbg   = get_irn_dbg_info(irn);
2735         tenv.irg   = cg->irg;
2736         tenv.irn   = irn;
2737         DEBUG_ONLY(tenv.mod   = cg->mod;)
2738         tenv.mode  = get_irn_mode(irn);
2739         tenv.cg    = cg;
2740
2741         switch(get_ia32_am_flavour(irn)) {
2742                 case ia32_am_B:
2743                         /* out register must be same as base register */
2744                         if (! REGS_ARE_EQUAL(out_reg, base_reg))
2745                                 return;
2746
2747                         op1 = base;
2748                         break;
2749                 case ia32_am_OB:
2750                         /* out register must be same as base register */
2751                         if (! REGS_ARE_EQUAL(out_reg, base_reg))
2752                                 return;
2753
2754                         op1 = base;
2755                         imm = 1;
2756                         break;
2757                 case ia32_am_OI:
2758                         /* out register must be same as index register */
2759                         if (! REGS_ARE_EQUAL(out_reg, index_reg))
2760                                 return;
2761
2762                         op1 = index;
2763                         imm = 1;
2764                         break;
2765                 case ia32_am_BI:
2766                         /* out register must be same as one in register */
2767                         if (REGS_ARE_EQUAL(out_reg, base_reg)) {
2768                                 op1 = base;
2769                                 op2 = index;
2770                         }
2771                         else if (REGS_ARE_EQUAL(out_reg, index_reg)) {
2772                                 op1 = index;
2773                                 op2 = base;
2774                         }
2775                         else {
2776                                 /* in registers a different from out -> no Add possible */
2777                                 return;
2778                         }
2779                 default:
2780                         break;
2781         }
2782
2783         res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, op1, op2, nomem);
2784         arch_set_irn_register(cg->arch_env, res, out_reg);
2785         set_ia32_op_type(res, ia32_Normal);
2786         set_ia32_commutative(res);
2787         set_ia32_res_mode(res, tenv.mode);
2788
2789         if (imm) {
2790                 set_ia32_cnst(res, offs);
2791                 set_ia32_immop_type(res, ia32_ImmConst);
2792         }
2793
2794         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(cg, irn));
2795
2796         /* add Add to schedule */
2797         sched_add_before(irn, res);
2798
2799         DBG_OPT_LEA2ADD(irn, res);
2800
2801         res = new_rd_Proj(tenv.dbg, tenv.irg, tenv.block, res, tenv.mode, pn_ia32_Add_res);
2802
2803         /* add result Proj to schedule */
2804         sched_add_before(irn, res);
2805
2806         /* remove the old LEA */
2807         sched_remove(irn);
2808
2809         /* exchange the Add and the LEA */
2810         exchange(irn, res);
2811 }
2812
2813 /**
2814  * the BAD transformer.
2815  */
2816 static ir_node *bad_transform(ia32_transform_env_t *env) {
2817         ir_fprintf(stderr, "Not implemented: %+F\n", env->irn);
2818         assert(0);
2819         return NULL;
2820 }
2821
2822 /**
2823  * Enters all transform functions into the generic pointer
2824  */
2825 void ia32_register_transformers(void) {
2826         ir_op *op_Max, *op_Min, *op_Mulh;
2827
2828         /* first clear the generic function pointer for all ops */
2829         clear_irp_opcodes_generic_func();
2830
2831 #define GEN(a)   op_##a->ops.generic = (op_func)gen_##a
2832 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
2833 #define IGN(a)
2834
2835         GEN(Add);
2836         GEN(Sub);
2837         GEN(Mul);
2838         GEN(And);
2839         GEN(Or);
2840         GEN(Eor);
2841
2842         GEN(Shl);
2843         GEN(Shr);
2844         GEN(Shrs);
2845         GEN(Rot);
2846
2847         GEN(Quot);
2848
2849         GEN(Div);
2850         GEN(Mod);
2851         GEN(DivMod);
2852
2853         GEN(Minus);
2854         GEN(Conv);
2855         GEN(Abs);
2856         GEN(Not);
2857
2858         GEN(Load);
2859         GEN(Store);
2860         GEN(Cond);
2861
2862         GEN(CopyB);
2863         GEN(Mux);
2864         GEN(Psi);
2865
2866         /* transform ops from intrinsic lowering */
2867         GEN(ia32_l_Add);
2868         GEN(ia32_l_AddC);
2869         GEN(ia32_l_Sub);
2870         GEN(ia32_l_SubC);
2871         GEN(ia32_l_Minus);
2872         GEN(ia32_l_Mul);
2873         GEN(ia32_l_Eor);
2874         GEN(ia32_l_MulS);
2875         GEN(ia32_l_Shl);
2876         GEN(ia32_l_Shr);
2877         GEN(ia32_l_Shrs);
2878         GEN(ia32_l_ShlD);
2879         GEN(ia32_l_ShrD);
2880         GEN(ia32_l_vfdiv);
2881         GEN(ia32_l_vfmul);
2882         GEN(ia32_l_vfsub);
2883         GEN(ia32_l_vfild);
2884         GEN(ia32_l_Load);
2885         GEN(ia32_l_vfist);
2886         GEN(ia32_l_Store);
2887         GEN(ia32_l_X87toSSE);
2888         GEN(ia32_l_SSEtoX87);
2889
2890         IGN(Call);
2891         IGN(Alloc);
2892
2893         IGN(Proj);
2894         IGN(Block);
2895         IGN(Start);
2896         IGN(End);
2897         IGN(NoMem);
2898         IGN(Phi);
2899         IGN(IJmp);
2900         IGN(Break);
2901         IGN(Cmp);
2902
2903         /* constant transformation happens earlier */
2904         IGN(Const);
2905         IGN(SymConst);
2906         IGN(Sync);
2907
2908         BAD(Raise);
2909         BAD(Sel);
2910         BAD(InstOf);
2911         BAD(Cast);
2912         BAD(Free);
2913         BAD(Tuple);
2914         BAD(Id);
2915         BAD(Bad);
2916         BAD(Confirm);
2917         BAD(Filter);
2918         BAD(CallBegin);
2919         BAD(EndReg);
2920         BAD(EndExcept);
2921
2922         GEN(be_FrameAddr);
2923         GEN(be_FrameLoad);
2924         GEN(be_FrameStore);
2925         GEN(be_StackParam);
2926
2927         /* set the register for all Unknown nodes */
2928         GEN(Unknown);
2929
2930         op_Max = get_op_Max();
2931         if (op_Max)
2932                 GEN(Max);
2933         op_Min = get_op_Min();
2934         if (op_Min)
2935                 GEN(Min);
2936         op_Mulh = get_op_Mulh();
2937         if (op_Mulh)
2938                 GEN(Mulh);
2939
2940 #undef GEN
2941 #undef BAD
2942 #undef IGN
2943 }
2944
2945 typedef ir_node *(transform_func)(ia32_transform_env_t *env);
2946
2947 /**
2948  * Transforms the given firm node (and maybe some other related nodes)
2949  * into one or more assembler nodes.
2950  *
2951  * @param node    the firm node
2952  * @param env     the debug module
2953  */
2954 void ia32_transform_node(ir_node *node, void *env) {
2955         ia32_code_gen_t *cg = (ia32_code_gen_t *)env;
2956         ir_op *op           = get_irn_op(node);
2957         ir_node *asm_node   = NULL;
2958         int i;
2959
2960         if (is_Block(node))
2961                 return;
2962
2963         /* link arguments pointing to Unknown to the UNKNOWN Proj */
2964         for (i = get_irn_arity(node) - 1; i >= 0; i--) {
2965                 if (is_Unknown(get_irn_n(node, i)))
2966                         set_irn_n(node, i, be_get_unknown_for_mode(cg, get_irn_mode(get_irn_n(node, i))));
2967         }
2968
2969         DBG((cg->mod, LEVEL_1, "check %+F ... ", node));
2970         if (op->ops.generic) {
2971                 ia32_transform_env_t  tenv;
2972                 transform_func *transform = (transform_func *)op->ops.generic;
2973
2974                 tenv.block    = get_nodes_block(node);
2975                 tenv.dbg      = get_irn_dbg_info(node);
2976                 tenv.irg      = current_ir_graph;
2977                 tenv.irn      = node;
2978                 tenv.mode     = get_irn_mode(node);
2979                 tenv.cg       = cg;
2980                 DEBUG_ONLY(tenv.mod = cg->mod;)
2981
2982                 asm_node = (*transform)(&tenv);
2983         }
2984
2985         /* exchange nodes if a new one was generated */
2986         if (asm_node) {
2987                 exchange(node, asm_node);
2988                 DB((cg->mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
2989         }
2990         else {
2991                 DB((cg->mod, LEVEL_1, "ignored\n"));
2992         }
2993 }
2994
2995 /**
2996  * Transforms a psi condition.
2997  */
2998 static void transform_psi_cond(ir_node *cond, ir_mode *mode, ia32_code_gen_t *cg) {
2999         int i;
3000
3001         /* if the mode is target mode, we have already seen this part of the tree */
3002         if (get_irn_mode(cond) == mode)
3003                 return;
3004
3005         assert(get_irn_mode(cond) == mode_b && "logical operator for condition must be mode_b");
3006
3007         set_irn_mode(cond, mode);
3008
3009         for (i = get_irn_arity(cond) - 1; i >= 0; i--) {
3010                 ir_node *in = get_irn_n(cond, i);
3011
3012                 /* if in is a compare: transform into Set/xCmp */
3013                 if (is_Proj(in)) {
3014                         ir_node  *new_op = NULL;
3015                         ir_node  *cmp    = get_Proj_pred(in);
3016                         ir_node  *cmp_a  = get_Cmp_left(cmp);
3017                         ir_node  *cmp_b  = get_Cmp_right(cmp);
3018                         dbg_info *dbg    = get_irn_dbg_info(cmp);
3019                         ir_graph *irg    = get_irn_irg(cmp);
3020                         ir_node  *block  = get_nodes_block(cmp);
3021                         ir_node  *noreg  = ia32_new_NoReg_gp(cg);
3022                         ir_node  *nomem  = new_rd_NoMem(irg);
3023                         int      pnc     = get_Proj_proj(in);
3024
3025                         /* this is a compare */
3026                         if (mode_is_float(mode)) {
3027                                 /* Psi is float, we need a floating point compare */
3028
3029                                 if (USE_SSE2(cg)) {
3030                                         /* SSE FPU */
3031                                         if (! mode_is_float(get_irn_mode(cmp_a))) {
3032                                                 cmp_a = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_a, cmp_a, mode);
3033                                                 cmp_b = gen_sse_conv_int2float(cg, dbg, irg, block, cmp_b, cmp_b, mode);
3034                                                 pnc  |= 8;
3035                                         }
3036
3037                                         new_op = new_rd_ia32_xCmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
3038                                         set_ia32_pncode(new_op, pnc);
3039                                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, cmp));
3040                                 }
3041                                 else {
3042                                         /* x87 FPU */
3043                                         assert(0);
3044                                 }
3045                         }
3046                         else {
3047                                 /* integer Psi */
3048                                 ia32_transform_env_t tenv;
3049                                 construct_binop_func *set_func  = NULL;
3050
3051                                 if (mode_is_float(get_irn_mode(cmp_a))) {
3052                                         /* 1st case: compare operands are floats */
3053                                         FP_USED(cg);
3054
3055                                         if (USE_SSE2(cg)) {
3056                                                 /* SSE FPU */
3057                                                 set_func  = new_rd_ia32_xCmpSet;
3058                                         }
3059                                         else {
3060                                                 /* x87 FPU */
3061                                                 set_func  = new_rd_ia32_vfCmpSet;
3062                                         }
3063
3064                                         pnc &= 7; /* fp compare -> int compare */
3065                                 }
3066                                 else {
3067                                         /* 2nd case: compare operand are integer too */
3068                                         set_func  = new_rd_ia32_CmpSet;
3069                                 }
3070
3071                                 tenv.block = block;
3072                                 tenv.cg    = cg;
3073                                 tenv.dbg   = dbg;
3074                                 tenv.irg   = irg;
3075                                 tenv.irn   = cmp;
3076                                 tenv.mode  = mode;
3077                                 tenv.mod   = cg->mod;
3078
3079                                 new_op = gen_binop(&tenv, cmp_a, cmp_b, set_func);
3080                                 set_ia32_pncode(get_Proj_pred(new_op), pnc);
3081                                 set_ia32_am_support(get_Proj_pred(new_op), ia32_am_Source);
3082                         }
3083
3084                         /* the the new compare as in */
3085                         set_irn_n(cond, i, new_op);
3086                 }
3087                 else {
3088                         /* another complex condition */
3089                         transform_psi_cond(in, mode, cg);
3090                 }
3091         }
3092 }
3093
3094 /**
3095  * The Psi selector can be a tree of compares combined with "And"s and "Or"s.
3096  * We create a Set node, respectively a xCmp in case the Psi is a float, for each
3097  * compare, which causes the compare result to be stores in a register.  The
3098  * "And"s and "Or"s are transformed later, we just have to set their mode right.
3099  */
3100 void ia32_transform_psi_cond_tree(ir_node *node, void *env) {
3101         ia32_code_gen_t *cg      = (ia32_code_gen_t *)env;
3102         ir_node         *psi_sel, *new_cmp, *block;
3103         ir_graph        *irg;
3104         ir_mode         *mode;
3105
3106         /* check for Psi */
3107         if (get_irn_opcode(node) != iro_Psi)
3108                 return;
3109
3110         psi_sel = get_Psi_cond(node, 0);
3111
3112         /* if psi_cond is a cmp: do nothing, this case is covered by gen_Psi */
3113         if (is_Proj(psi_sel))
3114                 return;
3115
3116         mode = get_irn_mode(node);
3117
3118         transform_psi_cond(psi_sel, mode, cg);
3119
3120         irg   = get_irn_irg(node);
3121         block = get_nodes_block(node);
3122
3123         /* we need to compare the evaluated condition tree with 0 */
3124
3125         /* BEWARE: new_r_Const_long works for floating point as well */
3126         new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode, 0));
3127         /* transform the const */
3128         ia32_place_consts_set_modes(new_cmp, cg);
3129         new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Ne + (mode_is_float(mode) ? pn_Cmp_Uo : 0));
3130
3131         set_Psi_cond(node, 0, new_cmp);
3132 }