2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief This file implements the ia32 node emitter.
23 * @author Christian Wuerdig, Matthias Braun
25 * Summary table for x86 floatingpoint compares:
26 * (remember effect of unordered on x86: ZF=1, PF=1, CF=1)
34 * pnc_Leg => NP (ordered)
56 #include "iredges_t.h"
60 #include "raw_bitset.h"
69 #include "beemitter.h"
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"
82 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
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;
90 static bool sp_relative;
91 static int frame_type_size;
92 static int callframe_offset;
94 /** Return the next block in Block schedule */
95 static ir_node *get_prev_block_sched(const ir_node *block)
97 return (ir_node*)get_irn_link(block);
100 /** Checks if the current block is a fall-through target. */
101 static int is_fallthrough(const ir_node *cfgpred)
105 if (!is_Proj(cfgpred))
107 pred = get_Proj_pred(cfgpred);
108 if (is_ia32_SwitchJmp(pred))
115 * returns non-zero if the given block needs a label
116 * because of being a jump-target (and not a fall-through)
118 static int block_needs_label(const ir_node *block)
121 int n_cfgpreds = get_Block_n_cfgpreds(block);
123 if (get_Block_entity(block) != NULL)
126 if (n_cfgpreds == 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);
132 if (get_prev_block_sched(block) == cfgpred_block
133 && is_fallthrough(cfgpred)) {
142 * Add a number to a prefix. This number will not be used a second time.
144 static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
146 static unsigned long id = 0;
147 snprintf(buf, buflen, "%s%s%lu", be_gas_get_private_prefix(), prefix, ++id);
152 * Emit the name of the 8bit low register
154 static void emit_8bit_register(const arch_register_t *reg)
156 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
157 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
160 be_emit_char(reg->name[1]); /* get the basic name of the register */
165 * Emit the name of the 8bit high register
167 static void emit_8bit_register_high(const arch_register_t *reg)
169 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
170 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
173 be_emit_char(reg->name[1]); /* get the basic name of the register */
177 static void emit_16bit_register(const arch_register_t *reg)
180 be_emit_string(reg->name + 1); /* skip the 'e' prefix of the 32bit names */
184 * emit a register, possible shortened by a mode
186 * @param reg the register
187 * @param mode the mode of the register or NULL for full register
189 static void emit_register(const arch_register_t *reg, const ir_mode *mode)
192 int size = get_mode_size_bits(mode);
194 case 8: emit_8bit_register(reg); return;
195 case 16: emit_16bit_register(reg); return;
197 assert(mode_is_float(mode) || size == 32);
201 be_emit_string(reg->name);
204 static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
206 be_gas_emit_entity(entity);
208 if (get_entity_owner(entity) == get_tls_type()) {
209 if (!entity_has_definition(entity)) {
210 be_emit_cstring("@INDNTPOFF");
212 be_emit_cstring("@NTPOFF");
216 if (do_pic && !no_pic_adjust) {
218 be_emit_string(pic_base_label);
222 static void emit_ia32_Immediate_no_prefix(const ir_node *node)
224 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
226 if (attr->symconst != NULL) {
229 ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
231 if (attr->symconst == NULL || attr->offset != 0) {
232 if (attr->symconst != NULL) {
233 be_emit_irprintf("%+d", attr->offset);
235 be_emit_irprintf("0x%X", attr->offset);
240 static void emit_ia32_Immediate(const ir_node *node)
243 emit_ia32_Immediate_no_prefix(node);
246 static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
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
255 case 64: be_emit_cstring("ll"); return;
257 panic("Can't output mode_suffix for %+F", mode);
260 static void ia32_emit_x87_mode_suffix(ir_node const *const node)
264 /* we only need to emit the mode on address mode */
265 if (get_ia32_op_type(node) == ia32_Normal)
268 mode = get_ia32_ls_mode(node);
269 assert(mode != NULL);
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
279 case 128: be_emit_char('t'); return;
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
288 case 64: be_emit_cstring("ll"); return;
291 panic("Can't output mode_suffix for %+F", mode);
294 static char get_xmm_mode_suffix(ir_mode *mode)
296 assert(mode_is_float(mode));
297 switch (get_mode_size_bits(mode)) {
300 default: panic("Invalid XMM mode");
304 static void ia32_emit_xmm_mode_suffix(ir_node const *const node)
306 ir_mode *mode = get_ia32_ls_mode(node);
307 assert(mode != NULL);
308 be_emit_char(get_xmm_mode_suffix(mode));
312 * Returns the target block for a control flow node.
314 static ir_node *get_cfop_target_block(const ir_node *irn)
316 assert(get_irn_mode(irn) == mode_X);
317 return (ir_node*)get_irn_link(irn);
321 * Emits the target label for a control flow node.
323 static void ia32_emit_cfop_target(const ir_node *node)
325 ir_node *block = get_cfop_target_block(node);
326 be_gas_emit_block_name(block);
330 * Emit the suffix for a compare instruction.
332 static void ia32_emit_condition_code(ia32_condition_code_t 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:
365 panic("Invalid ia32 condition code");
368 typedef enum ia32_emit_mod_t {
370 EMIT_RESPECT_LS = 1U << 0,
371 EMIT_ALTERNATE_AM = 1U << 1,
373 EMIT_HIGH_REG = 1U << 3,
374 EMIT_LOW_REG = 1U << 4,
375 EMIT_16BIT_REG = 1U << 5
377 ENUM_BITSET(ia32_emit_mod_t)
380 * Emits address mode.
382 static void ia32_emit_am(ir_node const *const node)
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);
391 /* just to be sure... */
392 assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
394 if (get_ia32_am_tls_segment(node))
395 be_emit_cstring("%gs:");
399 const ia32_attr_t *attr = get_ia32_attr_const(node);
400 if (is_ia32_am_sc_sign(node))
402 ia32_emit_entity(ent, attr->data.am_sc_no_pic_adjust);
405 /* also handle special case if nothing is set */
406 if (offs != 0 || (ent == NULL && !has_base && !has_index)) {
408 be_emit_irprintf("%+d", offs);
410 be_emit_irprintf("%d", offs);
414 if (has_base || has_index) {
419 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
420 emit_register(reg, NULL);
423 /* emit index + scale */
425 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
428 emit_register(reg, NULL);
430 scale = get_ia32_am_scale(node);
432 be_emit_irprintf(",%d", 1 << scale);
439 static ia32_condition_code_t determine_final_cc(ir_node const *node, int flags_pos, ia32_condition_code_t cc);
441 void ia32_emitf(ir_node const *const node, char const *fmt, ...)
448 const char *start = fmt;
449 ia32_emit_mod_t mod = EMIT_NONE;
451 while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
454 be_emit_string_len(start, fmt - start);
459 be_emit_write_line();
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;
487 arch_register_t const *reg;
497 if (get_ia32_op_type(node) == ia32_Normal) {
498 ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
499 char const *const fmt = attr->res_in_reg ? "%%st, %%%s" : "%%%s, %%st";
500 be_emit_irprintf(fmt, attr->reg->name);
508 if (mod & EMIT_ALTERNATE_AM)
514 reg = va_arg(ap, const arch_register_t*);
515 if (get_ia32_op_type(node) == ia32_Normal) {
522 if (get_ia32_op_type(node) == ia32_Normal) {
529 default: goto unknown;
535 imm = get_irn_n(node, n_ia32_binary_right);
536 if (is_ia32_Immediate(imm)) {
537 emit_ia32_Immediate(imm);
538 be_emit_cstring(", ");
539 if (get_ia32_op_type(node) == ia32_Normal) {
540 goto destination_operand;
545 if (get_ia32_op_type(node) == ia32_Normal) {
546 reg = arch_get_irn_register_in(node, n_ia32_binary_right);
547 emit_register(reg, get_ia32_ls_mode(node));
551 be_emit_cstring(", ");
553 reg = arch_get_irn_register_in(node, n_ia32_binary_left);
554 emit_register(reg, get_ia32_ls_mode(node));
559 if (*fmt < '0' || '9' < *fmt)
561 reg = arch_get_irn_register_out(node, *fmt++ - '0');
566 ia32_emit_x87_mode_suffix(node);
567 } else if (*fmt == 'P') {
568 ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
571 } else if (*fmt == 'R') {
572 /* NOTE: Work around a gas quirk for non-commutative operations if the
573 * destination register is not %st0. In this case r/non-r is swapped.
574 * %st0 = %st0 - %st1 -> fsub %st1, %st0 (as expected)
575 * %st0 = %st1 - %st0 -> fsubr %st1, %st0 (as expected)
576 * %st1 = %st0 - %st1 -> fsub %st0, %st1 (expected: fsubr)
577 * %st1 = %st1 - %st0 -> fsubr %st0, %st1 (expected: fsub)
578 * In fact this corresponds to the encoding of the instruction:
579 * - The r suffix selects whether %st0 is on the left (no r) or on the
580 * right (r) side of the executed operation.
581 * - The placement of %st0 selects whether the result is written to
582 * %st0 (right) or the other register (left).
583 * This means that it is sufficient to test whether the operands are
584 * permuted. In particular it is not necessary to consider wether the
585 * result is to be placed into the explicit register operand. */
586 if (get_ia32_x87_attr_const(node)->attr.data.ins_permuted)
588 } else if (*fmt == 'X') {
589 ia32_emit_xmm_mode_suffix(node);
590 } else if (*fmt == '0') {
592 be_emit_string(get_ia32_x87_attr_const(node)->reg->name);
602 if (!(mod & EMIT_ALTERNATE_AM))
604 emit_ia32_Immediate_no_prefix(imm);
608 ia32_emit_cfop_target(node);
612 ir_mode *mode = get_ia32_ls_mode(node);
615 if (mod & EMIT_RESPECT_LS) {
616 if (get_mode_size_bits(mode) == 32)
618 be_emit_char(mode_is_signed(mode) ? 's' : 'z');
620 ia32_emit_mode_suffix_mode(mode);
625 ia32_condition_code_t cc;
628 cc = (ia32_condition_code_t)va_arg(ap, int);
629 } else if ('0' <= *fmt && *fmt <= '9') {
630 cc = get_ia32_condcode(node);
631 cc = determine_final_cc(node, *fmt - '0', cc);
636 ia32_emit_condition_code(cc);
641 reg = va_arg(ap, const arch_register_t*);
643 if (mod & EMIT_ALTERNATE_AM)
645 if (mod & EMIT_HIGH_REG) {
646 emit_8bit_register_high(reg);
647 } else if (mod & EMIT_LOW_REG) {
648 emit_8bit_register(reg);
649 } else if (mod & EMIT_16BIT_REG) {
650 emit_16bit_register(reg);
652 emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
660 if (*fmt < '0' || '9' < *fmt)
664 imm = get_irn_n(node, pos);
665 if (is_ia32_Immediate(imm)) {
668 reg = arch_get_irn_register_in(node, pos);
674 const char *str = va_arg(ap, const char*);
680 if (mod & EMIT_LONG) {
681 unsigned long num = va_arg(ap, unsigned long);
682 be_emit_irprintf("%lu", num);
684 unsigned num = va_arg(ap, unsigned);
685 be_emit_irprintf("%u", num);
690 if (mod & EMIT_LONG) {
691 long num = va_arg(ap, long);
692 be_emit_irprintf("%ld", num);
694 int num = va_arg(ap, int);
695 be_emit_irprintf("%d", num);
701 panic("unknown format conversion");
705 be_emit_finish_line_gas(node);
709 static void emit_ia32_IMul(const ir_node *node)
711 ir_node *left = get_irn_n(node, n_ia32_IMul_left);
712 const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
714 /* do we need the 3-address form? */
715 if (is_ia32_NoReg_GP(left) ||
716 arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
717 ia32_emitf(node, "imul%M %#S4, %#AS3, %#D0");
719 ia32_emitf(node, "imul%M %#AS4, %#S3");
724 * walks up a tree of copies/perms/spills/reloads to find the original value
725 * that is moved around
727 static ir_node *find_original_value(ir_node *node)
729 if (irn_visited(node))
732 mark_irn_visited(node);
733 if (be_is_Copy(node)) {
734 return find_original_value(be_get_Copy_op(node));
735 } else if (be_is_CopyKeep(node)) {
736 return find_original_value(be_get_CopyKeep_op(node));
737 } else if (is_Proj(node)) {
738 ir_node *pred = get_Proj_pred(node);
739 if (be_is_Perm(pred)) {
740 return find_original_value(get_irn_n(pred, get_Proj_proj(node)));
741 } else if (be_is_MemPerm(pred)) {
742 return find_original_value(get_irn_n(pred, get_Proj_proj(node) + 1));
743 } else if (is_ia32_Load(pred)) {
744 return find_original_value(get_irn_n(pred, n_ia32_Load_mem));
745 } else if (is_ia32_Store(pred)) {
746 return find_original_value(get_irn_n(pred, n_ia32_Store_val));
750 } else if (is_Phi(node)) {
752 arity = get_irn_arity(node);
753 for (i = 0; i < arity; ++i) {
754 ir_node *in = get_irn_n(node, i);
755 ir_node *res = find_original_value(in);
766 static ia32_condition_code_t determine_final_cc(const ir_node *node,
767 int flags_pos, ia32_condition_code_t cc)
769 ir_node *flags = get_irn_n(node, flags_pos);
770 const ia32_attr_t *flags_attr;
771 flags = skip_Proj(flags);
773 if (is_ia32_Sahf(flags)) {
774 ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
775 if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
776 inc_irg_visited(current_ir_graph);
777 cmp = find_original_value(cmp);
779 assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
782 flags_attr = get_ia32_attr_const(cmp);
784 flags_attr = get_ia32_attr_const(flags);
787 if (flags_attr->data.ins_permuted)
788 cc = ia32_invert_condition_code(cc);
793 * Emits an exception label for a given node.
795 static void ia32_emit_exc_label(const ir_node *node)
797 be_emit_string(be_gas_insn_label_prefix());
798 be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
801 static int can_be_fallthrough(const ir_node *node)
803 ir_node *target_block = get_cfop_target_block(node);
804 ir_node *block = get_nodes_block(node);
805 return get_prev_block_sched(target_block) == block;
809 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
811 static void emit_ia32_Jcc(const ir_node *node)
813 int need_parity_label = 0;
814 ia32_condition_code_t cc = get_ia32_condcode(node);
816 cc = determine_final_cc(node, 0, cc);
819 ir_node const *proj_true = be_get_Proj_for_pn(node, pn_ia32_Jcc_true);
820 assert(proj_true && "Jcc without true Proj");
822 ir_node const *proj_false = be_get_Proj_for_pn(node, pn_ia32_Jcc_false);
823 assert(proj_false && "Jcc without false Proj");
825 if (can_be_fallthrough(proj_true)) {
826 /* exchange both proj's so the second one can be omitted */
827 const ir_node *t = proj_true;
829 proj_true = proj_false;
831 cc = ia32_negate_condition_code(cc);
834 if (cc & ia32_cc_float_parity_cases) {
835 /* Some floating point comparisons require a test of the parity flag,
836 * which indicates that the result is unordered */
837 if (cc & ia32_cc_negated) {
838 ia32_emitf(proj_true, "jp %L");
840 /* we need a local label if the false proj is a fallthrough
841 * as the falseblock might have no label emitted then */
842 if (can_be_fallthrough(proj_false)) {
843 need_parity_label = 1;
844 ia32_emitf(proj_false, "jp 1f");
846 ia32_emitf(proj_false, "jp %L");
850 ia32_emitf(proj_true, "j%PX %L", (int)cc);
851 if (need_parity_label) {
852 be_emit_cstring("1:\n");
853 be_emit_write_line();
856 /* the second Proj might be a fallthrough */
857 if (can_be_fallthrough(proj_false)) {
858 if (be_options.verbose_asm)
859 ia32_emitf(proj_false, "/* fallthrough to %L */");
861 ia32_emitf(proj_false, "jmp %L");
866 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
869 static void emit_ia32_Setcc(const ir_node *node)
871 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
873 ia32_condition_code_t cc = get_ia32_condcode(node);
874 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
875 if (cc & ia32_cc_float_parity_cases) {
876 if (cc & ia32_cc_negated) {
877 ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
878 ia32_emitf(node, "setp %>R", dreg);
879 ia32_emitf(node, "orb %>R, %<R", dreg, dreg);
881 ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
882 ia32_emitf(node, "setnp %>R", dreg);
883 ia32_emitf(node, "andb %>R, %<R", dreg, dreg);
886 ia32_emitf(node, "set%PX %#R", (int)cc, dreg);
890 static void emit_ia32_CMovcc(const ir_node *node)
892 const ia32_attr_t *attr = get_ia32_attr_const(node);
893 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
894 ia32_condition_code_t cc = get_ia32_condcode(node);
895 const arch_register_t *in_true;
896 const arch_register_t *in_false;
898 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
899 /* although you can't set ins_permuted in the constructor it might still
900 * be set by memory operand folding
901 * Permuting inputs of a cmov means the condition is negated!
903 if (attr->data.ins_permuted)
904 cc = ia32_negate_condition_code(cc);
906 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
907 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
909 /* should be same constraint fullfilled? */
910 if (out == in_false) {
911 /* yes -> nothing to do */
912 } else if (out == in_true) {
913 const arch_register_t *tmp;
915 assert(get_ia32_op_type(node) == ia32_Normal);
917 cc = ia32_negate_condition_code(cc);
924 ia32_emitf(node, "movl %R, %R", in_false, out);
927 if (cc & ia32_cc_float_parity_cases) {
928 panic("CMov with floatingpoint compare/parity not supported yet");
931 ia32_emitf(node, "cmov%PX %#AR, %#R", (int)cc, in_true, out);
935 * Emits code for a SwitchJmp
937 static void emit_ia32_SwitchJmp(const ir_node *node)
939 ir_entity *jump_table = get_ia32_am_sc(node);
940 const ir_switch_table *table = get_ia32_switch_table(node);
942 ia32_emitf(node, "jmp %*AM");
943 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
947 * Emits code for a unconditional jump.
949 static void emit_ia32_Jmp(const ir_node *node)
951 /* we have a block schedule */
952 if (can_be_fallthrough(node)) {
953 if (be_options.verbose_asm)
954 ia32_emitf(node, "/* fallthrough to %L */");
956 ia32_emitf(node, "jmp %L");
961 * Emit an inline assembler operand.
963 * @param node the ia32_ASM node
964 * @param s points to the operand (a %c)
966 * @return pointer to the first char in s NOT in the current operand
968 static const char* emit_asm_operand(const ir_node *node, const char *s)
970 const ia32_attr_t *ia32_attr = get_ia32_attr_const(node);
971 const ia32_asm_attr_t *attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
973 const arch_register_t *reg;
974 const ia32_asm_reg_t *asm_regs = attr->register_map;
975 const ia32_asm_reg_t *asm_reg;
984 /* parse modifiers */
987 ir_fprintf(stderr, "Warning: asm text (%+F) ends with %%\n", node);
1013 "Warning: asm text (%+F) contains unknown modifier '%c' for asm op\n",
1020 if (sscanf(s, "%d%n", &num, &p) != 1) {
1021 ir_fprintf(stderr, "Warning: Couldn't parse assembler operand (%+F)\n",
1028 if (num < 0 || ARR_LEN(asm_regs) <= (size_t)num) {
1030 "Error: Custom assembler references invalid input/output (%+F)\n",
1034 asm_reg = & asm_regs[num];
1035 assert(asm_reg->valid);
1038 if (asm_reg->use_input == 0) {
1039 reg = arch_get_irn_register_out(node, asm_reg->inout_pos);
1041 ir_node *pred = get_irn_n(node, asm_reg->inout_pos);
1043 /* might be an immediate value */
1044 if (is_ia32_Immediate(pred)) {
1045 emit_ia32_Immediate(pred);
1048 reg = arch_get_irn_register_in(node, asm_reg->inout_pos);
1052 "Warning: no register assigned for %d asm op (%+F)\n",
1057 /* Emit the register. */
1058 if (asm_reg->memory) {
1060 emit_register(reg, NULL);
1064 case '\0': emit_register(reg, asm_reg->mode); break;
1065 case 'b': emit_8bit_register(reg); break;
1066 case 'h': emit_8bit_register_high(reg); break;
1067 case 'w': emit_16bit_register(reg); break;
1068 default: panic("Invalid asm op modifier");
1076 * Emits code for an ASM pseudo op.
1078 static void emit_ia32_Asm(const ir_node *node)
1080 const void *gen_attr = get_irn_generic_attr_const(node);
1081 const ia32_asm_attr_t *attr
1082 = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, gen_attr);
1083 ident *asm_text = attr->asm_text;
1084 const char *s = get_id_str(asm_text);
1086 be_emit_cstring("#APP\n");
1087 be_emit_write_line();
1094 s = emit_asm_operand(node, s);
1100 be_emit_cstring("\n#NO_APP\n");
1101 be_emit_write_line();
1106 * Emit movsb/w instructions to make mov count divideable by 4
1108 static void emit_CopyB_prolog(unsigned size)
1111 ia32_emitf(NULL, "movsb");
1113 ia32_emitf(NULL, "movsw");
1117 * Emit rep movsd instruction for memcopy.
1119 static void emit_ia32_CopyB(const ir_node *node)
1121 unsigned size = get_ia32_copyb_size(node);
1123 emit_CopyB_prolog(size);
1124 ia32_emitf(node, "rep movsd");
1128 * Emits unrolled memcopy.
1130 static void emit_ia32_CopyB_i(const ir_node *node)
1132 unsigned size = get_ia32_copyb_size(node);
1134 emit_CopyB_prolog(size);
1138 ia32_emitf(NULL, "movsd");
1144 * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1146 static void emit_ia32_Conv_with_FP(const ir_node *node, const char* conv_f,
1149 ir_mode *ls_mode = get_ia32_ls_mode(node);
1150 int ls_bits = get_mode_size_bits(ls_mode);
1151 const char *conv = ls_bits == 32 ? conv_f : conv_d;
1153 ia32_emitf(node, "cvt%s %AS3, %D0", conv);
1156 static void emit_ia32_Conv_I2FP(const ir_node *node)
1158 emit_ia32_Conv_with_FP(node, "si2ss", "si2sd");
1161 static void emit_ia32_Conv_FP2I(const ir_node *node)
1163 emit_ia32_Conv_with_FP(node, "ss2si", "sd2si");
1166 static void emit_ia32_Conv_FP2FP(const ir_node *node)
1168 emit_ia32_Conv_with_FP(node, "sd2ss", "ss2sd");
1172 * Emits code to increase stack pointer.
1174 static void emit_be_IncSP(const ir_node *node)
1176 int offs = be_get_IncSP_offset(node);
1182 ia32_emitf(node, "subl $%u, %D0", offs);
1184 ia32_emitf(node, "addl $%u, %D0", -offs);
1189 * Emits code for Copy/CopyKeep.
1191 static void Copy_emitter(const ir_node *node, const ir_node *op)
1193 const arch_register_t *in = arch_get_irn_register(op);
1194 const arch_register_t *out = arch_get_irn_register(node);
1199 /* copies of fp nodes aren't real... */
1200 if (in->reg_class == &ia32_reg_classes[CLASS_ia32_fp])
1203 ia32_emitf(node, "movl %R, %R", in, out);
1206 static void emit_be_Copy(const ir_node *node)
1208 Copy_emitter(node, be_get_Copy_op(node));
1211 static void emit_be_CopyKeep(const ir_node *node)
1213 Copy_emitter(node, be_get_CopyKeep_op(node));
1217 * Emits code for exchange.
1219 static void emit_be_Perm(const ir_node *node)
1221 const arch_register_t *in0, *in1;
1223 in0 = arch_get_irn_register(get_irn_n(node, 0));
1224 in1 = arch_get_irn_register(get_irn_n(node, 1));
1226 arch_register_class_t const *const cls0 = in0->reg_class;
1227 assert(cls0 == in1->reg_class && "Register class mismatch at Perm");
1229 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
1230 ia32_emitf(node, "xchg %R, %R", in1, in0);
1231 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1232 ia32_emitf(NULL, "xorpd %R, %R", in1, in0);
1233 ia32_emitf(NULL, "xorpd %R, %R", in0, in1);
1234 ia32_emitf(node, "xorpd %R, %R", in1, in0);
1235 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_fp]) {
1238 panic("unexpected register class in be_Perm (%+F)", node);
1242 /* helper function for emit_ia32_Minus64Bit */
1243 static void emit_mov(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1245 ia32_emitf(node, "movl %R, %R", src, dst);
1248 /* helper function for emit_ia32_Minus64Bit */
1249 static void emit_neg(const ir_node* node, const arch_register_t *reg)
1251 ia32_emitf(node, "negl %R", reg);
1254 /* helper function for emit_ia32_Minus64Bit */
1255 static void emit_sbb0(const ir_node* node, const arch_register_t *reg)
1257 ia32_emitf(node, "sbbl $0, %R", reg);
1260 /* helper function for emit_ia32_Minus64Bit */
1261 static void emit_sbb(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1263 ia32_emitf(node, "sbbl %R, %R", src, dst);
1266 /* helper function for emit_ia32_Minus64Bit */
1267 static void emit_xchg(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1269 ia32_emitf(node, "xchgl %R, %R", src, dst);
1272 /* helper function for emit_ia32_Minus64Bit */
1273 static void emit_zero(const ir_node* node, const arch_register_t *reg)
1275 ia32_emitf(node, "xorl %R, %R", reg, reg);
1278 static void emit_ia32_Minus64Bit(const ir_node *node)
1280 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
1281 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
1282 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
1283 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
1285 if (out_lo == in_lo) {
1286 if (out_hi != in_hi) {
1287 /* a -> a, b -> d */
1290 /* a -> a, b -> b */
1293 } else if (out_lo == in_hi) {
1294 if (out_hi == in_lo) {
1295 /* a -> b, b -> a */
1296 emit_xchg(node, in_lo, in_hi);
1299 /* a -> b, b -> d */
1300 emit_mov(node, in_hi, out_hi);
1301 emit_mov(node, in_lo, out_lo);
1305 if (out_hi == in_lo) {
1306 /* a -> c, b -> a */
1307 emit_mov(node, in_lo, out_lo);
1309 } else if (out_hi == in_hi) {
1310 /* a -> c, b -> b */
1311 emit_mov(node, in_lo, out_lo);
1314 /* a -> c, b -> d */
1315 emit_mov(node, in_lo, out_lo);
1321 emit_neg( node, out_hi);
1322 emit_neg( node, out_lo);
1323 emit_sbb0(node, out_hi);
1327 emit_zero(node, out_hi);
1328 emit_neg( node, out_lo);
1329 emit_sbb( node, in_hi, out_hi);
1332 static void emit_ia32_GetEIP(const ir_node *node)
1334 ia32_emitf(node, "call %s", pic_base_label);
1335 be_emit_irprintf("%s:\n", pic_base_label);
1336 be_emit_write_line();
1337 ia32_emitf(node, "popl %D0");
1340 static void emit_ia32_ClimbFrame(const ir_node *node)
1342 const ia32_climbframe_attr_t *attr = get_ia32_climbframe_attr_const(node);
1344 ia32_emitf(node, "movl %S0, %D0");
1345 ia32_emitf(node, "movl $%u, %S1", attr->count);
1346 be_gas_emit_block_name(node);
1347 be_emit_cstring(":\n");
1348 be_emit_write_line();
1349 ia32_emitf(node, "movl (%D0), %D0");
1350 ia32_emitf(node, "dec %S1");
1351 be_emit_cstring("\tjnz ");
1352 be_gas_emit_block_name(node);
1353 be_emit_finish_line_gas(node);
1356 static void emit_be_Return(const ir_node *node)
1358 unsigned pop = be_Return_get_pop(node);
1360 if (pop > 0 || be_Return_get_emit_pop(node)) {
1361 ia32_emitf(node, "ret $%u", pop);
1363 ia32_emitf(node, "ret");
1369 * Enters the emitter functions for handled nodes into the generic
1370 * pointer of an opcode.
1372 static void ia32_register_emitters(void)
1374 #define IA32_EMIT(a) be_set_emitter(op_ia32_##a, emit_ia32_##a)
1375 #define EMIT(a) be_set_emitter(op_##a, emit_##a)
1376 #define IGN(a) be_set_emitter(op_##a, be_emit_nothing)
1377 #define BE_EMIT(a) be_set_emitter(op_be_##a, emit_be_##a)
1378 #define BE_IGN(a) be_set_emitter(op_be_##a, be_emit_nothing)
1380 /* first clear the generic function pointer for all ops */
1381 ir_clear_opcodes_generic_func();
1383 /* register all emitter functions defined in spec */
1384 ia32_register_spec_emitters();
1386 /* other ia32 emitter functions */
1389 IA32_EMIT(Conv_FP2FP);
1390 IA32_EMIT(Conv_FP2I);
1391 IA32_EMIT(Conv_I2FP);
1398 IA32_EMIT(Minus64Bit);
1399 IA32_EMIT(SwitchJmp);
1400 IA32_EMIT(ClimbFrame);
1403 /* benode emitter */
1423 * Assign and emit an exception label if the current instruction can fail.
1425 static void ia32_assign_exc_label(ir_node *node)
1427 /* assign a new ID to the instruction */
1428 set_ia32_exc_label_id(node, ++exc_label_id);
1430 ia32_emit_exc_label(node);
1432 be_emit_pad_comment();
1433 be_emit_cstring("/* exception to Block ");
1434 ia32_emit_cfop_target(node);
1435 be_emit_cstring(" */\n");
1436 be_emit_write_line();
1440 * Emits code for a node.
1442 static void ia32_emit_node(ir_node *node)
1444 DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
1446 if (is_ia32_irn(node)) {
1447 if (get_ia32_exc_label(node)) {
1448 /* emit the exception label of this instruction */
1449 ia32_assign_exc_label(node);
1451 if (mark_spill_reload) {
1452 if (is_ia32_is_spill(node)) {
1453 ia32_emitf(NULL, "xchg %ebx, %ebx /* spill mark */");
1455 if (is_ia32_is_reload(node)) {
1456 ia32_emitf(NULL, "xchg %edx, %edx /* reload mark */");
1458 if (is_ia32_is_remat(node)) {
1459 ia32_emitf(NULL, "xchg %ecx, %ecx /* remat mark */");
1467 int sp_change = arch_get_sp_bias(node);
1468 if (sp_change != 0) {
1469 assert(sp_change != SP_BIAS_RESET);
1470 callframe_offset += sp_change;
1471 be_dwarf_callframe_offset(callframe_offset);
1477 * Emits gas alignment directives
1479 static void ia32_emit_alignment(unsigned align, unsigned skip)
1481 ia32_emitf(NULL, ".p2align %u,,%u", align, skip);
1485 * Emits gas alignment directives for Labels depended on cpu architecture.
1487 static void ia32_emit_align_label(void)
1489 unsigned align = ia32_cg_config.label_alignment;
1490 unsigned maximum_skip = ia32_cg_config.label_alignment_max_skip;
1491 ia32_emit_alignment(align, maximum_skip);
1495 * Test whether a block should be aligned.
1496 * For cpus in the P4/Athlon class it is useful to align jump labels to
1497 * 16 bytes. However we should only do that if the alignment nops before the
1498 * label aren't executed more often than we have jumps to the label.
1500 static int should_align_block(const ir_node *block)
1502 static const double DELTA = .0001;
1503 ir_node *prev = get_prev_block_sched(block);
1504 double prev_freq = 0; /**< execfreq of the fallthrough block */
1505 double jmp_freq = 0; /**< execfreq of all non-fallthrough blocks */
1509 if (ia32_cg_config.label_alignment_factor <= 0)
1512 block_freq = get_block_execfreq(block);
1513 if (block_freq < DELTA)
1516 n_cfgpreds = get_Block_n_cfgpreds(block);
1517 for (i = 0; i < n_cfgpreds; ++i) {
1518 const ir_node *pred = get_Block_cfgpred_block(block, i);
1519 double pred_freq = get_block_execfreq(pred);
1522 prev_freq += pred_freq;
1524 jmp_freq += pred_freq;
1528 if (prev_freq < DELTA && !(jmp_freq < DELTA))
1531 jmp_freq /= prev_freq;
1533 return jmp_freq > ia32_cg_config.label_alignment_factor;
1537 * Emit the block header for a block.
1539 * @param block the block
1540 * @param prev_block the previous block
1542 static void ia32_emit_block_header(ir_node *block)
1544 ir_graph *const irg = get_Block_irg(block);
1545 if (block == get_irg_end_block(irg))
1548 if (ia32_cg_config.label_alignment > 0) {
1549 /* align the current block if:
1550 * a) if should be aligned due to its execution frequency
1551 * b) there is no fall-through here
1553 if (should_align_block(block)) {
1554 ia32_emit_align_label();
1556 /* if the predecessor block has no fall-through,
1557 we can always align the label. */
1559 int has_fallthrough = 0;
1561 for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
1562 ir_node *cfg_pred = get_Block_cfgpred(block, i);
1563 if (can_be_fallthrough(cfg_pred)) {
1564 has_fallthrough = 1;
1569 if (!has_fallthrough)
1570 ia32_emit_align_label();
1574 int const need_label = block_needs_label(block);
1575 be_gas_begin_block(block, need_label);
1579 * Walks over the nodes in a block connected by scheduling edges
1580 * and emits code for each node.
1582 static void ia32_gen_block(ir_node *block)
1584 ia32_emit_block_header(block);
1587 ir_graph *irg = get_irn_irg(block);
1588 callframe_offset = 4; /* 4 bytes for the return address */
1589 /* ESP guessing, TODO perform a real ESP simulation */
1590 if (block != get_irg_start_block(irg)) {
1591 callframe_offset += frame_type_size;
1593 be_dwarf_callframe_offset(callframe_offset);
1596 /* emit the contents of the block */
1597 be_dwarf_location(get_irn_dbg_info(block));
1598 sched_foreach(block, node) {
1599 ia32_emit_node(node);
1603 typedef struct exc_entry {
1604 ir_node *exc_instr; /** The instruction that can issue an exception. */
1605 ir_node *block; /** The block to call then. */
1610 * Sets labels for control flow nodes (jump target).
1611 * Links control predecessors to there destination blocks.
1613 static void ia32_gen_labels(ir_node *block, void *data)
1615 exc_entry **exc_list = (exc_entry**)data;
1619 for (n = get_Block_n_cfgpreds(block) - 1; n >= 0; --n) {
1620 pred = get_Block_cfgpred(block, n);
1621 set_irn_link(pred, block);
1623 pred = skip_Proj(pred);
1624 if (is_ia32_irn(pred) && get_ia32_exc_label(pred)) {
1629 ARR_APP1(exc_entry, *exc_list, e);
1630 set_irn_link(pred, block);
1636 * Compare two exception_entries.
1638 static int cmp_exc_entry(const void *a, const void *b)
1640 const exc_entry *ea = (const exc_entry*)a;
1641 const exc_entry *eb = (const exc_entry*)b;
1643 if (get_ia32_exc_label_id(ea->exc_instr) < get_ia32_exc_label_id(eb->exc_instr))
1648 static parameter_dbg_info_t *construct_parameter_infos(ir_graph *irg)
1650 ir_entity *entity = get_irg_entity(irg);
1651 ir_type *type = get_entity_type(entity);
1652 size_t n_params = get_method_n_params(type);
1653 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
1654 ir_type *arg_type = layout->arg_type;
1655 size_t n_members = get_compound_n_members(arg_type);
1656 parameter_dbg_info_t *infos = XMALLOCNZ(parameter_dbg_info_t, n_params);
1659 for (i = 0; i < n_members; ++i) {
1660 ir_entity *member = get_compound_member(arg_type, i);
1662 if (!is_parameter_entity(member))
1664 param = get_entity_parameter_number(member);
1665 if (param == IR_VA_START_PARAMETER_NUMBER)
1667 assert(infos[param].entity == NULL && infos[param].reg == NULL);
1668 infos[param].reg = NULL;
1669 infos[param].entity = member;
1676 * Main driver. Emits the code for one routine.
1678 void ia32_gen_routine(ir_graph *irg)
1680 ir_entity *entity = get_irg_entity(irg);
1681 exc_entry *exc_list = NEW_ARR_F(exc_entry, 0);
1682 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
1683 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
1684 ir_node **blk_sched = irg_data->blk_sched;
1685 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
1686 parameter_dbg_info_t *infos;
1689 isa = (ia32_isa_t*) arch_env;
1690 do_pic = be_options.pic;
1692 be_gas_elf_type_char = '@';
1694 ia32_register_emitters();
1696 get_unique_label(pic_base_label, sizeof(pic_base_label), "PIC_BASE");
1698 infos = construct_parameter_infos(irg);
1699 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
1703 sp_relative = layout->sp_relative;
1704 if (layout->sp_relative) {
1705 ir_type *frame_type = get_irg_frame_type(irg);
1706 frame_type_size = get_type_size_bytes(frame_type);
1707 be_dwarf_callframe_register(&ia32_registers[REG_ESP]);
1709 /* well not entirely correct here, we should emit this after the
1710 * "movl esp, ebp" */
1711 be_dwarf_callframe_register(&ia32_registers[REG_EBP]);
1712 /* TODO: do not hardcode the following */
1713 be_dwarf_callframe_offset(8);
1714 be_dwarf_callframe_spilloffset(&ia32_registers[REG_EBP], -8);
1717 /* we use links to point to target blocks */
1718 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
1719 irg_block_walk_graph(irg, ia32_gen_labels, NULL, &exc_list);
1721 /* initialize next block links */
1722 n = ARR_LEN(blk_sched);
1723 for (i = 0; i < n; ++i) {
1724 ir_node *block = blk_sched[i];
1725 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
1727 set_irn_link(block, prev);
1730 for (i = 0; i < n; ++i) {
1731 ir_node *block = blk_sched[i];
1733 ia32_gen_block(block);
1736 be_gas_emit_function_epilog(entity);
1738 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
1740 /* Sort the exception table using the exception label id's.
1741 Those are ascending with ascending addresses. */
1742 qsort(exc_list, ARR_LEN(exc_list), sizeof(exc_list[0]), cmp_exc_entry);
1746 for (e = 0; e < ARR_LEN(exc_list); ++e) {
1747 be_emit_cstring("\t.long ");
1748 ia32_emit_exc_label(exc_list[e].exc_instr);
1750 be_emit_cstring("\t.long ");
1751 be_gas_emit_block_name(exc_list[e].block);
1755 DEL_ARR_F(exc_list);
1758 static const lc_opt_table_entry_t ia32_emitter_options[] = {
1759 LC_OPT_ENT_BOOL("mark_spill_reload", "mark spills and reloads with ud opcodes", &mark_spill_reload),
1763 /* ==== Experimental binary emitter ==== */
1765 static unsigned char reg_gp_map[N_ia32_gp_REGS];
1766 //static unsigned char reg_mmx_map[N_ia32_mmx_REGS];
1767 //static unsigned char reg_sse_map[N_ia32_xmm_REGS];
1769 static void build_reg_map(void)
1771 reg_gp_map[REG_GP_EAX] = 0x0;
1772 reg_gp_map[REG_GP_ECX] = 0x1;
1773 reg_gp_map[REG_GP_EDX] = 0x2;
1774 reg_gp_map[REG_GP_EBX] = 0x3;
1775 reg_gp_map[REG_GP_ESP] = 0x4;
1776 reg_gp_map[REG_GP_EBP] = 0x5;
1777 reg_gp_map[REG_GP_ESI] = 0x6;
1778 reg_gp_map[REG_GP_EDI] = 0x7;
1781 /** Returns the encoding for a pnc field. */
1782 static unsigned char pnc2cc(ia32_condition_code_t cc)
1788 OP_8 = 0x00, /* 8bit operation. */
1789 OP_16_32 = 0x01, /* 16/32bit operation. */
1790 OP_MEM_SRC = 0x02, /* The memory operand is in the soruce position. */
1791 OP_IMM8 = 0x02, /* 8bit immediate, which gets sign extended for 16/32bit operation. */
1792 OP_16_32_IMM8 = 0x03, /* 16/32bit operation with sign extended 8bit immediate. */
1793 OP_EAX = 0x04, /* Short form of instruction with al/ax/eax as operand. */
1796 /** The mod encoding of the ModR/M */
1798 MOD_IND = 0x00, /**< [reg1] */
1799 MOD_IND_BYTE_OFS = 0x40, /**< [reg1 + byte ofs] */
1800 MOD_IND_WORD_OFS = 0x80, /**< [reg1 + word ofs] */
1801 MOD_REG = 0xC0 /**< reg1 */
1804 /** create R/M encoding for ModR/M */
1805 #define ENC_RM(x) (x)
1806 /** create REG encoding for ModR/M */
1807 #define ENC_REG(x) ((x) << 3)
1809 /** create encoding for a SIB byte */
1810 #define ENC_SIB(scale, index, base) ((scale) << 6 | (index) << 3 | (base))
1812 /* Node: The following routines are supposed to append bytes, words, dwords
1813 to the output stream.
1814 Currently the implementation is stupid in that it still creates output
1815 for an "assembler" in the form of .byte, .long
1816 We will change this when enough infrastructure is there to create complete
1817 machine code in memory/object files */
1819 static void bemit8(const unsigned char byte)
1821 be_emit_irprintf("\t.byte 0x%x\n", byte);
1822 be_emit_write_line();
1825 static void bemit16(const unsigned short u16)
1827 be_emit_irprintf("\t.word 0x%x\n", u16);
1828 be_emit_write_line();
1831 static void bemit32(const unsigned u32)
1833 be_emit_irprintf("\t.long 0x%x\n", u32);
1834 be_emit_write_line();
1838 * Emit address of an entity. If @p is_relative is true then a relative
1839 * offset from behind the address to the entity is created.
1841 static void bemit_entity(ir_entity *entity, bool entity_sign, int offset,
1844 if (entity == NULL) {
1849 /* the final version should remember the position in the bytestream
1850 and patch it with the correct address at linktime... */
1851 be_emit_cstring("\t.long ");
1854 be_gas_emit_entity(entity);
1856 if (get_entity_owner(entity) == get_tls_type()) {
1857 if (!entity_has_definition(entity)) {
1858 be_emit_cstring("@INDNTPOFF");
1860 be_emit_cstring("@NTPOFF");
1865 be_emit_cstring("-.");
1870 be_emit_irprintf("%+d", offset);
1873 be_emit_write_line();
1876 static void bemit_jmp_destination(const ir_node *dest_block)
1878 be_emit_cstring("\t.long ");
1879 be_gas_emit_block_name(dest_block);
1880 be_emit_cstring(" - . - 4\n");
1881 be_emit_write_line();
1884 /* end emit routines, all emitters following here should only use the functions
1887 typedef enum reg_modifier {
1892 /** Create a ModR/M byte for src1,src2 registers */
1893 static void bemit_modrr(const arch_register_t *src1,
1894 const arch_register_t *src2)
1896 unsigned char modrm = MOD_REG;
1897 modrm |= ENC_RM(reg_gp_map[src1->index]);
1898 modrm |= ENC_REG(reg_gp_map[src2->index]);
1902 /** Create a ModR/M8 byte for src1,src2 registers */
1903 static void bemit_modrr8(reg_modifier_t high_part1, const arch_register_t *src1,
1904 reg_modifier_t high_part2, const arch_register_t *src2)
1906 unsigned char modrm = MOD_REG;
1907 modrm |= ENC_RM(reg_gp_map[src1->index] + (high_part1 == REG_HIGH ? 4 : 0));
1908 modrm |= ENC_REG(reg_gp_map[src2->index] + (high_part2 == REG_HIGH ? 4 : 0));
1912 /** Create a ModR/M byte for one register and extension */
1913 static void bemit_modru(const arch_register_t *reg, unsigned ext)
1915 unsigned char modrm = MOD_REG;
1917 modrm |= ENC_RM(reg_gp_map[reg->index]);
1918 modrm |= ENC_REG(ext);
1922 /** Create a ModR/M8 byte for one register */
1923 static void bemit_modrm8(reg_modifier_t high_part, const arch_register_t *reg)
1925 unsigned char modrm = MOD_REG;
1926 assert(reg_gp_map[reg->index] < 4);
1927 modrm |= ENC_RM(reg_gp_map[reg->index] + (high_part == REG_HIGH ? 4 : 0));
1933 * Calculate the size of an signed immediate in bytes.
1935 * @param offset an offset
1937 static unsigned get_signed_imm_size(int offset)
1939 if (-128 <= offset && offset < 128) {
1941 } else if (-32768 <= offset && offset < 32768) {
1949 * Emit an address mode.
1951 * @param reg content of the reg field: either a register index or an opcode extension
1952 * @param node the node
1954 static void bemit_mod_am(unsigned reg, const ir_node *node)
1956 ir_entity *ent = get_ia32_am_sc(node);
1957 int offs = get_ia32_am_offs_int(node);
1958 ir_node *base = get_irn_n(node, n_ia32_base);
1959 int has_base = !is_ia32_NoReg_GP(base);
1960 ir_node *idx = get_irn_n(node, n_ia32_index);
1961 int has_index = !is_ia32_NoReg_GP(idx);
1964 unsigned emitoffs = 0;
1965 bool emitsib = false;
1968 /* set the mod part depending on displacement */
1970 modrm |= MOD_IND_WORD_OFS;
1972 } else if (offs == 0) {
1975 } else if (-128 <= offs && offs < 128) {
1976 modrm |= MOD_IND_BYTE_OFS;
1979 modrm |= MOD_IND_WORD_OFS;
1984 const arch_register_t *base_reg = arch_get_irn_register(base);
1985 base_enc = reg_gp_map[base_reg->index];
1987 /* Use the EBP encoding + MOD_IND if NO base register. There is
1988 * always a 32bit offset present in this case. */
1994 /* Determine if we need a SIB byte. */
1996 const arch_register_t *reg_index = arch_get_irn_register(idx);
1997 int scale = get_ia32_am_scale(node);
1999 /* R/M set to ESP means SIB in 32bit mode. */
2000 modrm |= ENC_RM(0x04);
2001 sib = ENC_SIB(scale, reg_gp_map[reg_index->index], base_enc);
2003 } else if (base_enc == 0x04) {
2004 /* for the above reason we are forced to emit a SIB when base is ESP.
2005 * Only the base is used, index must be ESP too, which means no index.
2007 modrm |= ENC_RM(0x04);
2008 sib = ENC_SIB(0, 0x04, 0x04);
2011 modrm |= ENC_RM(base_enc);
2014 /* We are forced to emit an 8bit offset as EBP base without offset is a
2015 * special case for SIB without base register. */
2016 if (base_enc == 0x05 && emitoffs == 0) {
2017 modrm |= MOD_IND_BYTE_OFS;
2021 modrm |= ENC_REG(reg);
2027 /* emit displacement */
2028 if (emitoffs == 8) {
2029 bemit8((unsigned) offs);
2030 } else if (emitoffs == 32) {
2031 bemit_entity(ent, is_ia32_am_sc_sign(node), offs, false);
2038 static void bemit_unop(const ir_node *node, unsigned char code, unsigned char ext, int input)
2041 if (get_ia32_op_type(node) == ia32_Normal) {
2042 const arch_register_t *in = arch_get_irn_register_in(node, input);
2043 bemit_modru(in, ext);
2045 bemit_mod_am(ext, node);
2049 static void bemit_unop_reg(const ir_node *node, unsigned char code, int input)
2051 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2052 bemit_unop(node, code, reg_gp_map[out->index], input);
2055 static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned char ext)
2057 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2060 bemit8(size == 8 ? code : code + 1);
2061 bemit_mod_am(ext, node);
2064 static void bemit_0f_unop_reg(ir_node const *const node, unsigned char const code, int const input)
2067 bemit_unop_reg(node, code, input);
2070 static void bemit_immediate(const ir_node *node, bool relative)
2072 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
2073 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, relative);
2076 static void bemit_copy(const ir_node *copy)
2078 const arch_register_t *in = arch_get_irn_register_in(copy, 0);
2079 const arch_register_t *out = arch_get_irn_register_out(copy, 0);
2083 /* copies of fp nodes aren't real... */
2084 if (in->reg_class == &ia32_reg_classes[CLASS_ia32_fp])
2087 assert(in->reg_class == &ia32_reg_classes[CLASS_ia32_gp]);
2089 bemit_modrr(in, out);
2092 static void bemit_perm(const ir_node *node)
2094 const arch_register_t *in0 = arch_get_irn_register(get_irn_n(node, 0));
2095 const arch_register_t *in1 = arch_get_irn_register(get_irn_n(node, 1));
2096 const arch_register_class_t *cls0 = in0->reg_class;
2098 assert(cls0 == in1->reg_class && "Register class mismatch at Perm");
2100 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
2101 if (in0->index == REG_GP_EAX) {
2102 bemit8(0x90 + reg_gp_map[in1->index]);
2103 } else if (in1->index == REG_GP_EAX) {
2104 bemit8(0x90 + reg_gp_map[in0->index]);
2107 bemit_modrr(in0, in1);
2109 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
2110 panic("unimplemented"); // TODO implement
2111 //ia32_emitf(NULL, "xorpd %R, %R", in1, in0);
2112 //ia32_emitf(NULL, "xorpd %R, %R", in0, in1);
2113 //ia32_emitf(node, "xorpd %R, %R", in1, in0);
2114 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_fp]) {
2117 panic("unexpected register class in be_Perm (%+F)", node);
2121 static void bemit_xor0(const ir_node *node)
2123 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2125 bemit_modrr(out, out);
2128 static void bemit_mov_const(const ir_node *node)
2130 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2131 bemit8(0xB8 + reg_gp_map[out->index]);
2132 bemit_immediate(node, false);
2138 static void bemit_binop(ir_node const *const node, unsigned const code)
2140 ir_mode *const ls_mode = get_ia32_ls_mode(node);
2141 unsigned size = ls_mode ? get_mode_size_bits(ls_mode) : 32;
2145 unsigned op = size == 8 ? OP_8 : OP_16_32;
2146 ir_node *const right = get_irn_n(node, n_ia32_binary_right);
2147 if (is_ia32_Immediate(right)) {
2148 ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(right);
2149 /* Try to use the short form with 8bit sign extended immediate. */
2150 if (op != OP_8 && !attr->symconst && get_signed_imm_size(attr->offset) == 1) {
2155 /* Emit the main opcode. */
2156 if (get_ia32_op_type(node) == ia32_Normal) {
2157 arch_register_t const *const dst = arch_get_irn_register_in(node, n_ia32_binary_left);
2158 /* Try to use the shorter al/ax/eax form. */
2159 if (dst->index == REG_GP_EAX && op != OP_16_32_IMM8) {
2160 bemit8(code << 3 | OP_EAX | op);
2163 bemit_modru(dst, code);
2167 bemit_mod_am(code, node);
2170 /* Emit the immediate. */
2172 case 8: bemit8(attr->offset); break;
2173 case 16: bemit16(attr->offset); break;
2174 case 32: bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false); break;
2177 bemit8(code << 3 | OP_MEM_SRC | op);
2178 arch_register_t const *const dst = arch_get_irn_register_in(node, n_ia32_binary_left);
2179 if (get_ia32_op_type(node) == ia32_Normal) {
2180 arch_register_t const *const src = arch_get_irn_register(right);
2181 bemit_modrr(src, dst);
2183 bemit_mod_am(reg_gp_map[dst->index], node);
2189 * Create a function for a binop.
2191 #define BINOP(op, code) \
2192 static void bemit_##op(ir_node const *const node) \
2194 bemit_binop(node, code); \
2207 static void bemit_binop_mem(ir_node const *const node, unsigned const code)
2209 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2213 unsigned op = size == 8 ? OP_8 : OP_16_32;
2214 ir_node *const val = get_irn_n(node, n_ia32_unary_op);
2215 if (is_ia32_Immediate(val)) {
2216 ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(val);
2217 /* Try to use the short form with 8bit sign extended immediate. */
2218 if (op != OP_8 && !attr->symconst && get_signed_imm_size(attr->offset) == 1) {
2223 /* Emit the main opcode. */
2225 bemit_mod_am(code, node);
2227 /* Emit the immediate. */
2229 case 8: bemit8(attr->offset); break;
2230 case 16: bemit16(attr->offset); break;
2231 case 32: bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false); break;
2234 bemit8(code << 3 | op);
2235 bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node);
2239 #define BINOPMEM(op, code) \
2240 static void bemit_##op(ir_node const *const node) \
2242 bemit_binop_mem(node, code); \
2253 * Creates a function for an Unop with code /ext encoding.
2255 #define UNOP(op, code, ext, input) \
2256 static void bemit_ ## op(const ir_node *node) { \
2257 bemit_unop(node, code, ext, input); \
2260 UNOP(not, 0xF7, 2, n_ia32_Not_val)
2261 UNOP(neg, 0xF7, 3, n_ia32_Neg_val)
2262 UNOP(mul, 0xF7, 4, n_ia32_Mul_right)
2263 UNOP(imul1op, 0xF7, 5, n_ia32_IMul1OP_right)
2264 UNOP(div, 0xF7, 6, n_ia32_Div_divisor)
2265 UNOP(idiv, 0xF7, 7, n_ia32_IDiv_divisor)
2267 /* TODO: am support for IJmp */
2268 UNOP(ijmp, 0xFF, 4, n_ia32_IJmp_target)
2270 #define SHIFT(op, ext) \
2271 static void bemit_##op(const ir_node *node) \
2273 const arch_register_t *out = arch_get_irn_register_out(node, 0); \
2274 ir_node *count = get_irn_n(node, 1); \
2275 if (is_ia32_Immediate(count)) { \
2276 int offset = get_ia32_immediate_attr_const(count)->offset; \
2277 if (offset == 1) { \
2279 bemit_modru(out, ext); \
2282 bemit_modru(out, ext); \
2287 bemit_modru(out, ext); \
2291 static void bemit_##op##mem(const ir_node *node) \
2294 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2297 count = get_irn_n(node, 1); \
2298 if (is_ia32_Immediate(count)) { \
2299 int offset = get_ia32_immediate_attr_const(count)->offset; \
2300 if (offset == 1) { \
2301 bemit8(size == 8 ? 0xD0 : 0xD1); \
2302 bemit_mod_am(ext, node); \
2304 bemit8(size == 8 ? 0xC0 : 0xC1); \
2305 bemit_mod_am(ext, node); \
2309 bemit8(size == 8 ? 0xD2 : 0xD3); \
2310 bemit_mod_am(ext, node); \
2320 static void bemit_shld(const ir_node *node)
2322 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShlD_val_low);
2323 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShlD_res);
2324 ir_node *count = get_irn_n(node, n_ia32_ShlD_count);
2326 if (is_ia32_Immediate(count)) {
2328 bemit_modrr(out, in);
2329 bemit8(get_ia32_immediate_attr_const(count)->offset);
2332 bemit_modrr(out, in);
2336 static void bemit_shrd(const ir_node *node)
2338 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShrD_val_low);
2339 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShrD_res);
2340 ir_node *count = get_irn_n(node, n_ia32_ShrD_count);
2342 if (is_ia32_Immediate(count)) {
2344 bemit_modrr(out, in);
2345 bemit8(get_ia32_immediate_attr_const(count)->offset);
2348 bemit_modrr(out, in);
2352 static void bemit_sbb0(ir_node const *const node)
2354 arch_register_t const *const out = arch_get_irn_register_out(node, pn_ia32_Sbb0_res);
2355 unsigned char const reg = reg_gp_map[out->index];
2357 bemit8(MOD_REG | ENC_REG(reg) | ENC_RM(reg));
2361 * binary emitter for setcc.
2363 static void bemit_setcc(const ir_node *node)
2365 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
2367 ia32_condition_code_t cc = get_ia32_condcode(node);
2368 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
2369 if (cc & ia32_cc_float_parity_cases) {
2370 if (cc & ia32_cc_negated) {
2373 bemit8(0x90 | pnc2cc(cc));
2374 bemit_modrm8(REG_LOW, dreg);
2379 bemit_modrm8(REG_HIGH, dreg);
2381 /* orb %>dreg, %<dreg */
2383 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2387 bemit8(0x90 | pnc2cc(cc));
2388 bemit_modrm8(REG_LOW, dreg);
2393 bemit_modrm8(REG_HIGH, dreg);
2395 /* andb %>dreg, %<dreg */
2397 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2402 bemit8(0x90 | pnc2cc(cc));
2403 bemit_modrm8(REG_LOW, dreg);
2407 static void bemit_bsf(ir_node const *const node)
2409 bemit_0f_unop_reg(node, 0xBC, n_ia32_Bsf_operand);
2412 static void bemit_bsr(ir_node const *const node)
2414 bemit_0f_unop_reg(node, 0xBD, n_ia32_Bsr_operand);
2417 static void bemit_bswap(ir_node const *const node)
2420 bemit_modru(arch_get_irn_register_out(node, pn_ia32_Bswap_res), 1);
2423 static void bemit_bt(ir_node const *const node)
2426 arch_register_t const *const lreg = arch_get_irn_register_in(node, n_ia32_Bt_left);
2427 ir_node const *const right = get_irn_n(node, n_ia32_Bt_right);
2428 if (is_ia32_Immediate(right)) {
2429 ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(right);
2430 int const offset = attr->offset;
2431 assert(!attr->symconst);
2432 assert(get_signed_imm_size(offset) == 1);
2434 bemit_modru(lreg, 4);
2438 bemit_modrr(lreg, arch_get_irn_register(right));
2442 static void bemit_cmovcc(const ir_node *node)
2444 const ia32_attr_t *attr = get_ia32_attr_const(node);
2445 int ins_permuted = attr->data.ins_permuted;
2446 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
2447 ia32_condition_code_t cc = get_ia32_condcode(node);
2448 const arch_register_t *in_true;
2449 const arch_register_t *in_false;
2451 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
2453 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
2454 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
2456 /* should be same constraint fullfilled? */
2457 if (out == in_false) {
2458 /* yes -> nothing to do */
2459 } else if (out == in_true) {
2460 assert(get_ia32_op_type(node) == ia32_Normal);
2461 ins_permuted = !ins_permuted;
2465 bemit8(0x8B); // mov %in_false, %out
2466 bemit_modrr(in_false, out);
2470 cc = ia32_negate_condition_code(cc);
2472 if (cc & ia32_cc_float_parity_cases)
2473 panic("cmov can't handle parity float cases");
2476 bemit8(0x40 | pnc2cc(cc));
2477 if (get_ia32_op_type(node) == ia32_Normal) {
2478 bemit_modrr(in_true, out);
2480 bemit_mod_am(reg_gp_map[out->index], node);
2484 static void bemit_test(ir_node const *const node)
2486 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
2490 unsigned const op = size == 8 ? OP_8 : OP_16_32;
2491 ir_node *const right = get_irn_n(node, n_ia32_Test_right);
2492 if (is_ia32_Immediate(right)) {
2493 /* Emit the main opcode. */
2494 if (get_ia32_op_type(node) == ia32_Normal) {
2495 arch_register_t const *const dst = arch_get_irn_register_in(node, n_ia32_Test_left);
2496 /* Try to use the shorter al/ax/eax form. */
2497 if (dst->index == REG_GP_EAX) {
2501 bemit_modru(dst, 0);
2505 bemit_mod_am(0, node);
2508 /* Emit the immediate. */
2509 ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(right);
2511 case 8: bemit8(attr->offset); break;
2512 case 16: bemit16(attr->offset); break;
2513 case 32: bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false); break;
2517 arch_register_t const *const dst = arch_get_irn_register_in(node, n_ia32_Test_left);
2518 if (get_ia32_op_type(node) == ia32_Normal) {
2519 arch_register_t const *const src = arch_get_irn_register(right);
2520 bemit_modrr(src, dst);
2522 bemit_mod_am(reg_gp_map[dst->index], node);
2527 static void bemit_imul(const ir_node *node)
2529 ir_node *right = get_irn_n(node, n_ia32_IMul_right);
2530 /* Do we need the immediate form? */
2531 if (is_ia32_Immediate(right)) {
2532 int imm = get_ia32_immediate_attr_const(right)->offset;
2533 if (get_signed_imm_size(imm) == 1) {
2534 bemit_unop_reg(node, 0x6B, n_ia32_IMul_left);
2537 bemit_unop_reg(node, 0x69, n_ia32_IMul_left);
2541 bemit_0f_unop_reg(node, 0xAF, n_ia32_IMul_right);
2545 static void bemit_dec(const ir_node *node)
2547 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Dec_res);
2548 bemit8(0x48 + reg_gp_map[out->index]);
2551 static void bemit_inc(const ir_node *node)
2553 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Inc_res);
2554 bemit8(0x40 + reg_gp_map[out->index]);
2557 #define UNOPMEM(op, code, ext) \
2558 static void bemit_##op(const ir_node *node) \
2560 bemit_unop_mem(node, code, ext); \
2563 UNOPMEM(notmem, 0xF6, 2)
2564 UNOPMEM(negmem, 0xF6, 3)
2565 UNOPMEM(incmem, 0xFE, 0)
2566 UNOPMEM(decmem, 0xFE, 1)
2568 static void bemit_ldtls(const ir_node *node)
2570 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2572 bemit8(0x65); // gs:
2573 if (out->index == REG_GP_EAX) {
2574 bemit8(0xA1); // movl 0, %eax
2576 bemit8(0x8B); // movl 0, %reg
2577 bemit8(MOD_IND | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x05));
2585 static void bemit_lea(const ir_node *node)
2587 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2589 bemit_mod_am(reg_gp_map[out->index], node);
2592 /* helper function for bemit_minus64bit */
2593 static void bemit_helper_mov(const arch_register_t *src, const arch_register_t *dst)
2595 bemit8(0x8B); // movl %src, %dst
2596 bemit_modrr(src, dst);
2599 /* helper function for bemit_minus64bit */
2600 static void bemit_helper_neg(const arch_register_t *reg)
2602 bemit8(0xF7); // negl %reg
2603 bemit_modru(reg, 3);
2606 /* helper function for bemit_minus64bit */
2607 static void bemit_helper_sbb0(const arch_register_t *reg)
2609 bemit8(0x83); // sbbl $0, %reg
2610 bemit_modru(reg, 3);
2614 /* helper function for bemit_minus64bit */
2615 static void bemit_helper_sbb(const arch_register_t *src, const arch_register_t *dst)
2617 bemit8(0x1B); // sbbl %src, %dst
2618 bemit_modrr(src, dst);
2621 /* helper function for bemit_minus64bit */
2622 static void bemit_helper_xchg(const arch_register_t *src, const arch_register_t *dst)
2624 if (src->index == REG_GP_EAX) {
2625 bemit8(0x90 + reg_gp_map[dst->index]); // xchgl %eax, %dst
2626 } else if (dst->index == REG_GP_EAX) {
2627 bemit8(0x90 + reg_gp_map[src->index]); // xchgl %src, %eax
2629 bemit8(0x87); // xchgl %src, %dst
2630 bemit_modrr(src, dst);
2634 /* helper function for bemit_minus64bit */
2635 static void bemit_helper_zero(const arch_register_t *reg)
2637 bemit8(0x33); // xorl %reg, %reg
2638 bemit_modrr(reg, reg);
2641 static void bemit_minus64bit(const ir_node *node)
2643 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
2644 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
2645 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
2646 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
2648 if (out_lo == in_lo) {
2649 if (out_hi != in_hi) {
2650 /* a -> a, b -> d */
2653 /* a -> a, b -> b */
2656 } else if (out_lo == in_hi) {
2657 if (out_hi == in_lo) {
2658 /* a -> b, b -> a */
2659 bemit_helper_xchg(in_lo, in_hi);
2662 /* a -> b, b -> d */
2663 bemit_helper_mov(in_hi, out_hi);
2664 bemit_helper_mov(in_lo, out_lo);
2668 if (out_hi == in_lo) {
2669 /* a -> c, b -> a */
2670 bemit_helper_mov(in_lo, out_lo);
2672 } else if (out_hi == in_hi) {
2673 /* a -> c, b -> b */
2674 bemit_helper_mov(in_lo, out_lo);
2677 /* a -> c, b -> d */
2678 bemit_helper_mov(in_lo, out_lo);
2684 bemit_helper_neg( out_hi);
2685 bemit_helper_neg( out_lo);
2686 bemit_helper_sbb0(out_hi);
2690 bemit_helper_zero(out_hi);
2691 bemit_helper_neg( out_lo);
2692 bemit_helper_sbb( in_hi, out_hi);
2696 * Emit a single opcode.
2698 #define EMIT_SINGLEOP(op, code) \
2699 static void bemit_ ## op(const ir_node *node) { \
2704 //EMIT_SINGLEOP(daa, 0x27)
2705 //EMIT_SINGLEOP(das, 0x2F)
2706 //EMIT_SINGLEOP(aaa, 0x37)
2707 //EMIT_SINGLEOP(aas, 0x3F)
2708 //EMIT_SINGLEOP(nop, 0x90)
2709 EMIT_SINGLEOP(cwtl, 0x98)
2710 EMIT_SINGLEOP(cltd, 0x99)
2711 //EMIT_SINGLEOP(fwait, 0x9B)
2712 EMIT_SINGLEOP(sahf, 0x9E)
2713 //EMIT_SINGLEOP(popf, 0x9D)
2714 EMIT_SINGLEOP(leave, 0xC9)
2715 EMIT_SINGLEOP(int3, 0xCC)
2716 //EMIT_SINGLEOP(iret, 0xCF)
2717 //EMIT_SINGLEOP(xlat, 0xD7)
2718 //EMIT_SINGLEOP(lock, 0xF0)
2719 EMIT_SINGLEOP(rep, 0xF3)
2720 //EMIT_SINGLEOP(halt, 0xF4)
2721 EMIT_SINGLEOP(cmc, 0xF5)
2722 EMIT_SINGLEOP(stc, 0xF9)
2723 //EMIT_SINGLEOP(cli, 0xFA)
2724 //EMIT_SINGLEOP(sti, 0xFB)
2725 //EMIT_SINGLEOP(std, 0xFD)
2728 * Emits a MOV out, [MEM].
2730 static void bemit_load(const ir_node *node)
2732 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2734 if (out->index == REG_GP_EAX) {
2735 ir_node *base = get_irn_n(node, n_ia32_base);
2736 int has_base = !is_ia32_NoReg_GP(base);
2737 ir_node *idx = get_irn_n(node, n_ia32_index);
2738 int has_index = !is_ia32_NoReg_GP(idx);
2739 if (!has_base && !has_index) {
2740 ir_entity *ent = get_ia32_am_sc(node);
2741 int offs = get_ia32_am_offs_int(node);
2742 /* load from constant address to EAX can be encoded
2745 bemit_entity(ent, 0, offs, false);
2750 bemit_mod_am(reg_gp_map[out->index], node);
2754 * Emits a MOV [mem], in.
2756 static void bemit_store(const ir_node *node)
2758 const ir_node *value = get_irn_n(node, n_ia32_Store_val);
2759 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2761 if (is_ia32_Immediate(value)) {
2764 bemit_mod_am(0, node);
2765 bemit8(get_ia32_immediate_attr_const(value)->offset);
2766 } else if (size == 16) {
2769 bemit_mod_am(0, node);
2770 bemit16(get_ia32_immediate_attr_const(value)->offset);
2773 bemit_mod_am(0, node);
2774 bemit_immediate(value, false);
2777 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Store_val);
2779 if (in->index == REG_GP_EAX) {
2780 ir_node *base = get_irn_n(node, n_ia32_base);
2781 int has_base = !is_ia32_NoReg_GP(base);
2782 ir_node *idx = get_irn_n(node, n_ia32_index);
2783 int has_index = !is_ia32_NoReg_GP(idx);
2784 if (!has_base && !has_index) {
2785 ir_entity *ent = get_ia32_am_sc(node);
2786 int offs = get_ia32_am_offs_int(node);
2787 /* store to constant address from EAX can be encoded as
2788 * 0xA2/0xA3 [offset]*/
2796 bemit_entity(ent, 0, offs, false);
2808 bemit_mod_am(reg_gp_map[in->index], node);
2812 static void bemit_conv_i2i(const ir_node *node)
2817 ir_mode *const smaller_mode = get_ia32_ls_mode(node);
2818 unsigned opcode = 0xB6;
2819 if (mode_is_signed(smaller_mode)) opcode |= 0x08;
2820 if (get_mode_size_bits(smaller_mode) == 16) opcode |= 0x01;
2821 bemit_0f_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
2824 static void bemit_popcnt(ir_node const *const node)
2827 bemit_0f_unop_reg(node, 0xB8, n_ia32_Popcnt_operand);
2833 static void bemit_push(const ir_node *node)
2835 const ir_node *value = get_irn_n(node, n_ia32_Push_val);
2837 if (is_ia32_Immediate(value)) {
2838 const ia32_immediate_attr_t *attr
2839 = get_ia32_immediate_attr_const(value);
2840 unsigned size = get_signed_imm_size(attr->offset);
2846 bemit8((unsigned char)attr->offset);
2851 bemit_immediate(value, false);
2854 } else if (is_ia32_NoReg_GP(value)) {
2856 bemit_mod_am(6, node);
2858 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_Push_val);
2859 bemit8(0x50 + reg_gp_map[reg->index]);
2866 static void bemit_pop(const ir_node *node)
2868 const arch_register_t *reg = arch_get_irn_register_out(node, pn_ia32_Pop_res);
2869 bemit8(0x58 + reg_gp_map[reg->index]);
2872 static void bemit_popmem(const ir_node *node)
2875 bemit_mod_am(0, node);
2878 static void bemit_call(const ir_node *node)
2880 ir_node *proc = get_irn_n(node, n_ia32_Call_addr);
2882 if (is_ia32_Immediate(proc)) {
2884 bemit_immediate(proc, true);
2886 bemit_unop(node, 0xFF, 2, n_ia32_Call_addr);
2890 static void bemit_jmp(const ir_node *dest_block)
2893 bemit_jmp_destination(dest_block);
2896 static void bemit_jump(const ir_node *node)
2898 if (can_be_fallthrough(node))
2901 bemit_jmp(get_cfop_target_block(node));
2904 static void bemit_jcc(ia32_condition_code_t pnc, const ir_node *dest_block)
2906 unsigned char cc = pnc2cc(pnc);
2909 bemit_jmp_destination(dest_block);
2912 static void bemit_jp(bool odd, const ir_node *dest_block)
2916 bemit_jmp_destination(dest_block);
2919 static void bemit_ia32_jcc(const ir_node *node)
2921 ia32_condition_code_t cc = get_ia32_condcode(node);
2922 const ir_node *dest_true;
2923 const ir_node *dest_false;
2925 cc = determine_final_cc(node, 0, cc);
2927 /* get both Projs */
2928 ir_node const *proj_true = be_get_Proj_for_pn(node, pn_ia32_Jcc_true);
2929 assert(proj_true && "Jcc without true Proj");
2931 ir_node const *proj_false = be_get_Proj_for_pn(node, pn_ia32_Jcc_false);
2932 assert(proj_false && "Jcc without false Proj");
2934 if (can_be_fallthrough(proj_true)) {
2935 /* exchange both proj's so the second one can be omitted */
2936 const ir_node *t = proj_true;
2938 proj_true = proj_false;
2940 cc = ia32_negate_condition_code(cc);
2943 dest_true = get_cfop_target_block(proj_true);
2944 dest_false = get_cfop_target_block(proj_false);
2946 if (cc & ia32_cc_float_parity_cases) {
2947 /* Some floating point comparisons require a test of the parity flag,
2948 * which indicates that the result is unordered */
2949 if (cc & ia32_cc_negated) {
2950 bemit_jp(false, dest_true);
2952 /* we need a local label if the false proj is a fallthrough
2953 * as the falseblock might have no label emitted then */
2954 if (can_be_fallthrough(proj_false)) {
2956 bemit8(0x06); // jp + 6
2958 bemit_jp(false, dest_false);
2962 bemit_jcc(cc, dest_true);
2964 /* the second Proj might be a fallthrough */
2965 if (can_be_fallthrough(proj_false)) {
2966 /* it's a fallthrough */
2968 bemit_jmp(dest_false);
2972 static void bemit_switchjmp(const ir_node *node)
2974 ir_entity *jump_table = get_ia32_am_sc(node);
2975 const ir_switch_table *table = get_ia32_switch_table(node);
2977 bemit8(0xFF); // jmp *tbl.label(,%in,4)
2978 bemit_mod_am(0x05, node);
2980 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
2986 static void bemit_return(const ir_node *node)
2988 unsigned pop = be_Return_get_pop(node);
2989 if (pop > 0 || be_Return_get_emit_pop(node)) {
2991 assert(pop <= 0xffff);
2998 static void bemit_subsp(const ir_node *node)
3000 const arch_register_t *out;
3003 /* mov %esp, %out */
3005 out = arch_get_irn_register_out(node, 1);
3006 bemit8(MOD_REG | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x04));
3009 static void bemit_incsp(const ir_node *node)
3012 const arch_register_t *reg;
3016 offs = be_get_IncSP_offset(node);
3027 size = get_signed_imm_size(offs);
3028 bemit8(size == 1 ? 0x83 : 0x81);
3030 reg = arch_get_irn_register_out(node, 0);
3031 bemit_modru(reg, ext);
3040 static void bemit_copybi(const ir_node *node)
3042 unsigned size = get_ia32_copyb_size(node);
3044 bemit8(0xA4); // movsb
3047 bemit8(0xA5); // movsw
3051 bemit8(0xA5); // movsl
3055 static void bemit_fbinop(ir_node const *const node, unsigned const op_fwd, unsigned const op_rev)
3057 ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
3058 unsigned const op = attr->attr.data.ins_permuted ? op_rev : op_fwd;
3059 if (get_ia32_op_type(node) == ia32_Normal) {
3060 assert(!attr->pop || attr->res_in_reg);
3062 unsigned char op0 = 0xD8;
3063 if (attr->res_in_reg) op0 |= 0x04;
3064 if (attr->pop) op0 |= 0x02;
3067 bemit8(MOD_REG | ENC_REG(op) | ENC_RM(attr->reg->index));
3072 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3073 bemit8(size == 32 ? 0xD8 : 0xDC);
3074 bemit_mod_am(op, node);
3078 static void bemit_fop_reg(ir_node const *const node, unsigned char const op0, unsigned char const op1)
3081 bemit8(op1 + get_ia32_x87_attr_const(node)->reg->index);
3084 static void bemit_fabs(const ir_node *node)
3092 static void bemit_fadd(const ir_node *node)
3094 bemit_fbinop(node, 0, 0);
3097 static void bemit_fchs(const ir_node *node)
3105 static void bemit_fdiv(const ir_node *node)
3107 bemit_fbinop(node, 6, 7);
3110 static void bemit_ffreep(ir_node const *const node)
3112 bemit_fop_reg(node, 0xDF, 0xC0);
3115 static void bemit_fild(const ir_node *node)
3117 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3119 bemit8(0xDF); // filds
3120 bemit_mod_am(0, node);
3124 bemit8(0xDB); // fildl
3125 bemit_mod_am(0, node);
3129 bemit8(0xDF); // fildll
3130 bemit_mod_am(5, node);
3134 panic("invalid mode size");
3138 static void bemit_fist(const ir_node *node)
3141 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3143 case 16: bemit8(0xDF); op = 2; break; // fist[p]s
3144 case 32: bemit8(0xDB); op = 2; break; // fist[p]l
3145 case 64: bemit8(0xDF); op = 6; break; // fistpll
3146 default: panic("invalid mode size");
3148 if (get_ia32_x87_attr_const(node)->pop)
3150 // There is only a pop variant for 64 bit integer store.
3151 assert(size < 64 || get_ia32_x87_attr_const(node)->pop);
3152 bemit_mod_am(op, node);
3155 static void bemit_fisttp(ir_node const *const node)
3157 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3158 case 16: bemit8(0xDF); break; // fisttps
3159 case 32: bemit8(0xDB); break; // fisttpl
3160 case 64: bemit8(0xDD); break; // fisttpll
3161 default: panic("Invalid mode size");
3163 bemit_mod_am(1, node);
3166 static void bemit_fld(const ir_node *node)
3168 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3170 bemit8(0xD9); // flds
3171 bemit_mod_am(0, node);
3175 bemit8(0xDD); // fldl
3176 bemit_mod_am(0, node);
3181 bemit8(0xDB); // fldt
3182 bemit_mod_am(5, node);
3186 panic("invalid mode size");
3190 static void bemit_fld1(const ir_node *node)
3194 bemit8(0xE8); // fld1
3197 static void bemit_fldcw(const ir_node *node)
3199 bemit8(0xD9); // fldcw
3200 bemit_mod_am(5, node);
3203 static void bemit_fldz(const ir_node *node)
3207 bemit8(0xEE); // fldz
3210 static void bemit_fmul(const ir_node *node)
3212 bemit_fbinop(node, 1, 1);
3215 static void bemit_fpop(const ir_node *node)
3217 bemit_fop_reg(node, 0xDD, 0xD8);
3220 static void bemit_fpush(const ir_node *node)
3222 bemit_fop_reg(node, 0xD9, 0xC0);
3225 static void bemit_fpushcopy(const ir_node *node)
3227 bemit_fop_reg(node, 0xD9, 0xC0);
3230 static void bemit_fst(const ir_node *node)
3233 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3235 case 32: bemit8(0xD9); op = 2; break; // fst[p]s
3236 case 64: bemit8(0xDD); op = 2; break; // fst[p]l
3238 case 96: bemit8(0xDB); op = 6; break; // fstpt
3239 default: panic("invalid mode size");
3241 if (get_ia32_x87_attr_const(node)->pop)
3243 // There is only a pop variant for long double store.
3244 assert(size < 80 || get_ia32_x87_attr_const(node)->pop);
3245 bemit_mod_am(op, node);
3248 static void bemit_fsub(const ir_node *node)
3250 bemit_fbinop(node, 4, 5);
3253 static void bemit_fnstcw(const ir_node *node)
3255 bemit8(0xD9); // fnstcw
3256 bemit_mod_am(7, node);
3259 static void bemit_fnstsw(void)
3261 bemit8(0xDF); // fnstsw %ax
3265 static void bemit_ftstfnstsw(const ir_node *node)
3269 bemit8(0xD9); // ftst
3274 static void bemit_fucomi(const ir_node *node)
3276 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3277 bemit8(attr->pop ? 0xDF : 0xDB); // fucom[p]i
3278 bemit8(0xE8 + attr->reg->index);
3281 static void bemit_fucomfnstsw(const ir_node *node)
3283 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3284 bemit8(0xDD); // fucom[p]
3285 bemit8((attr->pop ? 0xE8 : 0xE0) + attr->reg->index);
3289 static void bemit_fucomppfnstsw(const ir_node *node)
3293 bemit8(0xDA); // fucompp
3298 static void bemit_fxch(const ir_node *node)
3300 bemit_fop_reg(node, 0xD9, 0xC8);
3303 static void ia32_register_binary_emitters(void)
3305 /* first clear the generic function pointer for all ops */
3306 ir_clear_opcodes_generic_func();
3308 /* benode emitter */
3309 be_set_emitter(op_be_Copy, bemit_copy);
3310 be_set_emitter(op_be_CopyKeep, bemit_copy);
3311 be_set_emitter(op_be_IncSP, bemit_incsp);
3312 be_set_emitter(op_be_Perm, bemit_perm);
3313 be_set_emitter(op_be_Return, bemit_return);
3314 be_set_emitter(op_ia32_Adc, bemit_adc);
3315 be_set_emitter(op_ia32_Add, bemit_add);
3316 be_set_emitter(op_ia32_AddMem, bemit_addmem);
3317 be_set_emitter(op_ia32_And, bemit_and);
3318 be_set_emitter(op_ia32_AndMem, bemit_andmem);
3319 be_set_emitter(op_ia32_Asm, emit_ia32_Asm); // TODO implement binary emitter
3320 be_set_emitter(op_ia32_Breakpoint, bemit_int3);
3321 be_set_emitter(op_ia32_Bsf, bemit_bsf);
3322 be_set_emitter(op_ia32_Bsr, bemit_bsr);
3323 be_set_emitter(op_ia32_Bswap, bemit_bswap);
3324 be_set_emitter(op_ia32_Bt, bemit_bt);
3325 be_set_emitter(op_ia32_CMovcc, bemit_cmovcc);
3326 be_set_emitter(op_ia32_Call, bemit_call);
3327 be_set_emitter(op_ia32_Cltd, bemit_cltd);
3328 be_set_emitter(op_ia32_Cmc, bemit_cmc);
3329 be_set_emitter(op_ia32_Cmp, bemit_cmp);
3330 be_set_emitter(op_ia32_Const, bemit_mov_const);
3331 be_set_emitter(op_ia32_Conv_I2I, bemit_conv_i2i);
3332 be_set_emitter(op_ia32_CopyB_i, bemit_copybi);
3333 be_set_emitter(op_ia32_Cwtl, bemit_cwtl);
3334 be_set_emitter(op_ia32_Dec, bemit_dec);
3335 be_set_emitter(op_ia32_DecMem, bemit_decmem);
3336 be_set_emitter(op_ia32_Div, bemit_div);
3337 be_set_emitter(op_ia32_FldCW, bemit_fldcw);
3338 be_set_emitter(op_ia32_FnstCW, bemit_fnstcw);
3339 be_set_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw);
3340 be_set_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw);
3341 be_set_emitter(op_ia32_Fucomi, bemit_fucomi);
3342 be_set_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw);
3343 be_set_emitter(op_ia32_IDiv, bemit_idiv);
3344 be_set_emitter(op_ia32_IJmp, bemit_ijmp);
3345 be_set_emitter(op_ia32_IMul, bemit_imul);
3346 be_set_emitter(op_ia32_IMul1OP, bemit_imul1op);
3347 be_set_emitter(op_ia32_Inc, bemit_inc);
3348 be_set_emitter(op_ia32_IncMem, bemit_incmem);
3349 be_set_emitter(op_ia32_Jcc, bemit_ia32_jcc);
3350 be_set_emitter(op_ia32_Jmp, bemit_jump);
3351 be_set_emitter(op_ia32_LdTls, bemit_ldtls);
3352 be_set_emitter(op_ia32_Lea, bemit_lea);
3353 be_set_emitter(op_ia32_Leave, bemit_leave);
3354 be_set_emitter(op_ia32_Load, bemit_load);
3355 be_set_emitter(op_ia32_Minus64Bit, bemit_minus64bit);
3356 be_set_emitter(op_ia32_Mul, bemit_mul);
3357 be_set_emitter(op_ia32_Neg, bemit_neg);
3358 be_set_emitter(op_ia32_NegMem, bemit_negmem);
3359 be_set_emitter(op_ia32_Not, bemit_not);
3360 be_set_emitter(op_ia32_NotMem, bemit_notmem);
3361 be_set_emitter(op_ia32_Or, bemit_or);
3362 be_set_emitter(op_ia32_OrMem, bemit_ormem);
3363 be_set_emitter(op_ia32_Pop, bemit_pop);
3364 be_set_emitter(op_ia32_PopEbp, bemit_pop);
3365 be_set_emitter(op_ia32_PopMem, bemit_popmem);
3366 be_set_emitter(op_ia32_Popcnt, bemit_popcnt);
3367 be_set_emitter(op_ia32_Push, bemit_push);
3368 be_set_emitter(op_ia32_RepPrefix, bemit_rep);
3369 be_set_emitter(op_ia32_Rol, bemit_rol);
3370 be_set_emitter(op_ia32_RolMem, bemit_rolmem);
3371 be_set_emitter(op_ia32_Ror, bemit_ror);
3372 be_set_emitter(op_ia32_RorMem, bemit_rormem);
3373 be_set_emitter(op_ia32_Sahf, bemit_sahf);
3374 be_set_emitter(op_ia32_Sar, bemit_sar);
3375 be_set_emitter(op_ia32_SarMem, bemit_sarmem);
3376 be_set_emitter(op_ia32_Sbb, bemit_sbb);
3377 be_set_emitter(op_ia32_Sbb0, bemit_sbb0);
3378 be_set_emitter(op_ia32_Setcc, bemit_setcc);
3379 be_set_emitter(op_ia32_Shl, bemit_shl);
3380 be_set_emitter(op_ia32_ShlD, bemit_shld);
3381 be_set_emitter(op_ia32_ShlMem, bemit_shlmem);
3382 be_set_emitter(op_ia32_Shr, bemit_shr);
3383 be_set_emitter(op_ia32_ShrD, bemit_shrd);
3384 be_set_emitter(op_ia32_ShrMem, bemit_shrmem);
3385 be_set_emitter(op_ia32_Stc, bemit_stc);
3386 be_set_emitter(op_ia32_Store, bemit_store);
3387 be_set_emitter(op_ia32_Sub, bemit_sub);
3388 be_set_emitter(op_ia32_SubMem, bemit_submem);
3389 be_set_emitter(op_ia32_SubSP, bemit_subsp);
3390 be_set_emitter(op_ia32_SwitchJmp, bemit_switchjmp);
3391 be_set_emitter(op_ia32_Test, bemit_test);
3392 be_set_emitter(op_ia32_Xor, bemit_xor);
3393 be_set_emitter(op_ia32_Xor0, bemit_xor0);
3394 be_set_emitter(op_ia32_XorMem, bemit_xormem);
3395 be_set_emitter(op_ia32_fabs, bemit_fabs);
3396 be_set_emitter(op_ia32_fadd, bemit_fadd);
3397 be_set_emitter(op_ia32_fchs, bemit_fchs);
3398 be_set_emitter(op_ia32_fdiv, bemit_fdiv);
3399 be_set_emitter(op_ia32_ffreep, bemit_ffreep);
3400 be_set_emitter(op_ia32_fild, bemit_fild);
3401 be_set_emitter(op_ia32_fist, bemit_fist);
3402 be_set_emitter(op_ia32_fisttp, bemit_fisttp);
3403 be_set_emitter(op_ia32_fld, bemit_fld);
3404 be_set_emitter(op_ia32_fld1, bemit_fld1);
3405 be_set_emitter(op_ia32_fldz, bemit_fldz);
3406 be_set_emitter(op_ia32_fmul, bemit_fmul);
3407 be_set_emitter(op_ia32_fpop, bemit_fpop);
3408 be_set_emitter(op_ia32_fpush, bemit_fpush);
3409 be_set_emitter(op_ia32_fpushCopy, bemit_fpushcopy);
3410 be_set_emitter(op_ia32_fst, bemit_fst);
3411 be_set_emitter(op_ia32_fsub, bemit_fsub);
3412 be_set_emitter(op_ia32_fxch, bemit_fxch);
3414 /* ignore the following nodes */
3415 be_set_emitter(op_Phi, be_emit_nothing);
3416 be_set_emitter(op_be_Keep, be_emit_nothing);
3417 be_set_emitter(op_be_Start, be_emit_nothing);
3418 be_set_emitter(op_ia32_ProduceVal, be_emit_nothing);
3419 be_set_emitter(op_ia32_Unknown, be_emit_nothing);
3422 static void gen_binary_block(ir_node *block)
3424 ia32_emit_block_header(block);
3426 /* emit the contents of the block */
3427 sched_foreach(block, node) {
3428 ia32_emit_node(node);
3432 void ia32_gen_binary_routine(ir_graph *irg)
3434 ir_entity *entity = get_irg_entity(irg);
3435 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
3436 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
3437 ir_node **blk_sched = irg_data->blk_sched;
3439 parameter_dbg_info_t *infos;
3441 isa = (ia32_isa_t*) arch_env;
3443 ia32_register_binary_emitters();
3445 infos = construct_parameter_infos(irg);
3446 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
3450 /* we use links to point to target blocks */
3451 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
3452 irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
3454 /* initialize next block links */
3455 n = ARR_LEN(blk_sched);
3456 for (i = 0; i < n; ++i) {
3457 ir_node *block = blk_sched[i];
3458 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
3460 set_irn_link(block, prev);
3463 for (i = 0; i < n; ++i) {
3464 ir_node *block = blk_sched[i];
3465 gen_binary_block(block);
3468 be_gas_emit_function_epilog(entity);
3470 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
3474 void ia32_init_emitter(void)
3476 lc_opt_entry_t *be_grp;
3477 lc_opt_entry_t *ia32_grp;
3479 be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
3480 ia32_grp = lc_opt_get_grp(be_grp, "ia32");
3482 lc_opt_add_table(ia32_grp, ia32_emitter_options);
3486 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");