1 /*
2 * Copyright (C) 1995-2011 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 *
25 * Summary table for x86 floatingpoint compares:
26 * (remember effect of unordered on x86: ZF=1, PF=1, CF=1)
27 *
28 * pnc_Eq => !P && E
29 * pnc_Lt => !P && B
30 * pnc_Le => !P && BE
31 * pnc_Gt => A
32 * pnc_Ge => AE
33 * pnc_Lg => NE
34 * pnc_Leg => NP (ordered)
35 * pnc_Uo => P
36 * pnc_Ue => E
37 * pnc_Ul => B
38 * pnc_Ule => BE
39 * pnc_Ug => P || A
40 * pnc_Uge => P || AE
41 * pnc_Ne => P || NE
42 */
43 #include "config.h"
44
45 #include <limits.h>
46
47 #include "xmalloc.h"
48 #include "tv.h"
49 #include "iredges.h"
50 #include "debug.h"
51 #include "irgwalk.h"
52 #include "irprintf.h"
53 #include "irop_t.h"
54 #include "irargs_t.h"
55 #include "irprog_t.h"
56 #include "iredges_t.h"
57 #include "irtools.h"
58 #include "execfreq.h"
59 #include "error.h"
60 #include "raw_bitset.h"
61 #include "dbginfo.h"
62 #include "lc_opts.h"
63 #include "ircons.h"
64
65 #include "besched.h"
66 #include "benode.h"
67 #include "beabi.h"
68 #include "bedwarf.h"
69 #include "beemitter.h"
70 #include "begnuas.h"
71 #include "beirg.h"
72
73 #include "ia32_emitter.h"
74 #include "ia32_common_transform.h"
75 #include "gen_ia32_emitter.h"
76 #include "gen_ia32_regalloc_if.h"
77 #include "ia32_nodes_attr.h"
78 #include "ia32_new_nodes.h"
79 #include "ia32_architecture.h"
80 #include "bearch_ia32_t.h"
81
82 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
83
84 static const ia32_isa_t *isa;
85 static char pic_base_label[128];
86 static ir_label_t exc_label_id;
87 static int mark_spill_reload = 0;
88 static int do_pic;
89
90 static bool sp_relative;
91 static int frame_type_size;
92 static int callframe_offset;
93
94 /** Return the next block in Block schedule */
get_prev_block_sched(const ir_node * block)95 static ir_node *get_prev_block_sched(const ir_node *block)
96 {
97 return (ir_node*)get_irn_link(block);
98 }
99
100 /** Checks if the current block is a fall-through target. */
is_fallthrough(const ir_node * cfgpred)101 static int is_fallthrough(const ir_node *cfgpred)
102 {
103 ir_node *pred;
104
105 if (!is_Proj(cfgpred))
106 return 1;
107 pred = get_Proj_pred(cfgpred);
108 if (is_ia32_SwitchJmp(pred))
109 return 0;
110
111 return 1;
112 }
113
114 /**
115 * returns non-zero if the given block needs a label
116 * because of being a jump-target (and not a fall-through)
117 */
block_needs_label(const ir_node * block)118 static int block_needs_label(const ir_node *block)
119 {
120 int need_label = 1;
121 int n_cfgpreds = get_Block_n_cfgpreds(block);
122
123 if (get_Block_entity(block) != NULL)
124 return 1;
125
126 if (n_cfgpreds == 0) {
127 need_label = 0;
128 } else if (n_cfgpreds == 1) {
129 ir_node *cfgpred = get_Block_cfgpred(block, 0);
130 ir_node *cfgpred_block = get_nodes_block(cfgpred);
131
132 if (get_prev_block_sched(block) == cfgpred_block
133 && is_fallthrough(cfgpred)) {
134 need_label = 0;
135 }
136 }
137
138 return need_label;
139 }
140
141 /**
142 * Add a number to a prefix. This number will not be used a second time.
143 */
get_unique_label(char * buf,size_t buflen,const char * prefix)144 static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
145 {
146 static unsigned long id = 0;
147 snprintf(buf, buflen, "%s%s%lu", be_gas_get_private_prefix(), prefix, ++id);
148 return buf;
149 }
150
151 /**
152 * Emit the name of the 8bit low register
153 */
emit_8bit_register(const arch_register_t * reg)154 static void emit_8bit_register(const arch_register_t *reg)
155 {
156 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
157 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
158
159 be_emit_char('%');
160 be_emit_char(reg->name[1]); /* get the basic name of the register */
161 be_emit_char('l');
162 }
163
164 /**
165 * Emit the name of the 8bit high register
166 */
emit_8bit_register_high(const arch_register_t * reg)167 static void emit_8bit_register_high(const arch_register_t *reg)
168 {
169 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
170 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
171
172 be_emit_char('%');
173 be_emit_char(reg->name[1]); /* get the basic name of the register */
174 be_emit_char('h');
175 }
176
emit_16bit_register(const arch_register_t * reg)177 static void emit_16bit_register(const arch_register_t *reg)
178 {
179 be_emit_char('%');
180 be_emit_string(reg->name + 1); /* skip the 'e' prefix of the 32bit names */
181 }
182
183 /**
184 * emit a register, possible shortened by a mode
185 *
186 * @param reg the register
187 * @param mode the mode of the register or NULL for full register
188 */
emit_register(const arch_register_t * reg,const ir_mode * mode)189 static void emit_register(const arch_register_t *reg, const ir_mode *mode)
190 {
191 if (mode != NULL) {
192 int size = get_mode_size_bits(mode);
193 switch (size) {
194 case 8: emit_8bit_register(reg); return;
195 case 16: emit_16bit_register(reg); return;
196 }
197 assert(mode_is_float(mode) || size == 32);
198 }
199
200 be_emit_char('%');
201 be_emit_string(reg->name);
202 }
203
ia32_emit_entity(ir_entity * entity,int no_pic_adjust)204 static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
205 {
206 be_gas_emit_entity(entity);
207
208 if (get_entity_owner(entity) == get_tls_type()) {
209 if (!entity_has_definition(entity)) {
210 be_emit_cstring("@INDNTPOFF");
211 } else {
212 be_emit_cstring("@NTPOFF");
213 }
214 }
215
216 if (do_pic && !no_pic_adjust) {
217 be_emit_char('-');
218 be_emit_string(pic_base_label);
219 }
220 }
221
emit_ia32_Immediate_no_prefix(const ir_node * node)222 static void emit_ia32_Immediate_no_prefix(const ir_node *node)
223 {
224 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
225
226 if (attr->symconst != NULL) {
227 if (attr->sc_sign)
228 be_emit_char('-');
229 ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
230 }
231 if (attr->symconst == NULL || attr->offset != 0) {
232 if (attr->symconst != NULL) {
233 be_emit_irprintf("%+d", attr->offset);
234 } else {
235 be_emit_irprintf("0x%X", attr->offset);
236 }
237 }
238 }
239
emit_ia32_Immediate(const ir_node * node)240 static void emit_ia32_Immediate(const ir_node *node)
241 {
242 be_emit_char('$');
243 emit_ia32_Immediate_no_prefix(node);
244 }
245
ia32_emit_mode_suffix_mode(const ir_mode * mode)246 static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
247 {
248 assert(mode_is_int(mode) || mode_is_reference(mode));
249 switch (get_mode_size_bits(mode)) {
250 case 8: be_emit_char('b'); return;
251 case 16: be_emit_char('w'); return;
252 case 32: be_emit_char('l'); return;
253 /* gas docu says q is the suffix but gcc, objdump and icc use ll
254 * apparently */
255 case 64: be_emit_cstring("ll"); return;
256 }
257 panic("Can't output mode_suffix for %+F", mode);
258 }
259
ia32_emit_x87_mode_suffix(ir_node const * const node)260 static void ia32_emit_x87_mode_suffix(ir_node const *const node)
261 {
262 ir_mode *mode;
263
264 /* we only need to emit the mode on address mode */
265 if (get_ia32_op_type(node) == ia32_Normal)
266 return;
267
268 mode = get_ia32_ls_mode(node);
269 assert(mode != NULL);
270
271 if (mode_is_float(mode)) {
272 switch (get_mode_size_bits(mode)) {
273 case 32: be_emit_char('s'); return;
274 case 64: be_emit_char('l'); return;
275 /* long doubles have different sizes due to alignment on different
276 * platforms. */
277 case 80:
278 case 96:
279 case 128: be_emit_char('t'); return;
280 }
281 } else {
282 assert(mode_is_int(mode) || mode_is_reference(mode));
283 switch (get_mode_size_bits(mode)) {
284 case 16: be_emit_char('s'); return;
285 case 32: be_emit_char('l'); return;
286 /* gas docu says q is the suffix but gcc, objdump and icc use ll
287 * apparently */
288 case 64: be_emit_cstring("ll"); return;
289 }
290 }
291 panic("Can't output mode_suffix for %+F", mode);
292 }
293
get_xmm_mode_suffix(ir_mode * mode)294 static char get_xmm_mode_suffix(ir_mode *mode)
295 {
296 assert(mode_is_float(mode));
297 switch (get_mode_size_bits(mode)) {
298 case 32: return 's';
299 case 64: return 'd';
300 default: panic("Invalid XMM mode");
301 }
302 }
303
ia32_emit_xmm_mode_suffix(ir_node const * const node)304 static void ia32_emit_xmm_mode_suffix(ir_node const *const node)
305 {
306 ir_mode *mode = get_ia32_ls_mode(node);
307 assert(mode != NULL);
308 be_emit_char(get_xmm_mode_suffix(mode));
309 }
310
311 /**
312 * Returns the target block for a control flow node.
313 */
get_cfop_target_block(const ir_node * irn)314 static ir_node *get_cfop_target_block(const ir_node *irn)
315 {
316 assert(get_irn_mode(irn) == mode_X);
317 return (ir_node*)get_irn_link(irn);
318 }
319
320 /**
321 * Emits the target label for a control flow node.
322 */
ia32_emit_cfop_target(const ir_node * node)323 static void ia32_emit_cfop_target(const ir_node *node)
324 {
325 ir_node *block = get_cfop_target_block(node);
326 be_gas_emit_block_name(block);
327 }
328
329 /**
330 * Emit the suffix for a compare instruction.
331 */
ia32_emit_condition_code(ia32_condition_code_t cc)332 static void ia32_emit_condition_code(ia32_condition_code_t cc)
333 {
334 switch (cc) {
335 case ia32_cc_overflow: be_emit_cstring("o"); return;
336 case ia32_cc_not_overflow: be_emit_cstring("no"); return;
337 case ia32_cc_float_below:
338 case ia32_cc_float_unordered_below:
339 case ia32_cc_below: be_emit_cstring("b"); return;
340 case ia32_cc_float_above_equal:
341 case ia32_cc_float_unordered_above_equal:
342 case ia32_cc_above_equal: be_emit_cstring("ae"); return;
343 case ia32_cc_float_equal:
344 case ia32_cc_equal: be_emit_cstring("e"); return;
345 case ia32_cc_float_not_equal:
346 case ia32_cc_not_equal: be_emit_cstring("ne"); return;
347 case ia32_cc_float_below_equal:
348 case ia32_cc_float_unordered_below_equal:
349 case ia32_cc_below_equal: be_emit_cstring("be"); return;
350 case ia32_cc_float_above:
351 case ia32_cc_float_unordered_above:
352 case ia32_cc_above: be_emit_cstring("a"); return;
353 case ia32_cc_sign: be_emit_cstring("s"); return;
354 case ia32_cc_not_sign: be_emit_cstring("ns"); return;
355 case ia32_cc_parity: be_emit_cstring("p"); return;
356 case ia32_cc_not_parity: be_emit_cstring("np"); return;
357 case ia32_cc_less: be_emit_cstring("l"); return;
358 case ia32_cc_greater_equal: be_emit_cstring("ge"); return;
359 case ia32_cc_less_equal: be_emit_cstring("le"); return;
360 case ia32_cc_greater: be_emit_cstring("g"); return;
361 case ia32_cc_float_parity_cases:
362 case ia32_cc_additional_float_cases:
363 break;
364 }
365 panic("Invalid ia32 condition code");
366 }
367
368 typedef enum ia32_emit_mod_t {
369 EMIT_NONE = 0,
370 EMIT_RESPECT_LS = 1U << 0,
371 EMIT_ALTERNATE_AM = 1U << 1,
372 EMIT_LONG = 1U << 2,
373 EMIT_HIGH_REG = 1U << 3,
374 EMIT_LOW_REG = 1U << 4,
375 EMIT_16BIT_REG = 1U << 5
376 } ia32_emit_mod_t;
ENUM_BITSET(ia32_emit_mod_t)377 ENUM_BITSET(ia32_emit_mod_t)
378
379 /**
380 * Emits address mode.
381 */
382 static void ia32_emit_am(ir_node const *const node)
383 {
384 ir_entity *ent = get_ia32_am_sc(node);
385 int offs = get_ia32_am_offs_int(node);
386 ir_node *base = get_irn_n(node, n_ia32_base);
387 int has_base = !is_ia32_NoReg_GP(base);
388 ir_node *idx = get_irn_n(node, n_ia32_index);
389 int has_index = !is_ia32_NoReg_GP(idx);
390
391 /* just to be sure... */
392 assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
393
394 if (get_ia32_am_tls_segment(node))
395 be_emit_cstring("%gs:");
396
397 /* emit offset */
398 if (ent != NULL) {
399 const ia32_attr_t *attr = get_ia32_attr_const(node);
400 if (is_ia32_am_sc_sign(node))
401 be_emit_char('-');
402 ia32_emit_entity(ent, attr->data.am_sc_no_pic_adjust);
403 }
404
405 /* also handle special case if nothing is set */
406 if (offs != 0 || (ent == NULL && !has_base && !has_index)) {
407 if (ent != NULL) {
408 be_emit_irprintf("%+d", offs);
409 } else {
410 be_emit_irprintf("%d", offs);
411 }
412 }
413
414 if (has_base || has_index) {
415 be_emit_char('(');
416
417 /* emit base */
418 if (has_base) {
419 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
420 emit_register(reg, NULL);
421 }
422
423 /* emit index + scale */
424 if (has_index) {
425 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
426 int scale;
427 be_emit_char(',');
428 emit_register(reg, NULL);
429
430 scale = get_ia32_am_scale(node);
431 if (scale > 0) {
432 be_emit_irprintf(",%d", 1 << scale);
433 }
434 }
435 be_emit_char(')');
436 }
437 }
438
439 static ia32_condition_code_t determine_final_cc(ir_node const *node, int flags_pos, ia32_condition_code_t cc);
440
ia32_emitf(ir_node const * const node,char const * fmt,...)441 void ia32_emitf(ir_node const *const node, char const *fmt, ...)
442 {
443 va_list ap;
444 va_start(ap, fmt);
445
446 be_emit_char('\t');
447 for (;;) {
448 const char *start = fmt;
449 ia32_emit_mod_t mod = EMIT_NONE;
450
451 while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
452 ++fmt;
453 if (fmt != start) {
454 be_emit_string_len(start, fmt - start);
455 }
456
457 if (*fmt == '\n') {
458 be_emit_char('\n');
459 be_emit_write_line();
460 be_emit_char('\t');
461 ++fmt;
462 if (*fmt == '\0')
463 break;
464 continue;
465 }
466
467 if (*fmt == '\0')
468 break;
469
470 ++fmt;
471 for (;;) {
472 switch (*fmt) {
473 case '*': mod |= EMIT_ALTERNATE_AM; break;
474 case '#': mod |= EMIT_RESPECT_LS; break;
475 case 'l': mod |= EMIT_LONG; break;
476 case '>': mod |= EMIT_HIGH_REG; break;
477 case '<': mod |= EMIT_LOW_REG; break;
478 case '^': mod |= EMIT_16BIT_REG; break;
479 default:
480 goto end_of_mods;
481 }
482 ++fmt;
483 }
484 end_of_mods:
485
486 switch (*fmt++) {
487 arch_register_t const *reg;
488 ir_node const *imm;
489
490 case '%':
491 be_emit_char('%');
492 break;
493
494 case 'A': {
495 switch (*fmt++) {
496 case 'F':
497 if (get_ia32_op_type(node) == ia32_AddrModeS) {
498 goto emit_AM;
499 } else {
500 assert(get_ia32_op_type(node) == ia32_Normal);
501 ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
502 char const *const fmt = attr->res_in_reg ? "%%st, %%%s" : "%%%s, %%st";
503 be_emit_irprintf(fmt, attr->reg->name);
504 break;
505 }
506
507 emit_AM:
508 case 'M':
509 if (mod & EMIT_ALTERNATE_AM)
510 be_emit_char('*');
511 ia32_emit_am(node);
512 break;
513
514 case 'R':
515 reg = va_arg(ap, const arch_register_t*);
516 if (get_ia32_op_type(node) == ia32_AddrModeS) {
517 goto emit_AM;
518 } else {
519 goto emit_R;
520 }
521
522 case 'S':
523 if (get_ia32_op_type(node) == ia32_AddrModeS) {
524 ++fmt;
525 goto emit_AM;
526 } else {
527 assert(get_ia32_op_type(node) == ia32_Normal);
528 goto emit_S;
529 }
530
531 default: goto unknown;
532 }
533 break;
534 }
535
536 case 'B':
537 imm = get_irn_n(node, n_ia32_binary_right);
538 if (is_ia32_Immediate(imm)) {
539 emit_ia32_Immediate(imm);
540 be_emit_cstring(", ");
541 if (get_ia32_op_type(node) == ia32_AddrModeS) {
542 ia32_emit_am(node);
543 } else {
544 assert(get_ia32_op_type(node) == ia32_Normal);
545 reg = arch_get_irn_register_in(node, n_ia32_binary_left);
546 emit_register(reg, get_ia32_ls_mode(node));
547 }
548 } else {
549 if (get_ia32_op_type(node) == ia32_AddrModeS) {
550 ia32_emit_am(node);
551 } else {
552 assert(get_ia32_op_type(node) == ia32_Normal);
553 reg = arch_get_irn_register_in(node, n_ia32_binary_right);
554 emit_register(reg, get_ia32_ls_mode(node));
555 }
556 be_emit_cstring(", ");
557 reg = arch_get_irn_register_in(node, n_ia32_binary_left);
558 emit_register(reg, get_ia32_ls_mode(node));
559 }
560 break;
561
562 case 'D':
563 if (*fmt < '0' || '9' < *fmt)
564 goto unknown;
565 reg = arch_get_irn_register_out(node, *fmt++ - '0');
566 goto emit_R;
567
568 case 'F':
569 if (*fmt == 'M') {
570 ia32_emit_x87_mode_suffix(node);
571 } else if (*fmt == 'P') {
572 ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
573 if (attr->pop)
574 be_emit_char('p');
575 } else if (*fmt == 'R') {
576 /* NOTE: Work around a gas quirk for non-commutative operations if the
577 * destination register is not %st0. In this case r/non-r is swapped.
578 * %st0 = %st0 - %st1 -> fsub %st1, %st0 (as expected)
579 * %st0 = %st1 - %st0 -> fsubr %st1, %st0 (as expected)
580 * %st1 = %st0 - %st1 -> fsub %st0, %st1 (expected: fsubr)
581 * %st1 = %st1 - %st0 -> fsubr %st0, %st1 (expected: fsub)
582 * In fact this corresponds to the encoding of the instruction:
583 * - The r suffix selects whether %st0 is on the left (no r) or on the
584 * right (r) side of the executed operation.
585 * - The placement of %st0 selects whether the result is written to
586 * %st0 (right) or the other register (left).
587 * This means that it is sufficient to test whether the operands are
588 * permuted. In particular it is not necessary to consider wether the
589 * result is to be placed into the explicit register operand. */
590 if (get_ia32_x87_attr_const(node)->attr.data.ins_permuted)
591 be_emit_char('r');
592 } else if (*fmt == 'X') {
593 ia32_emit_xmm_mode_suffix(node);
594 } else if (*fmt == '0') {
595 be_emit_char('%');
596 be_emit_string(get_ia32_x87_attr_const(node)->reg->name);
597 } else {
598 goto unknown;
599 }
600 ++fmt;
601 break;
602
603 case 'I':
604 imm = node;
605 emit_I:
606 if (!(mod & EMIT_ALTERNATE_AM))
607 be_emit_char('$');
608 emit_ia32_Immediate_no_prefix(imm);
609 break;
610
611 case 'L':
612 ia32_emit_cfop_target(node);
613 break;
614
615 case 'M': {
616 ir_mode *mode = get_ia32_ls_mode(node);
617 if (!mode)
618 mode = mode_Iu;
619 if (mod & EMIT_RESPECT_LS) {
620 if (get_mode_size_bits(mode) == 32)
621 break;
622 be_emit_char(mode_is_signed(mode) ? 's' : 'z');
623 }
624 ia32_emit_mode_suffix_mode(mode);
625 break;
626 }
627
628 case 'P': {
629 ia32_condition_code_t cc;
630 if (*fmt == 'X') {
631 ++fmt;
632 cc = (ia32_condition_code_t)va_arg(ap, int);
633 } else if ('0' <= *fmt && *fmt <= '9') {
634 cc = get_ia32_condcode(node);
635 cc = determine_final_cc(node, *fmt - '0', cc);
636 ++fmt;
637 } else {
638 goto unknown;
639 }
640 ia32_emit_condition_code(cc);
641 break;
642 }
643
644 case 'R':
645 reg = va_arg(ap, const arch_register_t*);
646 emit_R:
647 if (mod & EMIT_ALTERNATE_AM)
648 be_emit_char('*');
649 if (mod & EMIT_HIGH_REG) {
650 emit_8bit_register_high(reg);
651 } else if (mod & EMIT_LOW_REG) {
652 emit_8bit_register(reg);
653 } else if (mod & EMIT_16BIT_REG) {
654 emit_16bit_register(reg);
655 } else {
656 emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
657 }
658 break;
659
660 emit_S:
661 case 'S': {
662 unsigned pos;
663
664 if (*fmt < '0' || '9' < *fmt)
665 goto unknown;
666
667 pos = *fmt++ - '0';
668 imm = get_irn_n(node, pos);
669 if (is_ia32_Immediate(imm)) {
670 goto emit_I;
671 } else {
672 reg = arch_get_irn_register_in(node, pos);
673 goto emit_R;
674 }
675 }
676
677 case 's': {
678 const char *str = va_arg(ap, const char*);
679 be_emit_string(str);
680 break;
681 }
682
683 case 'u':
684 if (mod & EMIT_LONG) {
685 unsigned long num = va_arg(ap, unsigned long);
686 be_emit_irprintf("%lu", num);
687 } else {
688 unsigned num = va_arg(ap, unsigned);
689 be_emit_irprintf("%u", num);
690 }
691 break;
692
693 case 'd':
694 if (mod & EMIT_LONG) {
695 long num = va_arg(ap, long);
696 be_emit_irprintf("%ld", num);
697 } else {
698 int num = va_arg(ap, int);
699 be_emit_irprintf("%d", num);
700 }
701 break;
702
703 default:
704 unknown:
705 panic("unknown format conversion");
706 }
707 }
708
709 be_emit_finish_line_gas(node);
710 va_end(ap);
711 }
712
emit_ia32_IMul(const ir_node * node)713 static void emit_ia32_IMul(const ir_node *node)
714 {
715 ir_node *left = get_irn_n(node, n_ia32_IMul_left);
716 const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
717
718 /* do we need the 3-address form? */
719 if (is_ia32_NoReg_GP(left) ||
720 arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
721 ia32_emitf(node, "imul%M %#S4, %#AS3, %#D0");
722 } else {
723 ia32_emitf(node, "imul%M %#AS4, %#S3");
724 }
725 }
726
727 /**
728 * walks up a tree of copies/perms/spills/reloads to find the original value
729 * that is moved around
730 */
find_original_value(ir_node * node)731 static ir_node *find_original_value(ir_node *node)
732 {
733 if (irn_visited(node))
734 return NULL;
735
736 mark_irn_visited(node);
737 if (be_is_Copy(node)) {
738 return find_original_value(be_get_Copy_op(node));
739 } else if (be_is_CopyKeep(node)) {
740 return find_original_value(be_get_CopyKeep_op(node));
741 } else if (is_Proj(node)) {
742 ir_node *pred = get_Proj_pred(node);
743 if (be_is_Perm(pred)) {
744 return find_original_value(get_irn_n(pred, get_Proj_proj(node)));
745 } else if (be_is_MemPerm(pred)) {
746 return find_original_value(get_irn_n(pred, get_Proj_proj(node) + 1));
747 } else if (is_ia32_Load(pred)) {
748 return find_original_value(get_irn_n(pred, n_ia32_Load_mem));
749 } else if (is_ia32_Store(pred)) {
750 return find_original_value(get_irn_n(pred, n_ia32_Store_val));
751 } else {
752 return node;
753 }
754 } else if (is_Phi(node)) {
755 int i, arity;
756 arity = get_irn_arity(node);
757 for (i = 0; i < arity; ++i) {
758 ir_node *in = get_irn_n(node, i);
759 ir_node *res = find_original_value(in);
760
761 if (res != NULL)
762 return res;
763 }
764 return NULL;
765 } else {
766 return node;
767 }
768 }
769
determine_final_cc(const ir_node * node,int flags_pos,ia32_condition_code_t cc)770 static ia32_condition_code_t determine_final_cc(const ir_node *node,
771 int flags_pos, ia32_condition_code_t cc)
772 {
773 ir_node *flags = get_irn_n(node, flags_pos);
774 const ia32_attr_t *flags_attr;
775 flags = skip_Proj(flags);
776
777 if (is_ia32_Sahf(flags)) {
778 ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
779 if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
780 inc_irg_visited(current_ir_graph);
781 cmp = find_original_value(cmp);
782 assert(cmp != NULL);
783 assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
784 }
785
786 flags_attr = get_ia32_attr_const(cmp);
787 } else {
788 flags_attr = get_ia32_attr_const(flags);
789 }
790
791 if (flags_attr->data.ins_permuted)
792 cc = ia32_invert_condition_code(cc);
793 return cc;
794 }
795
796 /**
797 * Emits an exception label for a given node.
798 */
ia32_emit_exc_label(const ir_node * node)799 static void ia32_emit_exc_label(const ir_node *node)
800 {
801 be_emit_string(be_gas_insn_label_prefix());
802 be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
803 }
804
805 /**
806 * Returns the Proj with projection number proj and NOT mode_M
807 */
get_proj(const ir_node * node,long proj)808 static ir_node *get_proj(const ir_node *node, long proj)
809 {
810 ir_node *src;
811
812 assert(get_irn_mode(node) == mode_T && "expected mode_T node");
813
814 foreach_out_edge(node, edge) {
815 src = get_edge_src_irn(edge);
816
817 assert(is_Proj(src) && "Proj expected");
818 if (get_irn_mode(src) == mode_M)
819 continue;
820
821 if (get_Proj_proj(src) == proj)
822 return src;
823 }
824 return NULL;
825 }
826
can_be_fallthrough(const ir_node * node)827 static int can_be_fallthrough(const ir_node *node)
828 {
829 ir_node *target_block = get_cfop_target_block(node);
830 ir_node *block = get_nodes_block(node);
831 return get_prev_block_sched(target_block) == block;
832 }
833
834 /**
835 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
836 */
emit_ia32_Jcc(const ir_node * node)837 static void emit_ia32_Jcc(const ir_node *node)
838 {
839 int need_parity_label = 0;
840 ia32_condition_code_t cc = get_ia32_condcode(node);
841 const ir_node *proj_true;
842 const ir_node *proj_false;
843
844 cc = determine_final_cc(node, 0, cc);
845
846 /* get both Projs */
847 proj_true = get_proj(node, pn_ia32_Jcc_true);
848 assert(proj_true && "Jcc without true Proj");
849
850 proj_false = get_proj(node, pn_ia32_Jcc_false);
851 assert(proj_false && "Jcc without false Proj");
852
853 if (can_be_fallthrough(proj_true)) {
854 /* exchange both proj's so the second one can be omitted */
855 const ir_node *t = proj_true;
856
857 proj_true = proj_false;
858 proj_false = t;
859 cc = ia32_negate_condition_code(cc);
860 }
861
862 if (cc & ia32_cc_float_parity_cases) {
863 /* Some floating point comparisons require a test of the parity flag,
864 * which indicates that the result is unordered */
865 if (cc & ia32_cc_negated) {
866 ia32_emitf(proj_true, "jp %L");
867 } else {
868 /* we need a local label if the false proj is a fallthrough
869 * as the falseblock might have no label emitted then */
870 if (can_be_fallthrough(proj_false)) {
871 need_parity_label = 1;
872 ia32_emitf(proj_false, "jp 1f");
873 } else {
874 ia32_emitf(proj_false, "jp %L");
875 }
876 }
877 }
878 ia32_emitf(proj_true, "j%PX %L", (int)cc);
879 if (need_parity_label) {
880 be_emit_cstring("1:\n");
881 be_emit_write_line();
882 }
883
884 /* the second Proj might be a fallthrough */
885 if (can_be_fallthrough(proj_false)) {
886 if (be_options.verbose_asm)
887 ia32_emitf(proj_false, "/* fallthrough to %L */");
888 } else {
889 ia32_emitf(proj_false, "jmp %L");
890 }
891 }
892
893 /**
894 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
895 * are tricky.
896 */
emit_ia32_Setcc(const ir_node * node)897 static void emit_ia32_Setcc(const ir_node *node)
898 {
899 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
900
901 ia32_condition_code_t cc = get_ia32_condcode(node);
902 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
903 if (cc & ia32_cc_float_parity_cases) {
904 if (cc & ia32_cc_negated) {
905 ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
906 ia32_emitf(node, "setp %>R", dreg);
907 ia32_emitf(node, "orb %>R, %<R", dreg, dreg);
908 } else {
909 ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
910 ia32_emitf(node, "setnp %>R", dreg);
911 ia32_emitf(node, "andb %>R, %<R", dreg, dreg);
912 }
913 } else {
914 ia32_emitf(node, "set%PX %#R", (int)cc, dreg);
915 }
916 }
917
emit_ia32_CMovcc(const ir_node * node)918 static void emit_ia32_CMovcc(const ir_node *node)
919 {
920 const ia32_attr_t *attr = get_ia32_attr_const(node);
921 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
922 ia32_condition_code_t cc = get_ia32_condcode(node);
923 const arch_register_t *in_true;
924 const arch_register_t *in_false;
925
926 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
927 /* although you can't set ins_permuted in the constructor it might still
928 * be set by memory operand folding
929 * Permuting inputs of a cmov means the condition is negated!
930 */
931 if (attr->data.ins_permuted)
932 cc = ia32_negate_condition_code(cc);
933
934 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
935 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
936
937 /* should be same constraint fullfilled? */
938 if (out == in_false) {
939 /* yes -> nothing to do */
940 } else if (out == in_true) {
941 const arch_register_t *tmp;
942
943 assert(get_ia32_op_type(node) == ia32_Normal);
944
945 cc = ia32_negate_condition_code(cc);
946
947 tmp = in_true;
948 in_true = in_false;
949 in_false = tmp;
950 } else {
951 /* we need a mov */
952 ia32_emitf(node, "movl %R, %R", in_false, out);
953 }
954
955 if (cc & ia32_cc_float_parity_cases) {
956 panic("CMov with floatingpoint compare/parity not supported yet");
957 }
958
959 ia32_emitf(node, "cmov%PX %#AR, %#R", (int)cc, in_true, out);
960 }
961
962 /**
963 * Emits code for a SwitchJmp
964 */
emit_ia32_SwitchJmp(const ir_node * node)965 static void emit_ia32_SwitchJmp(const ir_node *node)
966 {
967 ir_entity *jump_table = get_ia32_am_sc(node);
968 const ir_switch_table *table = get_ia32_switch_table(node);
969
970 ia32_emitf(node, "jmp %*AM");
971 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
972 }
973
974 /**
975 * Emits code for a unconditional jump.
976 */
emit_ia32_Jmp(const ir_node * node)977 static void emit_ia32_Jmp(const ir_node *node)
978 {
979 /* we have a block schedule */
980 if (can_be_fallthrough(node)) {
981 if (be_options.verbose_asm)
982 ia32_emitf(node, "/* fallthrough to %L */");
983 } else {
984 ia32_emitf(node, "jmp %L");
985 }
986 }
987
988 /**
989 * Emit an inline assembler operand.
990 *
991 * @param node the ia32_ASM node
992 * @param s points to the operand (a %c)
993 *
994 * @return pointer to the first char in s NOT in the current operand
995 */
emit_asm_operand(const ir_node * node,const char * s)996 static const char* emit_asm_operand(const ir_node *node, const char *s)
997 {
998 const ia32_attr_t *ia32_attr = get_ia32_attr_const(node);
999 const ia32_asm_attr_t *attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
1000 ia32_attr);
1001 const arch_register_t *reg;
1002 const ia32_asm_reg_t *asm_regs = attr->register_map;
1003 const ia32_asm_reg_t *asm_reg;
1004 char c;
1005 char modifier = 0;
1006 int num;
1007 int p;
1008
1009 assert(*s == '%');
1010 c = *(++s);
1011
1012 /* parse modifiers */
1013 switch (c) {
1014 case 0:
1015 ir_fprintf(stderr, "Warning: asm text (%+F) ends with %%\n", node);
1016 be_emit_char('%');
1017 return s + 1;
1018 case '%':
1019 be_emit_char('%');
1020 return s + 1;
1021 case 'w':
1022 case 'b':
1023 case 'h':
1024 modifier = c;
1025 ++s;
1026 break;
1027 case '0':
1028 case '1':
1029 case '2':
1030 case '3':
1031 case '4':
1032 case '5':
1033 case '6':
1034 case '7':
1035 case '8':
1036 case '9':
1037 break;
1038 default:
1039 ir_fprintf(stderr,
1040 "Warning: asm text (%+F) contains unknown modifier '%c' for asm op\n",
1041 node, c);
1042 ++s;
1043 break;
1044 }
1045
1046 /* parse number */
1047 if (sscanf(s, "%d%n", &num, &p) != 1) {
1048 ir_fprintf(stderr, "Warning: Couldn't parse assembler operand (%+F)\n",
1049 node);
1050 return s;
1051 } else {
1052 s += p;
1053 }
1054
1055 if (num < 0 || ARR_LEN(asm_regs) <= (size_t)num) {
1056 ir_fprintf(stderr,
1057 "Error: Custom assembler references invalid input/output (%+F)\n",
1058 node);
1059 return s;
1060 }
1061 asm_reg = & asm_regs[num];
1062 assert(asm_reg->valid);
1063
1064 /* get register */
1065 if (asm_reg->use_input == 0) {
1066 reg = arch_get_irn_register_out(node, asm_reg->inout_pos);
1067 } else {
1068 ir_node *pred = get_irn_n(node, asm_reg->inout_pos);
1069
1070 /* might be an immediate value */
1071 if (is_ia32_Immediate(pred)) {
1072 emit_ia32_Immediate(pred);
1073 return s;
1074 }
1075 reg = arch_get_irn_register_in(node, asm_reg->inout_pos);
1076 }
1077 if (reg == NULL) {
1078 ir_fprintf(stderr,
1079 "Warning: no register assigned for %d asm op (%+F)\n",
1080 num, node);
1081 return s;
1082 }
1083
1084 if (asm_reg->memory) {
1085 be_emit_char('(');
1086 }
1087
1088 /* emit it */
1089 if (modifier != 0) {
1090 switch (modifier) {
1091 case 'b':
1092 emit_8bit_register(reg);
1093 break;
1094 case 'h':
1095 emit_8bit_register_high(reg);
1096 break;
1097 case 'w':
1098 emit_16bit_register(reg);
1099 break;
1100 default:
1101 panic("Invalid asm op modifier");
1102 }
1103 } else {
1104 emit_register(reg, asm_reg->memory ? mode_Iu : asm_reg->mode);
1105 }
1106
1107 if (asm_reg->memory) {
1108 be_emit_char(')');
1109 }
1110
1111 return s;
1112 }
1113
1114 /**
1115 * Emits code for an ASM pseudo op.
1116 */
emit_ia32_Asm(const ir_node * node)1117 static void emit_ia32_Asm(const ir_node *node)
1118 {
1119 const void *gen_attr = get_irn_generic_attr_const(node);
1120 const ia32_asm_attr_t *attr
1121 = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, gen_attr);
1122 ident *asm_text = attr->asm_text;
1123 const char *s = get_id_str(asm_text);
1124
1125 be_emit_cstring("#APP\n");
1126 be_emit_write_line();
1127
1128 if (s[0] != '\t')
1129 be_emit_char('\t');
1130
1131 while (*s != 0) {
1132 if (*s == '%') {
1133 s = emit_asm_operand(node, s);
1134 } else {
1135 be_emit_char(*s++);
1136 }
1137 }
1138
1139 be_emit_cstring("\n#NO_APP\n");
1140 be_emit_write_line();
1141 }
1142
1143
1144 /**
1145 * Emit movsb/w instructions to make mov count divideable by 4
1146 */
emit_CopyB_prolog(unsigned size)1147 static void emit_CopyB_prolog(unsigned size)
1148 {
1149 if (size & 1)
1150 ia32_emitf(NULL, "movsb");
1151 if (size & 2)
1152 ia32_emitf(NULL, "movsw");
1153 }
1154
1155 /**
1156 * Emit rep movsd instruction for memcopy.
1157 */
emit_ia32_CopyB(const ir_node * node)1158 static void emit_ia32_CopyB(const ir_node *node)
1159 {
1160 unsigned size = get_ia32_copyb_size(node);
1161
1162 emit_CopyB_prolog(size);
1163 ia32_emitf(node, "rep movsd");
1164 }
1165
1166 /**
1167 * Emits unrolled memcopy.
1168 */
emit_ia32_CopyB_i(const ir_node * node)1169 static void emit_ia32_CopyB_i(const ir_node *node)
1170 {
1171 unsigned size = get_ia32_copyb_size(node);
1172
1173 emit_CopyB_prolog(size);
1174
1175 size >>= 2;
1176 while (size--) {
1177 ia32_emitf(NULL, "movsd");
1178 }
1179 }
1180
1181
1182 /**
1183 * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1184 */
emit_ia32_Conv_with_FP(const ir_node * node,const char * conv_f,const char * conv_d)1185 static void emit_ia32_Conv_with_FP(const ir_node *node, const char* conv_f,
1186 const char* conv_d)
1187 {
1188 ir_mode *ls_mode = get_ia32_ls_mode(node);
1189 int ls_bits = get_mode_size_bits(ls_mode);
1190 const char *conv = ls_bits == 32 ? conv_f : conv_d;
1191
1192 ia32_emitf(node, "cvt%s %AS3, %D0", conv);
1193 }
1194
emit_ia32_Conv_I2FP(const ir_node * node)1195 static void emit_ia32_Conv_I2FP(const ir_node *node)
1196 {
1197 emit_ia32_Conv_with_FP(node, "si2ss", "si2sd");
1198 }
1199
emit_ia32_Conv_FP2I(const ir_node * node)1200 static void emit_ia32_Conv_FP2I(const ir_node *node)
1201 {
1202 emit_ia32_Conv_with_FP(node, "ss2si", "sd2si");
1203 }
1204
emit_ia32_Conv_FP2FP(const ir_node * node)1205 static void emit_ia32_Conv_FP2FP(const ir_node *node)
1206 {
1207 emit_ia32_Conv_with_FP(node, "sd2ss", "ss2sd");
1208 }
1209
1210 /**
1211 * Emits code to increase stack pointer.
1212 */
emit_be_IncSP(const ir_node * node)1213 static void emit_be_IncSP(const ir_node *node)
1214 {
1215 int offs = be_get_IncSP_offset(node);
1216
1217 if (offs == 0)
1218 return;
1219
1220 if (offs > 0) {
1221 ia32_emitf(node, "subl $%u, %D0", offs);
1222 } else {
1223 ia32_emitf(node, "addl $%u, %D0", -offs);
1224 }
1225 }
1226
1227 /**
1228 * Emits code for Copy/CopyKeep.
1229 */
Copy_emitter(const ir_node * node,const ir_node * op)1230 static void Copy_emitter(const ir_node *node, const ir_node *op)
1231 {
1232 const arch_register_t *in = arch_get_irn_register(op);
1233 const arch_register_t *out = arch_get_irn_register(node);
1234
1235 if (in == out) {
1236 return;
1237 }
1238 /* copies of fp nodes aren't real... */
1239 if (in->reg_class == &ia32_reg_classes[CLASS_ia32_fp])
1240 return;
1241
1242 ia32_emitf(node, "movl %R, %R", in, out);
1243 }
1244
emit_be_Copy(const ir_node * node)1245 static void emit_be_Copy(const ir_node *node)
1246 {
1247 Copy_emitter(node, be_get_Copy_op(node));
1248 }
1249
emit_be_CopyKeep(const ir_node * node)1250 static void emit_be_CopyKeep(const ir_node *node)
1251 {
1252 Copy_emitter(node, be_get_CopyKeep_op(node));
1253 }
1254
1255 /**
1256 * Emits code for exchange.
1257 */
emit_be_Perm(const ir_node * node)1258 static void emit_be_Perm(const ir_node *node)
1259 {
1260 const arch_register_t *in0, *in1;
1261
1262 in0 = arch_get_irn_register(get_irn_n(node, 0));
1263 in1 = arch_get_irn_register(get_irn_n(node, 1));
1264
1265 arch_register_class_t const *const cls0 = in0->reg_class;
1266 assert(cls0 == in1->reg_class && "Register class mismatch at Perm");
1267
1268 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
1269 ia32_emitf(node, "xchg %R, %R", in1, in0);
1270 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1271 ia32_emitf(NULL, "xorpd %R, %R", in1, in0);
1272 ia32_emitf(NULL, "xorpd %R, %R", in0, in1);
1273 ia32_emitf(node, "xorpd %R, %R", in1, in0);
1274 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_fp]) {
1275 /* is a NOP */
1276 } else {
1277 panic("unexpected register class in be_Perm (%+F)", node);
1278 }
1279 }
1280
1281 /* helper function for emit_ia32_Minus64Bit */
emit_mov(const ir_node * node,const arch_register_t * src,const arch_register_t * dst)1282 static void emit_mov(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1283 {
1284 ia32_emitf(node, "movl %R, %R", src, dst);
1285 }
1286
1287 /* helper function for emit_ia32_Minus64Bit */
emit_neg(const ir_node * node,const arch_register_t * reg)1288 static void emit_neg(const ir_node* node, const arch_register_t *reg)
1289 {
1290 ia32_emitf(node, "negl %R", reg);
1291 }
1292
1293 /* helper function for emit_ia32_Minus64Bit */
emit_sbb0(const ir_node * node,const arch_register_t * reg)1294 static void emit_sbb0(const ir_node* node, const arch_register_t *reg)
1295 {
1296 ia32_emitf(node, "sbbl $0, %R", reg);
1297 }
1298
1299 /* helper function for emit_ia32_Minus64Bit */
emit_sbb(const ir_node * node,const arch_register_t * src,const arch_register_t * dst)1300 static void emit_sbb(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1301 {
1302 ia32_emitf(node, "sbbl %R, %R", src, dst);
1303 }
1304
1305 /* helper function for emit_ia32_Minus64Bit */
emit_xchg(const ir_node * node,const arch_register_t * src,const arch_register_t * dst)1306 static void emit_xchg(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1307 {
1308 ia32_emitf(node, "xchgl %R, %R", src, dst);
1309 }
1310
1311 /* helper function for emit_ia32_Minus64Bit */
emit_zero(const ir_node * node,const arch_register_t * reg)1312 static void emit_zero(const ir_node* node, const arch_register_t *reg)
1313 {
1314 ia32_emitf(node, "xorl %R, %R", reg, reg);
1315 }
1316
emit_ia32_Minus64Bit(const ir_node * node)1317 static void emit_ia32_Minus64Bit(const ir_node *node)
1318 {
1319 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
1320 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
1321 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
1322 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
1323
1324 if (out_lo == in_lo) {
1325 if (out_hi != in_hi) {
1326 /* a -> a, b -> d */
1327 goto zero_neg;
1328 } else {
1329 /* a -> a, b -> b */
1330 goto normal_neg;
1331 }
1332 } else if (out_lo == in_hi) {
1333 if (out_hi == in_lo) {
1334 /* a -> b, b -> a */
1335 emit_xchg(node, in_lo, in_hi);
1336 goto normal_neg;
1337 } else {
1338 /* a -> b, b -> d */
1339 emit_mov(node, in_hi, out_hi);
1340 emit_mov(node, in_lo, out_lo);
1341 goto normal_neg;
1342 }
1343 } else {
1344 if (out_hi == in_lo) {
1345 /* a -> c, b -> a */
1346 emit_mov(node, in_lo, out_lo);
1347 goto zero_neg;
1348 } else if (out_hi == in_hi) {
1349 /* a -> c, b -> b */
1350 emit_mov(node, in_lo, out_lo);
1351 goto normal_neg;
1352 } else {
1353 /* a -> c, b -> d */
1354 emit_mov(node, in_lo, out_lo);
1355 goto zero_neg;
1356 }
1357 }
1358
1359 normal_neg:
1360 emit_neg( node, out_hi);
1361 emit_neg( node, out_lo);
1362 emit_sbb0(node, out_hi);
1363 return;
1364
1365 zero_neg:
1366 emit_zero(node, out_hi);
1367 emit_neg( node, out_lo);
1368 emit_sbb( node, in_hi, out_hi);
1369 }
1370
emit_ia32_GetEIP(const ir_node * node)1371 static void emit_ia32_GetEIP(const ir_node *node)
1372 {
1373 ia32_emitf(node, "call %s", pic_base_label);
1374 be_emit_irprintf("%s:\n", pic_base_label);
1375 be_emit_write_line();
1376 ia32_emitf(node, "popl %D0");
1377 }
1378
emit_ia32_ClimbFrame(const ir_node * node)1379 static void emit_ia32_ClimbFrame(const ir_node *node)
1380 {
1381 const ia32_climbframe_attr_t *attr = get_ia32_climbframe_attr_const(node);
1382
1383 ia32_emitf(node, "movl %S0, %D0");
1384 ia32_emitf(node, "movl $%u, %S1", attr->count);
1385 be_gas_emit_block_name(node);
1386 be_emit_cstring(":\n");
1387 be_emit_write_line();
1388 ia32_emitf(node, "movl (%D0), %D0");
1389 ia32_emitf(node, "dec %S1");
1390 be_emit_cstring("\tjnz ");
1391 be_gas_emit_block_name(node);
1392 be_emit_finish_line_gas(node);
1393 }
1394
emit_be_Return(const ir_node * node)1395 static void emit_be_Return(const ir_node *node)
1396 {
1397 unsigned pop = be_Return_get_pop(node);
1398
1399 if (pop > 0 || be_Return_get_emit_pop(node)) {
1400 ia32_emitf(node, "ret $%u", pop);
1401 } else {
1402 ia32_emitf(node, "ret");
1403 }
1404 }
1405
emit_Nothing(const ir_node * node)1406 static void emit_Nothing(const ir_node *node)
1407 {
1408 (void) node;
1409 }
1410
1411
1412 /**
1413 * Enters the emitter functions for handled nodes into the generic
1414 * pointer of an opcode.
1415 */
ia32_register_emitters(void)1416 static void ia32_register_emitters(void)
1417 {
1418 #define IA32_EMIT(a) op_ia32_##a->ops.generic = (op_func)emit_ia32_##a
1419 #define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
1420 #define IGN(a) op_##a->ops.generic = (op_func)emit_Nothing
1421 #define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
1422 #define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing
1423
1424 /* first clear the generic function pointer for all ops */
1425 ir_clear_opcodes_generic_func();
1426
1427 /* register all emitter functions defined in spec */
1428 ia32_register_spec_emitters();
1429
1430 /* other ia32 emitter functions */
1431 IA32_EMIT(Asm);
1432 IA32_EMIT(CMovcc);
1433 IA32_EMIT(Conv_FP2FP);
1434 IA32_EMIT(Conv_FP2I);
1435 IA32_EMIT(Conv_I2FP);
1436 IA32_EMIT(CopyB);
1437 IA32_EMIT(CopyB_i);
1438 IA32_EMIT(GetEIP);
1439 IA32_EMIT(IMul);
1440 IA32_EMIT(Jcc);
1441 IA32_EMIT(Setcc);
1442 IA32_EMIT(Minus64Bit);
1443 IA32_EMIT(SwitchJmp);
1444 IA32_EMIT(ClimbFrame);
1445 IA32_EMIT(Jmp);
1446
1447 /* benode emitter */
1448 BE_EMIT(Copy);
1449 BE_EMIT(CopyKeep);
1450 BE_EMIT(IncSP);
1451 BE_EMIT(Perm);
1452 BE_EMIT(Return);
1453
1454 BE_IGN(Keep);
1455 BE_IGN(Start);
1456
1457 /* firm emitter */
1458 IGN(Phi);
1459
1460 #undef BE_EMIT
1461 #undef EMIT
1462 #undef IGN
1463 #undef IA32_EMIT
1464 }
1465
1466 typedef void (*emit_func_ptr) (const ir_node *);
1467
1468 /**
1469 * Assign and emit an exception label if the current instruction can fail.
1470 */
ia32_assign_exc_label(ir_node * node)1471 static void ia32_assign_exc_label(ir_node *node)
1472 {
1473 /* assign a new ID to the instruction */
1474 set_ia32_exc_label_id(node, ++exc_label_id);
1475 /* print it */
1476 ia32_emit_exc_label(node);
1477 be_emit_char(':');
1478 be_emit_pad_comment();
1479 be_emit_cstring("/* exception to Block ");
1480 ia32_emit_cfop_target(node);
1481 be_emit_cstring(" */\n");
1482 be_emit_write_line();
1483 }
1484
1485 /**
1486 * Emits code for a node.
1487 */
ia32_emit_node(ir_node * node)1488 static void ia32_emit_node(ir_node *node)
1489 {
1490 ir_op *op = get_irn_op(node);
1491
1492 DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
1493
1494 if (is_ia32_irn(node)) {
1495 if (get_ia32_exc_label(node)) {
1496 /* emit the exception label of this instruction */
1497 ia32_assign_exc_label(node);
1498 }
1499 if (mark_spill_reload) {
1500 if (is_ia32_is_spill(node)) {
1501 ia32_emitf(NULL, "xchg %ebx, %ebx /* spill mark */");
1502 }
1503 if (is_ia32_is_reload(node)) {
1504 ia32_emitf(NULL, "xchg %edx, %edx /* reload mark */");
1505 }
1506 if (is_ia32_is_remat(node)) {
1507 ia32_emitf(NULL, "xchg %ecx, %ecx /* remat mark */");
1508 }
1509 }
1510 }
1511 if (op->ops.generic) {
1512 emit_func_ptr func = (emit_func_ptr) op->ops.generic;
1513
1514 be_dwarf_location(get_irn_dbg_info(node));
1515
1516 (*func) (node);
1517 } else {
1518 emit_Nothing(node);
1519 ir_fprintf(stderr, "Error: No emit handler for node %+F (%+G, graph %+F)\n", node, node, current_ir_graph);
1520 abort();
1521 }
1522
1523 if (sp_relative) {
1524 int sp_change = arch_get_sp_bias(node);
1525 if (sp_change != 0) {
1526 assert(sp_change != SP_BIAS_RESET);
1527 callframe_offset += sp_change;
1528 be_dwarf_callframe_offset(callframe_offset);
1529 }
1530 }
1531 }
1532
1533 /**
1534 * Emits gas alignment directives
1535 */
ia32_emit_alignment(unsigned align,unsigned skip)1536 static void ia32_emit_alignment(unsigned align, unsigned skip)
1537 {
1538 ia32_emitf(NULL, ".p2align %u,,%u", align, skip);
1539 }
1540
1541 /**
1542 * Emits gas alignment directives for Labels depended on cpu architecture.
1543 */
ia32_emit_align_label(void)1544 static void ia32_emit_align_label(void)
1545 {
1546 unsigned align = ia32_cg_config.label_alignment;
1547 unsigned maximum_skip = ia32_cg_config.label_alignment_max_skip;
1548 ia32_emit_alignment(align, maximum_skip);
1549 }
1550
1551 /**
1552 * Test whether a block should be aligned.
1553 * For cpus in the P4/Athlon class it is useful to align jump labels to
1554 * 16 bytes. However we should only do that if the alignment nops before the
1555 * label aren't executed more often than we have jumps to the label.
1556 */
should_align_block(const ir_node * block)1557 static int should_align_block(const ir_node *block)
1558 {
1559 static const double DELTA = .0001;
1560 ir_node *prev = get_prev_block_sched(block);
1561 double prev_freq = 0; /**< execfreq of the fallthrough block */
1562 double jmp_freq = 0; /**< execfreq of all non-fallthrough blocks */
1563 double block_freq;
1564 int i, n_cfgpreds;
1565
1566 if (ia32_cg_config.label_alignment_factor <= 0)
1567 return 0;
1568
1569 block_freq = get_block_execfreq(block);
1570 if (block_freq < DELTA)
1571 return 0;
1572
1573 n_cfgpreds = get_Block_n_cfgpreds(block);
1574 for (i = 0; i < n_cfgpreds; ++i) {
1575 const ir_node *pred = get_Block_cfgpred_block(block, i);
1576 double pred_freq = get_block_execfreq(pred);
1577
1578 if (pred == prev) {
1579 prev_freq += pred_freq;
1580 } else {
1581 jmp_freq += pred_freq;
1582 }
1583 }
1584
1585 if (prev_freq < DELTA && !(jmp_freq < DELTA))
1586 return 1;
1587
1588 jmp_freq /= prev_freq;
1589
1590 return jmp_freq > ia32_cg_config.label_alignment_factor;
1591 }
1592
1593 /**
1594 * Emit the block header for a block.
1595 *
1596 * @param block the block
1597 * @param prev_block the previous block
1598 */
ia32_emit_block_header(ir_node * block)1599 static void ia32_emit_block_header(ir_node *block)
1600 {
1601 ir_graph *irg = current_ir_graph;
1602 int need_label = block_needs_label(block);
1603
1604 if (block == get_irg_end_block(irg))
1605 return;
1606
1607 if (ia32_cg_config.label_alignment > 0) {
1608 /* align the current block if:
1609 * a) if should be aligned due to its execution frequency
1610 * b) there is no fall-through here
1611 */
1612 if (should_align_block(block)) {
1613 ia32_emit_align_label();
1614 } else {
1615 /* if the predecessor block has no fall-through,
1616 we can always align the label. */
1617 int i;
1618 int has_fallthrough = 0;
1619
1620 for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
1621 ir_node *cfg_pred = get_Block_cfgpred(block, i);
1622 if (can_be_fallthrough(cfg_pred)) {
1623 has_fallthrough = 1;
1624 break;
1625 }
1626 }
1627
1628 if (!has_fallthrough)
1629 ia32_emit_align_label();
1630 }
1631 }
1632
1633 be_gas_begin_block(block, need_label);
1634 }
1635
1636 /**
1637 * Walks over the nodes in a block connected by scheduling edges
1638 * and emits code for each node.
1639 */
ia32_gen_block(ir_node * block)1640 static void ia32_gen_block(ir_node *block)
1641 {
1642 ia32_emit_block_header(block);
1643
1644 if (sp_relative) {
1645 ir_graph *irg = get_irn_irg(block);
1646 callframe_offset = 4; /* 4 bytes for the return address */
1647 /* ESP guessing, TODO perform a real ESP simulation */
1648 if (block != get_irg_start_block(irg)) {
1649 callframe_offset += frame_type_size;
1650 }
1651 be_dwarf_callframe_offset(callframe_offset);
1652 }
1653
1654 /* emit the contents of the block */
1655 be_dwarf_location(get_irn_dbg_info(block));
1656 sched_foreach(block, node) {
1657 ia32_emit_node(node);
1658 }
1659 }
1660
1661 typedef struct exc_entry {
1662 ir_node *exc_instr; /** The instruction that can issue an exception. */
1663 ir_node *block; /** The block to call then. */
1664 } exc_entry;
1665
1666 /**
1667 * Block-walker:
1668 * Sets labels for control flow nodes (jump target).
1669 * Links control predecessors to there destination blocks.
1670 */
ia32_gen_labels(ir_node * block,void * data)1671 static void ia32_gen_labels(ir_node *block, void *data)
1672 {
1673 exc_entry **exc_list = (exc_entry**)data;
1674 ir_node *pred;
1675 int n;
1676
1677 for (n = get_Block_n_cfgpreds(block) - 1; n >= 0; --n) {
1678 pred = get_Block_cfgpred(block, n);
1679 set_irn_link(pred, block);
1680
1681 pred = skip_Proj(pred);
1682 if (is_ia32_irn(pred) && get_ia32_exc_label(pred)) {
1683 exc_entry e;
1684
1685 e.exc_instr = pred;
1686 e.block = block;
1687 ARR_APP1(exc_entry, *exc_list, e);
1688 set_irn_link(pred, block);
1689 }
1690 }
1691 }
1692
1693 /**
1694 * Compare two exception_entries.
1695 */
cmp_exc_entry(const void * a,const void * b)1696 static int cmp_exc_entry(const void *a, const void *b)
1697 {
1698 const exc_entry *ea = (const exc_entry*)a;
1699 const exc_entry *eb = (const exc_entry*)b;
1700
1701 if (get_ia32_exc_label_id(ea->exc_instr) < get_ia32_exc_label_id(eb->exc_instr))
1702 return -1;
1703 return +1;
1704 }
1705
construct_parameter_infos(ir_graph * irg)1706 static parameter_dbg_info_t *construct_parameter_infos(ir_graph *irg)
1707 {
1708 ir_entity *entity = get_irg_entity(irg);
1709 ir_type *type = get_entity_type(entity);
1710 size_t n_params = get_method_n_params(type);
1711 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
1712 ir_type *arg_type = layout->arg_type;
1713 size_t n_members = get_compound_n_members(arg_type);
1714 parameter_dbg_info_t *infos = XMALLOCNZ(parameter_dbg_info_t, n_params);
1715 size_t i;
1716
1717 for (i = 0; i < n_members; ++i) {
1718 ir_entity *member = get_compound_member(arg_type, i);
1719 size_t param;
1720 if (!is_parameter_entity(member))
1721 continue;
1722 param = get_entity_parameter_number(member);
1723 if (param == IR_VA_START_PARAMETER_NUMBER)
1724 continue;
1725 assert(infos[param].entity == NULL && infos[param].reg == NULL);
1726 infos[param].reg = NULL;
1727 infos[param].entity = member;
1728 }
1729
1730 return infos;
1731 }
1732
1733 /**
1734 * Main driver. Emits the code for one routine.
1735 */
ia32_gen_routine(ir_graph * irg)1736 void ia32_gen_routine(ir_graph *irg)
1737 {
1738 ir_entity *entity = get_irg_entity(irg);
1739 exc_entry *exc_list = NEW_ARR_F(exc_entry, 0);
1740 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
1741 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
1742 ir_node **blk_sched = irg_data->blk_sched;
1743 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
1744 parameter_dbg_info_t *infos;
1745 int i, n;
1746
1747 isa = (ia32_isa_t*) arch_env;
1748 do_pic = be_options.pic;
1749
1750 be_gas_elf_type_char = '@';
1751
1752 ia32_register_emitters();
1753
1754 get_unique_label(pic_base_label, sizeof(pic_base_label), "PIC_BASE");
1755
1756 infos = construct_parameter_infos(irg);
1757 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
1758 infos);
1759 xfree(infos);
1760
1761 sp_relative = layout->sp_relative;
1762 if (layout->sp_relative) {
1763 ir_type *frame_type = get_irg_frame_type(irg);
1764 frame_type_size = get_type_size_bytes(frame_type);
1765 be_dwarf_callframe_register(&ia32_registers[REG_ESP]);
1766 } else {
1767 /* well not entirely correct here, we should emit this after the
1768 * "movl esp, ebp" */
1769 be_dwarf_callframe_register(&ia32_registers[REG_EBP]);
1770 /* TODO: do not hardcode the following */
1771 be_dwarf_callframe_offset(8);
1772 be_dwarf_callframe_spilloffset(&ia32_registers[REG_EBP], -8);
1773 }
1774
1775 /* we use links to point to target blocks */
1776 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
1777 irg_block_walk_graph(irg, ia32_gen_labels, NULL, &exc_list);
1778
1779 /* initialize next block links */
1780 n = ARR_LEN(blk_sched);
1781 for (i = 0; i < n; ++i) {
1782 ir_node *block = blk_sched[i];
1783 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
1784
1785 set_irn_link(block, prev);
1786 }
1787
1788 for (i = 0; i < n; ++i) {
1789 ir_node *block = blk_sched[i];
1790
1791 ia32_gen_block(block);
1792 }
1793
1794 be_gas_emit_function_epilog(entity);
1795
1796 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
1797
1798 /* Sort the exception table using the exception label id's.
1799 Those are ascending with ascending addresses. */
1800 qsort(exc_list, ARR_LEN(exc_list), sizeof(exc_list[0]), cmp_exc_entry);
1801 {
1802 size_t e;
1803
1804 for (e = 0; e < ARR_LEN(exc_list); ++e) {
1805 be_emit_cstring("\t.long ");
1806 ia32_emit_exc_label(exc_list[e].exc_instr);
1807 be_emit_char('\n');
1808 be_emit_cstring("\t.long ");
1809 be_gas_emit_block_name(exc_list[e].block);
1810 be_emit_char('\n');
1811 }
1812 }
1813 DEL_ARR_F(exc_list);
1814 }
1815
1816 static const lc_opt_table_entry_t ia32_emitter_options[] = {
1817 LC_OPT_ENT_BOOL("mark_spill_reload", "mark spills and reloads with ud opcodes", &mark_spill_reload),
1818 LC_OPT_LAST
1819 };
1820
1821 /* ==== Experimental binary emitter ==== */
1822
1823 static unsigned char reg_gp_map[N_ia32_gp_REGS];
1824 //static unsigned char reg_mmx_map[N_ia32_mmx_REGS];
1825 //static unsigned char reg_sse_map[N_ia32_xmm_REGS];
1826
build_reg_map(void)1827 static void build_reg_map(void)
1828 {
1829 reg_gp_map[REG_GP_EAX] = 0x0;
1830 reg_gp_map[REG_GP_ECX] = 0x1;
1831 reg_gp_map[REG_GP_EDX] = 0x2;
1832 reg_gp_map[REG_GP_EBX] = 0x3;
1833 reg_gp_map[REG_GP_ESP] = 0x4;
1834 reg_gp_map[REG_GP_EBP] = 0x5;
1835 reg_gp_map[REG_GP_ESI] = 0x6;
1836 reg_gp_map[REG_GP_EDI] = 0x7;
1837 }
1838
1839 /** Returns the encoding for a pnc field. */
pnc2cc(ia32_condition_code_t cc)1840 static unsigned char pnc2cc(ia32_condition_code_t cc)
1841 {
1842 return cc & 0xf;
1843 }
1844
1845 /** Sign extension bit values for binops */
1846 enum SignExt {
1847 UNSIGNED_IMM = 0, /**< unsigned immediate */
1848 SIGNEXT_IMM = 2, /**< sign extended immediate */
1849 };
1850
1851 /** The mod encoding of the ModR/M */
1852 enum Mod {
1853 MOD_IND = 0x00, /**< [reg1] */
1854 MOD_IND_BYTE_OFS = 0x40, /**< [reg1 + byte ofs] */
1855 MOD_IND_WORD_OFS = 0x80, /**< [reg1 + word ofs] */
1856 MOD_REG = 0xC0 /**< reg1 */
1857 };
1858
1859 /** create R/M encoding for ModR/M */
1860 #define ENC_RM(x) (x)
1861 /** create REG encoding for ModR/M */
1862 #define ENC_REG(x) ((x) << 3)
1863
1864 /** create encoding for a SIB byte */
1865 #define ENC_SIB(scale, index, base) ((scale) << 6 | (index) << 3 | (base))
1866
1867 /* Node: The following routines are supposed to append bytes, words, dwords
1868 to the output stream.
1869 Currently the implementation is stupid in that it still creates output
1870 for an "assembler" in the form of .byte, .long
1871 We will change this when enough infrastructure is there to create complete
1872 machine code in memory/object files */
1873
bemit8(const unsigned char byte)1874 static void bemit8(const unsigned char byte)
1875 {
1876 be_emit_irprintf("\t.byte 0x%x\n", byte);
1877 be_emit_write_line();
1878 }
1879
bemit16(const unsigned short u16)1880 static void bemit16(const unsigned short u16)
1881 {
1882 be_emit_irprintf("\t.word 0x%x\n", u16);
1883 be_emit_write_line();
1884 }
1885
bemit32(const unsigned u32)1886 static void bemit32(const unsigned u32)
1887 {
1888 be_emit_irprintf("\t.long 0x%x\n", u32);
1889 be_emit_write_line();
1890 }
1891
1892 /**
1893 * Emit address of an entity. If @p is_relative is true then a relative
1894 * offset from behind the address to the entity is created.
1895 */
bemit_entity(ir_entity * entity,bool entity_sign,int offset,bool is_relative)1896 static void bemit_entity(ir_entity *entity, bool entity_sign, int offset,
1897 bool is_relative)
1898 {
1899 if (entity == NULL) {
1900 bemit32(offset);
1901 return;
1902 }
1903
1904 /* the final version should remember the position in the bytestream
1905 and patch it with the correct address at linktime... */
1906 be_emit_cstring("\t.long ");
1907 if (entity_sign)
1908 be_emit_char('-');
1909 be_gas_emit_entity(entity);
1910
1911 if (get_entity_owner(entity) == get_tls_type()) {
1912 if (!entity_has_definition(entity)) {
1913 be_emit_cstring("@INDNTPOFF");
1914 } else {
1915 be_emit_cstring("@NTPOFF");
1916 }
1917 }
1918
1919 if (is_relative) {
1920 be_emit_cstring("-.");
1921 offset -= 4;
1922 }
1923
1924 if (offset != 0) {
1925 be_emit_irprintf("%+d", offset);
1926 }
1927 be_emit_char('\n');
1928 be_emit_write_line();
1929 }
1930
bemit_jmp_destination(const ir_node * dest_block)1931 static void bemit_jmp_destination(const ir_node *dest_block)
1932 {
1933 be_emit_cstring("\t.long ");
1934 be_gas_emit_block_name(dest_block);
1935 be_emit_cstring(" - . - 4\n");
1936 be_emit_write_line();
1937 }
1938
1939 /* end emit routines, all emitters following here should only use the functions
1940 above. */
1941
1942 typedef enum reg_modifier {
1943 REG_LOW = 0,
1944 REG_HIGH = 1
1945 } reg_modifier_t;
1946
1947 /** Create a ModR/M byte for src1,src2 registers */
bemit_modrr(const arch_register_t * src1,const arch_register_t * src2)1948 static void bemit_modrr(const arch_register_t *src1,
1949 const arch_register_t *src2)
1950 {
1951 unsigned char modrm = MOD_REG;
1952 modrm |= ENC_RM(reg_gp_map[src1->index]);
1953 modrm |= ENC_REG(reg_gp_map[src2->index]);
1954 bemit8(modrm);
1955 }
1956
1957 /** Create a ModR/M8 byte for src1,src2 registers */
bemit_modrr8(reg_modifier_t high_part1,const arch_register_t * src1,reg_modifier_t high_part2,const arch_register_t * src2)1958 static void bemit_modrr8(reg_modifier_t high_part1, const arch_register_t *src1,
1959 reg_modifier_t high_part2, const arch_register_t *src2)
1960 {
1961 unsigned char modrm = MOD_REG;
1962 modrm |= ENC_RM(reg_gp_map[src1->index] + (high_part1 == REG_HIGH ? 4 : 0));
1963 modrm |= ENC_REG(reg_gp_map[src2->index] + (high_part2 == REG_HIGH ? 4 : 0));
1964 bemit8(modrm);
1965 }
1966
1967 /** Create a ModR/M byte for one register and extension */
bemit_modru(const arch_register_t * reg,unsigned ext)1968 static void bemit_modru(const arch_register_t *reg, unsigned ext)
1969 {
1970 unsigned char modrm = MOD_REG;
1971 assert(ext <= 7);
1972 modrm |= ENC_RM(reg_gp_map[reg->index]);
1973 modrm |= ENC_REG(ext);
1974 bemit8(modrm);
1975 }
1976
1977 /** Create a ModR/M8 byte for one register */
bemit_modrm8(reg_modifier_t high_part,const arch_register_t * reg)1978 static void bemit_modrm8(reg_modifier_t high_part, const arch_register_t *reg)
1979 {
1980 unsigned char modrm = MOD_REG;
1981 assert(reg_gp_map[reg->index] < 4);
1982 modrm |= ENC_RM(reg_gp_map[reg->index] + (high_part == REG_HIGH ? 4 : 0));
1983 modrm |= MOD_REG;
1984 bemit8(modrm);
1985 }
1986
1987 /**
1988 * Calculate the size of an signed immediate in bytes.
1989 *
1990 * @param offset an offset
1991 */
get_signed_imm_size(int offset)1992 static unsigned get_signed_imm_size(int offset)
1993 {
1994 if (-128 <= offset && offset < 128) {
1995 return 1;
1996 } else if (-32768 <= offset && offset < 32768) {
1997 return 2;
1998 } else {
1999 return 4;
2000 }
2001 }
2002
2003 /**
2004 * Emit an address mode.
2005 *
2006 * @param reg content of the reg field: either a register index or an opcode extension
2007 * @param node the node
2008 */
bemit_mod_am(unsigned reg,const ir_node * node)2009 static void bemit_mod_am(unsigned reg, const ir_node *node)
2010 {
2011 ir_entity *ent = get_ia32_am_sc(node);
2012 int offs = get_ia32_am_offs_int(node);
2013 ir_node *base = get_irn_n(node, n_ia32_base);
2014 int has_base = !is_ia32_NoReg_GP(base);
2015 ir_node *idx = get_irn_n(node, n_ia32_index);
2016 int has_index = !is_ia32_NoReg_GP(idx);
2017 unsigned modrm = 0;
2018 unsigned sib = 0;
2019 unsigned emitoffs = 0;
2020 bool emitsib = false;
2021 unsigned base_enc;
2022
2023 /* set the mod part depending on displacement */
2024 if (ent != NULL) {
2025 modrm |= MOD_IND_WORD_OFS;
2026 emitoffs = 32;
2027 } else if (offs == 0) {
2028 modrm |= MOD_IND;
2029 emitoffs = 0;
2030 } else if (-128 <= offs && offs < 128) {
2031 modrm |= MOD_IND_BYTE_OFS;
2032 emitoffs = 8;
2033 } else {
2034 modrm |= MOD_IND_WORD_OFS;
2035 emitoffs = 32;
2036 }
2037
2038 if (has_base) {
2039 const arch_register_t *base_reg = arch_get_irn_register(base);
2040 base_enc = reg_gp_map[base_reg->index];
2041 } else {
2042 /* Use the EBP encoding + MOD_IND if NO base register. There is
2043 * always a 32bit offset present in this case. */
2044 modrm = MOD_IND;
2045 base_enc = 0x05;
2046 emitoffs = 32;
2047 }
2048
2049 /* Determine if we need a SIB byte. */
2050 if (has_index) {
2051 const arch_register_t *reg_index = arch_get_irn_register(idx);
2052 int scale = get_ia32_am_scale(node);
2053 assert(scale < 4);
2054 /* R/M set to ESP means SIB in 32bit mode. */
2055 modrm |= ENC_RM(0x04);
2056 sib = ENC_SIB(scale, reg_gp_map[reg_index->index], base_enc);
2057 emitsib = true;
2058 } else if (base_enc == 0x04) {
2059 /* for the above reason we are forced to emit a SIB when base is ESP.
2060 * Only the base is used, index must be ESP too, which means no index.
2061 */
2062 modrm |= ENC_RM(0x04);
2063 sib = ENC_SIB(0, 0x04, 0x04);
2064 emitsib = true;
2065 } else {
2066 modrm |= ENC_RM(base_enc);
2067 }
2068
2069 /* We are forced to emit an 8bit offset as EBP base without offset is a
2070 * special case for SIB without base register. */
2071 if (base_enc == 0x05 && emitoffs == 0) {
2072 modrm |= MOD_IND_BYTE_OFS;
2073 emitoffs = 8;
2074 }
2075
2076 modrm |= ENC_REG(reg);
2077
2078 bemit8(modrm);
2079 if (emitsib)
2080 bemit8(sib);
2081
2082 /* emit displacement */
2083 if (emitoffs == 8) {
2084 bemit8((unsigned) offs);
2085 } else if (emitoffs == 32) {
2086 bemit_entity(ent, is_ia32_am_sc_sign(node), offs, false);
2087 }
2088 }
2089
2090 /**
2091 * Emit a binop with a immediate operand.
2092 *
2093 * @param node the node to emit
2094 * @param opcode_eax the opcode for the op eax, imm variant
2095 * @param opcode the opcode for the reg, imm variant
2096 * @param ruval the opcode extension for opcode
2097 */
bemit_binop_with_imm(const ir_node * node,unsigned char opcode_ax,unsigned char opcode,unsigned char ruval)2098 static void bemit_binop_with_imm(
2099 const ir_node *node,
2100 unsigned char opcode_ax,
2101 unsigned char opcode, unsigned char ruval)
2102 {
2103 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2104 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2105 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2106 unsigned size;
2107
2108 /* Some instructions (test) have no short form with 32bit value + 8bit
2109 * immediate. */
2110 if (attr->symconst != NULL || opcode & SIGNEXT_IMM) {
2111 size = 4;
2112 } else {
2113 /* check for sign extension */
2114 size = get_signed_imm_size(attr->offset);
2115 }
2116
2117 switch (size) {
2118 case 1:
2119 bemit8(opcode | SIGNEXT_IMM);
2120 /* cmp has this special mode */
2121 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2122 bemit_mod_am(ruval, node);
2123 } else {
2124 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2125 bemit_modru(reg, ruval);
2126 }
2127 bemit8((unsigned char)attr->offset);
2128 return;
2129 case 2:
2130 case 4:
2131 /* check for eax variant: this variant is shorter for 32bit immediates only */
2132 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2133 bemit8(opcode);
2134 bemit_mod_am(ruval, node);
2135 } else {
2136 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2137 if (reg->index == REG_GP_EAX) {
2138 bemit8(opcode_ax);
2139 } else {
2140 bemit8(opcode);
2141 bemit_modru(reg, ruval);
2142 }
2143 }
2144 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2145 return;
2146 }
2147 panic("invalid imm size?!?");
2148 }
2149
2150 /**
2151 * Emits a binop.
2152 */
bemit_binop_2(const ir_node * node,unsigned code)2153 static void bemit_binop_2(const ir_node *node, unsigned code)
2154 {
2155 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2156 bemit8(code);
2157 if (get_ia32_op_type(node) == ia32_Normal) {
2158 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2159 bemit_modrr(op2, out);
2160 } else {
2161 bemit_mod_am(reg_gp_map[out->index], node);
2162 }
2163 }
2164
2165 /**
2166 * Emit a binop.
2167 */
bemit_binop(const ir_node * node,const unsigned char opcodes[4])2168 static void bemit_binop(const ir_node *node, const unsigned char opcodes[4])
2169 {
2170 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2171 if (is_ia32_Immediate(right)) {
2172 bemit_binop_with_imm(node, opcodes[1], opcodes[2], opcodes[3]);
2173 } else {
2174 bemit_binop_2(node, opcodes[0]);
2175 }
2176 }
2177
2178 /**
2179 * Emit an unop.
2180 */
bemit_unop(const ir_node * node,unsigned char code,unsigned char ext,int input)2181 static void bemit_unop(const ir_node *node, unsigned char code, unsigned char ext, int input)
2182 {
2183 bemit8(code);
2184 if (get_ia32_op_type(node) == ia32_Normal) {
2185 const arch_register_t *in = arch_get_irn_register_in(node, input);
2186 bemit_modru(in, ext);
2187 } else {
2188 bemit_mod_am(ext, node);
2189 }
2190 }
2191
bemit_unop_reg(const ir_node * node,unsigned char code,int input)2192 static void bemit_unop_reg(const ir_node *node, unsigned char code, int input)
2193 {
2194 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2195 bemit_unop(node, code, reg_gp_map[out->index], input);
2196 }
2197
bemit_unop_mem(const ir_node * node,unsigned char code,unsigned char ext)2198 static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned char ext)
2199 {
2200 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2201 if (size == 16)
2202 bemit8(0x66);
2203 bemit8(size == 8 ? code : code + 1);
2204 bemit_mod_am(ext, node);
2205 }
2206
bemit_0f_unop_reg(ir_node const * const node,unsigned char const code,int const input)2207 static void bemit_0f_unop_reg(ir_node const *const node, unsigned char const code, int const input)
2208 {
2209 bemit8(0x0F);
2210 bemit_unop_reg(node, code, input);
2211 }
2212
bemit_immediate(const ir_node * node,bool relative)2213 static void bemit_immediate(const ir_node *node, bool relative)
2214 {
2215 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
2216 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, relative);
2217 }
2218
bemit_copy(const ir_node * copy)2219 static void bemit_copy(const ir_node *copy)
2220 {
2221 const arch_register_t *in = arch_get_irn_register_in(copy, 0);
2222 const arch_register_t *out = arch_get_irn_register_out(copy, 0);
2223
2224 if (in == out)
2225 return;
2226 /* copies of fp nodes aren't real... */
2227 if (in->reg_class == &ia32_reg_classes[CLASS_ia32_fp])
2228 return;
2229
2230 assert(in->reg_class == &ia32_reg_classes[CLASS_ia32_gp]);
2231 bemit8(0x8B);
2232 bemit_modrr(in, out);
2233 }
2234
bemit_perm(const ir_node * node)2235 static void bemit_perm(const ir_node *node)
2236 {
2237 const arch_register_t *in0 = arch_get_irn_register(get_irn_n(node, 0));
2238 const arch_register_t *in1 = arch_get_irn_register(get_irn_n(node, 1));
2239 const arch_register_class_t *cls0 = in0->reg_class;
2240
2241 assert(cls0 == in1->reg_class && "Register class mismatch at Perm");
2242
2243 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
2244 if (in0->index == REG_GP_EAX) {
2245 bemit8(0x90 + reg_gp_map[in1->index]);
2246 } else if (in1->index == REG_GP_EAX) {
2247 bemit8(0x90 + reg_gp_map[in0->index]);
2248 } else {
2249 bemit8(0x87);
2250 bemit_modrr(in0, in1);
2251 }
2252 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
2253 panic("unimplemented"); // TODO implement
2254 //ia32_emitf(NULL, "xorpd %R, %R", in1, in0);
2255 //ia32_emitf(NULL, "xorpd %R, %R", in0, in1);
2256 //ia32_emitf(node, "xorpd %R, %R", in1, in0);
2257 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_fp]) {
2258 /* is a NOP */
2259 } else {
2260 panic("unexpected register class in be_Perm (%+F)", node);
2261 }
2262 }
2263
bemit_xor0(const ir_node * node)2264 static void bemit_xor0(const ir_node *node)
2265 {
2266 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2267 bemit8(0x31);
2268 bemit_modrr(out, out);
2269 }
2270
bemit_mov_const(const ir_node * node)2271 static void bemit_mov_const(const ir_node *node)
2272 {
2273 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2274 bemit8(0xB8 + reg_gp_map[out->index]);
2275 bemit_immediate(node, false);
2276 }
2277
2278 /**
2279 * Creates a function for a Binop with 3 possible encodings.
2280 */
2281 #define BINOP(op, op0, op1, op2, op2_ext) \
2282 static void bemit_ ## op(const ir_node *node) { \
2283 static const unsigned char op ## _codes[] = {op0, op1, op2, op2_ext}; \
2284 bemit_binop(node, op ## _codes); \
2285 }
2286
2287 /* insn def eax,imm imm */
2288 BINOP(add, 0x03, 0x05, 0x81, 0)
2289 BINOP(or, 0x0B, 0x0D, 0x81, 1)
2290 BINOP(adc, 0x13, 0x15, 0x81, 2)
2291 BINOP(sbb, 0x1B, 0x1D, 0x81, 3)
2292 BINOP(and, 0x23, 0x25, 0x81, 4)
2293 BINOP(sub, 0x2B, 0x2D, 0x81, 5)
2294 BINOP(xor, 0x33, 0x35, 0x81, 6)
2295 BINOP(test, 0x85, 0xA9, 0xF7, 0)
2296
2297 #define BINOPMEM(op, ext) \
2298 static void bemit_##op(const ir_node *node) \
2299 { \
2300 ir_node *val; \
2301 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2302 if (size == 16) \
2303 bemit8(0x66); \
2304 val = get_irn_n(node, n_ia32_unary_op); \
2305 if (is_ia32_Immediate(val)) { \
2306 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(val); \
2307 int offset = attr->offset; \
2308 if (attr->symconst == NULL && get_signed_imm_size(offset) == 1) { \
2309 bemit8(0x83); \
2310 bemit_mod_am(ext, node); \
2311 bemit8(offset); \
2312 } else { \
2313 bemit8(0x81); \
2314 bemit_mod_am(ext, node); \
2315 if (size == 16) { \
2316 bemit16(offset); \
2317 } else { \
2318 bemit_entity(attr->symconst, attr->sc_sign, offset, false); \
2319 } \
2320 } \
2321 } else { \
2322 bemit8(ext << 3 | 1); \
2323 bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
2324 } \
2325 } \
2326 \
2327 static void bemit_##op##8bit(const ir_node *node) \
2328 { \
2329 ir_node *val = get_irn_n(node, n_ia32_unary_op); \
2330 if (is_ia32_Immediate(val)) { \
2331 bemit8(0x80); \
2332 bemit_mod_am(ext, node); \
2333 bemit8(get_ia32_immediate_attr_const(val)->offset); \
2334 } else { \
2335 bemit8(ext << 3); \
2336 bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
2337 } \
2338 }
2339
2340 BINOPMEM(addmem, 0)
2341 BINOPMEM(ormem, 1)
2342 BINOPMEM(andmem, 4)
2343 BINOPMEM(submem, 5)
2344 BINOPMEM(xormem, 6)
2345
2346
2347 /**
2348 * Creates a function for an Unop with code /ext encoding.
2349 */
2350 #define UNOP(op, code, ext, input) \
2351 static void bemit_ ## op(const ir_node *node) { \
2352 bemit_unop(node, code, ext, input); \
2353 }
2354
2355 UNOP(not, 0xF7, 2, n_ia32_Not_val)
2356 UNOP(neg, 0xF7, 3, n_ia32_Neg_val)
2357 UNOP(mul, 0xF7, 4, n_ia32_Mul_right)
2358 UNOP(imul1op, 0xF7, 5, n_ia32_IMul1OP_right)
2359 UNOP(div, 0xF7, 6, n_ia32_Div_divisor)
2360 UNOP(idiv, 0xF7, 7, n_ia32_IDiv_divisor)
2361
2362 /* TODO: am support for IJmp */
2363 UNOP(ijmp, 0xFF, 4, n_ia32_IJmp_target)
2364
2365 #define SHIFT(op, ext) \
2366 static void bemit_##op(const ir_node *node) \
2367 { \
2368 const arch_register_t *out = arch_get_irn_register_out(node, 0); \
2369 ir_node *count = get_irn_n(node, 1); \
2370 if (is_ia32_Immediate(count)) { \
2371 int offset = get_ia32_immediate_attr_const(count)->offset; \
2372 if (offset == 1) { \
2373 bemit8(0xD1); \
2374 bemit_modru(out, ext); \
2375 } else { \
2376 bemit8(0xC1); \
2377 bemit_modru(out, ext); \
2378 bemit8(offset); \
2379 } \
2380 } else { \
2381 bemit8(0xD3); \
2382 bemit_modru(out, ext); \
2383 } \
2384 } \
2385 \
2386 static void bemit_##op##mem(const ir_node *node) \
2387 { \
2388 ir_node *count; \
2389 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2390 if (size == 16) \
2391 bemit8(0x66); \
2392 count = get_irn_n(node, 1); \
2393 if (is_ia32_Immediate(count)) { \
2394 int offset = get_ia32_immediate_attr_const(count)->offset; \
2395 if (offset == 1) { \
2396 bemit8(size == 8 ? 0xD0 : 0xD1); \
2397 bemit_mod_am(ext, node); \
2398 } else { \
2399 bemit8(size == 8 ? 0xC0 : 0xC1); \
2400 bemit_mod_am(ext, node); \
2401 bemit8(offset); \
2402 } \
2403 } else { \
2404 bemit8(size == 8 ? 0xD2 : 0xD3); \
2405 bemit_mod_am(ext, node); \
2406 } \
2407 }
2408
2409 SHIFT(rol, 0)
2410 SHIFT(ror, 1)
2411 SHIFT(shl, 4)
2412 SHIFT(shr, 5)
2413 SHIFT(sar, 7)
2414
bemit_shld(const ir_node * node)2415 static void bemit_shld(const ir_node *node)
2416 {
2417 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShlD_val_low);
2418 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShlD_res);
2419 ir_node *count = get_irn_n(node, n_ia32_ShlD_count);
2420 bemit8(0x0F);
2421 if (is_ia32_Immediate(count)) {
2422 bemit8(0xA4);
2423 bemit_modrr(out, in);
2424 bemit8(get_ia32_immediate_attr_const(count)->offset);
2425 } else {
2426 bemit8(0xA5);
2427 bemit_modrr(out, in);
2428 }
2429 }
2430
bemit_shrd(const ir_node * node)2431 static void bemit_shrd(const ir_node *node)
2432 {
2433 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShrD_val_low);
2434 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShrD_res);
2435 ir_node *count = get_irn_n(node, n_ia32_ShrD_count);
2436 bemit8(0x0F);
2437 if (is_ia32_Immediate(count)) {
2438 bemit8(0xAC);
2439 bemit_modrr(out, in);
2440 bemit8(get_ia32_immediate_attr_const(count)->offset);
2441 } else {
2442 bemit8(0xAD);
2443 bemit_modrr(out, in);
2444 }
2445 }
2446
bemit_sbb0(ir_node const * const node)2447 static void bemit_sbb0(ir_node const *const node)
2448 {
2449 arch_register_t const *const out = arch_get_irn_register_out(node, pn_ia32_Sbb0_res);
2450 unsigned char const reg = reg_gp_map[out->index];
2451 bemit8(0x1B);
2452 bemit8(MOD_REG | ENC_REG(reg) | ENC_RM(reg));
2453 }
2454
2455 /**
2456 * binary emitter for setcc.
2457 */
bemit_setcc(const ir_node * node)2458 static void bemit_setcc(const ir_node *node)
2459 {
2460 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
2461
2462 ia32_condition_code_t cc = get_ia32_condcode(node);
2463 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
2464 if (cc & ia32_cc_float_parity_cases) {
2465 if (cc & ia32_cc_negated) {
2466 /* set%PNC <dreg */
2467 bemit8(0x0F);
2468 bemit8(0x90 | pnc2cc(cc));
2469 bemit_modrm8(REG_LOW, dreg);
2470
2471 /* setp >dreg */
2472 bemit8(0x0F);
2473 bemit8(0x9A);
2474 bemit_modrm8(REG_HIGH, dreg);
2475
2476 /* orb %>dreg, %<dreg */
2477 bemit8(0x08);
2478 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2479 } else {
2480 /* set%PNC <dreg */
2481 bemit8(0x0F);
2482 bemit8(0x90 | pnc2cc(cc));
2483 bemit_modrm8(REG_LOW, dreg);
2484
2485 /* setnp >dreg */
2486 bemit8(0x0F);
2487 bemit8(0x9B);
2488 bemit_modrm8(REG_HIGH, dreg);
2489
2490 /* andb %>dreg, %<dreg */
2491 bemit8(0x20);
2492 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2493 }
2494 } else {
2495 /* set%PNC <dreg */
2496 bemit8(0x0F);
2497 bemit8(0x90 | pnc2cc(cc));
2498 bemit_modrm8(REG_LOW, dreg);
2499 }
2500 }
2501
bemit_bsf(ir_node const * const node)2502 static void bemit_bsf(ir_node const *const node)
2503 {
2504 bemit_0f_unop_reg(node, 0xBC, n_ia32_Bsf_operand);
2505 }
2506
bemit_bsr(ir_node const * const node)2507 static void bemit_bsr(ir_node const *const node)
2508 {
2509 bemit_0f_unop_reg(node, 0xBD, n_ia32_Bsr_operand);
2510 }
2511
bemit_bswap(ir_node const * const node)2512 static void bemit_bswap(ir_node const *const node)
2513 {
2514 bemit8(0x0F);
2515 bemit_modru(arch_get_irn_register_out(node, pn_ia32_Bswap_res), 1);
2516 }
2517
bemit_bt(ir_node const * const node)2518 static void bemit_bt(ir_node const *const node)
2519 {
2520 bemit8(0x0F);
2521 arch_register_t const *const lreg = arch_get_irn_register_in(node, n_ia32_Bt_left);
2522 ir_node const *const right = get_irn_n(node, n_ia32_Bt_right);
2523 if (is_ia32_Immediate(right)) {
2524 ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(right);
2525 int const offset = attr->offset;
2526 assert(!attr->symconst);
2527 assert(get_signed_imm_size(offset) == 1);
2528 bemit8(0xBA);
2529 bemit_modru(lreg, 4);
2530 bemit8(offset);
2531 } else {
2532 bemit8(0xA3);
2533 bemit_modrr(lreg, arch_get_irn_register(right));
2534 }
2535 }
2536
bemit_cmovcc(const ir_node * node)2537 static void bemit_cmovcc(const ir_node *node)
2538 {
2539 const ia32_attr_t *attr = get_ia32_attr_const(node);
2540 int ins_permuted = attr->data.ins_permuted;
2541 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
2542 ia32_condition_code_t cc = get_ia32_condcode(node);
2543 const arch_register_t *in_true;
2544 const arch_register_t *in_false;
2545
2546 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
2547
2548 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
2549 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
2550
2551 /* should be same constraint fullfilled? */
2552 if (out == in_false) {
2553 /* yes -> nothing to do */
2554 } else if (out == in_true) {
2555 assert(get_ia32_op_type(node) == ia32_Normal);
2556 ins_permuted = !ins_permuted;
2557 in_true = in_false;
2558 } else {
2559 /* we need a mov */
2560 bemit8(0x8B); // mov %in_false, %out
2561 bemit_modrr(in_false, out);
2562 }
2563
2564 if (ins_permuted)
2565 cc = ia32_negate_condition_code(cc);
2566
2567 if (cc & ia32_cc_float_parity_cases)
2568 panic("cmov can't handle parity float cases");
2569
2570 bemit8(0x0F);
2571 bemit8(0x40 | pnc2cc(cc));
2572 if (get_ia32_op_type(node) == ia32_Normal) {
2573 bemit_modrr(in_true, out);
2574 } else {
2575 bemit_mod_am(reg_gp_map[out->index], node);
2576 }
2577 }
2578
bemit_cmp(const ir_node * node)2579 static void bemit_cmp(const ir_node *node)
2580 {
2581 unsigned ls_size = get_mode_size_bits(get_ia32_ls_mode(node));
2582 ir_node *right;
2583
2584 if (ls_size == 16)
2585 bemit8(0x66);
2586
2587 right = get_irn_n(node, n_ia32_binary_right);
2588 if (is_ia32_Immediate(right)) {
2589 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2590 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2591 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2592 unsigned size;
2593
2594 if (attr->symconst != NULL) {
2595 size = 4;
2596 } else {
2597 /* check for sign extension */
2598 size = get_signed_imm_size(attr->offset);
2599 }
2600
2601 switch (size) {
2602 case 1:
2603 bemit8(0x81 | SIGNEXT_IMM);
2604 /* cmp has this special mode */
2605 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2606 bemit_mod_am(7, node);
2607 } else {
2608 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2609 bemit_modru(reg, 7);
2610 }
2611 bemit8((unsigned char)attr->offset);
2612 return;
2613 case 2:
2614 case 4:
2615 /* check for eax variant: this variant is shorter for 32bit immediates only */
2616 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2617 bemit8(0x81);
2618 bemit_mod_am(7, node);
2619 } else {
2620 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2621 if (reg->index == REG_GP_EAX) {
2622 bemit8(0x3D);
2623 } else {
2624 bemit8(0x81);
2625 bemit_modru(reg, 7);
2626 }
2627 }
2628 if (ls_size == 16) {
2629 bemit16(attr->offset);
2630 } else {
2631 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2632 }
2633 return;
2634 }
2635 panic("invalid imm size?!?");
2636 } else {
2637 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2638 bemit8(0x3B);
2639 if (get_ia32_op_type(node) == ia32_Normal) {
2640 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2641 bemit_modrr(op2, out);
2642 } else {
2643 bemit_mod_am(reg_gp_map[out->index], node);
2644 }
2645 }
2646 }
2647
bemit_cmp8bit(const ir_node * node)2648 static void bemit_cmp8bit(const ir_node *node)
2649 {
2650 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2651 if (is_ia32_Immediate(right)) {
2652 if (get_ia32_op_type(node) == ia32_Normal) {
2653 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2654 if (out->index == REG_GP_EAX) {
2655 bemit8(0x3C);
2656 } else {
2657 bemit8(0x80);
2658 bemit_modru(out, 7);
2659 }
2660 } else {
2661 bemit8(0x80);
2662 bemit_mod_am(7, node);
2663 }
2664 bemit8(get_ia32_immediate_attr_const(right)->offset);
2665 } else {
2666 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2667 bemit8(0x3A);
2668 if (get_ia32_op_type(node) == ia32_Normal) {
2669 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Cmp_right);
2670 bemit_modrr(out, in);
2671 } else {
2672 bemit_mod_am(reg_gp_map[out->index], node);
2673 }
2674 }
2675 }
2676
bemit_test8bit(const ir_node * node)2677 static void bemit_test8bit(const ir_node *node)
2678 {
2679 ir_node *right = get_irn_n(node, n_ia32_Test8Bit_right);
2680 if (is_ia32_Immediate(right)) {
2681 if (get_ia32_op_type(node) == ia32_Normal) {
2682 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
2683 if (out->index == REG_GP_EAX) {
2684 bemit8(0xA8);
2685 } else {
2686 bemit8(0xF6);
2687 bemit_modru(out, 0);
2688 }
2689 } else {
2690 bemit8(0xF6);
2691 bemit_mod_am(0, node);
2692 }
2693 bemit8(get_ia32_immediate_attr_const(right)->offset);
2694 } else {
2695 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
2696 bemit8(0x84);
2697 if (get_ia32_op_type(node) == ia32_Normal) {
2698 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Test8Bit_right);
2699 bemit_modrr(out, in);
2700 } else {
2701 bemit_mod_am(reg_gp_map[out->index], node);
2702 }
2703 }
2704 }
2705
bemit_imul(const ir_node * node)2706 static void bemit_imul(const ir_node *node)
2707 {
2708 ir_node *right = get_irn_n(node, n_ia32_IMul_right);
2709 /* Do we need the immediate form? */
2710 if (is_ia32_Immediate(right)) {
2711 int imm = get_ia32_immediate_attr_const(right)->offset;
2712 if (get_signed_imm_size(imm) == 1) {
2713 bemit_unop_reg(node, 0x6B, n_ia32_IMul_left);
2714 bemit8(imm);
2715 } else {
2716 bemit_unop_reg(node, 0x69, n_ia32_IMul_left);
2717 bemit32(imm);
2718 }
2719 } else {
2720 bemit_0f_unop_reg(node, 0xAF, n_ia32_IMul_right);
2721 }
2722 }
2723
bemit_dec(const ir_node * node)2724 static void bemit_dec(const ir_node *node)
2725 {
2726 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Dec_res);
2727 bemit8(0x48 + reg_gp_map[out->index]);
2728 }
2729
bemit_inc(const ir_node * node)2730 static void bemit_inc(const ir_node *node)
2731 {
2732 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Inc_res);
2733 bemit8(0x40 + reg_gp_map[out->index]);
2734 }
2735
2736 #define UNOPMEM(op, code, ext) \
2737 static void bemit_##op(const ir_node *node) \
2738 { \
2739 bemit_unop_mem(node, code, ext); \
2740 }
2741
2742 UNOPMEM(notmem, 0xF6, 2)
2743 UNOPMEM(negmem, 0xF6, 3)
2744 UNOPMEM(incmem, 0xFE, 0)
2745 UNOPMEM(decmem, 0xFE, 1)
2746
bemit_ldtls(const ir_node * node)2747 static void bemit_ldtls(const ir_node *node)
2748 {
2749 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2750
2751 bemit8(0x65); // gs:
2752 if (out->index == REG_GP_EAX) {
2753 bemit8(0xA1); // movl 0, %eax
2754 } else {
2755 bemit8(0x8B); // movl 0, %reg
2756 bemit8(MOD_IND | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x05));
2757 }
2758 bemit32(0);
2759 }
2760
2761 /**
2762 * Emit a Lea.
2763 */
bemit_lea(const ir_node * node)2764 static void bemit_lea(const ir_node *node)
2765 {
2766 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2767 bemit8(0x8D);
2768 bemit_mod_am(reg_gp_map[out->index], node);
2769 }
2770
2771 /* helper function for bemit_minus64bit */
bemit_helper_mov(const arch_register_t * src,const arch_register_t * dst)2772 static void bemit_helper_mov(const arch_register_t *src, const arch_register_t *dst)
2773 {
2774 bemit8(0x8B); // movl %src, %dst
2775 bemit_modrr(src, dst);
2776 }
2777
2778 /* helper function for bemit_minus64bit */
bemit_helper_neg(const arch_register_t * reg)2779 static void bemit_helper_neg(const arch_register_t *reg)
2780 {
2781 bemit8(0xF7); // negl %reg
2782 bemit_modru(reg, 3);
2783 }
2784
2785 /* helper function for bemit_minus64bit */
bemit_helper_sbb0(const arch_register_t * reg)2786 static void bemit_helper_sbb0(const arch_register_t *reg)
2787 {
2788 bemit8(0x83); // sbbl $0, %reg
2789 bemit_modru(reg, 3);
2790 bemit8(0);
2791 }
2792
2793 /* helper function for bemit_minus64bit */
bemit_helper_sbb(const arch_register_t * src,const arch_register_t * dst)2794 static void bemit_helper_sbb(const arch_register_t *src, const arch_register_t *dst)
2795 {
2796 bemit8(0x1B); // sbbl %src, %dst
2797 bemit_modrr(src, dst);
2798 }
2799
2800 /* helper function for bemit_minus64bit */
bemit_helper_xchg(const arch_register_t * src,const arch_register_t * dst)2801 static void bemit_helper_xchg(const arch_register_t *src, const arch_register_t *dst)
2802 {
2803 if (src->index == REG_GP_EAX) {
2804 bemit8(0x90 + reg_gp_map[dst->index]); // xchgl %eax, %dst
2805 } else if (dst->index == REG_GP_EAX) {
2806 bemit8(0x90 + reg_gp_map[src->index]); // xchgl %src, %eax
2807 } else {
2808 bemit8(0x87); // xchgl %src, %dst
2809 bemit_modrr(src, dst);
2810 }
2811 }
2812
2813 /* helper function for bemit_minus64bit */
bemit_helper_zero(const arch_register_t * reg)2814 static void bemit_helper_zero(const arch_register_t *reg)
2815 {
2816 bemit8(0x33); // xorl %reg, %reg
2817 bemit_modrr(reg, reg);
2818 }
2819
bemit_minus64bit(const ir_node * node)2820 static void bemit_minus64bit(const ir_node *node)
2821 {
2822 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
2823 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
2824 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
2825 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
2826
2827 if (out_lo == in_lo) {
2828 if (out_hi != in_hi) {
2829 /* a -> a, b -> d */
2830 goto zero_neg;
2831 } else {
2832 /* a -> a, b -> b */
2833 goto normal_neg;
2834 }
2835 } else if (out_lo == in_hi) {
2836 if (out_hi == in_lo) {
2837 /* a -> b, b -> a */
2838 bemit_helper_xchg(in_lo, in_hi);
2839 goto normal_neg;
2840 } else {
2841 /* a -> b, b -> d */
2842 bemit_helper_mov(in_hi, out_hi);
2843 bemit_helper_mov(in_lo, out_lo);
2844 goto normal_neg;
2845 }
2846 } else {
2847 if (out_hi == in_lo) {
2848 /* a -> c, b -> a */
2849 bemit_helper_mov(in_lo, out_lo);
2850 goto zero_neg;
2851 } else if (out_hi == in_hi) {
2852 /* a -> c, b -> b */
2853 bemit_helper_mov(in_lo, out_lo);
2854 goto normal_neg;
2855 } else {
2856 /* a -> c, b -> d */
2857 bemit_helper_mov(in_lo, out_lo);
2858 goto zero_neg;
2859 }
2860 }
2861
2862 normal_neg:
2863 bemit_helper_neg( out_hi);
2864 bemit_helper_neg( out_lo);
2865 bemit_helper_sbb0(out_hi);
2866 return;
2867
2868 zero_neg:
2869 bemit_helper_zero(out_hi);
2870 bemit_helper_neg( out_lo);
2871 bemit_helper_sbb( in_hi, out_hi);
2872 }
2873
2874 /**
2875 * Emit a single opcode.
2876 */
2877 #define EMIT_SINGLEOP(op, code) \
2878 static void bemit_ ## op(const ir_node *node) { \
2879 (void) node; \
2880 bemit8(code); \
2881 }
2882
2883 //EMIT_SINGLEOP(daa, 0x27)
2884 //EMIT_SINGLEOP(das, 0x2F)
2885 //EMIT_SINGLEOP(aaa, 0x37)
2886 //EMIT_SINGLEOP(aas, 0x3F)
2887 //EMIT_SINGLEOP(nop, 0x90)
2888 EMIT_SINGLEOP(cwtl, 0x98)
2889 EMIT_SINGLEOP(cltd, 0x99)
2890 //EMIT_SINGLEOP(fwait, 0x9B)
2891 EMIT_SINGLEOP(sahf, 0x9E)
2892 //EMIT_SINGLEOP(popf, 0x9D)
2893 EMIT_SINGLEOP(leave, 0xC9)
2894 EMIT_SINGLEOP(int3, 0xCC)
2895 //EMIT_SINGLEOP(iret, 0xCF)
2896 //EMIT_SINGLEOP(xlat, 0xD7)
2897 //EMIT_SINGLEOP(lock, 0xF0)
2898 EMIT_SINGLEOP(rep, 0xF3)
2899 //EMIT_SINGLEOP(halt, 0xF4)
2900 EMIT_SINGLEOP(cmc, 0xF5)
2901 EMIT_SINGLEOP(stc, 0xF9)
2902 //EMIT_SINGLEOP(cli, 0xFA)
2903 //EMIT_SINGLEOP(sti, 0xFB)
2904 //EMIT_SINGLEOP(std, 0xFD)
2905
2906 /**
2907 * Emits a MOV out, [MEM].
2908 */
bemit_load(const ir_node * node)2909 static void bemit_load(const ir_node *node)
2910 {
2911 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2912
2913 if (out->index == REG_GP_EAX) {
2914 ir_node *base = get_irn_n(node, n_ia32_base);
2915 int has_base = !is_ia32_NoReg_GP(base);
2916 ir_node *idx = get_irn_n(node, n_ia32_index);
2917 int has_index = !is_ia32_NoReg_GP(idx);
2918 if (!has_base && !has_index) {
2919 ir_entity *ent = get_ia32_am_sc(node);
2920 int offs = get_ia32_am_offs_int(node);
2921 /* load from constant address to EAX can be encoded
2922 as 0xA1 [offset] */
2923 bemit8(0xA1);
2924 bemit_entity(ent, 0, offs, false);
2925 return;
2926 }
2927 }
2928 bemit8(0x8B);
2929 bemit_mod_am(reg_gp_map[out->index], node);
2930 }
2931
2932 /**
2933 * Emits a MOV [mem], in.
2934 */
bemit_store(const ir_node * node)2935 static void bemit_store(const ir_node *node)
2936 {
2937 const ir_node *value = get_irn_n(node, n_ia32_Store_val);
2938 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2939
2940 if (is_ia32_Immediate(value)) {
2941 if (size == 8) {
2942 bemit8(0xC6);
2943 bemit_mod_am(0, node);
2944 bemit8(get_ia32_immediate_attr_const(value)->offset);
2945 } else if (size == 16) {
2946 bemit8(0x66);
2947 bemit8(0xC7);
2948 bemit_mod_am(0, node);
2949 bemit16(get_ia32_immediate_attr_const(value)->offset);
2950 } else {
2951 bemit8(0xC7);
2952 bemit_mod_am(0, node);
2953 bemit_immediate(value, false);
2954 }
2955 } else {
2956 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Store_val);
2957
2958 if (in->index == REG_GP_EAX) {
2959 ir_node *base = get_irn_n(node, n_ia32_base);
2960 int has_base = !is_ia32_NoReg_GP(base);
2961 ir_node *idx = get_irn_n(node, n_ia32_index);
2962 int has_index = !is_ia32_NoReg_GP(idx);
2963 if (!has_base && !has_index) {
2964 ir_entity *ent = get_ia32_am_sc(node);
2965 int offs = get_ia32_am_offs_int(node);
2966 /* store to constant address from EAX can be encoded as
2967 * 0xA2/0xA3 [offset]*/
2968 if (size == 8) {
2969 bemit8(0xA2);
2970 } else {
2971 if (size == 16)
2972 bemit8(0x66);
2973 bemit8(0xA3);
2974 }
2975 bemit_entity(ent, 0, offs, false);
2976 return;
2977 }
2978 }
2979
2980 if (size == 8) {
2981 bemit8(0x88);
2982 } else {
2983 if (size == 16)
2984 bemit8(0x66);
2985 bemit8(0x89);
2986 }
2987 bemit_mod_am(reg_gp_map[in->index], node);
2988 }
2989 }
2990
bemit_conv_i2i(const ir_node * node)2991 static void bemit_conv_i2i(const ir_node *node)
2992 {
2993 /* 8 16 bit source
2994 * movzx B6 B7
2995 * movsx BE BF */
2996 ir_mode *const smaller_mode = get_ia32_ls_mode(node);
2997 unsigned opcode = 0xB6;
2998 if (mode_is_signed(smaller_mode)) opcode |= 0x08;
2999 if (get_mode_size_bits(smaller_mode) == 16) opcode |= 0x01;
3000 bemit_0f_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
3001 }
3002
bemit_popcnt(ir_node const * const node)3003 static void bemit_popcnt(ir_node const *const node)
3004 {
3005 bemit8(0xF3);
3006 bemit_0f_unop_reg(node, 0xB8, n_ia32_Popcnt_operand);
3007 }
3008
3009 /**
3010 * Emit a Push.
3011 */
bemit_push(const ir_node * node)3012 static void bemit_push(const ir_node *node)
3013 {
3014 const ir_node *value = get_irn_n(node, n_ia32_Push_val);
3015
3016 if (is_ia32_Immediate(value)) {
3017 const ia32_immediate_attr_t *attr
3018 = get_ia32_immediate_attr_const(value);
3019 unsigned size = get_signed_imm_size(attr->offset);
3020 if (attr->symconst)
3021 size = 4;
3022 switch (size) {
3023 case 1:
3024 bemit8(0x6A);
3025 bemit8((unsigned char)attr->offset);
3026 break;
3027 case 2:
3028 case 4:
3029 bemit8(0x68);
3030 bemit_immediate(value, false);
3031 break;
3032 }
3033 } else if (is_ia32_NoReg_GP(value)) {
3034 bemit8(0xFF);
3035 bemit_mod_am(6, node);
3036 } else {
3037 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_Push_val);
3038 bemit8(0x50 + reg_gp_map[reg->index]);
3039 }
3040 }
3041
3042 /**
3043 * Emit a Pop.
3044 */
bemit_pop(const ir_node * node)3045 static void bemit_pop(const ir_node *node)
3046 {
3047 const arch_register_t *reg = arch_get_irn_register_out(node, pn_ia32_Pop_res);
3048 bemit8(0x58 + reg_gp_map[reg->index]);
3049 }
3050
bemit_popmem(const ir_node * node)3051 static void bemit_popmem(const ir_node *node)
3052 {
3053 bemit8(0x8F);
3054 bemit_mod_am(0, node);
3055 }
3056
bemit_call(const ir_node * node)3057 static void bemit_call(const ir_node *node)
3058 {
3059 ir_node *proc = get_irn_n(node, n_ia32_Call_addr);
3060
3061 if (is_ia32_Immediate(proc)) {
3062 bemit8(0xE8);
3063 bemit_immediate(proc, true);
3064 } else {
3065 bemit_unop(node, 0xFF, 2, n_ia32_Call_addr);
3066 }
3067 }
3068
bemit_jmp(const ir_node * dest_block)3069 static void bemit_jmp(const ir_node *dest_block)
3070 {
3071 bemit8(0xE9);
3072 bemit_jmp_destination(dest_block);
3073 }
3074
bemit_jump(const ir_node * node)3075 static void bemit_jump(const ir_node *node)
3076 {
3077 if (can_be_fallthrough(node))
3078 return;
3079
3080 bemit_jmp(get_cfop_target_block(node));
3081 }
3082
bemit_jcc(ia32_condition_code_t pnc,const ir_node * dest_block)3083 static void bemit_jcc(ia32_condition_code_t pnc, const ir_node *dest_block)
3084 {
3085 unsigned char cc = pnc2cc(pnc);
3086 bemit8(0x0F);
3087 bemit8(0x80 + cc);
3088 bemit_jmp_destination(dest_block);
3089 }
3090
bemit_jp(bool odd,const ir_node * dest_block)3091 static void bemit_jp(bool odd, const ir_node *dest_block)
3092 {
3093 bemit8(0x0F);
3094 bemit8(0x8A + odd);
3095 bemit_jmp_destination(dest_block);
3096 }
3097
bemit_ia32_jcc(const ir_node * node)3098 static void bemit_ia32_jcc(const ir_node *node)
3099 {
3100 ia32_condition_code_t cc = get_ia32_condcode(node);
3101 const ir_node *proj_true;
3102 const ir_node *proj_false;
3103 const ir_node *dest_true;
3104 const ir_node *dest_false;
3105
3106 cc = determine_final_cc(node, 0, cc);
3107
3108 /* get both Projs */
3109 proj_true = get_proj(node, pn_ia32_Jcc_true);
3110 assert(proj_true && "Jcc without true Proj");
3111
3112 proj_false = get_proj(node, pn_ia32_Jcc_false);
3113 assert(proj_false && "Jcc without false Proj");
3114
3115 if (can_be_fallthrough(proj_true)) {
3116 /* exchange both proj's so the second one can be omitted */
3117 const ir_node *t = proj_true;
3118
3119 proj_true = proj_false;
3120 proj_false = t;
3121 cc = ia32_negate_condition_code(cc);
3122 }
3123
3124 dest_true = get_cfop_target_block(proj_true);
3125 dest_false = get_cfop_target_block(proj_false);
3126
3127 if (cc & ia32_cc_float_parity_cases) {
3128 /* Some floating point comparisons require a test of the parity flag,
3129 * which indicates that the result is unordered */
3130 if (cc & ia32_cc_negated) {
3131 bemit_jp(false, dest_true);
3132 } else {
3133 /* we need a local label if the false proj is a fallthrough
3134 * as the falseblock might have no label emitted then */
3135 if (can_be_fallthrough(proj_false)) {
3136 bemit8(0x7A);
3137 bemit8(0x06); // jp + 6
3138 } else {
3139 bemit_jp(false, dest_false);
3140 }
3141 }
3142 }
3143 bemit_jcc(cc, dest_true);
3144
3145 /* the second Proj might be a fallthrough */
3146 if (can_be_fallthrough(proj_false)) {
3147 /* it's a fallthrough */
3148 } else {
3149 bemit_jmp(dest_false);
3150 }
3151 }
3152
bemit_switchjmp(const ir_node * node)3153 static void bemit_switchjmp(const ir_node *node)
3154 {
3155 ir_entity *jump_table = get_ia32_am_sc(node);
3156 const ir_switch_table *table = get_ia32_switch_table(node);
3157
3158 bemit8(0xFF); // jmp *tbl.label(,%in,4)
3159 bemit_mod_am(0x05, node);
3160
3161 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
3162 }
3163
3164 /**
3165 * Emits a return.
3166 */
bemit_return(const ir_node * node)3167 static void bemit_return(const ir_node *node)
3168 {
3169 unsigned pop = be_Return_get_pop(node);
3170 if (pop > 0 || be_Return_get_emit_pop(node)) {
3171 bemit8(0xC2);
3172 assert(pop <= 0xffff);
3173 bemit16(pop);
3174 } else {
3175 bemit8(0xC3);
3176 }
3177 }
3178
bemit_subsp(const ir_node * node)3179 static void bemit_subsp(const ir_node *node)
3180 {
3181 const arch_register_t *out;
3182 /* sub %in, %esp */
3183 bemit_sub(node);
3184 /* mov %esp, %out */
3185 bemit8(0x8B);
3186 out = arch_get_irn_register_out(node, 1);
3187 bemit8(MOD_REG | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x04));
3188 }
3189
bemit_incsp(const ir_node * node)3190 static void bemit_incsp(const ir_node *node)
3191 {
3192 int offs;
3193 const arch_register_t *reg;
3194 unsigned size;
3195 unsigned ext;
3196
3197 offs = be_get_IncSP_offset(node);
3198 if (offs == 0)
3199 return;
3200
3201 if (offs > 0) {
3202 ext = 5; /* sub */
3203 } else {
3204 ext = 0; /* add */
3205 offs = -offs;
3206 }
3207
3208 size = get_signed_imm_size(offs);
3209 bemit8(size == 1 ? 0x83 : 0x81);
3210
3211 reg = arch_get_irn_register_out(node, 0);
3212 bemit_modru(reg, ext);
3213
3214 if (size == 1) {
3215 bemit8(offs);
3216 } else {
3217 bemit32(offs);
3218 }
3219 }
3220
bemit_copybi(const ir_node * node)3221 static void bemit_copybi(const ir_node *node)
3222 {
3223 unsigned size = get_ia32_copyb_size(node);
3224 if (size & 1)
3225 bemit8(0xA4); // movsb
3226 if (size & 2) {
3227 bemit8(0x66);
3228 bemit8(0xA5); // movsw
3229 }
3230 size >>= 2;
3231 while (size--) {
3232 bemit8(0xA5); // movsl
3233 }
3234 }
3235
bemit_fbinop(ir_node const * const node,unsigned const op_fwd,unsigned const op_rev)3236 static void bemit_fbinop(ir_node const *const node, unsigned const op_fwd, unsigned const op_rev)
3237 {
3238 ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
3239 unsigned const op = attr->attr.data.ins_permuted ? op_rev : op_fwd;
3240 if (get_ia32_op_type(node) == ia32_Normal) {
3241 assert(!attr->pop || attr->res_in_reg);
3242
3243 unsigned char op0 = 0xD8;
3244 if (attr->res_in_reg) op0 |= 0x04;
3245 if (attr->pop) op0 |= 0x02;
3246 bemit8(op0);
3247
3248 bemit8(MOD_REG | ENC_REG(op) | ENC_RM(attr->reg->index));
3249 } else {
3250 assert(!attr->reg);
3251 assert(!attr->pop);
3252
3253 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3254 bemit8(size == 32 ? 0xD8 : 0xDC);
3255 bemit_mod_am(op, node);
3256 }
3257 }
3258
bemit_fop_reg(ir_node const * const node,unsigned char const op0,unsigned char const op1)3259 static void bemit_fop_reg(ir_node const *const node, unsigned char const op0, unsigned char const op1)
3260 {
3261 bemit8(op0);
3262 bemit8(op1 + get_ia32_x87_attr_const(node)->reg->index);
3263 }
3264
bemit_fabs(const ir_node * node)3265 static void bemit_fabs(const ir_node *node)
3266 {
3267 (void)node;
3268
3269 bemit8(0xD9);
3270 bemit8(0xE1);
3271 }
3272
bemit_fadd(const ir_node * node)3273 static void bemit_fadd(const ir_node *node)
3274 {
3275 bemit_fbinop(node, 0, 0);
3276 }
3277
bemit_fchs(const ir_node * node)3278 static void bemit_fchs(const ir_node *node)
3279 {
3280 (void)node;
3281
3282 bemit8(0xD9);
3283 bemit8(0xE0);
3284 }
3285
bemit_fdiv(const ir_node * node)3286 static void bemit_fdiv(const ir_node *node)
3287 {
3288 bemit_fbinop(node, 6, 7);
3289 }
3290
bemit_ffreep(ir_node const * const node)3291 static void bemit_ffreep(ir_node const *const node)
3292 {
3293 bemit_fop_reg(node, 0xDF, 0xC0);
3294 }
3295
bemit_fild(const ir_node * node)3296 static void bemit_fild(const ir_node *node)
3297 {
3298 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3299 case 16:
3300 bemit8(0xDF); // filds
3301 bemit_mod_am(0, node);
3302 return;
3303
3304 case 32:
3305 bemit8(0xDB); // fildl
3306 bemit_mod_am(0, node);
3307 return;
3308
3309 case 64:
3310 bemit8(0xDF); // fildll
3311 bemit_mod_am(5, node);
3312 return;
3313
3314 default:
3315 panic("invalid mode size");
3316 }
3317 }
3318
bemit_fist(const ir_node * node)3319 static void bemit_fist(const ir_node *node)
3320 {
3321 unsigned op;
3322 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3323 switch (size) {
3324 case 16: bemit8(0xDF); op = 2; break; // fist[p]s
3325 case 32: bemit8(0xDB); op = 2; break; // fist[p]l
3326 case 64: bemit8(0xDF); op = 6; break; // fistpll
3327 default: panic("invalid mode size");
3328 }
3329 if (get_ia32_x87_attr_const(node)->pop)
3330 ++op;
3331 // There is only a pop variant for 64 bit integer store.
3332 assert(size < 64 || get_ia32_x87_attr_const(node)->pop);
3333 bemit_mod_am(op, node);
3334 }
3335
bemit_fisttp(ir_node const * const node)3336 static void bemit_fisttp(ir_node const *const node)
3337 {
3338 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3339 case 16: bemit8(0xDF); break; // fisttps
3340 case 32: bemit8(0xDB); break; // fisttpl
3341 case 64: bemit8(0xDD); break; // fisttpll
3342 default: panic("Invalid mode size");
3343 }
3344 bemit_mod_am(1, node);
3345 }
3346
bemit_fld(const ir_node * node)3347 static void bemit_fld(const ir_node *node)
3348 {
3349 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3350 case 32:
3351 bemit8(0xD9); // flds
3352 bemit_mod_am(0, node);
3353 return;
3354
3355 case 64:
3356 bemit8(0xDD); // fldl
3357 bemit_mod_am(0, node);
3358 return;
3359
3360 case 80:
3361 case 96:
3362 bemit8(0xDB); // fldt
3363 bemit_mod_am(5, node);
3364 return;
3365
3366 default:
3367 panic("invalid mode size");
3368 }
3369 }
3370
bemit_fld1(const ir_node * node)3371 static void bemit_fld1(const ir_node *node)
3372 {
3373 (void)node;
3374 bemit8(0xD9);
3375 bemit8(0xE8); // fld1
3376 }
3377
bemit_fldcw(const ir_node * node)3378 static void bemit_fldcw(const ir_node *node)
3379 {
3380 bemit8(0xD9); // fldcw
3381 bemit_mod_am(5, node);
3382 }
3383
bemit_fldz(const ir_node * node)3384 static void bemit_fldz(const ir_node *node)
3385 {
3386 (void)node;
3387 bemit8(0xD9);
3388 bemit8(0xEE); // fldz
3389 }
3390
bemit_fmul(const ir_node * node)3391 static void bemit_fmul(const ir_node *node)
3392 {
3393 bemit_fbinop(node, 1, 1);
3394 }
3395
bemit_fpop(const ir_node * node)3396 static void bemit_fpop(const ir_node *node)
3397 {
3398 bemit_fop_reg(node, 0xDD, 0xD8);
3399 }
3400
bemit_fpush(const ir_node * node)3401 static void bemit_fpush(const ir_node *node)
3402 {
3403 bemit_fop_reg(node, 0xD9, 0xC0);
3404 }
3405
bemit_fpushcopy(const ir_node * node)3406 static void bemit_fpushcopy(const ir_node *node)
3407 {
3408 bemit_fop_reg(node, 0xD9, 0xC0);
3409 }
3410
bemit_fst(const ir_node * node)3411 static void bemit_fst(const ir_node *node)
3412 {
3413 unsigned op;
3414 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3415 switch (size) {
3416 case 32: bemit8(0xD9); op = 2; break; // fst[p]s
3417 case 64: bemit8(0xDD); op = 2; break; // fst[p]l
3418 case 80:
3419 case 96: bemit8(0xDB); op = 6; break; // fstpt
3420 default: panic("invalid mode size");
3421 }
3422 if (get_ia32_x87_attr_const(node)->pop)
3423 ++op;
3424 // There is only a pop variant for long double store.
3425 assert(size < 80 || get_ia32_x87_attr_const(node)->pop);
3426 bemit_mod_am(op, node);
3427 }
3428
bemit_fsub(const ir_node * node)3429 static void bemit_fsub(const ir_node *node)
3430 {
3431 bemit_fbinop(node, 4, 5);
3432 }
3433
bemit_fnstcw(const ir_node * node)3434 static void bemit_fnstcw(const ir_node *node)
3435 {
3436 bemit8(0xD9); // fnstcw
3437 bemit_mod_am(7, node);
3438 }
3439
bemit_fnstsw(void)3440 static void bemit_fnstsw(void)
3441 {
3442 bemit8(0xDF); // fnstsw %ax
3443 bemit8(0xE0);
3444 }
3445
bemit_ftstfnstsw(const ir_node * node)3446 static void bemit_ftstfnstsw(const ir_node *node)
3447 {
3448 (void)node;
3449
3450 bemit8(0xD9); // ftst
3451 bemit8(0xE4);
3452 bemit_fnstsw();
3453 }
3454
bemit_fucomi(const ir_node * node)3455 static void bemit_fucomi(const ir_node *node)
3456 {
3457 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3458 bemit8(attr->pop ? 0xDF : 0xDB); // fucom[p]i
3459 bemit8(0xE8 + attr->reg->index);
3460 }
3461
bemit_fucomfnstsw(const ir_node * node)3462 static void bemit_fucomfnstsw(const ir_node *node)
3463 {
3464 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3465 bemit8(0xDD); // fucom[p]
3466 bemit8((attr->pop ? 0xE8 : 0xE0) + attr->reg->index);
3467 bemit_fnstsw();
3468 }
3469
bemit_fucomppfnstsw(const ir_node * node)3470 static void bemit_fucomppfnstsw(const ir_node *node)
3471 {
3472 (void)node;
3473
3474 bemit8(0xDA); // fucompp
3475 bemit8(0xE9);
3476 bemit_fnstsw();
3477 }
3478
bemit_fxch(const ir_node * node)3479 static void bemit_fxch(const ir_node *node)
3480 {
3481 bemit_fop_reg(node, 0xD9, 0xC8);
3482 }
3483
3484 /**
3485 * The type of a emitter function.
3486 */
3487 typedef void (*emit_func) (const ir_node *);
3488
3489 /**
3490 * Set a node emitter. Make it a bit more type safe.
3491 */
register_emitter(ir_op * op,emit_func func)3492 static void register_emitter(ir_op *op, emit_func func)
3493 {
3494 op->ops.generic = (op_func) func;
3495 }
3496
ia32_register_binary_emitters(void)3497 static void ia32_register_binary_emitters(void)
3498 {
3499 /* first clear the generic function pointer for all ops */
3500 ir_clear_opcodes_generic_func();
3501
3502 /* benode emitter */
3503 register_emitter(op_be_Copy, bemit_copy);
3504 register_emitter(op_be_CopyKeep, bemit_copy);
3505 register_emitter(op_be_IncSP, bemit_incsp);
3506 register_emitter(op_be_Perm, bemit_perm);
3507 register_emitter(op_be_Return, bemit_return);
3508 register_emitter(op_ia32_Adc, bemit_adc);
3509 register_emitter(op_ia32_Add, bemit_add);
3510 register_emitter(op_ia32_AddMem, bemit_addmem);
3511 register_emitter(op_ia32_AddMem8Bit, bemit_addmem8bit);
3512 register_emitter(op_ia32_And, bemit_and);
3513 register_emitter(op_ia32_AndMem, bemit_andmem);
3514 register_emitter(op_ia32_AndMem8Bit, bemit_andmem8bit);
3515 register_emitter(op_ia32_Asm, emit_ia32_Asm); // TODO implement binary emitter
3516 register_emitter(op_ia32_Breakpoint, bemit_int3);
3517 register_emitter(op_ia32_Bsf, bemit_bsf);
3518 register_emitter(op_ia32_Bsr, bemit_bsr);
3519 register_emitter(op_ia32_Bswap, bemit_bswap);
3520 register_emitter(op_ia32_Bt, bemit_bt);
3521 register_emitter(op_ia32_CMovcc, bemit_cmovcc);
3522 register_emitter(op_ia32_Call, bemit_call);
3523 register_emitter(op_ia32_Cltd, bemit_cltd);
3524 register_emitter(op_ia32_Cmc, bemit_cmc);
3525 register_emitter(op_ia32_Cmp, bemit_cmp);
3526 register_emitter(op_ia32_Cmp8Bit, bemit_cmp8bit);
3527 register_emitter(op_ia32_Const, bemit_mov_const);
3528 register_emitter(op_ia32_Conv_I2I, bemit_conv_i2i);
3529 register_emitter(op_ia32_Conv_I2I8Bit, bemit_conv_i2i);
3530 register_emitter(op_ia32_CopyB_i, bemit_copybi);
3531 register_emitter(op_ia32_Cwtl, bemit_cwtl);
3532 register_emitter(op_ia32_Dec, bemit_dec);
3533 register_emitter(op_ia32_DecMem, bemit_decmem);
3534 register_emitter(op_ia32_Div, bemit_div);
3535 register_emitter(op_ia32_FldCW, bemit_fldcw);
3536 register_emitter(op_ia32_FnstCW, bemit_fnstcw);
3537 register_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw);
3538 register_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw);
3539 register_emitter(op_ia32_Fucomi, bemit_fucomi);
3540 register_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw);
3541 register_emitter(op_ia32_IDiv, bemit_idiv);
3542 register_emitter(op_ia32_IJmp, bemit_ijmp);
3543 register_emitter(op_ia32_IMul, bemit_imul);
3544 register_emitter(op_ia32_IMul1OP, bemit_imul1op);
3545 register_emitter(op_ia32_Inc, bemit_inc);
3546 register_emitter(op_ia32_IncMem, bemit_incmem);
3547 register_emitter(op_ia32_Jcc, bemit_ia32_jcc);
3548 register_emitter(op_ia32_Jmp, bemit_jump);
3549 register_emitter(op_ia32_LdTls, bemit_ldtls);
3550 register_emitter(op_ia32_Lea, bemit_lea);
3551 register_emitter(op_ia32_Leave, bemit_leave);
3552 register_emitter(op_ia32_Load, bemit_load);
3553 register_emitter(op_ia32_Minus64Bit, bemit_minus64bit);
3554 register_emitter(op_ia32_Mul, bemit_mul);
3555 register_emitter(op_ia32_Neg, bemit_neg);
3556 register_emitter(op_ia32_NegMem, bemit_negmem);
3557 register_emitter(op_ia32_Not, bemit_not);
3558 register_emitter(op_ia32_NotMem, bemit_notmem);
3559 register_emitter(op_ia32_Or, bemit_or);
3560 register_emitter(op_ia32_OrMem, bemit_ormem);
3561 register_emitter(op_ia32_OrMem8Bit, bemit_ormem8bit);
3562 register_emitter(op_ia32_Pop, bemit_pop);
3563 register_emitter(op_ia32_PopEbp, bemit_pop);
3564 register_emitter(op_ia32_PopMem, bemit_popmem);
3565 register_emitter(op_ia32_Popcnt, bemit_popcnt);
3566 register_emitter(op_ia32_Push, bemit_push);
3567 register_emitter(op_ia32_RepPrefix, bemit_rep);
3568 register_emitter(op_ia32_Rol, bemit_rol);
3569 register_emitter(op_ia32_RolMem, bemit_rolmem);
3570 register_emitter(op_ia32_Ror, bemit_ror);
3571 register_emitter(op_ia32_RorMem, bemit_rormem);
3572 register_emitter(op_ia32_Sahf, bemit_sahf);
3573 register_emitter(op_ia32_Sar, bemit_sar);
3574 register_emitter(op_ia32_SarMem, bemit_sarmem);
3575 register_emitter(op_ia32_Sbb, bemit_sbb);
3576 register_emitter(op_ia32_Sbb0, bemit_sbb0);
3577 register_emitter(op_ia32_Setcc, bemit_setcc);
3578 register_emitter(op_ia32_Shl, bemit_shl);
3579 register_emitter(op_ia32_ShlD, bemit_shld);
3580 register_emitter(op_ia32_ShlMem, bemit_shlmem);
3581 register_emitter(op_ia32_Shr, bemit_shr);
3582 register_emitter(op_ia32_ShrD, bemit_shrd);
3583 register_emitter(op_ia32_ShrMem, bemit_shrmem);
3584 register_emitter(op_ia32_Stc, bemit_stc);
3585 register_emitter(op_ia32_Store, bemit_store);
3586 register_emitter(op_ia32_Store8Bit, bemit_store);
3587 register_emitter(op_ia32_Sub, bemit_sub);
3588 register_emitter(op_ia32_SubMem, bemit_submem);
3589 register_emitter(op_ia32_SubMem8Bit, bemit_submem8bit);
3590 register_emitter(op_ia32_SubSP, bemit_subsp);
3591 register_emitter(op_ia32_SwitchJmp, bemit_switchjmp);
3592 register_emitter(op_ia32_Test, bemit_test);
3593 register_emitter(op_ia32_Test8Bit, bemit_test8bit);
3594 register_emitter(op_ia32_Xor, bemit_xor);
3595 register_emitter(op_ia32_Xor0, bemit_xor0);
3596 register_emitter(op_ia32_XorMem, bemit_xormem);
3597 register_emitter(op_ia32_XorMem8Bit, bemit_xormem8bit);
3598 register_emitter(op_ia32_fabs, bemit_fabs);
3599 register_emitter(op_ia32_fadd, bemit_fadd);
3600 register_emitter(op_ia32_fchs, bemit_fchs);
3601 register_emitter(op_ia32_fdiv, bemit_fdiv);
3602 register_emitter(op_ia32_ffreep, bemit_ffreep);
3603 register_emitter(op_ia32_fild, bemit_fild);
3604 register_emitter(op_ia32_fist, bemit_fist);
3605 register_emitter(op_ia32_fisttp, bemit_fisttp);
3606 register_emitter(op_ia32_fld, bemit_fld);
3607 register_emitter(op_ia32_fld1, bemit_fld1);
3608 register_emitter(op_ia32_fldz, bemit_fldz);
3609 register_emitter(op_ia32_fmul, bemit_fmul);
3610 register_emitter(op_ia32_fpop, bemit_fpop);
3611 register_emitter(op_ia32_fpush, bemit_fpush);
3612 register_emitter(op_ia32_fpushCopy, bemit_fpushcopy);
3613 register_emitter(op_ia32_fst, bemit_fst);
3614 register_emitter(op_ia32_fsub, bemit_fsub);
3615 register_emitter(op_ia32_fxch, bemit_fxch);
3616
3617 /* ignore the following nodes */
3618 register_emitter(op_ia32_ProduceVal, emit_Nothing);
3619 register_emitter(op_ia32_Unknown, emit_Nothing);
3620 register_emitter(op_be_Keep, emit_Nothing);
3621 register_emitter(op_be_Start, emit_Nothing);
3622 register_emitter(op_Phi, emit_Nothing);
3623 register_emitter(op_Start, emit_Nothing);
3624 }
3625
gen_binary_block(ir_node * block)3626 static void gen_binary_block(ir_node *block)
3627 {
3628 ia32_emit_block_header(block);
3629
3630 /* emit the contents of the block */
3631 sched_foreach(block, node) {
3632 ia32_emit_node(node);
3633 }
3634 }
3635
ia32_gen_binary_routine(ir_graph * irg)3636 void ia32_gen_binary_routine(ir_graph *irg)
3637 {
3638 ir_entity *entity = get_irg_entity(irg);
3639 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
3640 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
3641 ir_node **blk_sched = irg_data->blk_sched;
3642 size_t i, n;
3643 parameter_dbg_info_t *infos;
3644
3645 isa = (ia32_isa_t*) arch_env;
3646
3647 ia32_register_binary_emitters();
3648
3649 infos = construct_parameter_infos(irg);
3650 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
3651 NULL);
3652 xfree(infos);
3653
3654 /* we use links to point to target blocks */
3655 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
3656 irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
3657
3658 /* initialize next block links */
3659 n = ARR_LEN(blk_sched);
3660 for (i = 0; i < n; ++i) {
3661 ir_node *block = blk_sched[i];
3662 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
3663
3664 set_irn_link(block, prev);
3665 }
3666
3667 for (i = 0; i < n; ++i) {
3668 ir_node *block = blk_sched[i];
3669 gen_binary_block(block);
3670 }
3671
3672 be_gas_emit_function_epilog(entity);
3673
3674 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
3675 }
3676
3677
ia32_init_emitter(void)3678 void ia32_init_emitter(void)
3679 {
3680 lc_opt_entry_t *be_grp;
3681 lc_opt_entry_t *ia32_grp;
3682
3683 be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
3684 ia32_grp = lc_opt_get_grp(be_grp, "ia32");
3685
3686 lc_opt_add_table(ia32_grp, ia32_emitter_options);
3687
3688 build_reg_map();
3689
3690 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");
3691 }
3692