added format string for code emitter
[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 "../arch/archop.h"     /* we need this for Min and Max nodes */
16 #include "transform.h"
17 #include "new_nodes.h"
18
19 extern ir_op *get_op_Mulh(void);
20
21 /* determine if one operator is an Imm */
22 ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
23   if (op1)
24     return is_Imm(op1) ? op1 : (is_Imm(op2) ? op2 : NULL);
25   else return is_Imm(op2) ? op2 : NULL;
26 }
27
28 /* determine if one operator is not an Imm */
29 ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
30   return !is_Imm(op1) ? op1 : (!is_Imm(op2) ? op2 : NULL);
31 }
32
33
34
35 /**
36  * Creates an ia32 Add with immediate.
37  *
38  * @param dbg       firm dbg
39  * @param block     the block the new node should belong to
40  * @param expr_op   operator
41  * @param mode      node mode
42  * @return the created ia23 Add_i node
43  */
44 ir_node *gen_imm_Add(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
45   ir_node *new_op;
46   tarval  *tv = get_Immop_tarval(const_op);
47   int     normal_add = 0;
48   tarval_classification_t class_tv, class_negtv;
49
50   /* const_op: tarval or SymConst? */
51   if (tv) {
52     /* optimize tarvals */
53     class_tv    = classify_tarval(tv);
54     class_negtv = classify_tarval(tarval_neg(tv));
55
56     if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
57       new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
58     }
59     else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == Sub */
60       new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
61     }
62     else
63       normal_add = 1;
64   }
65   else
66     normal_add = 1;
67
68   if (normal_add)
69     new_op = new_rd_ia32_Lea_i(dbg, current_ir_graph, block, expr_op, mode);
70
71   return new_op;
72 }
73
74 /**
75  * Creates an ia32 Add.
76  *
77  * @param dbg       firm node dbg
78  * @param block     the block the new node should belong to
79  * @param op1       first operator
80  * @param op2       second operator
81  * @param mode      node mode
82  * @return the created ia32 Add node
83  */
84 ir_node *gen_Add(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
85   /* try to optimize with LEA */
86   ir_node *shli_op = is_ia32_Shl_i(op1) ? op1 : (is_ia32_Shl_i(op2) ? op2 : NULL);
87   ir_node *expr_op = shli_op == op1 ? op2 : (shli_op == op2 ? op1 : NULL);
88   int normal_add   = 0;
89   ir_node *new_op;
90
91   if (shli_op) {
92     tarval *tv   = get_Immop_tarval(shli_op);
93     tarval *offs = NULL;
94     if (tv) {
95       switch (get_tarval_long(tv)) {
96         case 1:
97         case 2:
98         case 3:
99           // If the other operand of the LEA is an LEA_i (that means LEA ofs(%regop1)),
100           // we can skip it and transform the whole sequence into LEA ofs(%regop1, %regop2, shl_val),
101           if (is_ia32_Lea_i(expr_op)) {
102             offs = get_Immop_tarval(expr_op);
103             expr_op = get_irn_n(expr_op, 0);
104           }
105
106           new_op = new_rd_ia32_Lea(dbg, current_ir_graph, block, expr_op, get_irn_n(shli_op, 0), mode);
107           set_Immop_attr_tv(new_op, tv);
108
109           if (offs)
110             set_ia32_Lea_offs(new_op, offs);
111
112           break;
113         default:
114           normal_add = 1;
115           break;
116       }
117     }
118     else
119       normal_add = 1;
120   }
121   else
122     normal_add = 1;
123
124   if (normal_add) {
125     new_op = new_rd_ia32_Lea(dbg, current_ir_graph, block, op1, op2, mode);
126     set_Immop_attr_tv(new_op, get_tarval_one(mode_Iu));
127     set_ia32_Lea_offs(new_op, NULL);
128   }
129
130   return new_op;
131 }
132
133
134
135 /**
136  * Creates an ia32 Mul with immediate.
137  *
138  * @param dbg       firm dbg
139  * @param block     the block the new node should belong to
140  * @param expr_op   operator
141  * @param mode      node mode
142  * @return the created ia23 Mul_i node
143  */
144 ir_node *gen_imm_Mul(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
145   return new_rd_ia32_Mul_i(dbg, current_ir_graph, block, expr_op, mode);
146 }
147
148 /**
149  * Creates an ia32 Mul.
150  *
151  * @param dbg       firm node dbg
152  * @param block     the block the new node should belong to
153  * @param op1       first operator
154  * @param op2       second operator
155  * @param mode      node mode
156  * @return the created ia32 Mul node
157  */
158 ir_node *gen_Mul(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
159   return new_rd_ia32_Mul(dbg, current_ir_graph, block, op1, op2, mode);
160 }
161
162
163
164 /**
165  * Creates an ia32 Mulh with immediate.
166  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
167  * this result while Mul returns the lower 32 bit.
168  *
169  * @param dbg       firm dbg
170  * @param block     the block the new node should belong to
171  * @param expr_op   operator
172  * @param mode      node mode
173  * @return the created ia23 Mulh_i node
174  */
175 ir_node *gen_imm_Mulh(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
176   return new_rd_ia32_Mulh_i(dbg, current_ir_graph, block, expr_op, mode);
177 }
178
179 /**
180  * Creates an ia32 Mulh.
181  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
182  * this result while Mul returns the lower 32 bit.
183  *
184  * @param dbg       firm node dbg
185  * @param block     the block the new node should belong to
186  * @param op1       first operator
187  * @param op2       second operator
188  * @param mode      node mode
189  * @return the created ia32 Mulh node
190  */
191 ir_node *gen_Mulh(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
192   return new_rd_ia32_Mulh(dbg, current_ir_graph, block, op1, op2, mode);
193 }
194
195
196
197 /**
198  * Creates an ia32 And with immediate.
199  *
200  * @param dbg       firm dbg
201  * @param block     the block the new node should belong to
202  * @param expr_op   operator
203  * @param mode      node mode
204  * @return the created ia23 And_i node
205  */
206 ir_node *gen_imm_And(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
207   return new_rd_ia32_And_i(dbg, current_ir_graph, block, expr_op, mode);
208 }
209
210 /**
211  * Creates an ia32 And.
212  *
213  * @param dbg       firm node dbg
214  * @param block     the block the new node should belong to
215  * @param op1       first operator
216  * @param op2       second operator
217  * @param mode      node mode
218  * @return the created ia32 And node
219  */
220 ir_node *gen_And(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
221   return new_rd_ia32_And(dbg, current_ir_graph, block, op1, op2, mode);
222 }
223
224
225
226 /**
227  * Creates an ia32 Or with immediate.
228  *
229  * @param dbg       firm dbg
230  * @param block     the block the new node should belong to
231  * @param expr_op   operator
232  * @param mode      node mode
233  * @return the created ia23 Or_i node
234  */
235 ir_node *gen_imm_Or(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
236   return new_rd_ia32_Or_i(dbg, current_ir_graph, block, expr_op, mode);
237 }
238
239 /**
240  * Creates an ia32 Or.
241  *
242  * @param dbg       firm node dbg
243  * @param block     the block the new node should belong to
244  * @param op1       first operator
245  * @param op2       second operator
246  * @param mode      node mode
247  * @return the created ia32 Or node
248  */
249 ir_node *gen_Or(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
250   return new_rd_ia32_Or(dbg, current_ir_graph, block, op1, op2, mode);
251 }
252
253
254
255 /**
256  * Creates an ia32 Eor with immediate.
257  *
258  * @param dbg       firm dbg
259  * @param block     the block the new node should belong to
260  * @param expr_op   operator
261  * @param mode      node mode
262  * @return the created ia23 Eor_i node
263  */
264 ir_node *gen_imm_Eor(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
265   return new_rd_ia32_Eor_i(dbg, current_ir_graph, block, expr_op, mode);
266 }
267
268 /**
269  * Creates an ia32 Eor.
270  *
271  * @param dbg       firm node dbg
272  * @param block     the block the new node should belong to
273  * @param op1       first operator
274  * @param op2       second operator
275  * @param mode      node mode
276  * @return the created ia32 Eor node
277  */
278 ir_node *gen_Eor(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
279   return new_rd_ia32_Eor(dbg, current_ir_graph, block, op1, op2, mode);
280 }
281
282
283
284 /**
285  * Creates an ia32 Max with immediate.
286  *
287  * @param dbg       firm dbg
288  * @param block     the block the new node should belong to
289  * @param expr_op   operator
290  * @param mode      node mode
291  * @return the created ia23 Max_i node
292  */
293 ir_node *gen_imm_Max(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
294   return new_rd_ia32_Max_i(dbg, current_ir_graph, block, expr_op, mode);
295 }
296
297 /**
298  * Creates an ia32 Max.
299  *
300  * @param dbg       firm dbg
301  * @param block     the block the new node should belong to
302  * @param expr_op   operator
303  * @param mode      node mode
304  * @return the created ia23 Max node
305  */
306 ir_node *gen_Max(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
307   return new_rd_ia32_Max(dbg, current_ir_graph, block, op1, op2, mode);
308 }
309
310
311
312 /**
313  * Creates an ia32 Min with immediate.
314  *
315  * @param dbg       firm dbg
316  * @param block     the block the new node should belong to
317  * @param expr_op   operator
318  * @param mode      node mode
319  * @return the created ia23 Min_i node
320  */
321 ir_node *gen_imm_Min(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
322   return new_rd_ia32_Min_i(dbg, current_ir_graph, block, expr_op, mode);
323 }
324
325 /**
326  * Creates an ia32 Min.
327  *
328  * @param dbg       firm dbg
329  * @param block     the block the new node should belong to
330  * @param expr_op   operator
331  * @param mode      node mode
332  * @return the created ia23 Min node
333  */
334 ir_node *gen_Min(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
335   return new_rd_ia32_Min(dbg, current_ir_graph, block, op1, op2, mode);
336 }
337
338
339
340 /**
341  * Creates an ia32 Cmp with immediate.
342  *
343  * @param dbg       firm dbg
344  * @param block     the block the new node should belong to
345  * @param expr_op   operator
346  * @param mode      node mode
347  * @return the created ia23 Cmp_i node
348  */
349 ir_node *gen_imm_Cmp(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
350   return new_rd_ia32_Cmp_i(dbg, current_ir_graph, block, expr_op, mode);
351 }
352
353 /**
354  * Creates an ia32 Cmp.
355  *
356  * @param dbg       firm node dbg
357  * @param block     the block the new node should belong to
358  * @param op1       first operator
359  * @param op2       second operator
360  * @param mode      node mode
361  * @return the created ia32 Cmp node
362  */
363 ir_node *gen_Cmp(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
364   return new_rd_ia32_Cmp(dbg, current_ir_graph, block, op1, op2, mode);
365 }
366
367
368
369 /**
370  * Creates an ia32 Sub with immediate.
371  *
372  * @param dbg       firm dbg
373  * @param block     the block the new node should belong to
374  * @param expr_op   operator
375  * @param mode      node mode
376  * @return the created ia23 Sub_i node
377  */
378 ir_node *gen_imm_Sub(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
379   ir_node *new_op;
380   tarval  *tv = get_Immop_tarval(const_op);
381   int     normal_sub = 0;
382   tarval_classification_t class_tv, class_negtv;
383
384   /* const_op: tarval or SymConst? */
385   if (tv) {
386     /* optimize tarvals */
387     class_tv    = classify_tarval(tv);
388     class_negtv = classify_tarval(tarval_neg(tv));
389
390     if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
391       new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
392     }
393     else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
394       new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
395     }
396     else
397       normal_sub = 1;
398   }
399   else
400     normal_sub = 1;
401
402   if (normal_sub)
403     new_op = new_rd_ia32_Sub_i(dbg, current_ir_graph, block, expr_op, mode);
404
405   return new_op;
406 }
407
408 /**
409  * Creates an ia32 Sub.
410  *
411  * @param dbg       firm node dbg
412  * @param block     the block the new node should belong to
413  * @param op1       first operator
414  * @param op2       second operator
415  * @param mode      node mode
416  * @return the created ia32 Sub node
417  */
418 ir_node *gen_Sub(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
419   ir_node *sub = NULL;
420
421   /* transform "const - expr" into "-expr + const" */
422   if (is_Imm(op1) && !is_Imm(op2)) {
423     DBG((mod, LEVEL_1, "optimizing c-e into -e+c ... "));
424
425     sub = new_rd_ia32_Minus(dbg, current_ir_graph, block, op2, mode);
426     sub = gen_imm_Add(dbg, block, sub, op1, mode);
427     set_Immop_attr(sub, op1);
428   }
429   else {
430     sub = new_rd_ia32_Sub(dbg, current_ir_graph, block, op1, op2, mode);
431   }
432
433   return sub;
434 }
435
436
437
438 /**
439  * Creates an ia32 Mod with immediate.
440  *
441  * @param dbg       firm dbg
442  * @param block     the block the new node should belong to
443  * @param expr_op   operator
444  * @param mode      node mode
445  * @return the created ia23 Mod_i node
446  */
447 ir_node *gen_imm_Mod(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
448   return new_rd_ia32_Mod_i(dbg, current_ir_graph, block, expr_op, mode);
449 }
450
451 /**
452  * Creates an ia32 Mod.
453  *
454  * @param dbg       firm node dbg
455  * @param block     the block the new node should belong to
456  * @param op1       first operator
457  * @param op2       second operator
458  * @param mode      node mode
459  * @return the created ia32 Mod node
460  */
461 ir_node *gen_Mod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
462   return new_rd_ia32_Mod(dbg, current_ir_graph, block, op1, op2, mode);
463 }
464
465
466
467 /**
468  * Creates an ia32 Div with immediate.
469  *
470  * @param dbg       firm dbg
471  * @param block     the block the new node should belong to
472  * @param expr_op   operator
473  * @param mode      node mode
474  * @return the created ia23 Div_i node
475  */
476 ir_node *gen_imm_Div(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
477   return new_rd_ia32_Div_i(dbg, current_ir_graph, block, expr_op, mode);
478 }
479
480 /**
481  * Creates an ia32 Div.
482  *
483  * @param dbg       firm node dbg
484  * @param block     the block the new node should belong to
485  * @param op1       first operator
486  * @param op2       second operator
487  * @param mode      node mode
488  * @return the created ia32 Div node
489  */
490 ir_node *gen_Div(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
491   return new_rd_ia32_Div(dbg, current_ir_graph, block, op1, op2, mode);
492 }
493
494
495
496 /**
497  * Creates an ia32 DivMod with immediate.
498  *
499  * @param dbg       firm dbg
500  * @param block     the block the new node should belong to
501  * @param expr_op   operator
502  * @param mode      node mode
503  * @return the created ia23 DivMod_i node
504  */
505 ir_node *gen_imm_DivMod(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
506   return new_rd_ia32_DivMod_i(dbg, current_ir_graph, block, expr_op, mode);
507 }
508
509 /**
510  * Creates an ia32 DivMod.
511  *
512  * @param dbg       firm node dbg
513  * @param block     the block the new node should belong to
514  * @param op1       first operator
515  * @param op2       second operator
516  * @param mode      node mode
517  * @return the created ia32 DivMod node
518  */
519 ir_node *gen_DivMod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
520   return new_rd_ia32_DivMod(dbg, current_ir_graph, block, op1, op2, mode);
521 }
522
523
524
525 /**
526  * Creates an ia32 Shl with immediate.
527  *
528  * @param dbg       firm dbg
529  * @param block     the block the new node should belong to
530  * @param expr_op   operator
531  * @param mode      node mode
532  * @return the created ia23 Shl_i node
533  */
534 ir_node *gen_imm_Shl(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
535   return new_rd_ia32_Shl_i(dbg, current_ir_graph, block, expr_op, mode);
536 }
537
538 /**
539  * Creates an ia32 Shl.
540  *
541  * @param dbg       firm node dbg
542  * @param block     the block the new node should belong to
543  * @param op1       first operator
544  * @param op2       second operator
545  * @param mode      node mode
546  * @return the created ia32 Shl node
547  */
548 ir_node *gen_Shl(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
549   return new_rd_ia32_Shl(dbg, current_ir_graph, block, op1, op2, mode);
550 }
551
552
553
554 /**
555  * Creates an ia32 Shr with immediate.
556  *
557  * @param dbg       firm dbg
558  * @param block     the block the new node should belong to
559  * @param expr_op   operator
560  * @param mode      node mode
561  * @return the created ia23 Shr_i node
562  */
563 ir_node *gen_imm_Shr(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
564   return new_rd_ia32_Shr_i(dbg, current_ir_graph, block, expr_op, mode);
565 }
566
567 /**
568  * Creates an ia32 Shr.
569  *
570  * @param dbg       firm node dbg
571  * @param block     the block the new node should belong to
572  * @param op1       first operator
573  * @param op2       second operator
574  * @param mode      node mode
575  * @return the created ia32 Shr node
576  */
577 ir_node *gen_Shr(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
578   return new_rd_ia32_Shr(dbg, current_ir_graph, block, op1, op2, mode);
579 }
580
581
582
583 /**
584  * Creates an ia32 Shrs with immediate.
585  *
586  * @param dbg       firm dbg
587  * @param block     the block the new node should belong to
588  * @param expr_op   operator
589  * @param mode      node mode
590  * @return the created ia23 Shrs_i node
591  */
592 ir_node *gen_imm_Shrs(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
593   return new_rd_ia32_Shrs_i(dbg, current_ir_graph, block, expr_op, mode);
594 }
595
596 /**
597  * Creates an ia32 Shrs.
598  *
599  * @param dbg       firm node dbg
600  * @param block     the block the new node should belong to
601  * @param op1       first operator
602  * @param op2       second operator
603  * @param mode      node mode
604  * @return the created ia32 Shrs node
605  */
606 ir_node *gen_Shrs(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
607   return new_rd_ia32_Shrs(dbg, current_ir_graph, block, op1, op2, mode);
608 }
609
610
611
612 /**
613  * Creates an ia32 Rot with immediate.
614  *
615  * @param dbg       firm dbg
616  * @param block     the block the new node should belong to
617  * @param expr_op   operator
618  * @param mode      node mode
619  * @return the created ia23 Rot_i node
620  */
621 ir_node *gen_imm_Rot(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
622   return new_rd_ia32_Rot_i(dbg, current_ir_graph, block, expr_op, mode);
623 }
624
625 /**
626  * Creates an ia32 Rot.
627  *
628  * @param dbg       firm node dbg
629  * @param block     the block the new node should belong to
630  * @param op1       first operator
631  * @param op2       second operator
632  * @param mode      node mode
633  * @return the created ia32 Rot node
634  */
635 ir_node *gen_Rot(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
636   return new_rd_ia32_Rot(dbg, current_ir_graph, block, op1, op2, mode);
637 }
638
639
640
641 /**
642  * Transforms commutative operations (op_Add, op_Mul, op_And, op_Or, op_Eor, op_Cmp)
643  * and non-commutative operations with com == 0 (op_Sub, op_Mod, op_Div, op_DivMod, op_Shl, op_Shr, op_Shrs, op_Rot)
644  *
645  * @param mod       the debug module
646  * @param block     the block node belongs to
647  * @param node      the node to transform
648  * @param op1       first operator
649  * @param op2       second operator
650  * @param mode      node mode
651  * @param com       flag if op is commutative
652  * @return the created assembler node
653  */
654 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) {
655   dbg_info *dbg     = get_irn_dbg_info(node);
656   ir_node *imm_op   = NULL;
657   ir_node *expr_op  = NULL;
658   ir_node *asm_node = NULL;
659
660 #define GENOP(a)  case iro_##a: asm_node = gen_##a(mod, dbg, block, op1, op2, mode); break
661 #define GENOPI(a) case iro_##a: asm_node = gen_imm_##a(dbg, block, expr_op, imm_op, mode); break
662
663   if (com)
664     imm_op  = get_immediate_op(op1, op2);
665   else
666     imm_op  = get_immediate_op(NULL, op2);
667
668   expr_op = get_expr_op(op1, op2);
669
670   /* TODO: Op(Imm, Imm) support */
671   if (is_Imm(op1) && is_Imm(op2)) {
672     DBG((mod, LEVEL_1, "found unexpected %s(Imm, Imm), creating binop ... ", get_irn_opname(node)));
673     imm_op = NULL;
674   }
675
676   DBG((mod, LEVEL_1, "(op1: %s -- op2: %s) ... ", get_irn_opname(op1), get_irn_opname(op2)));
677
678   if (imm_op) {
679     DBG((mod, LEVEL_1, "%s with imm ... ", get_irn_opname(node)));
680
681     switch(get_irn_opcode(node)) {
682       GENOPI(Add);
683       GENOPI(Mul);
684       GENOPI(And);
685       GENOPI(Or);
686       GENOPI(Eor);
687       GENOPI(Cmp);
688
689       GENOPI(Sub);
690       GENOPI(Mod);
691       GENOPI(Div);
692       GENOPI(DivMod);
693       GENOPI(Shl);
694       GENOPI(Shr);
695       GENOPI(Shrs);
696       GENOPI(Rot);
697       default:
698         if (get_irn_op(node) == get_op_Mulh()) {
699           asm_node = gen_imm_Mulh(dbg, block, expr_op, imm_op, mode);
700         }
701         else if (get_irn_op(node) == get_op_Max()) {
702           asm_node = gen_imm_Max(dbg, block, expr_op, imm_op, mode);
703         }
704         else if (get_irn_op(node) == get_op_Min()) {
705           asm_node = gen_imm_Min(dbg, block, expr_op, imm_op, mode);
706         }
707         else
708           assert("binop_i: THIS SHOULD NOT HAPPEN");
709     }
710
711     set_Immop_attr(asm_node, imm_op);
712   }
713   else {
714     DBG((mod, LEVEL_1, "%s as binop ... ", get_irn_opname(node)));
715
716     switch(get_irn_opcode(node)) {
717       GENOP(Add);
718       GENOP(Mul);
719       GENOP(And);
720       GENOP(Or);
721       GENOP(Eor);
722       GENOP(Cmp);
723
724       GENOP(Sub);
725       GENOP(Mod);
726       GENOP(Div);
727       GENOP(DivMod);
728       GENOP(Shl);
729       GENOP(Shr);
730       GENOP(Shrs);
731       GENOP(Rot);
732       default:
733         if (get_irn_op(node) == get_op_Mulh()) {
734           asm_node = gen_Mulh(mod, dbg, block, op1, op2, mode);
735         }
736         else if (get_irn_op(node) == get_op_Max()) {
737           asm_node = gen_Max(mod, dbg, block, op1, op2, mode);
738         }
739         else if (get_irn_op(node) == get_op_Min()) {
740           asm_node = gen_Min(mod, dbg, block, op1, op2, mode);
741         }
742         else
743           assert("binop: THIS SHOULD NOT HAPPEN");
744     }
745   }
746
747   return asm_node;
748 }
749
750
751
752 /**
753  * Transforms a Minus node.
754  *
755  * @param mod     the debug module
756  * @param block   the block the new node should belong to
757  * @param node    the ir Minus node
758  * @param op      operator
759  * @param mode    node mode
760  * @return the created ia32 Minus node
761  */
762 ir_node *gen_Minus(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
763   if (is_ia32_Minus(op)) {
764     DBG((mod, LEVEL_1, "optimizing --(e) to e ..."));
765     return get_irn_n(op, 0);
766   }
767   else
768     return new_rd_ia32_Minus(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
769 }
770
771
772
773 /**
774  * Transforms a Conv node.
775  *
776  * @param mod     the debug module
777  * @param block   the block the new node should belong to
778  * @param node    the ir Conv node
779  * @param op      operator
780  * @param mode    node mode
781  * @return the created ia32 Conv node
782  */
783 ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
784   return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
785 }
786
787
788
789 /**
790  * Transforms a Not node.
791  *
792  * @param mod     the debug module
793  * @param block   the block the new node should belong to
794  * @param node    the ir Not node
795  * @param op      operator
796  * @param mode    node mode
797  * @return the created ia32 Not node
798  */
799 ir_node *gen_Not(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
800   return new_rd_ia32_Not(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
801 }
802
803
804
805 /**
806  * Transforms an Abs node.
807  *
808  * @param mod     the debug module
809  * @param block   the block the new node should belong to
810  * @param node    the ir Abs node
811  * @param op      operator
812  * @param mode    node mode
813  * @return the created ia32 Abs node
814  */
815 ir_node *gen_Abs(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
816   return new_rd_ia32_Abs(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
817 }
818
819
820
821 /**
822  * Transforms a Load.
823  *
824  * @param mod     the debug module
825  * @param block   the block the new node should belong to
826  * @param node    the ir Load node
827  * @param mode    node mode
828  * @return the created ia32 Load node
829  */
830 ir_node *gen_Load(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
831   return new_rd_ia32_Load(get_irn_dbg_info(node), current_ir_graph, block, get_Load_mem(node), get_Load_ptr(node), mode);
832 }
833
834
835
836 /**
837  * Transforms a Store.
838  *
839  * @param mod     the debug module
840  * @param block   the block the new node should belong to
841  * @param node    the ir Store node
842  * @param mode    node mode
843  * @return the created ia32 Store node
844  */
845 ir_node *gen_Store(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
846   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);
847 }
848
849
850
851 /**
852  * Transforms a Call.
853  *
854  * @param mod     the debug module
855  * @param block   the block the new node should belong to
856  * @param node    the ir Call node
857  * @param dummy   mode doesn't matter
858  * @return the created ia32 Store node
859  */
860 ir_node *gen_Call(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *dummy) {
861   return new_rd_ia32_Call(get_irn_dbg_info(node), current_ir_graph, block, node);
862 }
863
864
865
866 /**
867  * Transforms the given firm node (and maybe some other related nodes)
868  * into one or more assembler nodes.
869  *
870  * @param node    the firm node
871  * @param env     the debug module
872  */
873 void transform_node(ir_node *node, void *env) {
874   firm_dbg_module_t *mod = (firm_dbg_module_t *)env;
875   opcode  code           = get_irn_opcode(node);
876   ir_node *asm_node      = NULL;
877   ir_node *block;
878   ir_mode *mode;
879
880   if (is_Block(node))
881     return;
882
883   block = get_nodes_block(node);
884   mode  = get_irn_mode(node);
885
886 #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
887 #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
888 #define UNOP(a)        case iro_##a: asm_node = gen_##a(mod, block, node, get_irn_n(node, 0), mode); break
889 #define GEN(a)         case iro_##a: asm_node = gen_##a(mod, block, node, mode); break
890 #define IGN(a)         case iro_##a: break
891 #define BAD(a)         case iro_##a: goto bad
892
893   DBG((mod, LEVEL_1, "transforming node %s (%ld) ... ", get_irn_opname(node), get_irn_node_nr(node)));
894
895   switch (code) {
896     BINOP_COM(Add);
897     BINOP_COM(Mul);
898     BINOP_COM(And);
899     BINOP_COM(Or);
900     BINOP_COM(Eor);
901     BINOP_COM(Cmp);
902
903     BINOP_NCOM(Sub);
904     BINOP_NCOM(Mod);
905     BINOP_NCOM(Div);
906     BINOP_NCOM(DivMod);
907     BINOP_NCOM(Shl);
908     BINOP_NCOM(Shr);
909     BINOP_NCOM(Shrs);
910     BINOP_NCOM(Rot);
911
912     UNOP(Minus);
913     UNOP(Conv);
914     UNOP(Abs);
915     UNOP(Not);
916
917     GEN(Load);
918     GEN(Store);
919     GEN(Call);
920
921     IGN(Const);
922     IGN(SymConst);
923     IGN(Block);
924     IGN(Start);
925     IGN(End);
926     IGN(NoMem);
927     IGN(Phi);
928     IGN(Cond);
929     IGN(Jmp);
930     IGN(IJmp);
931     IGN(Proj);
932     IGN(Break);
933
934     BAD(Raise);
935     BAD(Sel);
936     BAD(InstOf);
937     BAD(Quot);
938     BAD(Cast);
939     BAD(Alloc);
940     BAD(Free);
941     BAD(Sync);
942     BAD(Tuple);
943     BAD(Id);
944     BAD(Bad);
945     BAD(Confirm);
946     BAD(Unknown);
947     BAD(Filter);
948     BAD(CallBegin);
949     BAD(EndReg);
950     BAD(EndExcept);
951     BAD(Mux);
952     BAD(CopyB);
953
954     default:
955       if (get_irn_op(node) == get_op_Mulh() ||
956           get_irn_op(node) == get_op_Max()  ||
957           get_irn_op(node) == get_op_Min())
958       {
959         asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 1);
960       }
961       break;
962 bad:
963     fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
964     assert(0);
965   }
966
967   if (asm_node) {
968     exchange(node, asm_node);
969     DBG((mod, LEVEL_1, "created node %u\n", get_irn_node_nr(asm_node)));
970   }
971   else {
972     DBG((mod, LEVEL_1, "ignored\n"));
973   }
974 }