reimplement the long long -> double, conversion. Removed broken double -> long long...
[libfirm] / ir / be / ia32 / ia32_emitter.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       This file implements the ia32 node emitter.
23  * @author      Christian Wuerdig, Matthias Braun
24  * @version     $Id$
25  */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <limits.h>
31
32 #include "xmalloc.h"
33 #include "tv.h"
34 #include "iredges.h"
35 #include "debug.h"
36 #include "irgwalk.h"
37 #include "irprintf.h"
38 #include "irop_t.h"
39 #include "irargs_t.h"
40 #include "irprog_t.h"
41 #include "iredges_t.h"
42 #include "execfreq.h"
43 #include "error.h"
44 #include "raw_bitset.h"
45 #include "dbginfo.h"
46
47 #include "../besched_t.h"
48 #include "../benode_t.h"
49 #include "../beabi.h"
50 #include "../be_dbgout.h"
51 #include "../beemitter.h"
52 #include "../begnuas.h"
53 #include "../beirg_t.h"
54
55 #include "ia32_emitter.h"
56 #include "gen_ia32_emitter.h"
57 #include "gen_ia32_regalloc_if.h"
58 #include "ia32_nodes_attr.h"
59 #include "ia32_new_nodes.h"
60 #include "ia32_map_regs.h"
61 #include "ia32_architecture.h"
62 #include "bearch_ia32_t.h"
63
64 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
65
66 #define BLOCK_PREFIX ".L"
67
68 #define SNPRINTF_BUF_LEN 128
69
70 static const arch_env_t *arch_env;
71 static const ia32_isa_t *isa;
72 static ia32_code_gen_t  *cg;
73
74 /**
75  * Returns the register at in position pos.
76  */
77 static const arch_register_t *get_in_reg(const ir_node *irn, int pos)
78 {
79         ir_node               *op;
80         const arch_register_t *reg = NULL;
81
82         assert(get_irn_arity(irn) > pos && "Invalid IN position");
83
84         /* The out register of the operator at position pos is the
85            in register we need. */
86         op = get_irn_n(irn, pos);
87
88         reg = arch_get_irn_register(arch_env, op);
89
90         assert(reg && "no in register found");
91
92         if(reg == &ia32_gp_regs[REG_GP_NOREG])
93                 panic("trying to emit noreg for %+F input %d", irn, pos);
94
95         /* in case of unknown register: just return a valid register */
96         if (reg == &ia32_gp_regs[REG_GP_UKNWN]) {
97                 const arch_register_req_t *req;
98
99                 /* ask for the requirements */
100                 req = arch_get_register_req(arch_env, irn, pos);
101
102                 if (arch_register_req_is(req, limited)) {
103                         /* in case of limited requirements: get the first allowed register */
104                         unsigned idx = rbitset_next(req->limited, 0, 1);
105                         reg = arch_register_for_index(req->cls, idx);
106                 } else {
107                         /* otherwise get first register in class */
108                         reg = arch_register_for_index(req->cls, 0);
109                 }
110         }
111
112         return reg;
113 }
114
115 /**
116  * Returns the register at out position pos.
117  */
118 static const arch_register_t *get_out_reg(const ir_node *irn, int pos)
119 {
120         ir_node               *proj;
121         const arch_register_t *reg = NULL;
122
123         /* 1st case: irn is not of mode_T, so it has only                 */
124         /*           one OUT register -> good                             */
125         /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
126         /*           Proj with the corresponding projnum for the register */
127
128         if (get_irn_mode(irn) != mode_T) {
129                 assert(pos == 0);
130                 reg = arch_get_irn_register(arch_env, irn);
131         } else if (is_ia32_irn(irn)) {
132                 reg = get_ia32_out_reg(irn, pos);
133         } else {
134                 const ir_edge_t *edge;
135
136                 foreach_out_edge(irn, edge) {
137                         proj = get_edge_src_irn(edge);
138                         assert(is_Proj(proj) && "non-Proj from mode_T node");
139                         if (get_Proj_proj(proj) == pos) {
140                                 reg = arch_get_irn_register(arch_env, proj);
141                                 break;
142                         }
143                 }
144         }
145
146         assert(reg && "no out register found");
147         return reg;
148 }
149
150 /**
151  * Add a number to a prefix. This number will not be used a second time.
152  */
153 static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
154 {
155         static unsigned long id = 0;
156         snprintf(buf, buflen, "%s%lu", prefix, ++id);
157         return buf;
158 }
159
160 /*************************************************************
161  *             _       _    __   _          _
162  *            (_)     | |  / _| | |        | |
163  *  _ __  _ __ _ _ __ | |_| |_  | |__   ___| |_ __   ___ _ __
164  * | '_ \| '__| | '_ \| __|  _| | '_ \ / _ \ | '_ \ / _ \ '__|
165  * | |_) | |  | | | | | |_| |   | | | |  __/ | |_) |  __/ |
166  * | .__/|_|  |_|_| |_|\__|_|   |_| |_|\___|_| .__/ \___|_|
167  * | |                                       | |
168  * |_|                                       |_|
169  *************************************************************/
170
171 static void emit_8bit_register(const arch_register_t *reg)
172 {
173         const char *reg_name = arch_register_get_name(reg);
174
175         be_emit_char('%');
176         be_emit_char(reg_name[1]);
177         be_emit_char('l');
178 }
179
180 static void emit_16bit_register(const arch_register_t *reg)
181 {
182         const char *reg_name = ia32_get_mapped_reg_name(isa->regs_16bit, reg);
183
184         be_emit_char('%');
185         be_emit_string(reg_name);
186 }
187
188 static void emit_register(const arch_register_t *reg, const ir_mode *mode)
189 {
190         const char *reg_name;
191
192         if(mode != NULL) {
193                 int size = get_mode_size_bits(mode);
194                 if(size == 8) {
195                         emit_8bit_register(reg);
196                         return;
197                 } else if(size == 16) {
198                         emit_16bit_register(reg);
199                         return;
200                 } else {
201                         assert(mode_is_float(mode) || size == 32);
202                 }
203         }
204
205         reg_name = arch_register_get_name(reg);
206
207         be_emit_char('%');
208         be_emit_string(reg_name);
209 }
210
211 void ia32_emit_source_register(const ir_node *node, int pos)
212 {
213         const arch_register_t *reg      = get_in_reg(node, pos);
214
215         emit_register(reg, NULL);
216 }
217
218 static void emit_ia32_Immediate(const ir_node *node);
219
220 void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos)
221 {
222         const arch_register_t *reg;
223         ir_node               *in = get_irn_n(node, pos);
224         if(is_ia32_Immediate(in)) {
225                 emit_ia32_Immediate(in);
226                 return;
227         }
228
229         reg = get_in_reg(node, pos);
230         emit_8bit_register(reg);
231 }
232
233 void ia32_emit_dest_register(const ir_node *node, int pos)
234 {
235         const arch_register_t *reg  = get_out_reg(node, pos);
236
237         emit_register(reg, NULL);
238 }
239
240 void ia32_emit_8bit_dest_register(const ir_node *node, int pos)
241 {
242         const arch_register_t *reg  = get_out_reg(node, pos);
243
244         emit_register(reg, mode_Bu);
245 }
246
247 void ia32_emit_x87_register(const ir_node *node, int pos)
248 {
249         const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
250
251         assert(pos < 3);
252         be_emit_char('%');
253         be_emit_string(attr->x87[pos]->name);
254 }
255
256 static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
257 {
258         if(mode_is_float(mode)) {
259                 switch(get_mode_size_bits(mode)) {
260                 case 32: be_emit_char('s'); return;
261                 case 64: be_emit_char('l'); return;
262                 case 80:
263                 case 96: be_emit_char('t'); return;
264                 }
265         } else {
266                 assert(mode_is_int(mode) || mode_is_reference(mode));
267                 switch(get_mode_size_bits(mode)) {
268                 case 64: be_emit_cstring("ll"); return;
269                                  /* gas docu says q is the suffix but gcc, objdump and icc use
270                                         ll apparently */
271                 case 32: be_emit_char('l'); return;
272                 case 16: be_emit_char('w'); return;
273                 case 8:  be_emit_char('b'); return;
274                 }
275         }
276         panic("Can't output mode_suffix for %+F\n", mode);
277 }
278
279 void ia32_emit_mode_suffix(const ir_node *node)
280 {
281         ir_mode *mode = get_ia32_ls_mode(node);
282         if(mode == NULL)
283                 mode = mode_Iu;
284
285         ia32_emit_mode_suffix_mode(mode);
286 }
287
288 void ia32_emit_x87_mode_suffix(const ir_node *node)
289 {
290         ir_mode *mode = get_ia32_ls_mode(node);
291         assert(mode != NULL);
292         /* we only need to emit the mode on address mode */
293         if(get_ia32_op_type(node) != ia32_Normal)
294                 ia32_emit_mode_suffix_mode(mode);
295 }
296
297 static
298 char get_xmm_mode_suffix(ir_mode *mode)
299 {
300         assert(mode_is_float(mode));
301         switch(get_mode_size_bits(mode)) {
302         case 32:
303                 return 's';
304         case 64:
305                 return 'd';
306         default:
307                 assert(0);
308         }
309         return '%';
310 }
311
312 void ia32_emit_xmm_mode_suffix(const ir_node *node)
313 {
314         ir_mode *mode = get_ia32_ls_mode(node);
315         assert(mode != NULL);
316         be_emit_char('s');
317         be_emit_char(get_xmm_mode_suffix(mode));
318 }
319
320 void ia32_emit_xmm_mode_suffix_s(const ir_node *node)
321 {
322         ir_mode *mode = get_ia32_ls_mode(node);
323         assert(mode != NULL);
324         be_emit_char(get_xmm_mode_suffix(mode));
325 }
326
327 void ia32_emit_extend_suffix(const ir_mode *mode)
328 {
329         if(get_mode_size_bits(mode) == 32)
330                 return;
331         if(mode_is_signed(mode)) {
332                 be_emit_char('s');
333         } else {
334                 be_emit_char('z');
335         }
336 }
337
338 static
339 void ia32_emit_function_object(const char *name)
340 {
341         switch (be_gas_flavour) {
342         case GAS_FLAVOUR_NORMAL:
343                 be_emit_cstring("\t.type\t");
344                 be_emit_string(name);
345                 be_emit_cstring(", @function\n");
346                 be_emit_write_line();
347                 break;
348         case GAS_FLAVOUR_MINGW:
349                 be_emit_cstring("\t.def\t");
350                 be_emit_string(name);
351                 be_emit_cstring(";\t.scl\t2;\t.type\t32;\t.endef\n");
352                 be_emit_write_line();
353                 break;
354         default:
355                 break;
356         }
357 }
358
359 static
360 void ia32_emit_function_size(const char *name)
361 {
362         switch (be_gas_flavour) {
363         case GAS_FLAVOUR_NORMAL:
364                 be_emit_cstring("\t.size\t");
365                 be_emit_string(name);
366                 be_emit_cstring(", .-");
367                 be_emit_string(name);
368                 be_emit_char('\n');
369                 be_emit_write_line();
370                 break;
371         default:
372                 break;
373         }
374 }
375
376
377 void ia32_emit_source_register_or_immediate(const ir_node *node, int pos)
378 {
379         ir_node *in = get_irn_n(node, pos);
380         if(is_ia32_Immediate(in)) {
381                 emit_ia32_Immediate(in);
382         } else {
383                 const ir_mode         *mode = get_ia32_ls_mode(node);
384                 const arch_register_t *reg  = get_in_reg(node, pos);
385                 emit_register(reg, mode);
386         }
387 }
388
389 /**
390  * Emits registers and/or address mode of a binary operation.
391  */
392 void ia32_emit_binop(const ir_node *node) {
393         const ir_node         *right_op  = get_irn_n(node, n_ia32_binary_right);
394         const ir_mode         *mode      = get_ia32_ls_mode(node);
395         const arch_register_t *reg_left;
396
397         switch(get_ia32_op_type(node)) {
398         case ia32_Normal:
399                 reg_left = get_in_reg(node, n_ia32_binary_left);
400                 if(is_ia32_Immediate(right_op)) {
401                         emit_ia32_Immediate(right_op);
402                         be_emit_cstring(", ");
403                         emit_register(reg_left, mode);
404                         break;
405                 } else {
406                         const arch_register_t *reg_right
407                                 = get_in_reg(node, n_ia32_binary_right);
408                         emit_register(reg_right, mode);
409                         be_emit_cstring(", ");
410                         emit_register(reg_left, mode);
411                 }
412                 break;
413         case ia32_AddrModeS:
414                 if(is_ia32_Immediate(right_op)) {
415                         emit_ia32_Immediate(right_op);
416                         be_emit_cstring(", ");
417                         ia32_emit_am(node);
418                 } else {
419                         reg_left = get_in_reg(node, n_ia32_binary_left);
420                         ia32_emit_am(node);
421                         be_emit_cstring(", ");
422                         emit_register(reg_left, mode);
423                 }
424                 break;
425         case ia32_AddrModeD:
426                 panic("DestMode can't be output by %%binop anymore");
427                 break;
428         default:
429                 assert(0 && "unsupported op type");
430         }
431 }
432
433 /**
434  * Emits registers and/or address mode of a binary operation.
435  */
436 void ia32_emit_x87_binop(const ir_node *node) {
437         switch(get_ia32_op_type(node)) {
438                 case ia32_Normal:
439                         {
440                                 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
441                                 const arch_register_t *in1      = x87_attr->x87[0];
442                                 const arch_register_t *in2      = x87_attr->x87[1];
443                                 const arch_register_t *out      = x87_attr->x87[2];
444                                 const arch_register_t *in;
445
446                                 in  = out ? ((out == in2) ? in1 : in2) : in2;
447                                 out = out ? out : in1;
448
449                                 be_emit_char('%');
450                                 be_emit_string(arch_register_get_name(in));
451                                 be_emit_cstring(", %");
452                                 be_emit_string(arch_register_get_name(out));
453                         }
454                         break;
455                 case ia32_AddrModeS:
456                         ia32_emit_am(node);
457                         break;
458                 case ia32_AddrModeD:
459                 default:
460                         assert(0 && "unsupported op type");
461         }
462 }
463
464 void ia32_emit_am_or_dest_register(const ir_node *node,
465                                    int pos) {
466         if(get_ia32_op_type(node) == ia32_Normal) {
467                 ia32_emit_dest_register(node, pos);
468         } else {
469                 assert(get_ia32_op_type(node) == ia32_AddrModeD);
470                 ia32_emit_am(node);
471         }
472 }
473
474 /**
475  * Emits registers and/or address mode of a unary operation.
476  */
477 void ia32_emit_unop(const ir_node *node, int pos) {
478         const ir_node *op;
479
480         switch(get_ia32_op_type(node)) {
481         case ia32_Normal:
482                 op = get_irn_n(node, pos);
483                 if (is_ia32_Immediate(op)) {
484                         emit_ia32_Immediate(op);
485                 } else {
486                         ia32_emit_source_register(node, pos);
487                 }
488                 break;
489         case ia32_AddrModeS:
490         case ia32_AddrModeD:
491                 ia32_emit_am(node);
492                 break;
493         default:
494                 assert(0 && "unsupported op type");
495         }
496 }
497
498 static void ia32_emit_entity(ir_entity *entity)
499 {
500         ident *id;
501
502         set_entity_backend_marked(entity, 1);
503         id = get_entity_ld_ident(entity);
504         be_emit_ident(id);
505
506         if(get_entity_owner(entity) == get_tls_type()) {
507                 if (get_entity_visibility(entity) == visibility_external_allocated) {
508                         be_emit_cstring("@INDNTPOFF");
509                 } else {
510                         be_emit_cstring("@NTPOFF");
511                 }
512         }
513 }
514
515 /**
516  * Emits address mode.
517  */
518 void ia32_emit_am(const ir_node *node) {
519         ir_entity *ent       = get_ia32_am_sc(node);
520         int        offs      = get_ia32_am_offs_int(node);
521         ir_node   *base      = get_irn_n(node, 0);
522         int        has_base  = !is_ia32_NoReg_GP(base);
523         ir_node   *index     = get_irn_n(node, 1);
524         int        has_index = !is_ia32_NoReg_GP(index);
525
526         /* just to be sure... */
527         assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
528
529         /* emit offset */
530         if (ent != NULL) {
531                 if (is_ia32_am_sc_sign(node))
532                         be_emit_char('-');
533                 ia32_emit_entity(ent);
534         }
535
536         if(offs != 0) {
537                 if(ent != NULL) {
538                         be_emit_irprintf("%+d", offs);
539                 } else {
540                         be_emit_irprintf("%d", offs);
541                 }
542         }
543
544         if (has_base || has_index) {
545                 be_emit_char('(');
546
547                 /* emit base */
548                 if (has_base) {
549                         const arch_register_t *reg = get_in_reg(node, n_ia32_base);
550                         emit_register(reg, NULL);
551                 }
552
553                 /* emit index + scale */
554                 if (has_index) {
555                         const arch_register_t *reg = get_in_reg(node, n_ia32_index);
556                         int scale;
557                         be_emit_char(',');
558                         emit_register(reg, NULL);
559
560                         scale = get_ia32_am_scale(node);
561                         if (scale > 0) {
562                                 be_emit_irprintf(",%d", 1 << get_ia32_am_scale(node));
563                         }
564                 }
565                 be_emit_char(')');
566         }
567
568         /* special case if nothing is set */
569         if(ent == NULL && offs == 0 && !has_base && !has_index) {
570                 be_emit_char('0');
571         }
572 }
573
574 static void emit_ia32_IMul(const ir_node *node)
575 {
576         ir_node               *left    = get_irn_n(node, n_ia32_IMul_left);
577         const arch_register_t *out_reg = get_out_reg(node, pn_ia32_IMul_res);
578
579         be_emit_cstring("\timul");
580         ia32_emit_mode_suffix(node);
581         be_emit_char(' ');
582
583         ia32_emit_binop(node);
584
585         /* do we need the 3-address form? */
586         if(is_ia32_NoReg_GP(left) ||
587                         get_in_reg(node, n_ia32_IMul_left) != out_reg) {
588                 be_emit_cstring(", ");
589                 emit_register(out_reg, get_ia32_ls_mode(node));
590         }
591         be_emit_finish_line_gas(node);
592 }
593
594 /*************************************************
595  *                 _ _                         _
596  *                (_) |                       | |
597  *   ___ _ __ ___  _| |_    ___ ___  _ __   __| |
598  *  / _ \ '_ ` _ \| | __|  / __/ _ \| '_ \ / _` |
599  * |  __/ | | | | | | |_  | (_| (_) | | | | (_| |
600  *  \___|_| |_| |_|_|\__|  \___\___/|_| |_|\__,_|
601  *
602  *************************************************/
603
604 #undef IA32_DO_EMIT
605 #define IA32_DO_EMIT(irn) ia32_fprintf_format(F, irn, cmd_buf, cmnt_buf)
606
607 /*
608  * coding of conditions
609  */
610 struct cmp2conditon_t {
611         const char *name;
612         int         num;
613 };
614
615 /*
616  * positive conditions for signed compares
617  */
618 static const struct cmp2conditon_t cmp2condition_s[] = {
619         { NULL,              pn_Cmp_False },  /* always false */
620         { "e",               pn_Cmp_Eq },     /* == */
621         { "l",               pn_Cmp_Lt },     /* < */
622         { "le",              pn_Cmp_Le },     /* <= */
623         { "g",               pn_Cmp_Gt },     /* > */
624         { "ge",              pn_Cmp_Ge },     /* >= */
625         { "ne",              pn_Cmp_Lg },     /* != */
626         { NULL,              pn_Cmp_Leg},     /* always true */
627 };
628
629 /*
630  * positive conditions for unsigned compares
631  */
632 static const struct cmp2conditon_t cmp2condition_u[] = {
633         { NULL,              pn_Cmp_False },  /* always false */
634         { "e",               pn_Cmp_Eq },     /* == */
635         { "b",               pn_Cmp_Lt },     /* < */
636         { "be",              pn_Cmp_Le },     /* <= */
637         { "a",               pn_Cmp_Gt },     /* > */
638         { "ae",              pn_Cmp_Ge },     /* >= */
639         { "ne",              pn_Cmp_Lg },     /* != */
640         { NULL,              pn_Cmp_Leg },   /* always true  */
641 };
642
643 enum {
644         ia32_pn_Cmp_unsigned = 0x1000,
645         ia32_pn_Cmp_float    = 0x2000,
646 };
647
648 /**
649  * walks up a tree of copies/perms/spills/reloads to find the original value
650  * that is moved around
651  */
652 static ir_node *find_original_value(ir_node *node)
653 {
654         inc_irg_visited(current_ir_graph);
655         while(1) {
656                 mark_irn_visited(node);
657                 if(be_is_Copy(node)) {
658                         node = be_get_Copy_op(node);
659                 } else if(be_is_CopyKeep(node)) {
660                         node = be_get_CopyKeep_op(node);
661                 } else if(is_Proj(node)) {
662                         ir_node *pred = get_Proj_pred(node);
663                         if(be_is_Perm(pred)) {
664                                 node = get_irn_n(pred, get_Proj_proj(node));
665                         } else if(be_is_MemPerm(pred)) {
666                                 node = get_irn_n(pred, get_Proj_proj(node) + 1);
667                         } else if(is_ia32_Load(pred)) {
668                                 node = get_irn_n(pred, n_ia32_Load_mem);
669                         } else {
670                                 return node;
671                         }
672                 } else if(is_ia32_Store(node)) {
673                         node = get_irn_n(node, n_ia32_Store_val);
674                 } else if(is_Phi(node)) {
675                         int i, arity;
676                         arity = get_irn_arity(node);
677                         for(i = 0; i < arity; ++i) {
678                                 ir_node *in = get_irn_n(node, i);
679                                 if(irn_visited(in))
680                                         continue;
681                                 node = in;
682                                 break;
683                         }
684                         assert(i < arity);
685                 } else {
686                         return node;
687                 }
688         }
689 }
690
691 static int determine_final_pnc(const ir_node *node, int flags_pos,
692                                int pnc)
693 {
694         ir_node           *flags = get_irn_n(node, flags_pos);
695         const ia32_attr_t *flags_attr;
696         flags = skip_Proj(flags);
697
698         if(is_ia32_Sahf(flags)) {
699                 ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
700                 if(!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
701                                 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
702                         cmp = find_original_value(cmp);
703                         assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
704                                || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
705                 }
706
707                 flags_attr = get_ia32_attr_const(cmp);
708                 if(flags_attr->data.ins_permuted)
709                         pnc = get_mirrored_pnc(pnc);
710                 pnc |= ia32_pn_Cmp_float;
711         } else if(is_ia32_Ucomi(flags) || is_ia32_Fucomi(flags)
712                         || is_ia32_Fucompi(flags)) {
713                 flags_attr = get_ia32_attr_const(flags);
714
715                 if(flags_attr->data.ins_permuted)
716                         pnc = get_mirrored_pnc(pnc);
717                 pnc |= ia32_pn_Cmp_float;
718         } else {
719 #if 0
720                 assert(is_ia32_Cmp(flags) || is_ia32_Test(flags)
721                                 || is_ia32_Cmp8Bit(flags) || is_ia32_Test8Bit(flags));
722 #endif
723                 flags_attr = get_ia32_attr_const(flags);
724
725                 if(flags_attr->data.ins_permuted)
726                         pnc = get_mirrored_pnc(pnc);
727                 if(flags_attr->data.cmp_unsigned)
728                         pnc |= ia32_pn_Cmp_unsigned;
729         }
730
731         return pnc;
732 }
733
734 static void ia32_emit_cmp_suffix(int pnc)
735 {
736         const char        *str;
737
738         if((pnc & ia32_pn_Cmp_float) || (pnc & ia32_pn_Cmp_unsigned)) {
739                 pnc = pnc & 7;
740                 assert(cmp2condition_u[pnc].num == pnc);
741                 str = cmp2condition_u[pnc].name;
742         } else {
743                 pnc = pnc & 7;
744                 assert(cmp2condition_s[pnc].num == pnc);
745                 str = cmp2condition_s[pnc].name;
746         }
747
748         be_emit_string(str);
749 }
750
751 void ia32_emit_cmp_suffix_node(const ir_node *node,
752                                int flags_pos)
753 {
754         const ia32_attr_t *attr = get_ia32_attr_const(node);
755
756         pn_Cmp pnc = get_ia32_condcode(node);
757
758         pnc = determine_final_pnc(node, flags_pos, pnc);
759         if(attr->data.ins_permuted) {
760                 if(pnc & ia32_pn_Cmp_float) {
761                         pnc = get_negated_pnc(pnc, mode_F);
762                 } else {
763                         pnc = get_negated_pnc(pnc, mode_Iu);
764                 }
765         }
766
767         ia32_emit_cmp_suffix(pnc);
768 }
769
770 /**
771  * Returns the target block for a control flow node.
772  */
773 static
774 ir_node *get_cfop_target_block(const ir_node *irn) {
775         return get_irn_link(irn);
776 }
777
778 /**
779  * Emits a block label for the given block.
780  */
781 static
782 void ia32_emit_block_name(const ir_node *block)
783 {
784         if (has_Block_label(block)) {
785                 be_emit_string(be_gas_label_prefix());
786                 be_emit_irprintf("%u", (unsigned)get_Block_label(block));
787         } else {
788                 be_emit_cstring(BLOCK_PREFIX);
789                 be_emit_irprintf("%d", get_irn_node_nr(block));
790         }
791 }
792
793 /**
794  * Emits the target label for a control flow node.
795  */
796 static void ia32_emit_cfop_target(const ir_node *node)
797 {
798         ir_node *block = get_cfop_target_block(node);
799
800         ia32_emit_block_name(block);
801 }
802
803 /** Return the next block in Block schedule */
804 static ir_node *next_blk_sched(const ir_node *block)
805 {
806         return get_irn_link(block);
807 }
808
809 /**
810  * Returns the Proj with projection number proj and NOT mode_M
811  */
812 static ir_node *get_proj(const ir_node *node, long proj) {
813         const ir_edge_t *edge;
814         ir_node         *src;
815
816         assert(get_irn_mode(node) == mode_T && "expected mode_T node");
817
818         foreach_out_edge(node, edge) {
819                 src = get_edge_src_irn(edge);
820
821                 assert(is_Proj(src) && "Proj expected");
822                 if (get_irn_mode(src) == mode_M)
823                         continue;
824
825                 if (get_Proj_proj(src) == proj)
826                         return src;
827         }
828         return NULL;
829 }
830
831 /**
832  * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
833  */
834 static void emit_ia32_Jcc(const ir_node *node)
835 {
836         const ir_node *proj_true;
837         const ir_node *proj_false;
838         const ir_node *block;
839         const ir_node *next_block;
840         pn_Cmp         pnc = get_ia32_condcode(node);
841
842         pnc = determine_final_pnc(node, 0, pnc);
843
844         /* get both Projs */
845         proj_true = get_proj(node, pn_ia32_Jcc_true);
846         assert(proj_true && "Jcc without true Proj");
847
848         proj_false = get_proj(node, pn_ia32_Jcc_false);
849         assert(proj_false && "Jcc without false Proj");
850
851         block      = get_nodes_block(node);
852         next_block = next_blk_sched(block);
853
854         if (get_cfop_target_block(proj_true) == next_block) {
855                 /* exchange both proj's so the second one can be omitted */
856                 const ir_node *t = proj_true;
857
858                 proj_true  = proj_false;
859                 proj_false = t;
860                 if(pnc & ia32_pn_Cmp_float) {
861                         pnc = get_negated_pnc(pnc, mode_F);
862                 } else {
863                         pnc = get_negated_pnc(pnc, mode_Iu);
864                 }
865         }
866
867         if (pnc & ia32_pn_Cmp_float) {
868                 /* Some floating point comparisons require a test of the parity flag,
869                  * which indicates that the result is unordered */
870                 switch (pnc & 15) {
871                         case pn_Cmp_Uo:
872                                 be_emit_cstring("\tjp ");
873                                 ia32_emit_cfop_target(proj_true);
874                                 be_emit_finish_line_gas(proj_true);
875                                 break;
876
877                         case pn_Cmp_Leg:
878                                 be_emit_cstring("\tjnp ");
879                                 ia32_emit_cfop_target(proj_true);
880                                 be_emit_finish_line_gas(proj_true);
881                                 break;
882
883                         case pn_Cmp_Eq:
884                         case pn_Cmp_Lt:
885                         case pn_Cmp_Le:
886                                 be_emit_cstring("\tjp ");
887                                 ia32_emit_cfop_target(proj_false);
888                                 be_emit_finish_line_gas(proj_false);
889                                 goto emit_jcc;
890
891                         case pn_Cmp_Ug:
892                         case pn_Cmp_Uge:
893                         case pn_Cmp_Ne:
894                                 be_emit_cstring("\tjp ");
895                                 ia32_emit_cfop_target(proj_true);
896                                 be_emit_finish_line_gas(proj_true);
897                                 goto emit_jcc;
898
899                         default:
900                                 goto emit_jcc;
901                 }
902         } else {
903 emit_jcc:
904                 be_emit_cstring("\tj");
905                 ia32_emit_cmp_suffix(pnc);
906                 be_emit_char(' ');
907                 ia32_emit_cfop_target(proj_true);
908                 be_emit_finish_line_gas(proj_true);
909         }
910
911         /* the second Proj might be a fallthrough */
912         if (get_cfop_target_block(proj_false) != next_block) {
913                 be_emit_cstring("\tjmp ");
914                 ia32_emit_cfop_target(proj_false);
915                 be_emit_finish_line_gas(proj_false);
916         } else {
917                 be_emit_cstring("\t/* fallthrough to ");
918                 ia32_emit_cfop_target(proj_false);
919                 be_emit_cstring(" */");
920                 be_emit_finish_line_gas(proj_false);
921         }
922 }
923
924 static void emit_ia32_CMov(const ir_node *node)
925 {
926         const ia32_attr_t     *attr         = get_ia32_attr_const(node);
927         int                    ins_permuted = attr->data.ins_permuted;
928         const arch_register_t *out          = arch_get_irn_register(arch_env, node);
929         pn_Cmp                 pnc          = get_ia32_condcode(node);
930         const arch_register_t *in_true;
931         const arch_register_t *in_false;
932
933         pnc = determine_final_pnc(node, n_ia32_CMov_eflags, pnc);
934
935         in_true  = arch_get_irn_register(arch_env,
936                                          get_irn_n(node, n_ia32_CMov_val_true));
937         in_false = arch_get_irn_register(arch_env,
938                                          get_irn_n(node, n_ia32_CMov_val_false));
939
940         /* should be same constraint fullfilled? */
941         if(out == in_false) {
942                 /* yes -> nothing to do */
943         } else if(out == in_true) {
944                 const arch_register_t *tmp;
945
946                 assert(get_ia32_op_type(node) == ia32_Normal);
947
948                 ins_permuted = !ins_permuted;
949
950                 tmp      = in_true;
951                 in_true  = in_false;
952                 in_false = tmp;
953         } else {
954                 /* we need a mov */
955                 be_emit_cstring("\tmovl ");
956                 emit_register(in_false, NULL);
957                 be_emit_cstring(", ");
958                 emit_register(out, NULL);
959                 be_emit_finish_line_gas(node);
960         }
961
962         if(ins_permuted) {
963                 if(pnc & ia32_pn_Cmp_float) {
964                         pnc = get_negated_pnc(pnc, mode_F);
965                 } else {
966                         pnc = get_negated_pnc(pnc, mode_Iu);
967                 }
968         }
969
970         /* TODO: handling of Nans isn't correct yet */
971
972         be_emit_cstring("\tcmov");
973         ia32_emit_cmp_suffix(pnc);
974         be_emit_char(' ');
975         if(get_ia32_op_type(node) == ia32_AddrModeS) {
976                 ia32_emit_am(node);
977         } else {
978                 emit_register(in_true, get_ia32_ls_mode(node));
979         }
980         be_emit_cstring(", ");
981         emit_register(out, get_ia32_ls_mode(node));
982         be_emit_finish_line_gas(node);
983 }
984
985 /*********************************************************
986  *                 _ _       _
987  *                (_) |     (_)
988  *   ___ _ __ ___  _| |_     _ _   _ _ __ ___  _ __  ___
989  *  / _ \ '_ ` _ \| | __|   | | | | | '_ ` _ \| '_ \/ __|
990  * |  __/ | | | | | | |_    | | |_| | | | | | | |_) \__ \
991  *  \___|_| |_| |_|_|\__|   | |\__,_|_| |_| |_| .__/|___/
992  *                         _/ |               | |
993  *                        |__/                |_|
994  *********************************************************/
995
996 /* jump table entry (target and corresponding number) */
997 typedef struct _branch_t {
998         ir_node *target;
999         int      value;
1000 } branch_t;
1001
1002 /* jump table for switch generation */
1003 typedef struct _jmp_tbl_t {
1004         ir_node  *defProj;         /**< default target */
1005         long      min_value;       /**< smallest switch case */
1006         long      max_value;       /**< largest switch case */
1007         long      num_branches;    /**< number of jumps */
1008         char     *label;           /**< label of the jump table */
1009         branch_t *branches;        /**< jump array */
1010 } jmp_tbl_t;
1011
1012 /**
1013  * Compare two variables of type branch_t. Used to sort all switch cases
1014  */
1015 static
1016 int ia32_cmp_branch_t(const void *a, const void *b) {
1017         branch_t *b1 = (branch_t *)a;
1018         branch_t *b2 = (branch_t *)b;
1019
1020         if (b1->value <= b2->value)
1021                 return -1;
1022         else
1023                 return 1;
1024 }
1025
1026 /**
1027  * Emits code for a SwitchJmp (creates a jump table if
1028  * possible otherwise a cmp-jmp cascade). Port from
1029  * cggg ia32 backend
1030  */
1031 static void emit_ia32_SwitchJmp(const ir_node *node)
1032 {
1033         unsigned long       interval;
1034         int                 last_value, i;
1035         long                pnc;
1036         long                default_pn;
1037         jmp_tbl_t           tbl;
1038         ir_node            *proj;
1039         const ir_edge_t    *edge;
1040
1041         /* fill the table structure */
1042         tbl.label        = xmalloc(SNPRINTF_BUF_LEN);
1043         tbl.label        = get_unique_label(tbl.label, SNPRINTF_BUF_LEN, ".TBL_");
1044         tbl.defProj      = NULL;
1045         tbl.num_branches = get_irn_n_edges(node) - 1;
1046         tbl.branches     = xcalloc(tbl.num_branches, sizeof(tbl.branches[0]));
1047         tbl.min_value    = INT_MAX;
1048         tbl.max_value    = INT_MIN;
1049
1050         default_pn = get_ia32_condcode(node);
1051         i = 0;
1052         /* go over all proj's and collect them */
1053         foreach_out_edge(node, edge) {
1054                 proj = get_edge_src_irn(edge);
1055                 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
1056
1057                 pnc = get_Proj_proj(proj);
1058
1059                 /* check for default proj */
1060                 if (pnc == default_pn) {
1061                         assert(tbl.defProj == NULL && "found two default Projs at SwitchJmp");
1062                         tbl.defProj = proj;
1063                 } else {
1064                         tbl.min_value = pnc < tbl.min_value ? pnc : tbl.min_value;
1065                         tbl.max_value = pnc > tbl.max_value ? pnc : tbl.max_value;
1066
1067                         /* create branch entry */
1068                         tbl.branches[i].target = proj;
1069                         tbl.branches[i].value  = pnc;
1070                         ++i;
1071                 }
1072
1073         }
1074         assert(i == tbl.num_branches);
1075
1076         /* sort the branches by their number */
1077         qsort(tbl.branches, tbl.num_branches, sizeof(tbl.branches[0]), ia32_cmp_branch_t);
1078
1079         /* two-complement's magic make this work without overflow */
1080         interval = tbl.max_value - tbl.min_value;
1081
1082         /* emit the table */
1083         be_emit_cstring("\tcmpl $");
1084         be_emit_irprintf("%u, ", interval);
1085         ia32_emit_source_register(node, 0);
1086         be_emit_finish_line_gas(node);
1087
1088         be_emit_cstring("\tja ");
1089         ia32_emit_cfop_target(tbl.defProj);
1090         be_emit_finish_line_gas(node);
1091
1092         if (tbl.num_branches > 1) {
1093                 /* create table */
1094                 be_emit_cstring("\tjmp *");
1095                 be_emit_string(tbl.label);
1096                 be_emit_cstring("(,");
1097                 ia32_emit_source_register(node, 0);
1098                 be_emit_cstring(",4)");
1099                 be_emit_finish_line_gas(node);
1100
1101                 be_gas_emit_switch_section(GAS_SECTION_RODATA);
1102                 be_emit_cstring("\t.align 4\n");
1103                 be_emit_write_line();
1104
1105                 be_emit_string(tbl.label);
1106                 be_emit_cstring(":\n");
1107                 be_emit_write_line();
1108
1109                 be_emit_cstring(".long ");
1110                 ia32_emit_cfop_target(tbl.branches[0].target);
1111                 be_emit_finish_line_gas(NULL);
1112
1113                 last_value = tbl.branches[0].value;
1114                 for (i = 1; i < tbl.num_branches; ++i) {
1115                         while (++last_value < tbl.branches[i].value) {
1116                                 be_emit_cstring(".long ");
1117                                 ia32_emit_cfop_target(tbl.defProj);
1118                                 be_emit_finish_line_gas(NULL);
1119                         }
1120                         be_emit_cstring(".long ");
1121                         ia32_emit_cfop_target(tbl.branches[i].target);
1122                         be_emit_finish_line_gas(NULL);
1123                 }
1124                 be_gas_emit_switch_section(GAS_SECTION_TEXT);
1125         } else {
1126                 /* one jump is enough */
1127                 be_emit_cstring("\tjmp ");
1128                 ia32_emit_cfop_target(tbl.branches[0].target);
1129                 be_emit_finish_line_gas(node);
1130         }
1131
1132         if (tbl.label)
1133                 free(tbl.label);
1134         if (tbl.branches)
1135                 free(tbl.branches);
1136 }
1137
1138 /**
1139  * Emits code for a unconditional jump.
1140  */
1141 static void emit_Jmp(const ir_node *node)
1142 {
1143         ir_node *block, *next_block;
1144
1145         /* for now, the code works for scheduled and non-schedules blocks */
1146         block = get_nodes_block(node);
1147
1148         /* we have a block schedule */
1149         next_block = next_blk_sched(block);
1150         if (get_cfop_target_block(node) != next_block) {
1151                 be_emit_cstring("\tjmp ");
1152                 ia32_emit_cfop_target(node);
1153         } else {
1154                 be_emit_cstring("\t/* fallthrough to ");
1155                 ia32_emit_cfop_target(node);
1156                 be_emit_cstring(" */");
1157         }
1158         be_emit_finish_line_gas(node);
1159 }
1160
1161 static void emit_ia32_Immediate(const ir_node *node)
1162 {
1163         const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
1164
1165         be_emit_char('$');
1166         if(attr->symconst != NULL) {
1167                 if(attr->sc_sign)
1168                         be_emit_char('-');
1169                 ia32_emit_entity(attr->symconst);
1170         }
1171         if(attr->symconst == NULL || attr->offset != 0) {
1172                 if(attr->symconst != NULL) {
1173                         be_emit_irprintf("%+d", attr->offset);
1174                 } else {
1175                         be_emit_irprintf("0x%X", attr->offset);
1176                 }
1177         }
1178 }
1179
1180 /**
1181  * Emit an inline assembler operand.
1182  *
1183  * @param node  the ia32_ASM node
1184  * @param s     points to the operand (a %c)
1185  *
1186  * @return  pointer to the first char in s NOT in the current operand
1187  */
1188 static const char* emit_asm_operand(const ir_node *node, const char *s)
1189 {
1190         const ia32_attr_t     *ia32_attr = get_ia32_attr_const(node);
1191         const ia32_asm_attr_t *attr      = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
1192                                                             ia32_attr);
1193         const arch_register_t *reg;
1194         const ia32_asm_reg_t  *asm_regs = attr->register_map;
1195         const ia32_asm_reg_t  *asm_reg;
1196         const char            *reg_name;
1197         char                   c;
1198         char                   modifier = 0;
1199         int                    num      = -1;
1200         int                    p;
1201
1202         assert(*s == '%');
1203         c = *(++s);
1204
1205         /* parse modifiers */
1206         switch(c) {
1207         case 0:
1208                 ir_fprintf(stderr, "Warning: asm text (%+F) ends with %\n", node);
1209                 be_emit_char('%');
1210                 return s + 1;
1211         case '%':
1212                 be_emit_char('%');
1213                 return s + 1;
1214         case 'w':
1215         case 'b':
1216         case 'h':
1217                 modifier = c;
1218                 ++s;
1219                 break;
1220         case '0':
1221         case '1':
1222         case '2':
1223         case '3':
1224         case '4':
1225         case '5':
1226         case '6':
1227         case '7':
1228         case '8':
1229         case '9':
1230                 break;
1231         default:
1232                 ir_fprintf(stderr, "Warning: asm text (%+F) contains unknown modifier "
1233                            "'%c' for asm op\n", node, c);
1234                 ++s;
1235                 break;
1236         }
1237
1238         /* parse number */
1239         sscanf(s, "%d%n", &num, &p);
1240         if(num < 0) {
1241                 ir_fprintf(stderr, "Warning: Couldn't parse assembler operand (%+F)\n",
1242                            node);
1243                 return s;
1244         } else {
1245                 s += p;
1246         }
1247
1248         if(num < 0 || num >= ARR_LEN(asm_regs)) {
1249                 ir_fprintf(stderr, "Error: Custom assembler references invalid "
1250                            "input/output (%+F)\n", node);
1251                 return s;
1252         }
1253         asm_reg = & asm_regs[num];
1254         assert(asm_reg->valid);
1255
1256         /* get register */
1257         if(asm_reg->use_input == 0) {
1258                 reg = get_out_reg(node, asm_reg->inout_pos);
1259         } else {
1260                 ir_node *pred = get_irn_n(node, asm_reg->inout_pos);
1261
1262                 /* might be an immediate value */
1263                 if(is_ia32_Immediate(pred)) {
1264                         emit_ia32_Immediate(pred);
1265                         return s;
1266                 }
1267                 reg = get_in_reg(node, asm_reg->inout_pos);
1268         }
1269         if(reg == NULL) {
1270                 ir_fprintf(stderr, "Warning: no register assigned for %d asm op "
1271                            "(%+F)\n", num, node);
1272                 return s;
1273         }
1274
1275         if(asm_reg->memory) {
1276                 be_emit_char('(');
1277         }
1278
1279         /* emit it */
1280         if(modifier != 0) {
1281                 be_emit_char('%');
1282                 switch(modifier) {
1283                 case 'b':
1284                         reg_name = ia32_get_mapped_reg_name(isa->regs_8bit, reg);
1285                         break;
1286                 case 'h':
1287                         reg_name = ia32_get_mapped_reg_name(isa->regs_8bit_high, reg);
1288                         break;
1289                 case 'w':
1290                         reg_name = ia32_get_mapped_reg_name(isa->regs_16bit, reg);
1291                         break;
1292                 default:
1293                         panic("Invalid asm op modifier");
1294                 }
1295                 be_emit_string(reg_name);
1296         } else {
1297                 emit_register(reg, asm_reg->mode);
1298         }
1299
1300         if(asm_reg->memory) {
1301                 be_emit_char(')');
1302         }
1303
1304         return s;
1305 }
1306
1307 /**
1308  * Emits code for an ASM pseudo op.
1309  */
1310 static void emit_ia32_Asm(const ir_node *node)
1311 {
1312         const void            *gen_attr = get_irn_generic_attr_const(node);
1313         const ia32_asm_attr_t *attr
1314                 = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, gen_attr);
1315         ident                 *asm_text = attr->asm_text;
1316         const char            *s        = get_id_str(asm_text);
1317
1318         be_emit_cstring("# Begin ASM \t");
1319         be_emit_finish_line_gas(node);
1320
1321         if (s[0] != '\t')
1322                 be_emit_char('\t');
1323
1324         while(*s != 0) {
1325                 if(*s == '%') {
1326                         s = emit_asm_operand(node, s);
1327                         continue;
1328                 } else {
1329                         be_emit_char(*s);
1330                 }
1331                 ++s;
1332         }
1333
1334         be_emit_char('\n');
1335         be_emit_write_line();
1336
1337         be_emit_cstring("# End ASM\n");
1338         be_emit_write_line();
1339 }
1340
1341 /**********************************
1342  *   _____                  ____
1343  *  / ____|                |  _ \
1344  * | |     ___  _ __  _   _| |_) |
1345  * | |    / _ \| '_ \| | | |  _ <
1346  * | |___| (_) | |_) | |_| | |_) |
1347  *  \_____\___/| .__/ \__, |____/
1348  *             | |     __/ |
1349  *             |_|    |___/
1350  **********************************/
1351
1352 /**
1353  * Emit movsb/w instructions to make mov count divideable by 4
1354  */
1355 static void emit_CopyB_prolog(unsigned size) {
1356         be_emit_cstring("\tcld");
1357         be_emit_finish_line_gas(NULL);
1358
1359         switch (size) {
1360         case 1:
1361                 be_emit_cstring("\tmovsb");
1362                 be_emit_finish_line_gas(NULL);
1363                 break;
1364         case 2:
1365                 be_emit_cstring("\tmovsw");
1366                 be_emit_finish_line_gas(NULL);
1367                 break;
1368         case 3:
1369                 be_emit_cstring("\tmovsb");
1370                 be_emit_finish_line_gas(NULL);
1371                 be_emit_cstring("\tmovsw");
1372                 be_emit_finish_line_gas(NULL);
1373                 break;
1374         }
1375 }
1376
1377 /**
1378  * Emit rep movsd instruction for memcopy.
1379  */
1380 static void emit_ia32_CopyB(const ir_node *node)
1381 {
1382         unsigned size = get_ia32_copyb_size(node);
1383
1384         emit_CopyB_prolog(size);
1385
1386         be_emit_cstring("\trep movsd");
1387         be_emit_finish_line_gas(node);
1388 }
1389
1390 /**
1391  * Emits unrolled memcopy.
1392  */
1393 static void emit_ia32_CopyB_i(const ir_node *node)
1394 {
1395         unsigned size = get_ia32_copyb_size(node);
1396
1397         emit_CopyB_prolog(size & 0x3);
1398
1399         size >>= 2;
1400         while (size--) {
1401                 be_emit_cstring("\tmovsd");
1402                 be_emit_finish_line_gas(NULL);
1403         }
1404 }
1405
1406
1407
1408 /***************************
1409  *   _____
1410  *  / ____|
1411  * | |     ___  _ ____   __
1412  * | |    / _ \| '_ \ \ / /
1413  * | |___| (_) | | | \ V /
1414  *  \_____\___/|_| |_|\_/
1415  *
1416  ***************************/
1417
1418 /**
1419  * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1420  */
1421 static void emit_ia32_Conv_with_FP(const ir_node *node)
1422 {
1423         ir_mode            *ls_mode = get_ia32_ls_mode(node);
1424         int                 ls_bits = get_mode_size_bits(ls_mode);
1425
1426         be_emit_cstring("\tcvt");
1427
1428         if(is_ia32_Conv_I2FP(node)) {
1429                 if(ls_bits == 32) {
1430                         be_emit_cstring("si2ss");
1431                 } else {
1432                         be_emit_cstring("si2sd");
1433                 }
1434         } else if(is_ia32_Conv_FP2I(node)) {
1435                 if(ls_bits == 32) {
1436                         be_emit_cstring("ss2si");
1437                 } else {
1438                         be_emit_cstring("sd2si");
1439                 }
1440         } else {
1441                 assert(is_ia32_Conv_FP2FP(node));
1442                 if(ls_bits == 32) {
1443                         be_emit_cstring("sd2ss");
1444                 } else {
1445                         be_emit_cstring("ss2sd");
1446                 }
1447         }
1448         be_emit_char(' ');
1449
1450         switch(get_ia32_op_type(node)) {
1451                 case ia32_Normal:
1452                         ia32_emit_source_register(node, n_ia32_unary_op);
1453                         break;
1454                 case ia32_AddrModeS:
1455                         ia32_emit_am(node);
1456                         break;
1457                 default:
1458                         assert(0 && "unsupported op type for Conv");
1459         }
1460         be_emit_cstring(", ");
1461         ia32_emit_dest_register(node, 0);
1462         be_emit_finish_line_gas(node);
1463 }
1464
1465 static void emit_ia32_Conv_I2FP(const ir_node *node)
1466 {
1467         emit_ia32_Conv_with_FP(node);
1468 }
1469
1470 static void emit_ia32_Conv_FP2I(const ir_node *node)
1471 {
1472         emit_ia32_Conv_with_FP(node);
1473 }
1474
1475 static void emit_ia32_Conv_FP2FP(const ir_node *node)
1476 {
1477         emit_ia32_Conv_with_FP(node);
1478 }
1479
1480 /**
1481  * Emits code for an Int conversion.
1482  */
1483 static void emit_ia32_Conv_I2I(const ir_node *node)
1484 {
1485         const char            *sign_suffix;
1486         ir_mode               *smaller_mode = get_ia32_ls_mode(node);
1487         int                    smaller_bits = get_mode_size_bits(smaller_mode);
1488         int                    signed_mode;
1489         const arch_register_t *in_reg, *out_reg;
1490
1491         assert(!mode_is_float(smaller_mode));
1492         assert(smaller_bits == 8 || smaller_bits == 16 || smaller_bits == 32);
1493
1494         signed_mode = mode_is_signed(smaller_mode);
1495         if(smaller_bits == 32) {
1496                 // this should not happen as it's no convert
1497                 assert(0);
1498                 sign_suffix = "";
1499         } else {
1500                 sign_suffix = signed_mode ? "s" : "z";
1501         }
1502
1503         out_reg = get_out_reg(node, 0);
1504
1505         switch(get_ia32_op_type(node)) {
1506                 case ia32_Normal:
1507                         in_reg  = get_in_reg(node, n_ia32_unary_op);
1508
1509                         if (in_reg  == &ia32_gp_regs[REG_EAX] &&
1510                                 out_reg == &ia32_gp_regs[REG_EAX] &&
1511                                 signed_mode &&
1512                                 smaller_bits == 16)
1513                         {
1514                                 /* argument and result are both in EAX and */
1515                                 /* signedness is ok: -> use the smaller cwtl opcode */
1516                                 be_emit_cstring("\tcwtl");
1517                         } else {
1518                                 be_emit_cstring("\tmov");
1519                                 be_emit_string(sign_suffix);
1520                                 ia32_emit_mode_suffix_mode(smaller_mode);
1521                                 be_emit_cstring("l ");
1522                                 emit_register(in_reg, smaller_mode);
1523                                 be_emit_cstring(", ");
1524                                 emit_register(out_reg, NULL);
1525                         }
1526                         break;
1527                 case ia32_AddrModeS: {
1528                         be_emit_cstring("\tmov");
1529                         be_emit_string(sign_suffix);
1530                         ia32_emit_mode_suffix_mode(smaller_mode);
1531                         be_emit_cstring("l ");
1532                         ia32_emit_am(node);
1533                         be_emit_cstring(", ");
1534                         emit_register(out_reg, NULL);
1535                         break;
1536                 }
1537                 default:
1538                         assert(0 && "unsupported op type for Conv");
1539         }
1540         be_emit_finish_line_gas(node);
1541 }
1542
1543
1544 /*******************************************
1545  *  _                          _
1546  * | |                        | |
1547  * | |__   ___ _ __   ___   __| | ___  ___
1548  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
1549  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
1550  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
1551  *
1552  *******************************************/
1553
1554 /**
1555  * Emits a backend call
1556  */
1557 static void emit_be_Call(const ir_node *node)
1558 {
1559         ir_entity *ent = be_Call_get_entity(node);
1560
1561         be_emit_cstring("\tcall ");
1562         if (ent) {
1563                 ia32_emit_entity(ent);
1564         } else {
1565                 const arch_register_t *reg = get_in_reg(node, be_pos_Call_ptr);
1566                 be_emit_char('*');
1567                 emit_register(reg, NULL);
1568         }
1569         be_emit_finish_line_gas(node);
1570 }
1571
1572 /**
1573  * Emits code to increase stack pointer.
1574  */
1575 static void emit_be_IncSP(const ir_node *node)
1576 {
1577         int                    offs = be_get_IncSP_offset(node);
1578         const arch_register_t *reg  = arch_get_irn_register(arch_env, node);
1579
1580         if (offs == 0)
1581                 return;
1582
1583         if (offs > 0) {
1584                 be_emit_cstring("\tsubl $");
1585                 be_emit_irprintf("%u, ", offs);
1586                 emit_register(reg, NULL);
1587         } else {
1588                 be_emit_cstring("\taddl $");
1589                 be_emit_irprintf("%u, ", -offs);
1590                 emit_register(reg, NULL);
1591         }
1592         be_emit_finish_line_gas(node);
1593 }
1594
1595 /**
1596  * Emits code for Copy/CopyKeep.
1597  */
1598 static void Copy_emitter(const ir_node *node, const ir_node *op)
1599 {
1600         const arch_register_t *in  = arch_get_irn_register(arch_env, op);
1601         const arch_register_t *out = arch_get_irn_register(arch_env, node);
1602         ir_mode               *mode;
1603
1604         if(in == out) {
1605                 return;
1606         }
1607         if(is_unknown_reg(in))
1608                 return;
1609         /* copies of vf nodes aren't real... */
1610         if(arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
1611                 return;
1612
1613         mode = get_irn_mode(node);
1614         if (mode == mode_E) {
1615                 be_emit_cstring("\tmovsd ");
1616                 emit_register(in, NULL);
1617                 be_emit_cstring(", ");
1618                 emit_register(out, NULL);
1619         } else {
1620                 be_emit_cstring("\tmovl ");
1621                 emit_register(in, NULL);
1622                 be_emit_cstring(", ");
1623                 emit_register(out, NULL);
1624         }
1625         be_emit_finish_line_gas(node);
1626 }
1627
1628 static void emit_be_Copy(const ir_node *node)
1629 {
1630         Copy_emitter(node, be_get_Copy_op(node));
1631 }
1632
1633 static void emit_be_CopyKeep(const ir_node *node)
1634 {
1635         Copy_emitter(node, be_get_CopyKeep_op(node));
1636 }
1637
1638 /**
1639  * Emits code for exchange.
1640  */
1641 static void emit_be_Perm(const ir_node *node)
1642 {
1643         const arch_register_t *in0, *in1;
1644         const arch_register_class_t *cls0, *cls1;
1645
1646         in0 = arch_get_irn_register(arch_env, get_irn_n(node, 0));
1647         in1 = arch_get_irn_register(arch_env, get_irn_n(node, 1));
1648
1649         cls0 = arch_register_get_class(in0);
1650         cls1 = arch_register_get_class(in1);
1651
1652         assert(cls0 == cls1 && "Register class mismatch at Perm");
1653
1654         if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
1655                 be_emit_cstring("\txchg ");
1656                 emit_register(in1, NULL);
1657                 be_emit_cstring(", ");
1658                 emit_register(in0, NULL);
1659                 be_emit_finish_line_gas(node);
1660         } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1661                 be_emit_cstring("\txorpd ");
1662                 emit_register(in1, NULL);
1663                 be_emit_cstring(", ");
1664                 emit_register(in0, NULL);
1665                 be_emit_finish_line_gas(NULL);
1666
1667                 be_emit_cstring("\txorpd ");
1668                 emit_register(in0, NULL);
1669                 be_emit_cstring(", ");
1670                 emit_register(in1, NULL);
1671                 be_emit_finish_line_gas(NULL);
1672
1673                 be_emit_cstring("\txorpd ");
1674                 emit_register(in1, NULL);
1675                 be_emit_cstring(", ");
1676                 emit_register(in0, NULL);
1677                 be_emit_finish_line_gas(node);
1678         } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
1679                 /* is a NOP */
1680         } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
1681                 /* is a NOP */
1682         } else {
1683                 panic("unexpected register class in be_Perm (%+F)\n", node);
1684         }
1685 }
1686
1687 /**
1688  * Emits code for Constant loading.
1689  */
1690 static void emit_ia32_Const(const ir_node *node)
1691 {
1692         be_emit_cstring("\tmovl ");
1693         emit_ia32_Immediate(node);
1694         be_emit_cstring(", ");
1695         ia32_emit_dest_register(node, 0);
1696
1697         be_emit_finish_line_gas(node);
1698 }
1699
1700 /**
1701  * Emits code to load the TLS base
1702  */
1703 static void emit_ia32_LdTls(const ir_node *node)
1704 {
1705         be_emit_cstring("\tmovl %gs:0, ");
1706         ia32_emit_dest_register(node, 0);
1707         be_emit_finish_line_gas(node);
1708 }
1709
1710 /* helper function for emit_ia32_Minus64Bit */
1711 static void emit_mov(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1712 {
1713         be_emit_cstring("\tmovl ");
1714         emit_register(src, NULL);
1715         be_emit_cstring(", ");
1716         emit_register(dst, NULL);
1717         be_emit_finish_line_gas(node);
1718 }
1719
1720 /* helper function for emit_ia32_Minus64Bit */
1721 static void emit_neg(const ir_node* node, const arch_register_t *reg)
1722 {
1723         be_emit_cstring("\tnegl ");
1724         emit_register(reg, NULL);
1725         be_emit_finish_line_gas(node);
1726 }
1727
1728 /* helper function for emit_ia32_Minus64Bit */
1729 static void emit_sbb0(const ir_node* node, const arch_register_t *reg)
1730 {
1731         be_emit_cstring("\tsbbl $0, ");
1732         emit_register(reg, NULL);
1733         be_emit_finish_line_gas(node);
1734 }
1735
1736 /* helper function for emit_ia32_Minus64Bit */
1737 static void emit_sbb(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1738 {
1739         be_emit_cstring("\tsbbl ");
1740         emit_register(src, NULL);
1741         be_emit_cstring(", ");
1742         emit_register(dst, NULL);
1743         be_emit_finish_line_gas(node);
1744 }
1745
1746 /* helper function for emit_ia32_Minus64Bit */
1747 static void emit_xchg(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1748 {
1749         be_emit_cstring("\txchgl ");
1750         emit_register(src, NULL);
1751         be_emit_cstring(", ");
1752         emit_register(dst, NULL);
1753         be_emit_finish_line_gas(node);
1754 }
1755
1756 /* helper function for emit_ia32_Minus64Bit */
1757 static void emit_zero(const ir_node* node, const arch_register_t *reg)
1758 {
1759         be_emit_cstring("\txorl ");
1760         emit_register(reg, NULL);
1761         be_emit_cstring(", ");
1762         emit_register(reg, NULL);
1763         be_emit_finish_line_gas(node);
1764 }
1765
1766 static void emit_ia32_Minus64Bit(const ir_node *node)
1767 {
1768         const arch_register_t *in_lo  = get_in_reg(node, 0);
1769         const arch_register_t *in_hi  = get_in_reg(node, 1);
1770         const arch_register_t *out_lo = get_out_reg(node, 0);
1771         const arch_register_t *out_hi = get_out_reg(node, 1);
1772
1773         if (out_lo == in_lo) {
1774                 if (out_hi != in_hi) {
1775                         /* a -> a, b -> d */
1776                         goto zero_neg;
1777                 } else {
1778                         /* a -> a, b -> b */
1779                         goto normal_neg;
1780                 }
1781         } else if (out_lo == in_hi) {
1782                 if (out_hi == in_lo) {
1783                         /* a -> b, b -> a */
1784                         emit_xchg(node, in_lo, in_hi);
1785                         goto normal_neg;
1786                 } else {
1787                         /* a -> b, b -> d */
1788                         emit_mov(node, in_hi, out_hi);
1789                         emit_mov(node, in_lo, out_lo);
1790                         goto normal_neg;
1791                 }
1792         } else {
1793                 if (out_hi == in_lo) {
1794                         /* a -> c, b -> a */
1795                         emit_mov(node, in_lo, out_lo);
1796                         goto zero_neg;
1797                 } else if (out_hi == in_hi) {
1798                         /* a -> c, b -> b */
1799                         emit_mov(node, in_lo, out_lo);
1800                         goto normal_neg;
1801                 } else {
1802                         /* a -> c, b -> d */
1803                         emit_mov(node, in_lo, out_lo);
1804                         goto zero_neg;
1805                 }
1806         }
1807
1808 normal_neg:
1809         emit_neg( node, out_hi);
1810         emit_neg( node, out_lo);
1811         emit_sbb0(node, out_hi);
1812         return;
1813
1814 zero_neg:
1815         emit_zero(node, out_hi);
1816         emit_neg( node, out_lo);
1817         emit_sbb( node, in_hi, out_hi);
1818 }
1819
1820 static void emit_be_Return(const ir_node *node)
1821 {
1822         unsigned pop;
1823         be_emit_cstring("\tret");
1824
1825         pop = be_Return_get_pop(node);
1826         if(pop > 0) {
1827                 be_emit_irprintf(" $%d", pop);
1828         }
1829         be_emit_finish_line_gas(node);
1830 }
1831
1832 static void emit_Nothing(const ir_node *node)
1833 {
1834         (void) node;
1835 }
1836
1837
1838 /***********************************************************************************
1839  *                  _          __                                             _
1840  *                 (_)        / _|                                           | |
1841  *  _ __ ___   __ _ _ _ __   | |_ _ __ __ _ _ __ ___   _____      _____  _ __| | __
1842  * | '_ ` _ \ / _` | | '_ \  |  _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
1843  * | | | | | | (_| | | | | | | | | | | (_| | | | | | |  __/\ V  V / (_) | |  |   <
1844  * |_| |_| |_|\__,_|_|_| |_| |_| |_|  \__,_|_| |_| |_|\___| \_/\_/ \___/|_|  |_|\_\
1845  *
1846  ***********************************************************************************/
1847
1848 /**
1849  * Enters the emitter functions for handled nodes into the generic
1850  * pointer of an opcode.
1851  */
1852 static
1853 void ia32_register_emitters(void) {
1854
1855 #define IA32_EMIT2(a,b) op_ia32_##a->ops.generic = (op_func)emit_ia32_##b
1856 #define IA32_EMIT(a)    IA32_EMIT2(a,a)
1857 #define EMIT(a)         op_##a->ops.generic = (op_func)emit_##a
1858 #define IGN(a)                  op_##a->ops.generic = (op_func)emit_Nothing
1859 #define BE_EMIT(a)      op_be_##a->ops.generic = (op_func)emit_be_##a
1860 #define BE_IGN(a)               op_be_##a->ops.generic = (op_func)emit_Nothing
1861
1862         /* first clear the generic function pointer for all ops */
1863         clear_irp_opcodes_generic_func();
1864
1865         /* register all emitter functions defined in spec */
1866         ia32_register_spec_emitters();
1867
1868         /* other ia32 emitter functions */
1869         IA32_EMIT(Asm);
1870         IA32_EMIT(CMov);
1871         IA32_EMIT(IMul);
1872         IA32_EMIT(SwitchJmp);
1873         IA32_EMIT(CopyB);
1874         IA32_EMIT(CopyB_i);
1875         IA32_EMIT(Conv_I2FP);
1876         IA32_EMIT(Conv_FP2I);
1877         IA32_EMIT(Conv_FP2FP);
1878         IA32_EMIT(Conv_I2I);
1879         IA32_EMIT2(Conv_I2I8Bit, Conv_I2I);
1880         IA32_EMIT(Const);
1881         IA32_EMIT(LdTls);
1882         IA32_EMIT(Minus64Bit);
1883         IA32_EMIT(Jcc);
1884
1885         /* benode emitter */
1886         BE_EMIT(Call);
1887         BE_EMIT(IncSP);
1888         BE_EMIT(Copy);
1889         BE_EMIT(CopyKeep);
1890         BE_EMIT(Perm);
1891         BE_EMIT(Return);
1892
1893         BE_IGN(RegParams);
1894         BE_IGN(Barrier);
1895         BE_IGN(Keep);
1896
1897         /* firm emitter */
1898         EMIT(Jmp);
1899         IGN(Proj);
1900         IGN(Phi);
1901         IGN(Start);
1902
1903 #undef BE_EMIT
1904 #undef EMIT
1905 #undef IGN
1906 #undef IA32_EMIT2
1907 #undef IA32_EMIT
1908 }
1909
1910 static const char *last_name = NULL;
1911 static unsigned last_line = -1;
1912 static unsigned num = -1;
1913
1914 /**
1915  * Emit the debug support for node node.
1916  */
1917 static void ia32_emit_dbg(const ir_node *node)
1918 {
1919         dbg_info *db = get_irn_dbg_info(node);
1920         unsigned lineno;
1921         const char *fname = ir_retrieve_dbg_info(db, &lineno);
1922
1923         if (! cg->birg->main_env->options->stabs_debug_support)
1924                 return;
1925
1926         if (fname) {
1927                 if (last_name != fname) {
1928                         last_line = -1;
1929                         be_dbg_include_begin(cg->birg->main_env->db_handle, fname);
1930                         last_name = fname;
1931                 }
1932                 if (last_line != lineno) {
1933                         char name[64];
1934
1935                         snprintf(name, sizeof(name), ".LM%u", ++num);
1936                         last_line = lineno;
1937                         be_dbg_line(cg->birg->main_env->db_handle, lineno, name);
1938                         be_emit_string(name);
1939                         be_emit_cstring(":\n");
1940                         be_emit_write_line();
1941                 }
1942         }
1943 }
1944
1945 typedef void (*emit_func_ptr) (const ir_node *);
1946
1947 /**
1948  * Emits code for a node.
1949  */
1950 static void ia32_emit_node(const ir_node *node)
1951 {
1952         ir_op *op = get_irn_op(node);
1953
1954         DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
1955
1956         if (op->ops.generic) {
1957                 emit_func_ptr func = (emit_func_ptr) op->ops.generic;
1958                 ia32_emit_dbg(node);
1959                 (*func) (node);
1960         } else {
1961                 emit_Nothing(node);
1962                 ir_fprintf(stderr, "Error: No emit handler for node %+F (%+G, graph %+F)\n", node, node, current_ir_graph);
1963                 abort();
1964         }
1965 }
1966
1967 /**
1968  * Emits gas alignment directives
1969  */
1970 static void ia32_emit_alignment(unsigned align, unsigned skip)
1971 {
1972         be_emit_cstring("\t.p2align ");
1973         be_emit_irprintf("%u,,%u\n", align, skip);
1974         be_emit_write_line();
1975 }
1976
1977 /**
1978  * Emits gas alignment directives for Functions depended on cpu architecture.
1979  */
1980 static void ia32_emit_align_func(void)
1981 {
1982         unsigned align        = ia32_cg_config.function_alignment;
1983         unsigned maximum_skip = (1 << align) - 1;
1984
1985         ia32_emit_alignment(align, maximum_skip);
1986 }
1987
1988 /**
1989  * Emits gas alignment directives for Labels depended on cpu architecture.
1990  */
1991 static void ia32_emit_align_label(void)
1992 {
1993         unsigned align        = ia32_cg_config.label_alignment;
1994         unsigned maximum_skip = (1 << align) - 1;
1995         ia32_emit_alignment(align, maximum_skip);
1996 }
1997
1998 /**
1999  * Test wether a block should be aligned.
2000  * For cpus in the P4/Athlon class it is useful to align jump labels to
2001  * 16 bytes. However we should only do that if the alignment nops before the
2002  * label aren't executed more often than we have jumps to the label.
2003  */
2004 static int should_align_block(ir_node *block, ir_node *prev)
2005 {
2006         static const double DELTA = .0001;
2007         ir_exec_freq *exec_freq   = cg->birg->exec_freq;
2008         double        block_freq;
2009         double        prev_freq = 0;  /**< execfreq of the fallthrough block */
2010         double        jmp_freq  = 0;  /**< execfreq of all non-fallthrough blocks */
2011         int           i, n_cfgpreds;
2012
2013         if(exec_freq == NULL)
2014                 return 0;
2015         if(ia32_cg_config.label_alignment_factor <= 0)
2016                 return 0;
2017
2018         block_freq = get_block_execfreq(exec_freq, block);
2019         if(block_freq < DELTA)
2020                 return 0;
2021
2022         n_cfgpreds = get_Block_n_cfgpreds(block);
2023         for(i = 0; i < n_cfgpreds; ++i) {
2024                 ir_node *pred      = get_Block_cfgpred_block(block, i);
2025                 double   pred_freq = get_block_execfreq(exec_freq, pred);
2026
2027                 if(pred == prev) {
2028                         prev_freq += pred_freq;
2029                 } else {
2030                         jmp_freq  += pred_freq;
2031                 }
2032         }
2033
2034         if(prev_freq < DELTA && !(jmp_freq < DELTA))
2035                 return 1;
2036
2037         jmp_freq /= prev_freq;
2038
2039         return jmp_freq > ia32_cg_config.label_alignment_factor;
2040 }
2041
2042 static void ia32_emit_block_header(ir_node *block, ir_node *prev)
2043 {
2044         int           n_cfgpreds;
2045         int           need_label;
2046         int           i, arity;
2047         ir_exec_freq  *exec_freq = cg->birg->exec_freq;
2048
2049         n_cfgpreds = get_Block_n_cfgpreds(block);
2050         need_label = (n_cfgpreds != 0);
2051
2052         if (should_align_block(block, prev)) {
2053                 assert(need_label);
2054                 ia32_emit_align_label();
2055         }
2056
2057         if(need_label) {
2058                 ia32_emit_block_name(block);
2059                 be_emit_char(':');
2060
2061                 be_emit_pad_comment();
2062                 be_emit_cstring("   /* preds:");
2063
2064                 /* emit list of pred blocks in comment */
2065                 arity = get_irn_arity(block);
2066                 for (i = 0; i < arity; ++i) {
2067                         ir_node *predblock = get_Block_cfgpred_block(block, i);
2068                         be_emit_irprintf(" %d", get_irn_node_nr(predblock));
2069                 }
2070         } else {
2071                 be_emit_cstring("\t/* ");
2072                 ia32_emit_block_name(block);
2073                 be_emit_cstring(": ");
2074         }
2075         if (exec_freq != NULL) {
2076                 be_emit_irprintf(" freq: %f",
2077                                  get_block_execfreq(exec_freq, block));
2078         }
2079         be_emit_cstring(" */\n");
2080         be_emit_write_line();
2081 }
2082
2083 /**
2084  * Walks over the nodes in a block connected by scheduling edges
2085  * and emits code for each node.
2086  */
2087 static void ia32_gen_block(ir_node *block, ir_node *last_block)
2088 {
2089         const ir_node *node;
2090
2091         ia32_emit_block_header(block, last_block);
2092
2093         /* emit the contents of the block */
2094         ia32_emit_dbg(block);
2095         sched_foreach(block, node) {
2096                 ia32_emit_node(node);
2097         }
2098 }
2099
2100 /**
2101  * Emits code for function start.
2102  */
2103 static void ia32_emit_func_prolog(ir_graph *irg)
2104 {
2105         ir_entity  *irg_ent  = get_irg_entity(irg);
2106         const char *irg_name = get_entity_ld_name(irg_ent);
2107         const be_irg_t *birg = cg->birg;
2108
2109         /* write the begin line (used by scripts processing the assembler... */
2110         be_emit_write_line();
2111         be_emit_cstring("# -- Begin  ");
2112         be_emit_string(irg_name);
2113         be_emit_char('\n');
2114         be_emit_write_line();
2115
2116         be_gas_emit_switch_section(GAS_SECTION_TEXT);
2117         be_dbg_method_begin(birg->main_env->db_handle, irg_ent, be_abi_get_stack_layout(birg->abi));
2118         ia32_emit_align_func();
2119         if (get_entity_visibility(irg_ent) == visibility_external_visible) {
2120                 be_emit_cstring(".global ");
2121                 be_emit_string(irg_name);
2122                 be_emit_char('\n');
2123                 be_emit_write_line();
2124         }
2125         ia32_emit_function_object(irg_name);
2126         be_emit_string(irg_name);
2127         be_emit_cstring(":\n");
2128         be_emit_write_line();
2129 }
2130
2131 /**
2132  * Emits code for function end
2133  */
2134 static void ia32_emit_func_epilog(ir_graph *irg)
2135 {
2136         const char     *irg_name = get_entity_ld_name(get_irg_entity(irg));
2137         const be_irg_t *birg     = cg->birg;
2138
2139         ia32_emit_function_size(irg_name);
2140         be_dbg_method_end(birg->main_env->db_handle);
2141
2142         be_emit_cstring("# -- End  ");
2143         be_emit_string(irg_name);
2144         be_emit_char('\n');
2145         be_emit_write_line();
2146
2147         be_emit_char('\n');
2148         be_emit_write_line();
2149 }
2150
2151 /**
2152  * Block-walker:
2153  * Sets labels for control flow nodes (jump target)
2154  */
2155 static void ia32_gen_labels(ir_node *block, void *data)
2156 {
2157         ir_node *pred;
2158         int n = get_Block_n_cfgpreds(block);
2159         (void) data;
2160
2161         for (n--; n >= 0; n--) {
2162                 pred = get_Block_cfgpred(block, n);
2163                 set_irn_link(pred, block);
2164         }
2165 }
2166
2167 /**
2168  * Emit an exception label if the current instruction can fail.
2169  */
2170 void ia32_emit_exc_label(const ir_node *node)
2171 {
2172         if (get_ia32_exc_label(node)) {
2173                 be_emit_irprintf(".EXL%u\n", 0);
2174                 be_emit_write_line();
2175         }
2176 }
2177
2178 /**
2179  * Main driver. Emits the code for one routine.
2180  */
2181 void ia32_gen_routine(ia32_code_gen_t *ia32_cg, ir_graph *irg)
2182 {
2183         ir_node *block;
2184         ir_node *last_block = NULL;
2185         int i, n;
2186
2187         cg       = ia32_cg;
2188         isa      = (const ia32_isa_t*) cg->arch_env->isa;
2189         arch_env = cg->arch_env;
2190
2191         ia32_register_emitters();
2192
2193         ia32_emit_func_prolog(irg);
2194         irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
2195
2196         n = ARR_LEN(cg->blk_sched);
2197         for (i = 0; i < n;) {
2198                 ir_node *next_bl;
2199
2200                 block   = cg->blk_sched[i];
2201                 ++i;
2202                 next_bl = i < n ? cg->blk_sched[i] : NULL;
2203
2204                 /* set here the link. the emitter expects to find the next block here */
2205                 set_irn_link(block, next_bl);
2206                 ia32_gen_block(block, last_block);
2207                 last_block = block;
2208         }
2209
2210         ia32_emit_func_epilog(irg);
2211 }
2212
2213 void ia32_init_emitter(void)
2214 {
2215         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");
2216 }