optimize Add and Add with Shift with LEA
[libfirm] / ir / be / 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 "dbginfo.h"
10 #include "irop_t.h"
11 #include "debug.h"
12
13 #include "../firm2arch_nodes_attr.h"
14 #include "../bearch_firm.h"
15 #include "transform.h"
16 #include "new_nodes.h"
17
18
19
20 /* determine if one operator is an Imm */
21 ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
22   if (op1)
23     return is_Imm(op1) ? op1 : (is_Imm(op2) ? op2 : NULL);
24   else return is_Imm(op2) ? op2 : NULL;
25 }
26
27 /* determine if one operator is not an Imm */
28 ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
29   return !is_Imm(op1) ? op1 : (!is_Imm(op2) ? op2 : NULL);
30 }
31
32
33
34 /**
35  * Creates an ia32 Add with immediate.
36  *
37  * @param dbg       firm dbg
38  * @param block     the block the new node should belong to
39  * @param expr_op   operator
40  * @param mode      node mode
41  * @return the created ia23 Add_i node
42  */
43 ir_node *gen_imm_Add(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
44   ir_node *new_op;
45   tarval  *tv = get_Immop_tarval(const_op);
46   int     normal_add = 0;
47   tarval_classification_t class_tv, class_negtv;
48
49   /* const_op: tarval or SymConst? */
50   if (tv) {
51     /* optimize tarvals */
52     class_tv    = classify_tarval(tv);
53     class_negtv = classify_tarval(tarval_neg(tv));
54
55     if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
56       new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
57     }
58     else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == Sub */
59       new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
60     }
61     else
62       normal_add = 1;
63   }
64   else
65     normal_add = 1;
66
67   if (normal_add)
68     new_op = new_rd_ia32_Lea_i(dbg, current_ir_graph, block, expr_op, mode);
69
70   return new_op;
71 }
72
73 /**
74  * Creates an ia32 Add.
75  *
76  * @param dbg       firm node dbg
77  * @param block     the block the new node should belong to
78  * @param op1       first operator
79  * @param op2       second operator
80  * @param mode      node mode
81  * @return the created ia32 Add node
82  */
83 ir_node *gen_Add(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
84   /* try to optimize with LEA */
85   ir_node *shli_op = is_ia32_Shl_i(op1) ? op1 : (is_ia32_Shl_i(op2) ? op2 : NULL);
86   ir_node *expr_op = shli_op == op1 ? op2 : (shli_op == op2 ? op1 : NULL);
87   int normal_add   = 0;
88   ir_node *new_op;
89
90   if (shli_op) {
91     tarval *tv   = get_Immop_tarval(shli_op);
92     tarval *offs = NULL;
93     if (tv) {
94       switch (get_tarval_long(tv)) {
95         case 1:
96         case 2:
97         case 3:
98           // If the other operand of the LEA is an LEA_i (that means LEA ofs(%regop1)),
99           // we can skip it and transform the whole sequence into LEA ofs(%regop1, %regop2, shl_val),
100           if (is_ia32_Lea_i(expr_op)) {
101             offs = get_Immop_tarval(expr_op);
102             expr_op = get_irn_n(expr_op, 0);
103           }
104
105           new_op = new_rd_ia32_Lea(dbg, current_ir_graph, block, expr_op, get_irn_n(shli_op, 0), mode);
106           set_Immop_attr_tv(new_op, tv);
107
108           if (offs)
109             set_ia32_Lea_offs(new_op, offs);
110
111           break;
112         default:
113           normal_add = 1;
114           break;
115       }
116     }
117     else
118       normal_add = 1;
119   }
120   else
121     normal_add = 1;
122
123   if (normal_add) {
124     new_op = new_rd_ia32_Lea(dbg, current_ir_graph, block, op1, op2, mode);
125     set_Immop_attr_tv(new_op, get_tarval_one(mode));
126     set_ia32_Lea_offs(new_op, NULL);
127   }
128
129   return new_op;
130 }
131
132
133
134 /**
135  * Creates an ia32 Mul with immediate.
136  *
137  * @param dbg       firm dbg
138  * @param block     the block the new node should belong to
139  * @param expr_op   operator
140  * @param mode      node mode
141  * @return the created ia23 Mul_i node
142  */
143 ir_node *gen_imm_Mul(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
144   return new_rd_ia32_Mul_i(dbg, current_ir_graph, block, expr_op, mode);
145 }
146
147 /**
148  * Creates an ia32 Mul.
149  *
150  * @param dbg       firm node dbg
151  * @param block     the block the new node should belong to
152  * @param op1       first operator
153  * @param op2       second operator
154  * @param mode      node mode
155  * @return the created ia32 Mul node
156  */
157 ir_node *gen_Mul(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
158   return new_rd_ia32_Mul(dbg, current_ir_graph, block, op1, op2, mode);
159 }
160
161
162
163 /**
164  * Creates an ia32 And with immediate.
165  *
166  * @param dbg       firm dbg
167  * @param block     the block the new node should belong to
168  * @param expr_op   operator
169  * @param mode      node mode
170  * @return the created ia23 And_i node
171  */
172 ir_node *gen_imm_And(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
173   return new_rd_ia32_And_i(dbg, current_ir_graph, block, expr_op, mode);
174 }
175
176 /**
177  * Creates an ia32 And.
178  *
179  * @param dbg       firm node dbg
180  * @param block     the block the new node should belong to
181  * @param op1       first operator
182  * @param op2       second operator
183  * @param mode      node mode
184  * @return the created ia32 And node
185  */
186 ir_node *gen_And(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
187   return new_rd_ia32_And(dbg, current_ir_graph, block, op1, op2, mode);
188 }
189
190
191
192 /**
193  * Creates an ia32 Or with immediate.
194  *
195  * @param dbg       firm dbg
196  * @param block     the block the new node should belong to
197  * @param expr_op   operator
198  * @param mode      node mode
199  * @return the created ia23 Or_i node
200  */
201 ir_node *gen_imm_Or(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
202   return new_rd_ia32_Or_i(dbg, current_ir_graph, block, expr_op, mode);
203 }
204
205 /**
206  * Creates an ia32 Or.
207  *
208  * @param dbg       firm node dbg
209  * @param block     the block the new node should belong to
210  * @param op1       first operator
211  * @param op2       second operator
212  * @param mode      node mode
213  * @return the created ia32 Or node
214  */
215 ir_node *gen_Or(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
216   return new_rd_ia32_Or(dbg, current_ir_graph, block, op1, op2, mode);
217 }
218
219
220
221 /**
222  * Creates an ia32 Eor with immediate.
223  *
224  * @param dbg       firm dbg
225  * @param block     the block the new node should belong to
226  * @param expr_op   operator
227  * @param mode      node mode
228  * @return the created ia23 Eor_i node
229  */
230 ir_node *gen_imm_Eor(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
231   return new_rd_ia32_Eor_i(dbg, current_ir_graph, block, expr_op, mode);
232 }
233
234 /**
235  * Creates an ia32 Eor.
236  *
237  * @param dbg       firm node dbg
238  * @param block     the block the new node should belong to
239  * @param op1       first operator
240  * @param op2       second operator
241  * @param mode      node mode
242  * @return the created ia32 Eor node
243  */
244 ir_node *gen_Eor(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
245   return new_rd_ia32_Eor(dbg, current_ir_graph, block, op1, op2, mode);
246 }
247
248
249
250 /**
251  * Creates an ia32 Cmp with immediate.
252  *
253  * @param dbg       firm dbg
254  * @param block     the block the new node should belong to
255  * @param expr_op   operator
256  * @param mode      node mode
257  * @return the created ia23 Cmp_i node
258  */
259 ir_node *gen_imm_Cmp(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
260   return new_rd_ia32_Cmp_i(dbg, current_ir_graph, block, expr_op, mode);
261 }
262
263 /**
264  * Creates an ia32 Cmp.
265  *
266  * @param dbg       firm node dbg
267  * @param block     the block the new node should belong to
268  * @param op1       first operator
269  * @param op2       second operator
270  * @param mode      node mode
271  * @return the created ia32 Cmp node
272  */
273 ir_node *gen_Cmp(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
274   return new_rd_ia32_Cmp(dbg, current_ir_graph, block, op1, op2, mode);
275 }
276
277
278
279 /**
280  * Creates an ia32 Sub with immediate.
281  *
282  * @param dbg       firm dbg
283  * @param block     the block the new node should belong to
284  * @param expr_op   operator
285  * @param mode      node mode
286  * @return the created ia23 Sub_i node
287  */
288 ir_node *gen_imm_Sub(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
289   ir_node *new_op;
290   tarval  *tv = get_Immop_tarval(const_op);
291   int     normal_sub = 0;
292   tarval_classification_t class_tv, class_negtv;
293
294   /* const_op: tarval or SymConst? */
295   if (tv) {
296     /* optimize tarvals */
297     class_tv    = classify_tarval(tv);
298     class_negtv = classify_tarval(tarval_neg(tv));
299
300     if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
301       new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
302     }
303     else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
304       new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
305     }
306     else
307       normal_sub = 1;
308   }
309   else
310     normal_sub = 1;
311
312   if (normal_sub)
313     new_op = new_rd_ia32_Sub_i(dbg, current_ir_graph, block, expr_op, mode);
314
315   return new_op;
316 }
317
318 /**
319  * Creates an ia32 Sub.
320  *
321  * @param dbg       firm node dbg
322  * @param block     the block the new node should belong to
323  * @param op1       first operator
324  * @param op2       second operator
325  * @param mode      node mode
326  * @return the created ia32 Sub node
327  */
328 ir_node *gen_Sub(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
329   ir_node *sub = NULL;
330
331   /* transform "const - expr" into "-expr + const" */
332   if (is_Imm(op1) && !is_Imm(op2)) {
333     DBG((mod, LEVEL_1, "optimizing c-e into -e+c ... "));
334
335     sub = new_rd_ia32_Minus(dbg, current_ir_graph, block, op2, mode);
336     sub = gen_imm_Add(dbg, block, sub, op1, mode);
337     set_Immop_attr(sub, op1);
338   }
339   else {
340     sub = new_rd_ia32_Sub(dbg, current_ir_graph, block, op1, op2, mode);
341   }
342
343   return sub;
344 }
345
346
347
348 /**
349  * Creates an ia32 Mod with immediate.
350  *
351  * @param dbg       firm dbg
352  * @param block     the block the new node should belong to
353  * @param expr_op   operator
354  * @param mode      node mode
355  * @return the created ia23 Mod_i node
356  */
357 ir_node *gen_imm_Mod(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
358   return new_rd_ia32_Mod_i(dbg, current_ir_graph, block, expr_op, mode);
359 }
360
361 /**
362  * Creates an ia32 Mod.
363  *
364  * @param dbg       firm node dbg
365  * @param block     the block the new node should belong to
366  * @param op1       first operator
367  * @param op2       second operator
368  * @param mode      node mode
369  * @return the created ia32 Mod node
370  */
371 ir_node *gen_Mod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
372   return new_rd_ia32_Mod(dbg, current_ir_graph, block, op1, op2, mode);
373 }
374
375
376
377 /**
378  * Creates an ia32 Shl with immediate.
379  *
380  * @param dbg       firm dbg
381  * @param block     the block the new node should belong to
382  * @param expr_op   operator
383  * @param mode      node mode
384  * @return the created ia23 Shl_i node
385  */
386 ir_node *gen_imm_Shl(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
387   return new_rd_ia32_Shl_i(dbg, current_ir_graph, block, expr_op, mode);
388 }
389
390 /**
391  * Creates an ia32 Shl.
392  *
393  * @param dbg       firm node dbg
394  * @param block     the block the new node should belong to
395  * @param op1       first operator
396  * @param op2       second operator
397  * @param mode      node mode
398  * @return the created ia32 Shl node
399  */
400 ir_node *gen_Shl(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
401   return new_rd_ia32_Shl(dbg, current_ir_graph, block, op1, op2, mode);
402 }
403
404
405
406 /**
407  * Creates an ia32 Shr with immediate.
408  *
409  * @param dbg       firm dbg
410  * @param block     the block the new node should belong to
411  * @param expr_op   operator
412  * @param mode      node mode
413  * @return the created ia23 Shr_i node
414  */
415 ir_node *gen_imm_Shr(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
416   return new_rd_ia32_Shr_i(dbg, current_ir_graph, block, expr_op, mode);
417 }
418
419 /**
420  * Creates an ia32 Shr.
421  *
422  * @param dbg       firm node dbg
423  * @param block     the block the new node should belong to
424  * @param op1       first operator
425  * @param op2       second operator
426  * @param mode      node mode
427  * @return the created ia32 Shr node
428  */
429 ir_node *gen_Shr(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
430   return new_rd_ia32_Shr(dbg, current_ir_graph, block, op1, op2, mode);
431 }
432
433
434
435 /**
436  * Creates an ia32 Shrs with immediate.
437  *
438  * @param dbg       firm dbg
439  * @param block     the block the new node should belong to
440  * @param expr_op   operator
441  * @param mode      node mode
442  * @return the created ia23 Shrs_i node
443  */
444 ir_node *gen_imm_Shrs(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
445   return new_rd_ia32_Shrs_i(dbg, current_ir_graph, block, expr_op, mode);
446 }
447
448 /**
449  * Creates an ia32 Shrs.
450  *
451  * @param dbg       firm node dbg
452  * @param block     the block the new node should belong to
453  * @param op1       first operator
454  * @param op2       second operator
455  * @param mode      node mode
456  * @return the created ia32 Shrs node
457  */
458 ir_node *gen_Shrs(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
459   return new_rd_ia32_Shrs(dbg, current_ir_graph, block, op1, op2, mode);
460 }
461
462
463
464 /**
465  * Creates an ia32 Rot with immediate.
466  *
467  * @param dbg       firm dbg
468  * @param block     the block the new node should belong to
469  * @param expr_op   operator
470  * @param mode      node mode
471  * @return the created ia23 Rot_i node
472  */
473 ir_node *gen_imm_Rot(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
474   return new_rd_ia32_Rot_i(dbg, current_ir_graph, block, expr_op, mode);
475 }
476
477 /**
478  * Creates an ia32 Rot.
479  *
480  * @param dbg       firm node dbg
481  * @param block     the block the new node should belong to
482  * @param op1       first operator
483  * @param op2       second operator
484  * @param mode      node mode
485  * @return the created ia32 Rot node
486  */
487 ir_node *gen_Rot(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
488   return new_rd_ia32_Rot(dbg, current_ir_graph, block, op1, op2, mode);
489 }
490
491
492
493 /**
494  * Transforms a Minus node.
495  *
496  * @param mod     the debug module
497  * @param block   the block the new node should belong to
498  * @param node    the ir Minus node
499  * @param op      operator
500  * @param mode    node mode
501  * @return the created ia32 Minus node
502  */
503 ir_node *gen_Minus(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
504   if (is_ia32_Minus(op)) {
505     DBG((mod, LEVEL_1, "optimizing --(e) to e ..."));
506     return get_irn_n(op, 0);
507   }
508   else
509     return new_rd_ia32_Minus(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
510 }
511
512
513
514 /**
515  * Transforms a Conv node.
516  *
517  * @param mod     the debug module
518  * @param block   the block the new node should belong to
519  * @param node    the ir Conv node
520  * @param op      operator
521  * @param mode    node mode
522  * @return the created ia32 Conv node
523  */
524 ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
525   return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
526 }
527
528
529
530 /**
531  * Transforms commutative operations (op_Add, op_Mul, op_And, op_Or, op_Eor, op_Cmp)
532  * and non-commutative operations with com == 0 (op_Sub, op_Mod, op_Shl, op_Shr, op_Shrs, op_Rot)
533  *
534  * @param mod       the debug module
535  * @param block     the block node belongs to
536  * @param node      the node to transform
537  * @param op1       first operator
538  * @param op2       second operator
539  * @param mode      node mode
540  * @param com       flag if op is commutative
541  * @return the created assembler node
542  */
543 ir_node *gen_arith_Op(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op1, ir_node *op2, ir_mode *mode, int com) {
544   dbg_info *dbg     = get_irn_dbg_info(node);
545   ir_node *imm_op   = NULL;
546   ir_node *expr_op  = NULL;
547   ir_node *asm_node = NULL;
548
549 #define GENOP(a)  case iro_##a: asm_node = gen_##a(mod, dbg, block, op1, op2, mode); break
550 #define GENOPI(a) case iro_##a: asm_node = gen_imm_##a(dbg, block, expr_op, imm_op, mode); break
551
552   if (com)
553     imm_op  = get_immediate_op(op1, op2);
554   else
555     imm_op  = get_immediate_op(NULL, op2);
556
557   expr_op = get_expr_op(op1, op2);
558
559   /* TODO: Op(Imm, Imm) support */
560   if (is_Imm(op1) && is_Imm(op2)) {
561     DBG((mod, LEVEL_1, "found unexpected %s(Imm, Imm), creating binop ... ", get_irn_opname(node)));
562     imm_op = NULL;
563   }
564
565   DBG((mod, LEVEL_1, "(op1: %s -- op2: %s) ... ", get_irn_opname(op1), get_irn_opname(op2)));
566
567   if (imm_op) {
568     DBG((mod, LEVEL_1, "%s with imm ... ", get_irn_opname(node)));
569
570     switch(get_irn_opcode(node)) {
571       GENOPI(Add);
572       GENOPI(Mul);
573       GENOPI(And);
574       GENOPI(Or);
575       GENOPI(Eor);
576       GENOPI(Cmp);
577
578       GENOPI(Sub);
579       GENOPI(Mod);
580       GENOPI(Shl);
581       GENOPI(Shr);
582       GENOPI(Shrs);
583       GENOPI(Rot);
584       default:
585         assert("binop_i: THIS SHOULD NOT HAPPEN");
586     }
587
588     set_Immop_attr(asm_node, imm_op);
589   }
590   else {
591     DBG((mod, LEVEL_1, "%s as binop ... ", get_irn_opname(node)));
592
593     switch(get_irn_opcode(node)) {
594       GENOP(Add);
595       GENOP(Mul);
596       GENOP(And);
597       GENOP(Or);
598       GENOP(Eor);
599       GENOP(Cmp);
600
601       GENOP(Sub);
602       GENOP(Mod);
603       GENOP(Shl);
604       GENOP(Shr);
605       GENOP(Shrs);
606       GENOP(Rot);
607       default:
608         assert("binop: THIS SHOULD NOT HAPPEN");
609     }
610   }
611
612   return asm_node;
613 }
614
615
616
617 /**
618  * Transforms a Load.
619  *
620  * @param mod     the debug module
621  * @param block   the block the new node should belong to
622  * @param node    the ir Load node
623  * @param mode    node mode
624  * @return the created ia32 Load node
625  */
626 ir_node *gen_Load(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
627   return new_rd_ia32_Load(get_irn_dbg_info(node), current_ir_graph, block, get_Load_mem(node), get_Load_ptr(node), mode);
628 }
629
630
631
632 /**
633  * Transforms a Store.
634  *
635  * @param mod     the debug module
636  * @param block   the block the new node should belong to
637  * @param node    the ir Store node
638  * @param mode    node mode
639  * @return the created ia32 Store node
640  */
641 ir_node *gen_Store(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
642   return new_rd_ia32_Store(get_irn_dbg_info(node), current_ir_graph, block, get_Store_mem(node), get_Store_ptr(node), get_Store_value(node), mode);
643 }
644
645
646
647 /**
648  * Transforms the given firm node (and maybe some other related nodes)
649  * into one or more assembler nodes.
650  *
651  * @param node    the firm node
652  * @param env     the debug module
653  */
654 void transform_node(ir_node *node, void *env) {
655   firm_dbg_module_t *mod = (firm_dbg_module_t *)env;
656   opcode  code           = get_irn_opcode(node);
657   ir_node *asm_node      = NULL;
658   ir_node *block;
659   ir_mode *mode;
660
661   if (is_Block(node))
662     return;
663
664   block = get_nodes_block(node);
665   mode  = get_irn_mode(node);
666
667 #define BINOP_COM(a)   case iro_##a: asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 1); break
668 #define BINOP_NCOM(a)  case iro_##a: asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 0); break
669 #define UNOP(a)        case iro_##a: asm_node = gen_##a(mod, block, node, get_irn_n(node, 0), mode); break
670 #define GEN(a)         case iro_##a: asm_node = gen_##a(mod, block, node, mode); break
671 #define IGN(a)         case iro_##a: break
672
673   DBG((mod, LEVEL_1, "transforming node %s (%ld) ... ", get_irn_opname(node), get_irn_node_nr(node)));
674
675   switch (code) {
676     BINOP_COM(Add);
677     BINOP_COM(Mul);
678     BINOP_COM(And);
679     BINOP_COM(Or);
680     BINOP_COM(Eor);
681     BINOP_COM(Cmp);
682
683     BINOP_NCOM(Sub);
684     BINOP_NCOM(Mod);
685     BINOP_NCOM(Shl);
686     BINOP_NCOM(Shr);
687     BINOP_NCOM(Shrs);
688     BINOP_NCOM(Rot);
689 //    BINOP_ARITH_NCOM(DivMod);
690
691     UNOP(Minus);
692     UNOP(Conv);
693     GEN(Load);
694     GEN(Store);
695
696     IGN(Block);
697     IGN(Start);
698     IGN(End);
699   }
700
701   if (asm_node) {
702     exchange(node, asm_node);
703     DBG((mod, LEVEL_1, "created node %u\n", get_irn_node_nr(asm_node)));
704   }
705   else {
706     DBG((mod, LEVEL_1, "ignored\n"));
707   }
708 }