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