5e81df090a1c96fbd7ed092897f8242f9d492195
[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.
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 node
292  */
293 ir_node *gen_Max(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
294   return new_rd_ia32_Max(dbg, current_ir_graph, block, op1, op2, mode);
295 }
296
297
298
299 /**
300  * Creates an ia32 Min.
301  *
302  * @param dbg       firm dbg
303  * @param block     the block the new node should belong to
304  * @param expr_op   operator
305  * @param mode      node mode
306  * @return the created ia23 Min node
307  */
308 ir_node *gen_Min(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
309   return new_rd_ia32_Min(dbg, current_ir_graph, block, op1, op2, mode);
310 }
311
312
313
314 /**
315  * Creates an ia32 Cmp with immediate.
316  *
317  * @param dbg       firm dbg
318  * @param block     the block the new node should belong to
319  * @param expr_op   operator
320  * @param mode      node mode
321  * @return the created ia23 Cmp_i node
322  */
323 ir_node *gen_imm_Cmp(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
324   return new_rd_ia32_Cmp_i(dbg, current_ir_graph, block, expr_op, mode);
325 }
326
327 /**
328  * Creates an ia32 Cmp.
329  *
330  * @param dbg       firm node dbg
331  * @param block     the block the new node should belong to
332  * @param op1       first operator
333  * @param op2       second operator
334  * @param mode      node mode
335  * @return the created ia32 Cmp node
336  */
337 ir_node *gen_Cmp(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
338   return new_rd_ia32_Cmp(dbg, current_ir_graph, block, op1, op2, mode);
339 }
340
341
342
343 /**
344  * Creates an ia32 Sub with immediate.
345  *
346  * @param dbg       firm dbg
347  * @param block     the block the new node should belong to
348  * @param expr_op   operator
349  * @param mode      node mode
350  * @return the created ia23 Sub_i node
351  */
352 ir_node *gen_imm_Sub(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
353   ir_node *new_op;
354   tarval  *tv = get_Immop_tarval(const_op);
355   int     normal_sub = 0;
356   tarval_classification_t class_tv, class_negtv;
357
358   /* const_op: tarval or SymConst? */
359   if (tv) {
360     /* optimize tarvals */
361     class_tv    = classify_tarval(tv);
362     class_negtv = classify_tarval(tarval_neg(tv));
363
364     if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
365       new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
366     }
367     else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
368       new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
369     }
370     else
371       normal_sub = 1;
372   }
373   else
374     normal_sub = 1;
375
376   if (normal_sub)
377     new_op = new_rd_ia32_Sub_i(dbg, current_ir_graph, block, expr_op, mode);
378
379   return new_op;
380 }
381
382 /**
383  * Creates an ia32 Sub.
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 Sub node
391  */
392 ir_node *gen_Sub(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
393   ir_node *sub = NULL;
394
395   /* transform "const - expr" into "-expr + const" */
396   if (is_Imm(op1) && !is_Imm(op2)) {
397     DBG((mod, LEVEL_1, "optimizing c-e into -e+c ... "));
398
399     sub = new_rd_ia32_Minus(dbg, current_ir_graph, block, op2, mode);
400     sub = gen_imm_Add(dbg, block, sub, op1, mode);
401     set_Immop_attr(sub, op1);
402   }
403   else {
404     sub = new_rd_ia32_Sub(dbg, current_ir_graph, block, op1, op2, mode);
405   }
406
407   return sub;
408 }
409
410
411
412 /**
413  * Creates an ia32 Mod.
414  *
415  * @param dbg       firm node dbg
416  * @param block     the block the new node should belong to
417  * @param op1       first operator
418  * @param op2       second operator
419  * @param mode      node mode
420  * @return the created ia32 Mod node
421  */
422 ir_node *gen_Mod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
423   return new_rd_ia32_Mod(dbg, current_ir_graph, block, op1, op2, mode);
424 }
425
426
427
428 /**
429  * Creates an ia32 Div.
430  *
431  * @param dbg       firm node dbg
432  * @param block     the block the new node should belong to
433  * @param op1       first operator
434  * @param op2       second operator
435  * @param mode      node mode
436  * @return the created ia32 Div node
437  */
438 ir_node *gen_Div(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
439   return new_rd_ia32_Div(dbg, current_ir_graph, block, op1, op2, mode);
440 }
441
442
443
444 /**
445  * Creates an ia32 DivMod.
446  *
447  * @param dbg       firm node dbg
448  * @param block     the block the new node should belong to
449  * @param op1       first operator
450  * @param op2       second operator
451  * @param mode      node mode
452  * @return the created ia32 DivMod node
453  */
454 ir_node *gen_DivMod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
455   return new_rd_ia32_DivMod(dbg, current_ir_graph, block, op1, op2, mode);
456 }
457
458
459
460 /**
461  * Creates an ia32 Shl with immediate.
462  *
463  * @param dbg       firm dbg
464  * @param block     the block the new node should belong to
465  * @param expr_op   operator
466  * @param mode      node mode
467  * @return the created ia23 Shl_i node
468  */
469 ir_node *gen_imm_Shl(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
470   return new_rd_ia32_Shl_i(dbg, current_ir_graph, block, expr_op, mode);
471 }
472
473 /**
474  * Creates an ia32 Shl.
475  *
476  * @param dbg       firm node dbg
477  * @param block     the block the new node should belong to
478  * @param op1       first operator
479  * @param op2       second operator
480  * @param mode      node mode
481  * @return the created ia32 Shl node
482  */
483 ir_node *gen_Shl(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
484   return new_rd_ia32_Shl(dbg, current_ir_graph, block, op1, op2, mode);
485 }
486
487
488
489 /**
490  * Creates an ia32 Shr with immediate.
491  *
492  * @param dbg       firm dbg
493  * @param block     the block the new node should belong to
494  * @param expr_op   operator
495  * @param mode      node mode
496  * @return the created ia23 Shr_i node
497  */
498 ir_node *gen_imm_Shr(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
499   return new_rd_ia32_Shr_i(dbg, current_ir_graph, block, expr_op, mode);
500 }
501
502 /**
503  * Creates an ia32 Shr.
504  *
505  * @param dbg       firm node dbg
506  * @param block     the block the new node should belong to
507  * @param op1       first operator
508  * @param op2       second operator
509  * @param mode      node mode
510  * @return the created ia32 Shr node
511  */
512 ir_node *gen_Shr(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
513   return new_rd_ia32_Shr(dbg, current_ir_graph, block, op1, op2, mode);
514 }
515
516
517
518 /**
519  * Creates an ia32 Shrs with immediate.
520  *
521  * @param dbg       firm dbg
522  * @param block     the block the new node should belong to
523  * @param expr_op   operator
524  * @param mode      node mode
525  * @return the created ia23 Shrs_i node
526  */
527 ir_node *gen_imm_Shrs(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
528   return new_rd_ia32_Shrs_i(dbg, current_ir_graph, block, expr_op, mode);
529 }
530
531 /**
532  * Creates an ia32 Shrs.
533  *
534  * @param dbg       firm node dbg
535  * @param block     the block the new node should belong to
536  * @param op1       first operator
537  * @param op2       second operator
538  * @param mode      node mode
539  * @return the created ia32 Shrs node
540  */
541 ir_node *gen_Shrs(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
542   return new_rd_ia32_Shrs(dbg, current_ir_graph, block, op1, op2, mode);
543 }
544
545
546
547 /**
548  * Transforms commutative operations (op_Add, op_Mul, op_And, op_Or, op_Eor, op_Cmp)
549  * and non-commutative operations with com == 0 (op_Sub, op_Mod, op_Div, op_DivMod, op_Shl, op_Shr, op_Shrs)
550  *
551  * @param mod       the debug module
552  * @param block     the block node belongs to
553  * @param node      the node to transform
554  * @param op1       first operator
555  * @param op2       second operator
556  * @param mode      node mode
557  * @param com       flag if op is commutative
558  * @return the created assembler node
559  */
560 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) {
561   dbg_info *dbg      = get_irn_dbg_info(node);
562   ir_node  *imm_op   = NULL;
563   ir_node  *expr_op  = NULL;
564   ir_node  *asm_node = NULL;
565   opcode   opc       = get_irn_opcode(node);
566   ir_op    *op       = get_irn_op(node);
567
568 #define GENOP(a)  case iro_##a: asm_node = gen_##a(mod, dbg, block, op1, op2, mode); break
569 #define GENOPI(a) case iro_##a: asm_node = gen_imm_##a(dbg, block, expr_op, imm_op, mode); break
570
571   if (com)
572     imm_op  = get_immediate_op(op1, op2);
573   else
574     imm_op  = get_immediate_op(NULL, op2);
575
576   expr_op = get_expr_op(op1, op2);
577
578   /* TODO: Op(Imm, Imm) support */
579   if (is_Imm(op1) && is_Imm(op2)) {
580     DBG((mod, LEVEL_2, "found unexpected %s(Imm, Imm), creating binop ... ", get_irn_opname(node)));
581     imm_op = NULL;
582   }
583
584   /* On x86 there is only a DivMod operation, which
585      takes a register or a memory as argument (eax = eax DIV reg, edx = eax MOD reg)
586      Immediate is not possible, so we always generate "DIV reg" ops */
587   if (opc == iro_Div || opc == iro_Mod || opc == iro_DivMod) {
588     DBG((mod, LEVEL_2, "DIV imm not available, creating binop ... "));
589     imm_op = NULL;
590   }
591   else if (op == get_op_Min() || op == get_op_Max()) {
592     DBG((mod, LEVEL_2, "MIN/MAX imm not available, creating binop ... "));
593     imm_op = NULL;
594   }
595
596   DBG((mod, LEVEL_1, "(op1: %s -- op2: %s) ... ", get_irn_opname(op1), get_irn_opname(op2)));
597
598   if (imm_op) {
599     DBG((mod, LEVEL_1, "%s with imm ... ", get_irn_opname(node)));
600
601     switch(opc) {
602       GENOPI(Add);
603       GENOPI(Mul);
604       GENOPI(And);
605       GENOPI(Or);
606       GENOPI(Eor);
607       GENOPI(Cmp);
608
609       GENOPI(Sub);
610       GENOPI(Shl);
611       GENOPI(Shr);
612       GENOPI(Shrs);
613       default:
614         if (op == get_op_Mulh()) {
615           asm_node = gen_imm_Mulh(dbg, block, expr_op, imm_op, mode);
616         }
617         else
618           assert("binop_i: THIS SHOULD NOT HAPPEN");
619     }
620
621     set_Immop_attr(asm_node, imm_op);
622   }
623   else {
624     DBG((mod, LEVEL_1, "%s as binop ... ", get_irn_opname(node)));
625
626     switch(opc) {
627       GENOP(Add);
628       GENOP(Mul);
629       GENOP(And);
630       GENOP(Or);
631       GENOP(Eor);
632       GENOP(Cmp);
633
634       GENOP(Sub);
635       GENOP(Mod);
636       GENOP(Div);
637       GENOP(DivMod);
638       GENOP(Shl);
639       GENOP(Shr);
640       GENOP(Shrs);
641       default:
642         if (op == get_op_Mulh()) {
643           asm_node = gen_Mulh(mod, dbg, block, op1, op2, mode);
644         }
645         else if (op == get_op_Max()) {
646           asm_node = gen_Max(mod, dbg, block, op1, op2, mode);
647         }
648         else if (op == get_op_Min()) {
649           asm_node = gen_Min(mod, dbg, block, op1, op2, mode);
650         }
651         else
652           assert("binop: THIS SHOULD NOT HAPPEN");
653     }
654   }
655
656   return asm_node;
657 }
658
659
660
661 /**
662  * Transforms a Minus node.
663  *
664  * @param mod     the debug module
665  * @param block   the block the new node should belong to
666  * @param node    the ir Minus node
667  * @param op      operator
668  * @param mode    node mode
669  * @return the created ia32 Minus node
670  */
671 ir_node *gen_Minus(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
672   if (is_ia32_Minus(op)) {
673     DBG((mod, LEVEL_1, "optimizing --(e) to e ..."));
674     return get_irn_n(op, 0);
675   }
676   else
677     return new_rd_ia32_Minus(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
678 }
679
680
681
682 /**
683  * Transforms a Conv node.
684  *
685  * @param mod     the debug module
686  * @param block   the block the new node should belong to
687  * @param node    the ir Conv node
688  * @param op      operator
689  * @param mode    node mode
690  * @return the created ia32 Conv node
691  */
692 ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
693   return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
694 }
695
696
697
698 /**
699  * Transforms a Not node.
700  *
701  * @param mod     the debug module
702  * @param block   the block the new node should belong to
703  * @param node    the ir Not node
704  * @param op      operator
705  * @param mode    node mode
706  * @return the created ia32 Not node
707  */
708 ir_node *gen_Not(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
709   return new_rd_ia32_Not(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
710 }
711
712
713
714 /**
715  * Transforms an Abs node.
716  *
717  * @param mod     the debug module
718  * @param block   the block the new node should belong to
719  * @param node    the ir Abs node
720  * @param op      operator
721  * @param mode    node mode
722  * @return the created ia32 Abs node
723  */
724 ir_node *gen_Abs(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
725   return new_rd_ia32_Abs(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
726 }
727
728
729
730 /**
731  * Transforms a Load.
732  *
733  * @param mod     the debug module
734  * @param block   the block the new node should belong to
735  * @param node    the ir Load node
736  * @param mode    node mode
737  * @return the created ia32 Load node
738  */
739 ir_node *gen_Load(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
740   return new_rd_ia32_Load(get_irn_dbg_info(node), current_ir_graph, block, get_Load_mem(node), get_Load_ptr(node), mode);
741 }
742
743
744
745 /**
746  * Transforms a Store.
747  *
748  * @param mod     the debug module
749  * @param block   the block the new node should belong to
750  * @param node    the ir Store node
751  * @param mode    node mode
752  * @return the created ia32 Store node
753  */
754 ir_node *gen_Store(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
755   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);
756 }
757
758
759
760 /**
761  * Transforms a Call.
762  *
763  * @param mod     the debug module
764  * @param block   the block the new node should belong to
765  * @param node    the ir Call node
766  * @param dummy   mode doesn't matter
767  * @return the created ia32 Store node
768  */
769 ir_node *gen_Call(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *dummy) {
770   return new_rd_ia32_Call(get_irn_dbg_info(node), current_ir_graph, block, node);
771 }
772
773
774
775 /**
776  * Transforms the given firm node (and maybe some other related nodes)
777  * into one or more assembler nodes.
778  *
779  * @param node    the firm node
780  * @param env     the debug module
781  */
782 void transform_node(ir_node *node, void *env) {
783   firm_dbg_module_t *mod = (firm_dbg_module_t *)env;
784   opcode  code           = get_irn_opcode(node);
785   ir_node *asm_node      = NULL;
786   ir_node *block;
787   ir_mode *mode;
788
789   if (is_Block(node))
790     return;
791
792   block = get_nodes_block(node);
793   mode  = get_irn_mode(node);
794
795 #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
796 #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
797 #define UNOP(a)        case iro_##a: asm_node = gen_##a(mod, block, node, get_irn_n(node, 0), mode); break
798 #define GEN(a)         case iro_##a: asm_node = gen_##a(mod, block, node, mode); break
799 #define IGN(a)         case iro_##a: break
800 #define BAD(a)         case iro_##a: goto bad
801
802   DBG((mod, LEVEL_1, "transforming node %s (%ld) ... ", get_irn_opname(node), get_irn_node_nr(node)));
803
804   switch (code) {
805     BINOP_COM(Add);
806     BINOP_COM(Mul);
807     BINOP_COM(And);
808     BINOP_COM(Or);
809     BINOP_COM(Eor);
810     BINOP_COM(Cmp);
811
812     BINOP_NCOM(Sub);
813     BINOP_NCOM(Mod);
814     BINOP_NCOM(Div);
815     BINOP_NCOM(DivMod);
816     BINOP_NCOM(Shl);
817     BINOP_NCOM(Shr);
818     BINOP_NCOM(Shrs);
819
820     UNOP(Minus);
821     UNOP(Conv);
822     UNOP(Abs);
823     UNOP(Not);
824
825     GEN(Load);
826     GEN(Store);
827     GEN(Call);
828
829     IGN(Const);
830     IGN(SymConst);
831     IGN(Block);
832     IGN(Start);
833     IGN(End);
834     IGN(NoMem);
835     IGN(Phi);
836     IGN(Cond);
837     IGN(Jmp);
838     IGN(IJmp);
839     IGN(Proj);
840     IGN(Break);
841
842     BAD(Raise);
843     BAD(Sel);
844     BAD(InstOf);
845     BAD(Quot);
846     BAD(Cast);
847     BAD(Alloc);
848     BAD(Free);
849     BAD(Sync);
850     BAD(Tuple);
851     BAD(Id);
852     BAD(Bad);
853     BAD(Confirm);
854     BAD(Unknown);
855     BAD(Filter);
856     BAD(CallBegin);
857     BAD(EndReg);
858     BAD(EndExcept);
859     BAD(Mux);
860     BAD(CopyB);
861
862     default:
863       if (get_irn_op(node) == get_op_Mulh() ||
864           get_irn_op(node) == get_op_Max()  ||
865           get_irn_op(node) == get_op_Min())
866       {
867         asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 1);
868       }
869       break;
870 bad:
871     fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
872     assert(0);
873   }
874
875   if (asm_node) {
876     exchange(node, asm_node);
877     DBG((mod, LEVEL_1, "created node %u\n", get_irn_node_nr(asm_node)));
878   }
879   else {
880     DBG((mod, LEVEL_1, "ignored\n"));
881   }
882 }