renamed fp to xmm registers
[libfirm] / ir / be / ia32 / ia32_emitter.c
1 /**
2  * This file implements the node emitter.
3  *
4  * $Id$
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include <limits.h>
12
13 #include "xmalloc.h"
14 #include "tv.h"
15 #include "iredges.h"
16 #include "debug.h"
17 #include "irgwalk.h"
18 #include "irprintf.h"
19 #include "irop_t.h"
20 #include "irargs_t.h"
21 #include "irprog_t.h"
22 #include "iredges_t.h"
23
24 #include "../besched_t.h"
25 #include "../benode_t.h"
26
27 #include "ia32_emitter.h"
28 #include "gen_ia32_emitter.h"
29 #include "gen_ia32_regalloc_if.h"
30 #include "ia32_nodes_attr.h"
31 #include "ia32_new_nodes.h"
32 #include "ia32_map_regs.h"
33
34 #ifdef obstack_chunk_alloc
35 # undef obstack_chunk_alloc
36 # define obstack_chunk_alloc xmalloc
37 #else
38 # define obstack_chunk_alloc xmalloc
39 # define obstack_chunk_free free
40 #endif
41
42 #define BLOCK_PREFIX(x) ".L" x
43
44 extern int obstack_printf(struct obstack *obst, char *fmt, ...);
45
46 #define SNPRINTF_BUF_LEN 128
47
48 /* global arch_env for lc_printf functions */
49 static const arch_env_t *arch_env = NULL;
50
51 /* indicates whether blocks are scheduled or not
52    (this variable is set automatically) */
53 static int have_block_sched       = 0;
54
55 /*************************************************************
56  *             _       _    __   _          _
57  *            (_)     | |  / _| | |        | |
58  *  _ __  _ __ _ _ __ | |_| |_  | |__   ___| |_ __   ___ _ __
59  * | '_ \| '__| | '_ \| __|  _| | '_ \ / _ \ | '_ \ / _ \ '__|
60  * | |_) | |  | | | | | |_| |   | | | |  __/ | |_) |  __/ |
61  * | .__/|_|  |_|_| |_|\__|_|   |_| |_|\___|_| .__/ \___|_|
62  * | |                                       | |
63  * |_|                                       |_|
64  *************************************************************/
65
66 /* We always pass the ir_node which is a pointer. */
67 static int ia32_get_arg_type(const lc_arg_occ_t *occ) {
68         return lc_arg_type_ptr;
69 }
70
71
72 /**
73  * Returns the register at in position pos.
74  */
75 static const arch_register_t *get_in_reg(const ir_node *irn, int pos) {
76         ir_node                *op;
77         const arch_register_t  *reg = NULL;
78
79         assert(get_irn_arity(irn) > pos && "Invalid IN position");
80
81         /* The out register of the operator at position pos is the
82            in register we need. */
83         op = get_irn_n(irn, pos);
84
85         reg = arch_get_irn_register(arch_env, op);
86
87         assert(reg && "no in register found");
88         return reg;
89 }
90
91 /**
92  * Returns the register at out position pos.
93  */
94 static const arch_register_t *get_out_reg(const ir_node *irn, int pos) {
95         ir_node                *proj;
96         const arch_register_t  *reg = NULL;
97
98         /* 1st case: irn is not of mode_T, so it has only                 */
99         /*           one OUT register -> good                             */
100         /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
101         /*           Proj with the corresponding projnum for the register */
102
103         if (get_irn_mode(irn) != mode_T) {
104                 reg = arch_get_irn_register(arch_env, irn);
105         }
106         else if (is_ia32_irn(irn)) {
107                 reg = get_ia32_out_reg(irn, pos);
108         }
109         else {
110                 const ir_edge_t *edge;
111
112                 foreach_out_edge(irn, edge) {
113                         proj = get_edge_src_irn(edge);
114                         assert(is_Proj(proj) && "non-Proj from mode_T node");
115                         if (get_Proj_proj(proj) == pos) {
116                                 reg = arch_get_irn_register(arch_env, proj);
117                                 break;
118                         }
119                 }
120         }
121
122         assert(reg && "no out register found");
123         return reg;
124 }
125
126 enum io_direction {
127   IN_REG,
128   OUT_REG
129 };
130
131 /**
132  * Returns the name of the in register at position pos.
133  */
134 static const char *get_ia32_reg_name(ir_node *irn, int pos, enum io_direction in_out) {
135         const arch_register_t *reg;
136         const char            *name;
137         static char           *buf = NULL;
138         int                    len;
139
140         if (in_out == IN_REG) {
141                 reg = get_in_reg(irn, pos);
142         }
143         else {
144                 /* destination address mode nodes don't have outputs */
145                 if (is_ia32_irn(irn) && get_ia32_op_type(irn) == ia32_AddrModeD) {
146                         return "MEM";
147                 }
148
149                 reg = get_out_reg(irn, pos);
150         }
151
152         name = arch_register_get_name(reg);
153
154         if (buf) {
155                 free(buf);
156         }
157
158         len = strlen(name) + 2;
159         buf = xcalloc(1, len);
160
161         snprintf(buf, len, "%%%s", name);
162
163         return buf;
164 }
165
166 /**
167  * Get the register name for a node.
168  */
169 static int ia32_get_reg_name(lc_appendable_t *app,
170     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
171 {
172         const char *buf;
173         ir_node    *X  = arg->v_ptr;
174         int         nr = occ->width - 1;
175
176         if (!X)
177                 return lc_appendable_snadd(app, "(null)", 6);
178
179         buf = get_ia32_reg_name(X, nr, occ->conversion == 'S' ? IN_REG : OUT_REG);
180
181         return lc_appendable_snadd(app, buf, strlen(buf));
182 }
183
184 /**
185  * Returns the tarval, offset or scale of an ia32 as a string.
186  */
187 static int ia32_const_to_str(lc_appendable_t *app,
188     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
189 {
190         const char *buf;
191         ir_node    *X = arg->v_ptr;
192
193         if (!X)
194                 return lc_arg_append(app, occ, "(null)", 6);
195
196         if (occ->conversion == 'C') {
197                 buf = get_ia32_cnst(X);
198         }
199         else { /* 'O' */
200                 buf = get_ia32_am_offs(X);
201         }
202
203         return buf ? lc_appendable_snadd(app, buf, strlen(buf)) : 0;
204 }
205
206 /**
207  * Determines the SSE suffix depending on the mode.
208  */
209 static int ia32_get_mode_suffix(lc_appendable_t *app,
210     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
211 {
212         ir_node *X    = arg->v_ptr;
213         ir_mode *mode = get_irn_mode(X);
214
215         if (mode == mode_T) {
216                 mode = is_ia32_AddrModeS(X) || is_ia32_AddrModeD(X) ? get_ia32_ls_mode(X) : get_ia32_res_mode(X);
217         }
218
219         if (!X)
220                 return lc_arg_append(app, occ, "(null)", 6);
221
222         if (mode_is_float(mode)) {
223                 return lc_appendable_chadd(app, get_mode_size_bits(mode) == 32 ? 's' : 'd');
224         }
225         else {
226                 return lc_appendable_chadd(app, mode_is_signed(mode) ? 's' : 'z');
227         }
228 }
229
230 /**
231  * Return the ia32 printf arg environment.
232  * We use the firm environment with some additional handlers.
233  */
234 const lc_arg_env_t *ia32_get_arg_env(void) {
235         static lc_arg_env_t *env = NULL;
236
237         static const lc_arg_handler_t ia32_reg_handler   = { ia32_get_arg_type, ia32_get_reg_name };
238         static const lc_arg_handler_t ia32_const_handler = { ia32_get_arg_type, ia32_const_to_str };
239         static const lc_arg_handler_t ia32_mode_handler  = { ia32_get_arg_type, ia32_get_mode_suffix };
240
241         if(env == NULL) {
242                 /* extend the firm printer */
243                 env = firm_get_arg_env();
244
245                 lc_arg_register(env, "ia32:sreg", 'S', &ia32_reg_handler);
246                 lc_arg_register(env, "ia32:dreg", 'D', &ia32_reg_handler);
247                 lc_arg_register(env, "ia32:cnst", 'C', &ia32_const_handler);
248                 lc_arg_register(env, "ia32:offs", 'O', &ia32_const_handler);
249                 lc_arg_register(env, "ia32:mode", 'M', &ia32_mode_handler);
250         }
251
252         return env;
253 }
254
255 static char *ia32_get_reg_name_for_mode(ia32_emit_env_t *env, ir_mode *mode, const arch_register_t *reg) {
256         switch(get_mode_size_bits(mode)) {
257                 case 8:
258                         return ia32_get_mapped_reg_name(env->isa->regs_8bit, reg);
259                 case 16:
260                         return ia32_get_mapped_reg_name(env->isa->regs_16bit, reg);
261                 default:
262                         return (char *)arch_register_get_name(reg);
263         }
264 }
265
266 /**
267  * Emits registers and/or address mode of a binary operation.
268  */
269 char *ia32_emit_binop(const ir_node *n, ia32_emit_env_t *env) {
270         static char *buf = NULL;
271
272         /* verify that this function is never called on non-AM supporting operations */
273         //assert(get_ia32_am_support(n) != ia32_am_None && "emit binop expects addressmode support");
274
275 #define PRODUCES_RESULT(n)   \
276         (!(is_ia32_St(n)      || \
277         is_ia32_Store8Bit(n)  || \
278         is_ia32_CondJmp(n)    || \
279         is_ia32_fCondJmp(n)   || \
280         is_ia32_SwitchJmp(n)))
281
282         if (! buf) {
283                 buf = xcalloc(1, SNPRINTF_BUF_LEN);
284         }
285         else {
286                 memset(buf, 0, SNPRINTF_BUF_LEN);
287         }
288
289         switch(get_ia32_op_type(n)) {
290                 case ia32_Normal:
291                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
292                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%3S, %s", n, get_ia32_cnst(n));
293                         }
294                         else {
295                                 const arch_register_t *in1 = get_in_reg(n, 2);
296                                 const arch_register_t *in2 = get_in_reg(n, 3);
297                                 const arch_register_t *out = PRODUCES_RESULT(n) ? get_out_reg(n, 0) : NULL;
298                                 const arch_register_t *in;
299
300                                 in  = out ? (REGS_ARE_EQUAL(out, in2) ? in1 : in2) : in2;
301                                 out = out ? out : in1;
302
303                                 snprintf(buf, SNPRINTF_BUF_LEN, "%%%s, %%%s", \
304                                         arch_register_get_name(out), arch_register_get_name(in));
305                         }
306                         break;
307                 case ia32_AddrModeS:
308                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
309                                 assert(! PRODUCES_RESULT(n) && "Source AM with Const must not produce result");
310                                 snprintf(buf, SNPRINTF_BUF_LEN, "%s, %s", get_ia32_cnst(n), ia32_emit_am(n, env));
311                         }
312                         else {
313                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S, %s", n, ia32_emit_am(n, env));
314                         }
315                         break;
316                 case ia32_AddrModeD:
317                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
318                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s,%s%s",
319                                         ia32_emit_am(n, env),
320                                         is_ia32_ImmSymConst(n) ? " OFFSET FLAT:" : " ",  /* In case of a symconst we must add OFFSET to */
321                                         get_ia32_cnst(n));                               /* tell the assembler to store it's address.   */
322                         }
323                         else {
324                                 const arch_register_t *in1 = get_in_reg(n, 2);
325                                 ir_mode              *mode = get_ia32_res_mode(n);
326
327                                 mode = mode ? mode : get_ia32_ls_mode(n);
328                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %%%s",
329                                         ia32_emit_am(n, env), ia32_get_reg_name_for_mode(env, mode, in1));
330                         }
331                         break;
332                 default:
333                         assert(0 && "unsupported op type");
334         }
335
336 #undef PRODUCES_RESULT
337
338         return buf;
339 }
340
341 /**
342  * Emits registers and/or address mode of a unary operation.
343  */
344 char *ia32_emit_unop(const ir_node *n, ia32_emit_env_t *env) {
345         static char *buf = NULL;
346
347         if (! buf) {
348                 buf = xcalloc(1, SNPRINTF_BUF_LEN);
349         }
350         else {
351                 memset(buf, 0, SNPRINTF_BUF_LEN);
352         }
353
354         switch(get_ia32_op_type(n)) {
355                 case ia32_Normal:
356                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
357                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%C", n);
358                         }
359                         else {
360                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D", n);
361                         }
362                         break;
363                 case ia32_am_Dest:
364                         snprintf(buf, SNPRINTF_BUF_LEN, ia32_emit_am(n, env));
365                         break;
366                 default:
367                         assert(0 && "unsupported op type");
368         }
369
370         return buf;
371 }
372
373 /**
374  * Emits address mode.
375  */
376 char *ia32_emit_am(const ir_node *n, ia32_emit_env_t *env) {
377         ia32_am_flavour_t am_flav    = get_ia32_am_flavour(n);
378         int               had_output = 0;
379         char             *s;
380         int               size;
381         static struct obstack *obst  = NULL;
382         ir_mode *mode = get_ia32_ls_mode(n);
383
384         if (! is_ia32_Lea(n))
385                 assert(mode && "AM node must have ls_mode attribute set.");
386
387         if (! obst) {
388                 obst = xcalloc(1, sizeof(*obst));
389         }
390         else {
391                 obstack_free(obst, NULL);
392         }
393
394         /* obstack_free with NULL results in an uninitialized obstack */
395         obstack_init(obst);
396
397         if (mode) {
398                 switch (get_mode_size_bits(mode)) {
399                         case 8:
400                                 obstack_printf(obst, "BYTE PTR ");
401                                 break;
402                         case 16:
403                                 obstack_printf(obst, "WORD PTR ");
404                                 break;
405                         case 32:
406                                 obstack_printf(obst, "DWORD PTR ");
407                                 break;
408                         default:
409                                 break;
410                 }
411         }
412
413         obstack_printf(obst, "[");
414
415         if (am_flav & ia32_B) {
416                 lc_eoprintf(ia32_get_arg_env(), obst, "%1S", n);
417                 had_output = 1;
418         }
419
420         if (am_flav & ia32_I) {
421                 if (had_output) {
422                         obstack_printf(obst, "+");
423                 }
424
425                 lc_eoprintf(ia32_get_arg_env(), obst, "%2S", n);
426
427                 if (am_flav & ia32_S) {
428                         obstack_printf(obst, "*%d", 1 << get_ia32_am_scale(n));
429                 }
430
431                 had_output = 1;
432         }
433
434         if (am_flav & ia32_O) {
435                 s = get_ia32_am_offs(n);
436
437                 /* omit exlicit + if there was no base or index */
438                 if (! had_output && s[0] == '+')
439                         s++;
440
441                 obstack_printf(obst, s);
442         }
443
444         obstack_printf(obst, "] ");
445
446         size        = obstack_object_size(obst);
447         s           = obstack_finish(obst);
448         s[size - 1] = '\0';
449
450         return s;
451 }
452
453
454
455 /**
456  * Formated print of commands and comments.
457  */
458 static void ia32_fprintf_format(FILE *F, const ir_node *irn, char *cmd_buf, char *cmnt_buf) {
459         unsigned lineno;
460         const char *name = irn ? be_retrieve_dbg_info(get_irn_dbg_info((ir_node *)irn), &lineno) : NULL;
461
462         if (name)
463                 fprintf(F, "\t%-35s %-60s /* %s:%u */\n", cmd_buf, cmnt_buf, name, lineno);
464         else
465                 fprintf(F, "\t%-35s %-60s\n", cmd_buf, cmnt_buf);
466 }
467
468
469
470 /**
471  * Add a number to a prefix. This number will not be used a second time.
472  */
473 static char *get_unique_label(char *buf, size_t buflen, const char *prefix) {
474         static unsigned long id = 0;
475         snprintf(buf, buflen, "%s%lu", prefix, ++id);
476         return buf;
477 }
478
479
480
481 /*************************************************
482  *                 _ _                         _
483  *                (_) |                       | |
484  *   ___ _ __ ___  _| |_    ___ ___  _ __   __| |
485  *  / _ \ '_ ` _ \| | __|  / __/ _ \| '_ \ / _` |
486  * |  __/ | | | | | | |_  | (_| (_) | | | | (_| |
487  *  \___|_| |_| |_|_|\__|  \___\___/|_| |_|\__,_|
488  *
489  *************************************************/
490
491 #undef IA32_DO_EMIT
492 #define IA32_DO_EMIT(irn) ia32_fprintf_format(F, irn, cmd_buf, cmnt_buf)
493
494 /*
495  * coding of conditions
496  */
497 struct cmp2conditon_t {
498         const char *name;
499         pn_Cmp      num;
500 };
501
502 /*
503  * positive conditions for signed compares
504  */
505 static const struct cmp2conditon_t cmp2condition_s[] = {
506   { NULL,              pn_Cmp_False },  /* always false */
507   { "e",               pn_Cmp_Eq },     /* == */
508   { "l",               pn_Cmp_Lt },     /* < */
509   { "le",              pn_Cmp_Le },     /* <= */
510   { "g",               pn_Cmp_Gt },     /* > */
511   { "ge",              pn_Cmp_Ge },     /* >= */
512   { "ne",              pn_Cmp_Lg },     /* != */
513   { "ordered",         pn_Cmp_Leg },    /* Floating point: ordered */
514   { "unordered",       pn_Cmp_Uo },     /* FLoting point: unordered */
515   { "unordered or ==", pn_Cmp_Ue },     /* Floating point: unordered or == */
516   { "unordered or <",  pn_Cmp_Ul },     /* Floating point: unordered or < */
517   { "unordered or <=", pn_Cmp_Ule },    /* Floating point: unordered or <= */
518   { "unordered or >",  pn_Cmp_Ug },     /* Floating point: unordered or > */
519   { "unordered or >=", pn_Cmp_Uge },    /* Floating point: unordered or >= */
520   { "unordered or !=", pn_Cmp_Ne },     /* Floating point: unordered or != */
521   { NULL,              pn_Cmp_True },   /* always true */
522 };
523
524 /*
525  * positive conditions for unsigned compares
526  */
527 static const struct cmp2conditon_t cmp2condition_u[] = {
528         { NULL,              pn_Cmp_False },  /* always false */
529         { "e",               pn_Cmp_Eq },     /* == */
530         { "b",               pn_Cmp_Lt },     /* < */
531         {       "be",              pn_Cmp_Le },     /* <= */
532         { "a",               pn_Cmp_Gt },     /* > */
533         { "ae",              pn_Cmp_Ge },     /* >= */
534         { "ne",              pn_Cmp_Lg },     /* != */
535         { "ordered",         pn_Cmp_Leg },    /* Floating point: ordered */
536         { "unordered",       pn_Cmp_Uo },     /* FLoting point: unordered */
537         { "unordered or ==", pn_Cmp_Ue },     /* Floating point: unordered or == */
538         { "unordered or <",  pn_Cmp_Ul },     /* Floating point: unordered or < */
539         { "unordered or <=", pn_Cmp_Ule },    /* Floating point: unordered or <= */
540         { "unordered or >",  pn_Cmp_Ug },     /* Floating point: unordered or > */
541         { "unordered or >=", pn_Cmp_Uge },    /* Floating point: unordered or >= */
542         { "unordered or !=", pn_Cmp_Ne },     /* Floating point: unordered or != */
543         { NULL,              pn_Cmp_True },   /* always true */
544 };
545
546 /*
547  * returns the condition code
548  */
549 static const char *get_cmp_suffix(int cmp_code, int unsigned_cmp)
550 {
551         assert(cmp2condition_s[cmp_code].num == cmp_code);
552         assert(cmp2condition_u[cmp_code].num == cmp_code);
553
554         return unsigned_cmp ? cmp2condition_u[cmp_code & 7].name : cmp2condition_s[cmp_code & 7].name;
555 }
556
557 /**
558  * Returns the target block for a control flow node.
559  */
560 static ir_node *get_cfop_target_block(const ir_node *irn) {
561         return get_irn_link(irn);
562 }
563
564 /**
565  * Returns the target label for a control flow node.
566  */
567 static char *get_cfop_target(const ir_node *irn, char *buf) {
568         ir_node *bl = get_cfop_target_block(irn);
569
570         snprintf(buf, SNPRINTF_BUF_LEN, BLOCK_PREFIX("%ld"), get_irn_node_nr(bl));
571         return buf;
572 }
573
574 /** Return the next block in Block schedule */
575 static ir_node *next_blk_sched(const ir_node *block) {
576         return have_block_sched ? get_irn_link(block) : NULL;
577 }
578
579 /**
580  * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
581  */
582 static void finish_CondJmp(FILE *F, const ir_node *irn, ir_mode *mode) {
583         const ir_node   *proj1, *proj2 = NULL;
584         const ir_node   *block, *next_bl = NULL;
585         const ir_edge_t *edge;
586         char buf[SNPRINTF_BUF_LEN];
587         char cmd_buf[SNPRINTF_BUF_LEN];
588         char cmnt_buf[SNPRINTF_BUF_LEN];
589
590         /* get both Proj's */
591         edge = get_irn_out_edge_first(irn);
592         proj1 = get_edge_src_irn(edge);
593         assert(is_Proj(proj1) && "CondJmp with a non-Proj");
594
595         edge = get_irn_out_edge_next(irn, edge);
596         if (edge) {
597                 proj2 = get_edge_src_irn(edge);
598                 assert(is_Proj(proj2) && "CondJmp with a non-Proj");
599         }
600
601         /* for now, the code works for scheduled and non-schedules blocks */
602         block = get_nodes_block(irn);
603         if (proj2) {
604                 /* we have a block schedule */
605                 next_bl = next_blk_sched(block);
606
607                 if (get_cfop_target_block(proj1) == next_bl) {
608                         /* exchange both proj's so the second one can be omitted */
609                         const ir_node *t = proj1;
610                         proj1 = proj2;
611                         proj2 = t;
612                 }
613         }
614
615         /* the first Proj must always be created */
616         if (get_Proj_proj(proj1) == pn_Cond_true) {
617                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
618                                         get_cmp_suffix(get_ia32_pncode(irn), !mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
619                                         get_cfop_target(proj1, buf));
620                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* cmp(a, b) == TRUE */");
621         }
622         else  {
623                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
624                                         get_cmp_suffix(get_negated_pnc(get_ia32_pncode(irn), mode),
625                                         !mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
626                                         get_cfop_target(proj1, buf));
627                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* cmp(a, b) == FALSE */");
628         }
629         IA32_DO_EMIT(irn);
630
631         /* the second Proj might be a fallthrough */
632         if (proj2) {
633                 if (get_cfop_target_block(proj2) != next_bl) {
634                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(proj2, buf));
635                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* otherwise */");
636                 }
637                 else {
638                         cmd_buf[0] = '\0';
639                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* fallthrogh %s */", get_cfop_target(proj2, buf));
640                 }
641                 IA32_DO_EMIT(irn);
642         }
643 }
644
645 /**
646  * Emits code for conditional jump.
647  */
648 static void CondJmp_emitter(const ir_node *irn, ia32_emit_env_t *env) {
649         FILE *F = env->out;
650         char cmd_buf[SNPRINTF_BUF_LEN];
651         char cmnt_buf[SNPRINTF_BUF_LEN];
652
653         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmp %s", ia32_emit_binop(irn, env));
654         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
655         IA32_DO_EMIT(irn);
656         finish_CondJmp(F, irn, get_irn_mode(get_irn_n(irn, 2)));
657 }
658
659 /**
660  * Emits code for conditional jump with two variables.
661  */
662 static void emit_ia32_CondJmp(const ir_node *irn, ia32_emit_env_t *env) {
663         CondJmp_emitter(irn, env);
664 }
665
666 /**
667  * Emits code for conditional jump with immediate.
668  */
669 static void emit_ia32_CondJmp_i(const ir_node *irn, ia32_emit_env_t *env) {
670         CondJmp_emitter(irn, env);
671 }
672
673 /**
674  * Emits code for conditional test and jump.
675  */
676 static void TestJmp_emitter(const ir_node *irn, ia32_emit_env_t *env) {
677
678 #define IA32_IS_IMMOP (is_ia32_ImmConst(irn) || is_ia32_ImmSymConst(irn))
679
680         FILE       *F   = env->out;
681         const char *op1 = arch_register_get_name(get_in_reg(irn, 0));
682         const char *op2 = IA32_IS_IMMOP ? get_ia32_cnst(irn) : NULL;
683         char        cmd_buf[SNPRINTF_BUF_LEN];
684         char        cmnt_buf[SNPRINTF_BUF_LEN];
685
686         if (! op2)
687                 op2 = arch_register_get_name(get_in_reg(irn, 1));
688
689         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "test %%%s,%s%s ", op1, IA32_IS_IMMOP ? " " : " %", op2);
690         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
691
692         IA32_DO_EMIT(irn);
693         finish_CondJmp(F, irn, get_irn_mode(get_irn_n(irn, 0)));
694
695 #undef IA32_IS_IMMOP
696 }
697
698 /**
699  * Emits code for conditional test and jump with two variables.
700  */
701 static void emit_ia32_TestJmp(const ir_node *irn, ia32_emit_env_t *env) {
702         TestJmp_emitter(irn, env);
703 }
704
705 static void emit_ia32_CJmp(const ir_node *irn, ia32_emit_env_t *env) {
706         FILE *F = env->out;
707         char cmd_buf[SNPRINTF_BUF_LEN];
708         char cmnt_buf[SNPRINTF_BUF_LEN];
709
710         snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
711         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F omitted redundant test/cmp */", irn);
712         IA32_DO_EMIT(irn);
713         finish_CondJmp(F, irn, get_irn_mode(get_irn_n(irn, 0)));
714 }
715
716 static void emit_ia32_CJmpAM(const ir_node *irn, ia32_emit_env_t *env) {
717         FILE *F = env->out;
718         char cmd_buf[SNPRINTF_BUF_LEN];
719         char cmnt_buf[SNPRINTF_BUF_LEN];
720
721         snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
722         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F omitted redundant test/cmp */", irn);
723         IA32_DO_EMIT(irn);
724         finish_CondJmp(F, irn, get_irn_mode(get_irn_n(irn, 2)));
725 }
726
727 /*********************************************************
728  *                 _ _       _
729  *                (_) |     (_)
730  *   ___ _ __ ___  _| |_     _ _   _ _ __ ___  _ __  ___
731  *  / _ \ '_ ` _ \| | __|   | | | | | '_ ` _ \| '_ \/ __|
732  * |  __/ | | | | | | |_    | | |_| | | | | | | |_) \__ \
733  *  \___|_| |_| |_|_|\__|   | |\__,_|_| |_| |_| .__/|___/
734  *                         _/ |               | |
735  *                        |__/                |_|
736  *********************************************************/
737
738 /* jump table entry (target and corresponding number) */
739 typedef struct _branch_t {
740         ir_node *target;
741         int      value;
742 } branch_t;
743
744 /* jump table for switch generation */
745 typedef struct _jmp_tbl_t {
746         ir_node  *defProj;         /**< default target */
747         int       min_value;       /**< smallest switch case */
748         int       max_value;       /**< largest switch case */
749         int       num_branches;    /**< number of jumps */
750         char     *label;           /**< label of the jump table */
751         branch_t *branches;        /**< jump array */
752 } jmp_tbl_t;
753
754 /**
755  * Compare two variables of type branch_t. Used to sort all switch cases
756  */
757 static int ia32_cmp_branch_t(const void *a, const void *b) {
758         branch_t *b1 = (branch_t *)a;
759         branch_t *b2 = (branch_t *)b;
760
761         if (b1->value <= b2->value)
762                 return -1;
763         else
764                 return 1;
765 }
766
767 /**
768  * Emits code for a SwitchJmp (creates a jump table if
769  * possible otherwise a cmp-jmp cascade). Port from
770  * cggg ia32 backend
771  */
772 static void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) {
773         unsigned long       interval;
774         char                buf[SNPRINTF_BUF_LEN];
775         int                 last_value, i, pn, do_jmp_tbl = 1;
776         jmp_tbl_t           tbl;
777         ir_node            *proj;
778         const ir_edge_t    *edge;
779         const lc_arg_env_t *env = ia32_get_arg_env();
780         FILE               *F   = emit_env->out;
781         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
782
783         /* fill the table structure */
784         tbl.label        = xmalloc(SNPRINTF_BUF_LEN);
785         tbl.label        = get_unique_label(tbl.label, SNPRINTF_BUF_LEN, "JMPTBL_");
786         tbl.defProj      = NULL;
787         tbl.num_branches = get_irn_n_edges(irn);
788         tbl.branches     = xcalloc(tbl.num_branches, sizeof(tbl.branches[0]));
789         tbl.min_value    = INT_MAX;
790         tbl.max_value    = INT_MIN;
791
792         i = 0;
793         /* go over all proj's and collect them */
794         foreach_out_edge(irn, edge) {
795                 proj = get_edge_src_irn(edge);
796                 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
797
798                 pn = get_Proj_proj(proj);
799
800                 /* create branch entry */
801                 tbl.branches[i].target = proj;
802                 tbl.branches[i].value  = pn;
803
804                 tbl.min_value = pn < tbl.min_value ? pn : tbl.min_value;
805                 tbl.max_value = pn > tbl.max_value ? pn : tbl.max_value;
806
807                 /* check for default proj */
808                 if (pn == get_ia32_pncode(irn)) {
809                         assert(tbl.defProj == NULL && "found two defProjs at SwitchJmp");
810                         tbl.defProj = proj;
811                 }
812
813                 i++;
814         }
815
816         /* sort the branches by their number */
817         qsort(tbl.branches, tbl.num_branches, sizeof(tbl.branches[0]), ia32_cmp_branch_t);
818
819         /* two-complement's magic make this work without overflow */
820         interval = tbl.max_value - tbl.min_value;
821
822         /* check value interval */
823         if (interval > 16 * 1024) {
824                 do_jmp_tbl = 0;
825         }
826
827         /* check ratio of value interval to number of branches */
828         if ((float)(interval + 1) / (float)tbl.num_branches > 8.0) {
829                 do_jmp_tbl = 0;
830         }
831
832         if (do_jmp_tbl) {
833                 /* emit the table */
834                 if (tbl.min_value != 0) {
835                         lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "cmpl %lu, -%d(%1S)",
836                                 interval, tbl.min_value, irn);
837                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* first switch value is not 0 */");
838
839                         IA32_DO_EMIT(irn);
840                 }
841                 else {
842                         lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "cmpl %lu, %1S", interval, irn);
843                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* compare for switch */");
844
845                         IA32_DO_EMIT(irn);
846                 }
847
848                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "ja %s", get_cfop_target(tbl.defProj, buf));
849                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default jump if out of range  */");
850                 IA32_DO_EMIT(irn);
851
852                 if (tbl.num_branches > 1) {
853                         /* create table */
854
855                         lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "jmp [%1S*4+%s]", irn, tbl.label);
856                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* get jump table entry as target */");
857                         IA32_DO_EMIT(irn);
858
859                         fprintf(F, "\t.section\t.rodata\n");
860                         fprintf(F, "\t.align 4\n");
861
862                         fprintf(F, "%s:\n", tbl.label);
863
864                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.branches[0].target, buf));
865                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */\n",  tbl.branches[0].value);
866                         IA32_DO_EMIT(irn);
867
868                         last_value = tbl.branches[0].value;
869                         for (i = 1; i < tbl.num_branches; ++i) {
870                                 while (++last_value < tbl.branches[i].value) {
871                                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.defProj, buf));
872                                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default case */");
873                                         IA32_DO_EMIT(irn);
874                                 }
875                                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.branches[i].target, buf));
876                                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */", last_value);
877                                 IA32_DO_EMIT(irn);
878                         }
879
880                         fprintf(F, "\t.text");
881                 }
882                 else {
883                         /* one jump is enough */
884                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(tbl.branches[0].target, buf));
885                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* only one case given */");
886                         IA32_DO_EMIT(irn);
887                 }
888         }
889         else { // no jump table
890                 for (i = 0; i < tbl.num_branches; ++i) {
891                         lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "cmpl %d, %1S", tbl.branches[i].value, irn);
892                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */", i);
893                         IA32_DO_EMIT(irn);
894                         fprintf(F, "\tje %s\n", get_cfop_target(tbl.branches[i].target, buf));
895                 }
896
897                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(tbl.defProj, buf));
898                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default case */");
899                 IA32_DO_EMIT(irn);
900         }
901
902         if (tbl.label)
903                 free(tbl.label);
904         if (tbl.branches)
905                 free(tbl.branches);
906 }
907
908 /**
909  * Emits code for a unconditional jump.
910  */
911 static void emit_Jmp(const ir_node *irn, ia32_emit_env_t *env) {
912         ir_node *block, *next_bl;
913         FILE *F = env->out;
914         char buf[SNPRINTF_BUF_LEN], cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
915
916         /* for now, the code works for scheduled and non-schedules blocks */
917         block = get_nodes_block(irn);
918
919         /* we have a block schedule */
920         next_bl = next_blk_sched(block);
921         if (get_cfop_target_block(irn) != next_bl) {
922                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(irn, buf));
923                 lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%+F) */", irn, get_cfop_target_block(irn));
924         }
925         else {
926                 cmd_buf[0] = '\0';
927                 lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* fallthrough %s */", get_cfop_target(irn, buf));
928         }
929         IA32_DO_EMIT(irn);
930 }
931
932 /****************************
933  *                  _
934  *                 (_)
935  *  _ __  _ __ ___  _  ___
936  * | '_ \| '__/ _ \| |/ __|
937  * | |_) | | | (_) | |\__ \
938  * | .__/|_|  \___/| ||___/
939  * | |            _/ |
940  * |_|           |__/
941  ****************************/
942
943 /**
944  * Emits code for a proj -> node
945  */
946 static void emit_Proj(const ir_node *irn, ia32_emit_env_t *env) {
947         ir_node *pred = get_Proj_pred(irn);
948
949         if (get_irn_op(pred) == op_Start) {
950                 switch(get_Proj_proj(irn)) {
951                         case pn_Start_X_initial_exec:
952                                 emit_Jmp(irn, env);
953                                 break;
954                         default:
955                                 break;
956                 }
957         }
958 }
959
960 /**********************************
961  *   _____                  ____
962  *  / ____|                |  _ \
963  * | |     ___  _ __  _   _| |_) |
964  * | |    / _ \| '_ \| | | |  _ <
965  * | |___| (_) | |_) | |_| | |_) |
966  *  \_____\___/| .__/ \__, |____/
967  *             | |     __/ |
968  *             |_|    |___/
969  **********************************/
970
971 /**
972  * Emit movsb/w instructions to make mov count divideable by 4
973  */
974 static void emit_CopyB_prolog(FILE *F, int rem, int size) {
975         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
976
977         fprintf(F, "\t/* memcopy %d bytes*/\n", size);
978
979         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cld");
980         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* copy direction forward*/");
981         IA32_DO_EMIT(NULL);
982
983         switch(rem) {
984                 case 1:
985                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsb");
986                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 1 */");
987                         break;
988                 case 2:
989                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsw");
990                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 2 */");
991                         break;
992                 case 3:
993                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsb");
994                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 3 */");
995                         IA32_DO_EMIT(NULL);
996                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsw");
997                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 3 */");
998                         break;
999         }
1000
1001         IA32_DO_EMIT(NULL);
1002 }
1003
1004 /**
1005  * Emit rep movsd instruction for memcopy.
1006  */
1007 static void emit_ia32_CopyB(const ir_node *irn, ia32_emit_env_t *emit_env) {
1008         FILE   *F    = emit_env->out;
1009         tarval *tv   = get_ia32_Immop_tarval(irn);
1010         int     rem  = get_tarval_long(tv);
1011         int     size = get_tarval_long(get_ia32_Immop_tarval(get_irn_n(irn, 2)));
1012         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1013
1014         emit_CopyB_prolog(F, rem, size);
1015
1016         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "rep movsd");
1017         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy */");
1018         IA32_DO_EMIT(irn);
1019 }
1020
1021 /**
1022  * Emits unrolled memcopy.
1023  */
1024 static void emit_ia32_CopyB_i(const ir_node *irn, ia32_emit_env_t *emit_env) {
1025         tarval *tv   = get_ia32_Immop_tarval(irn);
1026         int     size = get_tarval_long(tv);
1027         FILE   *F    = emit_env->out;
1028         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1029
1030         emit_CopyB_prolog(F, size & 0x3, size);
1031
1032         size >>= 2;
1033         while (size--) {
1034                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsd");
1035                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy unrolled */");
1036                 IA32_DO_EMIT(irn);
1037         }
1038 }
1039
1040
1041
1042 /***************************
1043  *   _____
1044  *  / ____|
1045  * | |     ___  _ ____   __
1046  * | |    / _ \| '_ \ \ / /
1047  * | |___| (_) | | | \ V /
1048  *  \_____\___/|_| |_|\_/
1049  *
1050  ***************************/
1051
1052 /**
1053  * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1054  */
1055 static void emit_ia32_Conv_with_FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1056         FILE               *F    = emit_env->out;
1057         const lc_arg_env_t *env  = ia32_get_arg_env();
1058         char               *from, *to, buf[64];
1059         ir_mode *src_mode, *tgt_mode;
1060         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1061
1062         src_mode = is_ia32_AddrModeS(irn) ? get_ia32_ls_mode(irn) : get_irn_mode(get_irn_n(irn, 2));
1063         tgt_mode = get_ia32_res_mode(irn);
1064
1065         from = mode_is_float(src_mode) ? (get_mode_size_bits(src_mode) == 32 ? "ss" : "sd") : "si";
1066         to   = mode_is_float(tgt_mode) ? (get_mode_size_bits(tgt_mode) == 32 ? "ss" : "sd") : "si";
1067
1068         switch(get_ia32_op_type(irn)) {
1069                 case ia32_Normal:
1070                         lc_esnprintf(env, buf, sizeof(buf), "%1D, %3S", irn, irn);
1071                         break;
1072                 case ia32_AddrModeS:
1073                         lc_esnprintf(env, buf, sizeof(buf), "%1D, %s", irn, ia32_emit_am(irn, emit_env));
1074                         break;
1075                 default:
1076                         assert(0 && "unsupported op type for Conv");
1077         }
1078
1079         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cvt%s2%s %s", from, to, buf);
1080         lc_esnprintf(env, cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%+F, %+F) */", irn, src_mode, tgt_mode);
1081         IA32_DO_EMIT(irn);
1082 }
1083
1084 static void emit_ia32_Conv_I2FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1085         emit_ia32_Conv_with_FP(irn, emit_env);
1086 }
1087
1088 static void emit_ia32_Conv_FP2I(const ir_node *irn, ia32_emit_env_t *emit_env) {
1089         emit_ia32_Conv_with_FP(irn, emit_env);
1090 }
1091
1092 static void emit_ia32_Conv_FP2FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1093         emit_ia32_Conv_with_FP(irn, emit_env);
1094 }
1095
1096 /**
1097  * Emits code for an Int conversion.
1098  */
1099 static void emit_ia32_Conv_I2I(const ir_node *irn, ia32_emit_env_t *emit_env) {
1100         FILE               *F    = emit_env->out;
1101         const lc_arg_env_t *env  = ia32_get_arg_env();
1102         char *move_cmd, *conv_cmd;
1103         ir_mode *src_mode, *tgt_mode;
1104         int n, m;
1105         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1106         const arch_register_t *in_reg, *out_reg;
1107
1108         src_mode = is_ia32_AddrModeS(irn) ? get_ia32_ls_mode(irn) : get_irn_mode(get_irn_n(irn, 2));
1109         tgt_mode = get_ia32_res_mode(irn);
1110
1111         n = get_mode_size_bits(src_mode);
1112         m = get_mode_size_bits(tgt_mode);
1113
1114         if (mode_is_signed(n < m ? src_mode : tgt_mode)) {
1115                 move_cmd = "movsx";
1116                 if (n == 8 || m == 8)
1117                         conv_cmd = "cbw";
1118                 else if (n == 16 || m == 16)
1119                         conv_cmd = "cwde";
1120                 else
1121                         assert(0 && "unsupported Conv_I2I");
1122         }
1123         else {
1124                 move_cmd = "movzx";
1125                 conv_cmd = NULL;
1126         }
1127
1128         switch(get_ia32_op_type(irn)) {
1129                 case ia32_Normal:
1130                         in_reg  = get_in_reg(irn, 2);
1131                         out_reg = get_out_reg(irn, 0);
1132
1133                         if (REGS_ARE_EQUAL(in_reg, &ia32_gp_regs[REG_EAX]) &&
1134                                 REGS_ARE_EQUAL(out_reg, in_reg)                &&
1135                                 mode_is_signed(n < m ? src_mode : tgt_mode))
1136                         {
1137                                 /* argument and result are both in EAX and */
1138                                 /* signedness is ok: -> use converts       */
1139                                 lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s", conv_cmd);
1140                         }
1141                         else if (REGS_ARE_EQUAL(out_reg, in_reg) &&
1142                                 ! mode_is_signed(n < m ? src_mode : tgt_mode))
1143                         {
1144                                 /* argument and result are in the same register */
1145                                 /* and signedness is ok: -> use and with mask   */
1146                                 int mask = (1 << (n < m ? n : m)) - 1;
1147                                 lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "and %1D, 0x%x", irn, mask);
1148                         }
1149                         else {
1150                                 /* use move w/o sign extension */
1151                                 lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s %1D, %%%s",
1152                                         move_cmd, irn, ia32_get_reg_name_for_mode(emit_env, n < m ? src_mode : tgt_mode, in_reg));
1153                         }
1154
1155                         break;
1156                 case ia32_AddrModeS:
1157                         lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s %1D, %s",
1158                                 move_cmd, irn, ia32_emit_am(irn, emit_env));
1159                         break;
1160                 default:
1161                         assert(0 && "unsupported op type for Conv");
1162         }
1163
1164         lc_esnprintf(env, cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%d Bit mode_%F -> %d Bit mode_%F) */",
1165                 irn, n, src_mode, m, tgt_mode);
1166
1167         IA32_DO_EMIT(irn);
1168 }
1169
1170 /**
1171  * Emits code for an 8Bit Int conversion.
1172  */
1173 void emit_ia32_Conv_I2I8Bit(const ir_node *irn, ia32_emit_env_t *emit_env) {
1174         emit_ia32_Conv_I2I(irn, emit_env);
1175 }
1176
1177
1178 /*******************************************
1179  *  _                          _
1180  * | |                        | |
1181  * | |__   ___ _ __   ___   __| | ___  ___
1182  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
1183  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
1184  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
1185  *
1186  *******************************************/
1187
1188 /**
1189  * Emits a backend call
1190  */
1191 static void emit_be_Call(const ir_node *irn, ia32_emit_env_t *emit_env) {
1192         FILE *F = emit_env->out;
1193         entity *ent = be_Call_get_entity(irn);
1194         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1195
1196         if (ent) {
1197                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "call %s", get_entity_name(ent));
1198         }
1199         else {
1200                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "%1D", get_irn_n(irn, be_pos_Call_ptr));
1201         }
1202
1203         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (be_Call) */", irn);
1204
1205         IA32_DO_EMIT(irn);
1206 }
1207
1208 /**
1209  * Emits code to increase stack pointer.
1210  */
1211 static void emit_be_IncSP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1212         FILE          *F    = emit_env->out;
1213         unsigned       offs = be_get_IncSP_offset(irn);
1214         be_stack_dir_t dir  = be_get_IncSP_direction(irn);
1215         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1216
1217         if (offs) {
1218                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1S,%s%u", irn,
1219                         (dir == be_stack_dir_expand) ? " -" : " ", offs);
1220                 lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (IncSP) */", irn);
1221         }
1222         else {
1223                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
1224                 lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* omitted %+F (IncSP) with 0 */", irn);
1225         }
1226
1227         IA32_DO_EMIT(irn);
1228 }
1229
1230 /**
1231  * Emits code to set stack pointer.
1232  */
1233 static void emit_be_SetSP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1234         FILE *F = emit_env->out;
1235         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1236
1237         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, %3S", irn, irn);
1238         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (restore SP) */", irn);
1239         IA32_DO_EMIT(irn);
1240 }
1241
1242 /**
1243  * Emits code for Copy.
1244  */
1245 static void emit_be_Copy(const ir_node *irn, ia32_emit_env_t *emit_env) {
1246         FILE *F = emit_env->out;
1247         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1248
1249         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, %1S", irn, irn);
1250         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
1251         IA32_DO_EMIT(irn);
1252 }
1253
1254 /**
1255  * Emits code for exchange.
1256  */
1257 static void emit_be_Perm(const ir_node *irn, ia32_emit_env_t *emit_env) {
1258         FILE *F = emit_env->out;
1259         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1260
1261         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "xchg %1S, %2S", irn, irn);
1262         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%1A, %2A) */", irn, irn, irn);
1263         IA32_DO_EMIT(irn);
1264 }
1265
1266 /***********************************************************************************
1267  *                  _          __                                             _
1268  *                 (_)        / _|                                           | |
1269  *  _ __ ___   __ _ _ _ __   | |_ _ __ __ _ _ __ ___   _____      _____  _ __| | __
1270  * | '_ ` _ \ / _` | | '_ \  |  _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
1271  * | | | | | | (_| | | | | | | | | | | (_| | | | | | |  __/\ V  V / (_) | |  |   <
1272  * |_| |_| |_|\__,_|_|_| |_| |_| |_|  \__,_|_| |_| |_|\___| \_/\_/ \___/|_|  |_|\_\
1273  *
1274  ***********************************************************************************/
1275
1276 /**
1277  * Enters the emitter functions for handled nodes into the generic
1278  * pointer of an opcode.
1279  */
1280 static void ia32_register_emitters(void) {
1281
1282 #define IA32_EMIT(a) op_ia32_##a->ops.generic = (op_func)emit_ia32_##a
1283 #define EMIT(a)      op_##a->ops.generic = (op_func)emit_##a
1284 #define BE_EMIT(a)   op_be_##a->ops.generic = (op_func)emit_be_##a
1285
1286         /* first clear the generic function pointer for all ops */
1287         clear_irp_opcodes_generic_func();
1288
1289         /* register all emitter functions defined in spec */
1290         ia32_register_spec_emitters();
1291
1292         /* other ia32 emitter functions */
1293         IA32_EMIT(CondJmp);
1294         IA32_EMIT(TestJmp);
1295         IA32_EMIT(CJmp);
1296         IA32_EMIT(CJmpAM);
1297         IA32_EMIT(SwitchJmp);
1298         IA32_EMIT(CopyB);
1299         IA32_EMIT(CopyB_i);
1300         IA32_EMIT(Conv_I2FP);
1301         IA32_EMIT(Conv_FP2I);
1302         IA32_EMIT(Conv_FP2FP);
1303         IA32_EMIT(Conv_I2I);
1304         IA32_EMIT(Conv_I2I8Bit);
1305
1306         /* benode emitter */
1307         BE_EMIT(Call);
1308         BE_EMIT(IncSP);
1309         BE_EMIT(SetSP);
1310         BE_EMIT(Copy);
1311         BE_EMIT(Perm);
1312
1313         /* firm emitter */
1314         EMIT(Jmp);
1315         EMIT(Proj);
1316
1317 #undef IA32_EMIT
1318 #undef BE_EMIT
1319 #undef EMIT
1320 }
1321
1322 /**
1323  * Emits code for a node.
1324  */
1325 static void ia32_emit_node(const ir_node *irn, void *env) {
1326         ia32_emit_env_t        *emit_env = env;
1327         firm_dbg_module_t *mod      = emit_env->mod;
1328         FILE              *F        = emit_env->out;
1329         ir_op             *op       = get_irn_op(irn);
1330
1331         DBG((mod, LEVEL_1, "emitting code for %+F\n", irn));
1332
1333         if (op->ops.generic) {
1334                 void (*emit)(const ir_node *, void *) = (void (*)(const ir_node *, void *))op->ops.generic;
1335                 (*emit)(irn, env);
1336         }
1337         else {
1338                 ir_fprintf(F, "\t%35s /* %+F */\n", " ", irn);
1339         }
1340 }
1341
1342 /**
1343  * Walks over the nodes in a block connected by scheduling edges
1344  * and emits code for each node.
1345  */
1346 static void ia32_gen_block(ir_node *block, void *env) {
1347         const ir_node *irn;
1348
1349         if (! is_Block(block))
1350                 return;
1351
1352         fprintf(((ia32_emit_env_t *)env)->out, BLOCK_PREFIX("%ld:\n"), get_irn_node_nr(block));
1353         sched_foreach(block, irn) {
1354                 ia32_emit_node(irn, env);
1355         }
1356 }
1357
1358 /**
1359  * Emits code for function start.
1360  */
1361 static void ia32_emit_func_prolog(FILE *F, ir_graph *irg) {
1362         entity     *irg_ent  = get_irg_entity(irg);
1363         const char *irg_name = get_entity_name(irg_ent);
1364
1365         fprintf(F, "\t.text\n");
1366         if (get_entity_visibility(irg_ent) == visibility_external_visible) {
1367                 fprintf(F, ".globl %s\n", irg_name);
1368         }
1369         fprintf(F, "\t.type\t%s, @function\n", irg_name);
1370         fprintf(F, "%s:\n", irg_name);
1371 }
1372
1373 /**
1374  * Emits code for function end
1375  */
1376 static void ia32_emit_func_epilog(FILE *F, ir_graph *irg) {
1377         const char *irg_name = get_entity_name(get_irg_entity(irg));
1378
1379         fprintf(F, "\tret\n");
1380         fprintf(F, "\t.size\t%s, .-%s\n\n", irg_name, irg_name);
1381 }
1382
1383 /**
1384  * Block-walker:
1385  * Sets labels for control flow nodes (jump target)
1386  * TODO: Jump optimization
1387  */
1388 static void ia32_gen_labels(ir_node *block, void *env) {
1389         ir_node *pred;
1390         int n = get_Block_n_cfgpreds(block);
1391
1392         for (n--; n >= 0; n--) {
1393                 pred = get_Block_cfgpred(block, n);
1394                 set_irn_link(pred, block);
1395         }
1396 }
1397
1398 typedef struct {
1399         ir_node *start;
1400         ir_node *end;
1401 } anchor;
1402
1403 /**
1404  * Ext-Block walker: create a block schedule
1405  */
1406 static void create_block_list(ir_extblk *blk, void *env) {
1407         anchor *list = env;
1408         int i, n;
1409
1410         for (i = 0, n = get_extbb_n_blocks(blk); i < n; ++i) {
1411                 ir_node *block = get_extbb_block(blk, i);
1412
1413                 set_irn_link(block, NULL);
1414                 if (list->start)
1415                         set_irn_link(list->end, block);
1416                 else
1417                         list->start = block;
1418
1419                 list->end = block;
1420         }
1421 }
1422
1423 /**
1424  * Main driver. Emits the code for one routine.
1425  */
1426 void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) {
1427         ia32_emit_env_t emit_env;
1428         anchor list;
1429         ir_node *block;
1430
1431         emit_env.mod      = firm_dbg_register("firm.be.ia32.emitter");
1432         emit_env.out      = F;
1433         emit_env.arch_env = cg->arch_env;
1434         emit_env.cg       = cg;
1435         emit_env.isa      = (ia32_isa_t *)cg->arch_env->isa;
1436
1437         /* set the global arch_env (needed by print hooks) */
1438         arch_env = cg->arch_env;
1439
1440         ia32_register_emitters();
1441
1442         ia32_emit_func_prolog(F, irg);
1443         irg_block_walk_graph(irg, ia32_gen_labels, NULL, &emit_env);
1444
1445         if (cg->opt.extbb) {
1446                 /* schedule extended basic blocks */
1447
1448                 compute_extbb(irg);
1449
1450                 list.start = NULL;
1451                 list.end   = NULL;
1452                 irg_extblock_walk_graph(irg, NULL, create_block_list, &list);
1453
1454                 have_block_sched = 1;
1455                 for (block = list.start; block; block = get_irn_link(block))
1456                         ia32_gen_block(block, &emit_env);
1457         }
1458         else {
1459                 /* "normal" block schedule */
1460
1461                 have_block_sched = 0;
1462                 irg_walk_blkwise_graph(irg, NULL, ia32_gen_block, &emit_env);
1463         }
1464
1465         ia32_emit_func_epilog(F, irg);
1466 }