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
26 * Summary table for x86 floatingpoint compares:
27 * (remember effect of unordered on x86: ZF=1, PF=1, CF=1)
35 * pnc_Leg => NP (ordered)
57 #include "iredges_t.h"
61 #include "raw_bitset.h"
68 #include "be_dbgout.h"
69 #include "beemitter.h"
72 #include "be_dbgout.h"
74 #include "ia32_emitter.h"
75 #include "ia32_common_transform.h"
76 #include "gen_ia32_emitter.h"
77 #include "gen_ia32_regalloc_if.h"
78 #include "ia32_nodes_attr.h"
79 #include "ia32_new_nodes.h"
80 #include "ia32_architecture.h"
81 #include "bearch_ia32_t.h"
83 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
85 #define SNPRINTF_BUF_LEN 128
87 static const ia32_isa_t *isa;
88 static char pic_base_label[128];
89 static ir_label_t exc_label_id;
90 static int mark_spill_reload = 0;
93 /** Return the next block in Block schedule */
94 static ir_node *get_prev_block_sched(const ir_node *block)
96 return (ir_node*)get_irn_link(block);
99 /** Checks if the current block is a fall-through target. */
100 static int is_fallthrough(const ir_node *cfgpred)
104 if (!is_Proj(cfgpred))
106 pred = get_Proj_pred(cfgpred);
107 if (is_ia32_SwitchJmp(pred))
114 * returns non-zero if the given block needs a label
115 * because of being a jump-target (and not a fall-through)
117 static int block_needs_label(const ir_node *block)
120 int n_cfgpreds = get_Block_n_cfgpreds(block);
122 if (has_Block_entity(block))
125 if (n_cfgpreds == 0) {
127 } else if (n_cfgpreds == 1) {
128 ir_node *cfgpred = get_Block_cfgpred(block, 0);
129 ir_node *cfgpred_block = get_nodes_block(cfgpred);
131 if (get_prev_block_sched(block) == cfgpred_block
132 && is_fallthrough(cfgpred)) {
141 * Add a number to a prefix. This number will not be used a second time.
143 static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
145 static unsigned long id = 0;
146 snprintf(buf, buflen, "%s%s%lu", be_gas_get_private_prefix(), prefix, ++id);
151 * Emit the name of the 8bit low register
153 static void emit_8bit_register(const arch_register_t *reg)
155 const char *reg_name = arch_register_get_name(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 const char *reg_name = arch_register_get_name(reg);
170 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
171 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
174 be_emit_char(reg_name[1]); /* get the basic name of the register */
178 static void emit_16bit_register(const arch_register_t *reg)
180 const char *reg_name = arch_register_get_name(reg);
183 be_emit_string(reg_name+1); /* skip the 'e' prefix of the 32bit names */
187 * emit a register, possible shortened by a mode
189 * @param reg the register
190 * @param mode the mode of the register or NULL for full register
192 static void emit_register(const arch_register_t *reg, const ir_mode *mode)
194 const char *reg_name;
197 int size = get_mode_size_bits(mode);
199 case 8: emit_8bit_register(reg); return;
200 case 16: emit_16bit_register(reg); return;
202 assert(mode_is_float(mode) || size == 32);
205 reg_name = arch_register_get_name(reg);
208 be_emit_string(reg_name);
211 void ia32_emit_source_register(const ir_node *node, int pos)
213 const arch_register_t *reg = arch_get_irn_register_in(node, pos);
215 emit_register(reg, NULL);
218 static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
220 be_gas_emit_entity(entity);
222 if (get_entity_owner(entity) == get_tls_type()) {
223 if (get_entity_visibility(entity) == ir_visibility_external) {
224 be_emit_cstring("@INDNTPOFF");
226 be_emit_cstring("@NTPOFF");
230 if (do_pic && !no_pic_adjust) {
232 be_emit_string(pic_base_label);
236 static void emit_ia32_Immediate_no_prefix(const ir_node *node)
238 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
240 if (attr->symconst != NULL) {
243 ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
245 if (attr->symconst == NULL || attr->offset != 0) {
246 if (attr->symconst != NULL) {
247 be_emit_irprintf("%+d", attr->offset);
249 be_emit_irprintf("0x%X", attr->offset);
254 static void emit_ia32_Immediate(const ir_node *node)
257 emit_ia32_Immediate_no_prefix(node);
260 void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos)
262 const arch_register_t *reg;
263 const ir_node *in = get_irn_n(node, pos);
264 if (is_ia32_Immediate(in)) {
265 emit_ia32_Immediate(in);
269 reg = arch_get_irn_register_in(node, pos);
270 emit_8bit_register(reg);
273 void ia32_emit_8bit_high_source_register(const ir_node *node, int pos)
275 const arch_register_t *reg = arch_get_irn_register_in(node, pos);
276 emit_8bit_register_high(reg);
279 void ia32_emit_16bit_source_register_or_immediate(const ir_node *node, int pos)
281 const arch_register_t *reg;
282 const ir_node *in = get_irn_n(node, pos);
283 if (is_ia32_Immediate(in)) {
284 emit_ia32_Immediate(in);
288 reg = arch_get_irn_register_in(node, pos);
289 emit_16bit_register(reg);
292 void ia32_emit_dest_register(const ir_node *node, int pos)
294 const arch_register_t *reg = arch_get_irn_register_out(node, pos);
296 emit_register(reg, NULL);
299 void ia32_emit_dest_register_size(const ir_node *node, int pos)
301 const arch_register_t *reg = arch_get_irn_register_out(node, pos);
303 emit_register(reg, get_ia32_ls_mode(node));
306 void ia32_emit_8bit_dest_register(const ir_node *node, int pos)
308 const arch_register_t *reg = arch_get_irn_register_out(node, pos);
310 emit_register(reg, mode_Bu);
313 void ia32_emit_x87_register(const ir_node *node, int pos)
315 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
319 be_emit_string(attr->x87[pos]->name);
322 static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
324 assert(mode_is_int(mode) || mode_is_reference(mode));
325 switch (get_mode_size_bits(mode)) {
326 case 8: be_emit_char('b'); return;
327 case 16: be_emit_char('w'); return;
328 case 32: be_emit_char('l'); return;
329 /* gas docu says q is the suffix but gcc, objdump and icc use ll
331 case 64: be_emit_cstring("ll"); return;
333 panic("Can't output mode_suffix for %+F", mode);
336 void ia32_emit_mode_suffix(const ir_node *node)
338 ir_mode *mode = get_ia32_ls_mode(node);
342 ia32_emit_mode_suffix_mode(mode);
345 void ia32_emit_x87_mode_suffix(const ir_node *node)
349 /* we only need to emit the mode on address mode */
350 if (get_ia32_op_type(node) == ia32_Normal)
353 mode = get_ia32_ls_mode(node);
354 assert(mode != NULL);
356 if (mode_is_float(mode)) {
357 switch (get_mode_size_bits(mode)) {
358 case 32: be_emit_char('s'); return;
359 case 64: be_emit_char('l'); return;
360 /* long doubles have different sizes due to alignment on different
364 case 128: be_emit_char('t'); return;
367 assert(mode_is_int(mode) || mode_is_reference(mode));
368 switch (get_mode_size_bits(mode)) {
369 case 16: be_emit_char('s'); return;
370 case 32: be_emit_char('l'); return;
371 /* gas docu says q is the suffix but gcc, objdump and icc use ll
373 case 64: be_emit_cstring("ll"); return;
376 panic("Can't output mode_suffix for %+F", mode);
379 static char get_xmm_mode_suffix(ir_mode *mode)
381 assert(mode_is_float(mode));
382 switch (get_mode_size_bits(mode)) {
385 default: panic("Invalid XMM mode");
389 void ia32_emit_xmm_mode_suffix(const ir_node *node)
391 ir_mode *mode = get_ia32_ls_mode(node);
392 assert(mode != NULL);
394 be_emit_char(get_xmm_mode_suffix(mode));
397 void ia32_emit_xmm_mode_suffix_s(const ir_node *node)
399 ir_mode *mode = get_ia32_ls_mode(node);
400 assert(mode != NULL);
401 be_emit_char(get_xmm_mode_suffix(mode));
404 void ia32_emit_extend_suffix(const ir_node *node)
406 ir_mode *mode = get_ia32_ls_mode(node);
407 if (get_mode_size_bits(mode) == 32)
409 be_emit_char(mode_is_signed(mode) ? 's' : 'z');
410 ia32_emit_mode_suffix_mode(mode);
413 void ia32_emit_source_register_or_immediate(const ir_node *node, int pos)
415 ir_node *in = get_irn_n(node, pos);
416 if (is_ia32_Immediate(in)) {
417 emit_ia32_Immediate(in);
419 const ir_mode *mode = get_ia32_ls_mode(node);
420 const arch_register_t *reg = arch_get_irn_register_in(node, pos);
421 emit_register(reg, mode);
426 * Returns the target block for a control flow node.
428 static ir_node *get_cfop_target_block(const ir_node *irn)
430 assert(get_irn_mode(irn) == mode_X);
431 return (ir_node*)get_irn_link(irn);
435 * Emits the target label for a control flow node.
437 static void ia32_emit_cfop_target(const ir_node *node)
439 ir_node *block = get_cfop_target_block(node);
440 be_gas_emit_block_name(block);
444 * Emit the suffix for a compare instruction.
446 static void ia32_emit_condition_code(ia32_condition_code_t cc)
449 case ia32_cc_overflow: be_emit_cstring("o"); return;
450 case ia32_cc_not_overflow: be_emit_cstring("no"); return;
451 case ia32_cc_float_below:
452 case ia32_cc_float_unordered_below:
453 case ia32_cc_below: be_emit_cstring("b"); return;
454 case ia32_cc_float_above_equal:
455 case ia32_cc_float_unordered_above_equal:
456 case ia32_cc_above_equal: be_emit_cstring("ae"); return;
457 case ia32_cc_float_equal:
458 case ia32_cc_equal: be_emit_cstring("e"); return;
459 case ia32_cc_float_not_equal:
460 case ia32_cc_not_equal: be_emit_cstring("ne"); return;
461 case ia32_cc_float_below_equal:
462 case ia32_cc_float_unordered_below_equal:
463 case ia32_cc_below_equal: be_emit_cstring("be"); return;
464 case ia32_cc_float_above:
465 case ia32_cc_float_unordered_above:
466 case ia32_cc_above: be_emit_cstring("a"); return;
467 case ia32_cc_sign: be_emit_cstring("s"); return;
468 case ia32_cc_not_sign: be_emit_cstring("ns"); return;
469 case ia32_cc_parity: be_emit_cstring("p"); return;
470 case ia32_cc_not_parity: be_emit_cstring("np"); return;
471 case ia32_cc_less: be_emit_cstring("l"); return;
472 case ia32_cc_greater_equal: be_emit_cstring("ge"); return;
473 case ia32_cc_less_equal: be_emit_cstring("le"); return;
474 case ia32_cc_greater: be_emit_cstring("g"); return;
475 case ia32_cc_float_parity_cases:
476 case ia32_cc_additional_float_cases:
479 panic("Invalid ia32 condition code");
482 typedef enum ia32_emit_mod_t {
484 EMIT_RESPECT_LS = 1U << 0,
485 EMIT_ALTERNATE_AM = 1U << 1,
487 EMIT_HIGH_REG = 1U << 3,
488 EMIT_LOW_REG = 1U << 4
490 ENUM_BITSET(ia32_emit_mod_t)
493 * Emits address mode.
495 void ia32_emit_am(const ir_node *node)
497 ir_entity *ent = get_ia32_am_sc(node);
498 int offs = get_ia32_am_offs_int(node);
499 ir_node *base = get_irn_n(node, n_ia32_base);
500 int has_base = !is_ia32_NoReg_GP(base);
501 ir_node *idx = get_irn_n(node, n_ia32_index);
502 int has_index = !is_ia32_NoReg_GP(idx);
504 /* just to be sure... */
505 assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
507 if (get_ia32_am_tls_segment(node))
508 be_emit_cstring("%gs:");
512 const ia32_attr_t *attr = get_ia32_attr_const(node);
513 if (is_ia32_am_sc_sign(node))
515 ia32_emit_entity(ent, attr->data.am_sc_no_pic_adjust);
518 /* also handle special case if nothing is set */
519 if (offs != 0 || (ent == NULL && !has_base && !has_index)) {
521 be_emit_irprintf("%+d", offs);
523 be_emit_irprintf("%d", offs);
527 if (has_base || has_index) {
532 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
533 emit_register(reg, NULL);
536 /* emit index + scale */
538 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
541 emit_register(reg, NULL);
543 scale = get_ia32_am_scale(node);
545 be_emit_irprintf(",%d", 1 << scale);
553 * fmt parameter output
554 * ---- ---------------------- ---------------------------------------------
556 * %AM <node> address mode of the node
557 * %AR const arch_register_t* address mode of the node or register
558 * %ASx <node> address mode of the node or source register x
559 * %Dx <node> destination register x
560 * %I <node> immediate of the node
561 * %L <node> control flow target of the node
562 * %M <node> mode suffix of the node
563 * %P int condition code
564 * %R const arch_register_t* register
565 * %Sx <node> source register x
566 * %s const char* string
567 * %u unsigned int unsigned int
568 * %d signed int signed int
571 * # modifier for %ASx, %D, %R, and %S uses ls mode of node to alter register width
572 * * modifier does not prefix immediates with $, but AM with *
573 * l modifier for %lu and %ld
574 * > modifier to output high 8bit register (ah, bh)
575 * < modifier to output low 8bit register (al, bl)
577 static void ia32_emitf(const ir_node *node, const char *fmt, ...)
583 const char *start = fmt;
584 ia32_emit_mod_t mod = EMIT_NONE;
586 while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
589 be_emit_string_len(start, fmt - start);
593 be_emit_finish_line_gas(node);
606 case '*': mod |= EMIT_ALTERNATE_AM; break;
607 case '#': mod |= EMIT_RESPECT_LS; break;
608 case 'l': mod |= EMIT_LONG; break;
609 case '>': mod |= EMIT_HIGH_REG; break;
610 case '<': mod |= EMIT_LOW_REG; break;
619 arch_register_t const *reg;
630 if (mod & EMIT_ALTERNATE_AM)
636 reg = va_arg(ap, const arch_register_t*);
637 if (get_ia32_op_type(node) == ia32_AddrModeS) {
644 if (get_ia32_op_type(node) == ia32_AddrModeS) {
648 assert(get_ia32_op_type(node) == ia32_Normal);
652 default: goto unknown;
658 if (*fmt < '0' || '9' <= *fmt)
660 reg = arch_get_irn_register_out(node, *fmt++ - '0');
666 if (!(mod & EMIT_ALTERNATE_AM))
668 emit_ia32_Immediate_no_prefix(imm);
672 ia32_emit_cfop_target(node);
676 ia32_emit_mode_suffix_mode(get_ia32_ls_mode(node));
680 ia32_condition_code_t cc = va_arg(ap, ia32_condition_code_t);
681 ia32_emit_condition_code(cc);
686 reg = va_arg(ap, const arch_register_t*);
688 if (mod & EMIT_ALTERNATE_AM)
690 if (mod & EMIT_HIGH_REG) {
691 emit_8bit_register_high(reg);
692 } else if (mod & EMIT_LOW_REG) {
693 emit_8bit_register(reg);
695 emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
703 if (*fmt < '0' || '9' <= *fmt)
707 imm = get_irn_n(node, pos);
708 if (is_ia32_Immediate(imm)) {
711 reg = arch_get_irn_register_in(node, pos);
717 const char *str = va_arg(ap, const char*);
723 if (mod & EMIT_LONG) {
724 unsigned long num = va_arg(ap, unsigned long);
725 be_emit_irprintf("%lu", num);
727 unsigned num = va_arg(ap, unsigned);
728 be_emit_irprintf("%u", num);
733 if (mod & EMIT_LONG) {
734 long num = va_arg(ap, long);
735 be_emit_irprintf("%ld", num);
737 int num = va_arg(ap, int);
738 be_emit_irprintf("%d", num);
744 panic("unknown format conversion in ia32_emitf()");
752 * Emits registers and/or address mode of a binary operation.
754 void ia32_emit_binop(const ir_node *node)
756 if (is_ia32_Immediate(get_irn_n(node, n_ia32_binary_right))) {
757 ia32_emitf(node, "%#S4, %#AS3");
759 ia32_emitf(node, "%#AS4, %#S3");
764 * Emits registers and/or address mode of a binary operation.
766 void ia32_emit_x87_binop(const ir_node *node)
768 switch (get_ia32_op_type(node)) {
771 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
772 const arch_register_t *in1 = x87_attr->x87[0];
773 const arch_register_t *in = x87_attr->x87[1];
774 const arch_register_t *out = x87_attr->x87[2];
778 } else if (out == in) {
783 be_emit_string(arch_register_get_name(in));
784 be_emit_cstring(", %");
785 be_emit_string(arch_register_get_name(out));
793 assert(0 && "unsupported op type");
798 * Emits registers and/or address mode of a unary operation.
800 void ia32_emit_unop(const ir_node *node, int pos)
804 ia32_emitf(node, fmt);
807 static void emit_ia32_IMul(const ir_node *node)
809 ir_node *left = get_irn_n(node, n_ia32_IMul_left);
810 const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
812 /* do we need the 3-address form? */
813 if (is_ia32_NoReg_GP(left) ||
814 arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
815 ia32_emitf(node, "\timul%M %#S4, %#AS3, %#D0\n");
817 ia32_emitf(node, "\timul%M %#AS4, %#S3\n");
822 * walks up a tree of copies/perms/spills/reloads to find the original value
823 * that is moved around
825 static ir_node *find_original_value(ir_node *node)
827 if (irn_visited(node))
830 mark_irn_visited(node);
831 if (be_is_Copy(node)) {
832 return find_original_value(be_get_Copy_op(node));
833 } else if (be_is_CopyKeep(node)) {
834 return find_original_value(be_get_CopyKeep_op(node));
835 } else if (is_Proj(node)) {
836 ir_node *pred = get_Proj_pred(node);
837 if (be_is_Perm(pred)) {
838 return find_original_value(get_irn_n(pred, get_Proj_proj(node)));
839 } else if (be_is_MemPerm(pred)) {
840 return find_original_value(get_irn_n(pred, get_Proj_proj(node) + 1));
841 } else if (is_ia32_Load(pred)) {
842 return find_original_value(get_irn_n(pred, n_ia32_Load_mem));
843 } else if (is_ia32_Store(pred)) {
844 return find_original_value(get_irn_n(pred, n_ia32_Store_val));
848 } else if (is_Phi(node)) {
850 arity = get_irn_arity(node);
851 for (i = 0; i < arity; ++i) {
852 ir_node *in = get_irn_n(node, i);
853 ir_node *res = find_original_value(in);
864 static int determine_final_cc(const ir_node *node, int flags_pos, int cc)
866 ir_node *flags = get_irn_n(node, flags_pos);
867 const ia32_attr_t *flags_attr;
868 flags = skip_Proj(flags);
870 if (is_ia32_Sahf(flags)) {
871 ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
872 if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
873 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
874 inc_irg_visited(current_ir_graph);
875 cmp = find_original_value(cmp);
877 assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
878 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
881 flags_attr = get_ia32_attr_const(cmp);
883 flags_attr = get_ia32_attr_const(flags);
886 if (flags_attr->data.ins_permuted)
887 cc = ia32_invert_condition_code(cc);
891 void ia32_emit_cmp_suffix_node(const ir_node *node, int flags_pos)
893 ia32_condition_code_t cc = get_ia32_condcode(node);
894 cc = determine_final_cc(node, flags_pos, cc);
896 ia32_emit_condition_code(cc);
900 * Emits an exception label for a given node.
902 static void ia32_emit_exc_label(const ir_node *node)
904 be_emit_string(be_gas_insn_label_prefix());
905 be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
909 * Returns the Proj with projection number proj and NOT mode_M
911 static ir_node *get_proj(const ir_node *node, long proj)
913 const ir_edge_t *edge;
916 assert(get_irn_mode(node) == mode_T && "expected mode_T node");
918 foreach_out_edge(node, edge) {
919 src = get_edge_src_irn(edge);
921 assert(is_Proj(src) && "Proj expected");
922 if (get_irn_mode(src) == mode_M)
925 if (get_Proj_proj(src) == proj)
931 static int can_be_fallthrough(const ir_node *node)
933 ir_node *target_block = get_cfop_target_block(node);
934 ir_node *block = get_nodes_block(node);
935 return get_prev_block_sched(target_block) == block;
939 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
941 static void emit_ia32_Jcc(const ir_node *node)
943 int need_parity_label = 0;
944 ia32_condition_code_t cc = get_ia32_condcode(node);
945 const ir_node *proj_true;
946 const ir_node *proj_false;
948 cc = determine_final_cc(node, 0, cc);
951 proj_true = get_proj(node, pn_ia32_Jcc_true);
952 assert(proj_true && "Jcc without true Proj");
954 proj_false = get_proj(node, pn_ia32_Jcc_false);
955 assert(proj_false && "Jcc without false Proj");
957 if (can_be_fallthrough(proj_true)) {
958 /* exchange both proj's so the second one can be omitted */
959 const ir_node *t = proj_true;
961 proj_true = proj_false;
963 cc = ia32_negate_condition_code(cc);
966 if (cc & ia32_cc_float_parity_cases) {
967 /* Some floating point comparisons require a test of the parity flag,
968 * which indicates that the result is unordered */
969 if (cc & ia32_cc_negated) {
970 ia32_emitf(proj_true, "\tjp %L\n");
972 /* we need a local label if the false proj is a fallthrough
973 * as the falseblock might have no label emitted then */
974 if (can_be_fallthrough(proj_false)) {
975 need_parity_label = 1;
976 ia32_emitf(proj_false, "\tjp 1f\n");
978 ia32_emitf(proj_false, "\tjp %L\n");
982 ia32_emitf(proj_true, "\tj%P %L\n", cc);
983 if (need_parity_label) {
984 ia32_emitf(NULL, "1:\n");
987 /* the second Proj might be a fallthrough */
988 if (can_be_fallthrough(proj_false)) {
989 ia32_emitf(proj_false, "\t/* fallthrough to %L */\n");
991 ia32_emitf(proj_false, "\tjmp %L\n");
996 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
999 static void emit_ia32_Setcc(const ir_node *node)
1001 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
1003 ia32_condition_code_t cc = get_ia32_condcode(node);
1004 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
1005 if (cc & ia32_cc_float_parity_cases) {
1006 if (cc & ia32_cc_negated) {
1007 ia32_emitf(node, "\tset%P %<R\n", cc, dreg);
1008 ia32_emitf(node, "\tsetp %>R\n", dreg);
1009 ia32_emitf(node, "\torb %>R, %<R\n", dreg, dreg);
1011 ia32_emitf(node, "\tset%P %<R\n", cc, dreg);
1012 ia32_emitf(node, "\tsetnp %>R\n", dreg);
1013 ia32_emitf(node, "\tandb %>R, %<R\n", dreg, dreg);
1016 ia32_emitf(node, "\tset%P %#R\n", cc, dreg);
1020 static void emit_ia32_CMovcc(const ir_node *node)
1022 const ia32_attr_t *attr = get_ia32_attr_const(node);
1023 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
1024 ia32_condition_code_t cc = get_ia32_condcode(node);
1025 const arch_register_t *in_true;
1026 const arch_register_t *in_false;
1028 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
1029 /* although you can't set ins_permuted in the constructor it might still
1030 * be set by memory operand folding
1031 * Permuting inputs of a cmov means the condition is negated!
1033 if (attr->data.ins_permuted)
1034 cc = ia32_negate_condition_code(cc);
1036 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
1037 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
1039 /* should be same constraint fullfilled? */
1040 if (out == in_false) {
1041 /* yes -> nothing to do */
1042 } else if (out == in_true) {
1043 const arch_register_t *tmp;
1045 assert(get_ia32_op_type(node) == ia32_Normal);
1047 cc = ia32_negate_condition_code(cc);
1054 ia32_emitf(node, "\tmovl %R, %R\n", in_false, out);
1057 if (cc & ia32_cc_float_parity_cases) {
1058 panic("CMov with floatingpoint compare/parity not supported yet");
1061 ia32_emitf(node, "\tcmov%P %#AR, %#R\n", cc, in_true, out);
1065 * Emits code for a SwitchJmp
1067 static void emit_ia32_SwitchJmp(const ir_node *node)
1069 ir_entity *jump_table = get_ia32_am_sc(node);
1070 long default_pn = get_ia32_default_pn(node);
1072 ia32_emitf(node, "\tjmp %*AM\n");
1073 emit_jump_table(node, default_pn, jump_table, get_cfop_target_block);
1077 * Emits code for a unconditional jump.
1079 static void emit_ia32_Jmp(const ir_node *node)
1081 /* we have a block schedule */
1082 if (can_be_fallthrough(node)) {
1083 ia32_emitf(node, "\t/* fallthrough to %L */\n");
1085 ia32_emitf(node, "\tjmp %L\n");
1090 * Emit an inline assembler operand.
1092 * @param node the ia32_ASM node
1093 * @param s points to the operand (a %c)
1095 * @return pointer to the first char in s NOT in the current operand
1097 static const char* emit_asm_operand(const ir_node *node, const char *s)
1099 const ia32_attr_t *ia32_attr = get_ia32_attr_const(node);
1100 const ia32_asm_attr_t *attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
1102 const arch_register_t *reg;
1103 const ia32_asm_reg_t *asm_regs = attr->register_map;
1104 const ia32_asm_reg_t *asm_reg;
1113 /* parse modifiers */
1116 ir_fprintf(stderr, "Warning: asm text (%+F) ends with %%\n", node);
1141 "Warning: asm text (%+F) contains unknown modifier '%c' for asm op\n",
1148 if (sscanf(s, "%d%n", &num, &p) != 1) {
1149 ir_fprintf(stderr, "Warning: Couldn't parse assembler operand (%+F)\n",
1156 if (num < 0 || ARR_LEN(asm_regs) <= (size_t)num) {
1158 "Error: Custom assembler references invalid input/output (%+F)\n",
1162 asm_reg = & asm_regs[num];
1163 assert(asm_reg->valid);
1166 if (asm_reg->use_input == 0) {
1167 reg = arch_get_irn_register_out(node, asm_reg->inout_pos);
1169 ir_node *pred = get_irn_n(node, asm_reg->inout_pos);
1171 /* might be an immediate value */
1172 if (is_ia32_Immediate(pred)) {
1173 emit_ia32_Immediate(pred);
1176 reg = arch_get_irn_register_in(node, asm_reg->inout_pos);
1180 "Warning: no register assigned for %d asm op (%+F)\n",
1185 if (asm_reg->memory) {
1190 if (modifier != 0) {
1193 emit_8bit_register(reg);
1196 emit_8bit_register_high(reg);
1199 emit_16bit_register(reg);
1202 panic("Invalid asm op modifier");
1205 emit_register(reg, asm_reg->mode);
1208 if (asm_reg->memory) {
1216 * Emits code for an ASM pseudo op.
1218 static void emit_ia32_Asm(const ir_node *node)
1220 const void *gen_attr = get_irn_generic_attr_const(node);
1221 const ia32_asm_attr_t *attr
1222 = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, gen_attr);
1223 ident *asm_text = attr->asm_text;
1224 const char *s = get_id_str(asm_text);
1226 ia32_emitf(node, "#APP\t\n");
1233 s = emit_asm_operand(node, s);
1239 ia32_emitf(NULL, "\n#NO_APP\n");
1244 * Emit movsb/w instructions to make mov count divideable by 4
1246 static void emit_CopyB_prolog(unsigned size)
1249 ia32_emitf(NULL, "\tmovsb\n");
1251 ia32_emitf(NULL, "\tmovsw\n");
1255 * Emit rep movsd instruction for memcopy.
1257 static void emit_ia32_CopyB(const ir_node *node)
1259 unsigned size = get_ia32_copyb_size(node);
1261 emit_CopyB_prolog(size);
1262 ia32_emitf(node, "\trep movsd\n");
1266 * Emits unrolled memcopy.
1268 static void emit_ia32_CopyB_i(const ir_node *node)
1270 unsigned size = get_ia32_copyb_size(node);
1272 emit_CopyB_prolog(size);
1276 ia32_emitf(NULL, "\tmovsd\n");
1282 * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1284 static void emit_ia32_Conv_with_FP(const ir_node *node, const char* conv_f,
1287 ir_mode *ls_mode = get_ia32_ls_mode(node);
1288 int ls_bits = get_mode_size_bits(ls_mode);
1289 const char *conv = ls_bits == 32 ? conv_f : conv_d;
1291 ia32_emitf(node, "\tcvt%s %AS3, %D0\n", conv);
1294 static void emit_ia32_Conv_I2FP(const ir_node *node)
1296 emit_ia32_Conv_with_FP(node, "si2ss", "si2sd");
1299 static void emit_ia32_Conv_FP2I(const ir_node *node)
1301 emit_ia32_Conv_with_FP(node, "ss2si", "sd2si");
1304 static void emit_ia32_Conv_FP2FP(const ir_node *node)
1306 emit_ia32_Conv_with_FP(node, "sd2ss", "ss2sd");
1310 * Emits code for an Int conversion.
1312 static void emit_ia32_Conv_I2I(const ir_node *node)
1314 ir_mode *smaller_mode = get_ia32_ls_mode(node);
1315 int signed_mode = mode_is_signed(smaller_mode);
1316 const char *sign_suffix;
1318 assert(!mode_is_float(smaller_mode));
1320 sign_suffix = signed_mode ? "s" : "z";
1321 ia32_emitf(node, "\tmov%s%Ml %#AS3, %D0\n", sign_suffix);
1327 static void emit_ia32_Call(const ir_node *node)
1329 /* Special case: Call must not have its immediates prefixed by $, instead
1330 * address mode is prefixed by *. */
1331 ia32_emitf(node, "\tcall %*AS3\n");
1336 * Emits code to increase stack pointer.
1338 static void emit_be_IncSP(const ir_node *node)
1340 int offs = be_get_IncSP_offset(node);
1346 ia32_emitf(node, "\tsubl $%u, %D0\n", offs);
1348 ia32_emitf(node, "\taddl $%u, %D0\n", -offs);
1353 * Emits code for Copy/CopyKeep.
1355 static void Copy_emitter(const ir_node *node, const ir_node *op)
1357 const arch_register_t *in = arch_get_irn_register(op);
1358 const arch_register_t *out = arch_get_irn_register(node);
1363 /* copies of vf nodes aren't real... */
1364 if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
1367 if (get_irn_mode(node) == mode_E) {
1368 ia32_emitf(node, "\tmovsd %R, %R\n", in, out);
1370 ia32_emitf(node, "\tmovl %R, %R\n", in, out);
1374 static void emit_be_Copy(const ir_node *node)
1376 Copy_emitter(node, be_get_Copy_op(node));
1379 static void emit_be_CopyKeep(const ir_node *node)
1381 Copy_emitter(node, be_get_CopyKeep_op(node));
1385 * Emits code for exchange.
1387 static void emit_be_Perm(const ir_node *node)
1389 const arch_register_t *in0, *in1;
1390 const arch_register_class_t *cls0, *cls1;
1392 in0 = arch_get_irn_register(get_irn_n(node, 0));
1393 in1 = arch_get_irn_register(get_irn_n(node, 1));
1395 cls0 = arch_register_get_class(in0);
1396 cls1 = arch_register_get_class(in1);
1398 assert(cls0 == cls1 && "Register class mismatch at Perm");
1400 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
1401 ia32_emitf(node, "\txchg %R, %R\n", in1, in0);
1402 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1403 ia32_emitf(NULL, "\txorpd %R, %R\n", in1, in0);
1404 ia32_emitf(NULL, "\txorpd %R, %R\n", in0, in1);
1405 ia32_emitf(node, "\txorpd %R, %R\n", in1, in0);
1406 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
1408 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
1411 panic("unexpected register class in be_Perm (%+F)", node);
1416 * Emits code for Constant loading.
1418 static void emit_ia32_Const(const ir_node *node)
1420 ia32_emitf(node, "\tmovl %I, %D0\n");
1423 /* helper function for emit_ia32_Minus64Bit */
1424 static void emit_mov(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1426 ia32_emitf(node, "\tmovl %R, %R\n", src, dst);
1429 /* helper function for emit_ia32_Minus64Bit */
1430 static void emit_neg(const ir_node* node, const arch_register_t *reg)
1432 ia32_emitf(node, "\tnegl %R\n", reg);
1435 /* helper function for emit_ia32_Minus64Bit */
1436 static void emit_sbb0(const ir_node* node, const arch_register_t *reg)
1438 ia32_emitf(node, "\tsbbl $0, %R\n", reg);
1441 /* helper function for emit_ia32_Minus64Bit */
1442 static void emit_sbb(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1444 ia32_emitf(node, "\tsbbl %R, %R\n", src, dst);
1447 /* helper function for emit_ia32_Minus64Bit */
1448 static void emit_xchg(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1450 ia32_emitf(node, "\txchgl %R, %R\n", src, dst);
1453 /* helper function for emit_ia32_Minus64Bit */
1454 static void emit_zero(const ir_node* node, const arch_register_t *reg)
1456 ia32_emitf(node, "\txorl %R, %R\n", reg, reg);
1459 static void emit_ia32_Minus64Bit(const ir_node *node)
1461 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
1462 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
1463 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
1464 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
1466 if (out_lo == in_lo) {
1467 if (out_hi != in_hi) {
1468 /* a -> a, b -> d */
1471 /* a -> a, b -> b */
1474 } else if (out_lo == in_hi) {
1475 if (out_hi == in_lo) {
1476 /* a -> b, b -> a */
1477 emit_xchg(node, in_lo, in_hi);
1480 /* a -> b, b -> d */
1481 emit_mov(node, in_hi, out_hi);
1482 emit_mov(node, in_lo, out_lo);
1486 if (out_hi == in_lo) {
1487 /* a -> c, b -> a */
1488 emit_mov(node, in_lo, out_lo);
1490 } else if (out_hi == in_hi) {
1491 /* a -> c, b -> b */
1492 emit_mov(node, in_lo, out_lo);
1495 /* a -> c, b -> d */
1496 emit_mov(node, in_lo, out_lo);
1502 emit_neg( node, out_hi);
1503 emit_neg( node, out_lo);
1504 emit_sbb0(node, out_hi);
1508 emit_zero(node, out_hi);
1509 emit_neg( node, out_lo);
1510 emit_sbb( node, in_hi, out_hi);
1513 static void emit_ia32_GetEIP(const ir_node *node)
1515 ia32_emitf(node, "\tcall %s\n", pic_base_label);
1516 ia32_emitf(NULL, "%s:\n", pic_base_label);
1517 ia32_emitf(node, "\tpopl %D0\n");
1520 static void emit_ia32_ClimbFrame(const ir_node *node)
1522 const ia32_climbframe_attr_t *attr = get_ia32_climbframe_attr_const(node);
1524 ia32_emitf(node, "\tmovl %S0, %D0\n");
1525 ia32_emitf(node, "\tmovl $%u, %S1\n", attr->count);
1526 be_gas_emit_block_name(node);
1527 be_emit_cstring(":\n");
1528 be_emit_write_line();
1529 ia32_emitf(node, "\tmovl (%D0), %D0\n");
1530 ia32_emitf(node, "\tdec %S1\n");
1531 be_emit_cstring("\tjnz ");
1532 be_gas_emit_block_name(node);
1533 be_emit_finish_line_gas(node);
1536 static void emit_be_Return(const ir_node *node)
1538 unsigned pop = be_Return_get_pop(node);
1540 if (pop > 0 || be_Return_get_emit_pop(node)) {
1541 ia32_emitf(node, "\tret $%u\n", pop);
1543 ia32_emitf(node, "\tret\n");
1547 static void emit_Nothing(const ir_node *node)
1554 * Enters the emitter functions for handled nodes into the generic
1555 * pointer of an opcode.
1557 static void ia32_register_emitters(void)
1559 #define IA32_EMIT2(a,b) op_ia32_##a->ops.generic = (op_func)emit_ia32_##b
1560 #define IA32_EMIT(a) IA32_EMIT2(a,a)
1561 #define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
1562 #define IGN(a) op_##a->ops.generic = (op_func)emit_Nothing
1563 #define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
1564 #define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing
1566 /* first clear the generic function pointer for all ops */
1567 clear_irp_opcodes_generic_func();
1569 /* register all emitter functions defined in spec */
1570 ia32_register_spec_emitters();
1572 /* other ia32 emitter functions */
1573 IA32_EMIT2(Conv_I2I8Bit, Conv_I2I);
1578 IA32_EMIT(Conv_FP2FP);
1579 IA32_EMIT(Conv_FP2I);
1580 IA32_EMIT(Conv_I2FP);
1581 IA32_EMIT(Conv_I2I);
1588 IA32_EMIT(Minus64Bit);
1589 IA32_EMIT(SwitchJmp);
1590 IA32_EMIT(ClimbFrame);
1593 /* benode emitter */
1613 typedef void (*emit_func_ptr) (const ir_node *);
1616 * Assign and emit an exception label if the current instruction can fail.
1618 static void ia32_assign_exc_label(ir_node *node)
1620 /* assign a new ID to the instruction */
1621 set_ia32_exc_label_id(node, ++exc_label_id);
1623 ia32_emit_exc_label(node);
1625 be_emit_pad_comment();
1626 be_emit_cstring("/* exception to Block ");
1627 ia32_emit_cfop_target(node);
1628 be_emit_cstring(" */\n");
1629 be_emit_write_line();
1633 * Emits code for a node.
1635 static void ia32_emit_node(ir_node *node)
1637 ir_op *op = get_irn_op(node);
1639 DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
1641 if (is_ia32_irn(node)) {
1642 if (get_ia32_exc_label(node)) {
1643 /* emit the exception label of this instruction */
1644 ia32_assign_exc_label(node);
1646 if (mark_spill_reload) {
1647 if (is_ia32_is_spill(node)) {
1648 ia32_emitf(NULL, "\txchg %ebx, %ebx /* spill mark */\n");
1650 if (is_ia32_is_reload(node)) {
1651 ia32_emitf(NULL, "\txchg %edx, %edx /* reload mark */\n");
1653 if (is_ia32_is_remat(node)) {
1654 ia32_emitf(NULL, "\txchg %ecx, %ecx /* remat mark */\n");
1658 if (op->ops.generic) {
1659 emit_func_ptr func = (emit_func_ptr) op->ops.generic;
1661 be_dbg_set_dbg_info(get_irn_dbg_info(node));
1666 ir_fprintf(stderr, "Error: No emit handler for node %+F (%+G, graph %+F)\n", node, node, current_ir_graph);
1672 * Emits gas alignment directives
1674 static void ia32_emit_alignment(unsigned align, unsigned skip)
1676 ia32_emitf(NULL, "\t.p2align %u,,%u\n", align, skip);
1680 * Emits gas alignment directives for Labels depended on cpu architecture.
1682 static void ia32_emit_align_label(void)
1684 unsigned align = ia32_cg_config.label_alignment;
1685 unsigned maximum_skip = ia32_cg_config.label_alignment_max_skip;
1686 ia32_emit_alignment(align, maximum_skip);
1690 * Test whether a block should be aligned.
1691 * For cpus in the P4/Athlon class it is useful to align jump labels to
1692 * 16 bytes. However we should only do that if the alignment nops before the
1693 * label aren't executed more often than we have jumps to the label.
1695 static int should_align_block(const ir_node *block)
1697 static const double DELTA = .0001;
1698 ir_graph *irg = get_irn_irg(block);
1699 ir_exec_freq *exec_freq = be_get_irg_exec_freq(irg);
1700 ir_node *prev = get_prev_block_sched(block);
1702 double prev_freq = 0; /**< execfreq of the fallthrough block */
1703 double jmp_freq = 0; /**< execfreq of all non-fallthrough blocks */
1706 if (exec_freq == NULL)
1708 if (ia32_cg_config.label_alignment_factor <= 0)
1711 block_freq = get_block_execfreq(exec_freq, block);
1712 if (block_freq < DELTA)
1715 n_cfgpreds = get_Block_n_cfgpreds(block);
1716 for (i = 0; i < n_cfgpreds; ++i) {
1717 const ir_node *pred = get_Block_cfgpred_block(block, i);
1718 double pred_freq = get_block_execfreq(exec_freq, pred);
1721 prev_freq += pred_freq;
1723 jmp_freq += pred_freq;
1727 if (prev_freq < DELTA && !(jmp_freq < DELTA))
1730 jmp_freq /= prev_freq;
1732 return jmp_freq > ia32_cg_config.label_alignment_factor;
1736 * Emit the block header for a block.
1738 * @param block the block
1739 * @param prev_block the previous block
1741 static void ia32_emit_block_header(ir_node *block)
1743 ir_graph *irg = current_ir_graph;
1744 int need_label = block_needs_label(block);
1745 ir_exec_freq *exec_freq = be_get_irg_exec_freq(irg);
1748 if (block == get_irg_end_block(irg))
1751 if (ia32_cg_config.label_alignment > 0) {
1752 /* align the current block if:
1753 * a) if should be aligned due to its execution frequency
1754 * b) there is no fall-through here
1756 if (should_align_block(block)) {
1757 ia32_emit_align_label();
1759 /* if the predecessor block has no fall-through,
1760 we can always align the label. */
1762 int has_fallthrough = 0;
1764 for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
1765 ir_node *cfg_pred = get_Block_cfgpred(block, i);
1766 if (can_be_fallthrough(cfg_pred)) {
1767 has_fallthrough = 1;
1772 if (!has_fallthrough)
1773 ia32_emit_align_label();
1778 be_gas_emit_block_name(block);
1781 be_emit_pad_comment();
1782 be_emit_cstring(" /* ");
1784 be_emit_cstring("\t/* ");
1785 be_gas_emit_block_name(block);
1786 be_emit_cstring(": ");
1789 be_emit_cstring("preds:");
1791 /* emit list of pred blocks in comment */
1792 arity = get_irn_arity(block);
1794 be_emit_cstring(" none");
1797 for (i = 0; i < arity; ++i) {
1798 ir_node *predblock = get_Block_cfgpred_block(block, i);
1799 be_emit_irprintf(" %d", get_irn_node_nr(predblock));
1802 if (exec_freq != NULL) {
1803 be_emit_irprintf(", freq: %f",
1804 get_block_execfreq(exec_freq, block));
1806 be_emit_cstring(" */\n");
1807 be_emit_write_line();
1811 * Walks over the nodes in a block connected by scheduling edges
1812 * and emits code for each node.
1814 static void ia32_gen_block(ir_node *block)
1818 ia32_emit_block_header(block);
1820 /* emit the contents of the block */
1821 be_dbg_set_dbg_info(get_irn_dbg_info(block));
1822 sched_foreach(block, node) {
1823 ia32_emit_node(node);
1827 typedef struct exc_entry {
1828 ir_node *exc_instr; /** The instruction that can issue an exception. */
1829 ir_node *block; /** The block to call then. */
1834 * Sets labels for control flow nodes (jump target).
1835 * Links control predecessors to there destination blocks.
1837 static void ia32_gen_labels(ir_node *block, void *data)
1839 exc_entry **exc_list = (exc_entry**)data;
1843 for (n = get_Block_n_cfgpreds(block) - 1; n >= 0; --n) {
1844 pred = get_Block_cfgpred(block, n);
1845 set_irn_link(pred, block);
1847 pred = skip_Proj(pred);
1848 if (is_ia32_irn(pred) && get_ia32_exc_label(pred)) {
1853 ARR_APP1(exc_entry, *exc_list, e);
1854 set_irn_link(pred, block);
1860 * Compare two exception_entries.
1862 static int cmp_exc_entry(const void *a, const void *b)
1864 const exc_entry *ea = (const exc_entry*)a;
1865 const exc_entry *eb = (const exc_entry*)b;
1867 if (get_ia32_exc_label_id(ea->exc_instr) < get_ia32_exc_label_id(eb->exc_instr))
1873 * Main driver. Emits the code for one routine.
1875 void ia32_gen_routine(ir_graph *irg)
1877 ir_entity *entity = get_irg_entity(irg);
1878 exc_entry *exc_list = NEW_ARR_F(exc_entry, 0);
1879 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
1880 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
1881 ir_node **blk_sched = irg_data->blk_sched;
1884 isa = (ia32_isa_t*) arch_env;
1885 do_pic = be_get_irg_options(irg)->pic;
1887 be_gas_elf_type_char = '@';
1889 ia32_register_emitters();
1891 get_unique_label(pic_base_label, sizeof(pic_base_label), "PIC_BASE");
1893 be_dbg_method_begin(entity);
1894 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment);
1896 /* we use links to point to target blocks */
1897 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
1898 irg_block_walk_graph(irg, ia32_gen_labels, NULL, &exc_list);
1900 /* initialize next block links */
1901 n = ARR_LEN(blk_sched);
1902 for (i = 0; i < n; ++i) {
1903 ir_node *block = blk_sched[i];
1904 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
1906 set_irn_link(block, prev);
1909 for (i = 0; i < n; ++i) {
1910 ir_node *block = blk_sched[i];
1912 ia32_gen_block(block);
1915 be_gas_emit_function_epilog(entity);
1916 be_dbg_method_end();
1918 be_emit_write_line();
1920 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
1922 /* Sort the exception table using the exception label id's.
1923 Those are ascending with ascending addresses. */
1924 qsort(exc_list, ARR_LEN(exc_list), sizeof(exc_list[0]), cmp_exc_entry);
1928 for (e = 0; e < ARR_LEN(exc_list); ++e) {
1929 be_emit_cstring("\t.long ");
1930 ia32_emit_exc_label(exc_list[e].exc_instr);
1932 be_emit_cstring("\t.long ");
1933 be_gas_emit_block_name(exc_list[e].block);
1937 DEL_ARR_F(exc_list);
1940 static const lc_opt_table_entry_t ia32_emitter_options[] = {
1941 LC_OPT_ENT_BOOL("mark_spill_reload", "mark spills and reloads with ud opcodes", &mark_spill_reload),
1945 /* ==== Experimental binary emitter ==== */
1947 static unsigned char reg_gp_map[N_ia32_gp_REGS];
1948 //static unsigned char reg_mmx_map[N_ia32_mmx_REGS];
1949 //static unsigned char reg_sse_map[N_ia32_xmm_REGS];
1951 static void build_reg_map(void)
1953 reg_gp_map[REG_GP_EAX] = 0x0;
1954 reg_gp_map[REG_GP_ECX] = 0x1;
1955 reg_gp_map[REG_GP_EDX] = 0x2;
1956 reg_gp_map[REG_GP_EBX] = 0x3;
1957 reg_gp_map[REG_GP_ESP] = 0x4;
1958 reg_gp_map[REG_GP_EBP] = 0x5;
1959 reg_gp_map[REG_GP_ESI] = 0x6;
1960 reg_gp_map[REG_GP_EDI] = 0x7;
1963 /** Returns the encoding for a pnc field. */
1964 static unsigned char pnc2cc(ia32_condition_code_t cc)
1969 /** Sign extension bit values for binops */
1971 UNSIGNED_IMM = 0, /**< unsigned immediate */
1972 SIGNEXT_IMM = 2, /**< sign extended immediate */
1975 /** The mod encoding of the ModR/M */
1977 MOD_IND = 0x00, /**< [reg1] */
1978 MOD_IND_BYTE_OFS = 0x40, /**< [reg1 + byte ofs] */
1979 MOD_IND_WORD_OFS = 0x80, /**< [reg1 + word ofs] */
1980 MOD_REG = 0xC0 /**< reg1 */
1983 /** create R/M encoding for ModR/M */
1984 #define ENC_RM(x) (x)
1985 /** create REG encoding for ModR/M */
1986 #define ENC_REG(x) ((x) << 3)
1988 /** create encoding for a SIB byte */
1989 #define ENC_SIB(scale, index, base) ((scale) << 6 | (index) << 3 | (base))
1991 /* Node: The following routines are supposed to append bytes, words, dwords
1992 to the output stream.
1993 Currently the implementation is stupid in that it still creates output
1994 for an "assembler" in the form of .byte, .long
1995 We will change this when enough infrastructure is there to create complete
1996 machine code in memory/object files */
1998 static void bemit8(const unsigned char byte)
2000 be_emit_irprintf("\t.byte 0x%x\n", byte);
2001 be_emit_write_line();
2004 static void bemit16(const unsigned short u16)
2006 be_emit_irprintf("\t.word 0x%x\n", u16);
2007 be_emit_write_line();
2010 static void bemit32(const unsigned u32)
2012 be_emit_irprintf("\t.long 0x%x\n", u32);
2013 be_emit_write_line();
2017 * Emit address of an entity. If @p is_relative is true then a relative
2018 * offset from behind the address to the entity is created.
2020 static void bemit_entity(ir_entity *entity, bool entity_sign, int offset,
2023 if (entity == NULL) {
2028 /* the final version should remember the position in the bytestream
2029 and patch it with the correct address at linktime... */
2030 be_emit_cstring("\t.long ");
2033 be_gas_emit_entity(entity);
2035 if (get_entity_owner(entity) == get_tls_type()) {
2036 if (get_entity_visibility(entity) == ir_visibility_external) {
2037 be_emit_cstring("@INDNTPOFF");
2039 be_emit_cstring("@NTPOFF");
2044 be_emit_cstring("-.");
2049 be_emit_irprintf("%+d", offset);
2052 be_emit_write_line();
2055 static void bemit_jmp_destination(const ir_node *dest_block)
2057 be_emit_cstring("\t.long ");
2058 be_gas_emit_block_name(dest_block);
2059 be_emit_cstring(" - . - 4\n");
2060 be_emit_write_line();
2063 /* end emit routines, all emitters following here should only use the functions
2066 typedef enum reg_modifier {
2071 /** Create a ModR/M byte for src1,src2 registers */
2072 static void bemit_modrr(const arch_register_t *src1,
2073 const arch_register_t *src2)
2075 unsigned char modrm = MOD_REG;
2076 modrm |= ENC_RM(reg_gp_map[src1->index]);
2077 modrm |= ENC_REG(reg_gp_map[src2->index]);
2081 /** Create a ModR/M8 byte for src1,src2 registers */
2082 static void bemit_modrr8(reg_modifier_t high_part1, const arch_register_t *src1,
2083 reg_modifier_t high_part2, const arch_register_t *src2)
2085 unsigned char modrm = MOD_REG;
2086 modrm |= ENC_RM(reg_gp_map[src1->index] + (high_part1 == REG_HIGH ? 4 : 0));
2087 modrm |= ENC_REG(reg_gp_map[src2->index] + (high_part2 == REG_HIGH ? 4 : 0));
2091 /** Create a ModR/M byte for one register and extension */
2092 static void bemit_modru(const arch_register_t *reg, unsigned ext)
2094 unsigned char modrm = MOD_REG;
2096 modrm |= ENC_RM(reg_gp_map[reg->index]);
2097 modrm |= ENC_REG(ext);
2101 /** Create a ModR/M8 byte for one register */
2102 static void bemit_modrm8(reg_modifier_t high_part, const arch_register_t *reg)
2104 unsigned char modrm = MOD_REG;
2105 assert(reg_gp_map[reg->index] < 4);
2106 modrm |= ENC_RM(reg_gp_map[reg->index] + (high_part == REG_HIGH ? 4 : 0));
2112 * Calculate the size of an signed immediate in bytes.
2114 * @param offset an offset
2116 static unsigned get_signed_imm_size(int offset)
2118 if (-128 <= offset && offset < 128) {
2120 } else if (-32768 <= offset && offset < 32768) {
2128 * Emit an address mode.
2130 * @param reg content of the reg field: either a register index or an opcode extension
2131 * @param node the node
2133 static void bemit_mod_am(unsigned reg, const ir_node *node)
2135 ir_entity *ent = get_ia32_am_sc(node);
2136 int offs = get_ia32_am_offs_int(node);
2137 ir_node *base = get_irn_n(node, n_ia32_base);
2138 int has_base = !is_ia32_NoReg_GP(base);
2139 ir_node *idx = get_irn_n(node, n_ia32_index);
2140 int has_index = !is_ia32_NoReg_GP(idx);
2143 unsigned emitoffs = 0;
2144 bool emitsib = false;
2147 /* set the mod part depending on displacement */
2149 modrm |= MOD_IND_WORD_OFS;
2151 } else if (offs == 0) {
2154 } else if (-128 <= offs && offs < 128) {
2155 modrm |= MOD_IND_BYTE_OFS;
2158 modrm |= MOD_IND_WORD_OFS;
2163 const arch_register_t *base_reg = arch_get_irn_register(base);
2164 base_enc = reg_gp_map[base_reg->index];
2166 /* Use the EBP encoding + MOD_IND if NO base register. There is
2167 * always a 32bit offset present in this case. */
2173 /* Determine if we need a SIB byte. */
2175 const arch_register_t *reg_index = arch_get_irn_register(idx);
2176 int scale = get_ia32_am_scale(node);
2178 /* R/M set to ESP means SIB in 32bit mode. */
2179 modrm |= ENC_RM(0x04);
2180 sib = ENC_SIB(scale, reg_gp_map[reg_index->index], base_enc);
2182 } else if (base_enc == 0x04) {
2183 /* for the above reason we are forced to emit a SIB when base is ESP.
2184 * Only the base is used, index must be ESP too, which means no index.
2186 modrm |= ENC_RM(0x04);
2187 sib = ENC_SIB(0, 0x04, 0x04);
2190 modrm |= ENC_RM(base_enc);
2193 /* We are forced to emit an 8bit offset as EBP base without offset is a
2194 * special case for SIB without base register. */
2195 if (base_enc == 0x05 && emitoffs == 0) {
2196 modrm |= MOD_IND_BYTE_OFS;
2200 modrm |= ENC_REG(reg);
2206 /* emit displacement */
2207 if (emitoffs == 8) {
2208 bemit8((unsigned) offs);
2209 } else if (emitoffs == 32) {
2210 bemit_entity(ent, is_ia32_am_sc_sign(node), offs, false);
2215 * Emit a binop with a immediate operand.
2217 * @param node the node to emit
2218 * @param opcode_eax the opcode for the op eax, imm variant
2219 * @param opcode the opcode for the reg, imm variant
2220 * @param ruval the opcode extension for opcode
2222 static void bemit_binop_with_imm(
2223 const ir_node *node,
2224 unsigned char opcode_ax,
2225 unsigned char opcode, unsigned char ruval)
2227 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2228 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2229 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2232 /* Some instructions (test) have no short form with 32bit value + 8bit
2234 if (attr->symconst != NULL || opcode & SIGNEXT_IMM) {
2237 /* check for sign extension */
2238 size = get_signed_imm_size(attr->offset);
2243 bemit8(opcode | SIGNEXT_IMM);
2244 /* cmp has this special mode */
2245 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2246 bemit_mod_am(ruval, node);
2248 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2249 bemit_modru(reg, ruval);
2251 bemit8((unsigned char)attr->offset);
2255 /* check for eax variant: this variant is shorter for 32bit immediates only */
2256 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2258 bemit_mod_am(ruval, node);
2260 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2261 if (reg->index == REG_GP_EAX) {
2265 bemit_modru(reg, ruval);
2268 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2271 panic("invalid imm size?!?");
2277 static void bemit_binop_2(const ir_node *node, unsigned code)
2279 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2281 if (get_ia32_op_type(node) == ia32_Normal) {
2282 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2283 bemit_modrr(op2, out);
2285 bemit_mod_am(reg_gp_map[out->index], node);
2292 static void bemit_binop(const ir_node *node, const unsigned char opcodes[4])
2294 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2295 if (is_ia32_Immediate(right)) {
2296 bemit_binop_with_imm(node, opcodes[1], opcodes[2], opcodes[3]);
2298 bemit_binop_2(node, opcodes[0]);
2305 static void bemit_unop(const ir_node *node, unsigned char code, unsigned char ext, int input)
2308 if (get_ia32_op_type(node) == ia32_Normal) {
2309 const arch_register_t *in = arch_get_irn_register_in(node, input);
2310 bemit_modru(in, ext);
2312 bemit_mod_am(ext, node);
2316 static void bemit_unop_reg(const ir_node *node, unsigned char code, int input)
2318 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2319 bemit_unop(node, code, reg_gp_map[out->index], input);
2322 static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned char ext)
2324 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2327 bemit8(size == 8 ? code : code + 1);
2328 bemit_mod_am(ext, node);
2331 static void bemit_immediate(const ir_node *node, bool relative)
2333 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
2334 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, relative);
2337 static void bemit_copy(const ir_node *copy)
2339 const arch_register_t *in = arch_get_irn_register_in(copy, 0);
2340 const arch_register_t *out = arch_get_irn_register_out(copy, 0);
2344 /* copies of vf nodes aren't real... */
2345 if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
2348 if (get_irn_mode(copy) == mode_E) {
2351 assert(arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_gp]);
2353 bemit_modrr(in, out);
2357 static void bemit_perm(const ir_node *node)
2359 const arch_register_t *in0 = arch_get_irn_register(get_irn_n(node, 0));
2360 const arch_register_t *in1 = arch_get_irn_register(get_irn_n(node, 1));
2361 const arch_register_class_t *cls0 = arch_register_get_class(in0);
2363 assert(cls0 == arch_register_get_class(in1) && "Register class mismatch at Perm");
2365 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
2366 if (in0->index == REG_GP_EAX) {
2367 bemit8(0x90 + reg_gp_map[in1->index]);
2368 } else if (in1->index == REG_GP_EAX) {
2369 bemit8(0x90 + reg_gp_map[in0->index]);
2372 bemit_modrr(in0, in1);
2374 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
2375 panic("unimplemented"); // TODO implement
2376 //ia32_emitf(NULL, "\txorpd %R, %R\n", in1, in0);
2377 //ia32_emitf(NULL, "\txorpd %R, %R\n", in0, in1);
2378 //ia32_emitf(node, "\txorpd %R, %R\n", in1, in0);
2379 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
2381 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
2384 panic("unexpected register class in be_Perm (%+F)", node);
2388 static void bemit_xor0(const ir_node *node)
2390 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2392 bemit_modrr(out, out);
2395 static void bemit_mov_const(const ir_node *node)
2397 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2398 bemit8(0xB8 + reg_gp_map[out->index]);
2399 bemit_immediate(node, false);
2403 * Creates a function for a Binop with 3 possible encodings.
2405 #define BINOP(op, op0, op1, op2, op2_ext) \
2406 static void bemit_ ## op(const ir_node *node) { \
2407 static const unsigned char op ## _codes[] = {op0, op1, op2, op2_ext}; \
2408 bemit_binop(node, op ## _codes); \
2411 /* insn def eax,imm imm */
2412 BINOP(add, 0x03, 0x05, 0x81, 0)
2413 BINOP(or, 0x0B, 0x0D, 0x81, 1)
2414 BINOP(adc, 0x13, 0x15, 0x81, 2)
2415 BINOP(sbb, 0x1B, 0x1D, 0x81, 3)
2416 BINOP(and, 0x23, 0x25, 0x81, 4)
2417 BINOP(sub, 0x2B, 0x2D, 0x81, 5)
2418 BINOP(xor, 0x33, 0x35, 0x81, 6)
2419 BINOP(test, 0x85, 0xA9, 0xF7, 0)
2421 #define BINOPMEM(op, ext) \
2422 static void bemit_##op(const ir_node *node) \
2425 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2428 val = get_irn_n(node, n_ia32_unary_op); \
2429 if (is_ia32_Immediate(val)) { \
2430 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(val); \
2431 int offset = attr->offset; \
2432 if (attr->symconst == NULL && get_signed_imm_size(offset) == 1) { \
2434 bemit_mod_am(ext, node); \
2438 bemit_mod_am(ext, node); \
2442 bemit_entity(attr->symconst, attr->sc_sign, offset, false); \
2446 bemit8(ext << 3 | 1); \
2447 bemit_mod_am(reg_gp_map[arch_get_irn_register_out(val, 0)->index], node); \
2451 static void bemit_##op##8bit(const ir_node *node) \
2453 ir_node *val = get_irn_n(node, n_ia32_unary_op); \
2454 if (is_ia32_Immediate(val)) { \
2456 bemit_mod_am(ext, node); \
2457 bemit8(get_ia32_immediate_attr_const(val)->offset); \
2460 bemit_mod_am(reg_gp_map[arch_get_irn_register_out(val, 0)->index], node); \
2472 * Creates a function for an Unop with code /ext encoding.
2474 #define UNOP(op, code, ext, input) \
2475 static void bemit_ ## op(const ir_node *node) { \
2476 bemit_unop(node, code, ext, input); \
2479 UNOP(not, 0xF7, 2, n_ia32_Not_val)
2480 UNOP(neg, 0xF7, 3, n_ia32_Neg_val)
2481 UNOP(mul, 0xF7, 4, n_ia32_Mul_right)
2482 UNOP(imul1op, 0xF7, 5, n_ia32_IMul1OP_right)
2483 UNOP(div, 0xF7, 6, n_ia32_Div_divisor)
2484 UNOP(idiv, 0xF7, 7, n_ia32_IDiv_divisor)
2486 /* TODO: am support for IJmp */
2487 UNOP(ijmp, 0xFF, 4, n_ia32_IJmp_target)
2489 #define SHIFT(op, ext) \
2490 static void bemit_##op(const ir_node *node) \
2492 const arch_register_t *out = arch_get_irn_register_out(node, 0); \
2493 ir_node *count = get_irn_n(node, 1); \
2494 if (is_ia32_Immediate(count)) { \
2495 int offset = get_ia32_immediate_attr_const(count)->offset; \
2496 if (offset == 1) { \
2498 bemit_modru(out, ext); \
2501 bemit_modru(out, ext); \
2506 bemit_modru(out, ext); \
2510 static void bemit_##op##mem(const ir_node *node) \
2513 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2516 count = get_irn_n(node, 1); \
2517 if (is_ia32_Immediate(count)) { \
2518 int offset = get_ia32_immediate_attr_const(count)->offset; \
2519 if (offset == 1) { \
2520 bemit8(size == 8 ? 0xD0 : 0xD1); \
2521 bemit_mod_am(ext, node); \
2523 bemit8(size == 8 ? 0xC0 : 0xC1); \
2524 bemit_mod_am(ext, node); \
2528 bemit8(size == 8 ? 0xD2 : 0xD3); \
2529 bemit_mod_am(ext, node); \
2539 static void bemit_shld(const ir_node *node)
2541 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShlD_val_low);
2542 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShlD_res);
2543 ir_node *count = get_irn_n(node, n_ia32_ShlD_count);
2545 if (is_ia32_Immediate(count)) {
2547 bemit_modrr(out, in);
2548 bemit8(get_ia32_immediate_attr_const(count)->offset);
2551 bemit_modrr(out, in);
2555 static void bemit_shrd(const ir_node *node)
2557 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShrD_val_low);
2558 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShrD_res);
2559 ir_node *count = get_irn_n(node, n_ia32_ShrD_count);
2561 if (is_ia32_Immediate(count)) {
2563 bemit_modrr(out, in);
2564 bemit8(get_ia32_immediate_attr_const(count)->offset);
2567 bemit_modrr(out, in);
2572 * binary emitter for setcc.
2574 static void bemit_setcc(const ir_node *node)
2576 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
2578 ia32_condition_code_t cc = get_ia32_condcode(node);
2579 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
2580 if (cc & ia32_cc_float_parity_cases) {
2581 if (cc & ia32_cc_negated) {
2584 bemit8(0x90 | pnc2cc(cc));
2585 bemit_modrm8(REG_LOW, dreg);
2590 bemit_modrm8(REG_HIGH, dreg);
2592 /* orb %>dreg, %<dreg */
2594 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2598 bemit8(0x90 | pnc2cc(cc));
2599 bemit_modrm8(REG_LOW, dreg);
2604 bemit_modrm8(REG_HIGH, dreg);
2606 /* andb %>dreg, %<dreg */
2608 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2613 bemit8(0x90 | pnc2cc(cc));
2614 bemit_modrm8(REG_LOW, dreg);
2618 static void bemit_cmovcc(const ir_node *node)
2620 const ia32_attr_t *attr = get_ia32_attr_const(node);
2621 int ins_permuted = attr->data.ins_permuted;
2622 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
2623 ia32_condition_code_t cc = get_ia32_condcode(node);
2624 const arch_register_t *in_true;
2625 const arch_register_t *in_false;
2627 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
2629 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
2630 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
2632 /* should be same constraint fullfilled? */
2633 if (out == in_false) {
2634 /* yes -> nothing to do */
2635 } else if (out == in_true) {
2636 assert(get_ia32_op_type(node) == ia32_Normal);
2637 ins_permuted = !ins_permuted;
2641 bemit8(0x8B); // mov %in_false, %out
2642 bemit_modrr(in_false, out);
2646 cc = ia32_negate_condition_code(cc);
2648 if (cc & ia32_cc_float_parity_cases)
2649 panic("cmov can't handle parity float cases");
2652 bemit8(0x40 | pnc2cc(cc));
2653 if (get_ia32_op_type(node) == ia32_Normal) {
2654 bemit_modrr(in_true, out);
2656 bemit_mod_am(reg_gp_map[out->index], node);
2660 static void bemit_cmp(const ir_node *node)
2662 unsigned ls_size = get_mode_size_bits(get_ia32_ls_mode(node));
2668 right = get_irn_n(node, n_ia32_binary_right);
2669 if (is_ia32_Immediate(right)) {
2670 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2671 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2672 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2675 if (attr->symconst != NULL) {
2678 /* check for sign extension */
2679 size = get_signed_imm_size(attr->offset);
2684 bemit8(0x81 | SIGNEXT_IMM);
2685 /* cmp has this special mode */
2686 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2687 bemit_mod_am(7, node);
2689 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2690 bemit_modru(reg, 7);
2692 bemit8((unsigned char)attr->offset);
2696 /* check for eax variant: this variant is shorter for 32bit immediates only */
2697 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2699 bemit_mod_am(7, node);
2701 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2702 if (reg->index == REG_GP_EAX) {
2706 bemit_modru(reg, 7);
2709 if (ls_size == 16) {
2710 bemit16(attr->offset);
2712 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2716 panic("invalid imm size?!?");
2718 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2720 if (get_ia32_op_type(node) == ia32_Normal) {
2721 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2722 bemit_modrr(op2, out);
2724 bemit_mod_am(reg_gp_map[out->index], node);
2729 static void bemit_cmp8bit(const ir_node *node)
2731 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2732 if (is_ia32_Immediate(right)) {
2733 if (get_ia32_op_type(node) == ia32_Normal) {
2734 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2735 if (out->index == REG_GP_EAX) {
2739 bemit_modru(out, 7);
2743 bemit_mod_am(7, node);
2745 bemit8(get_ia32_immediate_attr_const(right)->offset);
2747 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2749 if (get_ia32_op_type(node) == ia32_Normal) {
2750 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Cmp_right);
2751 bemit_modrr(out, in);
2753 bemit_mod_am(reg_gp_map[out->index], node);
2758 static void bemit_test8bit(const ir_node *node)
2760 ir_node *right = get_irn_n(node, n_ia32_Test8Bit_right);
2761 if (is_ia32_Immediate(right)) {
2762 if (get_ia32_op_type(node) == ia32_Normal) {
2763 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
2764 if (out->index == REG_GP_EAX) {
2768 bemit_modru(out, 0);
2772 bemit_mod_am(0, node);
2774 bemit8(get_ia32_immediate_attr_const(right)->offset);
2776 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
2778 if (get_ia32_op_type(node) == ia32_Normal) {
2779 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Test8Bit_right);
2780 bemit_modrr(out, in);
2782 bemit_mod_am(reg_gp_map[out->index], node);
2787 static void bemit_imul(const ir_node *node)
2789 ir_node *right = get_irn_n(node, n_ia32_IMul_right);
2790 /* Do we need the immediate form? */
2791 if (is_ia32_Immediate(right)) {
2792 int imm = get_ia32_immediate_attr_const(right)->offset;
2793 if (get_signed_imm_size(imm) == 1) {
2794 bemit_unop_reg(node, 0x6B, n_ia32_IMul_left);
2797 bemit_unop_reg(node, 0x69, n_ia32_IMul_left);
2802 bemit_unop_reg(node, 0xAF, n_ia32_IMul_right);
2806 static void bemit_dec(const ir_node *node)
2808 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Dec_res);
2809 bemit8(0x48 + reg_gp_map[out->index]);
2812 static void bemit_inc(const ir_node *node)
2814 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Inc_res);
2815 bemit8(0x40 + reg_gp_map[out->index]);
2818 #define UNOPMEM(op, code, ext) \
2819 static void bemit_##op(const ir_node *node) \
2821 bemit_unop_mem(node, code, ext); \
2824 UNOPMEM(notmem, 0xF6, 2)
2825 UNOPMEM(negmem, 0xF6, 3)
2826 UNOPMEM(incmem, 0xFE, 0)
2827 UNOPMEM(decmem, 0xFE, 1)
2829 static void bemit_ldtls(const ir_node *node)
2831 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2833 bemit8(0x65); // gs:
2834 if (out->index == REG_GP_EAX) {
2835 bemit8(0xA1); // movl 0, %eax
2837 bemit8(0x8B); // movl 0, %reg
2838 bemit8(MOD_IND | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x05));
2846 static void bemit_lea(const ir_node *node)
2848 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2850 bemit_mod_am(reg_gp_map[out->index], node);
2853 /* helper function for bemit_minus64bit */
2854 static void bemit_helper_mov(const arch_register_t *src, const arch_register_t *dst)
2856 bemit8(0x8B); // movl %src, %dst
2857 bemit_modrr(src, dst);
2860 /* helper function for bemit_minus64bit */
2861 static void bemit_helper_neg(const arch_register_t *reg)
2863 bemit8(0xF7); // negl %reg
2864 bemit_modru(reg, 3);
2867 /* helper function for bemit_minus64bit */
2868 static void bemit_helper_sbb0(const arch_register_t *reg)
2870 bemit8(0x83); // sbbl $0, %reg
2871 bemit_modru(reg, 3);
2875 /* helper function for bemit_minus64bit */
2876 static void bemit_helper_sbb(const arch_register_t *src, const arch_register_t *dst)
2878 bemit8(0x1B); // sbbl %src, %dst
2879 bemit_modrr(src, dst);
2882 /* helper function for bemit_minus64bit */
2883 static void bemit_helper_xchg(const arch_register_t *src, const arch_register_t *dst)
2885 if (src->index == REG_GP_EAX) {
2886 bemit8(0x90 + reg_gp_map[dst->index]); // xchgl %eax, %dst
2887 } else if (dst->index == REG_GP_EAX) {
2888 bemit8(0x90 + reg_gp_map[src->index]); // xchgl %src, %eax
2890 bemit8(0x87); // xchgl %src, %dst
2891 bemit_modrr(src, dst);
2895 /* helper function for bemit_minus64bit */
2896 static void bemit_helper_zero(const arch_register_t *reg)
2898 bemit8(0x33); // xorl %reg, %reg
2899 bemit_modrr(reg, reg);
2902 static void bemit_minus64bit(const ir_node *node)
2904 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
2905 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
2906 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
2907 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
2909 if (out_lo == in_lo) {
2910 if (out_hi != in_hi) {
2911 /* a -> a, b -> d */
2914 /* a -> a, b -> b */
2917 } else if (out_lo == in_hi) {
2918 if (out_hi == in_lo) {
2919 /* a -> b, b -> a */
2920 bemit_helper_xchg(in_lo, in_hi);
2923 /* a -> b, b -> d */
2924 bemit_helper_mov(in_hi, out_hi);
2925 bemit_helper_mov(in_lo, out_lo);
2929 if (out_hi == in_lo) {
2930 /* a -> c, b -> a */
2931 bemit_helper_mov(in_lo, out_lo);
2933 } else if (out_hi == in_hi) {
2934 /* a -> c, b -> b */
2935 bemit_helper_mov(in_lo, out_lo);
2938 /* a -> c, b -> d */
2939 bemit_helper_mov(in_lo, out_lo);
2945 bemit_helper_neg( out_hi);
2946 bemit_helper_neg( out_lo);
2947 bemit_helper_sbb0(out_hi);
2951 bemit_helper_zero(out_hi);
2952 bemit_helper_neg( out_lo);
2953 bemit_helper_sbb( in_hi, out_hi);
2957 * Emit a single opcode.
2959 #define EMIT_SINGLEOP(op, code) \
2960 static void bemit_ ## op(const ir_node *node) { \
2965 //EMIT_SINGLEOP(daa, 0x27)
2966 //EMIT_SINGLEOP(das, 0x2F)
2967 //EMIT_SINGLEOP(aaa, 0x37)
2968 //EMIT_SINGLEOP(aas, 0x3F)
2969 //EMIT_SINGLEOP(nop, 0x90)
2970 EMIT_SINGLEOP(cwtl, 0x98)
2971 EMIT_SINGLEOP(cltd, 0x99)
2972 //EMIT_SINGLEOP(fwait, 0x9B)
2973 EMIT_SINGLEOP(sahf, 0x9E)
2974 //EMIT_SINGLEOP(popf, 0x9D)
2975 EMIT_SINGLEOP(leave, 0xC9)
2976 EMIT_SINGLEOP(int3, 0xCC)
2977 //EMIT_SINGLEOP(iret, 0xCF)
2978 //EMIT_SINGLEOP(xlat, 0xD7)
2979 //EMIT_SINGLEOP(lock, 0xF0)
2980 EMIT_SINGLEOP(rep, 0xF3)
2981 //EMIT_SINGLEOP(halt, 0xF4)
2982 EMIT_SINGLEOP(cmc, 0xF5)
2983 EMIT_SINGLEOP(stc, 0xF9)
2984 //EMIT_SINGLEOP(cli, 0xFA)
2985 //EMIT_SINGLEOP(sti, 0xFB)
2986 //EMIT_SINGLEOP(std, 0xFD)
2989 * Emits a MOV out, [MEM].
2991 static void bemit_load(const ir_node *node)
2993 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2995 if (out->index == REG_GP_EAX) {
2996 ir_node *base = get_irn_n(node, n_ia32_base);
2997 int has_base = !is_ia32_NoReg_GP(base);
2998 ir_node *idx = get_irn_n(node, n_ia32_index);
2999 int has_index = !is_ia32_NoReg_GP(idx);
3000 if (!has_base && !has_index) {
3001 ir_entity *ent = get_ia32_am_sc(node);
3002 int offs = get_ia32_am_offs_int(node);
3003 /* load from constant address to EAX can be encoded
3006 bemit_entity(ent, 0, offs, false);
3011 bemit_mod_am(reg_gp_map[out->index], node);
3015 * Emits a MOV [mem], in.
3017 static void bemit_store(const ir_node *node)
3019 const ir_node *value = get_irn_n(node, n_ia32_Store_val);
3020 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
3022 if (is_ia32_Immediate(value)) {
3025 bemit_mod_am(0, node);
3026 bemit8(get_ia32_immediate_attr_const(value)->offset);
3027 } else if (size == 16) {
3030 bemit_mod_am(0, node);
3031 bemit16(get_ia32_immediate_attr_const(value)->offset);
3034 bemit_mod_am(0, node);
3035 bemit_immediate(value, false);
3038 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Store_val);
3040 if (in->index == REG_GP_EAX) {
3041 ir_node *base = get_irn_n(node, n_ia32_base);
3042 int has_base = !is_ia32_NoReg_GP(base);
3043 ir_node *idx = get_irn_n(node, n_ia32_index);
3044 int has_index = !is_ia32_NoReg_GP(idx);
3045 if (!has_base && !has_index) {
3046 ir_entity *ent = get_ia32_am_sc(node);
3047 int offs = get_ia32_am_offs_int(node);
3048 /* store to constant address from EAX can be encoded as
3049 * 0xA2/0xA3 [offset]*/
3057 bemit_entity(ent, 0, offs, false);
3069 bemit_mod_am(reg_gp_map[in->index], node);
3073 static void bemit_conv_i2i(const ir_node *node)
3075 ir_mode *smaller_mode = get_ia32_ls_mode(node);
3084 if (mode_is_signed(smaller_mode)) opcode |= 0x08;
3085 if (get_mode_size_bits(smaller_mode) == 16) opcode |= 0x01;
3086 bemit_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
3092 static void bemit_push(const ir_node *node)
3094 const ir_node *value = get_irn_n(node, n_ia32_Push_val);
3096 if (is_ia32_Immediate(value)) {
3097 const ia32_immediate_attr_t *attr
3098 = get_ia32_immediate_attr_const(value);
3099 unsigned size = get_signed_imm_size(attr->offset);
3105 bemit8((unsigned char)attr->offset);
3110 bemit_immediate(value, false);
3113 } else if (is_ia32_NoReg_GP(value)) {
3115 bemit_mod_am(6, node);
3117 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_Push_val);
3118 bemit8(0x50 + reg_gp_map[reg->index]);
3125 static void bemit_pop(const ir_node *node)
3127 const arch_register_t *reg = arch_get_irn_register_out(node, pn_ia32_Pop_res);
3128 bemit8(0x58 + reg_gp_map[reg->index]);
3131 static void bemit_popmem(const ir_node *node)
3134 bemit_mod_am(0, node);
3137 static void bemit_call(const ir_node *node)
3139 ir_node *proc = get_irn_n(node, n_ia32_Call_addr);
3141 if (is_ia32_Immediate(proc)) {
3143 bemit_immediate(proc, true);
3145 bemit_unop(node, 0xFF, 2, n_ia32_Call_addr);
3149 static void bemit_jmp(const ir_node *dest_block)
3152 bemit_jmp_destination(dest_block);
3155 static void bemit_jump(const ir_node *node)
3157 if (can_be_fallthrough(node))
3160 bemit_jmp(get_cfop_target_block(node));
3163 static void bemit_jcc(int pnc, const ir_node *dest_block)
3165 unsigned char cc = pnc2cc(pnc);
3168 bemit_jmp_destination(dest_block);
3171 static void bemit_jp(bool odd, const ir_node *dest_block)
3175 bemit_jmp_destination(dest_block);
3178 static void bemit_ia32_jcc(const ir_node *node)
3180 ia32_condition_code_t cc = get_ia32_condcode(node);
3181 const ir_node *proj_true;
3182 const ir_node *proj_false;
3183 const ir_node *dest_true;
3184 const ir_node *dest_false;
3186 cc = determine_final_cc(node, 0, cc);
3188 /* get both Projs */
3189 proj_true = get_proj(node, pn_ia32_Jcc_true);
3190 assert(proj_true && "Jcc without true Proj");
3192 proj_false = get_proj(node, pn_ia32_Jcc_false);
3193 assert(proj_false && "Jcc without false Proj");
3195 if (can_be_fallthrough(proj_true)) {
3196 /* exchange both proj's so the second one can be omitted */
3197 const ir_node *t = proj_true;
3199 proj_true = proj_false;
3201 cc = ia32_negate_condition_code(cc);
3204 dest_true = get_cfop_target_block(proj_true);
3205 dest_false = get_cfop_target_block(proj_false);
3207 if (cc & ia32_cc_float_parity_cases) {
3208 /* Some floating point comparisons require a test of the parity flag,
3209 * which indicates that the result is unordered */
3210 if (cc & ia32_cc_negated) {
3211 bemit_jp(false, dest_true);
3213 /* we need a local label if the false proj is a fallthrough
3214 * as the falseblock might have no label emitted then */
3215 if (can_be_fallthrough(proj_false)) {
3217 bemit8(0x06); // jp + 6
3219 bemit_jp(false, dest_false);
3223 bemit_jcc(cc, dest_true);
3225 /* the second Proj might be a fallthrough */
3226 if (can_be_fallthrough(proj_false)) {
3227 /* it's a fallthrough */
3229 bemit_jmp(dest_false);
3233 static void bemit_switchjmp(const ir_node *node)
3235 ir_entity *jump_table = get_ia32_am_sc(node);
3236 long default_pn = get_ia32_default_pn(node);
3238 bemit8(0xFF); // jmp *tbl.label(,%in,4)
3239 bemit_mod_am(0x05, node);
3241 emit_jump_table(node, default_pn, jump_table, get_cfop_target_block);
3247 static void bemit_return(const ir_node *node)
3249 unsigned pop = be_Return_get_pop(node);
3250 if (pop > 0 || be_Return_get_emit_pop(node)) {
3252 assert(pop <= 0xffff);
3259 static void bemit_subsp(const ir_node *node)
3261 const arch_register_t *out;
3264 /* mov %esp, %out */
3266 out = arch_get_irn_register_out(node, 1);
3267 bemit8(MOD_REG | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x04));
3270 static void bemit_incsp(const ir_node *node)
3273 const arch_register_t *reg;
3277 offs = be_get_IncSP_offset(node);
3288 size = get_signed_imm_size(offs);
3289 bemit8(size == 1 ? 0x83 : 0x81);
3291 reg = arch_get_irn_register_out(node, 0);
3292 bemit_modru(reg, ext);
3301 static void bemit_copybi(const ir_node *node)
3303 unsigned size = get_ia32_copyb_size(node);
3305 bemit8(0xA4); // movsb
3308 bemit8(0xA5); // movsw
3312 bemit8(0xA5); // movsl
3316 static void bemit_fbinop(const ir_node *node, unsigned code, unsigned code_to)
3318 if (get_ia32_op_type(node) == ia32_Normal) {
3319 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
3320 const arch_register_t *in1 = x87_attr->x87[0];
3321 const arch_register_t *in = x87_attr->x87[1];
3322 const arch_register_t *out = x87_attr->x87[2];
3326 } else if (out == in) {
3330 if (out->index == 0) {
3332 bemit8(MOD_REG | ENC_REG(code) | ENC_RM(in->index));
3335 bemit8(MOD_REG | ENC_REG(code_to) | ENC_RM(out->index));
3338 if (get_mode_size_bits(get_ia32_ls_mode(node)) == 32) {
3343 bemit_mod_am(code, node);
3347 static void bemit_fbinopp(const ir_node *node, unsigned const code)
3349 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
3350 const arch_register_t *out = x87_attr->x87[2];
3352 bemit8(code + out->index);
3355 static void bemit_fabs(const ir_node *node)
3363 static void bemit_fadd(const ir_node *node)
3365 bemit_fbinop(node, 0, 0);
3368 static void bemit_faddp(const ir_node *node)
3370 bemit_fbinopp(node, 0xC0);
3373 static void bemit_fchs(const ir_node *node)
3381 static void bemit_fdiv(const ir_node *node)
3383 bemit_fbinop(node, 6, 7);
3386 static void bemit_fdivp(const ir_node *node)
3388 bemit_fbinopp(node, 0xF8);
3391 static void bemit_fdivr(const ir_node *node)
3393 bemit_fbinop(node, 7, 6);
3396 static void bemit_fdivrp(const ir_node *node)
3398 bemit_fbinopp(node, 0xF0);
3401 static void bemit_fild(const ir_node *node)
3403 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3405 bemit8(0xDF); // filds
3406 bemit_mod_am(0, node);
3410 bemit8(0xDB); // fildl
3411 bemit_mod_am(0, node);
3415 bemit8(0xDF); // fildll
3416 bemit_mod_am(5, node);
3420 panic("invalid mode size");
3424 static void bemit_fist(const ir_node *node)
3426 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3428 bemit8(0xDF); // fists
3432 bemit8(0xDB); // fistl
3436 panic("invalid mode size");
3438 bemit_mod_am(2, node);
3441 static void bemit_fistp(const ir_node *node)
3443 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3445 bemit8(0xDF); // fistps
3446 bemit_mod_am(3, node);
3450 bemit8(0xDB); // fistpl
3451 bemit_mod_am(3, node);
3455 bemit8(0xDF); // fistpll
3456 bemit_mod_am(7, node);
3460 panic("invalid mode size");
3464 static void bemit_fld(const ir_node *node)
3466 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3468 bemit8(0xD9); // flds
3469 bemit_mod_am(0, node);
3473 bemit8(0xDD); // fldl
3474 bemit_mod_am(0, node);
3479 bemit8(0xDB); // fldt
3480 bemit_mod_am(5, node);
3484 panic("invalid mode size");
3488 static void bemit_fld1(const ir_node *node)
3492 bemit8(0xE8); // fld1
3495 static void bemit_fldcw(const ir_node *node)
3497 bemit8(0xD9); // fldcw
3498 bemit_mod_am(5, node);
3501 static void bemit_fldz(const ir_node *node)
3505 bemit8(0xEE); // fldz
3508 static void bemit_fmul(const ir_node *node)
3510 bemit_fbinop(node, 1, 1);
3513 static void bemit_fmulp(const ir_node *node)
3515 bemit_fbinopp(node, 0xC8);
3518 static void bemit_fpop(const ir_node *node)
3520 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3522 bemit8(0xD8 + attr->x87[0]->index);
3525 static void bemit_fpush(const ir_node *node)
3527 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3529 bemit8(0xC0 + attr->x87[0]->index);
3532 static void bemit_fpushcopy(const ir_node *node)
3534 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3536 bemit8(0xC0 + attr->x87[0]->index);
3539 static void bemit_fst(const ir_node *node)
3541 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3543 bemit8(0xD9); // fsts
3547 bemit8(0xDD); // fstl
3551 panic("invalid mode size");
3553 bemit_mod_am(2, node);
3556 static void bemit_fstp(const ir_node *node)
3558 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3560 bemit8(0xD9); // fstps
3561 bemit_mod_am(3, node);
3565 bemit8(0xDD); // fstpl
3566 bemit_mod_am(3, node);
3571 bemit8(0xDB); // fstpt
3572 bemit_mod_am(7, node);
3576 panic("invalid mode size");
3580 static void bemit_fsub(const ir_node *node)
3582 bemit_fbinop(node, 4, 5);
3585 static void bemit_fsubp(const ir_node *node)
3587 bemit_fbinopp(node, 0xE8);
3590 static void bemit_fsubr(const ir_node *node)
3592 bemit_fbinop(node, 5, 4);
3595 static void bemit_fsubrp(const ir_node *node)
3597 bemit_fbinopp(node, 0xE0);
3600 static void bemit_fnstcw(const ir_node *node)
3602 bemit8(0xD9); // fnstcw
3603 bemit_mod_am(7, node);
3606 static void bemit_fnstsw(void)
3608 bemit8(0xDF); // fnstsw %ax
3612 static void bemit_ftstfnstsw(const ir_node *node)
3616 bemit8(0xD9); // ftst
3621 static void bemit_fucomi(const ir_node *node)
3623 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3624 bemit8(0xDB); // fucomi
3625 bemit8(0xE8 + attr->x87[1]->index);
3628 static void bemit_fucomip(const ir_node *node)
3630 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3631 bemit8(0xDF); // fucomip
3632 bemit8(0xE8 + attr->x87[1]->index);
3635 static void bemit_fucomfnstsw(const ir_node *node)
3637 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3638 bemit8(0xDD); // fucom
3639 bemit8(0xE0 + attr->x87[1]->index);
3643 static void bemit_fucompfnstsw(const ir_node *node)
3645 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3646 bemit8(0xDD); // fucomp
3647 bemit8(0xE8 + attr->x87[1]->index);
3651 static void bemit_fucomppfnstsw(const ir_node *node)
3655 bemit8(0xDA); // fucompp
3660 static void bemit_fxch(const ir_node *node)
3662 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3664 bemit8(0xC8 + attr->x87[0]->index);
3668 * The type of a emitter function.
3670 typedef void (*emit_func) (const ir_node *);
3673 * Set a node emitter. Make it a bit more type safe.
3675 static void register_emitter(ir_op *op, emit_func func)
3677 op->ops.generic = (op_func) func;
3680 static void ia32_register_binary_emitters(void)
3682 /* first clear the generic function pointer for all ops */
3683 clear_irp_opcodes_generic_func();
3685 /* benode emitter */
3686 register_emitter(op_be_Copy, bemit_copy);
3687 register_emitter(op_be_CopyKeep, bemit_copy);
3688 register_emitter(op_be_IncSP, bemit_incsp);
3689 register_emitter(op_be_Perm, bemit_perm);
3690 register_emitter(op_be_Return, bemit_return);
3691 register_emitter(op_ia32_Adc, bemit_adc);
3692 register_emitter(op_ia32_Add, bemit_add);
3693 register_emitter(op_ia32_AddMem, bemit_addmem);
3694 register_emitter(op_ia32_AddMem8Bit, bemit_addmem8bit);
3695 register_emitter(op_ia32_And, bemit_and);
3696 register_emitter(op_ia32_AndMem, bemit_andmem);
3697 register_emitter(op_ia32_AndMem8Bit, bemit_andmem8bit);
3698 register_emitter(op_ia32_Breakpoint, bemit_int3);
3699 register_emitter(op_ia32_CMovcc, bemit_cmovcc);
3700 register_emitter(op_ia32_Call, bemit_call);
3701 register_emitter(op_ia32_Cltd, bemit_cltd);
3702 register_emitter(op_ia32_Cmc, bemit_cmc);
3703 register_emitter(op_ia32_Cmp, bemit_cmp);
3704 register_emitter(op_ia32_Cmp8Bit, bemit_cmp8bit);
3705 register_emitter(op_ia32_Const, bemit_mov_const);
3706 register_emitter(op_ia32_Conv_I2I, bemit_conv_i2i);
3707 register_emitter(op_ia32_Conv_I2I8Bit, bemit_conv_i2i);
3708 register_emitter(op_ia32_CopyB_i, bemit_copybi);
3709 register_emitter(op_ia32_Cwtl, bemit_cwtl);
3710 register_emitter(op_ia32_Dec, bemit_dec);
3711 register_emitter(op_ia32_DecMem, bemit_decmem);
3712 register_emitter(op_ia32_Div, bemit_div);
3713 register_emitter(op_ia32_FldCW, bemit_fldcw);
3714 register_emitter(op_ia32_FnstCW, bemit_fnstcw);
3715 register_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw);
3716 register_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw);
3717 register_emitter(op_ia32_Fucomi, bemit_fucomi);
3718 register_emitter(op_ia32_FucompFnstsw, bemit_fucompfnstsw);
3719 register_emitter(op_ia32_Fucompi, bemit_fucomip);
3720 register_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw);
3721 register_emitter(op_ia32_IDiv, bemit_idiv);
3722 register_emitter(op_ia32_IJmp, bemit_ijmp);
3723 register_emitter(op_ia32_IMul, bemit_imul);
3724 register_emitter(op_ia32_IMul1OP, bemit_imul1op);
3725 register_emitter(op_ia32_Inc, bemit_inc);
3726 register_emitter(op_ia32_IncMem, bemit_incmem);
3727 register_emitter(op_ia32_Jcc, bemit_ia32_jcc);
3728 register_emitter(op_ia32_Jmp, bemit_jump);
3729 register_emitter(op_ia32_LdTls, bemit_ldtls);
3730 register_emitter(op_ia32_Lea, bemit_lea);
3731 register_emitter(op_ia32_Leave, bemit_leave);
3732 register_emitter(op_ia32_Load, bemit_load);
3733 register_emitter(op_ia32_Minus64Bit, bemit_minus64bit);
3734 register_emitter(op_ia32_Mul, bemit_mul);
3735 register_emitter(op_ia32_Neg, bemit_neg);
3736 register_emitter(op_ia32_NegMem, bemit_negmem);
3737 register_emitter(op_ia32_Not, bemit_not);
3738 register_emitter(op_ia32_NotMem, bemit_notmem);
3739 register_emitter(op_ia32_Or, bemit_or);
3740 register_emitter(op_ia32_OrMem, bemit_ormem);
3741 register_emitter(op_ia32_OrMem8Bit, bemit_ormem8bit);
3742 register_emitter(op_ia32_Pop, bemit_pop);
3743 register_emitter(op_ia32_PopEbp, bemit_pop);
3744 register_emitter(op_ia32_PopMem, bemit_popmem);
3745 register_emitter(op_ia32_Push, bemit_push);
3746 register_emitter(op_ia32_RepPrefix, bemit_rep);
3747 register_emitter(op_ia32_Rol, bemit_rol);
3748 register_emitter(op_ia32_RolMem, bemit_rolmem);
3749 register_emitter(op_ia32_Ror, bemit_ror);
3750 register_emitter(op_ia32_RorMem, bemit_rormem);
3751 register_emitter(op_ia32_Sahf, bemit_sahf);
3752 register_emitter(op_ia32_Sar, bemit_sar);
3753 register_emitter(op_ia32_SarMem, bemit_sarmem);
3754 register_emitter(op_ia32_Sbb, bemit_sbb);
3755 register_emitter(op_ia32_Setcc, bemit_setcc);
3756 register_emitter(op_ia32_Shl, bemit_shl);
3757 register_emitter(op_ia32_ShlD, bemit_shld);
3758 register_emitter(op_ia32_ShlMem, bemit_shlmem);
3759 register_emitter(op_ia32_Shr, bemit_shr);
3760 register_emitter(op_ia32_ShrD, bemit_shrd);
3761 register_emitter(op_ia32_ShrMem, bemit_shrmem);
3762 register_emitter(op_ia32_Stc, bemit_stc);
3763 register_emitter(op_ia32_Store, bemit_store);
3764 register_emitter(op_ia32_Store8Bit, bemit_store);
3765 register_emitter(op_ia32_Sub, bemit_sub);
3766 register_emitter(op_ia32_SubMem, bemit_submem);
3767 register_emitter(op_ia32_SubMem8Bit, bemit_submem8bit);
3768 register_emitter(op_ia32_SubSP, bemit_subsp);
3769 register_emitter(op_ia32_SwitchJmp, bemit_switchjmp);
3770 register_emitter(op_ia32_Test, bemit_test);
3771 register_emitter(op_ia32_Test8Bit, bemit_test8bit);
3772 register_emitter(op_ia32_Xor, bemit_xor);
3773 register_emitter(op_ia32_Xor0, bemit_xor0);
3774 register_emitter(op_ia32_XorMem, bemit_xormem);
3775 register_emitter(op_ia32_XorMem8Bit, bemit_xormem8bit);
3776 register_emitter(op_ia32_fabs, bemit_fabs);
3777 register_emitter(op_ia32_fadd, bemit_fadd);
3778 register_emitter(op_ia32_faddp, bemit_faddp);
3779 register_emitter(op_ia32_fchs, bemit_fchs);
3780 register_emitter(op_ia32_fdiv, bemit_fdiv);
3781 register_emitter(op_ia32_fdivp, bemit_fdivp);
3782 register_emitter(op_ia32_fdivr, bemit_fdivr);
3783 register_emitter(op_ia32_fdivrp, bemit_fdivrp);
3784 register_emitter(op_ia32_fild, bemit_fild);
3785 register_emitter(op_ia32_fist, bemit_fist);
3786 register_emitter(op_ia32_fistp, bemit_fistp);
3787 register_emitter(op_ia32_fld, bemit_fld);
3788 register_emitter(op_ia32_fld1, bemit_fld1);
3789 register_emitter(op_ia32_fldz, bemit_fldz);
3790 register_emitter(op_ia32_fmul, bemit_fmul);
3791 register_emitter(op_ia32_fmulp, bemit_fmulp);
3792 register_emitter(op_ia32_fpop, bemit_fpop);
3793 register_emitter(op_ia32_fpush, bemit_fpush);
3794 register_emitter(op_ia32_fpushCopy, bemit_fpushcopy);
3795 register_emitter(op_ia32_fst, bemit_fst);
3796 register_emitter(op_ia32_fstp, bemit_fstp);
3797 register_emitter(op_ia32_fsub, bemit_fsub);
3798 register_emitter(op_ia32_fsubp, bemit_fsubp);
3799 register_emitter(op_ia32_fsubr, bemit_fsubr);
3800 register_emitter(op_ia32_fsubrp, bemit_fsubrp);
3801 register_emitter(op_ia32_fxch, bemit_fxch);
3803 /* ignore the following nodes */
3804 register_emitter(op_ia32_ProduceVal, emit_Nothing);
3805 register_emitter(op_be_Keep, emit_Nothing);
3806 register_emitter(op_be_Start, emit_Nothing);
3807 register_emitter(op_Phi, emit_Nothing);
3808 register_emitter(op_Start, emit_Nothing);
3811 static void gen_binary_block(ir_node *block)
3815 ia32_emit_block_header(block);
3817 /* emit the contents of the block */
3818 sched_foreach(block, node) {
3819 ia32_emit_node(node);
3823 void ia32_gen_binary_routine(ir_graph *irg)
3825 ir_entity *entity = get_irg_entity(irg);
3826 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
3827 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
3828 ir_node **blk_sched = irg_data->blk_sched;
3831 isa = (ia32_isa_t*) arch_env;
3833 ia32_register_binary_emitters();
3835 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment);
3837 /* we use links to point to target blocks */
3838 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
3839 irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
3841 /* initialize next block links */
3842 n = ARR_LEN(blk_sched);
3843 for (i = 0; i < n; ++i) {
3844 ir_node *block = blk_sched[i];
3845 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
3847 set_irn_link(block, prev);
3850 for (i = 0; i < n; ++i) {
3851 ir_node *block = blk_sched[i];
3852 gen_binary_block(block);
3855 be_gas_emit_function_epilog(entity);
3856 be_dbg_method_end();
3858 be_emit_write_line();
3860 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
3864 void ia32_init_emitter(void)
3866 lc_opt_entry_t *be_grp;
3867 lc_opt_entry_t *ia32_grp;
3869 be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
3870 ia32_grp = lc_opt_get_grp(be_grp, "ia32");
3872 lc_opt_add_table(ia32_grp, ia32_emitter_options);
3876 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");