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