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); \
2206 #define BINOPMEM(op, ext) \
2207 static void bemit_##op(const ir_node *node) \
2210 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2213 val = get_irn_n(node, n_ia32_unary_op); \
2214 if (is_ia32_Immediate(val)) { \
2215 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(val); \
2216 int offset = attr->offset; \
2217 if (attr->symconst == NULL && get_signed_imm_size(offset) == 1) { \
2219 bemit_mod_am(ext, node); \
2223 bemit_mod_am(ext, node); \
2227 bemit_entity(attr->symconst, attr->sc_sign, offset, false); \
2231 bemit8(ext << 3 | 1); \
2232 bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
2236 static void bemit_##op##8bit(const ir_node *node) \
2238 ir_node *val = get_irn_n(node, n_ia32_unary_op); \
2239 if (is_ia32_Immediate(val)) { \
2241 bemit_mod_am(ext, node); \
2242 bemit8(get_ia32_immediate_attr_const(val)->offset); \
2245 bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
2257 * Creates a function for an Unop with code /ext encoding.
2259 #define UNOP(op, code, ext, input) \
2260 static void bemit_ ## op(const ir_node *node) { \
2261 bemit_unop(node, code, ext, input); \
2264 UNOP(not, 0xF7, 2, n_ia32_Not_val)
2265 UNOP(neg, 0xF7, 3, n_ia32_Neg_val)
2266 UNOP(mul, 0xF7, 4, n_ia32_Mul_right)
2267 UNOP(imul1op, 0xF7, 5, n_ia32_IMul1OP_right)
2268 UNOP(div, 0xF7, 6, n_ia32_Div_divisor)
2269 UNOP(idiv, 0xF7, 7, n_ia32_IDiv_divisor)
2271 /* TODO: am support for IJmp */
2272 UNOP(ijmp, 0xFF, 4, n_ia32_IJmp_target)
2274 #define SHIFT(op, ext) \
2275 static void bemit_##op(const ir_node *node) \
2277 const arch_register_t *out = arch_get_irn_register_out(node, 0); \
2278 ir_node *count = get_irn_n(node, 1); \
2279 if (is_ia32_Immediate(count)) { \
2280 int offset = get_ia32_immediate_attr_const(count)->offset; \
2281 if (offset == 1) { \
2283 bemit_modru(out, ext); \
2286 bemit_modru(out, ext); \
2291 bemit_modru(out, ext); \
2295 static void bemit_##op##mem(const ir_node *node) \
2298 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2301 count = get_irn_n(node, 1); \
2302 if (is_ia32_Immediate(count)) { \
2303 int offset = get_ia32_immediate_attr_const(count)->offset; \
2304 if (offset == 1) { \
2305 bemit8(size == 8 ? 0xD0 : 0xD1); \
2306 bemit_mod_am(ext, node); \
2308 bemit8(size == 8 ? 0xC0 : 0xC1); \
2309 bemit_mod_am(ext, node); \
2313 bemit8(size == 8 ? 0xD2 : 0xD3); \
2314 bemit_mod_am(ext, node); \
2324 static void bemit_shld(const ir_node *node)
2326 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShlD_val_low);
2327 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShlD_res);
2328 ir_node *count = get_irn_n(node, n_ia32_ShlD_count);
2330 if (is_ia32_Immediate(count)) {
2332 bemit_modrr(out, in);
2333 bemit8(get_ia32_immediate_attr_const(count)->offset);
2336 bemit_modrr(out, in);
2340 static void bemit_shrd(const ir_node *node)
2342 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShrD_val_low);
2343 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShrD_res);
2344 ir_node *count = get_irn_n(node, n_ia32_ShrD_count);
2346 if (is_ia32_Immediate(count)) {
2348 bemit_modrr(out, in);
2349 bemit8(get_ia32_immediate_attr_const(count)->offset);
2352 bemit_modrr(out, in);
2356 static void bemit_sbb0(ir_node const *const node)
2358 arch_register_t const *const out = arch_get_irn_register_out(node, pn_ia32_Sbb0_res);
2359 unsigned char const reg = reg_gp_map[out->index];
2361 bemit8(MOD_REG | ENC_REG(reg) | ENC_RM(reg));
2365 * binary emitter for setcc.
2367 static void bemit_setcc(const ir_node *node)
2369 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
2371 ia32_condition_code_t cc = get_ia32_condcode(node);
2372 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
2373 if (cc & ia32_cc_float_parity_cases) {
2374 if (cc & ia32_cc_negated) {
2377 bemit8(0x90 | pnc2cc(cc));
2378 bemit_modrm8(REG_LOW, dreg);
2383 bemit_modrm8(REG_HIGH, dreg);
2385 /* orb %>dreg, %<dreg */
2387 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2391 bemit8(0x90 | pnc2cc(cc));
2392 bemit_modrm8(REG_LOW, dreg);
2397 bemit_modrm8(REG_HIGH, dreg);
2399 /* andb %>dreg, %<dreg */
2401 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2406 bemit8(0x90 | pnc2cc(cc));
2407 bemit_modrm8(REG_LOW, dreg);
2411 static void bemit_bsf(ir_node const *const node)
2413 bemit_0f_unop_reg(node, 0xBC, n_ia32_Bsf_operand);
2416 static void bemit_bsr(ir_node const *const node)
2418 bemit_0f_unop_reg(node, 0xBD, n_ia32_Bsr_operand);
2421 static void bemit_bswap(ir_node const *const node)
2424 bemit_modru(arch_get_irn_register_out(node, pn_ia32_Bswap_res), 1);
2427 static void bemit_bt(ir_node const *const node)
2430 arch_register_t const *const lreg = arch_get_irn_register_in(node, n_ia32_Bt_left);
2431 ir_node const *const right = get_irn_n(node, n_ia32_Bt_right);
2432 if (is_ia32_Immediate(right)) {
2433 ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(right);
2434 int const offset = attr->offset;
2435 assert(!attr->symconst);
2436 assert(get_signed_imm_size(offset) == 1);
2438 bemit_modru(lreg, 4);
2442 bemit_modrr(lreg, arch_get_irn_register(right));
2446 static void bemit_cmovcc(const ir_node *node)
2448 const ia32_attr_t *attr = get_ia32_attr_const(node);
2449 int ins_permuted = attr->data.ins_permuted;
2450 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
2451 ia32_condition_code_t cc = get_ia32_condcode(node);
2452 const arch_register_t *in_true;
2453 const arch_register_t *in_false;
2455 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
2457 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
2458 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
2460 /* should be same constraint fullfilled? */
2461 if (out == in_false) {
2462 /* yes -> nothing to do */
2463 } else if (out == in_true) {
2464 assert(get_ia32_op_type(node) == ia32_Normal);
2465 ins_permuted = !ins_permuted;
2469 bemit8(0x8B); // mov %in_false, %out
2470 bemit_modrr(in_false, out);
2474 cc = ia32_negate_condition_code(cc);
2476 if (cc & ia32_cc_float_parity_cases)
2477 panic("cmov can't handle parity float cases");
2480 bemit8(0x40 | pnc2cc(cc));
2481 if (get_ia32_op_type(node) == ia32_Normal) {
2482 bemit_modrr(in_true, out);
2484 bemit_mod_am(reg_gp_map[out->index], node);
2488 static void bemit_cmp(const ir_node *node)
2490 unsigned ls_size = get_mode_size_bits(get_ia32_ls_mode(node));
2496 right = get_irn_n(node, n_ia32_binary_right);
2497 if (is_ia32_Immediate(right)) {
2498 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2499 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2500 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2503 if (attr->symconst != NULL) {
2506 /* check for sign extension */
2507 size = get_signed_imm_size(attr->offset);
2512 bemit8(0x80 | OP_16_32_IMM8);
2513 /* cmp has this special mode */
2514 if (get_ia32_op_type(node) == ia32_Normal) {
2515 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2516 bemit_modru(reg, 7);
2518 bemit_mod_am(7, node);
2520 bemit8((unsigned char)attr->offset);
2524 /* check for eax variant: this variant is shorter for 32bit immediates only */
2525 if (get_ia32_op_type(node) == ia32_Normal) {
2526 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2527 if (reg->index == REG_GP_EAX) {
2531 bemit_modru(reg, 7);
2535 bemit_mod_am(7, node);
2537 if (ls_size == 16) {
2538 bemit16(attr->offset);
2540 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2544 panic("invalid imm size?!?");
2546 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2548 if (get_ia32_op_type(node) == ia32_Normal) {
2549 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2550 bemit_modrr(op2, out);
2552 bemit_mod_am(reg_gp_map[out->index], node);
2557 static void bemit_cmp8bit(const ir_node *node)
2559 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2560 if (is_ia32_Immediate(right)) {
2561 if (get_ia32_op_type(node) == ia32_Normal) {
2562 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2563 if (out->index == REG_GP_EAX) {
2567 bemit_modru(out, 7);
2571 bemit_mod_am(7, node);
2573 bemit8(get_ia32_immediate_attr_const(right)->offset);
2575 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2577 if (get_ia32_op_type(node) == ia32_Normal) {
2578 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Cmp_right);
2579 bemit_modrr(out, in);
2581 bemit_mod_am(reg_gp_map[out->index], node);
2586 static void bemit_test(ir_node const *const node)
2588 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
2592 unsigned const op = size == 8 ? OP_8 : OP_16_32;
2593 ir_node *const right = get_irn_n(node, n_ia32_Test_right);
2594 if (is_ia32_Immediate(right)) {
2595 /* Emit the main opcode. */
2596 if (get_ia32_op_type(node) == ia32_Normal) {
2597 arch_register_t const *const dst = arch_get_irn_register_in(node, n_ia32_Test_left);
2598 /* Try to use the shorter al/ax/eax form. */
2599 if (dst->index == REG_GP_EAX) {
2603 bemit_modru(dst, 0);
2607 bemit_mod_am(0, node);
2610 /* Emit the immediate. */
2611 ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(right);
2613 case 8: bemit8(attr->offset); break;
2614 case 16: bemit16(attr->offset); break;
2615 case 32: bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false); break;
2619 arch_register_t const *const dst = arch_get_irn_register_in(node, n_ia32_Test_left);
2620 if (get_ia32_op_type(node) == ia32_Normal) {
2621 arch_register_t const *const src = arch_get_irn_register(right);
2622 bemit_modrr(src, dst);
2624 bemit_mod_am(reg_gp_map[dst->index], node);
2629 static void bemit_imul(const ir_node *node)
2631 ir_node *right = get_irn_n(node, n_ia32_IMul_right);
2632 /* Do we need the immediate form? */
2633 if (is_ia32_Immediate(right)) {
2634 int imm = get_ia32_immediate_attr_const(right)->offset;
2635 if (get_signed_imm_size(imm) == 1) {
2636 bemit_unop_reg(node, 0x6B, n_ia32_IMul_left);
2639 bemit_unop_reg(node, 0x69, n_ia32_IMul_left);
2643 bemit_0f_unop_reg(node, 0xAF, n_ia32_IMul_right);
2647 static void bemit_dec(const ir_node *node)
2649 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Dec_res);
2650 bemit8(0x48 + reg_gp_map[out->index]);
2653 static void bemit_inc(const ir_node *node)
2655 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Inc_res);
2656 bemit8(0x40 + reg_gp_map[out->index]);
2659 #define UNOPMEM(op, code, ext) \
2660 static void bemit_##op(const ir_node *node) \
2662 bemit_unop_mem(node, code, ext); \
2665 UNOPMEM(notmem, 0xF6, 2)
2666 UNOPMEM(negmem, 0xF6, 3)
2667 UNOPMEM(incmem, 0xFE, 0)
2668 UNOPMEM(decmem, 0xFE, 1)
2670 static void bemit_ldtls(const ir_node *node)
2672 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2674 bemit8(0x65); // gs:
2675 if (out->index == REG_GP_EAX) {
2676 bemit8(0xA1); // movl 0, %eax
2678 bemit8(0x8B); // movl 0, %reg
2679 bemit8(MOD_IND | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x05));
2687 static void bemit_lea(const ir_node *node)
2689 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2691 bemit_mod_am(reg_gp_map[out->index], node);
2694 /* helper function for bemit_minus64bit */
2695 static void bemit_helper_mov(const arch_register_t *src, const arch_register_t *dst)
2697 bemit8(0x8B); // movl %src, %dst
2698 bemit_modrr(src, dst);
2701 /* helper function for bemit_minus64bit */
2702 static void bemit_helper_neg(const arch_register_t *reg)
2704 bemit8(0xF7); // negl %reg
2705 bemit_modru(reg, 3);
2708 /* helper function for bemit_minus64bit */
2709 static void bemit_helper_sbb0(const arch_register_t *reg)
2711 bemit8(0x83); // sbbl $0, %reg
2712 bemit_modru(reg, 3);
2716 /* helper function for bemit_minus64bit */
2717 static void bemit_helper_sbb(const arch_register_t *src, const arch_register_t *dst)
2719 bemit8(0x1B); // sbbl %src, %dst
2720 bemit_modrr(src, dst);
2723 /* helper function for bemit_minus64bit */
2724 static void bemit_helper_xchg(const arch_register_t *src, const arch_register_t *dst)
2726 if (src->index == REG_GP_EAX) {
2727 bemit8(0x90 + reg_gp_map[dst->index]); // xchgl %eax, %dst
2728 } else if (dst->index == REG_GP_EAX) {
2729 bemit8(0x90 + reg_gp_map[src->index]); // xchgl %src, %eax
2731 bemit8(0x87); // xchgl %src, %dst
2732 bemit_modrr(src, dst);
2736 /* helper function for bemit_minus64bit */
2737 static void bemit_helper_zero(const arch_register_t *reg)
2739 bemit8(0x33); // xorl %reg, %reg
2740 bemit_modrr(reg, reg);
2743 static void bemit_minus64bit(const ir_node *node)
2745 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
2746 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
2747 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
2748 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
2750 if (out_lo == in_lo) {
2751 if (out_hi != in_hi) {
2752 /* a -> a, b -> d */
2755 /* a -> a, b -> b */
2758 } else if (out_lo == in_hi) {
2759 if (out_hi == in_lo) {
2760 /* a -> b, b -> a */
2761 bemit_helper_xchg(in_lo, in_hi);
2764 /* a -> b, b -> d */
2765 bemit_helper_mov(in_hi, out_hi);
2766 bemit_helper_mov(in_lo, out_lo);
2770 if (out_hi == in_lo) {
2771 /* a -> c, b -> a */
2772 bemit_helper_mov(in_lo, out_lo);
2774 } else if (out_hi == in_hi) {
2775 /* a -> c, b -> b */
2776 bemit_helper_mov(in_lo, out_lo);
2779 /* a -> c, b -> d */
2780 bemit_helper_mov(in_lo, out_lo);
2786 bemit_helper_neg( out_hi);
2787 bemit_helper_neg( out_lo);
2788 bemit_helper_sbb0(out_hi);
2792 bemit_helper_zero(out_hi);
2793 bemit_helper_neg( out_lo);
2794 bemit_helper_sbb( in_hi, out_hi);
2798 * Emit a single opcode.
2800 #define EMIT_SINGLEOP(op, code) \
2801 static void bemit_ ## op(const ir_node *node) { \
2806 //EMIT_SINGLEOP(daa, 0x27)
2807 //EMIT_SINGLEOP(das, 0x2F)
2808 //EMIT_SINGLEOP(aaa, 0x37)
2809 //EMIT_SINGLEOP(aas, 0x3F)
2810 //EMIT_SINGLEOP(nop, 0x90)
2811 EMIT_SINGLEOP(cwtl, 0x98)
2812 EMIT_SINGLEOP(cltd, 0x99)
2813 //EMIT_SINGLEOP(fwait, 0x9B)
2814 EMIT_SINGLEOP(sahf, 0x9E)
2815 //EMIT_SINGLEOP(popf, 0x9D)
2816 EMIT_SINGLEOP(leave, 0xC9)
2817 EMIT_SINGLEOP(int3, 0xCC)
2818 //EMIT_SINGLEOP(iret, 0xCF)
2819 //EMIT_SINGLEOP(xlat, 0xD7)
2820 //EMIT_SINGLEOP(lock, 0xF0)
2821 EMIT_SINGLEOP(rep, 0xF3)
2822 //EMIT_SINGLEOP(halt, 0xF4)
2823 EMIT_SINGLEOP(cmc, 0xF5)
2824 EMIT_SINGLEOP(stc, 0xF9)
2825 //EMIT_SINGLEOP(cli, 0xFA)
2826 //EMIT_SINGLEOP(sti, 0xFB)
2827 //EMIT_SINGLEOP(std, 0xFD)
2830 * Emits a MOV out, [MEM].
2832 static void bemit_load(const ir_node *node)
2834 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2836 if (out->index == REG_GP_EAX) {
2837 ir_node *base = get_irn_n(node, n_ia32_base);
2838 int has_base = !is_ia32_NoReg_GP(base);
2839 ir_node *idx = get_irn_n(node, n_ia32_index);
2840 int has_index = !is_ia32_NoReg_GP(idx);
2841 if (!has_base && !has_index) {
2842 ir_entity *ent = get_ia32_am_sc(node);
2843 int offs = get_ia32_am_offs_int(node);
2844 /* load from constant address to EAX can be encoded
2847 bemit_entity(ent, 0, offs, false);
2852 bemit_mod_am(reg_gp_map[out->index], node);
2856 * Emits a MOV [mem], in.
2858 static void bemit_store(const ir_node *node)
2860 const ir_node *value = get_irn_n(node, n_ia32_Store_val);
2861 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2863 if (is_ia32_Immediate(value)) {
2866 bemit_mod_am(0, node);
2867 bemit8(get_ia32_immediate_attr_const(value)->offset);
2868 } else if (size == 16) {
2871 bemit_mod_am(0, node);
2872 bemit16(get_ia32_immediate_attr_const(value)->offset);
2875 bemit_mod_am(0, node);
2876 bemit_immediate(value, false);
2879 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Store_val);
2881 if (in->index == REG_GP_EAX) {
2882 ir_node *base = get_irn_n(node, n_ia32_base);
2883 int has_base = !is_ia32_NoReg_GP(base);
2884 ir_node *idx = get_irn_n(node, n_ia32_index);
2885 int has_index = !is_ia32_NoReg_GP(idx);
2886 if (!has_base && !has_index) {
2887 ir_entity *ent = get_ia32_am_sc(node);
2888 int offs = get_ia32_am_offs_int(node);
2889 /* store to constant address from EAX can be encoded as
2890 * 0xA2/0xA3 [offset]*/
2898 bemit_entity(ent, 0, offs, false);
2910 bemit_mod_am(reg_gp_map[in->index], node);
2914 static void bemit_conv_i2i(const ir_node *node)
2919 ir_mode *const smaller_mode = get_ia32_ls_mode(node);
2920 unsigned opcode = 0xB6;
2921 if (mode_is_signed(smaller_mode)) opcode |= 0x08;
2922 if (get_mode_size_bits(smaller_mode) == 16) opcode |= 0x01;
2923 bemit_0f_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
2926 static void bemit_popcnt(ir_node const *const node)
2929 bemit_0f_unop_reg(node, 0xB8, n_ia32_Popcnt_operand);
2935 static void bemit_push(const ir_node *node)
2937 const ir_node *value = get_irn_n(node, n_ia32_Push_val);
2939 if (is_ia32_Immediate(value)) {
2940 const ia32_immediate_attr_t *attr
2941 = get_ia32_immediate_attr_const(value);
2942 unsigned size = get_signed_imm_size(attr->offset);
2948 bemit8((unsigned char)attr->offset);
2953 bemit_immediate(value, false);
2956 } else if (is_ia32_NoReg_GP(value)) {
2958 bemit_mod_am(6, node);
2960 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_Push_val);
2961 bemit8(0x50 + reg_gp_map[reg->index]);
2968 static void bemit_pop(const ir_node *node)
2970 const arch_register_t *reg = arch_get_irn_register_out(node, pn_ia32_Pop_res);
2971 bemit8(0x58 + reg_gp_map[reg->index]);
2974 static void bemit_popmem(const ir_node *node)
2977 bemit_mod_am(0, node);
2980 static void bemit_call(const ir_node *node)
2982 ir_node *proc = get_irn_n(node, n_ia32_Call_addr);
2984 if (is_ia32_Immediate(proc)) {
2986 bemit_immediate(proc, true);
2988 bemit_unop(node, 0xFF, 2, n_ia32_Call_addr);
2992 static void bemit_jmp(const ir_node *dest_block)
2995 bemit_jmp_destination(dest_block);
2998 static void bemit_jump(const ir_node *node)
3000 if (can_be_fallthrough(node))
3003 bemit_jmp(get_cfop_target_block(node));
3006 static void bemit_jcc(ia32_condition_code_t pnc, const ir_node *dest_block)
3008 unsigned char cc = pnc2cc(pnc);
3011 bemit_jmp_destination(dest_block);
3014 static void bemit_jp(bool odd, const ir_node *dest_block)
3018 bemit_jmp_destination(dest_block);
3021 static void bemit_ia32_jcc(const ir_node *node)
3023 ia32_condition_code_t cc = get_ia32_condcode(node);
3024 const ir_node *dest_true;
3025 const ir_node *dest_false;
3027 cc = determine_final_cc(node, 0, cc);
3029 /* get both Projs */
3030 ir_node const *proj_true = be_get_Proj_for_pn(node, pn_ia32_Jcc_true);
3031 assert(proj_true && "Jcc without true Proj");
3033 ir_node const *proj_false = be_get_Proj_for_pn(node, pn_ia32_Jcc_false);
3034 assert(proj_false && "Jcc without false Proj");
3036 if (can_be_fallthrough(proj_true)) {
3037 /* exchange both proj's so the second one can be omitted */
3038 const ir_node *t = proj_true;
3040 proj_true = proj_false;
3042 cc = ia32_negate_condition_code(cc);
3045 dest_true = get_cfop_target_block(proj_true);
3046 dest_false = get_cfop_target_block(proj_false);
3048 if (cc & ia32_cc_float_parity_cases) {
3049 /* Some floating point comparisons require a test of the parity flag,
3050 * which indicates that the result is unordered */
3051 if (cc & ia32_cc_negated) {
3052 bemit_jp(false, dest_true);
3054 /* we need a local label if the false proj is a fallthrough
3055 * as the falseblock might have no label emitted then */
3056 if (can_be_fallthrough(proj_false)) {
3058 bemit8(0x06); // jp + 6
3060 bemit_jp(false, dest_false);
3064 bemit_jcc(cc, dest_true);
3066 /* the second Proj might be a fallthrough */
3067 if (can_be_fallthrough(proj_false)) {
3068 /* it's a fallthrough */
3070 bemit_jmp(dest_false);
3074 static void bemit_switchjmp(const ir_node *node)
3076 ir_entity *jump_table = get_ia32_am_sc(node);
3077 const ir_switch_table *table = get_ia32_switch_table(node);
3079 bemit8(0xFF); // jmp *tbl.label(,%in,4)
3080 bemit_mod_am(0x05, node);
3082 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
3088 static void bemit_return(const ir_node *node)
3090 unsigned pop = be_Return_get_pop(node);
3091 if (pop > 0 || be_Return_get_emit_pop(node)) {
3093 assert(pop <= 0xffff);
3100 static void bemit_subsp(const ir_node *node)
3102 const arch_register_t *out;
3105 /* mov %esp, %out */
3107 out = arch_get_irn_register_out(node, 1);
3108 bemit8(MOD_REG | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x04));
3111 static void bemit_incsp(const ir_node *node)
3114 const arch_register_t *reg;
3118 offs = be_get_IncSP_offset(node);
3129 size = get_signed_imm_size(offs);
3130 bemit8(size == 1 ? 0x83 : 0x81);
3132 reg = arch_get_irn_register_out(node, 0);
3133 bemit_modru(reg, ext);
3142 static void bemit_copybi(const ir_node *node)
3144 unsigned size = get_ia32_copyb_size(node);
3146 bemit8(0xA4); // movsb
3149 bemit8(0xA5); // movsw
3153 bemit8(0xA5); // movsl
3157 static void bemit_fbinop(ir_node const *const node, unsigned const op_fwd, unsigned const op_rev)
3159 ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
3160 unsigned const op = attr->attr.data.ins_permuted ? op_rev : op_fwd;
3161 if (get_ia32_op_type(node) == ia32_Normal) {
3162 assert(!attr->pop || attr->res_in_reg);
3164 unsigned char op0 = 0xD8;
3165 if (attr->res_in_reg) op0 |= 0x04;
3166 if (attr->pop) op0 |= 0x02;
3169 bemit8(MOD_REG | ENC_REG(op) | ENC_RM(attr->reg->index));
3174 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3175 bemit8(size == 32 ? 0xD8 : 0xDC);
3176 bemit_mod_am(op, node);
3180 static void bemit_fop_reg(ir_node const *const node, unsigned char const op0, unsigned char const op1)
3183 bemit8(op1 + get_ia32_x87_attr_const(node)->reg->index);
3186 static void bemit_fabs(const ir_node *node)
3194 static void bemit_fadd(const ir_node *node)
3196 bemit_fbinop(node, 0, 0);
3199 static void bemit_fchs(const ir_node *node)
3207 static void bemit_fdiv(const ir_node *node)
3209 bemit_fbinop(node, 6, 7);
3212 static void bemit_ffreep(ir_node const *const node)
3214 bemit_fop_reg(node, 0xDF, 0xC0);
3217 static void bemit_fild(const ir_node *node)
3219 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3221 bemit8(0xDF); // filds
3222 bemit_mod_am(0, node);
3226 bemit8(0xDB); // fildl
3227 bemit_mod_am(0, node);
3231 bemit8(0xDF); // fildll
3232 bemit_mod_am(5, node);
3236 panic("invalid mode size");
3240 static void bemit_fist(const ir_node *node)
3243 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3245 case 16: bemit8(0xDF); op = 2; break; // fist[p]s
3246 case 32: bemit8(0xDB); op = 2; break; // fist[p]l
3247 case 64: bemit8(0xDF); op = 6; break; // fistpll
3248 default: panic("invalid mode size");
3250 if (get_ia32_x87_attr_const(node)->pop)
3252 // There is only a pop variant for 64 bit integer store.
3253 assert(size < 64 || get_ia32_x87_attr_const(node)->pop);
3254 bemit_mod_am(op, node);
3257 static void bemit_fisttp(ir_node const *const node)
3259 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3260 case 16: bemit8(0xDF); break; // fisttps
3261 case 32: bemit8(0xDB); break; // fisttpl
3262 case 64: bemit8(0xDD); break; // fisttpll
3263 default: panic("Invalid mode size");
3265 bemit_mod_am(1, node);
3268 static void bemit_fld(const ir_node *node)
3270 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3272 bemit8(0xD9); // flds
3273 bemit_mod_am(0, node);
3277 bemit8(0xDD); // fldl
3278 bemit_mod_am(0, node);
3283 bemit8(0xDB); // fldt
3284 bemit_mod_am(5, node);
3288 panic("invalid mode size");
3292 static void bemit_fld1(const ir_node *node)
3296 bemit8(0xE8); // fld1
3299 static void bemit_fldcw(const ir_node *node)
3301 bemit8(0xD9); // fldcw
3302 bemit_mod_am(5, node);
3305 static void bemit_fldz(const ir_node *node)
3309 bemit8(0xEE); // fldz
3312 static void bemit_fmul(const ir_node *node)
3314 bemit_fbinop(node, 1, 1);
3317 static void bemit_fpop(const ir_node *node)
3319 bemit_fop_reg(node, 0xDD, 0xD8);
3322 static void bemit_fpush(const ir_node *node)
3324 bemit_fop_reg(node, 0xD9, 0xC0);
3327 static void bemit_fpushcopy(const ir_node *node)
3329 bemit_fop_reg(node, 0xD9, 0xC0);
3332 static void bemit_fst(const ir_node *node)
3335 unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
3337 case 32: bemit8(0xD9); op = 2; break; // fst[p]s
3338 case 64: bemit8(0xDD); op = 2; break; // fst[p]l
3340 case 96: bemit8(0xDB); op = 6; break; // fstpt
3341 default: panic("invalid mode size");
3343 if (get_ia32_x87_attr_const(node)->pop)
3345 // There is only a pop variant for long double store.
3346 assert(size < 80 || get_ia32_x87_attr_const(node)->pop);
3347 bemit_mod_am(op, node);
3350 static void bemit_fsub(const ir_node *node)
3352 bemit_fbinop(node, 4, 5);
3355 static void bemit_fnstcw(const ir_node *node)
3357 bemit8(0xD9); // fnstcw
3358 bemit_mod_am(7, node);
3361 static void bemit_fnstsw(void)
3363 bemit8(0xDF); // fnstsw %ax
3367 static void bemit_ftstfnstsw(const ir_node *node)
3371 bemit8(0xD9); // ftst
3376 static void bemit_fucomi(const ir_node *node)
3378 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3379 bemit8(attr->pop ? 0xDF : 0xDB); // fucom[p]i
3380 bemit8(0xE8 + attr->reg->index);
3383 static void bemit_fucomfnstsw(const ir_node *node)
3385 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3386 bemit8(0xDD); // fucom[p]
3387 bemit8((attr->pop ? 0xE8 : 0xE0) + attr->reg->index);
3391 static void bemit_fucomppfnstsw(const ir_node *node)
3395 bemit8(0xDA); // fucompp
3400 static void bemit_fxch(const ir_node *node)
3402 bemit_fop_reg(node, 0xD9, 0xC8);
3405 static void ia32_register_binary_emitters(void)
3407 /* first clear the generic function pointer for all ops */
3408 ir_clear_opcodes_generic_func();
3410 /* benode emitter */
3411 be_set_emitter(op_be_Copy, bemit_copy);
3412 be_set_emitter(op_be_CopyKeep, bemit_copy);
3413 be_set_emitter(op_be_IncSP, bemit_incsp);
3414 be_set_emitter(op_be_Perm, bemit_perm);
3415 be_set_emitter(op_be_Return, bemit_return);
3416 be_set_emitter(op_ia32_Adc, bemit_adc);
3417 be_set_emitter(op_ia32_Add, bemit_add);
3418 be_set_emitter(op_ia32_AddMem, bemit_addmem);
3419 be_set_emitter(op_ia32_AddMem8Bit, bemit_addmem8bit);
3420 be_set_emitter(op_ia32_And, bemit_and);
3421 be_set_emitter(op_ia32_AndMem, bemit_andmem);
3422 be_set_emitter(op_ia32_AndMem8Bit, bemit_andmem8bit);
3423 be_set_emitter(op_ia32_Asm, emit_ia32_Asm); // TODO implement binary emitter
3424 be_set_emitter(op_ia32_Breakpoint, bemit_int3);
3425 be_set_emitter(op_ia32_Bsf, bemit_bsf);
3426 be_set_emitter(op_ia32_Bsr, bemit_bsr);
3427 be_set_emitter(op_ia32_Bswap, bemit_bswap);
3428 be_set_emitter(op_ia32_Bt, bemit_bt);
3429 be_set_emitter(op_ia32_CMovcc, bemit_cmovcc);
3430 be_set_emitter(op_ia32_Call, bemit_call);
3431 be_set_emitter(op_ia32_Cltd, bemit_cltd);
3432 be_set_emitter(op_ia32_Cmc, bemit_cmc);
3433 be_set_emitter(op_ia32_Cmp, bemit_cmp);
3434 be_set_emitter(op_ia32_Cmp8Bit, bemit_cmp8bit);
3435 be_set_emitter(op_ia32_Const, bemit_mov_const);
3436 be_set_emitter(op_ia32_Conv_I2I, bemit_conv_i2i);
3437 be_set_emitter(op_ia32_Conv_I2I8Bit, bemit_conv_i2i);
3438 be_set_emitter(op_ia32_CopyB_i, bemit_copybi);
3439 be_set_emitter(op_ia32_Cwtl, bemit_cwtl);
3440 be_set_emitter(op_ia32_Dec, bemit_dec);
3441 be_set_emitter(op_ia32_DecMem, bemit_decmem);
3442 be_set_emitter(op_ia32_Div, bemit_div);
3443 be_set_emitter(op_ia32_FldCW, bemit_fldcw);
3444 be_set_emitter(op_ia32_FnstCW, bemit_fnstcw);
3445 be_set_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw);
3446 be_set_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw);
3447 be_set_emitter(op_ia32_Fucomi, bemit_fucomi);
3448 be_set_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw);
3449 be_set_emitter(op_ia32_IDiv, bemit_idiv);
3450 be_set_emitter(op_ia32_IJmp, bemit_ijmp);
3451 be_set_emitter(op_ia32_IMul, bemit_imul);
3452 be_set_emitter(op_ia32_IMul1OP, bemit_imul1op);
3453 be_set_emitter(op_ia32_Inc, bemit_inc);
3454 be_set_emitter(op_ia32_IncMem, bemit_incmem);
3455 be_set_emitter(op_ia32_Jcc, bemit_ia32_jcc);
3456 be_set_emitter(op_ia32_Jmp, bemit_jump);
3457 be_set_emitter(op_ia32_LdTls, bemit_ldtls);
3458 be_set_emitter(op_ia32_Lea, bemit_lea);
3459 be_set_emitter(op_ia32_Leave, bemit_leave);
3460 be_set_emitter(op_ia32_Load, bemit_load);
3461 be_set_emitter(op_ia32_Minus64Bit, bemit_minus64bit);
3462 be_set_emitter(op_ia32_Mul, bemit_mul);
3463 be_set_emitter(op_ia32_Neg, bemit_neg);
3464 be_set_emitter(op_ia32_NegMem, bemit_negmem);
3465 be_set_emitter(op_ia32_Not, bemit_not);
3466 be_set_emitter(op_ia32_NotMem, bemit_notmem);
3467 be_set_emitter(op_ia32_Or, bemit_or);
3468 be_set_emitter(op_ia32_OrMem, bemit_ormem);
3469 be_set_emitter(op_ia32_OrMem8Bit, bemit_ormem8bit);
3470 be_set_emitter(op_ia32_Pop, bemit_pop);
3471 be_set_emitter(op_ia32_PopEbp, bemit_pop);
3472 be_set_emitter(op_ia32_PopMem, bemit_popmem);
3473 be_set_emitter(op_ia32_Popcnt, bemit_popcnt);
3474 be_set_emitter(op_ia32_Push, bemit_push);
3475 be_set_emitter(op_ia32_RepPrefix, bemit_rep);
3476 be_set_emitter(op_ia32_Rol, bemit_rol);
3477 be_set_emitter(op_ia32_RolMem, bemit_rolmem);
3478 be_set_emitter(op_ia32_Ror, bemit_ror);
3479 be_set_emitter(op_ia32_RorMem, bemit_rormem);
3480 be_set_emitter(op_ia32_Sahf, bemit_sahf);
3481 be_set_emitter(op_ia32_Sar, bemit_sar);
3482 be_set_emitter(op_ia32_SarMem, bemit_sarmem);
3483 be_set_emitter(op_ia32_Sbb, bemit_sbb);
3484 be_set_emitter(op_ia32_Sbb0, bemit_sbb0);
3485 be_set_emitter(op_ia32_Setcc, bemit_setcc);
3486 be_set_emitter(op_ia32_Shl, bemit_shl);
3487 be_set_emitter(op_ia32_ShlD, bemit_shld);
3488 be_set_emitter(op_ia32_ShlMem, bemit_shlmem);
3489 be_set_emitter(op_ia32_Shr, bemit_shr);
3490 be_set_emitter(op_ia32_ShrD, bemit_shrd);
3491 be_set_emitter(op_ia32_ShrMem, bemit_shrmem);
3492 be_set_emitter(op_ia32_Stc, bemit_stc);
3493 be_set_emitter(op_ia32_Store, bemit_store);
3494 be_set_emitter(op_ia32_Store8Bit, bemit_store);
3495 be_set_emitter(op_ia32_Sub, bemit_sub);
3496 be_set_emitter(op_ia32_SubMem, bemit_submem);
3497 be_set_emitter(op_ia32_SubMem8Bit, bemit_submem8bit);
3498 be_set_emitter(op_ia32_SubSP, bemit_subsp);
3499 be_set_emitter(op_ia32_SwitchJmp, bemit_switchjmp);
3500 be_set_emitter(op_ia32_Test, bemit_test);
3501 be_set_emitter(op_ia32_Xor, bemit_xor);
3502 be_set_emitter(op_ia32_Xor0, bemit_xor0);
3503 be_set_emitter(op_ia32_XorMem, bemit_xormem);
3504 be_set_emitter(op_ia32_XorMem8Bit, bemit_xormem8bit);
3505 be_set_emitter(op_ia32_fabs, bemit_fabs);
3506 be_set_emitter(op_ia32_fadd, bemit_fadd);
3507 be_set_emitter(op_ia32_fchs, bemit_fchs);
3508 be_set_emitter(op_ia32_fdiv, bemit_fdiv);
3509 be_set_emitter(op_ia32_ffreep, bemit_ffreep);
3510 be_set_emitter(op_ia32_fild, bemit_fild);
3511 be_set_emitter(op_ia32_fist, bemit_fist);
3512 be_set_emitter(op_ia32_fisttp, bemit_fisttp);
3513 be_set_emitter(op_ia32_fld, bemit_fld);
3514 be_set_emitter(op_ia32_fld1, bemit_fld1);
3515 be_set_emitter(op_ia32_fldz, bemit_fldz);
3516 be_set_emitter(op_ia32_fmul, bemit_fmul);
3517 be_set_emitter(op_ia32_fpop, bemit_fpop);
3518 be_set_emitter(op_ia32_fpush, bemit_fpush);
3519 be_set_emitter(op_ia32_fpushCopy, bemit_fpushcopy);
3520 be_set_emitter(op_ia32_fst, bemit_fst);
3521 be_set_emitter(op_ia32_fsub, bemit_fsub);
3522 be_set_emitter(op_ia32_fxch, bemit_fxch);
3524 /* ignore the following nodes */
3525 be_set_emitter(op_Phi, be_emit_nothing);
3526 be_set_emitter(op_be_Keep, be_emit_nothing);
3527 be_set_emitter(op_be_Start, be_emit_nothing);
3528 be_set_emitter(op_ia32_ProduceVal, be_emit_nothing);
3529 be_set_emitter(op_ia32_Unknown, be_emit_nothing);
3532 static void gen_binary_block(ir_node *block)
3534 ia32_emit_block_header(block);
3536 /* emit the contents of the block */
3537 sched_foreach(block, node) {
3538 ia32_emit_node(node);
3542 void ia32_gen_binary_routine(ir_graph *irg)
3544 ir_entity *entity = get_irg_entity(irg);
3545 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
3546 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
3547 ir_node **blk_sched = irg_data->blk_sched;
3549 parameter_dbg_info_t *infos;
3551 isa = (ia32_isa_t*) arch_env;
3553 ia32_register_binary_emitters();
3555 infos = construct_parameter_infos(irg);
3556 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
3560 /* we use links to point to target blocks */
3561 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
3562 irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
3564 /* initialize next block links */
3565 n = ARR_LEN(blk_sched);
3566 for (i = 0; i < n; ++i) {
3567 ir_node *block = blk_sched[i];
3568 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
3570 set_irn_link(block, prev);
3573 for (i = 0; i < n; ++i) {
3574 ir_node *block = blk_sched[i];
3575 gen_binary_block(block);
3578 be_gas_emit_function_epilog(entity);
3580 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
3584 void ia32_init_emitter(void)
3586 lc_opt_entry_t *be_grp;
3587 lc_opt_entry_t *ia32_grp;
3589 be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
3590 ia32_grp = lc_opt_get_grp(be_grp, "ia32");
3592 lc_opt_add_table(ia32_grp, ia32_emitter_options);
3596 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");