7399fb9d58e54e12a54985a6eded7a1f20d91adf
[libfirm] / ir / be / ia32 / ia32_transform.c
1 /**
2  * This file implements the IR transformation from firm into
3  * ia32-Firm.
4  *
5  * $Id$
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "irargs_t.h"
13 #include "irnode_t.h"
14 #include "irgraph_t.h"
15 #include "irmode_t.h"
16 #include "iropt_t.h"
17 #include "irop_t.h"
18 #include "irprog_t.h"
19 #include "iredges_t.h"
20 #include "irgmod.h"
21 #include "irvrfy.h"
22 #include "ircons.h"
23 #include "dbginfo.h"
24 #include "debug.h"
25
26 #include "../benode_t.h"
27 #include "../besched.h"
28
29 #include "bearch_ia32_t.h"
30
31 #include "ia32_nodes_attr.h"
32 #include "../arch/archop.h"     /* we need this for Min and Max nodes */
33 #include "ia32_transform.h"
34 #include "ia32_new_nodes.h"
35 #include "ia32_map_regs.h"
36
37 #include "gen_ia32_regalloc_if.h"
38
39 #define SFP_SIGN "0x80000000"
40 #define DFP_SIGN "0x8000000000000000"
41 #define SFP_ABS  "0x7FFFFFFF"
42 #define DFP_ABS  "0x7FFFFFFFFFFFFFFF"
43
44 #define TP_SFP_SIGN "ia32_sfp_sign"
45 #define TP_DFP_SIGN "ia32_dfp_sign"
46 #define TP_SFP_ABS  "ia32_sfp_abs"
47 #define TP_DFP_ABS  "ia32_dfp_abs"
48
49 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
50 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
51 #define ENT_SFP_ABS  "IA32_SFP_ABS"
52 #define ENT_DFP_ABS  "IA32_DFP_ABS"
53
54 extern ir_op *get_op_Mulh(void);
55
56 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
57                                                                           ir_node *op1, ir_node *op2, ir_node *mem, ir_mode *mode);
58
59 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
60                                                                          ir_node *op, ir_node *mem, ir_mode *mode);
61
62 typedef enum {
63         ia32_SSIGN, ia32_DSIGN, ia32_SABS, ia32_DABS, ia32_known_const_max
64 } ia32_known_const_t;
65
66 /****************************************************************************************************
67  *                  _        _                        __                           _   _
68  *                 | |      | |                      / _|                         | | (_)
69  *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
70  * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
71  * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
72  * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
73  *
74  ****************************************************************************************************/
75
76 /**
77  * Gets the Proj with number pn from irn.
78  */
79 static ir_node *get_proj_for_pn(const ir_node *irn, long pn) {
80         const ir_edge_t *edge;
81         ir_node   *proj;
82         assert(get_irn_mode(irn) == mode_T && "need mode_T");
83
84         foreach_out_edge(irn, edge) {
85                 proj = get_edge_src_irn(edge);
86
87                 if (get_Proj_proj(proj) == pn)
88                         return proj;
89         }
90
91         return NULL;
92 }
93
94 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
95 static ident *gen_fp_known_const(ir_mode *mode, ia32_known_const_t kct) {
96         static const struct {
97                 const char *tp_name;
98                 const char *ent_name;
99                 const char *cnst_str;
100         } names [ia32_known_const_max] = {
101                 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN },        /* ia32_SSIGN */
102                 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN },        /* ia32_DSIGN */
103                 { TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS },         /* ia32_SABS */
104                 { TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS }          /* ia32_DABS */
105         };
106         static struct entity *ent_cache[ia32_known_const_max];
107
108         const char    *tp_name, *ent_name, *cnst_str;
109         ir_type       *tp;
110         ir_node       *cnst;
111         ir_graph      *rem;
112         entity        *ent;
113         tarval        *tv;
114
115         ent_name = names[kct].ent_name;
116         if (! ent_cache[kct]) {
117                 tp_name  = names[kct].tp_name;
118                 cnst_str = names[kct].cnst_str;
119
120                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
121                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
122                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
123
124                 set_entity_ld_ident(ent, get_entity_ident(ent));
125                 set_entity_visibility(ent, visibility_local);
126                 set_entity_variability(ent, variability_constant);
127                 set_entity_allocation(ent, allocation_static);
128
129                 /* we create a new entity here: It's initialization must resist on the
130                     const code irg */
131                 rem = current_ir_graph;
132                 current_ir_graph = get_const_code_irg();
133                 cnst = new_Const(mode, tv);
134                 current_ir_graph = rem;
135
136                 set_atomic_ent_value(ent, cnst);
137
138                 /* cache the entry */
139                 ent_cache[kct] = ent;
140         }
141
142         return get_entity_ident(ent_cache[kct]);
143 }
144
145 #ifndef NDEBUG
146 /**
147  * Prints the old node name on cg obst and returns a pointer to it.
148  */
149 const char *ia32_get_old_node_name(ia32_transform_env_t *env) {
150         ia32_isa_t *isa = (ia32_isa_t *)env->cg->arch_env->isa;
151
152         lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", env->irn);
153         obstack_1grow(isa->name_obst, 0);
154         isa->name_obst_size += obstack_object_size(isa->name_obst);
155         return obstack_finish(isa->name_obst);
156 }
157 #endif /* NDEBUG */
158
159 /* determine if one operator is an Imm */
160 static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
161         if (op1)
162                 return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
163         else return is_ia32_Cnst(op2) ? op2 : NULL;
164 }
165
166 /* determine if one operator is not an Imm */
167 static ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
168         return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
169 }
170
171
172 /**
173  * Construct a standard binary operation, set AM and immediate if required.
174  *
175  * @param env   The transformation environment
176  * @param op1   The first operand
177  * @param op2   The second operand
178  * @param func  The node constructor function
179  * @return The constructed ia32 node.
180  */
181 static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, construct_binop_func *func) {
182         ir_node           *new_op   = NULL;
183         ir_mode           *mode     = env->mode;
184         dbg_info          *dbg      = env->dbg;
185         ir_graph          *irg      = env->irg;
186         ir_node           *block    = env->block;
187         firm_dbg_module_t *mod      = env->mod;
188         ir_node           *noreg_gp = ia32_new_NoReg_gp(env->cg);
189         ir_node           *noreg_fp = ia32_new_NoReg_fp(env->cg);
190         ir_node           *nomem    = new_NoMem();
191         ir_node           *expr_op, *imm_op;
192
193         /* Check if immediate optimization is on and */
194         /* if it's an operation with immediate.      */
195         if (! env->cg->opt.immops) {
196                 expr_op = op1;
197                 imm_op  = NULL;
198         }
199         else if (is_op_commutative(get_irn_op(env->irn))) {
200                 imm_op  = get_immediate_op(op1, op2);
201                 expr_op = get_expr_op(op1, op2);
202         }
203         else {
204                 imm_op  = get_immediate_op(NULL, op2);
205                 expr_op = get_expr_op(op1, op2);
206         }
207
208         assert((expr_op || imm_op) && "invalid operands");
209
210         if (!expr_op) {
211                 /* We have two consts here: not yet supported */
212                 imm_op = NULL;
213         }
214
215         if (mode_is_float(mode)) {
216                 /* floating point operations */
217                 if (imm_op) {
218                         DB((mod, LEVEL_1, "FP with immediate ..."));
219                         new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem, mode_T);
220                         set_ia32_Immop_attr(new_op, imm_op);
221                         set_ia32_am_support(new_op, ia32_am_None);
222                 }
223                 else {
224                         DB((mod, LEVEL_1, "FP binop ..."));
225                         new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem, mode_T);
226                         set_ia32_am_support(new_op, ia32_am_Source);
227                 }
228         }
229         else {
230                 /* integer operations */
231                 if (imm_op) {
232                         /* This is expr + const */
233                         DB((mod, LEVEL_1, "INT with immediate ..."));
234                         new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem, mode_T);
235                         set_ia32_Immop_attr(new_op, imm_op);
236
237                         /* set AM support */
238                         set_ia32_am_support(new_op, ia32_am_Dest);
239                 }
240                 else {
241                         DB((mod, LEVEL_1, "INT binop ..."));
242                         /* This is a normal operation */
243                         new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem, mode_T);
244
245                         /* set AM support */
246                         set_ia32_am_support(new_op, ia32_am_Full);
247                 }
248         }
249
250         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
251
252         set_ia32_res_mode(new_op, mode);
253
254         if (is_op_commutative(get_irn_op(env->irn))) {
255                 set_ia32_commutative(new_op);
256         }
257
258         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
259 }
260
261
262
263 /**
264  * Construct a shift/rotate binary operation, sets AM and immediate if required.
265  *
266  * @param env   The transformation environment
267  * @param op1   The first operand
268  * @param op2   The second operand
269  * @param func  The node constructor function
270  * @return The constructed ia32 node.
271  */
272 static ir_node *gen_shift_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, construct_binop_func *func) {
273         ir_node           *new_op = NULL;
274         ir_mode           *mode   = env->mode;
275         dbg_info          *dbg    = env->dbg;
276         ir_graph          *irg    = env->irg;
277         ir_node           *block  = env->block;
278         firm_dbg_module_t *mod    = env->mod;
279         ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
280         ir_node           *nomem  = new_NoMem();
281         ir_node           *expr_op, *imm_op;
282         tarval            *tv;
283
284         assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");
285
286         /* Check if immediate optimization is on and */
287         /* if it's an operation with immediate.      */
288         imm_op  = env->cg->opt.immops ? get_immediate_op(NULL, op2) : NULL;
289         expr_op = get_expr_op(op1, op2);
290
291         assert((expr_op || imm_op) && "invalid operands");
292
293         if (!expr_op) {
294                 /* We have two consts here: not yet supported */
295                 imm_op = NULL;
296         }
297
298         /* Limit imm_op within range imm8 */
299         if (imm_op) {
300                 tv = get_ia32_Immop_tarval(imm_op);
301
302                 if (tv) {
303                         tv = tarval_mod(tv, new_tarval_from_long(32, mode_Iu));
304                 }
305                 else {
306                         imm_op = NULL;
307                 }
308         }
309
310         /* integer operations */
311         if (imm_op) {
312                 /* This is shift/rot with const */
313                 DB((mod, LEVEL_1, "Shift/Rot with immediate ..."));
314
315                 new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T);
316                 set_ia32_Immop_attr(new_op, imm_op);
317         }
318         else {
319                 /* This is a normal shift/rot */
320                 DB((mod, LEVEL_1, "Shift/Rot binop ..."));
321                 new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T);
322         }
323
324         /* set AM support */
325         set_ia32_am_support(new_op, ia32_am_Dest);
326
327         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
328
329         set_ia32_res_mode(new_op, mode);
330         set_ia32_emit_cl(new_op);
331
332         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
333 }
334
335
336 /**
337  * Construct a standard unary operation, set AM and immediate if required.
338  *
339  * @param env   The transformation environment
340  * @param op    The operand
341  * @param func  The node constructor function
342  * @return The constructed ia32 node.
343  */
344 static ir_node *gen_unop(ia32_transform_env_t *env, ir_node *op, construct_unop_func *func) {
345         ir_node           *new_op = NULL;
346         ir_mode           *mode   = env->mode;
347         dbg_info          *dbg    = env->dbg;
348         firm_dbg_module_t *mod    = env->mod;
349         ir_graph          *irg    = env->irg;
350         ir_node           *block  = env->block;
351         ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
352         ir_node           *nomem  = new_NoMem();
353
354         new_op = func(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
355
356         if (mode_is_float(mode)) {
357                 DB((mod, LEVEL_1, "FP unop ..."));
358                 /* floating point operations don't support implicit store */
359                 set_ia32_am_support(new_op, ia32_am_None);
360         }
361         else {
362                 DB((mod, LEVEL_1, "INT unop ..."));
363                 set_ia32_am_support(new_op, ia32_am_Dest);
364         }
365
366         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
367
368         set_ia32_res_mode(new_op, mode);
369
370         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
371 }
372
373
374
375 /**
376  * Creates an ia32 Add with immediate.
377  *
378  * @param env       The transformation environment
379  * @param expr_op   The expression operator
380  * @param const_op  The constant
381  * @return the created ia32 Add node
382  */
383 static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
384         ir_node                *new_op     = NULL;
385         tarval                 *tv         = get_ia32_Immop_tarval(const_op);
386         firm_dbg_module_t      *mod        = env->mod;
387         dbg_info               *dbg        = env->dbg;
388         ir_graph               *irg        = env->irg;
389         ir_node                *block      = env->block;
390         ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
391         ir_node                *nomem      = new_NoMem();
392         int                     normal_add = 1;
393         tarval_classification_t class_tv, class_negtv;
394
395         /* try to optimize to inc/dec  */
396         if (env->cg->opt.incdec && tv) {
397                 /* optimize tarvals */
398                 class_tv    = classify_tarval(tv);
399                 class_negtv = classify_tarval(tarval_neg(tv));
400
401                 if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
402                         DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
403                         new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T);
404                         normal_add = 0;
405                 }
406                 else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
407                         DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
408                         new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T);
409                         normal_add = 0;
410                 }
411         }
412
413         if (normal_add) {
414                 new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T);
415                 set_ia32_Immop_attr(new_op, const_op);
416         }
417
418         return new_op;
419 }
420
421 /**
422  * Creates an ia32 Add.
423  *
424  * @param dbg       firm node dbg
425  * @param block     the block the new node should belong to
426  * @param op1       first operator
427  * @param op2       second operator
428  * @param mode      node mode
429  * @return the created ia32 Add node
430  */
431 static ir_node *gen_Add(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
432         ir_node  *new_op = NULL;
433         dbg_info *dbg    = env->dbg;
434         ir_mode  *mode   = env->mode;
435         ir_graph *irg    = env->irg;
436         ir_node  *block  = env->block;
437         ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
438         ir_node  *nomem  = new_NoMem();
439         ir_node  *expr_op, *imm_op;
440
441         /* Check if immediate optimization is on and */
442         /* if it's an operation with immediate.      */
443         imm_op  = env->cg->opt.immops ? get_immediate_op(op1, op2) : NULL;
444         expr_op = get_expr_op(op1, op2);
445
446         assert((expr_op || imm_op) && "invalid operands");
447
448         if (mode_is_float(mode)) {
449                 if (USE_SSE2(env->cg))
450                         return gen_binop(env, op1, op2, new_rd_ia32_fAdd);
451                 else {
452                         return gen_binop(env, op1, op2, new_rd_ia32_vfadd);
453                 }
454         }
455         else {
456                 /* integer ADD */
457                 if (!expr_op) {
458                         /* No expr_op means, that we have two const - one symconst and */
459                         /* one tarval or another symconst - because this case is not   */
460                         /* covered by constant folding                                 */
461
462                         new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);
463                         add_ia32_am_offs(new_op, get_ia32_cnst(op1));
464                         add_ia32_am_offs(new_op, get_ia32_cnst(op2));
465
466                         /* set AM support */
467                         set_ia32_am_support(new_op, ia32_am_Source);
468                         set_ia32_op_type(new_op, ia32_AddrModeS);
469                         set_ia32_am_flavour(new_op, ia32_am_O);
470
471                         /* Lea doesn't need a Proj */
472                         return new_op;
473                 }
474                 else if (imm_op) {
475                         /* This is expr + const */
476                         new_op = gen_imm_Add(env, expr_op, imm_op);
477
478                         /* set AM support */
479                         set_ia32_am_support(new_op, ia32_am_Dest);
480                 }
481                 else {
482                         /* This is a normal add */
483                         new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T);
484
485                         /* set AM support */
486                         set_ia32_am_support(new_op, ia32_am_Full);
487                 }
488         }
489
490         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
491
492         set_ia32_res_mode(new_op, mode);
493
494         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
495 }
496
497
498
499 /**
500  * Creates an ia32 Mul.
501  *
502  * @param dbg       firm node dbg
503  * @param block     the block the new node should belong to
504  * @param op1       first operator
505  * @param op2       second operator
506  * @param mode      node mode
507  * @return the created ia32 Mul node
508  */
509 static ir_node *gen_Mul(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
510         ir_node *new_op;
511
512         if (mode_is_float(env->mode)) {
513                 if (USE_SSE2(env->cg))
514                         new_op = gen_binop(env, op1, op2, new_rd_ia32_fMul);
515                 else
516                         new_op = gen_binop(env, op1, op2, new_rd_ia32_vfmul);
517         }
518         else {
519                 new_op = gen_binop(env, op1, op2, new_rd_ia32_Mul);
520         }
521
522         return new_op;
523 }
524
525
526
527 /**
528  * Creates an ia32 Mulh.
529  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
530  * this result while Mul returns the lower 32 bit.
531  *
532  * @param env   The transformation environment
533  * @param op1   The first operator
534  * @param op2   The second operator
535  * @return the created ia32 Mulh node
536  */
537 static ir_node *gen_Mulh(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
538         ir_node *proj_EAX, *proj_EDX, *mulh;
539         ir_node *in[1];
540
541         assert(!mode_is_float(env->mode) && "Mulh with float not supported");
542         proj_EAX = gen_binop(env, op1, op2, new_rd_ia32_Mulh);
543         mulh     = get_Proj_pred(proj_EAX);
544         proj_EDX = new_rd_Proj(env->dbg, env->irg, env->block, mulh, env->mode, pn_EDX);
545
546         /* to be on the save side */
547         set_Proj_proj(proj_EAX, pn_EAX);
548
549         if (is_ia32_ImmConst(mulh) || is_ia32_ImmSymConst(mulh)) {
550                 /* Mulh with const cannot have AM */
551                 set_ia32_am_support(mulh, ia32_am_None);
552         }
553         else {
554                 /* Mulh cannot have AM for destination */
555                 set_ia32_am_support(mulh, ia32_am_Source);
556         }
557
558         in[0] = proj_EAX;
559
560         /* keep EAX */
561         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], env->irg, env->block, 1, in);
562
563         return proj_EDX;
564 }
565
566
567
568 /**
569  * Creates an ia32 And.
570  *
571  * @param env   The transformation environment
572  * @param op1   The first operator
573  * @param op2   The second operator
574  * @return The created ia32 And node
575  */
576 static ir_node *gen_And(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
577         assert (! mode_is_float(env->mode));
578         return gen_binop(env, op1, op2, new_rd_ia32_And);
579 }
580
581
582
583 /**
584  * Creates an ia32 Or.
585  *
586  * @param env   The transformation environment
587  * @param op1   The first operator
588  * @param op2   The second operator
589  * @return The created ia32 Or node
590  */
591 static ir_node *gen_Or(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
592         assert (! mode_is_float(env->mode));
593         return gen_binop(env, op1, op2, new_rd_ia32_Or);
594 }
595
596
597
598 /**
599  * Creates an ia32 Eor.
600  *
601  * @param env   The transformation environment
602  * @param op1   The first operator
603  * @param op2   The second operator
604  * @return The created ia32 Eor node
605  */
606 static ir_node *gen_Eor(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
607         assert(! mode_is_float(env->mode));
608         return gen_binop(env, op1, op2, new_rd_ia32_Eor);
609 }
610
611
612
613 /**
614  * Creates an ia32 Max.
615  *
616  * @param env      The transformation environment
617  * @param op1      The first operator
618  * @param op2      The second operator
619  * @return the created ia32 Max node
620  */
621 static ir_node *gen_Max(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
622         ir_node *new_op;
623
624         if (mode_is_float(env->mode)) {
625                 new_op = gen_binop(env, op1, op2, new_rd_ia32_fMax);
626         }
627         else {
628                 new_op = new_rd_ia32_Max(env->dbg, env->irg, env->block, op1, op2, env->mode);
629                 set_ia32_am_support(new_op, ia32_am_None);
630                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
631         }
632
633         return new_op;
634 }
635
636
637
638 /**
639  * Creates an ia32 Min.
640  *
641  * @param env      The transformation environment
642  * @param op1      The first operator
643  * @param op2      The second operator
644  * @return the created ia32 Min node
645  */
646 static ir_node *gen_Min(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
647         ir_node *new_op;
648
649         if (mode_is_float(env->mode)) {
650                 new_op = gen_binop(env, op1, op2, new_rd_ia32_fMin);
651         }
652         else {
653                 new_op = new_rd_ia32_Min(env->dbg, env->irg, env->block, op1, op2, env->mode);
654                 set_ia32_am_support(new_op, ia32_am_None);
655                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
656         }
657
658         return new_op;
659 }
660
661
662
663 /**
664  * Creates an ia32 Sub with immediate.
665  *
666  * @param env   The transformation environment
667  * @param op1   The first operator
668  * @param op2   The second operator
669  * @return The created ia32 Sub node
670  */
671 static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
672         ir_node                *new_op     = NULL;
673         tarval                 *tv         = get_ia32_Immop_tarval(const_op);
674         firm_dbg_module_t      *mod        = env->mod;
675         dbg_info               *dbg        = env->dbg;
676         ir_graph               *irg        = env->irg;
677         ir_node                *block      = env->block;
678         ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
679         ir_node                *nomem      = new_NoMem();
680         int                     normal_sub = 1;
681         tarval_classification_t class_tv, class_negtv;
682
683         /* try to optimize to inc/dec  */
684         if (env->cg->opt.incdec && tv) {
685                 /* optimize tarvals */
686                 class_tv    = classify_tarval(tv);
687                 class_negtv = classify_tarval(tarval_neg(tv));
688
689                 if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
690                         DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
691                         new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T);
692                         normal_sub = 0;
693                 }
694                 else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
695                         DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
696                         new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T);
697                         normal_sub = 0;
698                 }
699         }
700
701         if (normal_sub) {
702                 new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T);
703                 set_ia32_Immop_attr(new_op, const_op);
704         }
705
706         return new_op;
707 }
708
709 /**
710  * Creates an ia32 Sub.
711  *
712  * @param env   The transformation environment
713  * @param op1   The first operator
714  * @param op2   The second operator
715  * @return The created ia32 Sub node
716  */
717 static ir_node *gen_Sub(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
718         ir_node  *new_op = NULL;
719         dbg_info *dbg    = env->dbg;
720         ir_mode  *mode   = env->mode;
721         ir_graph *irg    = env->irg;
722         ir_node  *block  = env->block;
723         ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
724         ir_node  *nomem  = new_NoMem();
725         ir_node  *expr_op, *imm_op;
726
727         /* Check if immediate optimization is on and */
728         /* if it's an operation with immediate.      */
729         imm_op  = env->cg->opt.immops ? get_immediate_op(NULL, op2) : NULL;
730         expr_op = get_expr_op(op1, op2);
731
732         assert((expr_op || imm_op) && "invalid operands");
733
734         if (mode_is_float(mode)) {
735                 if (USE_SSE2(env->cg))
736                         return gen_binop(env, op1, op2, new_rd_ia32_fSub);
737                 else
738                         return gen_binop(env, op1, op2, new_rd_ia32_vfsub);
739         }
740         else {
741                 /* integer SUB */
742                 if (!expr_op) {
743                         /* No expr_op means, that we have two const - one symconst and */
744                         /* one tarval or another symconst - because this case is not   */
745                         /* covered by constant folding                                 */
746
747                         new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);
748                         add_ia32_am_offs(new_op, get_ia32_cnst(op1));
749                         sub_ia32_am_offs(new_op, get_ia32_cnst(op2));
750
751                         /* set AM support */
752                         set_ia32_am_support(new_op, ia32_am_Source);
753                         set_ia32_op_type(new_op, ia32_AddrModeS);
754                         set_ia32_am_flavour(new_op, ia32_am_O);
755
756                         /* Lea doesn't need a Proj */
757                         return new_op;
758                 }
759                 else if (imm_op) {
760                         /* This is expr - const */
761                         new_op = gen_imm_Sub(env, expr_op, imm_op);
762
763                         /* set AM support */
764                         set_ia32_am_support(new_op, ia32_am_Dest);
765                 }
766                 else {
767                         /* This is a normal sub */
768                         new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T);
769
770                         /* set AM support */
771                         set_ia32_am_support(new_op, ia32_am_Full);
772                 }
773         }
774
775         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
776
777         set_ia32_res_mode(new_op, mode);
778
779         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
780 }
781
782
783
784 /**
785  * Generates an ia32 DivMod with additional infrastructure for the
786  * register allocator if needed.
787  *
788  * @param env      The transformation environment
789  * @param dividend -no comment- :)
790  * @param divisor  -no comment- :)
791  * @param dm_flav  flavour_Div/Mod/DivMod
792  * @return The created ia32 DivMod node
793  */
794 static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir_node *divisor, ia32_op_flavour_t dm_flav) {
795         ir_node  *res, *proj;
796         ir_node  *edx_node, *cltd;
797         ir_node  *in_keep[1];
798         dbg_info *dbg   = env->dbg;
799         ir_graph *irg   = env->irg;
800         ir_node  *block = env->block;
801         ir_mode  *mode  = env->mode;
802         ir_node  *irn   = env->irn;
803         ir_node  *mem;
804
805         switch (dm_flav) {
806                 case flavour_Div:
807                         mem  = get_Div_mem(irn);
808                         mode = get_irn_mode(get_proj_for_pn(irn, pn_Div_res));
809                         break;
810                 case flavour_Mod:
811                         mem  = get_Mod_mem(irn);
812                         mode = get_irn_mode(get_proj_for_pn(irn, pn_Mod_res));
813                         break;
814                 case flavour_DivMod:
815                         mem  = get_DivMod_mem(irn);
816                         mode = get_irn_mode(get_proj_for_pn(irn, pn_DivMod_res_div));
817                         break;
818                 default:
819                         assert(0);
820         }
821
822         if (mode_is_signed(mode)) {
823                 /* in signed mode, we need to sign extend the dividend */
824                 cltd     = new_rd_ia32_Cdq(dbg, irg, block, dividend, mode_T);
825                 dividend = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_EAX);
826                 edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_EDX);
827         }
828         else {
829                 edx_node = new_rd_ia32_Const(dbg, irg, block, mode_Iu);
830                 set_ia32_Const_type(edx_node, ia32_Const);
831                 set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
832         }
833
834         res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, mode_T);
835
836         set_ia32_flavour(res, dm_flav);
837         set_ia32_n_res(res, 2);
838
839         /* Only one proj is used -> We must add a second proj and */
840         /* connect this one to a Keep node to eat up the second   */
841         /* destroyed register.                                    */
842         if (get_irn_n_edges(irn) == 1) {
843                 proj = get_edge_src_irn(get_irn_out_edge_first(irn));
844                 assert(is_Proj(proj) && "non-Proj to Div/Mod node");
845
846                 if (get_Proj_proj(proj) == pn_DivMod_res_div) {
847                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_mod);
848                 }
849                 else {
850                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_div);
851                 }
852
853                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
854         }
855
856         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
857
858         set_ia32_res_mode(res, mode_Is);
859
860         return res;
861 }
862
863
864 /**
865  * Wrapper for generate_DivMod. Sets flavour_Mod.
866  */
867 static ir_node *gen_Mod(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
868         return generate_DivMod(env, op1, op2, flavour_Mod);
869 }
870
871
872
873 /**
874  * Wrapper for generate_DivMod. Sets flavour_Div.
875  */
876 static ir_node *gen_Div(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
877         return generate_DivMod(env, op1, op2, flavour_Div);
878 }
879
880
881
882 /**
883  * Wrapper for generate_DivMod. Sets flavour_DivMod.
884  */
885 static ir_node *gen_DivMod(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
886         return generate_DivMod(env, op1, op2, flavour_DivMod);
887 }
888
889
890
891 /**
892  * Creates an ia32 floating Div.
893  *
894  * @param env   The transformation environment
895  * @param op1   The first operator
896  * @param op2   The second operator
897  * @return The created ia32 fDiv node
898  */
899 static ir_node *gen_Quot(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
900         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
901         ir_node *new_op;
902         ir_node *nomem = new_rd_NoMem(env->irg);
903
904         if (USE_SSE2(env->cg)) {
905
906                 if (is_ia32_fConst(op2)) {
907                         new_op = new_rd_ia32_fDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, noreg, nomem, mode_T);
908                         set_ia32_am_support(new_op, ia32_am_None);
909                         set_ia32_Immop_attr(new_op, op2);
910                 }
911                 else {
912                         new_op = new_rd_ia32_fDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem, mode_T);
913                         set_ia32_am_support(new_op, ia32_am_Source);
914                 }
915         }
916         else {
917                         new_op = new_rd_ia32_vfdiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem, mode_T);
918                         set_ia32_am_support(new_op, ia32_am_Source);
919         }
920         set_ia32_res_mode(new_op, get_irn_mode(get_proj_for_pn(env->irn, pn_Quot_res)));
921         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
922
923         return new_op;
924 }
925
926
927
928 /**
929  * Creates an ia32 Shl.
930  *
931  * @param env   The transformation environment
932  * @param op1   The first operator
933  * @param op2   The second operator
934  * @return The created ia32 Shl node
935  */
936 static ir_node *gen_Shl(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
937         return gen_shift_binop(env, op1, op2, new_rd_ia32_Shl);
938 }
939
940
941
942 /**
943  * Creates an ia32 Shr.
944  *
945  * @param env   The transformation environment
946  * @param op1   The first operator
947  * @param op2   The second operator
948  * @return The created ia32 Shr node
949  */
950 static ir_node *gen_Shr(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
951         return gen_shift_binop(env, op1, op2, new_rd_ia32_Shr);
952 }
953
954
955
956 /**
957  * Creates an ia32 Shrs.
958  *
959  * @param env   The transformation environment
960  * @param op1   The first operator
961  * @param op2   The second operator
962  * @return The created ia32 Shrs node
963  */
964 static ir_node *gen_Shrs(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
965         return gen_shift_binop(env, op1, op2, new_rd_ia32_Shrs);
966 }
967
968
969
970 /**
971  * Creates an ia32 RotL.
972  *
973  * @param env   The transformation environment
974  * @param op1   The first operator
975  * @param op2   The second operator
976  * @return The created ia32 RotL node
977  */
978 static ir_node *gen_RotL(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
979         return gen_shift_binop(env, op1, op2, new_rd_ia32_RotL);
980 }
981
982
983
984 /**
985  * Creates an ia32 RotR.
986  * NOTE: There is no RotR with immediate because this would always be a RotL
987  *       "imm-mode_size_bits" which can be pre-calculated.
988  *
989  * @param env   The transformation environment
990  * @param op1   The first operator
991  * @param op2   The second operator
992  * @return The created ia32 RotR node
993  */
994 static ir_node *gen_RotR(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
995         return gen_shift_binop(env, op1, op2, new_rd_ia32_RotR);
996 }
997
998
999
1000 /**
1001  * Creates an ia32 RotR or RotL (depending on the found pattern).
1002  *
1003  * @param env   The transformation environment
1004  * @param op1   The first operator
1005  * @param op2   The second operator
1006  * @return The created ia32 RotL or RotR node
1007  */
1008 static ir_node *gen_Rot(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
1009         ir_node *rotate = NULL;
1010
1011         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1012                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1013                  that means we can create a RotR instead of an Add and a RotL */
1014
1015         if (is_Proj(op2)) {
1016                 ir_node *pred = get_Proj_pred(op2);
1017
1018                 if (is_ia32_Add(pred)) {
1019                         ir_node *pred_pred = get_irn_n(pred, 2);
1020                         tarval  *tv        = get_ia32_Immop_tarval(pred);
1021                         long     bits      = get_mode_size_bits(env->mode);
1022
1023                         if (is_Proj(pred_pred)) {
1024                                 pred_pred = get_Proj_pred(pred_pred);
1025                         }
1026
1027                         if (is_ia32_Minus(pred_pred) &&
1028                                 tarval_is_long(tv)       &&
1029                                 get_tarval_long(tv) == bits)
1030                         {
1031                                 DB((env->mod, LEVEL_1, "RotL into RotR ... "));
1032                                 rotate = gen_RotR(env, op1, get_irn_n(pred_pred, 2));
1033                         }
1034
1035                 }
1036         }
1037
1038         if (!rotate) {
1039                 rotate = gen_RotL(env, op1, op2);
1040         }
1041
1042         return rotate;
1043 }
1044
1045
1046
1047 /**
1048  * Transforms a Minus node.
1049  *
1050  * @param env   The transformation environment
1051  * @param op    The operator
1052  * @return The created ia32 Minus node
1053  */
1054 static ir_node *gen_Minus(ia32_transform_env_t *env, ir_node *op) {
1055         ident   *name;
1056         ir_node *new_op;
1057         ir_node *noreg_gp = ia32_new_NoReg_gp(env->cg);
1058         ir_node *noreg_fp = ia32_new_NoReg_fp(env->cg);
1059         ir_node *nomem    = new_rd_NoMem(env->irg);
1060         int      size;
1061
1062         if (mode_is_float(env->mode)) {
1063                 if (USE_SSE2(env->cg)) {
1064                         new_op = new_rd_ia32_fEor(env->dbg, env->irg, env->block, noreg_gp, noreg_gp, op, noreg_fp, nomem, mode_T);
1065
1066                         size   = get_mode_size_bits(env->mode);
1067                         name   = gen_fp_known_const(env->mode, size == 32 ? ia32_SSIGN : ia32_DSIGN);
1068
1069                         set_ia32_sc(new_op, name);
1070
1071                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1072
1073                         set_ia32_res_mode(new_op, env->mode);
1074                         set_ia32_immop_type(new_op, ia32_ImmSymConst);
1075
1076                         new_op = new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, 0);
1077                 }
1078                 else {
1079                         new_op = new_rd_ia32_vfchs(env->dbg, env->irg, env->block, op, env->mode);
1080                         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1081                 }
1082         }
1083         else {
1084                 new_op = gen_unop(env, op, new_rd_ia32_Minus);
1085         }
1086
1087         return new_op;
1088 }
1089
1090
1091
1092 /**
1093  * Transforms a Not node.
1094  *
1095  * @param env   The transformation environment
1096  * @param op    The operator
1097  * @return The created ia32 Not node
1098  */
1099 static ir_node *gen_Not(ia32_transform_env_t *env, ir_node *op) {
1100         assert (! mode_is_float(env->mode));
1101         return gen_unop(env, op, new_rd_ia32_Not);
1102 }
1103
1104
1105
1106 /**
1107  * Transforms an Abs node.
1108  *
1109  * @param env   The transformation environment
1110  * @param op    The operator
1111  * @return The created ia32 Abs node
1112  */
1113 static ir_node *gen_Abs(ia32_transform_env_t *env, ir_node *op) {
1114         ir_node  *res, *p_eax, *p_edx;
1115         dbg_info *dbg      = env->dbg;
1116         ir_mode  *mode     = env->mode;
1117         ir_graph *irg      = env->irg;
1118         ir_node  *block    = env->block;
1119         ir_node  *noreg_gp = ia32_new_NoReg_gp(env->cg);
1120         ir_node  *noreg_fp = ia32_new_NoReg_fp(env->cg);
1121         ir_node  *nomem    = new_NoMem();
1122         int       size;
1123         ident    *name;
1124
1125         if (mode_is_float(mode)) {
1126                 if (USE_SSE2(env->cg)) {
1127                         res = new_rd_ia32_fAnd(dbg,irg, block, noreg_gp, noreg_gp, op, noreg_fp, nomem, mode_T);
1128
1129                         size   = get_mode_size_bits(mode);
1130                         name   = gen_fp_known_const(mode, size == 32 ? ia32_SABS : ia32_DABS);
1131
1132                         set_ia32_sc(res, name);
1133
1134                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
1135
1136                         set_ia32_res_mode(res, mode);
1137                         set_ia32_immop_type(res, ia32_ImmSymConst);
1138
1139                         res = new_rd_Proj(dbg, irg, block, res, mode, 0);
1140                 }
1141                 else {
1142                         res = new_rd_ia32_vfabs(dbg, irg, block, op, mode);
1143                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
1144                 }
1145         }
1146         else {
1147                 res   = new_rd_ia32_Cdq(dbg, irg, block, op, mode_T);
1148                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
1149                 set_ia32_res_mode(res, mode);
1150
1151                 p_eax = new_rd_Proj(dbg, irg, block, res, mode, pn_EAX);
1152                 p_edx = new_rd_Proj(dbg, irg, block, res, mode, pn_EDX);
1153
1154                 res   = new_rd_ia32_Eor(dbg, irg, block, noreg_gp, noreg_gp, p_eax, p_edx, nomem, mode_T);
1155                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
1156                 set_ia32_res_mode(res, mode);
1157
1158                 res   = new_rd_Proj(dbg, irg, block, res, mode, 0);
1159
1160                 res   = new_rd_ia32_Sub(dbg, irg, block, noreg_gp, noreg_gp, res, p_edx, nomem, mode_T);
1161                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
1162                 set_ia32_res_mode(res, mode);
1163
1164                 res   = new_rd_Proj(dbg, irg, block, res, mode, 0);
1165         }
1166
1167         return res;
1168 }
1169
1170
1171
1172 /**
1173  * Transforms a Load.
1174  *
1175  * @param mod     the debug module
1176  * @param block   the block the new node should belong to
1177  * @param node    the ir Load node
1178  * @param mode    node mode
1179  * @return the created ia32 Load node
1180  */
1181 static ir_node *gen_Load(ia32_transform_env_t *env) {
1182         ir_node    *node  = env->irn;
1183         ir_node    *noreg = ia32_new_NoReg_gp(env->cg);
1184         ir_node    *ptr   = get_Load_ptr(node);
1185         ir_mode    *mode  = get_Load_mode(node);
1186         const char *offs  = NULL;
1187         ir_node *new_op;
1188         ia32_am_flavour_t am_flav = ia32_B;
1189
1190         /* address might be a constant (symconst or absolute address) */
1191         if (is_ia32_Const(ptr)) {
1192                 offs = get_ia32_cnst(ptr);
1193                 ptr  = noreg;
1194         }
1195
1196         if (mode_is_float(mode)) {
1197                 if (USE_SSE2(env->cg))
1198                         new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, get_Load_mem(node), env->mode);
1199                 else
1200                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, get_Load_mem(node), env->mode);
1201         }
1202         else {
1203                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, get_Load_mem(node), env->mode);
1204         }
1205
1206         /* base is an constant address */
1207         if (offs) {
1208                 add_ia32_am_offs(new_op, offs);
1209                 am_flav = ia32_O;
1210         }
1211
1212         set_ia32_am_support(new_op, ia32_am_Source);
1213         set_ia32_op_type(new_op, ia32_AddrModeS);
1214         set_ia32_am_flavour(new_op, am_flav);
1215         set_ia32_ls_mode(new_op, mode);
1216
1217         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1218
1219         return new_op;
1220 }
1221
1222
1223
1224 /**
1225  * Transforms a Store.
1226  *
1227  * @param mod     the debug module
1228  * @param block   the block the new node should belong to
1229  * @param node    the ir Store node
1230  * @param mode    node mode
1231  * @return the created ia32 Store node
1232  */
1233 static ir_node *gen_Store(ia32_transform_env_t *env) {
1234         ir_node *node    = env->irn;
1235         ir_node *noreg   = ia32_new_NoReg_gp(env->cg);
1236         ir_node *val     = get_Store_value(node);
1237         ir_node *ptr     = get_Store_ptr(node);
1238         ir_node *mem     = get_Store_mem(node);
1239         ir_mode *mode    = get_irn_mode(val);
1240         ir_node *sval    = val;
1241         const char *offs = NULL;
1242         ir_node *new_op;
1243         ia32_am_flavour_t am_flav = ia32_B;
1244   ia32_immop_type_t immop   = ia32_ImmNone;
1245
1246         /* in case of storing a const (but not a symconst) -> make it an attribute */
1247         if (is_ia32_Cnst(val)) {
1248                 switch (get_ia32_op_type(val)) {
1249                 case ia32_Const:
1250                         immop = ia32_ImmConst;
1251                         break;
1252                 case ia32_SymConst:
1253                         immop = ia32_ImmSymConst;
1254                         break;
1255                 default:
1256                         assert(0 && "unsupported Const type");
1257                 }
1258                 sval = noreg;
1259         }
1260
1261         /* address might be a constant (symconst or absolute address) */
1262         if (is_ia32_Const(ptr)) {
1263                 offs = get_ia32_cnst(ptr);
1264                 ptr  = noreg;
1265         }
1266
1267         if (mode_is_float(mode)) {
1268                 if (USE_SSE2(env->cg))
1269                         new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T);
1270                 else
1271                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T);
1272         }
1273         else if (get_mode_size_bits(mode) == 8) {
1274                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T);
1275         }
1276         else {
1277                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T);
1278         }
1279
1280         /* stored const is an attribute (saves a register) */
1281         if (is_ia32_Cnst(val)) {
1282                 set_ia32_Immop_attr(new_op, val);
1283         }
1284
1285         /* base is an constant address */
1286         if (offs) {
1287                 add_ia32_am_offs(new_op, offs);
1288                 am_flav = ia32_O;
1289         }
1290
1291         set_ia32_am_support(new_op, ia32_am_Dest);
1292         set_ia32_op_type(new_op, ia32_AddrModeD);
1293         set_ia32_am_flavour(new_op, am_flav);
1294         set_ia32_ls_mode(new_op, get_irn_mode(val));
1295         set_ia32_immop_type(new_op, immop);
1296
1297         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1298
1299         return new_op;
1300 }
1301
1302
1303
1304 /**
1305  * Transforms a Cond -> Proj[b] -> Cmp into a CondJmp, CondJmp_i or TestJmp
1306  *
1307  * @param env   The transformation environment
1308  * @return The transformed node.
1309  */
1310 static ir_node *gen_Cond(ia32_transform_env_t *env) {
1311         dbg_info *dbg      = env->dbg;
1312         ir_graph *irg      = env->irg;
1313         ir_node  *block    = env->block;
1314         ir_node  *node     = env->irn;
1315         ir_node  *sel      = get_Cond_selector(node);
1316         ir_mode  *sel_mode = get_irn_mode(sel);
1317         ir_node  *res      = NULL;
1318         ir_node  *pred     = NULL;
1319         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
1320         ir_node  *cmp_a, *cmp_b, *cnst, *expr;
1321
1322         if (is_Proj(sel) && sel_mode == mode_b) {
1323                 ir_node  *nomem = new_NoMem();
1324
1325                 pred  = get_Proj_pred(sel);
1326
1327                 /* get both compare operators */
1328                 cmp_a = get_Cmp_left(pred);
1329                 cmp_b = get_Cmp_right(pred);
1330
1331                 /* check if we can use a CondJmp with immediate */
1332                 cnst = env->cg->opt.immops ? get_immediate_op(cmp_a, cmp_b) : NULL;
1333                 expr = get_expr_op(cmp_a, cmp_b);
1334
1335                 if (cnst && expr) {
1336                         pn_Cmp pnc = get_Proj_proj(sel);
1337
1338                         if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_is_int(get_irn_mode(expr))) {
1339                                 if (classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL) {
1340                                         /* a Cmp A =/!= 0 */
1341                                         ir_node    *op1  = expr;
1342                                         ir_node    *op2  = expr;
1343                                         ir_node    *and  = skip_Proj(expr);
1344                                         const char *cnst = NULL;
1345
1346                                         /* check, if expr is an only once used And operation */
1347                                         if (get_irn_n_edges(expr) == 1 && is_ia32_And(and)) {
1348                                                 op1 = get_irn_n(and, 2);
1349                                                 op2 = get_irn_n(and, 3);
1350
1351                                                 cnst = (is_ia32_ImmConst(and) || is_ia32_ImmSymConst(and)) ? get_ia32_cnst(and) : NULL;
1352                                         }
1353                                         res = new_rd_ia32_TestJmp(dbg, irg, block, op1, op2, mode_T);
1354                                         set_ia32_pncode(res, get_Proj_proj(sel));
1355                                         set_ia32_res_mode(res, get_irn_mode(op1));
1356
1357                                         if (cnst) {
1358                                                 copy_ia32_Immop_attr(res, and);
1359                                         }
1360
1361                                         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
1362                                         return res;
1363                                 }
1364                         }
1365
1366                         if (mode_is_float(get_irn_mode(expr))) {
1367                                 res = new_rd_ia32_fCondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem, mode_T);
1368                         }
1369                         else {
1370                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem, mode_T);
1371                         }
1372                         set_ia32_Immop_attr(res, cnst);
1373                         set_ia32_res_mode(res, get_irn_mode(expr));
1374                 }
1375                 else {
1376                         if (mode_is_float(get_irn_mode(cmp_a))) {
1377                                 res = new_rd_ia32_fCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem, mode_T);
1378                         }
1379                         else {
1380                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem, mode_T);
1381                         }
1382                         set_ia32_res_mode(res, get_irn_mode(cmp_a));
1383                 }
1384
1385                 set_ia32_pncode(res, get_Proj_proj(sel));
1386                 set_ia32_am_support(res, ia32_am_Source);
1387         }
1388         else {
1389                 res = new_rd_ia32_SwitchJmp(dbg, irg, block, sel, mode_T);
1390                 set_ia32_pncode(res, get_Cond_defaultProj(node));
1391                 set_ia32_res_mode(res, get_irn_mode(sel));
1392         }
1393
1394         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
1395         return res;
1396 }
1397
1398
1399
1400 /**
1401  * Transforms a CopyB node.
1402  *
1403  * @param env   The transformation environment
1404  * @return The transformed node.
1405  */
1406 static ir_node *gen_CopyB(ia32_transform_env_t *env) {
1407         ir_node  *res   = NULL;
1408         dbg_info *dbg   = env->dbg;
1409         ir_graph *irg   = env->irg;
1410         ir_mode  *mode  = env->mode;
1411         ir_node  *block = env->block;
1412         ir_node  *node  = env->irn;
1413         ir_node  *src   = get_CopyB_src(node);
1414         ir_node  *dst   = get_CopyB_dst(node);
1415         ir_node  *mem   = get_CopyB_mem(node);
1416         int       size  = get_type_size_bytes(get_CopyB_type(node));
1417         int       rem;
1418
1419         /* If we have to copy more than 16 bytes, we use REP MOVSx and */
1420         /* then we need the size explicitly in ECX.                    */
1421         if (size >= 16 * 4) {
1422                 rem = size & 0x3; /* size % 4 */
1423                 size >>= 2;
1424
1425                 res = new_rd_ia32_Const(dbg, irg, block, mode_Is);
1426                 set_ia32_op_type(res, ia32_Const);
1427                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1428
1429                 res = new_rd_ia32_CopyB(dbg, irg, block, dst, src, res, mem, mode);
1430                 set_ia32_Immop_tarval(res, new_tarval_from_long(rem, mode_Is));
1431         }
1432         else {
1433                 res = new_rd_ia32_CopyB_i(dbg, irg, block, dst, src, mem, mode);
1434                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1435                 set_ia32_immop_type(res, ia32_ImmConst);
1436         }
1437
1438         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env));
1439
1440         return res;
1441 }
1442
1443
1444
1445 /**
1446  * Transforms a Mux node into CMov.
1447  *
1448  * @param env   The transformation environment
1449  * @return The transformed node.
1450  */
1451 static ir_node *gen_Mux(ia32_transform_env_t *env) {
1452         ir_node *node   = env->irn;
1453         ir_node *new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, \
1454                 get_Mux_sel(node), get_Mux_false(node), get_Mux_true(node), env->mode);
1455
1456         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1457
1458         return new_op;
1459 }
1460
1461
1462 /**
1463  * Following conversion rules apply:
1464  *
1465  *  INT -> INT
1466  * ============
1467  *  1) n bit -> m bit   n > m (downscale)
1468  *     a) target is signed:    movsx
1469  *     b) target is unsigned:  and with lower bits sets
1470  *  2) n bit -> m bit   n == m   (sign change)
1471  *     always ignored
1472  *  3) n bit -> m bit   n < m (upscale)
1473  *     a) source is signed:    movsx
1474  *     b) source is unsigned:  and with lower bits sets
1475  *
1476  *  INT -> FLOAT
1477  * ==============
1478  *  SSE(1/2) convert to float or double (cvtsi2ss/sd)
1479  *
1480  *  FLOAT -> INT
1481  * ==============
1482  *  SSE(1/2) convert from float or double to 32bit int (cvtss/sd2si)
1483  *  if target mode < 32bit: additional INT -> INT conversion (see above)
1484  *
1485  *  FLOAT -> FLOAT
1486  * ================
1487  *  SSE(1/2) convert from float or double to double or float (cvtss/sd2sd/ss)
1488  *  x87 is mode_E internally, conversions happen only at load and store
1489  *  in non-strict semantic
1490  */
1491
1492 //static ir_node *gen_int_downscale_conv(ia32_transform_env_t *env, ir_node *op,
1493 //                                                                         ir_mode *src_mode, ir_mode *tgt_mode)
1494 //{
1495 //      int       n     = get_mode_size_bits(src_mode);
1496 //      int       m     = get_mode_size_bits(tgt_mode);
1497 //      dbg_info *dbg   = env->dbg;
1498 //      ir_graph *irg   = env->irg;
1499 //      ir_node  *block = env->block;
1500 //      ir_node  *noreg = ia32_new_NoReg_gp(env->cg);
1501 //      ir_node  *nomem = new_rd_NoMem(irg);
1502 //      ir_node  *new_op, *proj;
1503 //      assert(n > m && "downscale expected");
1504 //      if (mode_is_signed(src_mode) && mode_is_signed(tgt_mode)) {
1505 //              /* ASHL Sn, n - m */
1506 //              new_op = new_rd_ia32_Shl(dbg, irg, block, noreg, noreg, op, noreg, nomem, mode_T);
1507 //              proj   = new_rd_Proj(dbg, irg, block, new_op, src_mode, 0);
1508 //              set_ia32_Immop_tarval(new_op, new_tarval_from_long(n - m, mode_Is));
1509 //              set_ia32_am_support(new_op, ia32_am_Source);
1510 //              SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1511 //              /* ASHR Sn, n - m */
1512 //              new_op = new_rd_ia32_Shrs(dbg, irg, block, noreg, noreg, proj, noreg, nomem, mode_T);
1513 //              set_ia32_Immop_tarval(new_op, new_tarval_from_long(n - m, mode_Is));
1514 //      }
1515 //      else {
1516 //              new_op = new_rd_ia32_And(dbg, irg, block, noreg, noreg, op, noreg, nomem, mode_T);
1517 //              set_ia32_Immop_tarval(new_op, new_tarval_from_long((1 << m) - 1, mode_Is));
1518 //      }
1519 //      return new_op;
1520 //}
1521
1522 /**
1523  * Transforms a Conv node.
1524  *
1525  * @param env   The transformation environment
1526  * @param op    The operator
1527  * @return The created ia32 Conv node
1528  */
1529 static ir_node *gen_Conv(ia32_transform_env_t *env, ir_node *op) {
1530         dbg_info          *dbg      = env->dbg;
1531         ir_graph          *irg      = env->irg;
1532         ir_mode           *src_mode = get_irn_mode(op);
1533         ir_mode           *tgt_mode = env->mode;
1534         int                src_bits = get_mode_size_bits(src_mode);
1535         int                tgt_bits = get_mode_size_bits(tgt_mode);
1536         ir_node           *block    = env->block;
1537         ir_node           *new_op   = NULL;
1538         ir_node           *noreg    = ia32_new_NoReg_gp(env->cg);
1539         ir_node           *nomem    = new_rd_NoMem(irg);
1540         firm_dbg_module_t *mod      = env->mod;
1541         ir_node           *proj;
1542
1543         if (src_mode == tgt_mode) {
1544                 /* this can happen when changing mode_P to mode_Is */
1545                 DB((mod, LEVEL_1, "killed Conv(mode, mode) ..."));
1546                 edges_reroute(env->irn, op, irg);
1547         }
1548         else if (mode_is_float(src_mode)) {
1549                 /* we convert from float ... */
1550                 if (mode_is_float(tgt_mode)) {
1551                         /* ... to float */
1552                         if (USE_SSE2(env->cg)) {
1553                                 DB((mod, LEVEL_1, "create Conv(float, float) ..."));
1554                                 new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1555                         }
1556                         else {
1557                                 DB((mod, LEVEL_1, "killed Conv(float, float) ..."));
1558                                 edges_reroute(env->irn, op, irg);
1559                         }
1560                 }
1561                 else {
1562                         /* ... to int */
1563                         DB((mod, LEVEL_1, "create Conv(float, int) ..."));
1564                         new_op = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1565                         /* if target mode is not int: add an additional downscale convert */
1566                         if (tgt_bits < 32) {
1567                                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1568                                 set_ia32_res_mode(new_op, tgt_mode);
1569                                 set_ia32_am_support(new_op, ia32_am_Source);
1570
1571                                 proj   = new_rd_Proj(dbg, irg, block, new_op, mode_Is, 0);
1572
1573                                 if (tgt_bits == 8 || src_bits == 8) {
1574                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, proj, nomem, mode_T);
1575                                 }
1576                                 else {
1577                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, proj, nomem, mode_T);
1578                                 }
1579                         }
1580                 }
1581         }
1582         else {
1583                 /* we convert from int ... */
1584                 if (mode_is_float(tgt_mode)) {
1585                         /* ... to float */
1586                         DB((mod, LEVEL_1, "create Conv(int, float) ..."));
1587                         new_op = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1588                 }
1589                 else {
1590                         /* ... to int */
1591                         if (get_mode_size_bits(src_mode) == tgt_bits) {
1592                                 DB((mod, LEVEL_1, "omitting equal size Conv(%+F, %+F) ...", src_mode, tgt_mode));
1593                                 edges_reroute(env->irn, op, irg);
1594                         }
1595                         else {
1596                                 DB((mod, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode));
1597                                 if (tgt_bits == 8 || src_bits == 8) {
1598                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1599                                 }
1600                                 else {
1601                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1602                                 }
1603                         }
1604                 }
1605         }
1606
1607         if (new_op) {
1608                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1609                 set_ia32_res_mode(new_op, tgt_mode);
1610
1611                 set_ia32_am_support(new_op, ia32_am_Source);
1612
1613                 new_op = new_rd_Proj(dbg, irg, block, new_op, tgt_mode, 0);
1614         }
1615
1616         return new_op;
1617 }
1618
1619
1620
1621 /********************************************
1622  *  _                          _
1623  * | |                        | |
1624  * | |__   ___ _ __   ___   __| | ___  ___
1625  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
1626  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
1627  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
1628  *
1629  ********************************************/
1630
1631 static ir_node *gen_StackParam(ia32_transform_env_t *env) {
1632         ir_node *new_op = NULL;
1633         ir_node *node   = env->irn;
1634         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
1635         ir_node *mem    = new_rd_NoMem(env->irg);
1636         ir_node *ptr    = get_irn_n(node, 0);
1637         entity  *ent    = be_get_frame_entity(node);
1638         ir_mode *mode   = env->mode;
1639
1640 //      /* If the StackParam has only one user ->     */
1641 //      /* put it in the Block where the user resides */
1642 //      if (get_irn_n_edges(node) == 1) {
1643 //              env->block = get_nodes_block(get_edge_src_irn(get_irn_out_edge_first(node)));
1644 //      }
1645
1646         if (mode_is_float(mode)) {
1647                 if (USE_SSE2(env->cg))
1648                         new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1649                 else
1650                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1651         }
1652         else {
1653                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1654         }
1655
1656         set_ia32_frame_ent(new_op, ent);
1657         set_ia32_use_frame(new_op);
1658
1659         set_ia32_am_support(new_op, ia32_am_Source);
1660         set_ia32_op_type(new_op, ia32_AddrModeS);
1661         set_ia32_am_flavour(new_op, ia32_B);
1662         set_ia32_ls_mode(new_op, mode);
1663
1664         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1665
1666         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, 0);
1667 }
1668
1669 /**
1670  * Transforms a FrameAddr into an ia32 Add.
1671  */
1672 static ir_node *gen_FrameAddr(ia32_transform_env_t *env) {
1673         ir_node *new_op = NULL;
1674         ir_node *node   = env->irn;
1675         ir_node *op     = get_irn_n(node, 0);
1676         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
1677         ir_node *nomem  = new_rd_NoMem(env->irg);
1678
1679         new_op = new_rd_ia32_Add(env->dbg, env->irg, env->block, noreg, noreg, op, noreg, nomem, mode_T);
1680         set_ia32_frame_ent(new_op, be_get_frame_entity(node));
1681         set_ia32_am_support(new_op, ia32_am_Full);
1682         set_ia32_use_frame(new_op);
1683         set_ia32_immop_type(new_op, ia32_ImmConst);
1684
1685         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1686
1687         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, 0);
1688 }
1689
1690 /**
1691  * Transforms a FrameLoad into an ia32 Load.
1692  */
1693 static ir_node *gen_FrameLoad(ia32_transform_env_t *env) {
1694         ir_node *new_op = NULL;
1695         ir_node *node   = env->irn;
1696         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
1697         ir_node *mem    = get_irn_n(node, 0);
1698         ir_node *ptr    = get_irn_n(node, 1);
1699         entity  *ent    = be_get_frame_entity(node);
1700         ir_mode *mode   = get_type_mode(get_entity_type(ent));
1701
1702         if (mode_is_float(mode)) {
1703                 if (USE_SSE2(env->cg))
1704                         new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1705                 else
1706                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1707         }
1708         else {
1709                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1710         }
1711
1712         set_ia32_frame_ent(new_op, ent);
1713         set_ia32_use_frame(new_op);
1714
1715         set_ia32_am_support(new_op, ia32_am_Source);
1716         set_ia32_op_type(new_op, ia32_AddrModeS);
1717         set_ia32_am_flavour(new_op, ia32_B);
1718         set_ia32_ls_mode(new_op, mode);
1719
1720         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1721
1722         return new_op;
1723 }
1724
1725
1726 /**
1727  * Transforms a FrameStore into an ia32 Store.
1728  */
1729 static ir_node *gen_FrameStore(ia32_transform_env_t *env) {
1730         ir_node *new_op = NULL;
1731         ir_node *node   = env->irn;
1732         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
1733         ir_node *mem    = get_irn_n(node, 0);
1734         ir_node *ptr    = get_irn_n(node, 1);
1735         ir_node *val    = get_irn_n(node, 2);
1736         entity  *ent    = be_get_frame_entity(node);
1737         ir_mode *mode   = get_irn_mode(val);
1738
1739         if (mode_is_float(mode)) {
1740                 if (USE_SSE2(env->cg))
1741                         new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
1742                 else
1743                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
1744         }
1745         else if (get_mode_size_bits(mode) == 8) {
1746                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
1747         }
1748         else {
1749                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
1750         }
1751
1752         set_ia32_frame_ent(new_op, ent);
1753         set_ia32_use_frame(new_op);
1754
1755         set_ia32_am_support(new_op, ia32_am_Dest);
1756         set_ia32_op_type(new_op, ia32_AddrModeD);
1757         set_ia32_am_flavour(new_op, ia32_B);
1758         set_ia32_ls_mode(new_op, mode);
1759
1760         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env));
1761
1762         return new_op;
1763 }
1764
1765
1766
1767 /*********************************************************
1768  *                  _             _      _
1769  *                 (_)           | |    (_)
1770  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
1771  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
1772  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
1773  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
1774  *
1775  *********************************************************/
1776
1777 /**
1778  * Transforms a Sub or fSub into Neg--Add iff OUT_REG == SRC2_REG.
1779  * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
1780  */
1781 void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
1782         ia32_transform_env_t tenv;
1783         ir_node *in1, *in2, *noreg, *nomem, *res;
1784         const arch_register_t *in1_reg, *in2_reg, *out_reg, **slots;
1785
1786         /* Return if AM node or not a Sub or fSub */
1787         if (get_ia32_op_type(irn) != ia32_Normal || !(is_ia32_Sub(irn) || is_ia32_fSub(irn)))
1788                 return;
1789
1790         noreg   = ia32_new_NoReg_gp(cg);
1791         nomem   = new_rd_NoMem(cg->irg);
1792         in1     = get_irn_n(irn, 2);
1793         in2     = get_irn_n(irn, 3);
1794         in1_reg = arch_get_irn_register(cg->arch_env, in1);
1795         in2_reg = arch_get_irn_register(cg->arch_env, in2);
1796         out_reg = get_ia32_out_reg(irn, 0);
1797
1798         tenv.block    = get_nodes_block(irn);
1799         tenv.dbg      = get_irn_dbg_info(irn);
1800         tenv.irg      = cg->irg;
1801         tenv.irn      = irn;
1802         tenv.mod      = cg->mod;
1803         tenv.mode     = get_ia32_res_mode(irn);
1804         tenv.cg       = cg;
1805
1806         /* in case of sub and OUT == SRC2 we can transform the sequence into neg src2 -- add */
1807         if (REGS_ARE_EQUAL(out_reg, in2_reg)) {
1808                 /* generate the neg src2 */
1809                 res = gen_Minus(&tenv, in2);
1810                 arch_set_irn_register(cg->arch_env, res, in2_reg);
1811
1812                 /* add to schedule */
1813                 sched_add_before(irn, res);
1814
1815                 /* generate the add */
1816                 if (mode_is_float(tenv.mode)) {
1817                         res = new_rd_ia32_fAdd(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem, mode_T);
1818                         set_ia32_am_support(res, ia32_am_Source);
1819                 }
1820                 else {
1821                         res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem, mode_T);
1822                         set_ia32_am_support(res, ia32_am_Full);
1823                 }
1824
1825                 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(&tenv));
1826                 /* copy register */
1827                 slots    = get_ia32_slots(res);
1828                 slots[0] = in2_reg;
1829
1830                 /* add to schedule */
1831                 sched_add_before(irn, res);
1832
1833                 /* remove the old sub */
1834                 sched_remove(irn);
1835
1836                 /* exchange the add and the sub */
1837                 exchange(irn, res);
1838         }
1839 }
1840
1841 /**
1842  * Transforms a LEA into an Add if possible
1843  * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
1844  */
1845 void ia32_transform_lea_to_add(ir_node *irn, ia32_code_gen_t *cg) {
1846         ia32_am_flavour_t am_flav;
1847         int               imm = 0;
1848         ir_node          *res = NULL;
1849         ir_node          *nomem, *noreg, *base, *index, *op1, *op2;
1850         char             *offs;
1851         ia32_transform_env_t tenv;
1852         const arch_register_t *out_reg, *base_reg, *index_reg;
1853
1854         /* must be a LEA */
1855         if (! is_ia32_Lea(irn))
1856                 return;
1857
1858         am_flav = get_ia32_am_flavour(irn);
1859
1860         /* only some LEAs can be transformed to an Add */
1861         if (am_flav != ia32_am_B && am_flav != ia32_am_OB && am_flav != ia32_am_OI && am_flav != ia32_am_BI)
1862                 return;
1863
1864         noreg = ia32_new_NoReg_gp(cg);
1865         nomem = new_rd_NoMem(cg->irg);
1866         op1   = noreg;
1867         op2   = noreg;
1868         base  = get_irn_n(irn, 0);
1869         index = get_irn_n(irn,1);
1870
1871         offs  = get_ia32_am_offs(irn);
1872
1873         /* offset has a explicit sign -> we need to skip + */
1874         if (offs && offs[0] == '+')
1875                 offs++;
1876
1877         out_reg   = arch_get_irn_register(cg->arch_env, irn);
1878         base_reg  = arch_get_irn_register(cg->arch_env, base);
1879         index_reg = arch_get_irn_register(cg->arch_env, index);
1880
1881         tenv.block = get_nodes_block(irn);
1882         tenv.dbg   = get_irn_dbg_info(irn);
1883         tenv.irg   = cg->irg;
1884         tenv.irn   = irn;
1885         tenv.mod   = cg->mod;
1886         tenv.mode  = get_irn_mode(irn);
1887         tenv.cg    = cg;
1888
1889         switch(get_ia32_am_flavour(irn)) {
1890                 case ia32_am_B:
1891                         /* out register must be same as base register */
1892                         if (! REGS_ARE_EQUAL(out_reg, base_reg))
1893                                 return;
1894
1895                         op1 = base;
1896                         break;
1897                 case ia32_am_OB:
1898                         /* out register must be same as base register */
1899                         if (! REGS_ARE_EQUAL(out_reg, base_reg))
1900                                 return;
1901
1902                         op1 = base;
1903                         imm = 1;
1904                         break;
1905                 case ia32_am_OI:
1906                         /* out register must be same as index register */
1907                         if (! REGS_ARE_EQUAL(out_reg, index_reg))
1908                                 return;
1909
1910                         op1 = index;
1911                         imm = 1;
1912                         break;
1913                 case ia32_am_BI:
1914                         /* out register must be same as one in register */
1915                         if (REGS_ARE_EQUAL(out_reg, base_reg)) {
1916                                 op1 = base;
1917                                 op2 = index;
1918                         }
1919                         else if (REGS_ARE_EQUAL(out_reg, index_reg)) {
1920                                 op1 = index;
1921                                 op2 = base;
1922                         }
1923                         else {
1924                                 /* in registers a different from out -> no Add possible */
1925                                 return;
1926                         }
1927                 default:
1928                         break;
1929         }
1930
1931         res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, op1, op2, nomem, mode_T);
1932         arch_set_irn_register(cg->arch_env, res, out_reg);
1933         set_ia32_op_type(res, ia32_Normal);
1934
1935         if (imm) {
1936                 set_ia32_cnst(res, offs);
1937                 set_ia32_immop_type(res, ia32_ImmConst);
1938         }
1939
1940         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(&tenv));
1941
1942         /* add Add to schedule */
1943         sched_add_before(irn, res);
1944
1945         res = new_rd_Proj(tenv.dbg, tenv.irg, tenv.block, res, tenv.mode, 0);
1946
1947         /* add result Proj to schedule */
1948         sched_add_before(irn, res);
1949
1950         /* remove the old LEA */
1951         sched_remove(irn);
1952
1953         /* exchange the Add and the LEA */
1954         exchange(irn, res);
1955 }
1956
1957 /**
1958  * Transforms the given firm node (and maybe some other related nodes)
1959  * into one or more assembler nodes.
1960  *
1961  * @param node    the firm node
1962  * @param env     the debug module
1963  */
1964 void ia32_transform_node(ir_node *node, void *env) {
1965         ia32_code_gen_t *cgenv = (ia32_code_gen_t *)env;
1966         opcode  code;
1967         ir_node *asm_node      = NULL;
1968         ia32_transform_env_t  tenv;
1969
1970         if (is_Block(node))
1971                 return;
1972
1973         tenv.block    = get_nodes_block(node);
1974         tenv.dbg      = get_irn_dbg_info(node);
1975         tenv.irg      = current_ir_graph;
1976         tenv.irn      = node;
1977         tenv.mod      = cgenv->mod;
1978         tenv.mode     = get_irn_mode(node);
1979         tenv.cg       = cgenv;
1980
1981 #define UNOP(a)  case iro_##a: asm_node = gen_##a(&tenv, get_##a##_op(node)); break
1982 #define BINOP(a) case iro_##a: asm_node = gen_##a(&tenv, get_##a##_left(node), get_##a##_right(node)); break
1983 #define GEN(a)   case iro_##a: asm_node = gen_##a(&tenv); break
1984 #define IGN(a)   case iro_##a: break
1985 #define BAD(a)   case iro_##a: goto bad
1986 #define OTHER_BIN(a)                                                       \
1987         if (get_irn_op(node) == get_op_##a()) {                                \
1988                 asm_node = gen_##a(&tenv, get_irn_n(node, 0), get_irn_n(node, 1)); \
1989                 break;                                                             \
1990         }
1991 #define BE_GEN(a)                  \
1992         if (be_is_##a(node)) {         \
1993                 asm_node = gen_##a(&tenv); \
1994                 break;                     \
1995         }
1996
1997         DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
1998
1999         code = get_irn_opcode(node);
2000         switch (code) {
2001                 BINOP(Add);
2002                 BINOP(Sub);
2003                 BINOP(Mul);
2004                 BINOP(And);
2005                 BINOP(Or);
2006                 BINOP(Eor);
2007
2008                 BINOP(Shl);
2009                 BINOP(Shr);
2010                 BINOP(Shrs);
2011                 BINOP(Rot);
2012
2013                 BINOP(Quot);
2014
2015                 BINOP(Div);
2016                 BINOP(Mod);
2017                 BINOP(DivMod);
2018
2019                 UNOP(Minus);
2020                 UNOP(Conv);
2021                 UNOP(Abs);
2022                 UNOP(Not);
2023
2024                 GEN(Load);
2025                 GEN(Store);
2026                 GEN(Cond);
2027
2028                 GEN(CopyB);
2029                 GEN(Mux);
2030
2031                 IGN(Call);
2032                 IGN(Alloc);
2033
2034                 IGN(Proj);
2035                 IGN(Block);
2036                 IGN(Start);
2037                 IGN(End);
2038                 IGN(NoMem);
2039                 IGN(Phi);
2040                 IGN(IJmp);
2041                 IGN(Break);
2042                 IGN(Cmp);
2043                 IGN(Unknown);
2044
2045                 /* constant transformation happens earlier */
2046                 IGN(Const);
2047                 IGN(SymConst);
2048                 IGN(Sync);
2049
2050                 BAD(Raise);
2051                 BAD(Sel);
2052                 BAD(InstOf);
2053                 BAD(Cast);
2054                 BAD(Free);
2055                 BAD(Tuple);
2056                 BAD(Id);
2057                 BAD(Bad);
2058                 BAD(Confirm);
2059                 BAD(Filter);
2060                 BAD(CallBegin);
2061                 BAD(EndReg);
2062                 BAD(EndExcept);
2063
2064                 default:
2065                         OTHER_BIN(Max);
2066                         OTHER_BIN(Min);
2067                         OTHER_BIN(Mulh);
2068
2069                         BE_GEN(FrameAddr);
2070                         BE_GEN(FrameLoad);
2071                         BE_GEN(FrameStore);
2072                         BE_GEN(StackParam);
2073                         break;
2074 bad:
2075                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
2076                 assert(0);
2077         }
2078
2079         /* exchange nodes if a new one was generated */
2080         if (asm_node) {
2081                 exchange(node, asm_node);
2082                 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
2083         }
2084         else {
2085                 DB((tenv.mod, LEVEL_1, "ignored\n"));
2086         }
2087
2088 #undef UNOP
2089 #undef BINOP
2090 #undef GEN
2091 #undef IGN
2092 #undef BAD
2093 #undef OTHER_BIN
2094 #undef BE_GEN
2095 }