ia32 isa implementation
[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 "ircons.h"
10 #include "dbginfo.h"
11 #include "irop_t.h"
12 #include "debug.h"
13
14 #include "ia32_nodes_attr.h"
15 #include "../arch/archop.h"     /* we need this for Min and Max nodes */
16 #include "ia32_transform.h"
17 #include "ia32_new_nodes.h"
18
19 extern ir_op *get_op_Mulh(void);
20
21 /* determine if one operator is an Imm */
22 static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
23   if (op1)
24     return is_ia32_Const(op1) ? op1 : (is_ia32_Const(op2) ? op2 : NULL);
25   else return is_ia32_Const(op2) ? op2 : NULL;
26 }
27
28 /* determine if one operator is not an Imm */
29 static ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
30   return !is_ia32_Const(op1) ? op1 : (!is_ia32_Const(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 static ir_node *gen_imm_Add(firm_dbg_module_t *mod, 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_ia32_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       DBG((mod, LEVEL_2, "optimizing Add(1) to Inc ... "));
58       new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
59     }
60     else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
61       DBG((mod, LEVEL_2, "optimizing Add(-1) to Dec ... "));
62       new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
63     }
64     else
65       normal_add = 1;
66   }
67   else
68     normal_add = 1;
69
70   if (normal_add)
71     new_op = new_rd_ia32_Lea_i(dbg, current_ir_graph, block, expr_op, mode);
72
73   return new_op;
74 }
75
76 /**
77  * Creates an ia32 Add.
78  *
79  * @param dbg       firm node dbg
80  * @param block     the block the new node should belong to
81  * @param op1       first operator
82  * @param op2       second operator
83  * @param mode      node mode
84  * @return the created ia32 Add node
85  */
86 static ir_node *gen_Add(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
87   /* try to optimize with LEA */
88   ir_node *shli_op = is_ia32_Shl_i(op1) ? op1 : (is_ia32_Shl_i(op2) ? op2 : NULL);
89   ir_node *expr_op = shli_op == op1 ? op2 : (shli_op == op2 ? op1 : NULL);
90   int normal_add   = 0;
91   ir_node *new_op;
92
93   if (shli_op) {
94     tarval *tv   = get_ia32_Immop_tarval(shli_op);
95     tarval *offs = NULL;
96     if (tv) {
97       switch (get_tarval_long(tv)) {
98         case 1:
99         case 2:
100         case 3:
101           // If the other operand of the LEA is an LEA_i (that means LEA ofs(%regop1)),
102           // we can skip it and transform the whole sequence into LEA ofs(%regop1, %regop2, shl_val),
103           if (is_ia32_Lea_i(expr_op)) {
104             offs    = get_ia32_Immop_tarval(expr_op);
105             expr_op = get_irn_n(expr_op, 0);
106           }
107
108           new_op = new_rd_ia32_Lea(dbg, current_ir_graph, block, expr_op, get_irn_n(shli_op, 0), mode);
109           set_ia32_Immop_tarval(new_op, tv);
110           set_ia32_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_ia32_Immop_tarval(new_op, get_tarval_one(mode_Iu));
127     set_ia32_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 static ir_node *gen_imm_Mul(firm_dbg_module_t *mod, 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 static ir_node *gen_imm_Mulh(firm_dbg_module_t *mod, 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 static 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 static ir_node *gen_imm_And(firm_dbg_module_t *mod, 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 static 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 static ir_node *gen_imm_Or(firm_dbg_module_t *mod, 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 static 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 static ir_node *gen_imm_Eor(firm_dbg_module_t *mod, 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 static 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 static 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 static 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 static ir_node *gen_imm_Cmp(firm_dbg_module_t *mod, 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 static 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 static ir_node *gen_imm_Sub(firm_dbg_module_t *mod, 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_ia32_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       DBG((mod, LEVEL_2, "optimizing Sub(1) to Dec ... "));
366       new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
367     }
368     else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
369       DBG((mod, LEVEL_2, "optimizing Sub(-1) to Inc ... "));
370       new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
371     }
372     else
373       normal_sub = 1;
374   }
375   else
376     normal_sub = 1;
377
378   if (normal_sub)
379     new_op = new_rd_ia32_Sub_i(dbg, current_ir_graph, block, expr_op, mode);
380
381   return new_op;
382 }
383
384 /**
385  * Creates an ia32 Sub.
386  *
387  * @param dbg       firm node dbg
388  * @param block     the block the new node should belong to
389  * @param op1       first operator
390  * @param op2       second operator
391  * @param mode      node mode
392  * @return the created ia32 Sub node
393  */
394 static ir_node *gen_Sub(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
395   return new_rd_ia32_Sub(dbg, current_ir_graph, block, op1, op2, mode);
396 }
397
398
399
400 /**
401  * Creates an ia32 Mod.
402  *
403  * @param dbg       firm node dbg
404  * @param block     the block the new node should belong to
405  * @param op1       first operator
406  * @param op2       second operator
407  * @param mode      node mode
408  * @return the created ia32 Mod node
409  */
410 static ir_node *gen_Mod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *mem, ir_node *op1, ir_node *op2, ir_mode *mode) {
411   return new_rd_ia32_DivMod(dbg, current_ir_graph, block, mem, op1, op2, flavour_Mod, mode);
412 }
413
414
415
416 /**
417  * Creates an ia32 Div.
418  *
419  * @param dbg       firm node dbg
420  * @param block     the block the new node should belong to
421  * @param op1       first operator
422  * @param op2       second operator
423  * @param mode      node mode
424  * @return the created ia32 Div node
425  */
426 static ir_node *gen_Div(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *mem, ir_node *op1, ir_node *op2, ir_mode *mode) {
427   return new_rd_ia32_DivMod(dbg, current_ir_graph, block, mem, op1, op2, flavour_Div, mode);
428 }
429
430
431
432 /**
433  * Creates an ia32 DivMod.
434  *
435  * @param dbg       firm node dbg
436  * @param block     the block the new node should belong to
437  * @param op1       first operator
438  * @param op2       second operator
439  * @param mode      node mode
440  * @return the created ia32 DivMod node
441  */
442 static ir_node *gen_DivMod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *mem, ir_node *op1, ir_node *op2, ir_mode *mode) {
443   return new_rd_ia32_DivMod(dbg, current_ir_graph, block, mem, op1, op2, flavour_DivMod, mode);
444 }
445
446
447
448 /**
449  * Creates an ia32 Shl with immediate.
450  *
451  * @param dbg       firm dbg
452  * @param block     the block the new node should belong to
453  * @param expr_op   operator
454  * @param mode      node mode
455  * @return the created ia23 Shl_i node
456  */
457 static ir_node *gen_imm_Shl(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
458   return new_rd_ia32_Shl_i(dbg, current_ir_graph, block, expr_op, mode);
459 }
460
461 /**
462  * Creates an ia32 Shl.
463  *
464  * @param dbg       firm node dbg
465  * @param block     the block the new node should belong to
466  * @param op1       first operator
467  * @param op2       second operator
468  * @param mode      node mode
469  * @return the created ia32 Shl node
470  */
471 static ir_node *gen_Shl(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
472   return new_rd_ia32_Shl(dbg, current_ir_graph, block, op1, op2, mode);
473 }
474
475
476
477 /**
478  * Creates an ia32 Shr with immediate.
479  *
480  * @param dbg       firm dbg
481  * @param block     the block the new node should belong to
482  * @param expr_op   operator
483  * @param mode      node mode
484  * @return the created ia23 Shr_i node
485  */
486 static ir_node *gen_imm_Shr(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
487   return new_rd_ia32_Shr_i(dbg, current_ir_graph, block, expr_op, mode);
488 }
489
490 /**
491  * Creates an ia32 Shr.
492  *
493  * @param dbg       firm node dbg
494  * @param block     the block the new node should belong to
495  * @param op1       first operator
496  * @param op2       second operator
497  * @param mode      node mode
498  * @return the created ia32 Shr node
499  */
500 static ir_node *gen_Shr(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
501   return new_rd_ia32_Shr(dbg, current_ir_graph, block, op1, op2, mode);
502 }
503
504
505
506 /**
507  * Creates an ia32 Shrs with immediate.
508  *
509  * @param dbg       firm dbg
510  * @param block     the block the new node should belong to
511  * @param expr_op   operator
512  * @param mode      node mode
513  * @return the created ia23 Shrs_i node
514  */
515 static ir_node *gen_imm_Shrs(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
516   return new_rd_ia32_Shrs_i(dbg, current_ir_graph, block, expr_op, mode);
517 }
518
519 /**
520  * Creates an ia32 Shrs.
521  *
522  * @param dbg       firm node dbg
523  * @param block     the block the new node should belong to
524  * @param op1       first operator
525  * @param op2       second operator
526  * @param mode      node mode
527  * @return the created ia32 Shrs node
528  */
529 static ir_node *gen_Shrs(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
530   return new_rd_ia32_Shrs(dbg, current_ir_graph, block, op1, op2, mode);
531 }
532
533
534
535 /**
536  * Creates an ia32 RotL.
537  *
538  * @param dbg       firm node dbg
539  * @param block     the block the new node should belong to
540  * @param op1       first operator
541  * @param op2       second operator
542  * @param mode      node mode
543  * @return the created ia32 RotL node
544  */
545 static ir_node *gen_RotL(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
546   return new_rd_ia32_RotL(dbg, current_ir_graph, block, op1, op2, mode);
547 }
548
549
550
551 /**
552  * Creates an ia32 RotR.
553  * NOTE: There is no RotR with immediate because this would always be a RotL
554  *       "imm-mode_size_bits" which can be pre-calculated.
555  *
556  * @param dbg       firm node dbg
557  * @param block     the block the new node should belong to
558  * @param op1       first operator
559  * @param op2       second operator
560  * @param mode      node mode
561  * @return the created ia32 RotR node
562  */
563 static ir_node *gen_RotR(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
564   return new_rd_ia32_RotR(dbg, current_ir_graph, block, op1, op2, mode);
565 }
566
567
568
569 /**
570  * Transforms a Rot with immediate into an ia32 RotL with immediate
571  * as the Firm Rot is a RotL (see NOTE on RotR with immediate above).
572  *
573  * @param dbg       firm node dbg
574  * @param block     the block the new node should belong to
575  * @param op1       first operator
576  * @param op2       second operator
577  * @param mode      node mode
578  * @return the created ia32 RotL node
579  */
580 static ir_node *gen_imm_Rot(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) {
581   return new_rd_ia32_RotL_i(dbg, current_ir_graph, block, expr_op, mode);
582 }
583
584 /**
585  * Creates an ia32 RotR or RotL (depending on the found pattern).
586  *
587  * @param dbg       firm node dbg
588  * @param block     the block the new node should belong to
589  * @param op1       first operator
590  * @param op2       second operator
591  * @param mode      node mode
592  * @return the created ia32 RotL or RotR node
593  */
594 static ir_node *gen_Rot(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
595   ir_node *rotate = NULL;
596
597   /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
598      operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
599      that means we can create a RotR instead of an Add and a RotL */
600
601   if (is_ia32_Add_i(op2)) {
602     ir_node *minus = get_irn_n(op2, 0); // is there an op_Minus?
603
604     if (is_ia32_Minus(minus)) {
605       tarval *tv = get_ia32_Immop_tarval(op2);
606       long bits  = get_mode_size_bits(mode);
607
608       if (tarval_is_long(tv) && get_tarval_long(tv) == bits) {
609         DBG((mod, LEVEL_1, "optimizing RotL into RotR ... "));
610         rotate = gen_RotR(mod, dbg, block, op1, get_irn_n(minus, 0), mode);
611       }
612     }
613   }
614
615   if (!rotate)
616     rotate = gen_RotL(mod, dbg, block, op1, op2, mode);
617
618   return rotate;
619 }
620
621
622
623 /**
624  * Transforms commutative operations (op_Add, op_Mul, op_And, op_Or, op_Eor, op_Cmp)
625  * and non-commutative operations with com == 0 (op_Sub, op_Shl, op_Shr, op_Shrs, op_Rot)
626  *
627  * @param mod       the debug module
628  * @param block     the block node belongs to
629  * @param node      the node to transform
630  * @param op1       first operator
631  * @param op2       second operator
632  * @param mode      node mode
633  * @param com       flag if op is commutative
634  * @return the created assembler node
635  */
636 static 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) {
637   dbg_info *dbg      = get_irn_dbg_info(node);
638   ir_node  *imm_op   = NULL;
639   ir_node  *expr_op  = NULL;
640   ir_node  *asm_node = NULL;
641   opcode   opc       = get_irn_opcode(node);
642   ir_op    *op       = get_irn_op(node);
643
644 #define GENOP(a)  case iro_##a: asm_node = gen_##a(mod, dbg, block, op1, op2, mode); break
645 #define GENOPI(a) case iro_##a: asm_node = gen_imm_##a(mod, dbg, block, expr_op, imm_op, mode); break
646
647   if (com)
648     imm_op  = get_immediate_op(op1, op2);
649   else
650     imm_op  = get_immediate_op(NULL, op2);
651
652   expr_op = get_expr_op(op1, op2);
653
654   /* TODO: Op(Const, Const) support */
655   if (is_ia32_Const(op1) && is_ia32_Const(op2)) {
656     DBG((mod, LEVEL_2, "found unexpected %s(Const, Const), creating binop ... ", get_irn_opname(node)));
657     imm_op = NULL;
658   }
659
660   if (op == get_op_Min() || op == get_op_Max()) {
661     DBG((mod, LEVEL_2, "MIN/MAX imm not available, creating binop ... "));
662     imm_op = NULL;
663   }
664
665   DBG((mod, LEVEL_1, "(op1: %s -- op2: %s) ... ", get_irn_opname(op1), get_irn_opname(op2)));
666
667   if (imm_op) {
668     DBG((mod, LEVEL_1, "%s with imm ... ", get_irn_opname(node)));
669
670     switch(opc) {
671       GENOPI(Add);
672       GENOPI(Mul);
673       GENOPI(And);
674       GENOPI(Or);
675       GENOPI(Eor);
676       GENOPI(Cmp);
677
678       GENOPI(Sub);
679       GENOPI(Shl);
680       GENOPI(Shr);
681       GENOPI(Shrs);
682       GENOPI(Rot);
683       default:
684         if (op == get_op_Mulh()) {
685           asm_node = gen_imm_Mulh(mod, dbg, block, expr_op, imm_op, mode);
686         }
687         else
688           assert("binop_i: THIS SHOULD NOT HAPPEN");
689     }
690
691     set_ia32_Immop_attr(asm_node, imm_op);
692   }
693   else {
694     DBG((mod, LEVEL_1, "%s as binop ... ", get_irn_opname(node)));
695
696     switch(opc) {
697       GENOP(Add);
698       GENOP(Mul);
699       GENOP(And);
700       GENOP(Or);
701       GENOP(Eor);
702       GENOP(Cmp);
703
704       GENOP(Sub);
705       GENOP(Shl);
706       GENOP(Shr);
707       GENOP(Shrs);
708       GENOP(Rot);
709       default:
710         if (op == get_op_Mulh()) {
711           asm_node = gen_Mulh(mod, dbg, block, op1, op2, mode);
712         }
713         else if (op == get_op_Max()) {
714           asm_node = gen_Max(mod, dbg, block, op1, op2, mode);
715         }
716         else if (op == get_op_Min()) {
717           asm_node = gen_Min(mod, dbg, block, op1, op2, mode);
718         }
719         else
720           assert("binop: THIS SHOULD NOT HAPPEN");
721     }
722   }
723
724   return asm_node;
725 }
726
727
728
729 /**
730  * Transforms a Minus node.
731  *
732  * @param mod     the debug module
733  * @param block   the block the new node should belong to
734  * @param node    the ir Minus node
735  * @param op      operator
736  * @param mode    node mode
737  * @return the created ia32 Minus node
738  */
739 static ir_node *gen_Minus(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
740   if (is_ia32_Minus(op)) {
741     DBG((mod, LEVEL_1, "optimizing --(e) to e ..."));
742     return get_irn_n(op, 0);
743   }
744   else
745     return new_rd_ia32_Minus(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
746 }
747
748
749
750 /**
751  * Transforms a Conv node.
752  *
753  * @param mod     the debug module
754  * @param block   the block the new node should belong to
755  * @param node    the ir Conv node
756  * @param op      operator
757  * @param mode    node mode
758  * @return the created ia32 Conv node
759  */
760 static ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
761   return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
762 }
763
764
765
766 /**
767  * Transforms a Not node.
768  *
769  * @param mod     the debug module
770  * @param block   the block the new node should belong to
771  * @param node    the ir Not node
772  * @param op      operator
773  * @param mode    node mode
774  * @return the created ia32 Not node
775  */
776 static ir_node *gen_Not(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
777   return new_rd_ia32_Not(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
778 }
779
780
781
782 /**
783  * Transforms an Abs node.
784  *
785  * @param mod     the debug module
786  * @param block   the block the new node should belong to
787  * @param node    the ir Abs node
788  * @param op      operator
789  * @param mode    node mode
790  * @return the created ia32 Abs node
791  */
792 static ir_node *gen_Abs(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
793   ir_node  *res, *p_eax, *p_edx;
794   dbg_info *dbg = get_irn_dbg_info(node);
795
796   res   = new_rd_ia32_Cltd(dbg, current_ir_graph, block, op, mode_T);
797   p_eax = new_rd_Proj(dbg, current_ir_graph, block, res, mode, pn_EAX);
798   p_edx = new_rd_Proj(dbg, current_ir_graph, block, res, mode, pn_EDX);
799   res   = new_rd_ia32_Eor(dbg, current_ir_graph, block, p_eax, p_edx, mode);
800   res   = new_rd_ia32_Sub(dbg, current_ir_graph, block, res, p_edx, mode);
801
802   return res;
803 }
804
805
806
807 /**
808  * Transforms a Load.
809  *
810  * @param mod     the debug module
811  * @param block   the block the new node should belong to
812  * @param node    the ir Load node
813  * @param mode    node mode
814  * @return the created ia32 Load node
815  */
816 static ir_node *gen_Load(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
817   return new_rd_ia32_Load(get_irn_dbg_info(node), current_ir_graph, block, get_Load_mem(node), get_Load_ptr(node), mode);
818 }
819
820
821
822 /**
823  * Transforms a Store.
824  *
825  * @param mod     the debug module
826  * @param block   the block the new node should belong to
827  * @param node    the ir Store node
828  * @param mode    node mode
829  * @return the created ia32 Store node
830  */
831 ir_node *gen_Store(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
832   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);
833 }
834
835
836
837 /**
838  * Transforms a Call.
839  *
840  * @param mod     the debug module
841  * @param block   the block the new node should belong to
842  * @param node    the ir Call node
843  * @param dummy   mode doesn't matter
844  * @return the created ia32 Call node
845  */
846 static ir_node *gen_Call(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *dummy) {
847   return new_rd_ia32_Call(get_irn_dbg_info(node), current_ir_graph, block, node);
848 }
849
850
851
852 /**
853  * Transforms a Const.
854  *
855  * @param mod     the debug module
856  * @param block   the block the new node should belong to
857  * @param node    the ir Const node
858  * @param mode    mode of the Const
859  * @return the created ia32 Const node
860  */
861 static ir_node *gen_Const(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
862   ir_node *cnst = new_rd_ia32_Const(get_irn_dbg_info(node), current_ir_graph, block, mode);
863   set_ia32_Const_attr(cnst, node);
864   return cnst;
865 }
866
867 /**
868  * Transforms a SymConst.
869  *
870  * @param mod     the debug module
871  * @param block   the block the new node should belong to
872  * @param node    the ir SymConst node
873  * @param mode    mode of the SymConst
874  * @return the created ia32 Const node
875  */
876 static ir_node *gen_SymConst(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
877   ir_node *cnst = new_rd_ia32_Const(get_irn_dbg_info(node), current_ir_graph, block, mode);
878   set_ia32_Const_attr(cnst, node);
879   return cnst;
880 }
881
882
883
884 /**
885  * Transforms the given firm node (and maybe some other related nodes)
886  * into one or more assembler nodes.
887  *
888  * @param node    the firm node
889  * @param env     the debug module
890  */
891 void ia32_transform_node(ir_node *node, void *env) {
892   firm_dbg_module_t *mod = (firm_dbg_module_t *)env;
893   opcode  code           = get_irn_opcode(node);
894   ir_node *asm_node      = NULL;
895   ir_node *block;
896   ir_mode *mode;
897
898   if (is_Block(node))
899     return;
900
901   block = get_nodes_block(node);
902   mode  = get_irn_mode(node);
903
904 #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
905 #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
906 #define TRIOP(a)       case iro_##a: asm_node = gen_##a(mod, get_irn_dbg_info(node), block, get_irn_n(node, 0), get_irn_n(node, 1), get_irn_n(node, 2), mode); break
907 #define UNOP(a)        case iro_##a: asm_node = gen_##a(mod, block, node, get_irn_n(node, 0), mode); break
908 #define GEN(a)         case iro_##a: asm_node = gen_##a(mod, block, node, mode); break
909 #define IGN(a)         case iro_##a: break
910 #define BAD(a)         case iro_##a: goto bad
911
912   DBG((mod, LEVEL_1, "transforming node %s (%ld) ... ", get_irn_opname(node), get_irn_node_nr(node)));
913
914   switch (code) {
915     BINOP_COM(Add);
916     BINOP_COM(Mul);
917     BINOP_COM(And);
918     BINOP_COM(Or);
919     BINOP_COM(Eor);
920     BINOP_COM(Cmp);
921
922     BINOP_NCOM(Sub);
923     TRIOP(Mod);
924     TRIOP(Div);
925     TRIOP(DivMod);
926     BINOP_NCOM(Shl);
927     BINOP_NCOM(Shr);
928     BINOP_NCOM(Shrs);
929
930     UNOP(Minus);
931     UNOP(Conv);
932     UNOP(Abs);
933     UNOP(Not);
934
935     GEN(Load);
936     GEN(Store);
937     GEN(Call);
938     GEN(Const);
939     GEN(SymConst);
940
941     IGN(Block);
942     IGN(Start);
943     IGN(End);
944     IGN(NoMem);
945     IGN(Phi);
946     IGN(Cond);
947     IGN(Jmp);
948     IGN(IJmp);
949     IGN(Proj);
950     IGN(Break);
951
952     BAD(Raise);
953     BAD(Sel);
954     BAD(InstOf);
955     BAD(Quot);
956     BAD(Cast);
957     BAD(Alloc);
958     BAD(Free);
959     BAD(Sync);
960     BAD(Tuple);
961     BAD(Id);
962     BAD(Bad);
963     BAD(Confirm);
964     BAD(Unknown);
965     BAD(Filter);
966     BAD(CallBegin);
967     BAD(EndReg);
968     BAD(EndExcept);
969     BAD(Mux);
970     BAD(CopyB);
971
972     default:
973       if (get_irn_op(node) == get_op_Mulh() ||
974           get_irn_op(node) == get_op_Max()  ||
975           get_irn_op(node) == get_op_Min())
976       {
977         asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 1);
978       }
979       break;
980 bad:
981     fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
982     assert(0);
983   }
984
985   if (asm_node) {
986     exchange(node, asm_node);
987     DBG((mod, LEVEL_1, "created node %u\n", get_irn_node_nr(asm_node)));
988   }
989   else {
990     DBG((mod, LEVEL_1, "ignored\n"));
991   }
992 }