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