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