Improved start sets for blocks with one pred.
[libfirm] / ir / be / ia32 / ia32_transform.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include "irnode_t.h"
6 #include "irgraph_t.h"
7 #include "irmode_t.h"
8 #include "irgmod.h"
9 #include "iredges.h"
10 #include "irvrfy.h"
11 #include "ircons.h"
12 #include "dbginfo.h"
13 #include "iropt_t.h"
14 #include "debug.h"
15
16 #include "../benode_t.h"
17 #include "bearch_ia32_t.h"
18
19 #include "ia32_nodes_attr.h"
20 #include "../arch/archop.h"     /* we need this for Min and Max nodes */
21 #include "ia32_transform.h"
22 #include "ia32_new_nodes.h"
23 #include "ia32_map_regs.h"
24
25 #include "gen_ia32_regalloc_if.h"
26
27 #define SFP_SIGN "0x80000000"
28 #define DFP_SIGN "0x8000000000000000"
29 #define SFP_ABS  "0x7FFFFFFF"
30 #define DFP_ABS  "0x7FFFFFFFFFFFFFFF"
31
32 #define TP_SFP_SIGN "ia32_sfp_sign"
33 #define TP_DFP_SIGN "ia32_dfp_sign"
34 #define TP_SFP_ABS  "ia32_sfp_abs"
35 #define TP_DFP_ABS  "ia32_dfp_abs"
36
37 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
38 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
39 #define ENT_SFP_ABS  "IA32_SFP_ABS"
40 #define ENT_DFP_ABS  "IA32_DFP_ABS"
41
42 extern ir_op *get_op_Mulh(void);
43
44 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
45                                                                           ir_node *op1, ir_node *op2, ir_node *mem, ir_mode *mode);
46
47 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
48                                                                          ir_node *op, ir_node *mem, ir_mode *mode);
49
50 typedef enum {
51         ia32_SSIGN, ia32_DSIGN, ia32_SABS, ia32_DABS
52 } ia32_known_const_t;
53
54 /* TEMPORARY WORKAROUND */
55 ir_node *be_new_NoReg(ir_graph *irg) {
56         return new_NoMem();
57 }
58
59 /****************************************************************************************************
60  *                  _        _                        __                           _   _
61  *                 | |      | |                      / _|                         | | (_)
62  *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
63  * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
64  * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
65  * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
66  *
67  ****************************************************************************************************/
68
69 struct tv_ent {
70         entity *ent;
71         tarval *tv;
72 };
73
74 /* Compares two (entity, tarval) combinations */
75 static int cmp_tv_ent(const void *a, const void *b, size_t len) {
76         const struct tv_ent *e1 = a;
77         const struct tv_ent *e2 = b;
78
79         return !(e1->tv == e2->tv);
80 }
81
82 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
83 static char *gen_fp_known_const(ir_mode *mode, ia32_known_const_t kct) {
84         static set    *const_set = NULL;
85         struct tv_ent  key;
86         struct tv_ent *entry;
87         char          *tp_name;
88         char          *ent_name;
89         char          *cnst_str;
90         ir_type       *tp;
91         ir_node       *cnst;
92         ir_graph      *rem;
93         entity        *ent;
94
95         if (! const_set) {
96                 const_set = new_set(cmp_tv_ent, 10);
97         }
98
99         switch (kct) {
100                 case ia32_SSIGN:
101                         tp_name  = TP_SFP_SIGN;
102                         ent_name = ENT_SFP_SIGN;
103                         cnst_str = SFP_SIGN;
104                         break;
105                 case ia32_DSIGN:
106                         tp_name  = TP_DFP_SIGN;
107                         ent_name = ENT_DFP_SIGN;
108                         cnst_str = DFP_SIGN;
109                         break;
110                 case ia32_SABS:
111                         tp_name  = TP_SFP_ABS;
112                         ent_name = ENT_SFP_ABS;
113                         cnst_str = SFP_ABS;
114                         break;
115                 case ia32_DABS:
116                         tp_name  = TP_DFP_ABS;
117                         ent_name = ENT_DFP_ABS;
118                         cnst_str = DFP_ABS;
119                         break;
120         }
121
122
123         key.tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
124         key.ent = NULL;
125
126         entry = set_insert(const_set, &key, sizeof(key), HASH_PTR(key.tv));
127
128         if (! entry->ent) {
129                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
130                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
131
132                 set_entity_ld_ident(ent, get_entity_ident(ent));
133                 set_entity_visibility(ent, visibility_local);
134                 set_entity_variability(ent, variability_constant);
135                 set_entity_allocation(ent, allocation_static);
136
137                 /* we create a new entity here: It's initialization must resist on the
138                     const code irg */
139                 rem = current_ir_graph;
140                 current_ir_graph = get_const_code_irg();
141                 cnst = new_Const(mode, key.tv);
142                 current_ir_graph = rem;
143
144                 set_atomic_ent_value(ent, cnst);
145
146                 /* set the entry for hashmap */
147                 entry->ent = ent;
148         }
149
150         return ent_name;
151 }
152
153
154 #undef is_cnst
155 #define is_cnst(op) (is_ia32_Const(op) || is_ia32_fConst(op))
156
157 /* determine if one operator is an Imm */
158 static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
159         if (op1)
160                 return is_cnst(op1) ? op1 : (is_cnst(op2) ? op2 : NULL);
161         else return is_cnst(op2) ? op2 : NULL;
162 }
163
164 /* determine if one operator is not an Imm */
165 static ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
166         return !is_cnst(op1) ? op1 : (!is_cnst(op2) ? op2 : NULL);
167 }
168
169
170 /**
171  * Construct a standard binary operation, set AM and immediate if required.
172  *
173  * @param env   The transformation environment
174  * @param op1   The first operand
175  * @param op2   The second operand
176  * @param func  The node constructor function
177  * @return The constructed ia32 node.
178  */
179 static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, construct_binop_func *func) {
180         ir_node           *new_op = NULL;
181         ir_mode           *mode   = env->mode;
182         dbg_info          *dbg    = env->dbg;
183         ir_graph          *irg    = env->irg;
184         ir_node           *block  = env->block;
185         firm_dbg_module_t *mod    = env->mod;
186         ir_node           *noreg  = be_new_NoReg(irg);
187         ir_node           *nomem  = new_NoMem();
188         ir_node           *expr_op, *imm_op;
189
190
191         /* check if it's an operation with immediate */
192         if (is_op_commutative(get_irn_op(env->irn))) {
193                 imm_op  = get_immediate_op(op1, op2);
194                 expr_op = get_expr_op(op1, op2);
195         }
196         else {
197                 imm_op  = get_immediate_op(NULL, op2);
198                 expr_op = get_expr_op(op1, op2);
199         }
200
201         assert((expr_op || imm_op) && "invalid operands");
202
203         if (!expr_op) {
204                 /* We have two consts here: not yet supported */
205                 imm_op = NULL;
206         }
207
208         if (mode_is_float(mode)) {
209                 /* floating point operations */
210                 if (imm_op) {
211
212                         new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T);
213                         set_ia32_Immop_attr(new_op, imm_op);
214                         set_ia32_am_support(new_op, ia32_am_None);
215                 }
216                 else {
217                         new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T);
218                         set_ia32_am_support(new_op, ia32_am_Source);
219                 }
220         }
221         else {
222                 /* integer operations */
223                 if (imm_op) {
224                         /* This is expr + const */
225                         new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T);
226                         set_ia32_Immop_attr(new_op, imm_op);
227
228                         /* set AM support */
229                         set_ia32_am_support(new_op, ia32_am_Dest);
230                 }
231                 else {
232                         /* This is a normal operation */
233                         new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T);
234
235                         /* set AM support */
236                         set_ia32_am_support(new_op, ia32_am_Full);
237                 }
238         }
239
240         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
241 }
242
243
244
245 /**
246  * Construct a shift/rotate binary operation, sets AM and immediate if required.
247  *
248  * @param env   The transformation environment
249  * @param op1   The first operand
250  * @param op2   The second operand
251  * @param func  The node constructor function
252  * @return The constructed ia32 node.
253  */
254 static ir_node *gen_shift_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, construct_binop_func *func) {
255         ir_node           *new_op = NULL;
256         ir_mode           *mode   = env->mode;
257         dbg_info          *dbg    = env->dbg;
258         ir_graph          *irg    = env->irg;
259         ir_node           *block  = env->block;
260         firm_dbg_module_t *mod    = env->mod;
261         ir_node           *noreg  = be_new_NoReg(irg);
262         ir_node           *nomem  = new_NoMem();
263         ir_node           *expr_op, *imm_op;
264         tarval            *tv;
265
266         assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");
267
268         imm_op  = get_immediate_op(NULL, op2);
269         expr_op = get_expr_op(op1, op2);
270
271         assert((expr_op || imm_op) && "invalid operands");
272
273         if (!expr_op) {
274                 /* We have two consts here: not yet supported */
275                 imm_op = NULL;
276         }
277
278         /* Limit imm_op within range imm8 */
279         if (imm_op) {
280                 tv = get_ia32_Immop_tarval(imm_op);
281
282                 if (tv) {
283                         tv = tarval_mod(tv, new_tarval_from_long(32, mode_Iu));
284                 }
285                 else {
286                         imm_op = NULL;
287                 }
288         }
289
290         /* integer operations */
291         if (imm_op) {
292                 /* This is shift/rot with const */
293
294                 new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T);
295                 set_ia32_Immop_attr(new_op, imm_op);
296         }
297         else {
298                 /* This is a normal shift/rot */
299                 new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T);
300         }
301
302         /* set AM support */
303         set_ia32_am_support(new_op, ia32_am_Dest);
304
305         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
306 }
307
308
309 /**
310  * Construct a standard unary operation, set AM and immediate if required.
311  *
312  * @param env   The transformation environment
313  * @param op    The operand
314  * @param func  The node constructor function
315  * @return The constructed ia32 node.
316  */
317 static ir_node *gen_unop(ia32_transform_env_t *env, ir_node *op, construct_unop_func *func) {
318         ir_node           *new_op = NULL;
319         ir_mode           *mode   = env->mode;
320         dbg_info          *dbg    = env->dbg;
321         ir_graph          *irg    = env->irg;
322         ir_node           *block  = env->block;
323         ir_node           *noreg  = be_new_NoReg(irg);
324         ir_node           *nomem  = new_NoMem();
325
326         new_op = func(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
327
328         if (mode_is_float(mode)) {
329                 /* floating point operations don't support implicit store */
330                 set_ia32_am_support(new_op, ia32_am_None);
331         }
332         else {
333                 set_ia32_am_support(new_op, ia32_am_Dest);
334         }
335
336         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
337 }
338
339
340
341 /**
342  * Creates an ia32 Add with immediate.
343  *
344  * @param env       The transformation environment
345  * @param expr_op   The expression operator
346  * @param const_op  The constant
347  * @return the created ia32 Add node
348  */
349 static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
350         ir_node                *new_op     = NULL;
351         tarval                 *tv         = get_ia32_Immop_tarval(const_op);
352         firm_dbg_module_t      *mod        = env->mod;
353         dbg_info               *dbg        = env->dbg;
354         ir_mode                *mode       = env->mode;
355         ir_graph               *irg        = env->irg;
356         ir_node                *block      = env->block;
357         ir_node                *noreg      = be_new_NoReg(irg);
358         ir_node                *nomem      = new_NoMem();
359         int                     normal_add = 1;
360         tarval_classification_t class_tv, class_negtv;
361
362         /* const_op: tarval or SymConst? */
363         if (tv) {
364                 /* optimize tarvals */
365                 class_tv    = classify_tarval(tv);
366                 class_negtv = classify_tarval(tarval_neg(tv));
367
368                 if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
369                         DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
370                         new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T);
371                         normal_add = 0;
372                 }
373                 else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
374                         DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
375                         new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T);
376                         normal_add = 0;
377                 }
378         }
379
380         if (normal_add) {
381                 new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T);
382                 set_ia32_Immop_attr(new_op, const_op);
383         }
384
385         return new_op;
386 }
387
388 /**
389  * Creates an ia32 Add.
390  *
391  * @param dbg       firm node dbg
392  * @param block     the block the new node should belong to
393  * @param op1       first operator
394  * @param op2       second operator
395  * @param mode      node mode
396  * @return the created ia32 Add node
397  */
398 static ir_node *gen_Add(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
399         ir_node  *new_op = NULL;
400         dbg_info *dbg    = env->dbg;
401         ir_mode  *mode   = env->mode;
402         ir_graph *irg    = env->irg;
403         ir_node  *block  = env->block;
404         ir_node  *noreg  = be_new_NoReg(irg);
405         ir_node  *nomem  = new_NoMem();
406         ir_node  *expr_op, *imm_op;
407
408         imm_op  = get_immediate_op(op1, op2);
409         expr_op = get_expr_op(op1, op2);
410
411         assert((expr_op || imm_op) && "invalid operands");
412
413         if (mode_is_float(mode)) {
414                 return gen_binop(env, op1, op2, new_rd_ia32_fAdd);
415         }
416         else {
417                 /* integer ADD */
418                 if (!expr_op) {
419                         /* No expr_op means, that we have two const - one symconst and */
420                         /* one tarval or another symconst - because this case is not   */
421                         /* covered by constant folding                                 */
422
423                         new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode_T);
424                         add_ia32_am_offs(new_op, get_ia32_cnst(op1));
425                         add_ia32_am_offs(new_op, get_ia32_cnst(op2));
426
427                         /* set AM support */
428                         set_ia32_am_support(new_op, ia32_am_Source);
429                         set_ia32_op_type(new_op, ia32_AddrModeS);
430                         set_ia32_am_flavour(new_op, ia32_am_O);
431
432                         /* Lea doesn't need a Proj */
433                         return new_op;
434                 }
435                 else if (imm_op) {
436                         /* This is expr + const */
437                         new_op = gen_imm_Add(env, expr_op, imm_op);
438
439                         /* set AM support */
440                         set_ia32_am_support(new_op, ia32_am_Dest);
441                 }
442                 else {
443                         /* This is a normal add */
444                         new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T);
445
446                         /* set AM support */
447                         set_ia32_am_support(new_op, ia32_am_Full);
448                 }
449         }
450
451         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
452 }
453
454
455
456 /**
457  * Creates an ia32 Mul.
458  *
459  * @param dbg       firm node dbg
460  * @param block     the block the new node should belong to
461  * @param op1       first operator
462  * @param op2       second operator
463  * @param mode      node mode
464  * @return the created ia32 Mul node
465  */
466 ir_node *gen_Mul(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
467         ir_node *new_op;
468
469         if (mode_is_float(env->mode)) {
470                 new_op = gen_binop(env, op1, op2, new_rd_ia32_fMul);
471         }
472         else {
473                 new_op = gen_binop(env, op1, op2, new_rd_ia32_Mul);
474         }
475
476         return new_op;
477 }
478
479
480
481 /**
482  * Creates an ia32 Mulh.
483  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
484  * this result while Mul returns the lower 32 bit.
485  *
486  * @param env   The transformation environment
487  * @param op1   The first operator
488  * @param op2   The second operator
489  * @return the created ia32 Mulh node
490  */
491 static ir_node *gen_Mulh(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
492         ir_node *proj_EAX, *proj_EDX, *mulh;
493         ir_node *in[1];
494
495         assert(mode_is_float(env->mode) && "Mulh with float not supported");
496         proj_EAX = gen_binop(env, op1, op2, new_rd_ia32_Mulh);
497         mulh     = get_Proj_pred(proj_EAX);
498         proj_EDX = new_rd_Proj(env->dbg, env->irg, env->block, mulh, env->mode, pn_EDX);
499
500         /* to be on the save side */
501         set_Proj_proj(proj_EAX, pn_EAX);
502
503         if (get_ia32_cnst(mulh)) {
504                 /* Mulh with const cannot have AM */
505                 set_ia32_am_support(mulh, ia32_am_None);
506         }
507         else {
508                 /* Mulh cannot have AM for destination */
509                 set_ia32_am_support(mulh, ia32_am_Source);
510         }
511
512         in[0] = proj_EAX;
513
514         /* keep EAX */
515         be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], env->irg, env->block, 1, in);
516
517         return proj_EDX;
518 }
519
520
521
522 /**
523  * Creates an ia32 And.
524  *
525  * @param env   The transformation environment
526  * @param op1   The first operator
527  * @param op2   The second operator
528  * @return The created ia32 And node
529  */
530 static ir_node *gen_And(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
531         if (mode_is_float(env->mode)) {
532                 return gen_binop(env, op1, op2, new_rd_ia32_fAnd);
533         }
534         else {
535                 return gen_binop(env, op1, op2, new_rd_ia32_And);
536         }
537 }
538
539
540
541 /**
542  * Creates an ia32 Or.
543  *
544  * @param env   The transformation environment
545  * @param op1   The first operator
546  * @param op2   The second operator
547  * @return The created ia32 Or node
548  */
549 static ir_node *gen_Or(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
550         if (mode_is_float(env->mode)) {
551                 return gen_binop(env, op1, op2, new_rd_ia32_fOr);
552         }
553         else {
554                 return gen_binop(env, op1, op2, new_rd_ia32_Or);
555         }
556 }
557
558
559
560 /**
561  * Creates an ia32 Eor.
562  *
563  * @param env   The transformation environment
564  * @param op1   The first operator
565  * @param op2   The second operator
566  * @return The created ia32 Eor node
567  */
568 static ir_node *gen_Eor(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
569         if (mode_is_float(env->mode)) {
570                 return gen_binop(env, op1, op2, new_rd_ia32_fEor);
571         }
572         else {
573                 return gen_binop(env, op1, op2, new_rd_ia32_Eor);
574         }
575 }
576
577
578
579 /**
580  * Creates an ia32 Max.
581  *
582  * @param env      The transformation environment
583  * @param op1      The first operator
584  * @param op2      The second operator
585  * @return the created ia32 Max node
586  */
587 static ir_node *gen_Max(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
588         ir_node *new_op;
589
590         if (mode_is_float(env->mode)) {
591                 new_op = gen_binop(env, op1, op2, new_rd_ia32_fMax);
592         }
593         else {
594                 new_op = new_rd_ia32_Max(env->dbg, env->irg, env->block, op1, op2, env->mode);
595                 set_ia32_am_support(new_op, ia32_am_None);
596         }
597
598         return new_op;
599 }
600
601
602
603 /**
604  * Creates an ia32 Min.
605  *
606  * @param env      The transformation environment
607  * @param op1      The first operator
608  * @param op2      The second operator
609  * @return the created ia32 Min node
610  */
611 static ir_node *gen_Min(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
612         ir_node *new_op;
613
614         if (mode_is_float(env->mode)) {
615                 new_op = gen_binop(env, op1, op2, new_rd_ia32_fMin);
616         }
617         else {
618                 new_op = new_rd_ia32_Min(env->dbg, env->irg, env->block, op1, op2, env->mode);
619                 set_ia32_am_support(new_op, ia32_am_None);
620         }
621
622         return new_op;
623 }
624
625
626
627 /**
628  * Creates an ia32 Sub with immediate.
629  *
630  * @param env   The transformation environment
631  * @param op1   The first operator
632  * @param op2   The second operator
633  * @return The created ia32 Sub node
634  */
635 static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
636         ir_node                *new_op     = NULL;
637         tarval                 *tv         = get_ia32_Immop_tarval(const_op);
638         firm_dbg_module_t      *mod        = env->mod;
639         dbg_info               *dbg        = env->dbg;
640         ir_mode                *mode       = env->mode;
641         ir_graph               *irg        = env->irg;
642         ir_node                *block      = env->block;
643         ir_node                *noreg      = be_new_NoReg(irg);
644         ir_node                *nomem      = new_NoMem();
645         int                     normal_sub = 1;
646         tarval_classification_t class_tv, class_negtv;
647
648         /* const_op: tarval or SymConst? */
649         if (tv) {
650                 /* optimize tarvals */
651                 class_tv    = classify_tarval(tv);
652                 class_negtv = classify_tarval(tarval_neg(tv));
653
654                 if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
655                         DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
656                         new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T);
657                         normal_sub = 0;
658                 }
659                 else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
660                         DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
661                         new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem, mode_T);
662                         normal_sub = 0;
663                 }
664         }
665
666         if (normal_sub) {
667                 new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem, mode_T);
668                 set_ia32_Immop_attr(new_op, const_op);
669         }
670
671         return new_op;
672 }
673
674 /**
675  * Creates an ia32 Sub.
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_Sub(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
683         ir_node  *new_op = NULL;
684         dbg_info *dbg    = env->dbg;
685         ir_mode  *mode   = env->mode;
686         ir_graph *irg    = env->irg;
687         ir_node  *block  = env->block;
688         ir_node  *noreg  = be_new_NoReg(irg);
689         ir_node  *nomem  = new_NoMem();
690         ir_node  *expr_op, *imm_op;
691
692         imm_op  = get_immediate_op(NULL, op2);
693         expr_op = get_expr_op(op1, op2);
694
695         assert((expr_op || imm_op) && "invalid operands");
696
697         if (mode_is_float(mode)) {
698                 return gen_binop(env, op1, op2, new_rd_ia32_fSub);
699         }
700         else {
701                 /* integer SUB */
702                 if (!expr_op) {
703                         /* No expr_op means, that we have two const - one symconst and */
704                         /* one tarval or another symconst - because this case is not   */
705                         /* covered by constant folding                                 */
706
707                         new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode_T);
708                         add_ia32_am_offs(new_op, get_ia32_cnst(op1));
709                         sub_ia32_am_offs(new_op, get_ia32_cnst(op2));
710
711                         /* set AM support */
712                         set_ia32_am_support(new_op, ia32_am_Source);
713                         set_ia32_op_type(new_op, ia32_AddrModeS);
714                         set_ia32_am_flavour(new_op, ia32_am_O);
715
716                         /* Lea doesn't need a Proj */
717                         return new_op;
718                 }
719                 else if (imm_op) {
720                         /* This is expr - const */
721                         new_op = gen_imm_Sub(env, expr_op, imm_op);
722
723                         /* set AM support */
724                         set_ia32_am_support(new_op, ia32_am_Dest);
725                 }
726                 else {
727                         /* This is a normal sub */
728                         new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem, mode_T);
729
730                         /* set AM support */
731                         set_ia32_am_support(new_op, ia32_am_Full);
732                 }
733         }
734
735         return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
736 }
737
738
739
740 /**
741  * Generates an ia32 DivMod with additional infrastructure for the
742  * register allocator if needed.
743  *
744  * @param env      The transformation environment
745  * @param dividend -no comment- :)
746  * @param divisor  -no comment- :)
747  * @param dm_flav  flavour_Div/Mod/DivMod
748  * @return The created ia32 DivMod node
749  */
750 static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir_node *divisor, ia32_op_flavour_t dm_flav) {
751         ir_node  *res, *proj;
752         ir_node  *edx_node, *cltd;
753         ir_node  *in_keep[1];
754         dbg_info *dbg   = env->dbg;
755         ir_graph *irg   = env->irg;
756         ir_node  *block = env->block;
757         ir_mode  *mode  = env->mode;
758         ir_node  *irn   = env->irn;
759         ir_node  *mem;
760
761         switch (dm_flav) {
762                 case flavour_Div:
763                         mem = get_Div_mem(irn);
764                         break;
765                 case flavour_Mod:
766                         mem = get_Mod_mem(irn);
767                         break;
768                 case flavour_DivMod:
769                         mem = get_DivMod_mem(irn);
770                         break;
771                 default:
772                         assert(0);
773         }
774
775         if (mode_is_signed(mode)) {
776                 /* in signed mode, we need to sign extend the dividend */
777                 cltd     = new_rd_ia32_Cdq(dbg, irg, block, dividend, mode_T);
778                 dividend = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_EAX);
779                 edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_EDX);
780         }
781         else {
782                 edx_node = new_rd_ia32_Const(dbg, irg, block, mode_Iu);
783                 set_ia32_Const_type(edx_node, ia32_Const);
784                 set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
785         }
786
787         res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, mode);
788
789         set_ia32_flavour(res, dm_flav);
790         set_ia32_n_res(res, 2);
791
792         /* Only one proj is used -> We must add a second proj and */
793         /* connect this one to a Keep node to eat up the second   */
794         /* destroyed register.                                    */
795         if (get_irn_n_edges(irn) == 1) {
796                 proj = get_edge_src_irn(get_irn_out_edge_first(irn));
797                 assert(is_Proj(proj) && "non-Proj to Div/Mod node");
798
799                 if (get_Proj_proj(proj) == pn_DivMod_res_div) {
800                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_mod);
801                 }
802                 else {
803                         in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_div);
804                 }
805
806                 be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
807         }
808
809         return res;
810 }
811
812
813 /**
814  * Wrapper for generate_DivMod. Sets flavour_Mod.
815  */
816 static ir_node *gen_Mod(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
817         return generate_DivMod(env, op1, op2, flavour_Mod);
818 }
819
820
821
822 /**
823  * Wrapper for generate_DivMod. Sets flavour_Div.
824  */
825 static ir_node *gen_Div(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
826         return generate_DivMod(env, op1, op2, flavour_Div);
827 }
828
829
830
831 /**
832  * Wrapper for generate_DivMod. Sets flavour_DivMod.
833  */
834 static ir_node *gen_DivMod(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
835         return generate_DivMod(env, op1, op2, flavour_DivMod);
836 }
837
838
839
840 /**
841  * Creates an ia32 floating Div.
842  *
843  * @param env   The transformation environment
844  * @param op1   The first operator
845  * @param op2   The second operator
846  * @return The created ia32 fDiv node
847  */
848 static ir_node *gen_Quot(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
849         return gen_binop(env, op1, op2, new_rd_ia32_fDiv);
850 }
851
852
853
854 /**
855  * Creates an ia32 Shl.
856  *
857  * @param env   The transformation environment
858  * @param op1   The first operator
859  * @param op2   The second operator
860  * @return The created ia32 Shl node
861  */
862 static ir_node *gen_Shl(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
863         return gen_shift_binop(env, op1, op2, new_rd_ia32_Shl);
864 }
865
866
867
868 /**
869  * Creates an ia32 Shr.
870  *
871  * @param env   The transformation environment
872  * @param op1   The first operator
873  * @param op2   The second operator
874  * @return The created ia32 Shr node
875  */
876 static ir_node *gen_Shr(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
877         return gen_shift_binop(env, op1, op2, new_rd_ia32_Shr);
878 }
879
880
881
882 /**
883  * Creates an ia32 Shrs.
884  *
885  * @param env   The transformation environment
886  * @param op1   The first operator
887  * @param op2   The second operator
888  * @return The created ia32 Shrs node
889  */
890 static ir_node *gen_Shrs(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
891         return gen_shift_binop(env, op1, op2, new_rd_ia32_Shrs);
892 }
893
894
895
896 /**
897  * Creates an ia32 RotL.
898  *
899  * @param env   The transformation environment
900  * @param op1   The first operator
901  * @param op2   The second operator
902  * @return The created ia32 RotL node
903  */
904 static ir_node *gen_RotL(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
905         return gen_shift_binop(env, op1, op2, new_rd_ia32_RotL);
906 }
907
908
909
910 /**
911  * Creates an ia32 RotR.
912  * NOTE: There is no RotR with immediate because this would always be a RotL
913  *       "imm-mode_size_bits" which can be pre-calculated.
914  *
915  * @param env   The transformation environment
916  * @param op1   The first operator
917  * @param op2   The second operator
918  * @return The created ia32 RotR node
919  */
920 static ir_node *gen_RotR(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
921         return gen_shift_binop(env, op1, op2, new_rd_ia32_RotR);
922 }
923
924
925
926 /**
927  * Creates an ia32 RotR or RotL (depending on the found pattern).
928  *
929  * @param env   The transformation environment
930  * @param op1   The first operator
931  * @param op2   The second operator
932  * @return The created ia32 RotL or RotR node
933  */
934 static ir_node *gen_Rot(ia32_transform_env_t *env, ir_node *op1, ir_node *op2) {
935         ir_node *rotate = NULL;
936
937         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
938                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
939                  that means we can create a RotR instead of an Add and a RotL */
940
941         if (is_Proj(op2)) {
942                 ir_node *pred = get_Proj_pred(op2);
943
944                 if (is_ia32_Add(pred)) {
945                         ir_node *pred_pred = get_irn_n(pred, 2);
946                         tarval  *tv        = get_ia32_Immop_tarval(pred);
947                         long     bits      = get_mode_size_bits(env->mode);
948
949                         if (is_Proj(pred_pred)) {
950                                 pred_pred = get_Proj_pred(pred_pred);
951                         }
952
953                         if (is_ia32_Minus(pred_pred) &&
954                                 tarval_is_long(tv)       &&
955                                 get_tarval_long(tv) == bits)
956                         {
957                                 DB((env->mod, LEVEL_1, "RotL into RotR ... "));
958                                 rotate = gen_RotR(env, op1, get_irn_n(pred_pred, 2));
959                         }
960
961                 }
962         }
963
964         if (!rotate) {
965                 rotate = gen_RotL(env, op1, op2);
966         }
967
968         return rotate;
969 }
970
971
972
973 /**
974  * Transforms a Conv node.
975  *
976  * @param env   The transformation environment
977  * @param op    The operator
978  * @return The created ia32 Conv node
979  */
980 static ir_node *gen_Conv(ia32_transform_env_t *env, ir_node *op) {
981         return new_rd_ia32_Conv(env->dbg, env->irg, env->block, op, env->mode);
982 }
983
984
985
986 /**
987  * Transforms a Minus node.
988  *
989  * @param env   The transformation environment
990  * @param op    The operator
991  * @return The created ia32 Minus node
992  */
993 static ir_node *gen_Minus(ia32_transform_env_t *env, ir_node *op) {
994         char    *name;
995         ir_node *new_op;
996         ir_node *noreg = be_new_NoReg(env->irg);
997         ir_node *nomem = new_rd_NoMem(env->irg);
998         int      size;
999
1000         if (mode_is_float(env->mode)) {
1001                 new_op = new_rd_ia32_fEor(env->dbg, env->irg, env->block, noreg, noreg, op, noreg, nomem, mode_T);
1002
1003                 size   = get_mode_size_bits(env->mode);
1004                 name   = gen_fp_known_const(env->mode, size == 32 ? ia32_SSIGN : ia32_DSIGN);
1005
1006                 set_ia32_sc(new_op, name);
1007
1008                 new_op = new_rd_Proj(env->dbg, env->irg, env->block, new_op, env->mode, 0);
1009         }
1010         else {
1011                 new_op = gen_unop(env, op, new_rd_ia32_Minus);
1012         }
1013
1014         return new_op;
1015 }
1016
1017
1018
1019 /**
1020  * Transforms a Not node.
1021  *
1022  * @param env   The transformation environment
1023  * @param op    The operator
1024  * @return The created ia32 Not node
1025  */
1026 static ir_node *gen_Not(ia32_transform_env_t *env, ir_node *op) {
1027         ir_node *new_op;
1028
1029         if (mode_is_float(env->mode)) {
1030                 assert(0);
1031         }
1032         else {
1033                 new_op = gen_unop(env, op, new_rd_ia32_Not);
1034         }
1035
1036         return new_op;
1037 }
1038
1039
1040
1041 /**
1042  * Transforms an Abs node.
1043  *
1044  * @param env   The transformation environment
1045  * @param op    The operator
1046  * @return The created ia32 Abs node
1047  */
1048 static ir_node *gen_Abs(ia32_transform_env_t *env, ir_node *op) {
1049         ir_node  *res, *p_eax, *p_edx;
1050         dbg_info *dbg   = env->dbg;
1051         ir_mode  *mode  = env->mode;
1052         ir_graph *irg   = env->irg;
1053         ir_node  *block = env->block;
1054         ir_node  *noreg = be_new_NoReg(irg);
1055         ir_node  *nomem = new_NoMem();
1056         int       size;
1057         char     *name;
1058
1059         if (mode_is_float(mode)) {
1060                 res = new_rd_ia32_fAnd(dbg,irg, block, noreg, noreg, op, noreg, nomem, mode_T);
1061
1062                 size   = get_mode_size_bits(mode);
1063                 name   = gen_fp_known_const(mode, size == 32 ? ia32_SABS : ia32_DABS);
1064
1065                 set_ia32_sc(res, name);
1066
1067                 res = new_rd_Proj(dbg, irg, block, res, mode, 0);
1068         }
1069         else {
1070                 res   = new_rd_ia32_Cdq(dbg, irg, block, op, mode_T);
1071                 p_eax = new_rd_Proj(dbg, irg, block, res, mode, pn_EAX);
1072                 p_edx = new_rd_Proj(dbg, irg, block, res, mode, pn_EDX);
1073                 res   = new_rd_ia32_Eor(dbg, irg, block, noreg, noreg, p_eax, p_edx, nomem, mode_T);
1074                 res   = new_rd_Proj(dbg, irg, block, res, mode, 0);
1075                 res   = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, res, p_edx, nomem, mode_T);
1076                 res   = new_rd_Proj(dbg, irg, block, res, mode, 0);
1077         }
1078
1079         return res;
1080 }
1081
1082
1083
1084 /**
1085  * Transforms a Load.
1086  *
1087  * @param mod     the debug module
1088  * @param block   the block the new node should belong to
1089  * @param node    the ir Load node
1090  * @param mode    node mode
1091  * @return the created ia32 Load node
1092  */
1093 static ir_node *gen_Load(ia32_transform_env_t *env) {
1094         ir_node *node  = env->irn;
1095         ir_node *noreg = be_new_NoReg(env->irg);
1096
1097         if (mode_is_float(env->mode)) {
1098                 return new_rd_ia32_fLoad(env->dbg, env->irg, env->block, get_Load_ptr(node), noreg, get_Load_mem(node), env->mode);
1099         }
1100         return new_rd_ia32_Load(env->dbg, env->irg, env->block, get_Load_ptr(node), noreg, get_Load_mem(node), env->mode);
1101 }
1102
1103
1104
1105 /**
1106  * Transforms a Store.
1107  *
1108  * @param mod     the debug module
1109  * @param block   the block the new node should belong to
1110  * @param node    the ir Store node
1111  * @param mode    node mode
1112  * @return the created ia32 Store node
1113  */
1114 ir_node *gen_Store(ia32_transform_env_t *env) {
1115         ir_node *node  = env->irn;
1116         ir_node *noreg = be_new_NoReg(env->irg);
1117
1118         if (mode_is_float(env->mode)) {
1119                 return new_rd_ia32_fStore(env->dbg, env->irg, env->block, get_Store_ptr(node), noreg, get_Store_value(node), get_Store_mem(node), env->mode);
1120         }
1121         return new_rd_ia32_Store(env->dbg, env->irg, env->block, get_Store_ptr(node), noreg, get_Store_value(node), get_Store_mem(node), env->mode);
1122 }
1123
1124
1125
1126 /**
1127  * Transforms a Call and its arguments corresponding to the calling convention.
1128  *
1129  * @param mod     the debug module
1130  * @param block   the block the new node should belong to
1131  * @param node    the ir Call node
1132  * @param dummy   mode doesn't matter
1133  * @return the created ia32 Call node
1134  */
1135 static ir_node *gen_Call(ia32_transform_env_t *env) {
1136 #if 0
1137         const ia32_register_req_t **in_req;
1138         ir_node          **in;
1139         ir_node           *new_call, *sync;
1140         int                i, j, n_new_call_in, ignore = 0;
1141         ia32_attr_t       *attr;
1142         dbg_info          *dbg          = env->dbg;
1143         ir_graph          *irg          = env->irg;
1144         ir_node           *block        = env->block;
1145         ir_node           *call         = env->irn;
1146         ir_node          **stack_param  = NULL;
1147         ir_node          **param        = get_Call_param_arr(call);
1148         ir_node           *call_Mem     = get_Call_mem(call);
1149         unsigned           cc           = get_method_calling_convention(get_Call_type(call));
1150         int                n            = get_Call_n_params(call);
1151         int                stack_idx    = 0;
1152         int                biggest_n    = -1;
1153         int                n_res        = get_method_n_ress(get_Call_type(call));
1154
1155         assert(n_res <= 2 && "method with more than two results not supported");
1156
1157         if (cc & cc_reg_param)
1158                 biggest_n = ia32_get_n_regparam_class(n, param, &ignore, &ignore);
1159
1160         /* remember: biggest_n = x means we can pass (x + 1) parameters in register */
1161
1162         /* do we need to pass arguments on stack? */
1163         if (biggest_n + 1 < n)
1164                 stack_param = xcalloc(n - biggest_n - 1, sizeof(ir_node *));
1165
1166         /* we need at least one in, either for the stack params or the call_Mem */
1167         n_new_call_in = biggest_n + 2;
1168
1169         /* the call has one IN for all stack parameter and one IN for each reg param */
1170         in     = xcalloc(n_new_call_in, sizeof(ir_node *));
1171         in_req = xcalloc(n_new_call_in, sizeof(arch_register_req_t *));
1172
1173         /* loop over all parameters and set the register requirements */
1174         for (i = 0; i <= biggest_n && (cc & cc_reg_param); i++) {
1175                 in_req[i] = ia32_get_RegParam_req(n, param, i, cc);
1176         }
1177         stack_idx = i;
1178
1179         /* create remaining stack parameters */
1180         if (cc & cc_last_on_top) {
1181                 for (i = stack_idx; i < n; i++) {
1182                         /* pass it on stack */
1183                         if (mode_is_float(get_irn_mode(param[i]))) {
1184                                 stack_param[i - stack_idx] = new_rd_ia32_fStackArg(get_irn_dbg_info(param[i]), irg,
1185                                                                                                                 block, call_Mem, param[i], mode_M);
1186                         }
1187                         else {
1188                                 stack_param[i - stack_idx] = new_rd_ia32_StackArg(get_irn_dbg_info(param[i]), irg,
1189                                                                                                                 block, call_Mem, param[i], mode_M);
1190                         }
1191                         /* set the argument number for later lowering */
1192                         set_ia32_pncode(stack_param[i - stack_idx], i - stack_idx);
1193                 }
1194         }
1195         else {
1196                 for (i = n - 1, j = 0; i >= stack_idx; i--, j++) {
1197                         /* pass it on stack */
1198                         if (mode_is_float(get_irn_mode(param[i]))) {
1199                                 stack_param[j] = new_rd_ia32_fStackArg(get_irn_dbg_info(param[i]), irg,
1200                                                                                                                 block, call_Mem, param[i], mode_M);
1201                         }
1202                         else {
1203                                 stack_param[j] = new_rd_ia32_StackArg(get_irn_dbg_info(param[i]), irg,
1204                                                                                                                 block, call_Mem, param[i], mode_M);
1205                         }
1206                         /* set the argument number for later lowering */
1207                         set_ia32_pncode(stack_param[j], j);
1208                 }
1209         }
1210
1211         if (stack_param) {
1212                 sync = new_r_Sync(irg, block, n - biggest_n - 1, stack_param);
1213                 in[n_new_call_in - 1] = sync;
1214         }
1215         else {
1216                 in[n_new_call_in - 1] = call_Mem;
1217         }
1218
1219         /* create the new node */
1220         new_call = new_rd_ia32_Call(dbg, irg, block, n_new_call_in, in);
1221         set_ia32_Immop_attr(new_call, get_Call_ptr(call));
1222
1223         /* set register requirements for in and out */
1224         attr             = get_ia32_attr(new_call);
1225         attr->in_req     = in_req;
1226
1227         set_ia32_n_res(new_call, n_res);
1228
1229         if (n_res > 0) {
1230                 attr->out_req    = xcalloc(n_res, sizeof(ia32_register_req_t *));
1231                 attr->slots      = xcalloc(n_res, sizeof(arch_register_t *));
1232         }
1233
1234         /* two results only appear when a 64bit int result is broken up into two 32bit results */
1235         if (n_res == 1) {
1236                 if (mode_is_float(get_type_mode(get_method_res_type(get_Call_type(call), 0))))
1237                         attr->out_req[0] = &ia32_default_req_ia32_fp_xmm0;
1238                 else
1239                         attr->out_req[0] = &ia32_default_req_ia32_gp_eax;
1240         }
1241         else if (n_res == 2) {
1242                 attr->out_req[0] = &ia32_default_req_ia32_gp_eax;
1243                 attr->out_req[1] = &ia32_default_req_ia32_gp_edx;
1244         }
1245
1246         /* stack parameter has no OUT register */
1247         attr->in_req[n_new_call_in - 1] = &ia32_default_req_none;
1248
1249         return new_call;
1250 #endif
1251 }
1252
1253
1254
1255 /**
1256  * Transforms a Cond -> Proj[b] -> Cmp into a CondJmp or CondJmp_i
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    = be_new_NoReg(irg);
1271         ir_node  *nomem    = new_NoMem();
1272         ir_node  *cmp_a, *cmp_b, *cnst, *expr;
1273
1274         if (is_Proj(sel) && sel_mode == mode_b) {
1275                 pred  = get_Proj_pred(sel);
1276
1277                 /* get both compare operators */
1278                 cmp_a = get_Cmp_left(pred);
1279                 cmp_b = get_Cmp_right(pred);
1280
1281                 /* check if we can use a CondJmp with immediate */
1282                 cnst = get_immediate_op(cmp_a, cmp_b);
1283                 expr = get_expr_op(cmp_a, cmp_b);
1284
1285                 if (cnst && expr) {
1286                         res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, expr, noreg, nomem, mode_T);
1287                         set_ia32_Immop_attr(res, cnst);
1288                 }
1289                 else {
1290                         res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem, mode_T);
1291                 }
1292
1293                 set_ia32_pncode(res, get_Proj_proj(sel));
1294         }
1295         else {
1296                 res = new_rd_ia32_SwitchJmp(dbg, irg, block, noreg, noreg, sel, nomem, mode_T);
1297                 set_ia32_pncode(res, get_Cond_defaultProj(node));
1298         }
1299
1300         return res;
1301 }
1302
1303
1304
1305 /**
1306  * Transform the argument projs from a start node corresponding to the
1307  * calling convention.
1308  * It transforms "Proj Arg x -> ProjT -> Start <- ProjM" into
1309  * "RegParam x   -> ProjT -> Start" OR
1310  * "StackParam x -> ProjM -> Start"
1311  * whether parameter is passed in register or on stack.
1312  *
1313  * @param mod     the debug module
1314  * @param block   the block the nodes should belong to
1315  * @param proj    the ProjT node which points to Start
1316  * @param start   the Start node
1317  * @return Should be always NULL
1318  */
1319 static ir_node *gen_Proj_Start(ia32_transform_env_t *env, ir_node *proj, ir_node *start) {
1320 #if 0
1321         const ia32_register_req_t *temp_req;
1322         const ir_edge_t   *edge;
1323         ir_node           *succ, *irn;
1324         ir_node          **projargs;
1325         ir_mode           *mode;
1326         int                n, i;
1327         unsigned           cc;
1328         ir_node           *proj_M     = get_irg_initial_mem(current_ir_graph);
1329         entity            *irg_ent    = get_irg_entity(current_ir_graph);
1330         ir_type           *tp         = get_entity_type(irg_ent);
1331         int                cur_pn     = 0;
1332         ir_graph          *irg        = env->irg;
1333         ir_node           *block      = env->block;
1334
1335         assert(is_Method_type(tp) && "irg type is not a method");
1336
1337         switch(get_Proj_proj(proj)) {
1338                 case pn_Start_T_args:
1339                         /* We cannot use get_method_n_params here as the function might
1340                            be variadic or one argument is not used. */
1341                         n = get_irn_n_edges(proj);
1342
1343                         /* Allocate memory for all non variadic parameters in advance to be on the save side */
1344                         env->cg->reg_param_req = xcalloc(get_method_n_params(tp), sizeof(ia32_register_req_t *));
1345
1346                         /* we are done here when there are no parameters */
1347                         if (n < 1)
1348                                 break;
1349
1350                         /* temporary remember all proj arg x */
1351                         projargs = xcalloc(n, sizeof(ir_node *));
1352
1353                         i = 0;
1354                         foreach_out_edge((const ir_node *)proj, edge) {
1355                                 succ = get_edge_src_irn(edge);
1356                                 assert(is_Proj(succ) && "non-Proj from a Proj_T (pn_Start_T_args).");
1357                                 projargs[i++] = succ;
1358                         }
1359
1360                         cc = get_method_calling_convention(tp);
1361
1362                         /* loop over all parameters and check whether its a int or float */
1363                         for (i = 0; i < n; i++) {
1364                                 mode   = get_irn_mode(projargs[i]);
1365                                 cur_pn = get_Proj_proj(projargs[i]);
1366
1367                                 if (cc & cc_reg_param) {
1368                                         temp_req = ia32_get_RegParam_req(n, projargs, cur_pn, cc);
1369                                 }
1370                                 else {
1371                                         temp_req = NULL;
1372                                 }
1373
1374                                 if (temp_req) {
1375                                         /* passed in register */
1376                                         env->cg->reg_param_req[cur_pn] = temp_req;
1377                                 }
1378                                 else {
1379                                         /* passed on stack */
1380                                         if (mode_is_float(mode))
1381                                                 irn = new_rd_ia32_fStackParam(get_irn_dbg_info(projargs[i]), irg, block, proj_M, mode);
1382                                         else
1383                                                 irn = new_rd_ia32_StackParam(get_irn_dbg_info(projargs[i]), irg, block, proj_M, mode);
1384
1385                                         set_ia32_pncode(irn, cur_pn);
1386
1387                                         /* kill the old "Proj Arg" and replace with the new stack param */
1388                                         exchange(projargs[i], irn);
1389                                 }
1390                         }
1391
1392                         free(projargs);
1393
1394                         break;
1395                 case pn_Start_P_frame_base:
1396                 case pn_Start_X_initial_exec:
1397                 case pn_Start_M:
1398                 case pn_Start_P_globals:
1399                 case pn_Start_P_value_arg_base:
1400                         break;
1401                 default:
1402                         assert(0 && "unsupported Proj(Start)");
1403         }
1404
1405         return NULL;
1406 #endif
1407 }
1408
1409 /**
1410  * Transform some Proj's (Proj_Proj, Proj_Start, Proj_Cmp, Proj_Cond, Proj_Call).
1411  * All others are ignored.
1412  *
1413  * @param mod     the debug module
1414  * @param block   the block the new node should belong to
1415  * @param node    the ir Proj node
1416  * @param mode    mode of the Proj
1417  * @return The transformed node.
1418  */
1419 static ir_node *gen_Proj(ia32_transform_env_t *env) {
1420         ir_node *new_node  = NULL;
1421         ir_node *pred      = get_Proj_pred(env->irn);
1422
1423         if (env->mode == mode_M)
1424                 return NULL;
1425
1426         if (get_irn_op(pred) == op_Start) {
1427                 new_node = gen_Proj_Start(env, env->irn, pred);
1428         }
1429
1430         return new_node;
1431 }
1432
1433
1434
1435 /*********************************************************
1436  *                  _             _      _
1437  *                 (_)           | |    (_)
1438  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
1439  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
1440  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
1441  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
1442  *
1443  *********************************************************/
1444
1445
1446
1447 /**
1448  * Transforms the given firm node (and maybe some other related nodes)
1449  * into one or more assembler nodes.
1450  *
1451  * @param node    the firm node
1452  * @param env     the debug module
1453  */
1454 void ia32_transform_node(ir_node *node, void *env) {
1455         ia32_code_gen_t *cgenv = (ia32_code_gen_t *)env;
1456         opcode  code           = get_irn_opcode(node);
1457         ir_node *asm_node      = NULL;
1458         ia32_transform_env_t  tenv;
1459
1460         if (is_Block(node))
1461                 return;
1462
1463         tenv.arch_env = cgenv->arch_env;
1464         tenv.block    = get_nodes_block(node);
1465         tenv.dbg      = get_irn_dbg_info(node);
1466         tenv.irg      = current_ir_graph;
1467         tenv.irn      = node;
1468         tenv.mod      = cgenv->mod;
1469         tenv.mode     = get_irn_mode(node);
1470         tenv.cg       = cgenv;
1471
1472 #define UNOP(a)  case iro_##a: asm_node = gen_##a(&tenv, get_##a##_op(node)); break
1473 #define BINOP(a) case iro_##a: asm_node = gen_##a(&tenv, get_##a##_left(node), get_##a##_right(node)); break
1474 #define GEN(a)   case iro_##a: asm_node = gen_##a(&tenv); break
1475 #define IGN(a)   case iro_##a: break
1476 #define BAD(a)   case iro_##a: goto bad
1477
1478         DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
1479
1480         switch (code) {
1481                 BINOP(Add);
1482                 BINOP(Sub);
1483                 BINOP(Mul);
1484                 BINOP(And);
1485                 BINOP(Or);
1486                 BINOP(Eor);
1487
1488                 BINOP(Shl);
1489                 BINOP(Shr);
1490                 BINOP(Shrs);
1491
1492                 BINOP(Quot);
1493
1494                 BINOP(Div);
1495                 BINOP(Mod);
1496                 BINOP(DivMod);
1497
1498                 UNOP(Minus);
1499                 UNOP(Conv);
1500                 UNOP(Abs);
1501                 UNOP(Not);
1502
1503                 GEN(Load);
1504                 GEN(Store);
1505                 GEN(Cond);
1506
1507                 IGN(Proj);
1508                 IGN(Call);
1509                 IGN(Alloc);
1510
1511                 IGN(Block);
1512                 IGN(Start);
1513                 IGN(End);
1514                 IGN(NoMem);
1515                 IGN(Phi);
1516                 IGN(IJmp);
1517                 IGN(Break);
1518                 IGN(Cmp);
1519                 IGN(Unknown);
1520                 /* constant transformation happens earlier */
1521                 IGN(Const);
1522                 IGN(SymConst);
1523
1524                 BAD(Raise);
1525                 BAD(Sel);
1526                 BAD(InstOf);
1527                 BAD(Cast);
1528                 BAD(Free);
1529                 BAD(Sync);
1530                 BAD(Tuple);
1531                 BAD(Id);
1532                 BAD(Bad);
1533                 BAD(Confirm);
1534                 BAD(Filter);
1535                 BAD(CallBegin);
1536                 BAD(EndReg);
1537                 BAD(EndExcept);
1538                 BAD(Mux);
1539                 BAD(CopyB);
1540
1541                 default:
1542                         if (get_irn_op(node) == get_op_Max()) {
1543                                 asm_node = gen_Max(&tenv, get_irn_n(node, 0), get_irn_n(node, 1));
1544                         }
1545                         else if (get_irn_op(node) == get_op_Min()) {
1546                                 asm_node = gen_Min(&tenv, get_irn_n(node, 0), get_irn_n(node, 1));
1547                         }
1548                         else if (get_irn_op(node) == get_op_Mulh()) {
1549                                 asm_node = gen_Mulh(&tenv, get_irn_n(node, 0), get_irn_n(node, 1));
1550                         }
1551                         break;
1552 bad:
1553                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
1554                 assert(0);
1555         }
1556
1557         if (asm_node) {
1558                 exchange(node, asm_node);
1559                 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
1560         }
1561         else {
1562                 DB((tenv.mod, LEVEL_1, "ignored\n"));
1563         }
1564 }