Changed ir_printf environment
[libfirm] / ir / be / ia32 / ia32_emitter.c
1 #include <limits.h>
2
3 #include "tv.h"
4 #include "iredges.h"
5 #include "debug.h"
6 #include "irgwalk.h"
7 #include "irprintf.h"
8 #include "irop_t.h"
9
10 #include "../besched.h"
11
12 #include "ia32_emitter.h"
13 #include "gen_ia32_emitter.h"
14 #include "ia32_nodes_attr.h"
15 #include "ia32_new_nodes.h"
16 #include "ia32_map_regs.h"
17
18 #define SNPRINTF_BUF_LEN 128
19
20 static set *cur_reg_set = NULL;
21
22
23 /*************************************************************
24  *             _       _    __   _          _
25  *            (_)     | |  / _| | |        | |
26  *  _ __  _ __ _ _ __ | |_| |_  | |__   ___| |_ __   ___ _ __
27  * | '_ \| '__| | '_ \| __|  _| | '_ \ / _ \ | '_ \ / _ \ '__|
28  * | |_) | |  | | | | | |_| |   | | | |  __/ | |_) |  __/ |
29  * | .__/|_|  |_|_| |_|\__|_|   |_| |_|\___|_| .__/ \___|_|
30  * | |                                       | |
31  * |_|                                       |_|
32  *************************************************************/
33
34 /**
35  * Return node's tarval as string.
36  */
37 const char *node_const_to_str(ir_node *n) {
38         char   *buf;
39         tarval *tv = get_ia32_Immop_tarval(n);
40
41         if (tv) {
42                 buf = malloc(SNPRINTF_BUF_LEN);
43                 tarval_snprintf(buf, SNPRINTF_BUF_LEN, tv);
44                 return buf;
45         }
46         else if (get_ia32_old_ir(n)) {
47                 return get_sc_name(get_ia32_old_ir(n));
48         }
49         else
50                 return "0";
51 }
52
53 /**
54  * Returns node's offset as string.
55  */
56 char *node_offset_to_str(ir_node *n) {
57         char   *buf;
58         tarval *tv = get_ia32_offs(n);
59
60         if (tv) {
61                 buf = malloc(SNPRINTF_BUF_LEN);
62                 tarval_snprintf(buf, SNPRINTF_BUF_LEN, tv);
63                 return buf;
64         }
65         else
66                 return "";
67 }
68
69 /* We always pass the ir_node which is a pointer. */
70 static int ia32_get_arg_type(const lc_arg_occ_t *occ) {
71         return lc_arg_type_ptr;
72 }
73
74
75 /**
76  * Returns the register at in position pos. If the IN node is not an
77  * ia32 node, we check for phi and proj.
78  */
79 static const arch_register_t *get_in_reg(ir_node *irn, int pos) {
80         ir_node                *op;
81         const arch_register_t  *reg = NULL;
82         const arch_register_t **slots;
83
84         assert(get_irn_arity(irn) > pos && "Invalid IN position");
85
86         /* The out register of the operator at position pos is the
87            in register we need. */
88         op = get_irn_n(irn, pos);
89
90         if (is_Proj(op)) {
91                 pos = (int)translate_proj_pos(op);
92                 while(is_Proj(op))
93                         op = get_Proj_pred(op);
94         }
95
96         if (is_ia32_irn(op)) {
97                 /* The operator is an ia32 node: this node has only one out */
98                 slots = get_ia32_slots(op);
99                 reg   = slots[0];
100         }
101         else {
102                 /* The operator is not an ia32 node: check for Phi or Proj */
103                 if (is_Phi(op)) {
104                         /* Phi's getting register assigned */
105                         reg  = ia32_get_firm_reg(NULL, op, cur_reg_set);
106                         assert(reg && "No register assigned to Phi node");
107                 }
108                 else {
109                         assert(0 && "Unsupported node for IN register");
110                 }
111         }
112
113         return reg;
114 }
115
116 /**
117  * Returns the number of the in register at position pos.
118  */
119 int get_ia32_in_regnr(ir_node *irn, int pos) {
120         const arch_register_t *reg;
121
122         reg = get_in_reg(irn, pos);
123         assert(reg && "no in register");
124         return reg->index;
125 }
126
127 /**
128  * Returns the name of the in register at position pos.
129  */
130 const char *get_ia32_in_reg_name(ir_node *irn, int pos) {
131         const arch_register_t *reg;
132
133         reg = get_in_reg(irn, pos);
134         assert(reg && "no in register");
135         return reg->name;
136 }
137
138 /**
139  * Get the register name for a node.
140  */
141 static int ia32_get_reg_name(lc_appendable_t *app,
142     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
143 {
144         const char *buf;
145         ir_node    *X  = arg->v_ptr;
146         int         nr = occ->width - 1;
147
148         if (!X)
149                 return lc_arg_append(app, occ, "(null)", 6);
150
151         if (occ->conversion == 's') {
152                 buf = get_ia32_in_reg_name(X, nr);
153         }
154         else { /* 'd' */
155                 buf = get_ia32_out_reg_name(X, nr);
156         }
157
158         return lc_arg_append(app, occ, buf, strlen(buf));
159 }
160
161 /**
162  * Returns the tarval or offset of an ia32 as a string.
163  */
164 static int ia32_const_to_str(lc_appendable_t *app,
165     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
166 {
167         const char *buf;
168         ir_node    *X = arg->v_ptr;
169
170         if (!X)
171                 return lc_arg_append(app, occ, "(null)", 6);
172
173         if (occ->conversion == 'c') {
174                 buf = node_const_to_str(X);
175         }
176         else { /* 'o' */
177                 buf = node_offset_to_str(X);
178         }
179
180         return lc_arg_append(app, occ, buf, strlen(buf));
181 }
182
183 /**
184  * Determines the SSE suffix depending on the mode.
185  */
186 static int ia32_get_mode_suffix(lc_appendable_t *app,
187     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
188 {
189         ir_node *X = arg->v_ptr;
190
191         if (!X)
192                 return lc_arg_append(app, occ, "(null)", 6);
193
194         if (get_mode_size_bits(get_irn_mode(X)) == 32)
195                 return lc_appendable_chadd(app, 's');
196         else
197                 return lc_appendable_chadd(app, 'd');
198 }
199
200 /**
201  * Return the ia32 printf arg environment.
202  * We use the firm environment with some additional handlers.
203  */
204 const lc_arg_env_t *ia32_get_arg_env(void) {
205   static lc_arg_env_t *env = NULL;
206
207   static const lc_arg_handler_t ia32_reg_handler   = { ia32_get_arg_type, ia32_get_reg_name };
208   static const lc_arg_handler_t ia32_const_handler = { ia32_get_arg_type, ia32_const_to_str };
209   static const lc_arg_handler_t ia32_mode_handler  = { ia32_get_arg_type, ia32_get_mode_suffix };
210
211   if(env == NULL) {
212     env = lc_arg_new_env();
213
214     lc_arg_register(env, "ia32:sreg", 's', &ia32_reg_handler);
215     lc_arg_register(env, "ia32:dreg", 'd', &ia32_reg_handler);
216     lc_arg_register(env, "ia32:cnst", 'c', &ia32_const_handler);
217     lc_arg_register(env, "ia32:offs", 'o', &ia32_const_handler);
218     lc_arg_register(env, "ia32:mode", 'm', &ia32_mode_handler);
219   }
220
221   return env;
222 }
223
224 /**
225  * For 2-address code we need to make sure the first src reg is equal to dest reg.
226  */
227 void equalize_dest_src(FILE *F, ir_node *n) {
228         if (get_ia32_in_regnr(n, 0) != get_ia32_out_regnr(n, 0)) {
229                 if (get_irn_arity(n) > 1 && get_ia32_in_regnr(n, 1) == get_ia32_out_regnr(n, 0)) {
230                         if (! is_op_commutative(get_irn_op(n))) {
231                                 /* we only need to echange for non-commutative ops */
232                                 lc_efprintf(ia32_get_arg_env(), F, "\txchg %1s, %2s\t\t\t/* xchg src1 <-> src2 for 2 address code */\n", n, n);
233                         }
234                 }
235                 else {
236                         lc_efprintf(ia32_get_arg_env(), F, "\tmovl %1s, %1d\t\t\t/* src -> dest for 2 address code */\n", n, n);
237                 }
238         }
239 }
240
241 /*
242  * Add a number to a prefix. This number will not be used a second time.
243  */
244 char *get_unique_label(char *buf, size_t buflen, const char *prefix) {
245         static unsigned long id = 0;
246         snprintf(buf, buflen, "%s%lu", prefix, ++id);
247         return buf;
248 }
249
250
251 /*************************************************
252  *                 _ _                         _
253  *                (_) |                       | |
254  *   ___ _ __ ___  _| |_    ___ ___  _ __   __| |
255  *  / _ \ '_ ` _ \| | __|  / __/ _ \| '_ \ / _` |
256  * |  __/ | | | | | | |_  | (_| (_) | | | | (_| |
257  *  \___|_| |_| |_|_|\__|  \___\___/|_| |_|\__,_|
258  *
259  *************************************************/
260
261 /*
262  * coding of conditions
263  */
264 struct cmp2conditon_t {
265         const char *name;
266         pn_Cmp      num;
267 };
268
269 /*
270  * positive conditions for signed compares
271  */
272 static const struct cmp2conditon_t cmp2condition_s[] = {
273   { NULL,              pn_Cmp_False },  /* always false */
274   { "e",               pn_Cmp_Eq },     /* == */
275   { "l",               pn_Cmp_Lt },     /* < */
276   { "le",              pn_Cmp_Le },     /* <= */
277   { "g",               pn_Cmp_Gt },     /* > */
278   { "ge",              pn_Cmp_Ge },     /* >= */
279   { "ne",              pn_Cmp_Lg },     /* != */
280   { "ordered",         pn_Cmp_Leg },    /* Floating point: ordered */
281   { "unordered",       pn_Cmp_Uo },     /* FLoting point: unordered */
282   { "unordered or ==", pn_Cmp_Ue },     /* Floating point: unordered or == */
283   { "unordered or <",  pn_Cmp_Ul },     /* Floating point: unordered or < */
284   { "unordered or <=", pn_Cmp_Ule },    /* Floating point: unordered or <= */
285   { "unordered or >",  pn_Cmp_Ug },     /* Floating point: unordered or > */
286   { "unordered or >=", pn_Cmp_Uge },    /* Floating point: unordered or >= */
287   { "unordered or !=", pn_Cmp_Ne },     /* Floating point: unordered or != */
288   { NULL,              pn_Cmp_True },   /* always true */
289 };
290
291 /*
292  * positive conditions for unsigned compares
293  */
294 static const struct cmp2conditon_t cmp2condition_u[] = {
295   { NULL,              pn_Cmp_False },  /* always false */
296   { "e",               pn_Cmp_Eq },     /* == */
297   { "b",               pn_Cmp_Lt },     /* < */
298   { "be",              pn_Cmp_Le },     /* <= */
299   { "a",               pn_Cmp_Gt },     /* > */
300   { "ae",              pn_Cmp_Ge },     /* >= */
301   { "ne",              pn_Cmp_Lg },     /* != */
302   { "ordered",         pn_Cmp_Leg },    /* Floating point: ordered */
303   { "unordered",       pn_Cmp_Uo },     /* FLoting point: unordered */
304   { "unordered or ==", pn_Cmp_Ue },     /* Floating point: unordered or == */
305   { "unordered or <",  pn_Cmp_Ul },     /* Floating point: unordered or < */
306   { "unordered or <=", pn_Cmp_Ule },    /* Floating point: unordered or <= */
307   { "unordered or >",  pn_Cmp_Ug },     /* Floating point: unordered or > */
308   { "unordered or >=", pn_Cmp_Uge },    /* Floating point: unordered or >= */
309   { "unordered or !=", pn_Cmp_Ne },     /* Floating point: unordered or != */
310   { NULL,              pn_Cmp_True },   /* always true */
311 };
312
313 /*
314  * returns the condition code
315  */
316 static const char *get_cmp_suffix(int cmp_code, int unsigned_cmp)
317 {
318         assert(cmp2condition_s[cmp_code].num == cmp_code);
319         assert(cmp2condition_u[cmp_code].num == cmp_code);
320
321         return unsigned_cmp ? cmp2condition_u[cmp_code & 7].name : cmp2condition_s[cmp_code & 7].name;
322 }
323
324 /**
325  * Returns the target label for a control flow node.
326  */
327 static char *get_cfop_target(const ir_node *irn, char *buf) {
328         ir_node *bl = get_irn_link(irn);
329
330         snprintf(buf, SNPRINTF_BUF_LEN, "BLOCK_%ld", get_irn_node_nr(bl));
331         return buf;
332 }
333
334 /**
335  * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
336  */
337 static void finish_CondJmp(FILE *F, ir_node *irn) {
338         const ir_node   *proj;
339         const ir_edge_t *edge;
340         char buf[SNPRINTF_BUF_LEN];
341
342         edge = get_irn_out_edge_first(irn);
343         proj = get_edge_src_irn(edge);
344         assert(is_Proj(proj) && "CondJmp with a non-Proj");
345
346         if (get_Proj_proj(proj) == 1) {
347                 fprintf(F, "\tj%s %s\t\t\t/* cmp(a, b) == TRUE */\n",
348                                         get_cmp_suffix(get_ia32_pncode(irn), !mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
349                                         get_cfop_target(proj, buf));
350         }
351         else  {
352                 fprintf(F, "\tjn%s %s\t\t\t/* cmp(a, b) == FALSE */\n",
353                                         get_cmp_suffix(get_ia32_pncode(irn), !mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
354                                         get_cfop_target(proj, buf));
355         }
356
357         edge = get_irn_out_edge_next(irn, edge);
358         if (edge) {
359                 proj = get_edge_src_irn(edge);
360                 assert(is_Proj(proj) && "CondJmp with a non-Proj");
361                 fprintf(F, "\tjmp %s\t\t\t/* otherwise */\n", get_cfop_target(proj, buf));
362         }
363 }
364
365 /**
366  * Emits code for conditional jump with two variables.
367  */
368 static void emit_ia32_CondJmp(ir_node *irn, emit_env_t *env) {
369         FILE *F = env->out;
370
371         lc_efprintf(ia32_get_arg_env(), F, "\tcmp %2s, %1s\t\t\t/* CondJmp(%+F, %+F) */\n", irn, irn,
372                                                                                                                                         get_irn_n(irn, 0), get_irn_n(irn, 1));
373         finish_CondJmp(F, irn);
374 }
375
376 /**
377  * Emits code for conditional jump with immediate.
378  */
379 void emit_ia32_CondJmp_i(ir_node *irn, emit_env_t *env) {
380         FILE *F = env->out;
381
382         lc_efprintf(ia32_get_arg_env(), F, "\tcmp %c, %1s\t\t\t/* CondJmp_i(%+F) */\n", irn, irn, get_irn_n(irn, 0));
383         finish_CondJmp(F, irn);
384 }
385
386
387
388 /*********************************************************
389  *                 _ _       _
390  *                (_) |     (_)
391  *   ___ _ __ ___  _| |_     _ _   _ _ __ ___  _ __  ___
392  *  / _ \ '_ ` _ \| | __|   | | | | | '_ ` _ \| '_ \/ __|
393  * |  __/ | | | | | | |_    | | |_| | | | | | | |_) \__ \
394  *  \___|_| |_| |_|_|\__|   | |\__,_|_| |_| |_| .__/|___/
395  *                         _/ |               | |
396  *                        |__/                |_|
397  *********************************************************/
398
399 /* jump table entry (target and corresponding number) */
400 typedef struct _branch_t {
401         ir_node *target;
402         int      value;
403 } branch_t;
404
405 /* jump table for switch generation */
406 typedef struct _jmp_tbl_t {
407         ir_node  *defProj;         /**< default target */
408         int       min_value;       /**< smallest switch case */
409         int       max_value;       /**< largest switch case */
410         int       num_branches;    /**< number of jumps */
411         char     *label;           /**< label of the jump table */
412         branch_t *branches;        /**< jump array */
413 } jmp_tbl_t;
414
415 /**
416  * Compare two variables of type branch_t. Used to sort all switch cases
417  */
418 static int ia32_cmp_branch_t(const void *a, const void *b) {
419         branch_t *b1 = (branch_t *)a;
420         branch_t *b2 = (branch_t *)b;
421
422         if (b1->value <= b2->value)
423                 return -1;
424         else
425                 return 1;
426 }
427
428 /**
429  * Emits code for a SwitchJmp (creates a jump table if
430  * possible otherwise a cmp-jmp cascade). Port from
431  * cggg ia32 backend
432  */
433 void emit_ia32_SwitchJmp(const ir_node *irn, emit_env_t *emit_env) {
434         unsigned long       interval;
435         char                buf[SNPRINTF_BUF_LEN];
436         int                 last_value, i, pn, do_jmp_tbl = 1;
437         jmp_tbl_t           tbl;
438         ir_node            *proj;
439         const ir_edge_t    *edge;
440         const lc_arg_env_t *env = ia32_get_arg_env();
441         FILE               *F   = emit_env->out;
442
443         /* fill the table structure */
444         tbl.label        = malloc(SNPRINTF_BUF_LEN);
445         tbl.label        = get_unique_label(tbl.label, SNPRINTF_BUF_LEN, "JMPTBL_");
446         tbl.defProj      = NULL;
447         tbl.num_branches = get_irn_n_edges(irn);
448         tbl.branches     = calloc(tbl.num_branches, sizeof(tbl.branches[0]));
449         tbl.min_value    = INT_MAX;
450         tbl.max_value    = INT_MIN;
451
452         i = 0;
453         /* go over all proj's and collect them */
454         foreach_out_edge(irn, edge) {
455                 proj = get_edge_src_irn(edge);
456                 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
457
458                 pn = get_Proj_proj(proj);
459
460                 /* create branch entry */
461                 tbl.branches[i].target = proj;
462                 tbl.branches[i].value  = pn;
463
464                 tbl.min_value = pn < tbl.min_value ? pn : tbl.min_value;
465                 tbl.max_value = pn > tbl.max_value ? pn : tbl.max_value;
466
467                 /* check for default proj */
468                 if (pn == get_ia32_pncode(irn)) {
469                         assert(tbl.defProj == NULL && "found two defProjs at SwitchJmp");
470                         tbl.defProj = proj;
471                 }
472
473                 i++;
474         }
475
476         /* sort the branches by their number */
477         qsort(tbl.branches, tbl.num_branches, sizeof(tbl.branches[0]), ia32_cmp_branch_t);
478
479         /* two-complement's magic make this work without overflow */
480         interval = tbl.max_value - tbl.min_value;
481
482         /* check value interval */
483         if (interval > 16 * 1024) {
484                 do_jmp_tbl = 0;
485         }
486
487         /* check ratio of value interval to number of branches */
488         if ((float)(interval + 1) / (float)tbl.num_branches > 8.0) {
489                 do_jmp_tbl = 0;
490         }
491
492         if (do_jmp_tbl) {
493                 /* emit the table */
494                 if (tbl.min_value != 0) {
495                         fprintf(F, "\tcmpl %lu, -%d", interval, tbl.min_value);
496                         lc_efprintf(env, F, "(%1s)\t\t/* first switch value is not 0 */\n", irn);
497                 }
498                 else {
499                         fprintf(F, "\tcmpl %lu, ", interval);
500                         lc_efprintf(env, F, "%1s\t\t\t/* compare for switch */\n", irn);
501                 }
502
503                 fprintf(F, "\tja %s\t\t\t/* default jump if out of range  */\n", get_cfop_target(tbl.defProj, buf));
504
505                 if (tbl.num_branches > 1) {
506                         /* create table */
507
508                         fprintf(F, "\tjmp *%s", tbl.label);
509                         lc_efprintf(env, F, "(,%1s,4)\t\t/* get jump table entry as target */\n", irn);
510
511                         fprintf(F, "\t.section\t.rodata\t\t/* start jump table */\n");
512                         fprintf(F, "\t.align 4\n");
513
514                         fprintf(F, "%s:\n", tbl.label);
515                         fprintf(F, "\t.long %s\t\t\t/* case %d */\n", get_cfop_target(tbl.branches[0].target, buf), tbl.branches[0].value);
516
517                         last_value = tbl.branches[0].value;
518                         for (i = 1; i < tbl.num_branches; ++i) {
519                                 while (++last_value < tbl.branches[i].value) {
520                                         fprintf(F, "\t.long %s\t\t/* default case */\n", get_cfop_target(tbl.defProj, buf));
521                                 }
522                                 fprintf(F, "\t.long %s\t\t\t/* case %d */\n", get_cfop_target(tbl.branches[i].target, buf), last_value);
523                         }
524
525                         fprintf(F, "\t.text\t\t\t\t/* end of jump table */\n");
526                 }
527                 else {
528                         /* one jump is enough */
529                         fprintf(F, "\tjmp %s\t\t/* only one case given */\n", get_cfop_target(tbl.branches[0].target, buf));
530                 }
531         }
532         else { // no jump table
533                 for (i = 0; i < tbl.num_branches; ++i) {
534                         fprintf(F, "\tcmpl %d, ", tbl.branches[i].value);
535                         lc_efprintf(env, F, "%1s", irn);
536                         fprintf(F, "\t\t\t/* case %d */\n", tbl.branches[i].value);
537                         fprintf(F, "\tje %s\n", get_cfop_target(tbl.branches[i].target, buf));
538                 }
539
540                 fprintf(F, "\tjmp %s\t\t\t/* default case */\n", get_cfop_target(tbl.defProj, buf));
541         }
542
543         if (tbl.label)
544                 free(tbl.label);
545         if (tbl.branches)
546                 free(tbl.branches);
547 }
548
549 /**
550  * Emits code for a unconditional jump.
551  */
552 void emit_Jmp(ir_node *irn, emit_env_t *env) {
553         FILE *F = env->out;
554
555         char buf[SNPRINTF_BUF_LEN];
556         ir_fprintf(F, "\tjmp %s\t\t\t/* Jmp(%+F) */\n", get_cfop_target(irn, buf), get_irn_link(irn));
557 }
558
559
560
561 /****************************
562  *                  _
563  *                 (_)
564  *  _ __  _ __ ___  _  ___
565  * | '_ \| '__/ _ \| |/ __|
566  * | |_) | | | (_) | |\__ \
567  * | .__/|_|  \___/| ||___/
568  * | |            _/ |
569  * |_|           |__/
570  ****************************/
571
572 /**
573  * Emits code for a proj -> node
574  */
575 void emit_Proj(ir_node *irn, emit_env_t *env) {
576         ir_node *pred = get_Proj_pred(irn);
577
578         if (get_irn_opcode(pred) == iro_Start) {
579                 switch(get_Proj_proj(irn)) {
580                         case pn_Start_X_initial_exec:
581                                 emit_Jmp(irn, env);
582                                 break;
583                         default:
584                                 break;
585                 }
586         }
587 }
588
589
590
591 /***********************************************************************************
592  *                  _          __                                             _
593  *                 (_)        / _|                                           | |
594  *  _ __ ___   __ _ _ _ __   | |_ _ __ __ _ _ __ ___   _____      _____  _ __| | __
595  * | '_ ` _ \ / _` | | '_ \  |  _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
596  * | | | | | | (_| | | | | | | | | | | (_| | | | | | |  __/\ V  V / (_) | |  |   <
597  * |_| |_| |_|\__,_|_|_| |_| |_| |_|  \__,_|_| |_| |_|\___| \_/\_/ \___/|_|  |_|\_\
598  *
599  ***********************************************************************************/
600
601 /**
602  * Emits code for a node.
603  */
604 void ia32_emit_node(ir_node *irn, void *env) {
605         emit_env_t *emit_env   = env;
606         firm_dbg_module_t *mod = emit_env->mod;
607         FILE              *F   = emit_env->out;
608
609         DBG((mod, LEVEL_1, "emitting code for %+F\n", irn));
610
611 #define IA32_EMIT(a) if (is_ia32_##a(irn))               { emit_ia32_##a(irn, emit_env); return; }
612 #define EMIT(a)      if (get_irn_opcode(irn) == iro_##a) { emit_##a(irn, emit_env); return; }
613
614         /* generated int emitter functions */
615         IA32_EMIT(Const);
616
617         IA32_EMIT(Add);
618         IA32_EMIT(Add_i);
619         IA32_EMIT(Sub);
620         IA32_EMIT(Sub_i);
621         IA32_EMIT(Minus);
622         IA32_EMIT(Inc);
623         IA32_EMIT(Dec);
624
625         IA32_EMIT(Max);
626         IA32_EMIT(Min);
627
628         IA32_EMIT(And);
629         IA32_EMIT(And_i);
630         IA32_EMIT(Or);
631         IA32_EMIT(Or_i);
632         IA32_EMIT(Eor);
633         IA32_EMIT(Eor_i);
634         IA32_EMIT(Not);
635
636         IA32_EMIT(Shl);
637         IA32_EMIT(Shl_i);
638         IA32_EMIT(Shr);
639         IA32_EMIT(Shr_i);
640         IA32_EMIT(Shrs);
641         IA32_EMIT(Shrs_i);
642         IA32_EMIT(RotL);
643         IA32_EMIT(RotL_i);
644         IA32_EMIT(RotR);
645
646         IA32_EMIT(Lea);
647         IA32_EMIT(Lea_i);
648
649         IA32_EMIT(Mul);
650         IA32_EMIT(Mul_i);
651         IA32_EMIT(Mulh);
652         IA32_EMIT(Mulh_i);
653
654         IA32_EMIT(Cltd);
655         IA32_EMIT(DivMod);
656
657         IA32_EMIT(Store);
658         IA32_EMIT(Load);
659
660         /* generated floating point emitter */
661         IA32_EMIT(fConst);
662
663         IA32_EMIT(fAdd);
664         IA32_EMIT(fSub);
665         IA32_EMIT(fMinus);
666
667         IA32_EMIT(fMul);
668         IA32_EMIT(fDiv);
669
670         IA32_EMIT(fMin);
671         IA32_EMIT(fMax);
672
673         IA32_EMIT(fLoad);
674         IA32_EMIT(fStore);
675
676         /* other emitter functions */
677         IA32_EMIT(CondJmp);
678         IA32_EMIT(CondJmp_i);
679         IA32_EMIT(SwitchJmp);
680
681         EMIT(Jmp);
682         EMIT(Proj);
683
684         ir_fprintf(F, "\t\t\t\t\t/* %+F */\n", irn);
685 }
686
687 /**
688  * Walks over the nodes in a block connected by scheduling edges
689  * and emits code for each node.
690  */
691 void ia32_gen_block(ir_node *block, void *env) {
692         ir_node *irn;
693
694         fprintf(((emit_env_t *)env)->out, "BLOCK_%ld:\n", get_irn_node_nr(block));
695         sched_foreach(block, irn) {
696                 ia32_emit_node(irn, env);
697         }
698 }
699
700
701 /**
702  * Emits code for function start.
703  */
704 void ia32_emit_start(FILE *F, ir_graph *irg) {
705         const char *irg_name = get_entity_name(get_irg_entity(irg));
706
707         fprintf(F, "\t.text\n");
708         fprintf(F, ".globl %s\n", irg_name);
709         fprintf(F, "\t.type\t%s, @function\n", irg_name);
710         fprintf(F, "%s:\n", irg_name);
711 }
712
713 /**
714  * Emits code for function end
715  */
716 void ia32_emit_end(FILE *F, ir_graph *irg) {
717         const char *irg_name = get_entity_name(get_irg_entity(irg));
718
719         fprintf(F, "\tret\n");
720         fprintf(F, "\t.size\t%s, .-%s\n\n", irg_name, irg_name);
721 }
722
723 /**
724  * Sets labels for control flow nodes (jump target)
725  * TODO: Jump optimization
726  */
727 void ia32_gen_labels(ir_node *block, void *env) {
728         ir_node *pred;
729         int n = get_Block_n_cfgpreds(block);
730
731         for (n--; n >= 0; n--) {
732                 pred = get_Block_cfgpred(block, n);
733                 set_irn_link(pred, block);
734         }
735 }
736
737 /**
738  * Main driver
739  */
740 void ia32_gen_routine(FILE *F, ir_graph *irg, set *reg_set) {
741         emit_env_t emit_env;
742
743         emit_env.mod     = firm_dbg_register("be.codegen.ia32");
744         emit_env.out     = F;
745         emit_env.reg_set = reg_set;
746
747         cur_reg_set = reg_set;
748
749         ia32_emit_start(F, irg);
750         irg_block_walk_graph(irg, ia32_gen_labels, NULL, &emit_env);
751         irg_block_walk_graph(irg, NULL, ia32_gen_block, &emit_env);
752         ia32_emit_end(F, irg);
753 }