BugFix: test can only be created for a&b == 0 or a&b != 0
[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_mode *mode  = get_Load_mode(node);
1183         ir_node *new_op;
1184
1185         if (mode_is_float(mode)) {
1186                 new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, get_Load_ptr(node), noreg, get_Load_mem(node), env->mode);
1187         }
1188         else {
1189                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, get_Load_ptr(node), noreg, get_Load_mem(node), env->mode);
1190         }
1191
1192         set_ia32_am_support(new_op, ia32_am_Source);
1193         set_ia32_op_type(new_op, ia32_AddrModeS);
1194         set_ia32_am_flavour(new_op, ia32_B);
1195         set_ia32_ls_mode(new_op, mode);
1196
1197         SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1198
1199         return new_op;
1200 }
1201
1202
1203
1204 /**
1205  * Transforms a Store.
1206  *
1207  * @param mod     the debug module
1208  * @param block   the block the new node should belong to
1209  * @param node    the ir Store node
1210  * @param mode    node mode
1211  * @return the created ia32 Store node
1212  */
1213 static ir_node *gen_Store(ia32_transform_env_t *env) {
1214         ir_node *node  = env->irn;
1215         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1216         ir_node *val   = get_Store_value(node);
1217         ir_node *ptr   = get_Store_ptr(node);
1218         ir_node *mem   = get_Store_mem(node);
1219         ir_mode *mode  = get_irn_mode(val);
1220         ir_node *sval  = val;
1221         ir_node *new_op;
1222
1223         /* in case of storing a const (but not a symconst) -> make it an attribute */
1224         if (is_ia32_Const(val)) {
1225                 sval = noreg;
1226         }
1227
1228         if (mode_is_float(mode)) {
1229                 new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T);
1230         }
1231         else if (get_mode_size_bits(mode) == 8) {
1232                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T);
1233         }
1234         else {
1235                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T);
1236         }
1237
1238         /* stored const is an attribute (saves a register) */
1239         if (is_ia32_Const(val)) {
1240                 set_ia32_Immop_attr(new_op, val);
1241         }
1242
1243         set_ia32_am_support(new_op, ia32_am_Dest);
1244         set_ia32_op_type(new_op, ia32_AddrModeD);
1245         set_ia32_am_flavour(new_op, ia32_B);
1246         set_ia32_ls_mode(new_op, get_irn_mode(val));
1247
1248         SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1249
1250         return new_op;
1251 }
1252
1253
1254
1255 /**
1256  * Transforms a Cond -> Proj[b] -> Cmp into a CondJmp, CondJmp_i or TestJmp
1257  *
1258  * @param env   The transformation environment
1259  * @return The transformed node.
1260  */
1261 static ir_node *gen_Cond(ia32_transform_env_t *env) {
1262         dbg_info *dbg      = env->dbg;
1263         ir_graph *irg      = env->irg;
1264         ir_node  *block    = env->block;
1265         ir_node  *node     = env->irn;
1266         ir_node  *sel      = get_Cond_selector(node);
1267         ir_mode  *sel_mode = get_irn_mode(sel);
1268         ir_node  *res      = NULL;
1269         ir_node  *pred     = NULL;
1270         ir_node  *noreg    = ia32_new_NoReg_gp(env->cg);
1271         ir_node  *cmp_a, *cmp_b, *cnst, *expr;
1272
1273         if (is_Proj(sel) && sel_mode == mode_b) {
1274                 ir_node  *nomem = new_NoMem();
1275
1276                 pred  = get_Proj_pred(sel);
1277
1278                 /* get both compare operators */
1279                 cmp_a = get_Cmp_left(pred);
1280                 cmp_b = get_Cmp_right(pred);
1281
1282                 /* check if we can use a CondJmp with immediate */
1283                 cnst = env->cg->opt.immops ? get_immediate_op(cmp_a, cmp_b) : NULL;
1284                 expr = get_expr_op(cmp_a, cmp_b);
1285
1286                 if (cnst && expr) {
1287                         pn_Cmp pnc = get_Proj_proj(sel);
1288
1289                         if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_is_int(get_irn_mode(expr))) {
1290                                 if (classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL) {
1291                                         /* a Cmp A =/!= 0 */
1292                                         ir_node    *op1  = expr;
1293                                         ir_node    *op2  = expr;
1294                                         ir_node    *and  = skip_Proj(expr);
1295                                         const char *cnst = NULL;
1296
1297                                         /* check, if expr is an only once used And operation */
1298                                         if (get_irn_n_edges(expr) == 1 && is_ia32_And(and)) {
1299                                                 op1 = get_irn_n(and, 2);
1300                                                 op2 = get_irn_n(and, 3);
1301
1302                                                 cnst = (is_ia32_ImmConst(and) || is_ia32_ImmSymConst(and)) ? get_ia32_cnst(and) : NULL;
1303                                         }
1304                                         res = new_rd_ia32_TestJmp(dbg, irg, block, op1, op2, mode_T);
1305                                         set_ia32_pncode(res, get_Proj_proj(sel));
1306
1307                                         if (cnst) {
1308                                                 copy_ia32_Immop_attr(res, and);
1309                                         }
1310
1311                                         SET_IA32_ORIG_NODE(res, get_old_node_name(env));
1312                                         return res;
1313                                 }
1314                         }
1315
1316                         if (mode_is_float(get_irn_mode(expr))) {
1317                                 res = new_rd_ia32_fCondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem, mode_T);
1318                         }
1319                         else {
1320                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem, mode_T);
1321                         }
1322                         set_ia32_Immop_attr(res, cnst);
1323                 }
1324                 else {
1325                         if (mode_is_float(get_irn_mode(cmp_a))) {
1326                                 res = new_rd_ia32_fCondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem, mode_T);
1327                         }
1328                         else {
1329                                 res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem, mode_T);
1330                         }
1331                 }
1332
1333                 set_ia32_pncode(res, get_Proj_proj(sel));
1334                 set_ia32_am_support(res, ia32_am_Source);
1335         }
1336         else {
1337                 res = new_rd_ia32_SwitchJmp(dbg, irg, block, sel, mode_T);
1338                 set_ia32_pncode(res, get_Cond_defaultProj(node));
1339         }
1340
1341         SET_IA32_ORIG_NODE(res, get_old_node_name(env));
1342         return res;
1343 }
1344
1345
1346
1347 /**
1348  * Transforms a CopyB node.
1349  *
1350  * @param env   The transformation environment
1351  * @return The transformed node.
1352  */
1353 static ir_node *gen_CopyB(ia32_transform_env_t *env) {
1354         ir_node  *res   = NULL;
1355         dbg_info *dbg   = env->dbg;
1356         ir_graph *irg   = env->irg;
1357         ir_mode  *mode  = env->mode;
1358         ir_node  *block = env->block;
1359         ir_node  *node  = env->irn;
1360         ir_node  *src   = get_CopyB_src(node);
1361         ir_node  *dst   = get_CopyB_dst(node);
1362         ir_node  *mem   = get_CopyB_mem(node);
1363         int       size  = get_type_size_bytes(get_CopyB_type(node));
1364         int       rem;
1365
1366         /* If we have to copy more than 16 bytes, we use REP MOVSx and */
1367         /* then we need the size explicitly in ECX.                    */
1368         if (size >= 16 * 4) {
1369                 rem = size & 0x3; /* size % 4 */
1370                 size >>= 2;
1371
1372                 res = new_rd_ia32_Const(dbg, irg, block, mode_Is);
1373                 set_ia32_op_type(res, ia32_Const);
1374                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1375
1376                 res = new_rd_ia32_CopyB(dbg, irg, block, dst, src, res, mem, mode);
1377                 set_ia32_Immop_tarval(res, new_tarval_from_long(rem, mode_Is));
1378         }
1379         else {
1380                 res = new_rd_ia32_CopyB_i(dbg, irg, block, dst, src, mem, mode);
1381                 set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
1382                 set_ia32_immop_type(res, ia32_ImmConst);
1383         }
1384
1385         SET_IA32_ORIG_NODE(res, get_old_node_name(env));
1386
1387         return res;
1388 }
1389
1390
1391
1392 /**
1393  * Transforms a Mux node into CMov.
1394  *
1395  * @param env   The transformation environment
1396  * @return The transformed node.
1397  */
1398 static ir_node *gen_Mux(ia32_transform_env_t *env) {
1399         ir_node *node   = env->irn;
1400         ir_node *new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, \
1401                 get_Mux_sel(node), get_Mux_false(node), get_Mux_true(node), env->mode);
1402
1403         SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1404
1405         return new_op;
1406 }
1407
1408
1409 /**
1410  * Following conversion rules apply:
1411  *
1412  *  INT -> INT
1413  * ============
1414  *  1) n bit -> m bit   n > m (downscale)
1415  *     a) target is signed:    movsx
1416  *     b) target is unsigned:  and with lower bits sets
1417  *  2) n bit -> m bit   n == m   (sign change)
1418  *     always ignored
1419  *  3) n bit -> m bit   n < m (upscale)
1420  *     a) source is signed:    movsx
1421  *     b) source is unsigned:  and with lower bits sets
1422  *
1423  *  INT -> FLOAT
1424  * ==============
1425  *  SSE(1/2) convert to float or double (cvtsi2ss/sd)
1426  *
1427  *  FLOAT -> INT
1428  * ==============
1429  *  SSE(1/2) convert from float or double to 32bit int (cvtss/sd2si)
1430  *  if target mode < 32bit: additional INT -> INT conversion (see above)
1431  *
1432  *  FLOAT -> FLOAT
1433  * ================
1434  *  SSE(1/2) convert from float or double to double or float (cvtss/sd2sd/ss)
1435  */
1436
1437 //static ir_node *gen_int_downscale_conv(ia32_transform_env_t *env, ir_node *op,
1438 //                                                                         ir_mode *src_mode, ir_mode *tgt_mode)
1439 //{
1440 //      int       n     = get_mode_size_bits(src_mode);
1441 //      int       m     = get_mode_size_bits(tgt_mode);
1442 //      dbg_info *dbg   = env->dbg;
1443 //      ir_graph *irg   = env->irg;
1444 //      ir_node  *block = env->block;
1445 //      ir_node  *noreg = ia32_new_NoReg_gp(env->cg);
1446 //      ir_node  *nomem = new_rd_NoMem(irg);
1447 //      ir_node  *new_op, *proj;
1448 //      assert(n > m && "downscale expected");
1449 //      if (mode_is_signed(src_mode) && mode_is_signed(tgt_mode)) {
1450 //              /* ASHL Sn, n - m */
1451 //              new_op = new_rd_ia32_Shl(dbg, irg, block, noreg, noreg, op, noreg, nomem, mode_T);
1452 //              proj   = new_rd_Proj(dbg, irg, block, new_op, src_mode, 0);
1453 //              set_ia32_Immop_tarval(new_op, new_tarval_from_long(n - m, mode_Is));
1454 //              set_ia32_am_support(new_op, ia32_am_Source);
1455 //              SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1456 //              /* ASHR Sn, n - m */
1457 //              new_op = new_rd_ia32_Shrs(dbg, irg, block, noreg, noreg, proj, noreg, nomem, mode_T);
1458 //              set_ia32_Immop_tarval(new_op, new_tarval_from_long(n - m, mode_Is));
1459 //      }
1460 //      else {
1461 //              new_op = new_rd_ia32_And(dbg, irg, block, noreg, noreg, op, noreg, nomem, mode_T);
1462 //              set_ia32_Immop_tarval(new_op, new_tarval_from_long((1 << m) - 1, mode_Is));
1463 //      }
1464 //      return new_op;
1465 //}
1466
1467 /**
1468  * Transforms a Conv node.
1469  *
1470  * @param env   The transformation environment
1471  * @param op    The operator
1472  * @return The created ia32 Conv node
1473  */
1474 static ir_node *gen_Conv(ia32_transform_env_t *env, ir_node *op) {
1475         dbg_info          *dbg      = env->dbg;
1476         ir_graph          *irg      = env->irg;
1477         ir_mode           *src_mode = get_irn_mode(op);
1478         ir_mode           *tgt_mode = env->mode;
1479         int                src_bits = get_mode_size_bits(src_mode);
1480         int                tgt_bits = get_mode_size_bits(tgt_mode);
1481         ir_node           *block    = env->block;
1482         ir_node           *new_op   = NULL;
1483         ir_node           *noreg    = ia32_new_NoReg_gp(env->cg);
1484         ir_node           *nomem    = new_rd_NoMem(irg);
1485         firm_dbg_module_t *mod      = env->mod;
1486         ir_node           *proj;
1487
1488         if (src_mode == tgt_mode) {
1489                 /* this can happen when changing mode_P to mode_Is */
1490                 DB((mod, LEVEL_1, "killed Conv(mode, mode) ..."));
1491                 edges_reroute(env->irn, op, irg);
1492         }
1493         else if (mode_is_float(src_mode)) {
1494                 /* we convert from float ... */
1495                 if (mode_is_float(tgt_mode)) {
1496                         /* ... to float */
1497                         DB((mod, LEVEL_1, "create Conv(float, float) ..."));
1498                         new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1499                 }
1500                 else {
1501                         /* ... to int */
1502                         DB((mod, LEVEL_1, "create Conv(float, int) ..."));
1503                         new_op = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1504                         /* if target mode is not int: add an additional downscale convert */
1505                         if (tgt_bits < 32) {
1506                                 SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1507                                 set_ia32_res_mode(new_op, tgt_mode);
1508                                 set_ia32_am_support(new_op, ia32_am_Source);
1509
1510                                 proj   = new_rd_Proj(dbg, irg, block, new_op, mode_Is, 0);
1511
1512                                 if (tgt_bits == 8 || src_bits == 8) {
1513                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, proj, nomem, mode_T);
1514                                 }
1515                                 else {
1516                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, proj, nomem, mode_T);
1517                                 }
1518                         }
1519                 }
1520         }
1521         else {
1522                 /* we convert from int ... */
1523                 if (mode_is_float(tgt_mode)) {
1524                         /* ... to float */
1525                         DB((mod, LEVEL_1, "create Conv(int, float) ..."));
1526                         new_op = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1527                 }
1528                 else {
1529                         /* ... to int */
1530                         if (get_mode_size_bits(src_mode) == tgt_bits) {
1531                                 DB((mod, LEVEL_1, "omitting equal size Conv(%+F, %+F) ...", src_mode, tgt_mode));
1532                                 edges_reroute(env->irn, op, irg);
1533                         }
1534                         else {
1535                                 DB((mod, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode));
1536                                 if (tgt_bits == 8 || src_bits == 8) {
1537                                         new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1538                                 }
1539                                 else {
1540                                         new_op = new_rd_ia32_Conv_I2I(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
1541                                 }
1542                         }
1543                 }
1544         }
1545
1546         if (new_op) {
1547                 SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1548                 set_ia32_res_mode(new_op, tgt_mode);
1549
1550                 set_ia32_am_support(new_op, ia32_am_Source);
1551
1552                 new_op = new_rd_Proj(dbg, irg, block, new_op, tgt_mode, 0);
1553         }
1554
1555         return new_op;
1556 }
1557
1558
1559
1560 /********************************************
1561  *  _                          _
1562  * | |                        | |
1563  * | |__   ___ _ __   ___   __| | ___  ___
1564  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
1565  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
1566  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
1567  *
1568  ********************************************/
1569
1570 static ir_node *gen_StackParam(ia32_transform_env_t *env) {
1571         ir_node *new_op = NULL;
1572         ir_node *node   = env->irn;
1573         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
1574         ir_node *mem    = new_rd_NoMem(env->irg);
1575         ir_node *ptr    = get_irn_n(node, 0);
1576         entity  *ent    = be_get_frame_entity(node);
1577         ir_mode *mode   = env->mode;
1578
1579         if (mode_is_float(mode)) {
1580                 new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1581         }
1582         else {
1583                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1584         }
1585
1586         set_ia32_frame_ent(new_op, ent);
1587         set_ia32_use_frame(new_op);
1588
1589         set_ia32_am_support(new_op, ia32_am_Source);
1590         set_ia32_op_type(new_op, ia32_AddrModeS);
1591         set_ia32_am_flavour(new_op, ia32_B);
1592         set_ia32_ls_mode(new_op, mode);
1593
1594         SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1595
1596         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, 0);
1597 }
1598
1599 /**
1600  * Transforms a FrameAddr into an ia32 Add.
1601  */
1602 static ir_node *gen_FrameAddr(ia32_transform_env_t *env) {
1603         ir_node *new_op = NULL;
1604         ir_node *node   = env->irn;
1605         ir_node *op     = get_irn_n(node, 0);
1606         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
1607         ir_node *nomem  = new_rd_NoMem(env->irg);
1608
1609         new_op = new_rd_ia32_Add(env->dbg, env->irg, env->block, noreg, noreg, op, noreg, nomem, mode_T);
1610         set_ia32_frame_ent(new_op, be_get_frame_entity(node));
1611         set_ia32_am_support(new_op, ia32_am_Full);
1612         set_ia32_use_frame(new_op);
1613         set_ia32_immop_type(new_op, ia32_ImmConst);
1614
1615         SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1616
1617         return new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, 0);
1618 }
1619
1620 /**
1621  * Transforms a FrameLoad into an ia32 Load.
1622  */
1623 static ir_node *gen_FrameLoad(ia32_transform_env_t *env) {
1624         ir_node *new_op = NULL;
1625         ir_node *node   = env->irn;
1626         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
1627         ir_node *mem    = get_irn_n(node, 0);
1628         ir_node *ptr    = get_irn_n(node, 1);
1629         entity  *ent    = be_get_frame_entity(node);
1630         ir_mode *mode   = get_type_mode(get_entity_type(ent));
1631
1632         if (mode_is_float(mode)) {
1633                 new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1634         }
1635         else {
1636                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
1637         }
1638
1639         set_ia32_frame_ent(new_op, ent);
1640         set_ia32_use_frame(new_op);
1641
1642         set_ia32_am_support(new_op, ia32_am_Source);
1643         set_ia32_op_type(new_op, ia32_AddrModeS);
1644         set_ia32_am_flavour(new_op, ia32_B);
1645         set_ia32_ls_mode(new_op, mode);
1646
1647         SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1648
1649         return new_op;
1650 }
1651
1652
1653 /**
1654  * Transforms a FrameStore into an ia32 Store.
1655  */
1656 static ir_node *gen_FrameStore(ia32_transform_env_t *env) {
1657         ir_node *new_op = NULL;
1658         ir_node *node   = env->irn;
1659         ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
1660         ir_node *mem    = get_irn_n(node, 0);
1661         ir_node *ptr    = get_irn_n(node, 1);
1662         ir_node *val    = get_irn_n(node, 2);
1663         entity  *ent    = be_get_frame_entity(node);
1664         ir_mode *mode   = get_irn_mode(val);
1665
1666         if (mode_is_float(mode)) {
1667                 new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
1668         }
1669         else if (get_mode_size_bits(mode) == 8) {
1670                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
1671         }
1672         else {
1673                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
1674         }
1675
1676         set_ia32_frame_ent(new_op, ent);
1677         set_ia32_use_frame(new_op);
1678
1679         set_ia32_am_support(new_op, ia32_am_Dest);
1680         set_ia32_op_type(new_op, ia32_AddrModeD);
1681         set_ia32_am_flavour(new_op, ia32_B);
1682         set_ia32_ls_mode(new_op, mode);
1683
1684         SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
1685
1686         return new_op;
1687 }
1688
1689
1690
1691 /*********************************************************
1692  *                  _             _      _
1693  *                 (_)           | |    (_)
1694  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
1695  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
1696  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
1697  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
1698  *
1699  *********************************************************/
1700
1701 /**
1702  * Transforms a Sub or fSub into Neg--Add iff OUT_REG == SRC2_REG.
1703  * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
1704  */
1705 void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
1706         ia32_transform_env_t tenv;
1707         ir_node *in1, *in2, *noreg, *nomem, *res;
1708         const arch_register_t *in1_reg, *in2_reg, *out_reg, **slots;
1709
1710         /* Return if AM node or not a Sub or fSub */
1711         if (get_ia32_op_type(irn) != ia32_Normal || !(is_ia32_Sub(irn) || is_ia32_fSub(irn)))
1712                 return;
1713
1714         noreg   = ia32_new_NoReg_gp(cg);
1715         nomem   = new_rd_NoMem(cg->irg);
1716         in1     = get_irn_n(irn, 2);
1717         in2     = get_irn_n(irn, 3);
1718         in1_reg = arch_get_irn_register(cg->arch_env, in1);
1719         in2_reg = arch_get_irn_register(cg->arch_env, in2);
1720         out_reg = get_ia32_out_reg(irn, 0);
1721
1722         tenv.block    = get_nodes_block(irn);
1723         tenv.dbg      = get_irn_dbg_info(irn);
1724         tenv.irg      = cg->irg;
1725         tenv.irn      = irn;
1726         tenv.mod      = cg->mod;
1727         tenv.mode     = get_ia32_res_mode(irn);
1728         tenv.cg       = cg;
1729
1730         /* in case of sub and OUT == SRC2 we can transform the sequence into neg src2 -- add */
1731         if (REGS_ARE_EQUAL(out_reg, in2_reg)) {
1732                 /* generate the neg src2 */
1733                 res = gen_Minus(&tenv, in2);
1734                 arch_set_irn_register(cg->arch_env, res, in2_reg);
1735
1736                 /* add to schedule */
1737                 sched_add_before(irn, res);
1738
1739                 /* generate the add */
1740                 if (mode_is_float(tenv.mode)) {
1741                         res = new_rd_ia32_fAdd(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem, mode_T);
1742                         set_ia32_am_support(res, ia32_am_Source);
1743                 }
1744                 else {
1745                         res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, res, in1, nomem, mode_T);
1746                         set_ia32_am_support(res, ia32_am_Full);
1747                 }
1748
1749                 SET_IA32_ORIG_NODE(res, get_old_node_name(&tenv));
1750                 /* copy register */
1751                 slots    = get_ia32_slots(res);
1752                 slots[0] = in2_reg;
1753
1754                 /* add to schedule */
1755                 sched_add_before(irn, res);
1756
1757                 /* remove the old sub */
1758                 sched_remove(irn);
1759
1760                 /* exchange the add and the sub */
1761                 exchange(irn, res);
1762         }
1763 }
1764
1765 /**
1766  * Transforms a LEA into an Add if possible
1767  * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
1768  */
1769 void ia32_transform_lea_to_add(ir_node *irn, ia32_code_gen_t *cg) {
1770         ia32_am_flavour_t am_flav;
1771         int               imm = 0;
1772         ir_node          *res = NULL;
1773         ir_node          *nomem, *noreg, *base, *index, *op1, *op2;
1774         char             *offs;
1775         ia32_transform_env_t tenv;
1776         const arch_register_t *out_reg, *base_reg, *index_reg;
1777
1778         /* must be a LEA */
1779         if (! is_ia32_Lea(irn))
1780                 return;
1781
1782         am_flav = get_ia32_am_flavour(irn);
1783
1784         /* only some LEAs can be transformed to an Add */
1785         if (am_flav != ia32_am_B && am_flav != ia32_am_OB && am_flav != ia32_am_OI && am_flav != ia32_am_BI)
1786                 return;
1787
1788         noreg = ia32_new_NoReg_gp(cg);
1789         nomem = new_rd_NoMem(cg->irg);
1790         op1   = noreg;
1791         op2   = noreg;
1792         base  = get_irn_n(irn, 0);
1793         index = get_irn_n(irn,1);
1794
1795         offs  = get_ia32_am_offs(irn);
1796
1797         /* offset has a explicit sign -> we need to skip + */
1798         if (offs && offs[0] == '+')
1799                 offs++;
1800
1801         out_reg   = arch_get_irn_register(cg->arch_env, irn);
1802         base_reg  = arch_get_irn_register(cg->arch_env, base);
1803         index_reg = arch_get_irn_register(cg->arch_env, index);
1804
1805         tenv.block = get_nodes_block(irn);
1806         tenv.dbg   = get_irn_dbg_info(irn);
1807         tenv.irg   = cg->irg;
1808         tenv.irn   = irn;
1809         tenv.mod   = cg->mod;
1810         tenv.mode  = get_irn_mode(irn);
1811         tenv.cg    = cg;
1812
1813         switch(get_ia32_am_flavour(irn)) {
1814                 case ia32_am_B:
1815                         /* out register must be same as base register */
1816                         if (! REGS_ARE_EQUAL(out_reg, base_reg))
1817                                 return;
1818
1819                         op1 = base;
1820                         break;
1821                 case ia32_am_OB:
1822                         /* out register must be same as base register */
1823                         if (! REGS_ARE_EQUAL(out_reg, base_reg))
1824                                 return;
1825
1826                         op1 = base;
1827                         imm = 1;
1828                         break;
1829                 case ia32_am_OI:
1830                         /* out register must be same as index register */
1831                         if (! REGS_ARE_EQUAL(out_reg, index_reg))
1832                                 return;
1833
1834                         op1 = index;
1835                         imm = 1;
1836                         break;
1837                 case ia32_am_BI:
1838                         /* out register must be same as one in register */
1839                         if (REGS_ARE_EQUAL(out_reg, base_reg)) {
1840                                 op1 = base;
1841                                 op2 = index;
1842                         }
1843                         else if (REGS_ARE_EQUAL(out_reg, index_reg)) {
1844                                 op1 = index;
1845                                 op2 = base;
1846                         }
1847                         else {
1848                                 /* in registers a different from out -> no Add possible */
1849                                 return;
1850                         }
1851                 default:
1852                         break;
1853         }
1854
1855         res = new_rd_ia32_Add(tenv.dbg, tenv.irg, tenv.block, noreg, noreg, op1, op2, nomem, mode_T);
1856         arch_set_irn_register(cg->arch_env, res, out_reg);
1857         set_ia32_op_type(res, ia32_Normal);
1858
1859         if (imm) {
1860                 set_ia32_cnst(res, offs);
1861                 set_ia32_immop_type(res, ia32_ImmConst);
1862         }
1863
1864         SET_IA32_ORIG_NODE(res, get_old_node_name(&tenv));
1865
1866         /* add Add to schedule */
1867         sched_add_before(irn, res);
1868
1869         res = new_rd_Proj(tenv.dbg, tenv.irg, tenv.block, res, tenv.mode, 0);
1870
1871         /* add result Proj to schedule */
1872         sched_add_before(irn, res);
1873
1874         /* remove the old LEA */
1875         sched_remove(irn);
1876
1877         /* exchange the Add and the LEA */
1878         exchange(irn, res);
1879 }
1880
1881 /**
1882  * Transforms the given firm node (and maybe some other related nodes)
1883  * into one or more assembler nodes.
1884  *
1885  * @param node    the firm node
1886  * @param env     the debug module
1887  */
1888 void ia32_transform_node(ir_node *node, void *env) {
1889         ia32_code_gen_t *cgenv = (ia32_code_gen_t *)env;
1890         opcode  code;
1891         ir_node *asm_node      = NULL;
1892         ia32_transform_env_t  tenv;
1893
1894         if (is_Block(node))
1895                 return;
1896
1897         tenv.block    = get_nodes_block(node);
1898         tenv.dbg      = get_irn_dbg_info(node);
1899         tenv.irg      = current_ir_graph;
1900         tenv.irn      = node;
1901         tenv.mod      = cgenv->mod;
1902         tenv.mode     = get_irn_mode(node);
1903         tenv.cg       = cgenv;
1904
1905 #define UNOP(a)  case iro_##a: asm_node = gen_##a(&tenv, get_##a##_op(node)); break
1906 #define BINOP(a) case iro_##a: asm_node = gen_##a(&tenv, get_##a##_left(node), get_##a##_right(node)); break
1907 #define GEN(a)   case iro_##a: asm_node = gen_##a(&tenv); break
1908 #define IGN(a)   case iro_##a: break
1909 #define BAD(a)   case iro_##a: goto bad
1910 #define OTHER_BIN(a)                                                       \
1911         if (get_irn_op(node) == get_op_##a()) {                                \
1912                 asm_node = gen_##a(&tenv, get_irn_n(node, 0), get_irn_n(node, 1)); \
1913                 break;                                                             \
1914         }
1915 #define BE_GEN(a)                  \
1916         if (be_is_##a(node)) {         \
1917                 asm_node = gen_##a(&tenv); \
1918                 break;                     \
1919         }
1920
1921         DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
1922
1923         code = get_irn_opcode(node);
1924         switch (code) {
1925                 BINOP(Add);
1926                 BINOP(Sub);
1927                 BINOP(Mul);
1928                 BINOP(And);
1929                 BINOP(Or);
1930                 BINOP(Eor);
1931
1932                 BINOP(Shl);
1933                 BINOP(Shr);
1934                 BINOP(Shrs);
1935                 BINOP(Rot);
1936
1937                 BINOP(Quot);
1938
1939                 BINOP(Div);
1940                 BINOP(Mod);
1941                 BINOP(DivMod);
1942
1943                 UNOP(Minus);
1944                 UNOP(Conv);
1945                 UNOP(Abs);
1946                 UNOP(Not);
1947
1948                 GEN(Load);
1949                 GEN(Store);
1950                 GEN(Cond);
1951
1952                 GEN(CopyB);
1953                 GEN(Mux);
1954
1955                 IGN(Call);
1956                 IGN(Alloc);
1957
1958                 IGN(Proj);
1959                 IGN(Block);
1960                 IGN(Start);
1961                 IGN(End);
1962                 IGN(NoMem);
1963                 IGN(Phi);
1964                 IGN(IJmp);
1965                 IGN(Break);
1966                 IGN(Cmp);
1967                 IGN(Unknown);
1968
1969                 /* constant transformation happens earlier */
1970                 IGN(Const);
1971                 IGN(SymConst);
1972                 IGN(Sync);
1973
1974                 BAD(Raise);
1975                 BAD(Sel);
1976                 BAD(InstOf);
1977                 BAD(Cast);
1978                 BAD(Free);
1979                 BAD(Tuple);
1980                 BAD(Id);
1981                 BAD(Bad);
1982                 BAD(Confirm);
1983                 BAD(Filter);
1984                 BAD(CallBegin);
1985                 BAD(EndReg);
1986                 BAD(EndExcept);
1987
1988                 default:
1989                         OTHER_BIN(Max);
1990                         OTHER_BIN(Min);
1991                         OTHER_BIN(Mulh);
1992
1993                         BE_GEN(FrameAddr);
1994                         BE_GEN(FrameLoad);
1995                         BE_GEN(FrameStore);
1996                         BE_GEN(StackParam);
1997                         break;
1998 bad:
1999                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
2000                 assert(0);
2001         }
2002
2003         /* exchange nodes if a new one was generated */
2004         if (asm_node) {
2005                 exchange(node, asm_node);
2006                 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
2007         }
2008         else {
2009                 DB((tenv.mod, LEVEL_1, "ignored\n"));
2010         }
2011
2012 #undef UNOP
2013 #undef BINOP
2014 #undef GEN
2015 #undef IGN
2016 #undef BAD
2017 #undef OTHER_BIN
2018 #undef BE_GEN
2019 }