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