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 const char *reg_name = arch_register_get_name(reg);
157 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
158 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
161 be_emit_char(reg_name[1]); /* get the basic name of the register */
166 * Emit the name of the 8bit high register
168 static void emit_8bit_register_high(const arch_register_t *reg)
170 const char *reg_name = arch_register_get_name(reg);
171 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
172 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
175 be_emit_char(reg_name[1]); /* get the basic name of the register */
179 static void emit_16bit_register(const arch_register_t *reg)
181 const char *reg_name = arch_register_get_name(reg);
184 be_emit_string(reg_name+1); /* skip the 'e' prefix of the 32bit names */
188 * emit a register, possible shortened by a mode
190 * @param reg the register
191 * @param mode the mode of the register or NULL for full register
193 static void emit_register(const arch_register_t *reg, const ir_mode *mode)
195 const char *reg_name;
198 int size = get_mode_size_bits(mode);
200 case 8: emit_8bit_register(reg); return;
201 case 16: emit_16bit_register(reg); return;
203 assert(mode_is_float(mode) || size == 32);
206 reg_name = arch_register_get_name(reg);
209 be_emit_string(reg_name);
212 static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
214 be_gas_emit_entity(entity);
216 if (get_entity_owner(entity) == get_tls_type()) {
217 if (!entity_has_definition(entity)) {
218 be_emit_cstring("@INDNTPOFF");
220 be_emit_cstring("@NTPOFF");
224 if (do_pic && !no_pic_adjust) {
226 be_emit_string(pic_base_label);
230 static void emit_ia32_Immediate_no_prefix(const ir_node *node)
232 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
234 if (attr->symconst != NULL) {
237 ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
239 if (attr->symconst == NULL || attr->offset != 0) {
240 if (attr->symconst != NULL) {
241 be_emit_irprintf("%+d", attr->offset);
243 be_emit_irprintf("0x%X", attr->offset);
248 static void emit_ia32_Immediate(const ir_node *node)
251 emit_ia32_Immediate_no_prefix(node);
254 static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
256 assert(mode_is_int(mode) || mode_is_reference(mode));
257 switch (get_mode_size_bits(mode)) {
258 case 8: be_emit_char('b'); return;
259 case 16: be_emit_char('w'); return;
260 case 32: be_emit_char('l'); return;
261 /* gas docu says q is the suffix but gcc, objdump and icc use ll
263 case 64: be_emit_cstring("ll"); return;
265 panic("Can't output mode_suffix for %+F", mode);
268 static void ia32_emit_x87_mode_suffix(ir_node const *const node)
272 /* we only need to emit the mode on address mode */
273 if (get_ia32_op_type(node) == ia32_Normal)
276 mode = get_ia32_ls_mode(node);
277 assert(mode != NULL);
279 if (mode_is_float(mode)) {
280 switch (get_mode_size_bits(mode)) {
281 case 32: be_emit_char('s'); return;
282 case 64: be_emit_char('l'); return;
283 /* long doubles have different sizes due to alignment on different
287 case 128: be_emit_char('t'); return;
290 assert(mode_is_int(mode) || mode_is_reference(mode));
291 switch (get_mode_size_bits(mode)) {
292 case 16: be_emit_char('s'); return;
293 case 32: be_emit_char('l'); return;
294 /* gas docu says q is the suffix but gcc, objdump and icc use ll
296 case 64: be_emit_cstring("ll"); return;
299 panic("Can't output mode_suffix for %+F", mode);
302 static char get_xmm_mode_suffix(ir_mode *mode)
304 assert(mode_is_float(mode));
305 switch (get_mode_size_bits(mode)) {
308 default: panic("Invalid XMM mode");
312 static void ia32_emit_xmm_mode_suffix(ir_node const *const node)
314 ir_mode *mode = get_ia32_ls_mode(node);
315 assert(mode != NULL);
316 be_emit_char(get_xmm_mode_suffix(mode));
320 * Returns the target block for a control flow node.
322 static ir_node *get_cfop_target_block(const ir_node *irn)
324 assert(get_irn_mode(irn) == mode_X);
325 return (ir_node*)get_irn_link(irn);
329 * Emits the target label for a control flow node.
331 static void ia32_emit_cfop_target(const ir_node *node)
333 ir_node *block = get_cfop_target_block(node);
334 be_gas_emit_block_name(block);
338 * Emit the suffix for a compare instruction.
340 static void ia32_emit_condition_code(ia32_condition_code_t cc)
343 case ia32_cc_overflow: be_emit_cstring("o"); return;
344 case ia32_cc_not_overflow: be_emit_cstring("no"); return;
345 case ia32_cc_float_below:
346 case ia32_cc_float_unordered_below:
347 case ia32_cc_below: be_emit_cstring("b"); return;
348 case ia32_cc_float_above_equal:
349 case ia32_cc_float_unordered_above_equal:
350 case ia32_cc_above_equal: be_emit_cstring("ae"); return;
351 case ia32_cc_float_equal:
352 case ia32_cc_equal: be_emit_cstring("e"); return;
353 case ia32_cc_float_not_equal:
354 case ia32_cc_not_equal: be_emit_cstring("ne"); return;
355 case ia32_cc_float_below_equal:
356 case ia32_cc_float_unordered_below_equal:
357 case ia32_cc_below_equal: be_emit_cstring("be"); return;
358 case ia32_cc_float_above:
359 case ia32_cc_float_unordered_above:
360 case ia32_cc_above: be_emit_cstring("a"); return;
361 case ia32_cc_sign: be_emit_cstring("s"); return;
362 case ia32_cc_not_sign: be_emit_cstring("ns"); return;
363 case ia32_cc_parity: be_emit_cstring("p"); return;
364 case ia32_cc_not_parity: be_emit_cstring("np"); return;
365 case ia32_cc_less: be_emit_cstring("l"); return;
366 case ia32_cc_greater_equal: be_emit_cstring("ge"); return;
367 case ia32_cc_less_equal: be_emit_cstring("le"); return;
368 case ia32_cc_greater: be_emit_cstring("g"); return;
369 case ia32_cc_float_parity_cases:
370 case ia32_cc_additional_float_cases:
373 panic("Invalid ia32 condition code");
376 typedef enum ia32_emit_mod_t {
378 EMIT_RESPECT_LS = 1U << 0,
379 EMIT_ALTERNATE_AM = 1U << 1,
381 EMIT_HIGH_REG = 1U << 3,
382 EMIT_LOW_REG = 1U << 4,
383 EMIT_16BIT_REG = 1U << 5
385 ENUM_BITSET(ia32_emit_mod_t)
388 * Emits address mode.
390 static void ia32_emit_am(ir_node const *const node)
392 ir_entity *ent = get_ia32_am_sc(node);
393 int offs = get_ia32_am_offs_int(node);
394 ir_node *base = get_irn_n(node, n_ia32_base);
395 int has_base = !is_ia32_NoReg_GP(base);
396 ir_node *idx = get_irn_n(node, n_ia32_index);
397 int has_index = !is_ia32_NoReg_GP(idx);
399 /* just to be sure... */
400 assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
402 if (get_ia32_am_tls_segment(node))
403 be_emit_cstring("%gs:");
407 const ia32_attr_t *attr = get_ia32_attr_const(node);
408 if (is_ia32_am_sc_sign(node))
410 ia32_emit_entity(ent, attr->data.am_sc_no_pic_adjust);
413 /* also handle special case if nothing is set */
414 if (offs != 0 || (ent == NULL && !has_base && !has_index)) {
416 be_emit_irprintf("%+d", offs);
418 be_emit_irprintf("%d", offs);
422 if (has_base || has_index) {
427 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
428 emit_register(reg, NULL);
431 /* emit index + scale */
433 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
436 emit_register(reg, NULL);
438 scale = get_ia32_am_scale(node);
440 be_emit_irprintf(",%d", 1 << scale);
447 static ia32_condition_code_t determine_final_cc(ir_node const *node, int flags_pos, ia32_condition_code_t cc);
449 void ia32_emitf(ir_node const *const node, char const *fmt, ...)
456 const char *start = fmt;
457 ia32_emit_mod_t mod = EMIT_NONE;
459 while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
462 be_emit_string_len(start, fmt - start);
467 be_emit_write_line();
481 case '*': mod |= EMIT_ALTERNATE_AM; break;
482 case '#': mod |= EMIT_RESPECT_LS; break;
483 case 'l': mod |= EMIT_LONG; break;
484 case '>': mod |= EMIT_HIGH_REG; break;
485 case '<': mod |= EMIT_LOW_REG; break;
486 case '^': mod |= EMIT_16BIT_REG; break;
495 arch_register_t const *reg;
505 if (get_ia32_op_type(node) == ia32_AddrModeS) {
508 assert(get_ia32_op_type(node) == ia32_Normal);
509 ia32_x87_attr_t const *const x87_attr = get_ia32_x87_attr_const(node);
510 arch_register_t const *const in1 = x87_attr->x87[0];
511 arch_register_t const * in = x87_attr->x87[1];
512 arch_register_t const * out = x87_attr->x87[2];
515 } else if (out == in) {
518 be_emit_irprintf("%%%s, %%%s", arch_register_get_name(in), arch_register_get_name(out));
524 if (mod & EMIT_ALTERNATE_AM)
530 reg = va_arg(ap, const arch_register_t*);
531 if (get_ia32_op_type(node) == ia32_AddrModeS) {
538 if (get_ia32_op_type(node) == ia32_AddrModeS) {
542 assert(get_ia32_op_type(node) == ia32_Normal);
546 default: goto unknown;
552 imm = get_irn_n(node, n_ia32_binary_right);
553 if (is_ia32_Immediate(imm)) {
554 emit_ia32_Immediate(imm);
555 be_emit_cstring(", ");
556 if (get_ia32_op_type(node) == ia32_AddrModeS) {
559 assert(get_ia32_op_type(node) == ia32_Normal);
560 reg = arch_get_irn_register_in(node, n_ia32_binary_left);
561 emit_register(reg, get_ia32_ls_mode(node));
564 if (get_ia32_op_type(node) == ia32_AddrModeS) {
567 assert(get_ia32_op_type(node) == ia32_Normal);
568 reg = arch_get_irn_register_in(node, n_ia32_binary_right);
569 emit_register(reg, get_ia32_ls_mode(node));
571 be_emit_cstring(", ");
572 reg = arch_get_irn_register_in(node, n_ia32_binary_left);
573 emit_register(reg, get_ia32_ls_mode(node));
578 if (*fmt < '0' || '9' <= *fmt)
580 reg = arch_get_irn_register_out(node, *fmt++ - '0');
586 ia32_emit_x87_mode_suffix(node);
587 } else if (*fmt == 'X') {
589 ia32_emit_xmm_mode_suffix(node);
590 } else if ('0' <= *fmt && *fmt <= '3') {
591 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
593 be_emit_string(attr->x87[*fmt++ - '0']->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_FucompFnstsw(cmp)
776 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
777 inc_irg_visited(current_ir_graph);
778 cmp = find_original_value(cmp);
780 assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
781 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
784 flags_attr = get_ia32_attr_const(cmp);
786 flags_attr = get_ia32_attr_const(flags);
789 if (flags_attr->data.ins_permuted)
790 cc = ia32_invert_condition_code(cc);
795 * Emits an exception label for a given node.
797 static void ia32_emit_exc_label(const ir_node *node)
799 be_emit_string(be_gas_insn_label_prefix());
800 be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
804 * Returns the Proj with projection number proj and NOT mode_M
806 static ir_node *get_proj(const ir_node *node, long proj)
810 assert(get_irn_mode(node) == mode_T && "expected mode_T node");
812 foreach_out_edge(node, edge) {
813 src = get_edge_src_irn(edge);
815 assert(is_Proj(src) && "Proj expected");
816 if (get_irn_mode(src) == mode_M)
819 if (get_Proj_proj(src) == proj)
825 static int can_be_fallthrough(const ir_node *node)
827 ir_node *target_block = get_cfop_target_block(node);
828 ir_node *block = get_nodes_block(node);
829 return get_prev_block_sched(target_block) == block;
833 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
835 static void emit_ia32_Jcc(const ir_node *node)
837 int need_parity_label = 0;
838 ia32_condition_code_t cc = get_ia32_condcode(node);
839 const ir_node *proj_true;
840 const ir_node *proj_false;
842 cc = determine_final_cc(node, 0, cc);
845 proj_true = get_proj(node, pn_ia32_Jcc_true);
846 assert(proj_true && "Jcc without true Proj");
848 proj_false = get_proj(node, pn_ia32_Jcc_false);
849 assert(proj_false && "Jcc without false Proj");
851 if (can_be_fallthrough(proj_true)) {
852 /* exchange both proj's so the second one can be omitted */
853 const ir_node *t = proj_true;
855 proj_true = proj_false;
857 cc = ia32_negate_condition_code(cc);
860 if (cc & ia32_cc_float_parity_cases) {
861 /* Some floating point comparisons require a test of the parity flag,
862 * which indicates that the result is unordered */
863 if (cc & ia32_cc_negated) {
864 ia32_emitf(proj_true, "jp %L");
866 /* we need a local label if the false proj is a fallthrough
867 * as the falseblock might have no label emitted then */
868 if (can_be_fallthrough(proj_false)) {
869 need_parity_label = 1;
870 ia32_emitf(proj_false, "jp 1f");
872 ia32_emitf(proj_false, "jp %L");
876 ia32_emitf(proj_true, "j%PX %L", (int)cc);
877 if (need_parity_label) {
878 be_emit_cstring("1:\n");
879 be_emit_write_line();
882 /* the second Proj might be a fallthrough */
883 if (can_be_fallthrough(proj_false)) {
884 if (be_options.verbose_asm)
885 ia32_emitf(proj_false, "/* fallthrough to %L */");
887 ia32_emitf(proj_false, "jmp %L");
892 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
895 static void emit_ia32_Setcc(const ir_node *node)
897 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
899 ia32_condition_code_t cc = get_ia32_condcode(node);
900 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
901 if (cc & ia32_cc_float_parity_cases) {
902 if (cc & ia32_cc_negated) {
903 ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
904 ia32_emitf(node, "setp %>R", dreg);
905 ia32_emitf(node, "orb %>R, %<R", dreg, dreg);
907 ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
908 ia32_emitf(node, "setnp %>R", dreg);
909 ia32_emitf(node, "andb %>R, %<R", dreg, dreg);
912 ia32_emitf(node, "set%PX %#R", (int)cc, dreg);
916 static void emit_ia32_CMovcc(const ir_node *node)
918 const ia32_attr_t *attr = get_ia32_attr_const(node);
919 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
920 ia32_condition_code_t cc = get_ia32_condcode(node);
921 const arch_register_t *in_true;
922 const arch_register_t *in_false;
924 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
925 /* although you can't set ins_permuted in the constructor it might still
926 * be set by memory operand folding
927 * Permuting inputs of a cmov means the condition is negated!
929 if (attr->data.ins_permuted)
930 cc = ia32_negate_condition_code(cc);
932 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
933 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
935 /* should be same constraint fullfilled? */
936 if (out == in_false) {
937 /* yes -> nothing to do */
938 } else if (out == in_true) {
939 const arch_register_t *tmp;
941 assert(get_ia32_op_type(node) == ia32_Normal);
943 cc = ia32_negate_condition_code(cc);
950 ia32_emitf(node, "movl %R, %R", in_false, out);
953 if (cc & ia32_cc_float_parity_cases) {
954 panic("CMov with floatingpoint compare/parity not supported yet");
957 ia32_emitf(node, "cmov%PX %#AR, %#R", (int)cc, in_true, out);
961 * Emits code for a SwitchJmp
963 static void emit_ia32_SwitchJmp(const ir_node *node)
965 ir_entity *jump_table = get_ia32_am_sc(node);
966 const ir_switch_table *table = get_ia32_switch_table(node);
968 ia32_emitf(node, "jmp %*AM");
969 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
973 * Emits code for a unconditional jump.
975 static void emit_ia32_Jmp(const ir_node *node)
977 /* we have a block schedule */
978 if (can_be_fallthrough(node)) {
979 if (be_options.verbose_asm)
980 ia32_emitf(node, "/* fallthrough to %L */");
982 ia32_emitf(node, "jmp %L");
987 * Emit an inline assembler operand.
989 * @param node the ia32_ASM node
990 * @param s points to the operand (a %c)
992 * @return pointer to the first char in s NOT in the current operand
994 static const char* emit_asm_operand(const ir_node *node, const char *s)
996 const ia32_attr_t *ia32_attr = get_ia32_attr_const(node);
997 const ia32_asm_attr_t *attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
999 const arch_register_t *reg;
1000 const ia32_asm_reg_t *asm_regs = attr->register_map;
1001 const ia32_asm_reg_t *asm_reg;
1010 /* parse modifiers */
1013 ir_fprintf(stderr, "Warning: asm text (%+F) ends with %%\n", node);
1038 "Warning: asm text (%+F) contains unknown modifier '%c' for asm op\n",
1045 if (sscanf(s, "%d%n", &num, &p) != 1) {
1046 ir_fprintf(stderr, "Warning: Couldn't parse assembler operand (%+F)\n",
1053 if (num < 0 || ARR_LEN(asm_regs) <= (size_t)num) {
1055 "Error: Custom assembler references invalid input/output (%+F)\n",
1059 asm_reg = & asm_regs[num];
1060 assert(asm_reg->valid);
1063 if (asm_reg->use_input == 0) {
1064 reg = arch_get_irn_register_out(node, asm_reg->inout_pos);
1066 ir_node *pred = get_irn_n(node, asm_reg->inout_pos);
1068 /* might be an immediate value */
1069 if (is_ia32_Immediate(pred)) {
1070 emit_ia32_Immediate(pred);
1073 reg = arch_get_irn_register_in(node, asm_reg->inout_pos);
1077 "Warning: no register assigned for %d asm op (%+F)\n",
1082 if (asm_reg->memory) {
1087 if (modifier != 0) {
1090 emit_8bit_register(reg);
1093 emit_8bit_register_high(reg);
1096 emit_16bit_register(reg);
1099 panic("Invalid asm op modifier");
1102 emit_register(reg, asm_reg->memory ? mode_Iu : asm_reg->mode);
1105 if (asm_reg->memory) {
1113 * Emits code for an ASM pseudo op.
1115 static void emit_ia32_Asm(const ir_node *node)
1117 const void *gen_attr = get_irn_generic_attr_const(node);
1118 const ia32_asm_attr_t *attr
1119 = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, gen_attr);
1120 ident *asm_text = attr->asm_text;
1121 const char *s = get_id_str(asm_text);
1123 be_emit_cstring("#APP\n");
1124 be_emit_write_line();
1131 s = emit_asm_operand(node, s);
1137 be_emit_cstring("\n#NO_APP\n");
1138 be_emit_write_line();
1143 * Emit movsb/w instructions to make mov count divideable by 4
1145 static void emit_CopyB_prolog(unsigned size)
1148 ia32_emitf(NULL, "movsb");
1150 ia32_emitf(NULL, "movsw");
1154 * Emit rep movsd instruction for memcopy.
1156 static void emit_ia32_CopyB(const ir_node *node)
1158 unsigned size = get_ia32_copyb_size(node);
1160 emit_CopyB_prolog(size);
1161 ia32_emitf(node, "rep movsd");
1165 * Emits unrolled memcopy.
1167 static void emit_ia32_CopyB_i(const ir_node *node)
1169 unsigned size = get_ia32_copyb_size(node);
1171 emit_CopyB_prolog(size);
1175 ia32_emitf(NULL, "movsd");
1181 * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1183 static void emit_ia32_Conv_with_FP(const ir_node *node, const char* conv_f,
1186 ir_mode *ls_mode = get_ia32_ls_mode(node);
1187 int ls_bits = get_mode_size_bits(ls_mode);
1188 const char *conv = ls_bits == 32 ? conv_f : conv_d;
1190 ia32_emitf(node, "cvt%s %AS3, %D0", conv);
1193 static void emit_ia32_Conv_I2FP(const ir_node *node)
1195 emit_ia32_Conv_with_FP(node, "si2ss", "si2sd");
1198 static void emit_ia32_Conv_FP2I(const ir_node *node)
1200 emit_ia32_Conv_with_FP(node, "ss2si", "sd2si");
1203 static void emit_ia32_Conv_FP2FP(const ir_node *node)
1205 emit_ia32_Conv_with_FP(node, "sd2ss", "ss2sd");
1209 * Emits code to increase stack pointer.
1211 static void emit_be_IncSP(const ir_node *node)
1213 int offs = be_get_IncSP_offset(node);
1219 ia32_emitf(node, "subl $%u, %D0", offs);
1221 ia32_emitf(node, "addl $%u, %D0", -offs);
1226 * Emits code for Copy/CopyKeep.
1228 static void Copy_emitter(const ir_node *node, const ir_node *op)
1230 const arch_register_t *in = arch_get_irn_register(op);
1231 const arch_register_t *out = arch_get_irn_register(node);
1236 /* copies of vf nodes aren't real... */
1237 if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
1240 ia32_emitf(node, "movl %R, %R", in, out);
1243 static void emit_be_Copy(const ir_node *node)
1245 Copy_emitter(node, be_get_Copy_op(node));
1248 static void emit_be_CopyKeep(const ir_node *node)
1250 Copy_emitter(node, be_get_CopyKeep_op(node));
1254 * Emits code for exchange.
1256 static void emit_be_Perm(const ir_node *node)
1258 const arch_register_t *in0, *in1;
1259 const arch_register_class_t *cls0, *cls1;
1261 in0 = arch_get_irn_register(get_irn_n(node, 0));
1262 in1 = arch_get_irn_register(get_irn_n(node, 1));
1264 cls0 = arch_register_get_class(in0);
1265 cls1 = arch_register_get_class(in1);
1267 assert(cls0 == cls1 && "Register class mismatch at Perm");
1269 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
1270 ia32_emitf(node, "xchg %R, %R", in1, in0);
1271 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1272 ia32_emitf(NULL, "xorpd %R, %R", in1, in0);
1273 ia32_emitf(NULL, "xorpd %R, %R", in0, in1);
1274 ia32_emitf(node, "xorpd %R, %R", in1, in0);
1275 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
1277 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
1280 panic("unexpected register class in be_Perm (%+F)", node);
1284 /* helper function for emit_ia32_Minus64Bit */
1285 static void emit_mov(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1287 ia32_emitf(node, "movl %R, %R", src, dst);
1290 /* helper function for emit_ia32_Minus64Bit */
1291 static void emit_neg(const ir_node* node, const arch_register_t *reg)
1293 ia32_emitf(node, "negl %R", reg);
1296 /* helper function for emit_ia32_Minus64Bit */
1297 static void emit_sbb0(const ir_node* node, const arch_register_t *reg)
1299 ia32_emitf(node, "sbbl $0, %R", reg);
1302 /* helper function for emit_ia32_Minus64Bit */
1303 static void emit_sbb(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1305 ia32_emitf(node, "sbbl %R, %R", src, dst);
1308 /* helper function for emit_ia32_Minus64Bit */
1309 static void emit_xchg(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1311 ia32_emitf(node, "xchgl %R, %R", src, dst);
1314 /* helper function for emit_ia32_Minus64Bit */
1315 static void emit_zero(const ir_node* node, const arch_register_t *reg)
1317 ia32_emitf(node, "xorl %R, %R", reg, reg);
1320 static void emit_ia32_Minus64Bit(const ir_node *node)
1322 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
1323 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
1324 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
1325 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
1327 if (out_lo == in_lo) {
1328 if (out_hi != in_hi) {
1329 /* a -> a, b -> d */
1332 /* a -> a, b -> b */
1335 } else if (out_lo == in_hi) {
1336 if (out_hi == in_lo) {
1337 /* a -> b, b -> a */
1338 emit_xchg(node, in_lo, in_hi);
1341 /* a -> b, b -> d */
1342 emit_mov(node, in_hi, out_hi);
1343 emit_mov(node, in_lo, out_lo);
1347 if (out_hi == in_lo) {
1348 /* a -> c, b -> a */
1349 emit_mov(node, in_lo, out_lo);
1351 } else if (out_hi == in_hi) {
1352 /* a -> c, b -> b */
1353 emit_mov(node, in_lo, out_lo);
1356 /* a -> c, b -> d */
1357 emit_mov(node, in_lo, out_lo);
1363 emit_neg( node, out_hi);
1364 emit_neg( node, out_lo);
1365 emit_sbb0(node, out_hi);
1369 emit_zero(node, out_hi);
1370 emit_neg( node, out_lo);
1371 emit_sbb( node, in_hi, out_hi);
1374 static void emit_ia32_GetEIP(const ir_node *node)
1376 ia32_emitf(node, "call %s", pic_base_label);
1377 be_emit_irprintf("%s:\n", pic_base_label);
1378 be_emit_write_line();
1379 ia32_emitf(node, "popl %D0");
1382 static void emit_ia32_ClimbFrame(const ir_node *node)
1384 const ia32_climbframe_attr_t *attr = get_ia32_climbframe_attr_const(node);
1386 ia32_emitf(node, "movl %S0, %D0");
1387 ia32_emitf(node, "movl $%u, %S1", attr->count);
1388 be_gas_emit_block_name(node);
1389 be_emit_cstring(":\n");
1390 be_emit_write_line();
1391 ia32_emitf(node, "movl (%D0), %D0");
1392 ia32_emitf(node, "dec %S1");
1393 be_emit_cstring("\tjnz ");
1394 be_gas_emit_block_name(node);
1395 be_emit_finish_line_gas(node);
1398 static void emit_be_Return(const ir_node *node)
1400 unsigned pop = be_Return_get_pop(node);
1402 if (pop > 0 || be_Return_get_emit_pop(node)) {
1403 ia32_emitf(node, "ret $%u", pop);
1405 ia32_emitf(node, "ret");
1409 static void emit_Nothing(const ir_node *node)
1416 * Enters the emitter functions for handled nodes into the generic
1417 * pointer of an opcode.
1419 static void ia32_register_emitters(void)
1421 #define IA32_EMIT(a) op_ia32_##a->ops.generic = (op_func)emit_ia32_##a
1422 #define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
1423 #define IGN(a) op_##a->ops.generic = (op_func)emit_Nothing
1424 #define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
1425 #define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing
1427 /* first clear the generic function pointer for all ops */
1428 ir_clear_opcodes_generic_func();
1430 /* register all emitter functions defined in spec */
1431 ia32_register_spec_emitters();
1433 /* other ia32 emitter functions */
1436 IA32_EMIT(Conv_FP2FP);
1437 IA32_EMIT(Conv_FP2I);
1438 IA32_EMIT(Conv_I2FP);
1445 IA32_EMIT(Minus64Bit);
1446 IA32_EMIT(SwitchJmp);
1447 IA32_EMIT(ClimbFrame);
1450 /* benode emitter */
1469 typedef void (*emit_func_ptr) (const ir_node *);
1472 * Assign and emit an exception label if the current instruction can fail.
1474 static void ia32_assign_exc_label(ir_node *node)
1476 /* assign a new ID to the instruction */
1477 set_ia32_exc_label_id(node, ++exc_label_id);
1479 ia32_emit_exc_label(node);
1481 be_emit_pad_comment();
1482 be_emit_cstring("/* exception to Block ");
1483 ia32_emit_cfop_target(node);
1484 be_emit_cstring(" */\n");
1485 be_emit_write_line();
1489 * Emits code for a node.
1491 static void ia32_emit_node(ir_node *node)
1493 ir_op *op = get_irn_op(node);
1495 DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
1497 if (is_ia32_irn(node)) {
1498 if (get_ia32_exc_label(node)) {
1499 /* emit the exception label of this instruction */
1500 ia32_assign_exc_label(node);
1502 if (mark_spill_reload) {
1503 if (is_ia32_is_spill(node)) {
1504 ia32_emitf(NULL, "xchg %ebx, %ebx /* spill mark */");
1506 if (is_ia32_is_reload(node)) {
1507 ia32_emitf(NULL, "xchg %edx, %edx /* reload mark */");
1509 if (is_ia32_is_remat(node)) {
1510 ia32_emitf(NULL, "xchg %ecx, %ecx /* remat mark */");
1514 if (op->ops.generic) {
1515 emit_func_ptr func = (emit_func_ptr) op->ops.generic;
1517 be_dwarf_location(get_irn_dbg_info(node));
1522 ir_fprintf(stderr, "Error: No emit handler for node %+F (%+G, graph %+F)\n", node, node, current_ir_graph);
1527 int sp_change = arch_get_sp_bias(node);
1528 if (sp_change != 0) {
1529 assert(sp_change != SP_BIAS_RESET);
1530 callframe_offset += sp_change;
1531 be_dwarf_callframe_offset(callframe_offset);
1537 * Emits gas alignment directives
1539 static void ia32_emit_alignment(unsigned align, unsigned skip)
1541 ia32_emitf(NULL, ".p2align %u,,%u", align, skip);
1545 * Emits gas alignment directives for Labels depended on cpu architecture.
1547 static void ia32_emit_align_label(void)
1549 unsigned align = ia32_cg_config.label_alignment;
1550 unsigned maximum_skip = ia32_cg_config.label_alignment_max_skip;
1551 ia32_emit_alignment(align, maximum_skip);
1555 * Test whether a block should be aligned.
1556 * For cpus in the P4/Athlon class it is useful to align jump labels to
1557 * 16 bytes. However we should only do that if the alignment nops before the
1558 * label aren't executed more often than we have jumps to the label.
1560 static int should_align_block(const ir_node *block)
1562 static const double DELTA = .0001;
1563 ir_node *prev = get_prev_block_sched(block);
1564 double prev_freq = 0; /**< execfreq of the fallthrough block */
1565 double jmp_freq = 0; /**< execfreq of all non-fallthrough blocks */
1569 if (ia32_cg_config.label_alignment_factor <= 0)
1572 block_freq = get_block_execfreq(block);
1573 if (block_freq < DELTA)
1576 n_cfgpreds = get_Block_n_cfgpreds(block);
1577 for (i = 0; i < n_cfgpreds; ++i) {
1578 const ir_node *pred = get_Block_cfgpred_block(block, i);
1579 double pred_freq = get_block_execfreq(pred);
1582 prev_freq += pred_freq;
1584 jmp_freq += pred_freq;
1588 if (prev_freq < DELTA && !(jmp_freq < DELTA))
1591 jmp_freq /= prev_freq;
1593 return jmp_freq > ia32_cg_config.label_alignment_factor;
1597 * Emit the block header for a block.
1599 * @param block the block
1600 * @param prev_block the previous block
1602 static void ia32_emit_block_header(ir_node *block)
1604 ir_graph *irg = current_ir_graph;
1605 int need_label = block_needs_label(block);
1607 if (block == get_irg_end_block(irg))
1610 if (ia32_cg_config.label_alignment > 0) {
1611 /* align the current block if:
1612 * a) if should be aligned due to its execution frequency
1613 * b) there is no fall-through here
1615 if (should_align_block(block)) {
1616 ia32_emit_align_label();
1618 /* if the predecessor block has no fall-through,
1619 we can always align the label. */
1621 int has_fallthrough = 0;
1623 for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
1624 ir_node *cfg_pred = get_Block_cfgpred(block, i);
1625 if (can_be_fallthrough(cfg_pred)) {
1626 has_fallthrough = 1;
1631 if (!has_fallthrough)
1632 ia32_emit_align_label();
1636 be_gas_begin_block(block, need_label);
1640 * Walks over the nodes in a block connected by scheduling edges
1641 * and emits code for each node.
1643 static void ia32_gen_block(ir_node *block)
1645 ia32_emit_block_header(block);
1648 ir_graph *irg = get_irn_irg(block);
1649 callframe_offset = 4; /* 4 bytes for the return address */
1650 /* ESP guessing, TODO perform a real ESP simulation */
1651 if (block != get_irg_start_block(irg)) {
1652 callframe_offset += frame_type_size;
1654 be_dwarf_callframe_offset(callframe_offset);
1657 /* emit the contents of the block */
1658 be_dwarf_location(get_irn_dbg_info(block));
1659 sched_foreach(block, node) {
1660 ia32_emit_node(node);
1664 typedef struct exc_entry {
1665 ir_node *exc_instr; /** The instruction that can issue an exception. */
1666 ir_node *block; /** The block to call then. */
1671 * Sets labels for control flow nodes (jump target).
1672 * Links control predecessors to there destination blocks.
1674 static void ia32_gen_labels(ir_node *block, void *data)
1676 exc_entry **exc_list = (exc_entry**)data;
1680 for (n = get_Block_n_cfgpreds(block) - 1; n >= 0; --n) {
1681 pred = get_Block_cfgpred(block, n);
1682 set_irn_link(pred, block);
1684 pred = skip_Proj(pred);
1685 if (is_ia32_irn(pred) && get_ia32_exc_label(pred)) {
1690 ARR_APP1(exc_entry, *exc_list, e);
1691 set_irn_link(pred, block);
1697 * Compare two exception_entries.
1699 static int cmp_exc_entry(const void *a, const void *b)
1701 const exc_entry *ea = (const exc_entry*)a;
1702 const exc_entry *eb = (const exc_entry*)b;
1704 if (get_ia32_exc_label_id(ea->exc_instr) < get_ia32_exc_label_id(eb->exc_instr))
1709 static parameter_dbg_info_t *construct_parameter_infos(ir_graph *irg)
1711 ir_entity *entity = get_irg_entity(irg);
1712 ir_type *type = get_entity_type(entity);
1713 size_t n_params = get_method_n_params(type);
1714 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
1715 ir_type *arg_type = layout->arg_type;
1716 size_t n_members = get_compound_n_members(arg_type);
1717 parameter_dbg_info_t *infos = XMALLOCNZ(parameter_dbg_info_t, n_params);
1720 for (i = 0; i < n_members; ++i) {
1721 ir_entity *member = get_compound_member(arg_type, i);
1723 if (!is_parameter_entity(member))
1725 param = get_entity_parameter_number(member);
1726 if (param == IR_VA_START_PARAMETER_NUMBER)
1728 assert(infos[param].entity == NULL && infos[param].reg == NULL);
1729 infos[param].reg = NULL;
1730 infos[param].entity = member;
1737 * Main driver. Emits the code for one routine.
1739 void ia32_gen_routine(ir_graph *irg)
1741 ir_entity *entity = get_irg_entity(irg);
1742 exc_entry *exc_list = NEW_ARR_F(exc_entry, 0);
1743 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
1744 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
1745 ir_node **blk_sched = irg_data->blk_sched;
1746 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
1747 parameter_dbg_info_t *infos;
1750 isa = (ia32_isa_t*) arch_env;
1751 do_pic = be_options.pic;
1753 be_gas_elf_type_char = '@';
1755 ia32_register_emitters();
1757 get_unique_label(pic_base_label, sizeof(pic_base_label), "PIC_BASE");
1759 infos = construct_parameter_infos(irg);
1760 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
1764 sp_relative = layout->sp_relative;
1765 if (layout->sp_relative) {
1766 ir_type *frame_type = get_irg_frame_type(irg);
1767 frame_type_size = get_type_size_bytes(frame_type);
1768 be_dwarf_callframe_register(&ia32_registers[REG_ESP]);
1770 /* well not entirely correct here, we should emit this after the
1771 * "movl esp, ebp" */
1772 be_dwarf_callframe_register(&ia32_registers[REG_EBP]);
1773 /* TODO: do not hardcode the following */
1774 be_dwarf_callframe_offset(8);
1775 be_dwarf_callframe_spilloffset(&ia32_registers[REG_EBP], -8);
1778 /* we use links to point to target blocks */
1779 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
1780 irg_block_walk_graph(irg, ia32_gen_labels, NULL, &exc_list);
1782 /* initialize next block links */
1783 n = ARR_LEN(blk_sched);
1784 for (i = 0; i < n; ++i) {
1785 ir_node *block = blk_sched[i];
1786 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
1788 set_irn_link(block, prev);
1791 for (i = 0; i < n; ++i) {
1792 ir_node *block = blk_sched[i];
1794 ia32_gen_block(block);
1797 be_gas_emit_function_epilog(entity);
1799 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
1801 /* Sort the exception table using the exception label id's.
1802 Those are ascending with ascending addresses. */
1803 qsort(exc_list, ARR_LEN(exc_list), sizeof(exc_list[0]), cmp_exc_entry);
1807 for (e = 0; e < ARR_LEN(exc_list); ++e) {
1808 be_emit_cstring("\t.long ");
1809 ia32_emit_exc_label(exc_list[e].exc_instr);
1811 be_emit_cstring("\t.long ");
1812 be_gas_emit_block_name(exc_list[e].block);
1816 DEL_ARR_F(exc_list);
1819 static const lc_opt_table_entry_t ia32_emitter_options[] = {
1820 LC_OPT_ENT_BOOL("mark_spill_reload", "mark spills and reloads with ud opcodes", &mark_spill_reload),
1824 /* ==== Experimental binary emitter ==== */
1826 static unsigned char reg_gp_map[N_ia32_gp_REGS];
1827 //static unsigned char reg_mmx_map[N_ia32_mmx_REGS];
1828 //static unsigned char reg_sse_map[N_ia32_xmm_REGS];
1830 static void build_reg_map(void)
1832 reg_gp_map[REG_GP_EAX] = 0x0;
1833 reg_gp_map[REG_GP_ECX] = 0x1;
1834 reg_gp_map[REG_GP_EDX] = 0x2;
1835 reg_gp_map[REG_GP_EBX] = 0x3;
1836 reg_gp_map[REG_GP_ESP] = 0x4;
1837 reg_gp_map[REG_GP_EBP] = 0x5;
1838 reg_gp_map[REG_GP_ESI] = 0x6;
1839 reg_gp_map[REG_GP_EDI] = 0x7;
1842 /** Returns the encoding for a pnc field. */
1843 static unsigned char pnc2cc(ia32_condition_code_t cc)
1848 /** Sign extension bit values for binops */
1850 UNSIGNED_IMM = 0, /**< unsigned immediate */
1851 SIGNEXT_IMM = 2, /**< sign extended immediate */
1854 /** The mod encoding of the ModR/M */
1856 MOD_IND = 0x00, /**< [reg1] */
1857 MOD_IND_BYTE_OFS = 0x40, /**< [reg1 + byte ofs] */
1858 MOD_IND_WORD_OFS = 0x80, /**< [reg1 + word ofs] */
1859 MOD_REG = 0xC0 /**< reg1 */
1862 /** create R/M encoding for ModR/M */
1863 #define ENC_RM(x) (x)
1864 /** create REG encoding for ModR/M */
1865 #define ENC_REG(x) ((x) << 3)
1867 /** create encoding for a SIB byte */
1868 #define ENC_SIB(scale, index, base) ((scale) << 6 | (index) << 3 | (base))
1870 /* Node: The following routines are supposed to append bytes, words, dwords
1871 to the output stream.
1872 Currently the implementation is stupid in that it still creates output
1873 for an "assembler" in the form of .byte, .long
1874 We will change this when enough infrastructure is there to create complete
1875 machine code in memory/object files */
1877 static void bemit8(const unsigned char byte)
1879 be_emit_irprintf("\t.byte 0x%x\n", byte);
1880 be_emit_write_line();
1883 static void bemit16(const unsigned short u16)
1885 be_emit_irprintf("\t.word 0x%x\n", u16);
1886 be_emit_write_line();
1889 static void bemit32(const unsigned u32)
1891 be_emit_irprintf("\t.long 0x%x\n", u32);
1892 be_emit_write_line();
1896 * Emit address of an entity. If @p is_relative is true then a relative
1897 * offset from behind the address to the entity is created.
1899 static void bemit_entity(ir_entity *entity, bool entity_sign, int offset,
1902 if (entity == NULL) {
1907 /* the final version should remember the position in the bytestream
1908 and patch it with the correct address at linktime... */
1909 be_emit_cstring("\t.long ");
1912 be_gas_emit_entity(entity);
1914 if (get_entity_owner(entity) == get_tls_type()) {
1915 if (!entity_has_definition(entity)) {
1916 be_emit_cstring("@INDNTPOFF");
1918 be_emit_cstring("@NTPOFF");
1923 be_emit_cstring("-.");
1928 be_emit_irprintf("%+d", offset);
1931 be_emit_write_line();
1934 static void bemit_jmp_destination(const ir_node *dest_block)
1936 be_emit_cstring("\t.long ");
1937 be_gas_emit_block_name(dest_block);
1938 be_emit_cstring(" - . - 4\n");
1939 be_emit_write_line();
1942 /* end emit routines, all emitters following here should only use the functions
1945 typedef enum reg_modifier {
1950 /** Create a ModR/M byte for src1,src2 registers */
1951 static void bemit_modrr(const arch_register_t *src1,
1952 const arch_register_t *src2)
1954 unsigned char modrm = MOD_REG;
1955 modrm |= ENC_RM(reg_gp_map[src1->index]);
1956 modrm |= ENC_REG(reg_gp_map[src2->index]);
1960 /** Create a ModR/M8 byte for src1,src2 registers */
1961 static void bemit_modrr8(reg_modifier_t high_part1, const arch_register_t *src1,
1962 reg_modifier_t high_part2, const arch_register_t *src2)
1964 unsigned char modrm = MOD_REG;
1965 modrm |= ENC_RM(reg_gp_map[src1->index] + (high_part1 == REG_HIGH ? 4 : 0));
1966 modrm |= ENC_REG(reg_gp_map[src2->index] + (high_part2 == REG_HIGH ? 4 : 0));
1970 /** Create a ModR/M byte for one register and extension */
1971 static void bemit_modru(const arch_register_t *reg, unsigned ext)
1973 unsigned char modrm = MOD_REG;
1975 modrm |= ENC_RM(reg_gp_map[reg->index]);
1976 modrm |= ENC_REG(ext);
1980 /** Create a ModR/M8 byte for one register */
1981 static void bemit_modrm8(reg_modifier_t high_part, const arch_register_t *reg)
1983 unsigned char modrm = MOD_REG;
1984 assert(reg_gp_map[reg->index] < 4);
1985 modrm |= ENC_RM(reg_gp_map[reg->index] + (high_part == REG_HIGH ? 4 : 0));
1991 * Calculate the size of an signed immediate in bytes.
1993 * @param offset an offset
1995 static unsigned get_signed_imm_size(int offset)
1997 if (-128 <= offset && offset < 128) {
1999 } else if (-32768 <= offset && offset < 32768) {
2007 * Emit an address mode.
2009 * @param reg content of the reg field: either a register index or an opcode extension
2010 * @param node the node
2012 static void bemit_mod_am(unsigned reg, const ir_node *node)
2014 ir_entity *ent = get_ia32_am_sc(node);
2015 int offs = get_ia32_am_offs_int(node);
2016 ir_node *base = get_irn_n(node, n_ia32_base);
2017 int has_base = !is_ia32_NoReg_GP(base);
2018 ir_node *idx = get_irn_n(node, n_ia32_index);
2019 int has_index = !is_ia32_NoReg_GP(idx);
2022 unsigned emitoffs = 0;
2023 bool emitsib = false;
2026 /* set the mod part depending on displacement */
2028 modrm |= MOD_IND_WORD_OFS;
2030 } else if (offs == 0) {
2033 } else if (-128 <= offs && offs < 128) {
2034 modrm |= MOD_IND_BYTE_OFS;
2037 modrm |= MOD_IND_WORD_OFS;
2042 const arch_register_t *base_reg = arch_get_irn_register(base);
2043 base_enc = reg_gp_map[base_reg->index];
2045 /* Use the EBP encoding + MOD_IND if NO base register. There is
2046 * always a 32bit offset present in this case. */
2052 /* Determine if we need a SIB byte. */
2054 const arch_register_t *reg_index = arch_get_irn_register(idx);
2055 int scale = get_ia32_am_scale(node);
2057 /* R/M set to ESP means SIB in 32bit mode. */
2058 modrm |= ENC_RM(0x04);
2059 sib = ENC_SIB(scale, reg_gp_map[reg_index->index], base_enc);
2061 } else if (base_enc == 0x04) {
2062 /* for the above reason we are forced to emit a SIB when base is ESP.
2063 * Only the base is used, index must be ESP too, which means no index.
2065 modrm |= ENC_RM(0x04);
2066 sib = ENC_SIB(0, 0x04, 0x04);
2069 modrm |= ENC_RM(base_enc);
2072 /* We are forced to emit an 8bit offset as EBP base without offset is a
2073 * special case for SIB without base register. */
2074 if (base_enc == 0x05 && emitoffs == 0) {
2075 modrm |= MOD_IND_BYTE_OFS;
2079 modrm |= ENC_REG(reg);
2085 /* emit displacement */
2086 if (emitoffs == 8) {
2087 bemit8((unsigned) offs);
2088 } else if (emitoffs == 32) {
2089 bemit_entity(ent, is_ia32_am_sc_sign(node), offs, false);
2094 * Emit a binop with a immediate operand.
2096 * @param node the node to emit
2097 * @param opcode_eax the opcode for the op eax, imm variant
2098 * @param opcode the opcode for the reg, imm variant
2099 * @param ruval the opcode extension for opcode
2101 static void bemit_binop_with_imm(
2102 const ir_node *node,
2103 unsigned char opcode_ax,
2104 unsigned char opcode, unsigned char ruval)
2106 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2107 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2108 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2111 /* Some instructions (test) have no short form with 32bit value + 8bit
2113 if (attr->symconst != NULL || opcode & SIGNEXT_IMM) {
2116 /* check for sign extension */
2117 size = get_signed_imm_size(attr->offset);
2122 bemit8(opcode | SIGNEXT_IMM);
2123 /* cmp has this special mode */
2124 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2125 bemit_mod_am(ruval, node);
2127 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2128 bemit_modru(reg, ruval);
2130 bemit8((unsigned char)attr->offset);
2134 /* check for eax variant: this variant is shorter for 32bit immediates only */
2135 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2137 bemit_mod_am(ruval, node);
2139 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2140 if (reg->index == REG_GP_EAX) {
2144 bemit_modru(reg, ruval);
2147 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2150 panic("invalid imm size?!?");
2156 static void bemit_binop_2(const ir_node *node, unsigned code)
2158 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2160 if (get_ia32_op_type(node) == ia32_Normal) {
2161 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2162 bemit_modrr(op2, out);
2164 bemit_mod_am(reg_gp_map[out->index], node);
2171 static void bemit_binop(const ir_node *node, const unsigned char opcodes[4])
2173 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2174 if (is_ia32_Immediate(right)) {
2175 bemit_binop_with_imm(node, opcodes[1], opcodes[2], opcodes[3]);
2177 bemit_binop_2(node, opcodes[0]);
2184 static void bemit_unop(const ir_node *node, unsigned char code, unsigned char ext, int input)
2187 if (get_ia32_op_type(node) == ia32_Normal) {
2188 const arch_register_t *in = arch_get_irn_register_in(node, input);
2189 bemit_modru(in, ext);
2191 bemit_mod_am(ext, node);
2195 static void bemit_unop_reg(const ir_node *node, unsigned char code, int input)
2197 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2198 bemit_unop(node, code, reg_gp_map[out->index], input);
2201 static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned char ext)
2203 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2206 bemit8(size == 8 ? code : code + 1);
2207 bemit_mod_am(ext, node);
2210 static void bemit_0f_unop_reg(ir_node const *const node, unsigned char const code, int const input)
2213 bemit_unop_reg(node, code, input);
2216 static void bemit_immediate(const ir_node *node, bool relative)
2218 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
2219 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, relative);
2222 static void bemit_copy(const ir_node *copy)
2224 const arch_register_t *in = arch_get_irn_register_in(copy, 0);
2225 const arch_register_t *out = arch_get_irn_register_out(copy, 0);
2229 /* copies of vf nodes aren't real... */
2230 if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
2233 assert(arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_gp]);
2235 bemit_modrr(in, out);
2238 static void bemit_perm(const ir_node *node)
2240 const arch_register_t *in0 = arch_get_irn_register(get_irn_n(node, 0));
2241 const arch_register_t *in1 = arch_get_irn_register(get_irn_n(node, 1));
2242 const arch_register_class_t *cls0 = arch_register_get_class(in0);
2244 assert(cls0 == arch_register_get_class(in1) && "Register class mismatch at Perm");
2246 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
2247 if (in0->index == REG_GP_EAX) {
2248 bemit8(0x90 + reg_gp_map[in1->index]);
2249 } else if (in1->index == REG_GP_EAX) {
2250 bemit8(0x90 + reg_gp_map[in0->index]);
2253 bemit_modrr(in0, in1);
2255 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
2256 panic("unimplemented"); // TODO implement
2257 //ia32_emitf(NULL, "xorpd %R, %R", in1, in0);
2258 //ia32_emitf(NULL, "xorpd %R, %R", in0, in1);
2259 //ia32_emitf(node, "xorpd %R, %R", in1, in0);
2260 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
2262 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
2265 panic("unexpected register class in be_Perm (%+F)", node);
2269 static void bemit_xor0(const ir_node *node)
2271 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2273 bemit_modrr(out, out);
2276 static void bemit_mov_const(const ir_node *node)
2278 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2279 bemit8(0xB8 + reg_gp_map[out->index]);
2280 bemit_immediate(node, false);
2284 * Creates a function for a Binop with 3 possible encodings.
2286 #define BINOP(op, op0, op1, op2, op2_ext) \
2287 static void bemit_ ## op(const ir_node *node) { \
2288 static const unsigned char op ## _codes[] = {op0, op1, op2, op2_ext}; \
2289 bemit_binop(node, op ## _codes); \
2292 /* insn def eax,imm imm */
2293 BINOP(add, 0x03, 0x05, 0x81, 0)
2294 BINOP(or, 0x0B, 0x0D, 0x81, 1)
2295 BINOP(adc, 0x13, 0x15, 0x81, 2)
2296 BINOP(sbb, 0x1B, 0x1D, 0x81, 3)
2297 BINOP(and, 0x23, 0x25, 0x81, 4)
2298 BINOP(sub, 0x2B, 0x2D, 0x81, 5)
2299 BINOP(xor, 0x33, 0x35, 0x81, 6)
2300 BINOP(test, 0x85, 0xA9, 0xF7, 0)
2302 #define BINOPMEM(op, ext) \
2303 static void bemit_##op(const ir_node *node) \
2306 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2309 val = get_irn_n(node, n_ia32_unary_op); \
2310 if (is_ia32_Immediate(val)) { \
2311 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(val); \
2312 int offset = attr->offset; \
2313 if (attr->symconst == NULL && get_signed_imm_size(offset) == 1) { \
2315 bemit_mod_am(ext, node); \
2319 bemit_mod_am(ext, node); \
2323 bemit_entity(attr->symconst, attr->sc_sign, offset, false); \
2327 bemit8(ext << 3 | 1); \
2328 bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
2332 static void bemit_##op##8bit(const ir_node *node) \
2334 ir_node *val = get_irn_n(node, n_ia32_unary_op); \
2335 if (is_ia32_Immediate(val)) { \
2337 bemit_mod_am(ext, node); \
2338 bemit8(get_ia32_immediate_attr_const(val)->offset); \
2341 bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
2353 * Creates a function for an Unop with code /ext encoding.
2355 #define UNOP(op, code, ext, input) \
2356 static void bemit_ ## op(const ir_node *node) { \
2357 bemit_unop(node, code, ext, input); \
2360 UNOP(not, 0xF7, 2, n_ia32_Not_val)
2361 UNOP(neg, 0xF7, 3, n_ia32_Neg_val)
2362 UNOP(mul, 0xF7, 4, n_ia32_Mul_right)
2363 UNOP(imul1op, 0xF7, 5, n_ia32_IMul1OP_right)
2364 UNOP(div, 0xF7, 6, n_ia32_Div_divisor)
2365 UNOP(idiv, 0xF7, 7, n_ia32_IDiv_divisor)
2367 /* TODO: am support for IJmp */
2368 UNOP(ijmp, 0xFF, 4, n_ia32_IJmp_target)
2370 #define SHIFT(op, ext) \
2371 static void bemit_##op(const ir_node *node) \
2373 const arch_register_t *out = arch_get_irn_register_out(node, 0); \
2374 ir_node *count = get_irn_n(node, 1); \
2375 if (is_ia32_Immediate(count)) { \
2376 int offset = get_ia32_immediate_attr_const(count)->offset; \
2377 if (offset == 1) { \
2379 bemit_modru(out, ext); \
2382 bemit_modru(out, ext); \
2387 bemit_modru(out, ext); \
2391 static void bemit_##op##mem(const ir_node *node) \
2394 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2397 count = get_irn_n(node, 1); \
2398 if (is_ia32_Immediate(count)) { \
2399 int offset = get_ia32_immediate_attr_const(count)->offset; \
2400 if (offset == 1) { \
2401 bemit8(size == 8 ? 0xD0 : 0xD1); \
2402 bemit_mod_am(ext, node); \
2404 bemit8(size == 8 ? 0xC0 : 0xC1); \
2405 bemit_mod_am(ext, node); \
2409 bemit8(size == 8 ? 0xD2 : 0xD3); \
2410 bemit_mod_am(ext, node); \
2420 static void bemit_shld(const ir_node *node)
2422 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShlD_val_low);
2423 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShlD_res);
2424 ir_node *count = get_irn_n(node, n_ia32_ShlD_count);
2426 if (is_ia32_Immediate(count)) {
2428 bemit_modrr(out, in);
2429 bemit8(get_ia32_immediate_attr_const(count)->offset);
2432 bemit_modrr(out, in);
2436 static void bemit_shrd(const ir_node *node)
2438 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShrD_val_low);
2439 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShrD_res);
2440 ir_node *count = get_irn_n(node, n_ia32_ShrD_count);
2442 if (is_ia32_Immediate(count)) {
2444 bemit_modrr(out, in);
2445 bemit8(get_ia32_immediate_attr_const(count)->offset);
2448 bemit_modrr(out, in);
2453 * binary emitter for setcc.
2455 static void bemit_setcc(const ir_node *node)
2457 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
2459 ia32_condition_code_t cc = get_ia32_condcode(node);
2460 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
2461 if (cc & ia32_cc_float_parity_cases) {
2462 if (cc & ia32_cc_negated) {
2465 bemit8(0x90 | pnc2cc(cc));
2466 bemit_modrm8(REG_LOW, dreg);
2471 bemit_modrm8(REG_HIGH, dreg);
2473 /* orb %>dreg, %<dreg */
2475 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2479 bemit8(0x90 | pnc2cc(cc));
2480 bemit_modrm8(REG_LOW, dreg);
2485 bemit_modrm8(REG_HIGH, dreg);
2487 /* andb %>dreg, %<dreg */
2489 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2494 bemit8(0x90 | pnc2cc(cc));
2495 bemit_modrm8(REG_LOW, dreg);
2499 static void bemit_bsf(ir_node const *const node)
2501 bemit_0f_unop_reg(node, 0xBC, n_ia32_Bsf_operand);
2504 static void bemit_bsr(ir_node const *const node)
2506 bemit_0f_unop_reg(node, 0xBD, n_ia32_Bsr_operand);
2509 static void bemit_cmovcc(const ir_node *node)
2511 const ia32_attr_t *attr = get_ia32_attr_const(node);
2512 int ins_permuted = attr->data.ins_permuted;
2513 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
2514 ia32_condition_code_t cc = get_ia32_condcode(node);
2515 const arch_register_t *in_true;
2516 const arch_register_t *in_false;
2518 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
2520 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
2521 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
2523 /* should be same constraint fullfilled? */
2524 if (out == in_false) {
2525 /* yes -> nothing to do */
2526 } else if (out == in_true) {
2527 assert(get_ia32_op_type(node) == ia32_Normal);
2528 ins_permuted = !ins_permuted;
2532 bemit8(0x8B); // mov %in_false, %out
2533 bemit_modrr(in_false, out);
2537 cc = ia32_negate_condition_code(cc);
2539 if (cc & ia32_cc_float_parity_cases)
2540 panic("cmov can't handle parity float cases");
2543 bemit8(0x40 | pnc2cc(cc));
2544 if (get_ia32_op_type(node) == ia32_Normal) {
2545 bemit_modrr(in_true, out);
2547 bemit_mod_am(reg_gp_map[out->index], node);
2551 static void bemit_cmp(const ir_node *node)
2553 unsigned ls_size = get_mode_size_bits(get_ia32_ls_mode(node));
2559 right = get_irn_n(node, n_ia32_binary_right);
2560 if (is_ia32_Immediate(right)) {
2561 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2562 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2563 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2566 if (attr->symconst != NULL) {
2569 /* check for sign extension */
2570 size = get_signed_imm_size(attr->offset);
2575 bemit8(0x81 | SIGNEXT_IMM);
2576 /* cmp has this special mode */
2577 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2578 bemit_mod_am(7, node);
2580 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2581 bemit_modru(reg, 7);
2583 bemit8((unsigned char)attr->offset);
2587 /* check for eax variant: this variant is shorter for 32bit immediates only */
2588 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2590 bemit_mod_am(7, node);
2592 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2593 if (reg->index == REG_GP_EAX) {
2597 bemit_modru(reg, 7);
2600 if (ls_size == 16) {
2601 bemit16(attr->offset);
2603 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2607 panic("invalid imm size?!?");
2609 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2611 if (get_ia32_op_type(node) == ia32_Normal) {
2612 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2613 bemit_modrr(op2, out);
2615 bemit_mod_am(reg_gp_map[out->index], node);
2620 static void bemit_cmp8bit(const ir_node *node)
2622 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2623 if (is_ia32_Immediate(right)) {
2624 if (get_ia32_op_type(node) == ia32_Normal) {
2625 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2626 if (out->index == REG_GP_EAX) {
2630 bemit_modru(out, 7);
2634 bemit_mod_am(7, node);
2636 bemit8(get_ia32_immediate_attr_const(right)->offset);
2638 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2640 if (get_ia32_op_type(node) == ia32_Normal) {
2641 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Cmp_right);
2642 bemit_modrr(out, in);
2644 bemit_mod_am(reg_gp_map[out->index], node);
2649 static void bemit_test8bit(const ir_node *node)
2651 ir_node *right = get_irn_n(node, n_ia32_Test8Bit_right);
2652 if (is_ia32_Immediate(right)) {
2653 if (get_ia32_op_type(node) == ia32_Normal) {
2654 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
2655 if (out->index == REG_GP_EAX) {
2659 bemit_modru(out, 0);
2663 bemit_mod_am(0, node);
2665 bemit8(get_ia32_immediate_attr_const(right)->offset);
2667 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
2669 if (get_ia32_op_type(node) == ia32_Normal) {
2670 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Test8Bit_right);
2671 bemit_modrr(out, in);
2673 bemit_mod_am(reg_gp_map[out->index], node);
2678 static void bemit_imul(const ir_node *node)
2680 ir_node *right = get_irn_n(node, n_ia32_IMul_right);
2681 /* Do we need the immediate form? */
2682 if (is_ia32_Immediate(right)) {
2683 int imm = get_ia32_immediate_attr_const(right)->offset;
2684 if (get_signed_imm_size(imm) == 1) {
2685 bemit_unop_reg(node, 0x6B, n_ia32_IMul_left);
2688 bemit_unop_reg(node, 0x69, n_ia32_IMul_left);
2692 bemit_0f_unop_reg(node, 0xAF, n_ia32_IMul_right);
2696 static void bemit_dec(const ir_node *node)
2698 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Dec_res);
2699 bemit8(0x48 + reg_gp_map[out->index]);
2702 static void bemit_inc(const ir_node *node)
2704 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Inc_res);
2705 bemit8(0x40 + reg_gp_map[out->index]);
2708 #define UNOPMEM(op, code, ext) \
2709 static void bemit_##op(const ir_node *node) \
2711 bemit_unop_mem(node, code, ext); \
2714 UNOPMEM(notmem, 0xF6, 2)
2715 UNOPMEM(negmem, 0xF6, 3)
2716 UNOPMEM(incmem, 0xFE, 0)
2717 UNOPMEM(decmem, 0xFE, 1)
2719 static void bemit_ldtls(const ir_node *node)
2721 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2723 bemit8(0x65); // gs:
2724 if (out->index == REG_GP_EAX) {
2725 bemit8(0xA1); // movl 0, %eax
2727 bemit8(0x8B); // movl 0, %reg
2728 bemit8(MOD_IND | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x05));
2736 static void bemit_lea(const ir_node *node)
2738 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2740 bemit_mod_am(reg_gp_map[out->index], node);
2743 /* helper function for bemit_minus64bit */
2744 static void bemit_helper_mov(const arch_register_t *src, const arch_register_t *dst)
2746 bemit8(0x8B); // movl %src, %dst
2747 bemit_modrr(src, dst);
2750 /* helper function for bemit_minus64bit */
2751 static void bemit_helper_neg(const arch_register_t *reg)
2753 bemit8(0xF7); // negl %reg
2754 bemit_modru(reg, 3);
2757 /* helper function for bemit_minus64bit */
2758 static void bemit_helper_sbb0(const arch_register_t *reg)
2760 bemit8(0x83); // sbbl $0, %reg
2761 bemit_modru(reg, 3);
2765 /* helper function for bemit_minus64bit */
2766 static void bemit_helper_sbb(const arch_register_t *src, const arch_register_t *dst)
2768 bemit8(0x1B); // sbbl %src, %dst
2769 bemit_modrr(src, dst);
2772 /* helper function for bemit_minus64bit */
2773 static void bemit_helper_xchg(const arch_register_t *src, const arch_register_t *dst)
2775 if (src->index == REG_GP_EAX) {
2776 bemit8(0x90 + reg_gp_map[dst->index]); // xchgl %eax, %dst
2777 } else if (dst->index == REG_GP_EAX) {
2778 bemit8(0x90 + reg_gp_map[src->index]); // xchgl %src, %eax
2780 bemit8(0x87); // xchgl %src, %dst
2781 bemit_modrr(src, dst);
2785 /* helper function for bemit_minus64bit */
2786 static void bemit_helper_zero(const arch_register_t *reg)
2788 bemit8(0x33); // xorl %reg, %reg
2789 bemit_modrr(reg, reg);
2792 static void bemit_minus64bit(const ir_node *node)
2794 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
2795 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
2796 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
2797 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
2799 if (out_lo == in_lo) {
2800 if (out_hi != in_hi) {
2801 /* a -> a, b -> d */
2804 /* a -> a, b -> b */
2807 } else if (out_lo == in_hi) {
2808 if (out_hi == in_lo) {
2809 /* a -> b, b -> a */
2810 bemit_helper_xchg(in_lo, in_hi);
2813 /* a -> b, b -> d */
2814 bemit_helper_mov(in_hi, out_hi);
2815 bemit_helper_mov(in_lo, out_lo);
2819 if (out_hi == in_lo) {
2820 /* a -> c, b -> a */
2821 bemit_helper_mov(in_lo, out_lo);
2823 } else if (out_hi == in_hi) {
2824 /* a -> c, b -> b */
2825 bemit_helper_mov(in_lo, out_lo);
2828 /* a -> c, b -> d */
2829 bemit_helper_mov(in_lo, out_lo);
2835 bemit_helper_neg( out_hi);
2836 bemit_helper_neg( out_lo);
2837 bemit_helper_sbb0(out_hi);
2841 bemit_helper_zero(out_hi);
2842 bemit_helper_neg( out_lo);
2843 bemit_helper_sbb( in_hi, out_hi);
2847 * Emit a single opcode.
2849 #define EMIT_SINGLEOP(op, code) \
2850 static void bemit_ ## op(const ir_node *node) { \
2855 //EMIT_SINGLEOP(daa, 0x27)
2856 //EMIT_SINGLEOP(das, 0x2F)
2857 //EMIT_SINGLEOP(aaa, 0x37)
2858 //EMIT_SINGLEOP(aas, 0x3F)
2859 //EMIT_SINGLEOP(nop, 0x90)
2860 EMIT_SINGLEOP(cwtl, 0x98)
2861 EMIT_SINGLEOP(cltd, 0x99)
2862 //EMIT_SINGLEOP(fwait, 0x9B)
2863 EMIT_SINGLEOP(sahf, 0x9E)
2864 //EMIT_SINGLEOP(popf, 0x9D)
2865 EMIT_SINGLEOP(leave, 0xC9)
2866 EMIT_SINGLEOP(int3, 0xCC)
2867 //EMIT_SINGLEOP(iret, 0xCF)
2868 //EMIT_SINGLEOP(xlat, 0xD7)
2869 //EMIT_SINGLEOP(lock, 0xF0)
2870 EMIT_SINGLEOP(rep, 0xF3)
2871 //EMIT_SINGLEOP(halt, 0xF4)
2872 EMIT_SINGLEOP(cmc, 0xF5)
2873 EMIT_SINGLEOP(stc, 0xF9)
2874 //EMIT_SINGLEOP(cli, 0xFA)
2875 //EMIT_SINGLEOP(sti, 0xFB)
2876 //EMIT_SINGLEOP(std, 0xFD)
2879 * Emits a MOV out, [MEM].
2881 static void bemit_load(const ir_node *node)
2883 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2885 if (out->index == REG_GP_EAX) {
2886 ir_node *base = get_irn_n(node, n_ia32_base);
2887 int has_base = !is_ia32_NoReg_GP(base);
2888 ir_node *idx = get_irn_n(node, n_ia32_index);
2889 int has_index = !is_ia32_NoReg_GP(idx);
2890 if (!has_base && !has_index) {
2891 ir_entity *ent = get_ia32_am_sc(node);
2892 int offs = get_ia32_am_offs_int(node);
2893 /* load from constant address to EAX can be encoded
2896 bemit_entity(ent, 0, offs, false);
2901 bemit_mod_am(reg_gp_map[out->index], node);
2905 * Emits a MOV [mem], in.
2907 static void bemit_store(const ir_node *node)
2909 const ir_node *value = get_irn_n(node, n_ia32_Store_val);
2910 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2912 if (is_ia32_Immediate(value)) {
2915 bemit_mod_am(0, node);
2916 bemit8(get_ia32_immediate_attr_const(value)->offset);
2917 } else if (size == 16) {
2920 bemit_mod_am(0, node);
2921 bemit16(get_ia32_immediate_attr_const(value)->offset);
2924 bemit_mod_am(0, node);
2925 bemit_immediate(value, false);
2928 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Store_val);
2930 if (in->index == REG_GP_EAX) {
2931 ir_node *base = get_irn_n(node, n_ia32_base);
2932 int has_base = !is_ia32_NoReg_GP(base);
2933 ir_node *idx = get_irn_n(node, n_ia32_index);
2934 int has_index = !is_ia32_NoReg_GP(idx);
2935 if (!has_base && !has_index) {
2936 ir_entity *ent = get_ia32_am_sc(node);
2937 int offs = get_ia32_am_offs_int(node);
2938 /* store to constant address from EAX can be encoded as
2939 * 0xA2/0xA3 [offset]*/
2947 bemit_entity(ent, 0, offs, false);
2959 bemit_mod_am(reg_gp_map[in->index], node);
2963 static void bemit_conv_i2i(const ir_node *node)
2968 ir_mode *const smaller_mode = get_ia32_ls_mode(node);
2969 unsigned opcode = 0xB6;
2970 if (mode_is_signed(smaller_mode)) opcode |= 0x08;
2971 if (get_mode_size_bits(smaller_mode) == 16) opcode |= 0x01;
2972 bemit_0f_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
2978 static void bemit_push(const ir_node *node)
2980 const ir_node *value = get_irn_n(node, n_ia32_Push_val);
2982 if (is_ia32_Immediate(value)) {
2983 const ia32_immediate_attr_t *attr
2984 = get_ia32_immediate_attr_const(value);
2985 unsigned size = get_signed_imm_size(attr->offset);
2991 bemit8((unsigned char)attr->offset);
2996 bemit_immediate(value, false);
2999 } else if (is_ia32_NoReg_GP(value)) {
3001 bemit_mod_am(6, node);
3003 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_Push_val);
3004 bemit8(0x50 + reg_gp_map[reg->index]);
3011 static void bemit_pop(const ir_node *node)
3013 const arch_register_t *reg = arch_get_irn_register_out(node, pn_ia32_Pop_res);
3014 bemit8(0x58 + reg_gp_map[reg->index]);
3017 static void bemit_popmem(const ir_node *node)
3020 bemit_mod_am(0, node);
3023 static void bemit_call(const ir_node *node)
3025 ir_node *proc = get_irn_n(node, n_ia32_Call_addr);
3027 if (is_ia32_Immediate(proc)) {
3029 bemit_immediate(proc, true);
3031 bemit_unop(node, 0xFF, 2, n_ia32_Call_addr);
3035 static void bemit_jmp(const ir_node *dest_block)
3038 bemit_jmp_destination(dest_block);
3041 static void bemit_jump(const ir_node *node)
3043 if (can_be_fallthrough(node))
3046 bemit_jmp(get_cfop_target_block(node));
3049 static void bemit_jcc(ia32_condition_code_t pnc, const ir_node *dest_block)
3051 unsigned char cc = pnc2cc(pnc);
3054 bemit_jmp_destination(dest_block);
3057 static void bemit_jp(bool odd, const ir_node *dest_block)
3061 bemit_jmp_destination(dest_block);
3064 static void bemit_ia32_jcc(const ir_node *node)
3066 ia32_condition_code_t cc = get_ia32_condcode(node);
3067 const ir_node *proj_true;
3068 const ir_node *proj_false;
3069 const ir_node *dest_true;
3070 const ir_node *dest_false;
3072 cc = determine_final_cc(node, 0, cc);
3074 /* get both Projs */
3075 proj_true = get_proj(node, pn_ia32_Jcc_true);
3076 assert(proj_true && "Jcc without true Proj");
3078 proj_false = get_proj(node, pn_ia32_Jcc_false);
3079 assert(proj_false && "Jcc without false Proj");
3081 if (can_be_fallthrough(proj_true)) {
3082 /* exchange both proj's so the second one can be omitted */
3083 const ir_node *t = proj_true;
3085 proj_true = proj_false;
3087 cc = ia32_negate_condition_code(cc);
3090 dest_true = get_cfop_target_block(proj_true);
3091 dest_false = get_cfop_target_block(proj_false);
3093 if (cc & ia32_cc_float_parity_cases) {
3094 /* Some floating point comparisons require a test of the parity flag,
3095 * which indicates that the result is unordered */
3096 if (cc & ia32_cc_negated) {
3097 bemit_jp(false, dest_true);
3099 /* we need a local label if the false proj is a fallthrough
3100 * as the falseblock might have no label emitted then */
3101 if (can_be_fallthrough(proj_false)) {
3103 bemit8(0x06); // jp + 6
3105 bemit_jp(false, dest_false);
3109 bemit_jcc(cc, dest_true);
3111 /* the second Proj might be a fallthrough */
3112 if (can_be_fallthrough(proj_false)) {
3113 /* it's a fallthrough */
3115 bemit_jmp(dest_false);
3119 static void bemit_switchjmp(const ir_node *node)
3121 ir_entity *jump_table = get_ia32_am_sc(node);
3122 const ir_switch_table *table = get_ia32_switch_table(node);
3124 bemit8(0xFF); // jmp *tbl.label(,%in,4)
3125 bemit_mod_am(0x05, node);
3127 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
3133 static void bemit_return(const ir_node *node)
3135 unsigned pop = be_Return_get_pop(node);
3136 if (pop > 0 || be_Return_get_emit_pop(node)) {
3138 assert(pop <= 0xffff);
3145 static void bemit_subsp(const ir_node *node)
3147 const arch_register_t *out;
3150 /* mov %esp, %out */
3152 out = arch_get_irn_register_out(node, 1);
3153 bemit8(MOD_REG | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x04));
3156 static void bemit_incsp(const ir_node *node)
3159 const arch_register_t *reg;
3163 offs = be_get_IncSP_offset(node);
3174 size = get_signed_imm_size(offs);
3175 bemit8(size == 1 ? 0x83 : 0x81);
3177 reg = arch_get_irn_register_out(node, 0);
3178 bemit_modru(reg, ext);
3187 static void bemit_copybi(const ir_node *node)
3189 unsigned size = get_ia32_copyb_size(node);
3191 bemit8(0xA4); // movsb
3194 bemit8(0xA5); // movsw
3198 bemit8(0xA5); // movsl
3202 static void bemit_fbinop(const ir_node *node, unsigned code, unsigned code_to)
3204 if (get_ia32_op_type(node) == ia32_Normal) {
3205 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
3206 const arch_register_t *in1 = x87_attr->x87[0];
3207 const arch_register_t *in = x87_attr->x87[1];
3208 const arch_register_t *out = x87_attr->x87[2];
3212 } else if (out == in) {
3216 if (out->index == 0) {
3218 bemit8(MOD_REG | ENC_REG(code) | ENC_RM(in->index));
3221 bemit8(MOD_REG | ENC_REG(code_to) | ENC_RM(out->index));
3224 if (get_mode_size_bits(get_ia32_ls_mode(node)) == 32) {
3229 bemit_mod_am(code, node);
3233 static void bemit_fbinopp(const ir_node *node, unsigned const code)
3235 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
3236 const arch_register_t *out = x87_attr->x87[2];
3238 bemit8(code + out->index);
3241 static void bemit_fop_reg(ir_node const *const node, unsigned char const op0, unsigned char const op1)
3244 bemit8(op1 + get_ia32_x87_attr_const(node)->x87[0]->index);
3247 static void bemit_fabs(const ir_node *node)
3255 static void bemit_fadd(const ir_node *node)
3257 bemit_fbinop(node, 0, 0);
3260 static void bemit_faddp(const ir_node *node)
3262 bemit_fbinopp(node, 0xC0);
3265 static void bemit_fchs(const ir_node *node)
3273 static void bemit_fdiv(const ir_node *node)
3275 bemit_fbinop(node, 6, 7);
3278 static void bemit_fdivp(const ir_node *node)
3280 bemit_fbinopp(node, 0xF8);
3283 static void bemit_fdivr(const ir_node *node)
3285 bemit_fbinop(node, 7, 6);
3288 static void bemit_fdivrp(const ir_node *node)
3290 bemit_fbinopp(node, 0xF0);
3293 static void bemit_fild(const ir_node *node)
3295 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3297 bemit8(0xDF); // filds
3298 bemit_mod_am(0, node);
3302 bemit8(0xDB); // fildl
3303 bemit_mod_am(0, node);
3307 bemit8(0xDF); // fildll
3308 bemit_mod_am(5, node);
3312 panic("invalid mode size");
3316 static void bemit_fist(const ir_node *node)
3318 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3320 bemit8(0xDF); // fists
3324 bemit8(0xDB); // fistl
3328 panic("invalid mode size");
3330 bemit_mod_am(2, node);
3333 static void bemit_fistp(const ir_node *node)
3335 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3337 bemit8(0xDF); // fistps
3338 bemit_mod_am(3, node);
3342 bemit8(0xDB); // fistpl
3343 bemit_mod_am(3, node);
3347 bemit8(0xDF); // fistpll
3348 bemit_mod_am(7, node);
3352 panic("invalid mode size");
3356 static void bemit_fld(const ir_node *node)
3358 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3360 bemit8(0xD9); // flds
3361 bemit_mod_am(0, node);
3365 bemit8(0xDD); // fldl
3366 bemit_mod_am(0, node);
3371 bemit8(0xDB); // fldt
3372 bemit_mod_am(5, node);
3376 panic("invalid mode size");
3380 static void bemit_fld1(const ir_node *node)
3384 bemit8(0xE8); // fld1
3387 static void bemit_fldcw(const ir_node *node)
3389 bemit8(0xD9); // fldcw
3390 bemit_mod_am(5, node);
3393 static void bemit_fldz(const ir_node *node)
3397 bemit8(0xEE); // fldz
3400 static void bemit_fmul(const ir_node *node)
3402 bemit_fbinop(node, 1, 1);
3405 static void bemit_fmulp(const ir_node *node)
3407 bemit_fbinopp(node, 0xC8);
3410 static void bemit_fpop(const ir_node *node)
3412 bemit_fop_reg(node, 0xDD, 0xD8);
3415 static void bemit_fpush(const ir_node *node)
3417 bemit_fop_reg(node, 0xD9, 0xC0);
3420 static void bemit_fpushcopy(const ir_node *node)
3422 bemit_fop_reg(node, 0xD9, 0xC0);
3425 static void bemit_fst(const ir_node *node)
3427 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3429 bemit8(0xD9); // fsts
3433 bemit8(0xDD); // fstl
3437 panic("invalid mode size");
3439 bemit_mod_am(2, node);
3442 static void bemit_fstp(const ir_node *node)
3444 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3446 bemit8(0xD9); // fstps
3447 bemit_mod_am(3, node);
3451 bemit8(0xDD); // fstpl
3452 bemit_mod_am(3, node);
3457 bemit8(0xDB); // fstpt
3458 bemit_mod_am(7, node);
3462 panic("invalid mode size");
3466 static void bemit_fsub(const ir_node *node)
3468 bemit_fbinop(node, 4, 5);
3471 static void bemit_fsubp(const ir_node *node)
3473 bemit_fbinopp(node, 0xE8);
3476 static void bemit_fsubr(const ir_node *node)
3478 bemit_fbinop(node, 5, 4);
3481 static void bemit_fsubrp(const ir_node *node)
3483 bemit_fbinopp(node, 0xE0);
3486 static void bemit_fnstcw(const ir_node *node)
3488 bemit8(0xD9); // fnstcw
3489 bemit_mod_am(7, node);
3492 static void bemit_fnstsw(void)
3494 bemit8(0xDF); // fnstsw %ax
3498 static void bemit_ftstfnstsw(const ir_node *node)
3502 bemit8(0xD9); // ftst
3507 static void bemit_fucomi(const ir_node *node)
3509 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3510 bemit8(0xDB); // fucomi
3511 bemit8(0xE8 + attr->x87[1]->index);
3514 static void bemit_fucomip(const ir_node *node)
3516 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3517 bemit8(0xDF); // fucomip
3518 bemit8(0xE8 + attr->x87[1]->index);
3521 static void bemit_fucomfnstsw(const ir_node *node)
3523 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3524 bemit8(0xDD); // fucom
3525 bemit8(0xE0 + attr->x87[1]->index);
3529 static void bemit_fucompfnstsw(const ir_node *node)
3531 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3532 bemit8(0xDD); // fucomp
3533 bemit8(0xE8 + attr->x87[1]->index);
3537 static void bemit_fucomppfnstsw(const ir_node *node)
3541 bemit8(0xDA); // fucompp
3546 static void bemit_fxch(const ir_node *node)
3548 bemit_fop_reg(node, 0xD9, 0xC8);
3552 * The type of a emitter function.
3554 typedef void (*emit_func) (const ir_node *);
3557 * Set a node emitter. Make it a bit more type safe.
3559 static void register_emitter(ir_op *op, emit_func func)
3561 op->ops.generic = (op_func) func;
3564 static void ia32_register_binary_emitters(void)
3566 /* first clear the generic function pointer for all ops */
3567 ir_clear_opcodes_generic_func();
3569 /* benode emitter */
3570 register_emitter(op_be_Copy, bemit_copy);
3571 register_emitter(op_be_CopyKeep, bemit_copy);
3572 register_emitter(op_be_IncSP, bemit_incsp);
3573 register_emitter(op_be_Perm, bemit_perm);
3574 register_emitter(op_be_Return, bemit_return);
3575 register_emitter(op_ia32_Adc, bemit_adc);
3576 register_emitter(op_ia32_Add, bemit_add);
3577 register_emitter(op_ia32_AddMem, bemit_addmem);
3578 register_emitter(op_ia32_AddMem8Bit, bemit_addmem8bit);
3579 register_emitter(op_ia32_And, bemit_and);
3580 register_emitter(op_ia32_AndMem, bemit_andmem);
3581 register_emitter(op_ia32_AndMem8Bit, bemit_andmem8bit);
3582 register_emitter(op_ia32_Breakpoint, bemit_int3);
3583 register_emitter(op_ia32_Bsf, bemit_bsf);
3584 register_emitter(op_ia32_Bsr, bemit_bsr);
3585 register_emitter(op_ia32_CMovcc, bemit_cmovcc);
3586 register_emitter(op_ia32_Call, bemit_call);
3587 register_emitter(op_ia32_Cltd, bemit_cltd);
3588 register_emitter(op_ia32_Cmc, bemit_cmc);
3589 register_emitter(op_ia32_Cmp, bemit_cmp);
3590 register_emitter(op_ia32_Cmp8Bit, bemit_cmp8bit);
3591 register_emitter(op_ia32_Const, bemit_mov_const);
3592 register_emitter(op_ia32_Conv_I2I, bemit_conv_i2i);
3593 register_emitter(op_ia32_Conv_I2I8Bit, bemit_conv_i2i);
3594 register_emitter(op_ia32_CopyB_i, bemit_copybi);
3595 register_emitter(op_ia32_Cwtl, bemit_cwtl);
3596 register_emitter(op_ia32_Dec, bemit_dec);
3597 register_emitter(op_ia32_DecMem, bemit_decmem);
3598 register_emitter(op_ia32_Div, bemit_div);
3599 register_emitter(op_ia32_FldCW, bemit_fldcw);
3600 register_emitter(op_ia32_FnstCW, bemit_fnstcw);
3601 register_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw);
3602 register_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw);
3603 register_emitter(op_ia32_Fucomi, bemit_fucomi);
3604 register_emitter(op_ia32_FucompFnstsw, bemit_fucompfnstsw);
3605 register_emitter(op_ia32_Fucompi, bemit_fucomip);
3606 register_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw);
3607 register_emitter(op_ia32_IDiv, bemit_idiv);
3608 register_emitter(op_ia32_IJmp, bemit_ijmp);
3609 register_emitter(op_ia32_IMul, bemit_imul);
3610 register_emitter(op_ia32_IMul1OP, bemit_imul1op);
3611 register_emitter(op_ia32_Inc, bemit_inc);
3612 register_emitter(op_ia32_IncMem, bemit_incmem);
3613 register_emitter(op_ia32_Jcc, bemit_ia32_jcc);
3614 register_emitter(op_ia32_Jmp, bemit_jump);
3615 register_emitter(op_ia32_LdTls, bemit_ldtls);
3616 register_emitter(op_ia32_Lea, bemit_lea);
3617 register_emitter(op_ia32_Leave, bemit_leave);
3618 register_emitter(op_ia32_Load, bemit_load);
3619 register_emitter(op_ia32_Minus64Bit, bemit_minus64bit);
3620 register_emitter(op_ia32_Mul, bemit_mul);
3621 register_emitter(op_ia32_Neg, bemit_neg);
3622 register_emitter(op_ia32_NegMem, bemit_negmem);
3623 register_emitter(op_ia32_Not, bemit_not);
3624 register_emitter(op_ia32_NotMem, bemit_notmem);
3625 register_emitter(op_ia32_Or, bemit_or);
3626 register_emitter(op_ia32_OrMem, bemit_ormem);
3627 register_emitter(op_ia32_OrMem8Bit, bemit_ormem8bit);
3628 register_emitter(op_ia32_Pop, bemit_pop);
3629 register_emitter(op_ia32_PopEbp, bemit_pop);
3630 register_emitter(op_ia32_PopMem, bemit_popmem);
3631 register_emitter(op_ia32_Push, bemit_push);
3632 register_emitter(op_ia32_RepPrefix, bemit_rep);
3633 register_emitter(op_ia32_Rol, bemit_rol);
3634 register_emitter(op_ia32_RolMem, bemit_rolmem);
3635 register_emitter(op_ia32_Ror, bemit_ror);
3636 register_emitter(op_ia32_RorMem, bemit_rormem);
3637 register_emitter(op_ia32_Sahf, bemit_sahf);
3638 register_emitter(op_ia32_Sar, bemit_sar);
3639 register_emitter(op_ia32_SarMem, bemit_sarmem);
3640 register_emitter(op_ia32_Sbb, bemit_sbb);
3641 register_emitter(op_ia32_Setcc, bemit_setcc);
3642 register_emitter(op_ia32_Shl, bemit_shl);
3643 register_emitter(op_ia32_ShlD, bemit_shld);
3644 register_emitter(op_ia32_ShlMem, bemit_shlmem);
3645 register_emitter(op_ia32_Shr, bemit_shr);
3646 register_emitter(op_ia32_ShrD, bemit_shrd);
3647 register_emitter(op_ia32_ShrMem, bemit_shrmem);
3648 register_emitter(op_ia32_Stc, bemit_stc);
3649 register_emitter(op_ia32_Store, bemit_store);
3650 register_emitter(op_ia32_Store8Bit, bemit_store);
3651 register_emitter(op_ia32_Sub, bemit_sub);
3652 register_emitter(op_ia32_SubMem, bemit_submem);
3653 register_emitter(op_ia32_SubMem8Bit, bemit_submem8bit);
3654 register_emitter(op_ia32_SubSP, bemit_subsp);
3655 register_emitter(op_ia32_SwitchJmp, bemit_switchjmp);
3656 register_emitter(op_ia32_Test, bemit_test);
3657 register_emitter(op_ia32_Test8Bit, bemit_test8bit);
3658 register_emitter(op_ia32_Xor, bemit_xor);
3659 register_emitter(op_ia32_Xor0, bemit_xor0);
3660 register_emitter(op_ia32_XorMem, bemit_xormem);
3661 register_emitter(op_ia32_XorMem8Bit, bemit_xormem8bit);
3662 register_emitter(op_ia32_fabs, bemit_fabs);
3663 register_emitter(op_ia32_fadd, bemit_fadd);
3664 register_emitter(op_ia32_faddp, bemit_faddp);
3665 register_emitter(op_ia32_fchs, bemit_fchs);
3666 register_emitter(op_ia32_fdiv, bemit_fdiv);
3667 register_emitter(op_ia32_fdivp, bemit_fdivp);
3668 register_emitter(op_ia32_fdivr, bemit_fdivr);
3669 register_emitter(op_ia32_fdivrp, bemit_fdivrp);
3670 register_emitter(op_ia32_fild, bemit_fild);
3671 register_emitter(op_ia32_fist, bemit_fist);
3672 register_emitter(op_ia32_fistp, bemit_fistp);
3673 register_emitter(op_ia32_fld, bemit_fld);
3674 register_emitter(op_ia32_fld1, bemit_fld1);
3675 register_emitter(op_ia32_fldz, bemit_fldz);
3676 register_emitter(op_ia32_fmul, bemit_fmul);
3677 register_emitter(op_ia32_fmulp, bemit_fmulp);
3678 register_emitter(op_ia32_fpop, bemit_fpop);
3679 register_emitter(op_ia32_fpush, bemit_fpush);
3680 register_emitter(op_ia32_fpushCopy, bemit_fpushcopy);
3681 register_emitter(op_ia32_fst, bemit_fst);
3682 register_emitter(op_ia32_fstp, bemit_fstp);
3683 register_emitter(op_ia32_fsub, bemit_fsub);
3684 register_emitter(op_ia32_fsubp, bemit_fsubp);
3685 register_emitter(op_ia32_fsubr, bemit_fsubr);
3686 register_emitter(op_ia32_fsubrp, bemit_fsubrp);
3687 register_emitter(op_ia32_fxch, bemit_fxch);
3689 /* ignore the following nodes */
3690 register_emitter(op_ia32_ProduceVal, emit_Nothing);
3691 register_emitter(op_ia32_Unknown, emit_Nothing);
3692 register_emitter(op_be_Keep, emit_Nothing);
3693 register_emitter(op_be_Start, emit_Nothing);
3694 register_emitter(op_Phi, emit_Nothing);
3695 register_emitter(op_Start, emit_Nothing);
3698 static void gen_binary_block(ir_node *block)
3700 ia32_emit_block_header(block);
3702 /* emit the contents of the block */
3703 sched_foreach(block, node) {
3704 ia32_emit_node(node);
3708 void ia32_gen_binary_routine(ir_graph *irg)
3710 ir_entity *entity = get_irg_entity(irg);
3711 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
3712 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
3713 ir_node **blk_sched = irg_data->blk_sched;
3715 parameter_dbg_info_t *infos;
3717 isa = (ia32_isa_t*) arch_env;
3719 ia32_register_binary_emitters();
3721 infos = construct_parameter_infos(irg);
3722 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
3726 /* we use links to point to target blocks */
3727 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
3728 irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
3730 /* initialize next block links */
3731 n = ARR_LEN(blk_sched);
3732 for (i = 0; i < n; ++i) {
3733 ir_node *block = blk_sched[i];
3734 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
3736 set_irn_link(block, prev);
3739 for (i = 0; i < n; ++i) {
3740 ir_node *block = blk_sched[i];
3741 gen_binary_block(block);
3744 be_gas_emit_function_epilog(entity);
3746 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
3750 void ia32_init_emitter(void)
3752 lc_opt_entry_t *be_grp;
3753 lc_opt_entry_t *ia32_grp;
3755 be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
3756 ia32_grp = lc_opt_get_grp(be_grp, "ia32");
3758 lc_opt_add_table(ia32_grp, ia32_emitter_options);
3762 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");