added ctor section support
[libfirm] / ir / be / ia32 / ia32_emitter.c
1 /**
2  * This file implements the node emitter.
3  * @author Christian Wuerdig
4  * $Id$
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include <limits.h>
12
13 #include "xmalloc.h"
14 #include "tv.h"
15 #include "iredges.h"
16 #include "debug.h"
17 #include "irgwalk.h"
18 #include "irprintf.h"
19 #include "irop_t.h"
20 #include "irargs_t.h"
21 #include "irprog_t.h"
22 #include "iredges_t.h"
23
24 #include "../besched_t.h"
25 #include "../benode_t.h"
26
27 #include "ia32_emitter.h"
28 #include "gen_ia32_emitter.h"
29 #include "gen_ia32_regalloc_if.h"
30 #include "ia32_nodes_attr.h"
31 #include "ia32_new_nodes.h"
32 #include "ia32_map_regs.h"
33 #include "bearch_ia32_t.h"
34
35 #define BLOCK_PREFIX(x) ".L" x
36
37 #define SNPRINTF_BUF_LEN 128
38
39 /* global arch_env for lc_printf functions */
40 static const arch_env_t *arch_env = NULL;
41
42 /** by default, we generate assembler code for the Linux gas */
43 asm_flavour_t asm_flavour = ASM_LINUX_GAS;
44
45 /**
46  * Switch to a new section
47  */
48 void ia32_switch_section(FILE *F, section_t sec) {
49         static section_t curr_sec = NO_SECTION;
50         static const char *text[ASM_MAX][SECTION_MAX] = {
51                 {
52                         ".section\t.text",
53                         ".section\t.data",
54                         ".section\t.rodata",
55                         ".section\t.text",
56                         ".section\t.tbss,\"awT\",@nobits",
57                         ".section\t.ctors,\"aw\",@progbits"
58                 },
59                 {
60                         ".section\t.text",
61                         ".section\t.data",
62                         ".section .rdata,\"dr\"",
63                         ".section\t.text",
64                         ".section\t.tbss,\"awT\",@nobits",
65                         ".section\t.ctors,\"aw\",@progbits"
66                 }
67         };
68
69         if (curr_sec == sec)
70                 return;
71
72         curr_sec = sec;
73         switch (sec) {
74
75         case NO_SECTION:
76                 break;
77
78         case SECTION_TEXT:
79         case SECTION_DATA:
80         case SECTION_RODATA:
81         case SECTION_COMMON:
82         case SECTION_TLS:
83                 fprintf(F, "\t%s\n", text[asm_flavour][sec]);
84                 break;
85
86         default:
87                 break;
88         }
89 }
90
91 static void ia32_dump_function_object(FILE *F, const char *name)
92 {
93         switch (asm_flavour) {
94         case ASM_LINUX_GAS:
95                 fprintf(F, "\t.type\t%s, @function\n", name);
96                 break;
97         case ASM_MINGW_GAS:
98                 fprintf(F, "\t.def\t%s;\t.scl\t2;\t.type\t32;\t.endef\n", name);
99                 break;
100         default:
101                 break;
102         }
103 }
104
105 static void ia32_dump_function_size(FILE *F, const char *name)
106 {
107         switch (asm_flavour) {
108         case ASM_LINUX_GAS:
109                 fprintf(F, "\t.size\t%s, .-%s\n", name, name);
110                 break;
111         default:
112                 break;
113         }
114 }
115
116 /*************************************************************
117  *             _       _    __   _          _
118  *            (_)     | |  / _| | |        | |
119  *  _ __  _ __ _ _ __ | |_| |_  | |__   ___| |_ __   ___ _ __
120  * | '_ \| '__| | '_ \| __|  _| | '_ \ / _ \ | '_ \ / _ \ '__|
121  * | |_) | |  | | | | | |_| |   | | | |  __/ | |_) |  __/ |
122  * | .__/|_|  |_|_| |_|\__|_|   |_| |_|\___|_| .__/ \___|_|
123  * | |                                       | |
124  * |_|                                       |_|
125  *************************************************************/
126
127 static INLINE int be_is_unknown_reg(const arch_register_t *reg) {
128         return \
129                 REGS_ARE_EQUAL(reg, &ia32_gp_regs[REG_GP_UKNWN])   || \
130                 REGS_ARE_EQUAL(reg, &ia32_xmm_regs[REG_XMM_UKNWN]) || \
131                 REGS_ARE_EQUAL(reg, &ia32_vfp_regs[REG_VFP_UKNWN]);
132 }
133
134 /**
135  * returns true if a node has x87 registers
136  */
137 static INLINE int has_x87_register(const ir_node *n) {
138         return is_irn_machine_user(n, 0);
139 }
140
141 /* We always pass the ir_node which is a pointer. */
142 static int ia32_get_arg_type(const lc_arg_occ_t *occ) {
143         return lc_arg_type_ptr;
144 }
145
146
147 /**
148  * Returns the register at in position pos.
149  */
150 static const arch_register_t *get_in_reg(const ir_node *irn, int pos) {
151         ir_node                *op;
152         const arch_register_t  *reg = NULL;
153
154         assert(get_irn_arity(irn) > pos && "Invalid IN position");
155
156         /* The out register of the operator at position pos is the
157            in register we need. */
158         op = get_irn_n(irn, pos);
159
160         reg = arch_get_irn_register(arch_env, op);
161
162         assert(reg && "no in register found");
163
164         /* in case of unknown: just return a register */
165         if (REGS_ARE_EQUAL(reg, &ia32_gp_regs[REG_GP_UKNWN]))
166                 reg = &ia32_gp_regs[REG_EAX];
167         else if (REGS_ARE_EQUAL(reg, &ia32_xmm_regs[REG_XMM_UKNWN]))
168                 reg = &ia32_xmm_regs[REG_XMM0];
169         else if (REGS_ARE_EQUAL(reg, &ia32_vfp_regs[REG_VFP_UKNWN]))
170                 reg = &ia32_vfp_regs[REG_VF0];
171
172         return reg;
173 }
174
175 /**
176  * Returns the register at out position pos.
177  */
178 static const arch_register_t *get_out_reg(const ir_node *irn, int pos) {
179         ir_node                *proj;
180         const arch_register_t  *reg = NULL;
181
182         /* 1st case: irn is not of mode_T, so it has only                 */
183         /*           one OUT register -> good                             */
184         /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
185         /*           Proj with the corresponding projnum for the register */
186
187         if (get_irn_mode(irn) != mode_T) {
188                 reg = arch_get_irn_register(arch_env, irn);
189         }
190         else if (is_ia32_irn(irn)) {
191                 reg = get_ia32_out_reg(irn, pos);
192         }
193         else {
194                 const ir_edge_t *edge;
195
196                 foreach_out_edge(irn, edge) {
197                         proj = get_edge_src_irn(edge);
198                         assert(is_Proj(proj) && "non-Proj from mode_T node");
199                         if (get_Proj_proj(proj) == pos) {
200                                 reg = arch_get_irn_register(arch_env, proj);
201                                 break;
202                         }
203                 }
204         }
205
206         assert(reg && "no out register found");
207         return reg;
208 }
209
210 enum io_direction {
211   IN_REG,
212   OUT_REG
213 };
214
215 /**
216  * Returns the name of the in register at position pos.
217  */
218 static const char *get_ia32_reg_name(ir_node *irn, int pos, enum io_direction in_out) {
219         const arch_register_t *reg;
220
221         if (in_out == IN_REG) {
222                 reg = get_in_reg(irn, pos);
223
224                 if (reg->reg_class == &ia32_reg_classes[CLASS_ia32_vfp]) {
225                         /* FIXME: works for binop only */
226                         assert(2 <= pos && pos <= 3);
227                         reg = get_ia32_attr(irn)->x87[pos - 2];
228                 }
229         }
230         else {
231                 /* destination address mode nodes don't have outputs */
232                 if (is_ia32_irn(irn) && get_ia32_op_type(irn) == ia32_AddrModeD) {
233                         return "MEM";
234                 }
235
236                 reg = get_out_reg(irn, pos);
237                 if (reg->reg_class == &ia32_reg_classes[CLASS_ia32_vfp])
238                         reg = get_ia32_attr(irn)->x87[pos + 2];
239         }
240         return arch_register_get_name(reg);
241 }
242
243 /**
244  * Get the register name for a node.
245  */
246 static int ia32_get_reg_name(lc_appendable_t *app,
247     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
248 {
249         const char *buf;
250         ir_node    *irn = arg->v_ptr;
251         int         nr = occ->width - 1;
252
253         if (! irn)
254                 return lc_appendable_snadd(app, "(null)", 6);
255
256         buf = get_ia32_reg_name(irn, nr, occ->conversion == 'S' ? IN_REG : OUT_REG);
257
258         /* append the stupid % to register names */
259         lc_appendable_chadd(app, '%');
260         return lc_appendable_snadd(app, buf, strlen(buf));
261 }
262
263 /**
264  * Get the x87 register name for a node.
265  */
266 static int ia32_get_x87_name(lc_appendable_t *app,
267     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
268 {
269         const char *buf;
270         ir_node     *irn = arg->v_ptr;
271         int         nr = occ->width - 1;
272         ia32_attr_t *attr;
273
274         if (! irn)
275                 return lc_appendable_snadd(app, "(null)", 6);
276
277         attr = get_ia32_attr(irn);
278         buf = attr->x87[nr]->name;
279         lc_appendable_chadd(app, '%');
280         return lc_appendable_snadd(app, buf, strlen(buf));
281 }
282
283 /**
284  * Returns the tarval, offset or scale of an ia32 as a string.
285  */
286 static int ia32_const_to_str(lc_appendable_t *app,
287     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
288 {
289         const char *buf;
290         ir_node    *irn = arg->v_ptr;
291
292         if (! irn)
293                 return lc_arg_append(app, occ, "(null)", 6);
294
295         if (occ->conversion == 'C') {
296                 buf = get_ia32_cnst(irn);
297         }
298         else { /* 'O' */
299                 buf = get_ia32_am_offs(irn);
300         }
301
302         return buf ? lc_appendable_snadd(app, buf, strlen(buf)) : 0;
303 }
304
305 /**
306  * Determines the SSE suffix depending on the mode.
307  */
308 static int ia32_get_mode_suffix(lc_appendable_t *app,
309     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
310 {
311         ir_node *irn  = arg->v_ptr;
312         ir_mode *mode = get_irn_mode(irn);
313
314         if (mode == mode_T) {
315                 mode = get_ia32_res_mode(irn);
316                 if (! mode)
317                         mode = get_ia32_ls_mode(irn);
318         }
319
320         if (! irn)
321                 return lc_arg_append(app, occ, "(null)", 6);
322
323         if (mode_is_float(mode)) {
324                 return lc_appendable_chadd(app, get_mode_size_bits(mode) == 32 ? 's' : 'd');
325         }
326         else {
327                 return lc_appendable_chadd(app, mode_is_signed(mode) ? 's' : 'z');
328         }
329 }
330
331 /**
332  * Return the ia32 printf arg environment.
333  * We use the firm environment with some additional handlers.
334  */
335 const lc_arg_env_t *ia32_get_arg_env(void) {
336         static lc_arg_env_t *env = NULL;
337
338         static const lc_arg_handler_t ia32_reg_handler   = { ia32_get_arg_type, ia32_get_reg_name };
339         static const lc_arg_handler_t ia32_const_handler = { ia32_get_arg_type, ia32_const_to_str };
340         static const lc_arg_handler_t ia32_mode_handler  = { ia32_get_arg_type, ia32_get_mode_suffix };
341         static const lc_arg_handler_t ia32_x87_handler   = { ia32_get_arg_type, ia32_get_x87_name };
342
343         if(env == NULL) {
344                 /* extend the firm printer */
345                 env = firm_get_arg_env();
346
347                 lc_arg_register(env, "ia32:sreg", 'S', &ia32_reg_handler);
348                 lc_arg_register(env, "ia32:dreg", 'D', &ia32_reg_handler);
349                 lc_arg_register(env, "ia32:cnst", 'C', &ia32_const_handler);
350                 lc_arg_register(env, "ia32:offs", 'O', &ia32_const_handler);
351                 lc_arg_register(env, "ia32:mode", 'M', &ia32_mode_handler);
352                 lc_arg_register(env, "ia32:x87",  'X', &ia32_x87_handler);
353         }
354
355         return env;
356 }
357
358 static const char *ia32_get_reg_name_for_mode(ia32_emit_env_t *env, ir_mode *mode, const arch_register_t *reg) {
359         switch(get_mode_size_bits(mode)) {
360                 case 8:
361                         return ia32_get_mapped_reg_name(env->isa->regs_8bit, reg);
362                 case 16:
363                         return ia32_get_mapped_reg_name(env->isa->regs_16bit, reg);
364                 default:
365                         return (char *)arch_register_get_name(reg);
366         }
367 }
368
369 /**
370  * Emits registers and/or address mode of a binary operation.
371  */
372 const char *ia32_emit_binop(const ir_node *n, ia32_emit_env_t *env) {
373         static char *buf = NULL;
374
375         /* verify that this function is never called on non-AM supporting operations */
376         //assert(get_ia32_am_support(n) != ia32_am_None && "emit binop expects addressmode support");
377
378 #define PRODUCES_RESULT(n)   \
379         (!(is_ia32_St(n)      || \
380         is_ia32_Store8Bit(n)  || \
381         is_ia32_CondJmp(n)    || \
382         is_ia32_xCondJmp(n)   || \
383         is_ia32_CmpSet(n)     || \
384         is_ia32_xCmpSet(n)    || \
385         is_ia32_SwitchJmp(n)))
386
387         if (! buf) {
388                 buf = xcalloc(1, SNPRINTF_BUF_LEN);
389         }
390         else {
391                 memset(buf, 0, SNPRINTF_BUF_LEN);
392         }
393
394         switch(get_ia32_op_type(n)) {
395                 case ia32_Normal:
396                         if (is_ia32_ImmConst(n)) {
397                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%3S, %s", n, get_ia32_cnst(n));
398                         }
399                         else if (is_ia32_ImmSymConst(n)) {
400                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%3S, OFFSET FLAT:%s", n, get_ia32_cnst(n));
401                         }
402                         else {
403                                 const arch_register_t *in1 = get_in_reg(n, 2);
404                                 const arch_register_t *in2 = get_in_reg(n, 3);
405                                 const arch_register_t *out = PRODUCES_RESULT(n) ? get_out_reg(n, 0) : NULL;
406                                 const arch_register_t *in;
407                                 const char            *in_name;
408
409                                 in      = out ? (REGS_ARE_EQUAL(out, in2) ? in1 : in2) : in2;
410                                 out     = out ? out : in1;
411                                 in_name = arch_register_get_name(in);
412
413                                 if (is_ia32_emit_cl(n)) {
414                                         assert(REGS_ARE_EQUAL(&ia32_gp_regs[REG_ECX], in) && "shift operation needs ecx");
415                                         in_name = "cl";
416                                 }
417
418                                 snprintf(buf, SNPRINTF_BUF_LEN, "%%%s, %%%s", arch_register_get_name(out), in_name);
419                         }
420                         break;
421                 case ia32_AddrModeS:
422                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
423                                 assert(! PRODUCES_RESULT(n) && "Source AM with Const must not produce result");
424                                 snprintf(buf, SNPRINTF_BUF_LEN, "%s, %s", get_ia32_cnst(n), ia32_emit_am(n, env));
425                         }
426                         else {
427                                 if (PRODUCES_RESULT(n)) {
428                                         lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D, %s", n, ia32_emit_am(n, env));
429                                 }
430                                 else {
431                                         lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%3S, %s", n, ia32_emit_am(n, env));
432                                 }
433                         }
434                         break;
435                 case ia32_AddrModeD:
436                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
437                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s,%s%s",
438                                         ia32_emit_am(n, env),
439                                         is_ia32_ImmSymConst(n) ? " OFFSET FLAT:" : " ",  /* In case of a symconst we must add OFFSET to */
440                                         get_ia32_cnst(n));                               /* tell the assembler to store it's address.   */
441                         }
442                         else {
443                                 const arch_register_t *in1 = get_in_reg(n, get_irn_arity(n) == 5 ? 3 : 2);
444                                 ir_mode               *mode = get_ia32_res_mode(n);
445                                 const char            *in_name;
446
447                                 mode    = mode ? mode : get_ia32_ls_mode(n);
448                                 in_name = ia32_get_reg_name_for_mode(env, mode, in1);
449
450                                 if (is_ia32_emit_cl(n)) {
451                                         assert(REGS_ARE_EQUAL(&ia32_gp_regs[REG_ECX], in1) && "shift operation needs ecx");
452                                         in_name = "cl";
453                                 }
454
455                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %%%s", ia32_emit_am(n, env), in_name);
456                         }
457                         break;
458                 default:
459                         assert(0 && "unsupported op type");
460         }
461
462 #undef PRODUCES_RESULT
463
464         return buf;
465 }
466
467 /**
468  * Returns the xxx PTR string for a given mode
469  *
470  * @param mode      the mode
471  * @param x87_insn  if non-zero returns the string for a x87 instruction
472  *                  else for a SSE instruction
473  */
474 static const char *pointer_size(ir_mode *mode, int x87_insn)
475 {
476         if (mode) {
477                 switch (get_mode_size_bits(mode)) {
478                 case 8:  return "BYTE PTR";
479                 case 16: return "WORD PTR";
480                 case 32: return "DWORD PTR";
481                 case 64:
482                         if (x87_insn)
483                                 return "QWORD PTR";
484                         return NULL;
485                 case 80:
486                 case 96: return "XWORD PTR";
487                 default: return NULL;
488                 }
489         }
490         return NULL;
491 }
492
493 /**
494  * Emits registers and/or address mode of a binary operation.
495  */
496 const char *ia32_emit_x87_binop(const ir_node *n, ia32_emit_env_t *env) {
497         static char *buf = NULL;
498
499         /* verify that this function is never called on non-AM supporting operations */
500         //assert(get_ia32_am_support(n) != ia32_am_None && "emit binop expects addressmode support");
501
502         if (! buf) {
503                 buf = xcalloc(1, SNPRINTF_BUF_LEN);
504         }
505         else {
506                 memset(buf, 0, SNPRINTF_BUF_LEN);
507         }
508
509         switch(get_ia32_op_type(n)) {
510                 case ia32_Normal:
511                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
512                                 ir_mode *mode = get_ia32_ls_mode(n);
513                                 const char *p = pointer_size(mode, 1);
514                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s %s", p, get_ia32_cnst(n));
515                         }
516                         else {
517                                 ia32_attr_t *attr = get_ia32_attr(n);
518                                 const arch_register_t *in1 = attr->x87[0];
519                                 const arch_register_t *in2 = attr->x87[1];
520                                 const arch_register_t *out = attr->x87[2];
521                                 const arch_register_t *in;
522                                 const char            *in_name;
523
524                                 in      = out ? (REGS_ARE_EQUAL(out, in2) ? in1 : in2) : in2;
525                                 out     = out ? out : in1;
526                                 in_name = arch_register_get_name(in);
527
528                                 snprintf(buf, SNPRINTF_BUF_LEN, "%%%s, %%%s", arch_register_get_name(out), in_name);
529                         }
530                         break;
531                 case ia32_AddrModeS:
532                 case ia32_AddrModeD:
533                         lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s", ia32_emit_am(n, env));
534                         break;
535                 default:
536                         assert(0 && "unsupported op type");
537         }
538
539         return buf;
540 }
541
542 /**
543  * Emits registers and/or address mode of a unary operation.
544  */
545 const char *ia32_emit_unop(const ir_node *n, ia32_emit_env_t *env) {
546         static char *buf = NULL;
547
548         if (! buf) {
549                 buf = xcalloc(1, SNPRINTF_BUF_LEN);
550         }
551         else {
552                 memset(buf, 0, SNPRINTF_BUF_LEN);
553         }
554
555         switch(get_ia32_op_type(n)) {
556                 case ia32_Normal:
557                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
558                                 lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%C", n);
559                         }
560                         else {
561                                 if (is_ia32_MulS(n) || is_ia32_Mulh(n)) {
562                                         /* MulS and Mulh implicitly multiply by EAX */
563                                         lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S", n);
564                                 }
565                                 else
566                                         lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D", n);
567                         }
568                         break;
569                 case ia32_AddrModeD:
570                         snprintf(buf, SNPRINTF_BUF_LEN, "%s", ia32_emit_am(n, env));
571                         break;
572                 case ia32_AddrModeS:
573                         /*
574                                 Mulh is emitted via emit_unop
575                                 imul [MEM]  means EDX:EAX <- EAX * [MEM]
576                         */
577                         assert((is_ia32_Mulh(n) || is_ia32_MulS(n)) && "Only MulS and Mulh can have AM source as unop");
578                         lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s", ia32_emit_am(n, env));
579                         break;
580                 default:
581                         assert(0 && "unsupported op type");
582         }
583
584         return buf;
585 }
586
587 /**
588  * Emits address mode.
589  */
590 const char *ia32_emit_am(const ir_node *n, ia32_emit_env_t *env) {
591         ia32_am_flavour_t am_flav    = get_ia32_am_flavour(n);
592         int               had_output = 0;
593         char              *s;
594         const char        *p;
595         static struct obstack *obst  = NULL;
596         ir_mode *mode = get_ia32_ls_mode(n);
597
598         if (! is_ia32_Lea(n))
599                 assert(mode && "AM node must have ls_mode attribute set.");
600
601         if (! obst) {
602                 obst = xcalloc(1, sizeof(*obst));
603         }
604         else {
605                 obstack_free(obst, NULL);
606         }
607
608         /* obstack_free with NULL results in an uninitialized obstack */
609         obstack_init(obst);
610
611         p = pointer_size(mode, has_x87_register(n) || is_ia32_GetST0(n) || is_ia32_SetST0(n));
612         if (p)
613                 obstack_printf(obst, "%s ", p);
614
615         /* emit address mode symconst */
616         if (get_ia32_am_sc(n)) {
617                 if (is_ia32_am_sc_sign(n))
618                         obstack_printf(obst, "-");
619                 obstack_printf(obst, "%s", get_id_str(get_ia32_am_sc(n)));
620         }
621
622         if (am_flav & ia32_B) {
623                 obstack_printf(obst, "[");
624                 lc_eoprintf(ia32_get_arg_env(), obst, "%1S", n);
625                 had_output = 1;
626         }
627
628         if (am_flav & ia32_I) {
629                 if (had_output) {
630                         obstack_printf(obst, "+");
631                 }
632                 else {
633                         obstack_printf(obst, "[");
634                 }
635
636                 lc_eoprintf(ia32_get_arg_env(), obst, "%2S", n);
637
638                 if (am_flav & ia32_S) {
639                         obstack_printf(obst, "*%d", 1 << get_ia32_am_scale(n));
640                 }
641
642                 had_output = 1;
643         }
644
645         if (am_flav & ia32_O) {
646                 s = get_ia32_am_offs(n);
647
648                 if (s) {
649                         /* omit explicit + if there was no base or index */
650                         if (! had_output) {
651                                 obstack_printf(obst, "[");
652                                 if (s[0] == '+')
653                                         s++;
654                         }
655
656                         obstack_printf(obst, s);
657                         had_output = 1;
658                 }
659         }
660
661         if (had_output)
662                 obstack_printf(obst, "] ");
663
664         obstack_1grow(obst, '\0');
665         s = obstack_finish(obst);
666
667         return s;
668 }
669
670 /**
671  * emit an address
672  */
673 const char *ia32_emit_adr(const ir_node *irn, ia32_emit_env_t *env)
674 {
675         static char buf[SNPRINTF_BUF_LEN];
676         ir_mode    *mode = get_ia32_ls_mode(irn);
677         const char *adr  = get_ia32_cnst(irn);
678         const char *pref = pointer_size(mode, has_x87_register(irn));
679
680         snprintf(buf, SNPRINTF_BUF_LEN, "%s %s", pref ? pref : "", adr);
681         return buf;
682 }
683
684 /**
685  * Formated print of commands and comments.
686  */
687 static void ia32_fprintf_format(FILE *F, const ir_node *irn, char *cmd_buf, char *cmnt_buf) {
688         unsigned lineno;
689         const char *name = irn ? be_retrieve_dbg_info(get_irn_dbg_info((ir_node *)irn), &lineno) : NULL;
690
691         if (name)
692                 fprintf(F, "\t%-35s %-60s /* %s:%u */\n", cmd_buf, cmnt_buf, name, lineno);
693         else
694                 fprintf(F, "\t%-35s %-60s\n", cmd_buf, cmnt_buf);
695 }
696
697
698
699 /**
700  * Add a number to a prefix. This number will not be used a second time.
701  */
702 static char *get_unique_label(char *buf, size_t buflen, const char *prefix) {
703         static unsigned long id = 0;
704         snprintf(buf, buflen, "%s%lu", prefix, ++id);
705         return buf;
706 }
707
708
709
710 /*************************************************
711  *                 _ _                         _
712  *                (_) |                       | |
713  *   ___ _ __ ___  _| |_    ___ ___  _ __   __| |
714  *  / _ \ '_ ` _ \| | __|  / __/ _ \| '_ \ / _` |
715  * |  __/ | | | | | | |_  | (_| (_) | | | | (_| |
716  *  \___|_| |_| |_|_|\__|  \___\___/|_| |_|\__,_|
717  *
718  *************************************************/
719
720 #undef IA32_DO_EMIT
721 #define IA32_DO_EMIT(irn) ia32_fprintf_format(F, irn, cmd_buf, cmnt_buf)
722
723 /*
724  * coding of conditions
725  */
726 struct cmp2conditon_t {
727         const char *name;
728         pn_Cmp      num;
729 };
730
731 /*
732  * positive conditions for signed compares
733  */
734 static const struct cmp2conditon_t cmp2condition_s[] = {
735   { NULL,              pn_Cmp_False },  /* always false */
736   { "e",               pn_Cmp_Eq },     /* == */
737   { "l",               pn_Cmp_Lt },     /* < */
738   { "le",              pn_Cmp_Le },     /* <= */
739   { "g",               pn_Cmp_Gt },     /* > */
740   { "ge",              pn_Cmp_Ge },     /* >= */
741   { "ne",              pn_Cmp_Lg },     /* != */
742   { "ordered",         pn_Cmp_Leg },    /* Floating point: ordered */
743   { "unordered",       pn_Cmp_Uo },     /* FLoting point: unordered */
744   { "e",               pn_Cmp_Ue },     /* Floating point: unordered or == */
745   { "b",               pn_Cmp_Ul },     /* Floating point: unordered or < */
746   { "be",              pn_Cmp_Ule },    /* Floating point: unordered or <= */
747   { "a",               pn_Cmp_Ug },     /* Floating point: unordered or > */
748   { "ae",              pn_Cmp_Uge },    /* Floating point: unordered or >= */
749   { "ne",              pn_Cmp_Ne },     /* Floating point: unordered or != */
750   { NULL,              pn_Cmp_True },   /* always true */
751 };
752
753 /*
754  * positive conditions for unsigned compares
755  */
756 static const struct cmp2conditon_t cmp2condition_u[] = {
757         { NULL,              pn_Cmp_False },  /* always false */
758         { "e",               pn_Cmp_Eq },     /* == */
759         { "b",               pn_Cmp_Lt },     /* < */
760         { "be",              pn_Cmp_Le },     /* <= */
761         { "a",               pn_Cmp_Gt },     /* > */
762         { "ae",              pn_Cmp_Ge },     /* >= */
763         { "ne",              pn_Cmp_Lg },     /* != */
764         { "ordered",         pn_Cmp_Leg },    /* Floating point: ordered */
765         { "unordered",       pn_Cmp_Uo },     /* FLoting point: unordered */
766         { "e",               pn_Cmp_Ue },     /* Floating point: unordered or == */
767         { "b",               pn_Cmp_Ul },     /* Floating point: unordered or < */
768         { "be",              pn_Cmp_Ule },    /* Floating point: unordered or <= */
769         { "a",               pn_Cmp_Ug },     /* Floating point: unordered or > */
770         { "ae",              pn_Cmp_Uge },    /* Floating point: unordered or >= */
771         { "ne",              pn_Cmp_Ne },     /* Floating point: unordered or != */
772         { NULL,              pn_Cmp_True },   /* always true */
773 };
774
775 /*
776  * returns the condition code
777  */
778 static const char *get_cmp_suffix(int cmp_code, int unsigned_cmp)
779 {
780         assert(cmp2condition_s[cmp_code].num == cmp_code);
781         assert(cmp2condition_u[cmp_code].num == cmp_code);
782
783         return unsigned_cmp ? cmp2condition_u[cmp_code & 7].name : cmp2condition_s[cmp_code & 7].name;
784 }
785
786 /**
787  * Returns the target block for a control flow node.
788  */
789 static ir_node *get_cfop_target_block(const ir_node *irn) {
790         return get_irn_link(irn);
791 }
792
793 /**
794  * Returns the target label for a control flow node.
795  */
796 static char *get_cfop_target(const ir_node *irn, char *buf) {
797         ir_node *bl = get_cfop_target_block(irn);
798
799         snprintf(buf, SNPRINTF_BUF_LEN, BLOCK_PREFIX("%ld"), get_irn_node_nr(bl));
800         return buf;
801 }
802
803 /** Return the next block in Block schedule */
804 static ir_node *next_blk_sched(const ir_node *block) {
805         return get_irn_link(block);
806 }
807
808 /**
809  * Returns the Proj with projection number proj and NOT mode_M
810  */
811 static ir_node *get_proj(const ir_node *irn, long proj) {
812         const ir_edge_t *edge;
813         ir_node         *src;
814
815         assert(get_irn_mode(irn) == mode_T && "expected mode_T node");
816
817         foreach_out_edge(irn, edge) {
818                 src = get_edge_src_irn(edge);
819
820                 assert(is_Proj(src) && "Proj expected");
821                 if (get_irn_mode(src) == mode_M)
822                         continue;
823
824                 if (get_Proj_proj(src) == proj)
825                         return src;
826         }
827         return NULL;
828 }
829
830 /**
831  * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
832  */
833 static void finish_CondJmp(FILE *F, const ir_node *irn, ir_mode *mode) {
834         const ir_node *proj_true;
835         const ir_node *proj_false;
836         const ir_node *block;
837         const ir_node *next_block;
838         char buf[SNPRINTF_BUF_LEN];
839         char cmd_buf[SNPRINTF_BUF_LEN];
840         char cmnt_buf[SNPRINTF_BUF_LEN];
841         int is_unsigned;
842         int pnc;
843         int flipped = 0;
844
845         /* get both Proj's */
846         proj_true = get_proj(irn, pn_Cond_true);
847         assert(proj_true && "CondJmp without true Proj");
848
849         proj_false = get_proj(irn, pn_Cond_false);
850         assert(proj_false && "CondJmp without false Proj");
851
852         pnc = get_ia32_pncode(irn);
853
854         /* for now, the code works for scheduled and non-schedules blocks */
855         block = get_nodes_block(irn);
856
857         /* we have a block schedule */
858         next_block = next_blk_sched(block);
859
860         if (get_cfop_target_block(proj_true) == next_block) {
861                 /* exchange both proj's so the second one can be omitted */
862                 const ir_node *t = proj_true;
863                 proj_true = proj_false;
864                 proj_false = t;
865
866                 flipped = 1;
867                 pnc = get_negated_pnc(pnc, mode);
868         }
869
870         /* the first Proj must always be created */
871         is_unsigned = mode_is_float(mode) || ! mode_is_signed(mode);
872         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
873                  get_cmp_suffix(pnc, is_unsigned),
874                  get_cfop_target(proj_true, buf));
875         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* %s(a, b) %s*/",
876                  get_pnc_string(pnc), flipped ? "(was flipped)" : "");
877         IA32_DO_EMIT(irn);
878
879         /* the second Proj might be a fallthrough */
880         if (get_cfop_target_block(proj_false) != next_block) {
881                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(proj_false, buf));
882                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* otherwise */");
883         }
884         else {
885                 cmd_buf[0] = '\0';
886                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* fallthrough %s */", get_cfop_target(proj_false, buf));
887         }
888         IA32_DO_EMIT(irn);
889 }
890
891 /**
892  * Emits code for conditional jump.
893  */
894 static void CondJmp_emitter(const ir_node *irn, ia32_emit_env_t *env) {
895         FILE *F = env->out;
896         char cmd_buf[SNPRINTF_BUF_LEN];
897         char cmnt_buf[SNPRINTF_BUF_LEN];
898
899         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmp %s", ia32_emit_binop(irn, env));
900         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
901         IA32_DO_EMIT(irn);
902         finish_CondJmp(F, irn, get_ia32_res_mode(irn));
903 }
904
905 /**
906  * Emits code for conditional jump with two variables.
907  */
908 static void emit_ia32_CondJmp(const ir_node *irn, ia32_emit_env_t *env) {
909         CondJmp_emitter(irn, env);
910 }
911
912 /**
913  * Emits code for conditional test and jump.
914  */
915 static void TestJmp_emitter(const ir_node *irn, ia32_emit_env_t *env) {
916
917 #define IA32_IS_IMMOP (is_ia32_ImmConst(irn) || is_ia32_ImmSymConst(irn))
918
919         FILE       *F   = env->out;
920         const char *op1 = arch_register_get_name(get_in_reg(irn, 0));
921         const char *op2 = IA32_IS_IMMOP ? get_ia32_cnst(irn) : NULL;
922         char        cmd_buf[SNPRINTF_BUF_LEN];
923         char        cmnt_buf[SNPRINTF_BUF_LEN];
924
925         if (! op2)
926                 op2 = arch_register_get_name(get_in_reg(irn, 1));
927
928         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "test %%%s,%s%s ", op1, IA32_IS_IMMOP ? " " : " %", op2);
929         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
930
931         IA32_DO_EMIT(irn);
932         finish_CondJmp(F, irn, get_ia32_res_mode(irn));
933
934 #undef IA32_IS_IMMOP
935 }
936
937 /**
938  * Emits code for conditional test and jump with two variables.
939  */
940 static void emit_ia32_TestJmp(const ir_node *irn, ia32_emit_env_t *env) {
941         TestJmp_emitter(irn, env);
942 }
943
944 static void emit_ia32_CJmp(const ir_node *irn, ia32_emit_env_t *env) {
945         FILE *F = env->out;
946         char cmd_buf[SNPRINTF_BUF_LEN];
947         char cmnt_buf[SNPRINTF_BUF_LEN];
948
949         snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
950         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F omitted redundant test */", irn);
951         IA32_DO_EMIT(irn);
952         finish_CondJmp(F, irn, get_ia32_res_mode(irn));
953 }
954
955 static void emit_ia32_CJmpAM(const ir_node *irn, ia32_emit_env_t *env) {
956         FILE *F = env->out;
957         char cmd_buf[SNPRINTF_BUF_LEN];
958         char cmnt_buf[SNPRINTF_BUF_LEN];
959
960         snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
961         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F omitted redundant test/cmp */", irn);
962         IA32_DO_EMIT(irn);
963         finish_CondJmp(F, irn, get_ia32_res_mode(irn));
964 }
965
966 /**
967  * Emits code for conditional SSE floating point jump with two variables.
968  */
969 static void emit_ia32_xCondJmp(ir_node *irn, ia32_emit_env_t *env) {
970         FILE *F = env->out;
971         char cmd_buf[SNPRINTF_BUF_LEN];
972         char cmnt_buf[SNPRINTF_BUF_LEN];
973
974         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "ucomis%M %s", irn, ia32_emit_binop(irn, env));
975         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
976         IA32_DO_EMIT(irn);
977         finish_CondJmp(F, irn, mode_F);
978
979 }
980
981 /**
982  * Emits code for conditional x87 floating point jump with two variables.
983  */
984 static void emit_ia32_x87CondJmp(ir_node *irn, ia32_emit_env_t *env) {
985         FILE *F = env->out;
986         char cmd_buf[SNPRINTF_BUF_LEN];
987         char cmnt_buf[SNPRINTF_BUF_LEN];
988         ia32_attr_t *attr = get_ia32_attr(irn);
989         const char *reg = attr->x87[1]->name;
990         const char *instr = "fcom";
991         int reverse = 0;
992
993         switch (get_ia32_irn_opcode(irn)) {
994         case iro_ia32_fcomrJmp:
995                 reverse = 1;
996         case iro_ia32_fcomJmp:
997         default:
998                 instr = "fucom";
999                 break;
1000         case iro_ia32_fcomrpJmp:
1001                 reverse = 1;
1002         case iro_ia32_fcompJmp:
1003                 instr = "fucomp";
1004                 break;
1005         case iro_ia32_fcomrppJmp:
1006                 reverse = 1;
1007         case iro_ia32_fcomppJmp:
1008                 instr = "fucompp";
1009                 reg = "";
1010                 break;
1011         }
1012
1013         if (reverse)
1014                 set_ia32_pncode(irn, (long)get_inversed_pnc(get_ia32_pncode(irn)));
1015
1016         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "%s %s%s", instr, reg[0] == '\0' ? "" : "%", reg);
1017         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
1018         IA32_DO_EMIT(irn);
1019         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "fnstsw %%ax", irn);
1020         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* Store x87 FPU Control Word */");
1021         IA32_DO_EMIT(irn);
1022         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "sahf");
1023         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* Store ah into flags */");
1024         IA32_DO_EMIT(irn);
1025
1026         /* the compare flags must be evaluated using carry , ie unsigned */
1027         finish_CondJmp(F, irn, mode_Iu);
1028 }
1029
1030 static void CMov_emitter(ir_node *irn, ia32_emit_env_t *env) {
1031         FILE               *F       = env->out;
1032         const lc_arg_env_t *arg_env = ia32_get_arg_env();
1033         ir_mode    *mode       = get_irn_mode(get_irn_n(irn, 0));
1034         int        is_unsigned = mode_is_float(mode) || ! mode_is_signed(mode);
1035         const char *cmp_suffix = get_cmp_suffix(get_ia32_pncode(irn), is_unsigned);
1036         int is_PsiCondCMov     = is_ia32_PsiCondCMov(irn);
1037         int idx_left  = 2 - is_PsiCondCMov;
1038         int idx_right = 3 - is_PsiCondCMov;
1039
1040         char cmd_buf[SNPRINTF_BUF_LEN];
1041         char cmnt_buf[SNPRINTF_BUF_LEN];
1042         const arch_register_t *in1, *in2, *out;
1043
1044         out = arch_get_irn_register(env->arch_env, irn);
1045         in1 = arch_get_irn_register(env->arch_env, get_irn_n(irn, idx_left));
1046         in2 = arch_get_irn_register(env->arch_env, get_irn_n(irn, idx_right));
1047
1048         /* we have to emit the cmp first, because the destination register */
1049         /* could be one of the compare registers                           */
1050         if (is_ia32_CmpCMov(irn)) {
1051                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "cmp %1S, %2S", irn, irn);
1052         }
1053         else if (is_ia32_xCmpCMov(irn)) {
1054                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "ucomis%M %1S, %2S", get_irn_n(irn, 0), irn, irn);
1055         }
1056         else if (is_PsiCondCMov) {
1057                 /* omit compare because flags are already set by And/Or */
1058                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "test %1S, %1S", irn, irn);
1059         }
1060         else {
1061                 assert(0 && "unsupported CMov");
1062         }
1063         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* Psi condition */" );
1064         IA32_DO_EMIT(irn);
1065
1066         if (REGS_ARE_EQUAL(out, in2)) {
1067                 /* best case: default in == out -> do nothing */
1068         }
1069         else if (REGS_ARE_EQUAL(out, in1)) {
1070                 /* true in == out -> need complement compare and exchange true and default in */
1071                 ir_node *t = get_irn_n(irn, idx_left);
1072                 set_irn_n(irn, idx_left, get_irn_n(irn, idx_right));
1073                 set_irn_n(irn, idx_right, t);
1074
1075                 cmp_suffix  = get_cmp_suffix(get_negated_pnc(get_ia32_pncode(irn), get_irn_mode(irn)), is_unsigned);
1076
1077         }
1078         else {
1079                 /* out is different from in: need copy default -> out */
1080                 if (is_PsiCondCMov)
1081                         lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, %3S", irn, irn);
1082                 else
1083                         lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, %4S", irn, irn);
1084
1085                 lc_esnprintf(arg_env, cmnt_buf, SNPRINTF_BUF_LEN, "/* copy default -> out */" );
1086                 IA32_DO_EMIT(irn);
1087         }
1088
1089         if (is_PsiCondCMov)
1090                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "cmov%s %1D, %2S", cmp_suffix, irn, irn);
1091         else
1092                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "cmov%s %1D, %3S", cmp_suffix, irn, irn);
1093
1094         lc_esnprintf(arg_env, cmnt_buf, SNPRINTF_BUF_LEN, "/* condition is true case */" );
1095         IA32_DO_EMIT(irn);
1096 }
1097
1098 static void emit_ia32_CmpCMov(ir_node *irn, ia32_emit_env_t *env) {
1099         CMov_emitter(irn, env);
1100 }
1101
1102 static void emit_ia32_PsiCondCMov(ir_node *irn, ia32_emit_env_t *env) {
1103         CMov_emitter(irn, env);
1104 }
1105
1106 static void emit_ia32_xCmpCMov(ir_node *irn, ia32_emit_env_t *env) {
1107         CMov_emitter(irn, env);
1108 }
1109
1110 static void Set_emitter(ir_node *irn, ir_mode *mode, ia32_emit_env_t *env) {
1111         FILE               *F       = env->out;
1112         const lc_arg_env_t *arg_env = ia32_get_arg_env();
1113         int        is_unsigned = mode_is_float(mode) || ! mode_is_signed(mode);
1114         const char *cmp_suffix = get_cmp_suffix(get_ia32_pncode(irn), is_unsigned);
1115         const char *reg8bit;
1116
1117         char cmd_buf[SNPRINTF_BUF_LEN];
1118         char cmnt_buf[SNPRINTF_BUF_LEN];
1119         const arch_register_t *out;
1120
1121         out     = arch_get_irn_register(env->arch_env, irn);
1122         reg8bit = ia32_get_mapped_reg_name(env->isa->regs_8bit, out);
1123
1124         if (is_ia32_CmpSet(irn)) {
1125                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "cmp %s", ia32_emit_binop(irn, env));
1126         }
1127         else if (is_ia32_xCmpSet(irn)) {
1128                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "ucomis%M %s", get_irn_n(irn, 2), ia32_emit_binop(irn, env));
1129         }
1130         else if (is_ia32_PsiCondSet(irn)) {
1131                 /* omit compare because flags are already set by And/Or */
1132                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
1133         }
1134         else {
1135                 assert(0 && "unsupported Set");
1136         }
1137         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* calculate Psi condition */" );
1138         IA32_DO_EMIT(irn);
1139
1140         /* use mov to clear target because it doesn't affect the eflags */
1141         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "mov %%%s, 0", arch_register_get_name(out));
1142         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* clear target as set modifies only lower 8 bit */");
1143         IA32_DO_EMIT(irn);
1144
1145         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "set%s %%%s", cmp_suffix, reg8bit);
1146         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* set 1 iff true, 0 otherweise */" );
1147         IA32_DO_EMIT(irn);
1148 }
1149
1150 static void emit_ia32_CmpSet(ir_node *irn, ia32_emit_env_t *env) {
1151         Set_emitter(irn, get_irn_mode(get_irn_n(irn, 2)), env);
1152 }
1153
1154 static void emit_ia32_PsiCondSet(ir_node *irn, ia32_emit_env_t *env) {
1155         Set_emitter(irn, get_irn_mode(get_irn_n(irn, 0)), env);
1156 }
1157
1158 static void emit_ia32_xCmpSet(ir_node *irn, ia32_emit_env_t *env) {
1159         Set_emitter(irn, get_irn_mode(get_irn_n(irn, 2)), env);
1160 }
1161
1162 static void emit_ia32_xCmp(ir_node *irn, ia32_emit_env_t *env) {
1163         FILE               *F       = env->out;
1164         const lc_arg_env_t *arg_env = ia32_get_arg_env();
1165         int                sse_pnc  = -1;
1166         long               pnc      = get_ia32_pncode(irn);
1167         long               unord    = pnc & pn_Cmp_Uo;
1168         char cmd_buf[SNPRINTF_BUF_LEN];
1169         char cmnt_buf[SNPRINTF_BUF_LEN];
1170
1171         switch (pnc) {
1172                 case pn_Cmp_Leg: /* odered */
1173                         sse_pnc = 7;
1174                         break;
1175                 case pn_Cmp_Uo:  /* unordered */
1176                         sse_pnc = 3;
1177                         break;
1178                 case pn_Cmp_Ue:
1179                 case pn_Cmp_Eq:  /* == */
1180                         sse_pnc = 0;
1181                         break;
1182                 case pn_Cmp_Ul:
1183                 case pn_Cmp_Lt:  /* < */
1184                         sse_pnc = 1;
1185                         break;
1186                 case pn_Cmp_Ule:
1187                 case pn_Cmp_Le: /* <= */
1188                         sse_pnc = 2;
1189                         break;
1190                 case pn_Cmp_Ug:
1191                 case pn_Cmp_Gt:  /* > */
1192                         sse_pnc = 6;
1193                         break;
1194                 case pn_Cmp_Uge:
1195                 case pn_Cmp_Ge: /* >= */
1196                         sse_pnc = 5;
1197                         break;
1198                 case pn_Cmp_Ne:
1199                 case pn_Cmp_Lg:  /* != */
1200                         sse_pnc = 4;
1201                         break;
1202         }
1203
1204         assert(sse_pnc >= 0 && "unsupported compare");
1205
1206         if (unord && sse_pnc != 3) {
1207                 /*
1208                         We need a separate compare against unordered.
1209                         Quick and Dirty solution:
1210                         - get some memory on stack
1211                         - compare
1212                         - store result
1213                         - compare
1214                         - and result and stored result
1215                     - cleanup stack
1216                 */
1217                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "sub %%esp, 8");
1218                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* reserve some space for unordered compare result */");
1219                 IA32_DO_EMIT(NULL);
1220                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmpsd %s, 3", ia32_emit_binop(irn, env));
1221                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* SSE compare: unordered */");
1222                 IA32_DO_EMIT(NULL);
1223                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "movsd [%%esp], %1D", irn);
1224                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* store compare result */");
1225                 IA32_DO_EMIT(NULL);
1226         }
1227
1228         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmpsd %s, %d", ia32_emit_binop(irn, env), sse_pnc);
1229         lc_esnprintf(arg_env, cmnt_buf, SNPRINTF_BUF_LEN, "/* SSE compare (%+F) with result in %1D */", irn, irn);
1230         IA32_DO_EMIT(irn);
1231
1232         if (unord && sse_pnc != 3) {
1233                 lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "andpd %1D, [%%esp]", irn);
1234                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* build the final result */");
1235                 IA32_DO_EMIT(NULL);
1236                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "add %%esp, 8");
1237                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* free allocated space */");
1238                 IA32_DO_EMIT(NULL);
1239         }
1240 }
1241
1242 /*********************************************************
1243  *                 _ _       _
1244  *                (_) |     (_)
1245  *   ___ _ __ ___  _| |_     _ _   _ _ __ ___  _ __  ___
1246  *  / _ \ '_ ` _ \| | __|   | | | | | '_ ` _ \| '_ \/ __|
1247  * |  __/ | | | | | | |_    | | |_| | | | | | | |_) \__ \
1248  *  \___|_| |_| |_|_|\__|   | |\__,_|_| |_| |_| .__/|___/
1249  *                         _/ |               | |
1250  *                        |__/                |_|
1251  *********************************************************/
1252
1253 /* jump table entry (target and corresponding number) */
1254 typedef struct _branch_t {
1255         ir_node *target;
1256         int      value;
1257 } branch_t;
1258
1259 /* jump table for switch generation */
1260 typedef struct _jmp_tbl_t {
1261         ir_node  *defProj;         /**< default target */
1262         int       min_value;       /**< smallest switch case */
1263         int       max_value;       /**< largest switch case */
1264         int       num_branches;    /**< number of jumps */
1265         char     *label;           /**< label of the jump table */
1266         branch_t *branches;        /**< jump array */
1267 } jmp_tbl_t;
1268
1269 /**
1270  * Compare two variables of type branch_t. Used to sort all switch cases
1271  */
1272 static int ia32_cmp_branch_t(const void *a, const void *b) {
1273         branch_t *b1 = (branch_t *)a;
1274         branch_t *b2 = (branch_t *)b;
1275
1276         if (b1->value <= b2->value)
1277                 return -1;
1278         else
1279                 return 1;
1280 }
1281
1282 /**
1283  * Emits code for a SwitchJmp (creates a jump table if
1284  * possible otherwise a cmp-jmp cascade). Port from
1285  * cggg ia32 backend
1286  */
1287 static void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) {
1288         unsigned long       interval;
1289         char                buf[SNPRINTF_BUF_LEN];
1290         int                 last_value, i, pn;
1291         jmp_tbl_t           tbl;
1292         ir_node            *proj;
1293         const ir_edge_t    *edge;
1294         const lc_arg_env_t *env = ia32_get_arg_env();
1295         FILE               *F   = emit_env->out;
1296         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1297
1298         /* fill the table structure */
1299         tbl.label        = xmalloc(SNPRINTF_BUF_LEN);
1300         tbl.label        = get_unique_label(tbl.label, SNPRINTF_BUF_LEN, ".TBL_");
1301         tbl.defProj      = NULL;
1302         tbl.num_branches = get_irn_n_edges(irn);
1303         tbl.branches     = xcalloc(tbl.num_branches, sizeof(tbl.branches[0]));
1304         tbl.min_value    = INT_MAX;
1305         tbl.max_value    = INT_MIN;
1306
1307         i = 0;
1308         /* go over all proj's and collect them */
1309         foreach_out_edge(irn, edge) {
1310                 proj = get_edge_src_irn(edge);
1311                 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
1312
1313                 pn = get_Proj_proj(proj);
1314
1315                 /* create branch entry */
1316                 tbl.branches[i].target = proj;
1317                 tbl.branches[i].value  = pn;
1318
1319                 tbl.min_value = pn < tbl.min_value ? pn : tbl.min_value;
1320                 tbl.max_value = pn > tbl.max_value ? pn : tbl.max_value;
1321
1322                 /* check for default proj */
1323                 if (pn == get_ia32_pncode(irn)) {
1324                         assert(tbl.defProj == NULL && "found two defProjs at SwitchJmp");
1325                         tbl.defProj = proj;
1326                 }
1327
1328                 i++;
1329         }
1330
1331         /* sort the branches by their number */
1332         qsort(tbl.branches, tbl.num_branches, sizeof(tbl.branches[0]), ia32_cmp_branch_t);
1333
1334         /* two-complement's magic make this work without overflow */
1335         interval = tbl.max_value - tbl.min_value;
1336
1337         /* emit the table */
1338         lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "cmp %1S, %u", irn, interval);
1339         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* compare for switch */");
1340         IA32_DO_EMIT(irn);
1341
1342         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "ja %s", get_cfop_target(tbl.defProj, buf));
1343         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default jump if out of range  */");
1344         IA32_DO_EMIT(irn);
1345
1346         if (tbl.num_branches > 1) {
1347                 /* create table */
1348
1349                 lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "jmp %s[%1S*4]", tbl.label, irn);
1350                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* get jump table entry as target */");
1351                 IA32_DO_EMIT(irn);
1352
1353                 ia32_switch_section(F, SECTION_RODATA);
1354                 fprintf(F, "\t.align 4\n");
1355
1356                 fprintf(F, "%s:\n", tbl.label);
1357
1358                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.branches[0].target, buf));
1359                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */",  tbl.branches[0].value);
1360                 IA32_DO_EMIT(irn);
1361
1362                 last_value = tbl.branches[0].value;
1363                 for (i = 1; i < tbl.num_branches; ++i) {
1364                         while (++last_value < tbl.branches[i].value) {
1365                                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.defProj, buf));
1366                                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default case */");
1367                                 IA32_DO_EMIT(irn);
1368                         }
1369                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.branches[i].target, buf));
1370                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */", last_value);
1371                         IA32_DO_EMIT(irn);
1372                 }
1373                 ia32_switch_section(F, SECTION_TEXT);
1374         }
1375         else {
1376                 /* one jump is enough */
1377                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(tbl.branches[0].target, buf));
1378                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* only one case given */");
1379                 IA32_DO_EMIT(irn);
1380         }
1381
1382         if (tbl.label)
1383                 free(tbl.label);
1384         if (tbl.branches)
1385                 free(tbl.branches);
1386 }
1387
1388 /**
1389  * Emits code for a unconditional jump.
1390  */
1391 static void emit_Jmp(const ir_node *irn, ia32_emit_env_t *env) {
1392         ir_node *block, *next_bl;
1393         FILE *F = env->out;
1394         char buf[SNPRINTF_BUF_LEN], cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1395
1396         /* for now, the code works for scheduled and non-schedules blocks */
1397         block = get_nodes_block(irn);
1398
1399         /* we have a block schedule */
1400         next_bl = next_blk_sched(block);
1401         if (get_cfop_target_block(irn) != next_bl) {
1402                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(irn, buf));
1403                 lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%+F) */", irn, get_cfop_target_block(irn));
1404         }
1405         else {
1406                 cmd_buf[0] = '\0';
1407                 lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* fallthrough %s */", get_cfop_target(irn, buf));
1408         }
1409         IA32_DO_EMIT(irn);
1410 }
1411
1412 /****************************
1413  *                  _
1414  *                 (_)
1415  *  _ __  _ __ ___  _  ___
1416  * | '_ \| '__/ _ \| |/ __|
1417  * | |_) | | | (_) | |\__ \
1418  * | .__/|_|  \___/| ||___/
1419  * | |            _/ |
1420  * |_|           |__/
1421  ****************************/
1422
1423 /**
1424  * Emits code for a proj -> node
1425  */
1426 static void emit_Proj(const ir_node *irn, ia32_emit_env_t *env) {
1427         ir_node *pred = get_Proj_pred(irn);
1428
1429         if (get_irn_op(pred) == op_Start) {
1430                 switch(get_Proj_proj(irn)) {
1431                         case pn_Start_X_initial_exec:
1432                                 emit_Jmp(irn, env);
1433                                 break;
1434                         default:
1435                                 break;
1436                 }
1437         }
1438 }
1439
1440 /**********************************
1441  *   _____                  ____
1442  *  / ____|                |  _ \
1443  * | |     ___  _ __  _   _| |_) |
1444  * | |    / _ \| '_ \| | | |  _ <
1445  * | |___| (_) | |_) | |_| | |_) |
1446  *  \_____\___/| .__/ \__, |____/
1447  *             | |     __/ |
1448  *             |_|    |___/
1449  **********************************/
1450
1451 /**
1452  * Emit movsb/w instructions to make mov count divideable by 4
1453  */
1454 static void emit_CopyB_prolog(FILE *F, const ir_node *irn, int rem) {
1455         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1456
1457         ir_fprintf(F, "\t/* memcopy prolog %+F */\n", irn);
1458
1459         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cld");
1460         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* copy direction forward */");
1461
1462         switch(rem) {
1463                 case 1:
1464                         IA32_DO_EMIT(NULL);
1465                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsb");
1466                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 1 */");
1467                         break;
1468                 case 2:
1469                         IA32_DO_EMIT(NULL);
1470                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsw");
1471                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 2 */");
1472                         break;
1473                 case 3:
1474                         IA32_DO_EMIT(NULL);
1475                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsb");
1476                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 3 */");
1477                         IA32_DO_EMIT(NULL);
1478                         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsw");
1479                         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 3 */");
1480                         break;
1481         }
1482
1483         IA32_DO_EMIT(NULL);
1484 }
1485
1486 /**
1487  * Emit rep movsd instruction for memcopy.
1488  */
1489 static void emit_ia32_CopyB(const ir_node *irn, ia32_emit_env_t *emit_env) {
1490         FILE   *F  = emit_env->out;
1491         tarval *tv = get_ia32_Immop_tarval(irn);
1492         int    rem = get_tarval_long(tv);
1493         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1494
1495         emit_CopyB_prolog(F, irn, rem);
1496
1497         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "rep movsd");
1498         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy */");
1499         IA32_DO_EMIT(irn);
1500 }
1501
1502 /**
1503  * Emits unrolled memcopy.
1504  */
1505 static void emit_ia32_CopyB_i(const ir_node *irn, ia32_emit_env_t *emit_env) {
1506         tarval *tv   = get_ia32_Immop_tarval(irn);
1507         int     size = get_tarval_long(tv);
1508         FILE   *F    = emit_env->out;
1509         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1510
1511         emit_CopyB_prolog(F, irn, size & 0x3);
1512
1513         size >>= 2;
1514         while (size--) {
1515                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsd");
1516                 snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy unrolled */");
1517                 IA32_DO_EMIT(irn);
1518         }
1519 }
1520
1521
1522
1523 /***************************
1524  *   _____
1525  *  / ____|
1526  * | |     ___  _ ____   __
1527  * | |    / _ \| '_ \ \ / /
1528  * | |___| (_) | | | \ V /
1529  *  \_____\___/|_| |_|\_/
1530  *
1531  ***************************/
1532
1533 /**
1534  * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1535  */
1536 static void emit_ia32_Conv_with_FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1537         FILE               *F        = emit_env->out;
1538         const lc_arg_env_t *env      = ia32_get_arg_env();
1539         ir_mode            *src_mode = get_ia32_src_mode(irn);
1540         ir_mode            *tgt_mode = get_ia32_tgt_mode(irn);
1541         char               *from, *to, buf[64];
1542         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1543
1544         from = mode_is_float(src_mode) ? (get_mode_size_bits(src_mode) == 32 ? "ss" : "sd") : "si";
1545         to   = mode_is_float(tgt_mode) ? (get_mode_size_bits(tgt_mode) == 32 ? "ss" : "sd") : "si";
1546
1547         switch(get_ia32_op_type(irn)) {
1548                 case ia32_Normal:
1549                         lc_esnprintf(env, buf, sizeof(buf), "%1D, %3S", irn, irn);
1550                         break;
1551                 case ia32_AddrModeS:
1552                         lc_esnprintf(env, buf, sizeof(buf), "%1D, %s", irn, ia32_emit_am(irn, emit_env));
1553                         break;
1554                 default:
1555                         assert(0 && "unsupported op type for Conv");
1556         }
1557
1558         snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cvt%s2%s %s", from, to, buf);
1559         lc_esnprintf(env, cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%+F, %+F) */", irn, src_mode, tgt_mode);
1560         IA32_DO_EMIT(irn);
1561 }
1562
1563 static void emit_ia32_Conv_I2FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1564         emit_ia32_Conv_with_FP(irn, emit_env);
1565 }
1566
1567 static void emit_ia32_Conv_FP2I(const ir_node *irn, ia32_emit_env_t *emit_env) {
1568         emit_ia32_Conv_with_FP(irn, emit_env);
1569 }
1570
1571 static void emit_ia32_Conv_FP2FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1572         emit_ia32_Conv_with_FP(irn, emit_env);
1573 }
1574
1575 /**
1576  * Emits code for an Int conversion.
1577  */
1578 static void emit_ia32_Conv_I2I(const ir_node *irn, ia32_emit_env_t *emit_env) {
1579         FILE               *F        = emit_env->out;
1580         const lc_arg_env_t *env      = ia32_get_arg_env();
1581         char               *move_cmd = "movzx";
1582         char               *conv_cmd = NULL;
1583         ir_mode            *src_mode = get_ia32_src_mode(irn);
1584         ir_mode            *tgt_mode = get_ia32_tgt_mode(irn);
1585         int n, m;
1586         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1587         const arch_register_t *in_reg, *out_reg;
1588
1589         n = get_mode_size_bits(src_mode);
1590         m = get_mode_size_bits(tgt_mode);
1591
1592         if (mode_is_signed(n < m ? src_mode : tgt_mode)) {
1593                 move_cmd = "movsx";
1594                 if (n == 8 || m == 8)
1595                         conv_cmd = "cbw";
1596                 else if (n == 16 || m == 16)
1597                         conv_cmd = "cwde";
1598                 else {
1599                         printf("%d -> %d unsupported\n", n, m);
1600                         assert(0 && "unsupported Conv_I2I");
1601                 }
1602         }
1603
1604          switch(get_ia32_op_type(irn)) {
1605                 case ia32_Normal:
1606                         in_reg  = get_in_reg(irn, 2);
1607                         out_reg = get_out_reg(irn, 0);
1608
1609                         if (REGS_ARE_EQUAL(in_reg, &ia32_gp_regs[REG_EAX]) &&
1610                                 REGS_ARE_EQUAL(out_reg, in_reg)                &&
1611                                 mode_is_signed(n < m ? src_mode : tgt_mode))
1612                         {
1613                                 /* argument and result are both in EAX and */
1614                                 /* signedness is ok: -> use converts       */
1615                                 lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s", conv_cmd);
1616                         }
1617                         else if (REGS_ARE_EQUAL(out_reg, in_reg) &&
1618                                 ! mode_is_signed(n < m ? src_mode : tgt_mode))
1619                         {
1620                                 /* argument and result are in the same register */
1621                                 /* and signedness is ok: -> use and with mask   */
1622                                 int mask = (1 << (n < m ? n : m)) - 1;
1623                                 lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "and %1D, 0x%x", irn, mask);
1624                         }
1625                         else {
1626                                 /* use move w/o sign extension */
1627                                 lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s %1D, %%%s",
1628                                         move_cmd, irn, ia32_get_reg_name_for_mode(emit_env, n < m ? src_mode : tgt_mode, in_reg));
1629                         }
1630
1631                         break;
1632                 case ia32_AddrModeS:
1633                         lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s %1D, %s",
1634                                 move_cmd, irn, ia32_emit_am(irn, emit_env));
1635                         break;
1636                 default:
1637                         assert(0 && "unsupported op type for Conv");
1638         }
1639
1640         lc_esnprintf(env, cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%d Bit mode_%F -> %d Bit mode_%F) */",
1641                 irn, n, src_mode, m, tgt_mode);
1642
1643         IA32_DO_EMIT(irn);
1644 }
1645
1646 /**
1647  * Emits code for an 8Bit Int conversion.
1648  */
1649 void emit_ia32_Conv_I2I8Bit(const ir_node *irn, ia32_emit_env_t *emit_env) {
1650         emit_ia32_Conv_I2I(irn, emit_env);
1651 }
1652
1653
1654 /*******************************************
1655  *  _                          _
1656  * | |                        | |
1657  * | |__   ___ _ __   ___   __| | ___  ___
1658  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
1659  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
1660  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
1661  *
1662  *******************************************/
1663
1664 /**
1665  * Emits a backend call
1666  */
1667 static void emit_be_Call(const ir_node *irn, ia32_emit_env_t *emit_env) {
1668         FILE *F = emit_env->out;
1669         entity *ent = be_Call_get_entity(irn);
1670         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1671
1672         if (ent) {
1673                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, "call %s", get_entity_ld_name(ent));
1674         }
1675         else {
1676                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "call %1D", get_irn_n(irn, be_pos_Call_ptr));
1677         }
1678
1679         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (be_Call) */", irn);
1680
1681         IA32_DO_EMIT(irn);
1682 }
1683
1684 /**
1685  * Emits code to increase stack pointer.
1686  */
1687 static void emit_be_IncSP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1688         FILE          *F    = emit_env->out;
1689         int offs = be_get_IncSP_offset(irn);
1690         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1691
1692         if (offs) {
1693                 if (offs > 0)
1694                         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "sub %1S, %u", irn, offs);
1695                 else
1696                         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1S, %u", irn, -offs);
1697                 lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (IncSP) */", irn);
1698         }
1699         else {
1700                 snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
1701                 lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* omitted %+F (IncSP) with 0 */", irn);
1702         }
1703
1704         IA32_DO_EMIT(irn);
1705 }
1706
1707 /**
1708  * Emits code to set stack pointer.
1709  */
1710 static void emit_be_SetSP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1711         FILE *F = emit_env->out;
1712         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1713
1714         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, %3S", irn, irn);
1715         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (restore SP) */", irn);
1716         IA32_DO_EMIT(irn);
1717 }
1718
1719 /**
1720  * Emits code for Copy/CopyKeep.
1721  */
1722 static void Copy_emitter(const ir_node *irn, ir_node *op, ia32_emit_env_t *emit_env) {
1723         FILE             *F    = emit_env->out;
1724         const arch_env_t *aenv = emit_env->arch_env;
1725         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1726
1727         if (REGS_ARE_EQUAL(arch_get_irn_register(aenv, irn), arch_get_irn_register(aenv, op)) ||
1728                 be_is_unknown_reg(arch_get_irn_register(aenv, op)))
1729                 return;
1730
1731         if (mode_is_float(get_irn_mode(irn)))
1732                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "movs%M %1D, %1S", irn, irn, irn);
1733         else
1734                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, %1S", irn, irn);
1735         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
1736         IA32_DO_EMIT(irn);
1737 }
1738
1739 static void emit_be_Copy(const ir_node *irn, ia32_emit_env_t *emit_env) {
1740         Copy_emitter(irn, be_get_Copy_op(irn), emit_env);
1741 }
1742
1743 static void emit_be_CopyKeep(const ir_node *irn, ia32_emit_env_t *emit_env) {
1744         Copy_emitter(irn, be_get_CopyKeep_op(irn), emit_env);
1745 }
1746
1747 /**
1748  * Emits code for exchange.
1749  */
1750 static void emit_be_Perm(const ir_node *irn, ia32_emit_env_t *emit_env) {
1751         FILE *F = emit_env->out;
1752         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1753         const arch_register_t *in1, *in2;
1754         const arch_register_class_t *cls1, *cls2;
1755
1756         in1 = arch_get_irn_register(emit_env->arch_env, get_irn_n(irn, 0));
1757         in2 = arch_get_irn_register(emit_env->arch_env, get_irn_n(irn, 1));
1758
1759         cls1 = arch_register_get_class(in1);
1760         cls2 = arch_register_get_class(in2);
1761
1762         assert(cls1 == cls2 && "Register class mismatch at Perm");
1763
1764         if (cls1 == &ia32_reg_classes[CLASS_ia32_gp]) {
1765                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "xchg %1S, %2S", irn, irn);
1766         }
1767         else if (cls1 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1768                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN,
1769                         "pxor %1S, %2S\n\tpxor %2S, %1S\n\tpxor %1S, %2S", irn, irn, irn, irn, irn, irn);
1770         }
1771         else if (cls1 == &ia32_reg_classes[CLASS_ia32_vfp]) {
1772                 /* is a NOP */
1773                 cmd_buf[0] = '\0';
1774         }
1775         else if (cls1 == &ia32_reg_classes[CLASS_ia32_st]) {
1776                 /* is a NOP */
1777                 cmd_buf[0] = '\0';
1778         }
1779
1780         lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%1A, %2A) */", irn, irn, irn);
1781         IA32_DO_EMIT(irn);
1782 }
1783
1784 /**
1785  * Emits code for Constant loading.
1786  */
1787 static void emit_ia32_Const(const ir_node *n, ia32_emit_env_t *env) {
1788         FILE *F = env->out;
1789         char cmd_buf[256], cmnt_buf[256];
1790         const lc_arg_env_t *arg_env = ia32_get_arg_env();
1791
1792         if (get_ia32_Immop_tarval(n) == get_tarval_null(get_irn_mode(n))) {
1793                 const char *instr = "xor";
1794                 if (env->isa->opt_arch == arch_pentium_4) {
1795                         /* P4 prefers sub r, r, others xor r, r */
1796                         instr = "sub";
1797                 }
1798                 lc_esnprintf(arg_env, cmd_buf, 256, "%s %1D, %1D ", instr, n, n);
1799                 lc_esnprintf(arg_env, cmnt_buf, 256, "/* optimized mov 0 to register */");
1800         }
1801         else {
1802                 if (get_ia32_op_type(n) == ia32_SymConst) {
1803                         lc_esnprintf(arg_env, cmd_buf, 256, "mov %1D, OFFSET FLAT:%C ", n, n);
1804                         lc_esnprintf(arg_env, cmnt_buf, 256, "/* Move address of SymConst into register */");
1805                 }
1806                 else {
1807                         lc_esnprintf(arg_env, cmd_buf, 256, "mov %1D, %C ", n, n);
1808                         lc_esnprintf(arg_env, cmnt_buf, 256, "/* Mov Const into register */");
1809                 }
1810         }
1811         lc_efprintf(arg_env, F, "\t%-35s %-60s /* %+F (%+G) */\n", cmd_buf, cmnt_buf, n, n);
1812 }
1813
1814 /**
1815  * Emits code to increase stack pointer.
1816  */
1817 static void emit_ia32_AddSP(const ir_node *irn, ia32_emit_env_t *emit_env) {
1818         FILE *F = emit_env->out;
1819         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1820
1821         if (is_ia32_ImmConst(irn)) {
1822                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "sub %1D, %C", irn, irn);
1823         }
1824         else if (is_ia32_ImmSymConst(irn)) {
1825                 if (get_ia32_op_type(irn) == ia32_Normal)
1826                         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "sub %1D, OFFSET_FLAT:%C", irn, irn);
1827                 else /* source address mode */
1828                         lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "sub %1D, [%s%s]", irn, get_id_str(get_ia32_am_sc(irn)), get_ia32_am_offs(irn));
1829         }
1830         else {
1831                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "sub %1D, %2S", irn, irn);
1832         }
1833         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* reserve space on stack */");
1834
1835         IA32_DO_EMIT(irn);
1836 }
1837
1838 /**
1839  * Emits code to load the TLS base
1840  */
1841 static void emit_ia32_LdTls(const ir_node *irn, ia32_emit_env_t *emit_env) {
1842         FILE *F = emit_env->out;
1843         char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
1844
1845         switch (asm_flavour) {
1846         case ASM_LINUX_GAS:
1847                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, DWORD PTR %%gs:0", irn);
1848                 break;
1849         case ASM_MINGW_GAS:
1850                 lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, DWORD PTR %%gs:0", irn);
1851                 break;
1852         default:
1853                 assert(0 && "unsupported TLS");
1854                 break;
1855         }
1856         snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* get thread local storage base */");
1857
1858         IA32_DO_EMIT(irn);
1859 }
1860
1861 static void emit_be_Return(const ir_node *n, ia32_emit_env_t *env) {
1862         FILE *F = env->out;
1863         const lc_arg_env_t *arg_env = ia32_get_arg_env();
1864
1865         lc_efprintf(arg_env, F, "\t%-35s %-60s /* %+F (%+G) */\n", "ret", "/* be_Return */", n, n);
1866 }
1867
1868 static void emit_Nothing(const ir_node *n, ia32_emit_env_t *env) {
1869         FILE *F = env->out;
1870
1871         ir_fprintf(F, "\t%35s /* %+F (%+G) */\n", " ", n, n);
1872 }
1873
1874
1875 /***********************************************************************************
1876  *                  _          __                                             _
1877  *                 (_)        / _|                                           | |
1878  *  _ __ ___   __ _ _ _ __   | |_ _ __ __ _ _ __ ___   _____      _____  _ __| | __
1879  * | '_ ` _ \ / _` | | '_ \  |  _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
1880  * | | | | | | (_| | | | | | | | | | | (_| | | | | | |  __/\ V  V / (_) | |  |   <
1881  * |_| |_| |_|\__,_|_|_| |_| |_| |_|  \__,_|_| |_| |_|\___| \_/\_/ \___/|_|  |_|\_\
1882  *
1883  ***********************************************************************************/
1884
1885 /**
1886  * Enters the emitter functions for handled nodes into the generic
1887  * pointer of an opcode.
1888  */
1889 static void ia32_register_emitters(void) {
1890
1891 #define IA32_EMIT2(a,b) op_ia32_##a->ops.generic = (op_func)emit_ia32_##b
1892 #define IA32_EMIT(a)    IA32_EMIT2(a,a)
1893 #define EMIT(a)         op_##a->ops.generic = (op_func)emit_##a
1894 #define IGN(a)                  op_##a->ops.generic = (op_func)emit_Nothing
1895 #define BE_EMIT(a)      op_be_##a->ops.generic = (op_func)emit_be_##a
1896 #define BE_IGN(a)               op_be_##a->ops.generic = (op_func)emit_Nothing
1897
1898         /* first clear the generic function pointer for all ops */
1899         clear_irp_opcodes_generic_func();
1900
1901         /* register all emitter functions defined in spec */
1902         ia32_register_spec_emitters();
1903
1904         /* other ia32 emitter functions */
1905         IA32_EMIT(CondJmp);
1906         IA32_EMIT(TestJmp);
1907         IA32_EMIT(CJmp);
1908         IA32_EMIT(CJmpAM);
1909         IA32_EMIT(CmpCMov);
1910         IA32_EMIT(PsiCondCMov);
1911         IA32_EMIT(CmpSet);
1912         IA32_EMIT(PsiCondSet);
1913         IA32_EMIT(SwitchJmp);
1914         IA32_EMIT(CopyB);
1915         IA32_EMIT(CopyB_i);
1916         IA32_EMIT(Conv_I2FP);
1917         IA32_EMIT(Conv_FP2I);
1918         IA32_EMIT(Conv_FP2FP);
1919         IA32_EMIT(Conv_I2I);
1920         IA32_EMIT(Conv_I2I8Bit);
1921         IA32_EMIT(Const);
1922         IA32_EMIT(AddSP);
1923         IA32_EMIT(LdTls);
1924         IA32_EMIT(xCmp);
1925         IA32_EMIT(xCmpSet);
1926         IA32_EMIT(xCmpCMov);
1927         IA32_EMIT(xCondJmp);
1928         IA32_EMIT2(fcomJmp, x87CondJmp);
1929         IA32_EMIT2(fcompJmp, x87CondJmp);
1930         IA32_EMIT2(fcomppJmp, x87CondJmp);
1931         IA32_EMIT2(fcomrJmp, x87CondJmp);
1932         IA32_EMIT2(fcomrpJmp, x87CondJmp);
1933         IA32_EMIT2(fcomrppJmp, x87CondJmp);
1934
1935         /* benode emitter */
1936         BE_EMIT(Call);
1937         BE_EMIT(IncSP);
1938         BE_EMIT(SetSP);
1939         BE_EMIT(Copy);
1940         BE_EMIT(CopyKeep);
1941         BE_EMIT(Perm);
1942         BE_EMIT(Return);
1943
1944         BE_IGN(RegParams);
1945         BE_IGN(Barrier);
1946         BE_IGN(Keep);
1947
1948         /* firm emitter */
1949         EMIT(Jmp);
1950         EMIT(Proj);
1951         IGN(Phi);
1952         IGN(Start);
1953
1954 #undef BE_EMIT
1955 #undef EMIT
1956 #undef IGN
1957 #undef IA32_EMIT2
1958 #undef IA32_EMIT
1959 }
1960
1961 /**
1962  * Emits code for a node.
1963  */
1964 static void ia32_emit_node(const ir_node *irn, void *env) {
1965         ia32_emit_env_t   *emit_env = env;
1966         ir_op             *op       = get_irn_op(irn);
1967         DEBUG_ONLY(firm_dbg_module_t *mod = emit_env->mod;)
1968
1969         DBG((mod, LEVEL_1, "emitting code for %+F\n", irn));
1970
1971         if (op->ops.generic) {
1972                 void (*emit)(const ir_node *, void *) = (void (*)(const ir_node *, void *))op->ops.generic;
1973                 (*emit)(irn, env);
1974         }
1975         else {
1976                 emit_Nothing(irn, env);
1977                 ir_fprintf(stderr, "Warning: No emit handler for node %+F (%+G)\n", irn, irn);
1978         }
1979 }
1980
1981 /**
1982  * Emits gas alignment directives
1983  */
1984 static void ia32_emit_alignment(FILE *F, unsigned align, unsigned skip) {
1985         fprintf(F, "\t.p2align %u,,%u\n", align, skip);
1986 }
1987
1988 /**
1989  * Emits gas alignment directives for Functions depended on cpu architecture.
1990  */
1991 static void ia32_emit_align_func(FILE *F, cpu_support cpu) {
1992         unsigned align; unsigned maximum_skip;
1993
1994         /* gcc doesn't emit alignment for p4 ?*/
1995     if (cpu == arch_pentium_4)
1996                 return;
1997
1998         switch (cpu) {
1999                 case arch_i386:
2000                         align = 2; maximum_skip = 3;
2001                         break;
2002                 case arch_i486:
2003                         align = 4; maximum_skip = 15;
2004                         break;
2005                 case arch_k6:
2006                         align = 5; maximum_skip = 31;
2007                         break;
2008                 default:
2009                         align = 4; maximum_skip = 15;
2010         }
2011         ia32_emit_alignment(F, align, maximum_skip);
2012 }
2013
2014 /**
2015  * Emits gas alignment directives for Labels depended on cpu architecture.
2016  */
2017 static void ia32_emit_align_label(FILE *F, cpu_support cpu) {
2018         unsigned align; unsigned maximum_skip;
2019
2020         /* gcc doesn't emit alignment for p4 ?*/
2021         if (cpu == arch_pentium_4)
2022                 return;
2023
2024         switch (cpu) {
2025                 case arch_i386:
2026                         align = 2; maximum_skip = 3;
2027                         break;
2028                 case arch_i486:
2029                         align = 4; maximum_skip = 15;
2030                         break;
2031                 case arch_k6:
2032                         align = 5; maximum_skip = 7;
2033                         break;
2034                 default:
2035                         align = 4; maximum_skip = 7;
2036         }
2037         ia32_emit_alignment(F, align, maximum_skip);
2038 }
2039
2040 /**
2041  * Walks over the nodes in a block connected by scheduling edges
2042  * and emits code for each node.
2043  */
2044 static void ia32_gen_block(ir_node *block, void *env) {
2045         ia32_emit_env_t *emit_env = env;
2046         const ir_node *irn;
2047         int need_label = block != get_irg_start_block(get_irn_irg(block));
2048         FILE *F = emit_env->out;
2049
2050         if (! is_Block(block))
2051                 return;
2052
2053         if (need_label && (emit_env->cg->opt & IA32_OPT_EXTBB)) {
2054                 /* if the extended block scheduler is used, only leader blocks need
2055                    labels. */
2056                 need_label = (block == get_extbb_leader(get_nodes_extbb(block)));
2057         }
2058
2059         if (need_label) {
2060                 char cmd_buf[SNPRINTF_BUF_LEN];
2061                 int i, arity;
2062
2063                 ia32_emit_align_label(emit_env->out, emit_env->isa->opt_arch);
2064
2065                 ir_snprintf(cmd_buf, sizeof(cmd_buf), BLOCK_PREFIX("%d:"),
2066                             get_irn_node_nr(block));
2067                 fprintf(F, "%-43s ", cmd_buf);
2068
2069                 /* emit list of pred blocks in comment */
2070                 fprintf(F, "/* preds:");
2071
2072                 arity = get_irn_arity(block);
2073                 for(i = 0; i < arity; ++i) {
2074                         ir_node *predblock = get_Block_cfgpred_block(block, i);
2075                         fprintf(F, " %ld", get_irn_node_nr(predblock));
2076                 }
2077                 fprintf(F, " */\n");
2078         }
2079
2080         /* emit the contents of the block */
2081         sched_foreach(block, irn) {
2082                 ia32_emit_node(irn, env);
2083         }
2084 }
2085
2086 /**
2087  * Emits code for function start.
2088  */
2089 static void ia32_emit_func_prolog(FILE *F, ir_graph *irg, cpu_support cpu) {
2090         entity     *irg_ent  = get_irg_entity(irg);
2091         const char *irg_name = get_entity_ld_name(irg_ent);
2092
2093         fprintf(F, "\n");
2094         ia32_switch_section(F, SECTION_TEXT);
2095         ia32_emit_align_func(F, cpu);
2096         if (get_entity_visibility(irg_ent) == visibility_external_visible) {
2097                 fprintf(F, ".globl %s\n", irg_name);
2098         }
2099         ia32_dump_function_object(F, irg_name);
2100         fprintf(F, "%s:\n", irg_name);
2101 }
2102
2103 /**
2104  * Emits code for function end
2105  */
2106 static void ia32_emit_func_epilog(FILE *F, ir_graph *irg) {
2107         const char *irg_name = get_entity_ld_name(get_irg_entity(irg));
2108
2109         ia32_dump_function_size(F, irg_name);
2110         fprintf(F, "\n");
2111 }
2112
2113 /**
2114  * Block-walker:
2115  * Sets labels for control flow nodes (jump target)
2116  * TODO: Jump optimization
2117  */
2118 static void ia32_gen_labels(ir_node *block, void *env) {
2119         ir_node *pred;
2120         int n = get_Block_n_cfgpreds(block);
2121
2122         for (n--; n >= 0; n--) {
2123                 pred = get_Block_cfgpred(block, n);
2124                 set_irn_link(pred, block);
2125         }
2126 }
2127
2128 /**
2129  * Main driver. Emits the code for one routine.
2130  */
2131 void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) {
2132         ia32_emit_env_t emit_env;
2133         ir_node *block;
2134
2135         emit_env.out      = F;
2136         emit_env.arch_env = cg->arch_env;
2137         emit_env.cg       = cg;
2138         emit_env.isa      = (ia32_isa_t *)cg->arch_env->isa;
2139         FIRM_DBG_REGISTER(emit_env.mod, "firm.be.ia32.emitter");
2140
2141         /* set the global arch_env (needed by print hooks) */
2142         arch_env = cg->arch_env;
2143
2144         ia32_register_emitters();
2145
2146         ia32_emit_func_prolog(F, irg, emit_env.isa->opt_arch);
2147         irg_block_walk_graph(irg, ia32_gen_labels, NULL, &emit_env);
2148
2149         if ((cg->opt & IA32_OPT_EXTBB) && cg->blk_sched) {
2150                 int i, n = ARR_LEN(cg->blk_sched);
2151
2152                 for (i = 0; i < n;) {
2153                         ir_node *next_bl;
2154
2155                         block   = cg->blk_sched[i];
2156                         ++i;
2157                         next_bl = i < n ? cg->blk_sched[i] : NULL;
2158
2159                         /* set here the link. the emitter expects to find the next block here */
2160                         set_irn_link(block, next_bl);
2161                         ia32_gen_block(block, &emit_env);
2162                 }
2163         }
2164         else {
2165                 /* "normal" block schedule: Note the get_next_block() returns the NUMBER of the block
2166                    in the block schedule. As this number should NEVER be equal the next block,
2167                    we does not need a clear block link here. */
2168                 irg_walk_blkwise_graph(irg, NULL, ia32_gen_block, &emit_env);
2169         }
2170
2171         ia32_emit_func_epilog(F, irg);
2172 }