fixed indents
[libfirm] / ir / be / ia32 / ia32_transform.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include "irnode_t.h"
6 #include "irgraph_t.h"
7 #include "irmode_t.h"
8 #include "irgmod.h"
9 #include "iredges.h"
10 #include "irvrfy.h"
11 #include "ircons.h"
12 #include "dbginfo.h"
13 #include "iropt_t.h"
14 #include "debug.h"
15
16 #include "ia32_nodes_attr.h"
17 #include "../arch/archop.h"     /* we need this for Min and Max nodes */
18 #include "ia32_transform.h"
19 #include "ia32_new_nodes.h"
20
21 #include "gen_ia32_regalloc_if.h"
22
23 extern ir_op *get_op_Mulh(void);
24
25 static int maxnum_gpreg_args = 3;   /* maximum number of int arguments passed in registers; default 3 */
26 static int maxnum_fpreg_args = 5;   /* maximum number of float arguments passed in registers; default 5 */
27
28 static const arch_register_req_t **current_gpreg_param_req;
29 static const arch_register_req_t **current_fpreg_param_req;
30
31 /* this is the order of the assigned registers usesd for parameter passing */
32
33 const arch_register_req_t *gpreg_param_req_std[] = {
34         &ia32_default_req_ia32_general_purpose_eax,
35         &ia32_default_req_ia32_general_purpose_ecx,
36         &ia32_default_req_ia32_general_purpose_edx,
37         &ia32_default_req_ia32_general_purpose_ebx,
38         &ia32_default_req_ia32_general_purpose_edi,
39         &ia32_default_req_ia32_general_purpose_esi
40 };
41
42 const arch_register_req_t *gpreg_param_req_this[] = {
43         &ia32_default_req_ia32_general_purpose_ecx,
44         &ia32_default_req_ia32_general_purpose_eax,
45         &ia32_default_req_ia32_general_purpose_edx,
46         &ia32_default_req_ia32_general_purpose_ebx,
47         &ia32_default_req_ia32_general_purpose_edi,
48         &ia32_default_req_ia32_general_purpose_esi
49 };
50
51 const arch_register_req_t *fpreg_param_req_std[] = {
52         &ia32_default_req_ia32_floating_point_xmm0,
53         &ia32_default_req_ia32_floating_point_xmm1,
54         &ia32_default_req_ia32_floating_point_xmm2,
55         &ia32_default_req_ia32_floating_point_xmm3,
56         &ia32_default_req_ia32_floating_point_xmm4,
57         &ia32_default_req_ia32_floating_point_xmm5,
58         &ia32_default_req_ia32_floating_point_xmm6,
59         &ia32_default_req_ia32_floating_point_xmm7
60 };
61
62 const arch_register_req_t *fpreg_param_req_this[] = {
63         NULL,  /* in case of a "this" pointer, the first parameter must not be a float */
64         &ia32_default_req_ia32_floating_point_xmm0,
65         &ia32_default_req_ia32_floating_point_xmm1,
66         &ia32_default_req_ia32_floating_point_xmm2,
67         &ia32_default_req_ia32_floating_point_xmm3,
68         &ia32_default_req_ia32_floating_point_xmm4,
69         &ia32_default_req_ia32_floating_point_xmm5,
70         &ia32_default_req_ia32_floating_point_xmm6,
71         &ia32_default_req_ia32_floating_point_xmm7
72 };
73
74
75
76 /****************************************************************************************************
77  *                  _        _                        __                           _   _
78  *                 | |      | |                      / _|                         | | (_)
79  *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
80  * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
81  * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
82  * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
83  *
84  ****************************************************************************************************/
85
86
87
88 /* determine if one operator is an Imm */
89 static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
90         if (op1)
91                 return is_ia32_Const(op1) ? op1 : (is_ia32_Const(op2) ? op2 : NULL);
92         else return is_ia32_Const(op2) ? op2 : NULL;
93 }
94
95 /* determine if one operator is not an Imm */
96 static ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
97         return !is_ia32_Const(op1) ? op1 : (!is_ia32_Const(op2) ? op2 : NULL);
98 }
99
100
101
102 /**
103  * Creates an ia32 Add with immediate.
104  *
105  * @param dbg       firm dbg
106  * @param block     the block the new node should belong to
107  * @param expr_op   operator
108  * @param mode      node mode
109  * @return the created ia23 Add_i node
110  */
111 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) {
112         ir_node *new_op;
113         tarval  *tv = get_ia32_Immop_tarval(const_op);
114         int     normal_add = 0;
115         tarval_classification_t class_tv, class_negtv;
116
117         /* const_op: tarval or SymConst? */
118         if (tv) {
119                 /* optimize tarvals */
120                 class_tv    = classify_tarval(tv);
121                 class_negtv = classify_tarval(tarval_neg(tv));
122
123                 if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
124                         DBG((mod, LEVEL_2, "optimizing Add(1) to Inc ... "));
125                         new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
126                 }
127                 else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
128                         DBG((mod, LEVEL_2, "optimizing Add(-1) to Dec ... "));
129                         new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
130                 }
131                 else
132                         normal_add = 1;
133         }
134         else
135                 normal_add = 1;
136
137         if (normal_add)
138                 new_op = new_rd_ia32_Lea_i(dbg, current_ir_graph, block, expr_op, mode);
139
140         return new_op;
141 }
142
143 /**
144  * Creates an ia32 Add.
145  *
146  * @param dbg       firm node dbg
147  * @param block     the block the new node should belong to
148  * @param op1       first operator
149  * @param op2       second operator
150  * @param mode      node mode
151  * @return the created ia32 Add node
152  */
153 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) {
154         ir_node *shli_op;
155         ir_node *expr_op;
156         ir_node *new_op;
157         int normal_add  = 0;
158
159         if (mode_is_float(mode)) {
160                 return new_rd_ia32_fAdd(dbg, current_ir_graph, block, op1, op2, mode);
161         }
162
163         /* try to optimize with LEA */
164
165         shli_op = is_ia32_Shl_i(op1) ? op1 : (is_ia32_Shl_i(op2) ? op2 : NULL);
166         expr_op = shli_op == op1 ? op2 : (shli_op == op2 ? op1 : NULL);
167
168         if (shli_op) {
169                 tarval *tv   = get_ia32_Immop_tarval(shli_op);
170                 tarval *offs = NULL;
171                 if (tv) {
172                         switch (get_tarval_long(tv)) {
173                                 case 1:
174                                 case 2:
175                                 case 3:
176                                         // If the other operand of the LEA is an LEA_i (that means LEA ofs(%regop1)),
177                                         // we can skip it and transform the whole sequence into LEA ofs(%regop1, %regop2, shl_val),
178                                         if (is_ia32_Lea_i(expr_op)) {
179                                                 offs    = get_ia32_Immop_tarval(expr_op);
180                                                 expr_op = get_irn_n(expr_op, 0);
181                                         }
182
183                                         new_op = new_rd_ia32_Lea(dbg, current_ir_graph, block, expr_op, get_irn_n(shli_op, 0), mode);
184                                         set_ia32_Immop_tarval(new_op, tv);
185                                         set_ia32_offs(new_op, offs);
186
187                                         break;
188                                 default:
189                                         normal_add = 1;
190                                         break;
191                         }
192                 }
193                 else
194                         normal_add = 1;
195         }
196         else
197                 normal_add = 1;
198
199         if (normal_add) {
200                 new_op = new_rd_ia32_Lea(dbg, current_ir_graph, block, op1, op2, mode);
201                 set_ia32_Immop_tarval(new_op, get_tarval_one(mode_Iu));
202                 set_ia32_offs(new_op, NULL);
203         }
204
205         return new_op;
206 }
207
208
209
210 /**
211  * Creates an ia32 Mul with immediate.
212  *
213  * @param dbg       firm dbg
214  * @param block     the block the new node should belong to
215  * @param expr_op   operator
216  * @param mode      node mode
217  * @return the created ia23 Mul_i node
218  */
219 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) {
220         return new_rd_ia32_Mul_i(dbg, current_ir_graph, block, expr_op, mode);
221 }
222
223 /**
224  * Creates an ia32 Mul.
225  *
226  * @param dbg       firm node dbg
227  * @param block     the block the new node should belong to
228  * @param op1       first operator
229  * @param op2       second operator
230  * @param mode      node mode
231  * @return the created ia32 Mul node
232  */
233 ir_node *gen_Mul(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
234         if (mode_is_float(mode)) {
235                 return new_rd_ia32_fMul(dbg, current_ir_graph, block, op1, op2, mode);
236         }
237         return new_rd_ia32_Mul(dbg, current_ir_graph, block, op1, op2, mode);
238 }
239
240
241
242 /**
243  * Creates an ia32 Mulh with immediate.
244  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
245  * this result while Mul returns the lower 32 bit.
246  *
247  * @param dbg       firm dbg
248  * @param block     the block the new node should belong to
249  * @param expr_op   operator
250  * @param mode      node mode
251  * @return the created ia23 Mulh_i node
252  */
253 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) {
254         return new_rd_ia32_Mulh_i(dbg, current_ir_graph, block, expr_op, mode);
255 }
256
257 /**
258  * Creates an ia32 Mulh.
259  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
260  * this result while Mul returns the lower 32 bit.
261  *
262  * @param dbg       firm node dbg
263  * @param block     the block the new node should belong to
264  * @param op1       first operator
265  * @param op2       second operator
266  * @param mode      node mode
267  * @return the created ia32 Mulh node
268  */
269 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) {
270         return new_rd_ia32_Mulh(dbg, current_ir_graph, block, op1, op2, mode);
271 }
272
273
274
275 /**
276  * Creates an ia32 And with immediate.
277  *
278  * @param dbg       firm dbg
279  * @param block     the block the new node should belong to
280  * @param expr_op   operator
281  * @param mode      node mode
282  * @return the created ia23 And_i node
283  */
284 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) {
285         return new_rd_ia32_And_i(dbg, current_ir_graph, block, expr_op, mode);
286 }
287
288 /**
289  * Creates an ia32 And.
290  *
291  * @param dbg       firm node dbg
292  * @param block     the block the new node should belong to
293  * @param op1       first operator
294  * @param op2       second operator
295  * @param mode      node mode
296  * @return the created ia32 And node
297  */
298 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) {
299         return new_rd_ia32_And(dbg, current_ir_graph, block, op1, op2, mode);
300 }
301
302
303
304 /**
305  * Creates an ia32 Or with immediate.
306  *
307  * @param dbg       firm dbg
308  * @param block     the block the new node should belong to
309  * @param expr_op   operator
310  * @param mode      node mode
311  * @return the created ia23 Or_i node
312  */
313 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) {
314         return new_rd_ia32_Or_i(dbg, current_ir_graph, block, expr_op, mode);
315 }
316
317 /**
318  * Creates an ia32 Or.
319  *
320  * @param dbg       firm node dbg
321  * @param block     the block the new node should belong to
322  * @param op1       first operator
323  * @param op2       second operator
324  * @param mode      node mode
325  * @return the created ia32 Or node
326  */
327 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) {
328         return new_rd_ia32_Or(dbg, current_ir_graph, block, op1, op2, mode);
329 }
330
331
332
333 /**
334  * Creates an ia32 Eor with immediate.
335  *
336  * @param dbg       firm dbg
337  * @param block     the block the new node should belong to
338  * @param expr_op   operator
339  * @param mode      node mode
340  * @return the created ia23 Eor_i node
341  */
342 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) {
343         return new_rd_ia32_Eor_i(dbg, current_ir_graph, block, expr_op, mode);
344 }
345
346 /**
347  * Creates an ia32 Eor.
348  *
349  * @param dbg       firm node dbg
350  * @param block     the block the new node should belong to
351  * @param op1       first operator
352  * @param op2       second operator
353  * @param mode      node mode
354  * @return the created ia32 Eor node
355  */
356 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) {
357         return new_rd_ia32_Eor(dbg, current_ir_graph, block, op1, op2, mode);
358 }
359
360
361
362 /**
363  * Creates an ia32 Max.
364  *
365  * @param dbg       firm dbg
366  * @param block     the block the new node should belong to
367  * @param expr_op   operator
368  * @param mode      node mode
369  * @return the created ia23 Max node
370  */
371 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) {
372         return new_rd_ia32_Max(dbg, current_ir_graph, block, op1, op2, mode);
373 }
374
375
376
377 /**
378  * Creates an ia32 Min.
379  *
380  * @param dbg       firm dbg
381  * @param block     the block the new node should belong to
382  * @param expr_op   operator
383  * @param mode      node mode
384  * @return the created ia23 Min node
385  */
386 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) {
387         return new_rd_ia32_Min(dbg, current_ir_graph, block, op1, op2, mode);
388 }
389
390
391
392 /**
393  * Creates an ia32 Sub with immediate.
394  *
395  * @param dbg       firm dbg
396  * @param block     the block the new node should belong to
397  * @param expr_op   operator
398  * @param mode      node mode
399  * @return the created ia23 Sub_i node
400  */
401 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) {
402         ir_node *new_op;
403         tarval  *tv = get_ia32_Immop_tarval(const_op);
404         int     normal_sub = 0;
405         tarval_classification_t class_tv, class_negtv;
406
407         /* const_op: tarval or SymConst? */
408         if (tv) {
409                 /* optimize tarvals */
410                 class_tv    = classify_tarval(tv);
411                 class_negtv = classify_tarval(tarval_neg(tv));
412
413                 if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
414                         DBG((mod, LEVEL_2, "optimizing Sub(1) to Dec ... "));
415                         new_op = new_rd_ia32_Dec(dbg, current_ir_graph, block, expr_op, mode);
416                 }
417                 else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
418                         DBG((mod, LEVEL_2, "optimizing Sub(-1) to Inc ... "));
419                         new_op = new_rd_ia32_Inc(dbg, current_ir_graph, block, expr_op, mode);
420                 }
421                 else
422                         normal_sub = 1;
423         }
424         else
425                 normal_sub = 1;
426
427         if (normal_sub)
428                 new_op = new_rd_ia32_Sub_i(dbg, current_ir_graph, block, expr_op, mode);
429
430         return new_op;
431 }
432
433 /**
434  * Creates an ia32 Sub.
435  *
436  * @param dbg       firm node dbg
437  * @param block     the block the new node should belong to
438  * @param op1       first operator
439  * @param op2       second operator
440  * @param mode      node mode
441  * @return the created ia32 Sub node
442  */
443 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) {
444         if (mode_is_float(mode)) {
445                 return new_rd_ia32_fSub(dbg, current_ir_graph, block, op1, op2, mode);
446         }
447         return new_rd_ia32_Sub(dbg, current_ir_graph, block, op1, op2, mode);
448 }
449
450
451
452 /**
453  * Creates an ia32 Mod.
454  *
455  * @param dbg       firm node dbg
456  * @param block     the block the new node should belong to
457  * @param op1       first operator
458  * @param op2       second operator
459  * @param mode      node mode
460  * @return the created ia32 Mod node
461  */
462 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) {
463         return new_rd_ia32_DivMod(dbg, current_ir_graph, block, op1, op2, mem, flavour_Mod, mode);
464 }
465
466
467
468 /**
469  * Creates an ia32 Div.
470  *
471  * @param dbg       firm node dbg
472  * @param block     the block the new node should belong to
473  * @param op1       first operator
474  * @param op2       second operator
475  * @param mode      node mode
476  * @return the created ia32 Div node
477  */
478 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) {
479         return new_rd_ia32_DivMod(dbg, current_ir_graph, block, op1, op2, mem, flavour_Div, mode);
480 }
481
482
483
484 /**
485  * Creates an ia32 DivMod.
486  *
487  * @param dbg       firm node dbg
488  * @param block     the block the new node should belong to
489  * @param op1       first operator
490  * @param op2       second operator
491  * @param mode      node mode
492  * @return the created ia32 DivMod node
493  */
494 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) {
495         return new_rd_ia32_DivMod(dbg, current_ir_graph, block, op1, op2, mem, flavour_DivMod, mode);
496 }
497
498
499
500 /**
501  * Creates an ia32 floating Div.
502  *
503  * @param dbg       firm node dbg
504  * @param block     the block the new node should belong to
505  * @param op1       first operator
506  * @param op2       second operator
507  * @param mode      node mode
508  * @return the created ia32 fDiv node
509  */
510 static ir_node *gen_Quot(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
511         return new_rd_ia32_fDiv(dbg, current_ir_graph, block, op1, op2, mode);
512 }
513
514
515
516 /**
517  * Creates an ia32 Shl with immediate.
518  *
519  * @param dbg       firm dbg
520  * @param block     the block the new node should belong to
521  * @param expr_op   operator
522  * @param mode      node mode
523  * @return the created ia23 Shl_i node
524  */
525 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) {
526         return new_rd_ia32_Shl_i(dbg, current_ir_graph, block, expr_op, mode);
527 }
528
529 /**
530  * Creates an ia32 Shl.
531  *
532  * @param dbg       firm node dbg
533  * @param block     the block the new node should belong to
534  * @param op1       first operator
535  * @param op2       second operator
536  * @param mode      node mode
537  * @return the created ia32 Shl node
538  */
539 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) {
540         return new_rd_ia32_Shl(dbg, current_ir_graph, block, op1, op2, mode);
541 }
542
543
544
545 /**
546  * Creates an ia32 Shr with immediate.
547  *
548  * @param dbg       firm dbg
549  * @param block     the block the new node should belong to
550  * @param expr_op   operator
551  * @param mode      node mode
552  * @return the created ia23 Shr_i node
553  */
554 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) {
555         return new_rd_ia32_Shr_i(dbg, current_ir_graph, block, expr_op, mode);
556 }
557
558 /**
559  * Creates an ia32 Shr.
560  *
561  * @param dbg       firm node dbg
562  * @param block     the block the new node should belong to
563  * @param op1       first operator
564  * @param op2       second operator
565  * @param mode      node mode
566  * @return the created ia32 Shr node
567  */
568 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) {
569         return new_rd_ia32_Shr(dbg, current_ir_graph, block, op1, op2, mode);
570 }
571
572
573
574 /**
575  * Creates an ia32 Shrs with immediate.
576  *
577  * @param dbg       firm dbg
578  * @param block     the block the new node should belong to
579  * @param expr_op   operator
580  * @param mode      node mode
581  * @return the created ia23 Shrs_i node
582  */
583 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) {
584         return new_rd_ia32_Shrs_i(dbg, current_ir_graph, block, expr_op, mode);
585 }
586
587 /**
588  * Creates an ia32 Shrs.
589  *
590  * @param dbg       firm node dbg
591  * @param block     the block the new node should belong to
592  * @param op1       first operator
593  * @param op2       second operator
594  * @param mode      node mode
595  * @return the created ia32 Shrs node
596  */
597 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) {
598         return new_rd_ia32_Shrs(dbg, current_ir_graph, block, op1, op2, mode);
599 }
600
601
602
603 /**
604  * Creates an ia32 RotL.
605  *
606  * @param dbg       firm node dbg
607  * @param block     the block the new node should belong to
608  * @param op1       first operator
609  * @param op2       second operator
610  * @param mode      node mode
611  * @return the created ia32 RotL node
612  */
613 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) {
614         return new_rd_ia32_RotL(dbg, current_ir_graph, block, op1, op2, mode);
615 }
616
617
618
619 /**
620  * Creates an ia32 RotR.
621  * NOTE: There is no RotR with immediate because this would always be a RotL
622  *       "imm-mode_size_bits" which can be pre-calculated.
623  *
624  * @param dbg       firm node dbg
625  * @param block     the block the new node should belong to
626  * @param op1       first operator
627  * @param op2       second operator
628  * @param mode      node mode
629  * @return the created ia32 RotR node
630  */
631 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) {
632         return new_rd_ia32_RotR(dbg, current_ir_graph, block, op1, op2, mode);
633 }
634
635
636
637 /**
638  * Transforms a Rot with immediate into an ia32 RotL with immediate
639  * as the Firm Rot is a RotL (see NOTE on RotR with immediate above).
640  *
641  * @param dbg       firm node dbg
642  * @param block     the block the new node should belong to
643  * @param op1       first operator
644  * @param op2       second operator
645  * @param mode      node mode
646  * @return the created ia32 RotL node
647  */
648 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) {
649         return new_rd_ia32_RotL_i(dbg, current_ir_graph, block, expr_op, mode);
650 }
651
652 /**
653  * Creates an ia32 RotR or RotL (depending on the found pattern).
654  *
655  * @param dbg       firm node dbg
656  * @param block     the block the new node should belong to
657  * @param op1       first operator
658  * @param op2       second operator
659  * @param mode      node mode
660  * @return the created ia32 RotL or RotR node
661  */
662 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) {
663         ir_node *rotate = NULL;
664
665         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
666                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
667                  that means we can create a RotR instead of an Add and a RotL */
668
669         if (is_ia32_Add_i(op2)) {
670                 ir_node *minus = get_irn_n(op2, 0); // is there an op_Minus?
671
672                 if (is_ia32_Minus(minus)) {
673                         tarval *tv = get_ia32_Immop_tarval(op2);
674                         long bits  = get_mode_size_bits(mode);
675
676                         if (tarval_is_long(tv) && get_tarval_long(tv) == bits) {
677                                 DBG((mod, LEVEL_1, "optimizing RotL into RotR ... "));
678                                 rotate = gen_RotR(mod, dbg, block, op1, get_irn_n(minus, 0), mode);
679                         }
680                 }
681         }
682
683         if (!rotate)
684                 rotate = gen_RotL(mod, dbg, block, op1, op2, mode);
685
686         return rotate;
687 }
688
689
690
691 /**
692  * Transforms commutative operations (op_Add, op_Mul, op_And, op_Or, op_Eor)
693  * and non-commutative operations with com == 0 (op_Sub, op_Shl, op_Shr, op_Shrs, op_Rot)
694  *
695  * @param mod       the debug module
696  * @param block     the block node belongs to
697  * @param node      the node to transform
698  * @param op1       first operator
699  * @param op2       second operator
700  * @param mode      node mode
701  * @param com       flag if op is commutative
702  * @return the created assembler node
703  */
704 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) {
705         dbg_info *dbg      = get_irn_dbg_info(node);
706         ir_node  *imm_op   = NULL;
707         ir_node  *expr_op  = NULL;
708         ir_node  *asm_node = NULL;
709         opcode   opc       = get_irn_opcode(node);
710         ir_op    *op       = get_irn_op(node);
711
712 #define GENOP(a)  case iro_##a: asm_node = gen_##a(mod, dbg, block, op1, op2, mode); break
713 #define GENOPI(a) case iro_##a: asm_node = gen_imm_##a(mod, dbg, block, expr_op, imm_op, mode); break
714
715         if (com)
716                 imm_op  = get_immediate_op(op1, op2);
717         else
718                 imm_op  = get_immediate_op(NULL, op2);
719
720         expr_op = get_expr_op(op1, op2);
721
722         /* TODO: Op(Const, Const) support */
723         if (is_ia32_Const(op1) && is_ia32_Const(op2)) {
724                 DBG((mod, LEVEL_2, "found unexpected %s(Const, Const), creating binop ... ", get_irn_opname(node)));
725                 imm_op = NULL;
726         }
727
728         if (op == get_op_Min() || op == get_op_Max()) {
729                 DBG((mod, LEVEL_2, "MIN/MAX imm not available, creating binop ... "));
730                 imm_op = NULL;
731         }
732
733         DBG((mod, LEVEL_1, "(op1: %s -- op2: %s) ... ", get_irn_opname(op1), get_irn_opname(op2)));
734
735         if (!mode_is_float(mode) && imm_op) {
736                 DBG((mod, LEVEL_1, "%s with imm ... ", get_irn_opname(node)));
737
738                 switch(opc) {
739                         GENOPI(Add);
740                         GENOPI(Mul);
741                         GENOPI(And);
742                         GENOPI(Or);
743                         GENOPI(Eor);
744
745                         GENOPI(Sub);
746                         GENOPI(Shl);
747                         GENOPI(Shr);
748                         GENOPI(Shrs);
749                         GENOPI(Rot);
750                         default:
751                                 if (op == get_op_Mulh()) {
752                                         asm_node = gen_imm_Mulh(mod, dbg, block, expr_op, imm_op, mode);
753                                 }
754                                 else
755                                         assert("binop_i: THIS SHOULD NOT HAPPEN");
756                 }
757
758                 set_ia32_Immop_attr(asm_node, imm_op);
759         }
760         else {
761                 DBG((mod, LEVEL_1, "%s as binop ... ", get_irn_opname(node)));
762
763                 switch(opc) {
764                         GENOP(Add);
765                         GENOP(Mul);
766                         GENOP(And);
767                         GENOP(Or);
768                         GENOP(Eor);
769
770                         GENOP(Quot);
771
772                         GENOP(Sub);
773                         GENOP(Shl);
774                         GENOP(Shr);
775                         GENOP(Shrs);
776                         GENOP(Rot);
777                         default:
778                                 if (op == get_op_Mulh()) {
779                                         asm_node = gen_Mulh(mod, dbg, block, op1, op2, mode);
780                                 }
781                                 else if (op == get_op_Max()) {
782                                         asm_node = gen_Max(mod, dbg, block, op1, op2, mode);
783                                 }
784                                 else if (op == get_op_Min()) {
785                                         asm_node = gen_Min(mod, dbg, block, op1, op2, mode);
786                                 }
787                                 else
788                                         assert("binop: THIS SHOULD NOT HAPPEN");
789                 }
790         }
791
792         return asm_node;
793 }
794
795
796
797 /**
798  * Transforms a Minus node.
799  *
800  * @param mod     the debug module
801  * @param block   the block the new node should belong to
802  * @param node    the ir Minus node
803  * @param op      operator
804  * @param mode    node mode
805  * @return the created ia32 Minus node
806  */
807 static ir_node *gen_Minus(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
808         if (is_ia32_Minus(op) || is_ia32_fMinus(op)) {
809                 DBG((mod, LEVEL_1, "optimizing --(e) to e ..."));
810                 return get_irn_n(op, 0);
811         }
812         else {
813                 if (mode_is_float(mode)) {
814                         return new_rd_ia32_fMinus(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
815                 }
816                 return new_rd_ia32_Minus(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
817         }
818 }
819
820
821
822 /**
823  * Transforms a Conv node.
824  *
825  * @param mod     the debug module
826  * @param block   the block the new node should belong to
827  * @param node    the ir Conv node
828  * @param op      operator
829  * @param mode    node mode
830  * @return the created ia32 Conv node
831  */
832 static ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
833         return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
834 }
835
836
837
838 /**
839  * Transforms a Not node.
840  *
841  * @param mod     the debug module
842  * @param block   the block the new node should belong to
843  * @param node    the ir Not node
844  * @param op      operator
845  * @param mode    node mode
846  * @return the created ia32 Not node
847  */
848 static ir_node *gen_Not(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
849         return new_rd_ia32_Not(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
850 }
851
852
853
854 /**
855  * Transforms an Abs node.
856  *
857  * @param mod     the debug module
858  * @param block   the block the new node should belong to
859  * @param node    the ir Abs node
860  * @param op      operator
861  * @param mode    node mode
862  * @return the created ia32 Abs node
863  */
864 static ir_node *gen_Abs(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
865         ir_node  *res, *p_eax, *p_edx;
866         dbg_info *dbg = get_irn_dbg_info(node);
867
868         res   = new_rd_ia32_Cltd(dbg, current_ir_graph, block, op, mode_T);
869         p_eax = new_rd_Proj(dbg, current_ir_graph, block, res, mode, pn_EAX);
870         p_edx = new_rd_Proj(dbg, current_ir_graph, block, res, mode, pn_EDX);
871         res   = new_rd_ia32_Eor(dbg, current_ir_graph, block, p_eax, p_edx, mode);
872         res   = new_rd_ia32_Sub(dbg, current_ir_graph, block, res, p_edx, mode);
873
874         return res;
875 }
876
877
878
879 /**
880  * Transforms a Load.
881  *
882  * @param mod     the debug module
883  * @param block   the block the new node should belong to
884  * @param node    the ir Load node
885  * @param mode    node mode
886  * @return the created ia32 Load node
887  */
888 static ir_node *gen_Load(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
889         if (mode_is_float(mode)) {
890                 return new_rd_ia32_fLoad(get_irn_dbg_info(node), current_ir_graph, block, get_Load_ptr(node), get_Load_mem(node), mode);
891         }
892         return new_rd_ia32_Load(get_irn_dbg_info(node), current_ir_graph, block, get_Load_ptr(node), get_Load_mem(node), mode);
893 }
894
895
896
897 /**
898  * Transforms a Store.
899  *
900  * @param mod     the debug module
901  * @param block   the block the new node should belong to
902  * @param node    the ir Store node
903  * @param mode    node mode
904  * @return the created ia32 Store node
905  */
906 ir_node *gen_Store(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
907         if (mode_is_float(mode)) {
908                 return new_rd_ia32_fStore(get_irn_dbg_info(node), current_ir_graph, block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), mode);
909         }
910         return new_rd_ia32_Store(get_irn_dbg_info(node), current_ir_graph, block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), mode);
911 }
912
913
914
915 /**
916  * Check all parameters and determine the maximum number of parameters
917  * to pass in gp regs resp. in fp regs.
918  */
919 static void get_n_regparam_class(int n, ir_node **param, int *n_int, int *n_float) {
920         int i;
921
922         for (i = 0; i < n; i++) {
923                 if (mode_is_int(get_irn_mode(param[i])))
924                         *n_int = *n_int + 1;
925                 else if (mode_is_float(get_irn_mode(param[i])))
926                         *n_float = *n_float + 1;
927
928                 /* test for maximum */
929                 if (*n_int == maxnum_gpreg_args)
930                         break;
931
932                 if (*n_float == maxnum_fpreg_args)
933                         break;
934         }
935 }
936
937 /**
938  * Transforms a Call and its arguments corresponding to the calling convention.
939  *
940  * @param mod     the debug module
941  * @param block   the block the new node should belong to
942  * @param node    the ir Call node
943  * @param dummy   mode doesn't matter
944  * @return the created ia32 Call node
945  */
946 static ir_node *gen_Call(firm_dbg_module_t *mod, ir_node *block, ir_node *call, ir_mode *dummy) {
947         const arch_register_req_t **in_req;
948         ir_node    **in;
949         ir_node     *new_call, *sync;
950         ir_mode     *mode;
951         int          i, j, n_new_call_in;
952         asmop_attr  *attr;
953         ir_node    **stack_param  = NULL;
954         ir_node    **param        = get_Call_param_arr(call);
955         ir_node     *call_Mem     = get_Call_mem(call);
956         unsigned     cc           = get_method_calling_convention(get_Call_type(call));
957         int          n            = get_Call_n_params(call);
958         int          n_gpregparam = 0;
959         int          n_fpregparam = 0;
960         int          cur_gp_idx   = 0;
961         int          cur_fp_idx   = 0;
962         int          stack_idx    = 0;
963         int          done         = 0;
964
965         if (cc & cc_reg_param)
966                 get_n_regparam_class(n, param, &n_gpregparam, &n_fpregparam);
967
968         /* do we need to pass arguments on stack? */
969         if (n - n_gpregparam - n_fpregparam > 0)
970                 stack_param = calloc(n - n_gpregparam - n_fpregparam, sizeof(ir_node *));
971
972         /* we need at least one in, either for the stack params or the call_Mem */
973         n_new_call_in = 1 + n_gpregparam + n_fpregparam;
974
975         current_gpreg_param_req = gpreg_param_req_std;
976         current_fpreg_param_req = fpreg_param_req_std;
977
978         if (cc & cc_this_call) {
979                 current_gpreg_param_req = gpreg_param_req_this;
980                 current_fpreg_param_req = fpreg_param_req_this;
981         }
982
983         /* the call has one IN for all stack parameter and one IN for each reg param */
984         in     = calloc(n_new_call_in, sizeof(ir_node *));
985         in_req = calloc(n_new_call_in, sizeof(arch_register_req_t *));
986
987         /* loop over all parameters and determine whether its a int or float register parameter */
988         for (i = 0; i < n && !done && (cc & cc_reg_param); i++) {
989                 mode = get_irn_mode(param[i]);
990
991                 if (mode_is_int(mode) && cur_gp_idx < maxnum_gpreg_args) {
992                         /* param can be passed in general purpose register and we have some registers left */
993                         in[cur_gp_idx + cur_fp_idx] = param[i];
994                         in_req[cur_gp_idx] = current_gpreg_param_req[cur_gp_idx];
995                         cur_gp_idx++;
996                 }
997                 else if (mode_is_float(mode) && cur_fp_idx < maxnum_fpreg_args) {
998                         /* param can be passed in floating point register and we have some registers left */
999                         assert(current_gpreg_param_req[cur_fp_idx] && "'this' pointer cannot be passed as float");
1000                         in[cur_gp_idx + cur_fp_idx] = param[i];
1001                         in_req[cur_fp_idx] = current_gpreg_param_req[cur_fp_idx];
1002                         cur_fp_idx++;
1003                 }
1004
1005                 /* maximum number of register parameters in one class reached? */
1006                 if (cur_gp_idx >= maxnum_gpreg_args || cur_fp_idx >= maxnum_fpreg_args) {
1007                         done      = 1;
1008                 }
1009         }
1010         stack_idx = i;
1011
1012         /* create remaining stack parameters */
1013         if (cc & cc_last_on_top) {
1014                 for (i = stack_idx; i < n; i++) {
1015                         /* pass it on stack */
1016                         if (mode_is_float(get_irn_mode(param[i]))) {
1017                                 stack_param[i] = new_rd_ia32_fStackArg(get_irn_dbg_info(param[i]), current_ir_graph,
1018                                                                                                                 block, call_Mem, param[i], mode_M);
1019                         }
1020                         else {
1021                                 stack_param[i] = new_rd_ia32_StackArg(get_irn_dbg_info(param[i]), current_ir_graph,
1022                                                                                                                 block, call_Mem, param[i], mode_M);
1023                         }
1024                 }
1025         }
1026         else {
1027                 for (i = n - 1, j = stack_idx; i >= stack_idx; i--, j++) {
1028                         /* pass it on stack */
1029                         if (mode_is_float(get_irn_mode(param[i]))) {
1030                                 stack_param[i] = new_rd_ia32_fStackArg(get_irn_dbg_info(param[i]), current_ir_graph,
1031                                                                                                                 block, call_Mem, param[i], mode_M);
1032                         }
1033                         else {
1034                                 stack_param[i] = new_rd_ia32_StackArg(get_irn_dbg_info(param[i]), current_ir_graph,
1035                                                                                                                 block, call_Mem, param[i], mode_M);
1036                         }
1037                 }
1038         }
1039
1040         if (stack_param) {
1041                 sync = new_r_Sync(current_ir_graph, block, n - n_gpregparam - n_fpregparam, stack_param);
1042                 in[n_new_call_in - 1] = sync;
1043         }
1044         else {
1045                 in[n_new_call_in - 1] = call_Mem;
1046         }
1047
1048         /* create the new node */
1049         new_call = new_rd_ia32_Call(get_irn_dbg_info(call), current_ir_graph, block, n_new_call_in, in);
1050         set_ia32_Immop_attr(new_call, get_Call_ptr(call));
1051         set_ia32_n_res(new_call, 1);
1052
1053         /* set register requirements for in and out */
1054         attr             = get_ia32_attr(new_call);
1055         attr->in_req     = in_req;
1056         attr->out_req    = calloc(1, sizeof(arch_register_req_t *));
1057         attr->out_req[0] = &ia32_default_req_ia32_general_purpose_eax;
1058         attr->slots      = calloc(1, sizeof(arch_register_t *));
1059
1060         /* stack parameter has no OUT register */
1061         attr->in_req[n_new_call_in - 1] = &ia32_default_req_none;
1062
1063         return new_call;
1064 }
1065
1066
1067
1068 /**
1069  * creates a unique ident by adding a number to a tag
1070  *
1071  * @param tag   the tag string, must contain a %d if a number
1072  *              should be added
1073  */
1074 static ident *unique_id(const char *tag)
1075 {
1076   static unsigned id = 0;
1077   char str[256];
1078
1079   snprintf(str, sizeof(str), tag, ++id);
1080   return new_id_from_str(str);
1081 }
1082
1083 /**
1084  * Transforms a SymConst.
1085  *
1086  * @param mod     the debug module
1087  * @param block   the block the new node should belong to
1088  * @param node    the ir SymConst node
1089  * @param mode    mode of the SymConst
1090  * @return the created ia32 Const node
1091  */
1092 static ir_node *gen_SymConst(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
1093         ir_node *cnst;
1094
1095         if (mode_is_float(mode)) {
1096                 cnst = new_rd_ia32_fConst(get_irn_dbg_info(node), current_ir_graph, block, mode);
1097
1098         }
1099         else {
1100                 cnst = new_rd_ia32_Const(get_irn_dbg_info(node), current_ir_graph, block, mode);
1101         }
1102
1103         set_ia32_Const_attr(cnst, node);
1104         return cnst;
1105 }
1106
1107 /**
1108  * Transforms a Const.
1109  *
1110  * @param mod     the debug module
1111  * @param block   the block the new node should belong to
1112  * @param node    the ir Const node
1113  * @param mode    mode of the Const
1114  * @return the created ia32 Const node
1115  */
1116 static ir_node *gen_Const(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
1117         ir_node *cnst;
1118         entity  *ent;
1119         type    *tp;
1120         symconst_symbol sym;
1121
1122         if (mode_is_float(mode)) {
1123                 tp  = get_Const_type(node);
1124                 if (tp == firm_unknown_type) {
1125                         tp = new_type_primitive(unique_id("tp_ia32_float_%u"), mode);
1126                 }
1127
1128                 ent = new_entity(get_glob_type(), unique_id("ia32FloatCnst_%u"), tp);
1129
1130                 set_entity_ld_ident(ent, get_entity_ident(ent));
1131                 set_entity_visibility(ent, visibility_local);
1132                 set_entity_variability(ent, variability_constant);
1133                 set_entity_allocation(ent, allocation_static);
1134
1135                 set_atomic_ent_value(ent, node);
1136
1137                 sym.entity_p = ent;
1138
1139                 cnst = new_rd_SymConst(get_irn_dbg_info(node), current_ir_graph, block, sym, symconst_addr_ent);
1140                 cnst = gen_SymConst(mod, block, cnst, mode);
1141         }
1142         else {
1143                 cnst = new_rd_ia32_Const(get_irn_dbg_info(node), current_ir_graph, block, mode);
1144                 set_ia32_Const_attr(cnst, node);
1145         }
1146
1147         return cnst;
1148 }
1149
1150
1151
1152 /**
1153  * Transforms a Cond -> Proj[b] -> Cmp into a CondJmp or CondJmp_i
1154  *
1155  * @param mod     the debug module
1156  * @param block   the block the new node should belong to
1157  * @param node    the ir Cond node
1158  * @param mode    mode of the Cond
1159  * @return The transformed node.
1160  */
1161 static ir_node *gen_Cond(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
1162         ir_node *sel      = get_Cond_selector(node);
1163         ir_mode *sel_mode = get_irn_mode(sel);
1164         ir_node *res      = NULL;
1165         ir_node *pred     = NULL;
1166         ir_node *cmp_a, *cmp_b, *cnst, *expr;
1167
1168         if (is_Proj(sel) && sel_mode == mode_b) {
1169                 pred  = get_Proj_pred(sel);
1170
1171                 /* get both compare operators */
1172                 cmp_a = get_Cmp_left(pred);
1173                 cmp_b = get_Cmp_right(pred);
1174
1175                 /* check if we can use a CondJmp with immediate */
1176                 cnst = get_immediate_op(cmp_a, cmp_b);
1177                 expr = get_expr_op(cmp_a, cmp_b);
1178
1179                 if (cnst && expr) {
1180                         res = new_rd_ia32_CondJmp_i(get_irn_dbg_info(node), current_ir_graph, block, expr, mode_T);
1181                         set_ia32_Immop_attr(res, cnst);
1182                 }
1183                 else {
1184                         res = new_rd_ia32_CondJmp(get_irn_dbg_info(node), current_ir_graph, block, cmp_a, cmp_b, mode_T);
1185                 }
1186
1187                 set_ia32_pncode(res, get_Proj_proj(sel));
1188         }
1189         else {
1190                 res = new_rd_ia32_SwitchJmp(get_irn_dbg_info(node), current_ir_graph, block, sel, mode_T);
1191                 set_ia32_pncode(res, get_Cond_defaultProj(node));
1192         }
1193
1194         return res;
1195 }
1196
1197
1198
1199 /**
1200  * Transform the argument projs from a start node corresponding to the
1201  * calling convention.
1202  * It transforms "Proj Arg x -> ProjT -> Start <- ProjM" into
1203  * "RegParam x   -> ProjT -> Start" OR
1204  * "StackParam x -> ProjM -> Start"
1205  * whether parameter is passed in register or on stack.
1206  *
1207  * @param mod     the debug module
1208  * @param block   the block the nodes should belong to
1209  * @param proj    the ProjT node which points to Start
1210  * @param start   the Start node
1211  * @return Should be always NULL
1212  */
1213 static ir_node *gen_Proj_Start(firm_dbg_module_t *mod, ir_node *block, ir_node *proj, ir_node *start) {
1214         const ir_edge_t *edge;
1215         ir_node         *succ, *irn;
1216         ir_node        **projargs;
1217         ir_mode         *mode;
1218         int              n, i, j;
1219         unsigned         cc;
1220         ir_node         *proj_M     = get_irg_initial_mem(current_ir_graph);
1221         entity          *irg_ent    = get_irg_entity(current_ir_graph);
1222         type            *tp         = get_entity_type(irg_ent);
1223         int              cur_gp_idx = 0;
1224         int              cur_fp_idx = 0;
1225         int              stack_idx  = 0;
1226         int              done       = 0;
1227
1228         assert(is_Method_type(tp) && "irg type is not a method");
1229
1230         switch(get_Proj_proj(proj)) {
1231                 case pn_Start_T_args:
1232                         /* We cannot use get_method_n_params here as the function might
1233                            be variadic or one argument is not used. */
1234                         n  = get_irn_n_edges(proj);
1235
1236                         /* we are done here when there are no parameters */
1237                         if (n < 1)
1238                                 break;
1239
1240                         /* temporary remember all proj arg x */
1241                         projargs = calloc(n, sizeof(ir_node *));
1242
1243                         foreach_out_edge((const ir_node *)proj, edge) {
1244                                 succ = get_edge_src_irn(edge);
1245                                 assert(is_Proj(succ) && "non-Proj from a Proj_T (pn_Start_T_args).");
1246                                 projargs[get_Proj_proj(succ)] = succ;
1247                         }
1248
1249                         cc = get_method_calling_convention(tp);
1250
1251                         /* get the correct order in case of 'this' call */
1252                         current_gpreg_param_req = gpreg_param_req_std;
1253                         current_fpreg_param_req = fpreg_param_req_std;
1254                         if (cc & cc_this_call) {
1255                                 current_gpreg_param_req = gpreg_param_req_this;
1256                                 current_fpreg_param_req = fpreg_param_req_this;
1257                         }
1258
1259                         /* loop over all parameters and check whether its a int or float */
1260                         for (i = 0; i < n && !done && (cc & cc_reg_param); i++) {
1261                                 mode = get_irn_mode(projargs[i]);
1262
1263                                 if (mode_is_int(mode) && cur_gp_idx < maxnum_gpreg_args) {
1264                                         /* parameter got passed in general purpose register */
1265                                         irn = new_rd_ia32_RegParam(get_irn_dbg_info(proj), current_ir_graph, block, proj, mode);
1266                                         set_ia32_pncode(irn, i);
1267                                         set_ia32_regreq_out(irn, current_gpreg_param_req[cur_gp_idx], 0);
1268                                         cur_gp_idx++;
1269                                 }
1270                                 else if (mode_is_float(mode) && cur_fp_idx < maxnum_fpreg_args) {
1271                                         /* parameter got passed in floating point register*/
1272                                         irn = new_rd_ia32_RegParam(get_irn_dbg_info(proj), current_ir_graph, block, proj, mode);
1273                                         set_ia32_pncode(irn, i);
1274                                         set_ia32_regreq_out(irn, current_fpreg_param_req[cur_fp_idx], 0);
1275                                         cur_fp_idx++;
1276                                 }
1277
1278                                 /* kill the old "Proj Arg" and replace with the new Arg */
1279                                 exchange(projargs[i], irn);
1280
1281                                 if (cur_gp_idx >= maxnum_gpreg_args || cur_fp_idx >= maxnum_fpreg_args) {
1282                                         stack_idx = i;
1283                                         done      = 1;
1284                                 }
1285                         }
1286
1287                         /* create all remaining stack parameters */
1288                         if (cc & cc_last_on_top) {
1289                                 for (i = stack_idx; i < n; i++) {
1290                                         mode = get_irn_mode(projargs[i]);
1291
1292                                         if (mode_is_float(mode))
1293                                                 irn = new_rd_ia32_fStackParam(get_irn_dbg_info(projargs[i]), current_ir_graph, block, proj_M, mode);
1294                                         else
1295                                                 irn = new_rd_ia32_StackParam(get_irn_dbg_info(projargs[i]), current_ir_graph, block, proj_M, mode);
1296
1297                                         set_ia32_pncode(irn, i);
1298
1299                                         /* kill the old "Proj Arg" and replace with the new stack param */
1300                                         exchange(projargs[i], irn);
1301                                 }
1302                         }
1303                         else {
1304                                 for (i = n - 1, j = stack_idx; i >= stack_idx; i--, j++) {
1305                                         mode = get_irn_mode(projargs[i]);
1306
1307                                         if (mode_is_float(mode))
1308                                                 irn = new_rd_ia32_fStackParam(get_irn_dbg_info(projargs[i]), current_ir_graph, block, proj_M, mode);
1309                                         else
1310                                                 irn = new_rd_ia32_StackParam(get_irn_dbg_info(projargs[i]), current_ir_graph, block, proj_M, mode);
1311
1312                                         set_ia32_pncode(irn, j);
1313
1314                                         /* kill the old "Proj Arg" and replace with the new stack param */
1315                                         exchange(projargs[i], irn);
1316                                 }
1317                         }
1318
1319                         free(projargs);
1320
1321                         break;
1322                 case pn_Start_X_initial_exec:
1323                 case pn_Start_M:
1324                 case pn_Start_P_frame_base:
1325                 case pn_Start_P_globals:
1326                 case pn_Start_P_value_arg_base:
1327                         break;
1328                 default:
1329                         assert(0 && "unsupported Proj(Start)");
1330         }
1331
1332         return NULL;
1333 }
1334
1335 /**
1336  * Transform some Proj's (Proj_Proj, Proj_Start, Proj_Cmp, Proj_Cond, Proj_Call).
1337  * All others are ignored.
1338  *
1339  * @param mod     the debug module
1340  * @param block   the block the new node should belong to
1341  * @param node    the ir Proj node
1342  * @param mode    mode of the Proj
1343  * @return The transformed node.
1344  */
1345 static ir_node *gen_Proj(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
1346         ir_node *new_node  = NULL;
1347         ir_node *pred      = get_Proj_pred(node);
1348
1349         if (mode == mode_M)
1350                 return NULL;
1351
1352         if (get_irn_op(pred) == op_Start) {
1353                 new_node = gen_Proj_Start(mod, block, node, pred);
1354         }
1355
1356         return new_node;
1357 }
1358
1359
1360
1361 /*********************************************************
1362  *                  _             _      _
1363  *                 (_)           | |    (_)
1364  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
1365  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
1366  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
1367  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
1368  *
1369  *********************************************************/
1370
1371
1372
1373 /**
1374  * Transforms the given firm node (and maybe some other related nodes)
1375  * into one or more assembler nodes.
1376  *
1377  * @param node    the firm node
1378  * @param env     the debug module
1379  */
1380 void ia32_transform_node(ir_node *node, void *env) {
1381         firm_dbg_module_t *mod = (firm_dbg_module_t *)env;
1382         opcode  code           = get_irn_opcode(node);
1383         ir_node *asm_node      = NULL;
1384         ir_node *block;
1385         ir_mode *mode;
1386
1387         if (is_Block(node))
1388                 return;
1389
1390         block = get_nodes_block(node);
1391         mode  = get_irn_mode(node);
1392
1393 #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
1394 #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
1395 #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
1396 #define UNOP(a)        case iro_##a: asm_node = gen_##a(mod, block, node, get_irn_n(node, 0), mode); break
1397 #define GEN(a)         case iro_##a: asm_node = gen_##a(mod, block, node, mode); break
1398 #define IGN(a)         case iro_##a: break
1399 #define BAD(a)         case iro_##a: goto bad
1400
1401         DBG((mod, LEVEL_1, "transforming node %s (%ld) ... ", get_irn_opname(node), get_irn_node_nr(node)));
1402
1403         switch (code) {
1404                 BINOP_COM(Add);
1405                 BINOP_COM(Mul);
1406                 BINOP_COM(And);
1407                 BINOP_COM(Or);
1408                 BINOP_COM(Eor);
1409
1410                 BINOP_NCOM(Sub);
1411                 TRIOP(Mod);
1412                 TRIOP(Div);
1413                 TRIOP(DivMod);
1414                 BINOP_NCOM(Shl);
1415                 BINOP_NCOM(Shr);
1416                 BINOP_NCOM(Shrs);
1417                 BINOP_NCOM(Quot);
1418
1419                 UNOP(Minus);
1420                 UNOP(Conv);
1421                 UNOP(Abs);
1422                 UNOP(Not);
1423
1424                 GEN(Load);
1425                 GEN(Store);
1426                 GEN(Call);
1427                 GEN(Const);
1428                 GEN(SymConst);
1429                 GEN(Cond);
1430
1431                 GEN(Proj);
1432
1433                 IGN(Block);
1434                 IGN(Start);
1435                 IGN(End);
1436                 IGN(NoMem);
1437                 IGN(Phi);
1438                 IGN(IJmp);
1439                 IGN(Break);
1440                 IGN(Cmp);
1441
1442                 BAD(Raise);
1443                 BAD(Sel);
1444                 BAD(InstOf);
1445                 BAD(Cast);
1446                 BAD(Alloc);
1447                 BAD(Free);
1448                 BAD(Sync);
1449                 BAD(Tuple);
1450                 BAD(Id);
1451                 BAD(Bad);
1452                 BAD(Confirm);
1453                 BAD(Unknown);
1454                 BAD(Filter);
1455                 BAD(CallBegin);
1456                 BAD(EndReg);
1457                 BAD(EndExcept);
1458                 BAD(Mux);
1459                 BAD(CopyB);
1460
1461                 default:
1462                         if (get_irn_op(node) == get_op_Mulh() ||
1463                                         get_irn_op(node) == get_op_Max()  ||
1464                                         get_irn_op(node) == get_op_Min())
1465                         {
1466                                 asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 1);
1467                         }
1468                         break;
1469 bad:
1470                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
1471                 assert(0);
1472         }
1473
1474         if (asm_node) {
1475                 exchange(node, asm_node);
1476                 DBG((mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
1477         }
1478         else {
1479                 DBG((mod, LEVEL_1, "ignored\n"));
1480         }
1481 }