2 * Copyright (C) 1995-2008 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
39 #include "iredges_t.h"
43 #include "raw_bitset.h"
47 #include "../besched.h"
48 #include "../benode.h"
50 #include "../be_dbgout.h"
51 #include "../beemitter.h"
52 #include "../begnuas.h"
54 #include "../be_dbgout.h"
56 #include "ia32_emitter.h"
57 #include "gen_ia32_emitter.h"
58 #include "gen_ia32_regalloc_if.h"
59 #include "ia32_nodes_attr.h"
60 #include "ia32_new_nodes.h"
61 #include "ia32_map_regs.h"
62 #include "ia32_architecture.h"
63 #include "bearch_ia32_t.h"
65 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
67 #define BLOCK_PREFIX ".L"
69 #define SNPRINTF_BUF_LEN 128
71 static const ia32_isa_t *isa;
72 static ia32_code_gen_t *cg;
73 static char pic_base_label[128];
74 static ir_label_t exc_label_id;
75 static int mark_spill_reload = 0;
78 /** Return the next block in Block schedule */
79 static ir_node *get_prev_block_sched(const ir_node *block)
81 return get_irn_link(block);
84 /** Checks if the current block is a fall-through target. */
85 static int is_fallthrough(const ir_node *cfgpred)
89 if (!is_Proj(cfgpred))
91 pred = get_Proj_pred(cfgpred);
92 if (is_ia32_SwitchJmp(pred))
99 * returns non-zero if the given block needs a label
100 * because of being a jump-target (and not a fall-through)
102 static int block_needs_label(const ir_node *block)
105 int n_cfgpreds = get_Block_n_cfgpreds(block);
107 if (has_Block_entity(block))
110 if (n_cfgpreds == 0) {
112 } else if (n_cfgpreds == 1) {
113 ir_node *cfgpred = get_Block_cfgpred(block, 0);
114 ir_node *cfgpred_block = get_nodes_block(cfgpred);
116 if (get_prev_block_sched(block) == cfgpred_block
117 && is_fallthrough(cfgpred)) {
126 * Returns the register at in position pos.
128 static const arch_register_t *get_in_reg(const ir_node *irn, int pos)
131 const arch_register_t *reg = NULL;
133 assert(get_irn_arity(irn) > pos && "Invalid IN position");
135 /* The out register of the operator at position pos is the
136 in register we need. */
137 op = get_irn_n(irn, pos);
139 reg = arch_get_irn_register(op);
141 assert(reg && "no in register found");
143 if (reg == &ia32_gp_regs[REG_GP_NOREG])
144 panic("trying to emit noreg for %+F input %d", irn, pos);
146 /* in case of unknown register: just return a valid register */
147 if (reg == &ia32_gp_regs[REG_GP_UKNWN]) {
148 const arch_register_req_t *req = arch_get_register_req(irn, pos);
150 if (arch_register_req_is(req, limited)) {
151 /* in case of limited requirements: get the first allowed register */
152 unsigned idx = rbitset_next(req->limited, 0, 1);
153 reg = arch_register_for_index(req->cls, idx);
155 /* otherwise get first register in class */
156 reg = arch_register_for_index(req->cls, 0);
164 * Returns the register at out position pos.
166 static const arch_register_t *get_out_reg(const ir_node *irn, int pos)
169 const arch_register_t *reg = NULL;
171 /* 1st case: irn is not of mode_T, so it has only */
172 /* one OUT register -> good */
173 /* 2nd case: irn is of mode_T -> collect all Projs and ask the */
174 /* Proj with the corresponding projnum for the register */
176 if (get_irn_mode(irn) != mode_T) {
178 reg = arch_get_irn_register(irn);
179 } else if (is_ia32_irn(irn)) {
180 reg = arch_irn_get_register(irn, pos);
182 const ir_edge_t *edge;
184 foreach_out_edge(irn, edge) {
185 proj = get_edge_src_irn(edge);
186 assert(is_Proj(proj) && "non-Proj from mode_T node");
187 if (get_Proj_proj(proj) == pos) {
188 reg = arch_get_irn_register(proj);
194 assert(reg && "no out register found");
199 * Add a number to a prefix. This number will not be used a second time.
201 static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
203 static unsigned long id = 0;
204 snprintf(buf, buflen, "%s%lu", prefix, ++id);
208 /*************************************************************
210 * (_) | | / _| | | | |
211 * _ __ _ __ _ _ __ | |_| |_ | |__ ___| |_ __ ___ _ __
212 * | '_ \| '__| | '_ \| __| _| | '_ \ / _ \ | '_ \ / _ \ '__|
213 * | |_) | | | | | | | |_| | | | | | __/ | |_) | __/ |
214 * | .__/|_| |_|_| |_|\__|_| |_| |_|\___|_| .__/ \___|_|
217 *************************************************************/
220 * Emit the name of the 8bit low register
222 static void emit_8bit_register(const arch_register_t *reg)
224 const char *reg_name = arch_register_get_name(reg);
227 be_emit_char(reg_name[1]);
232 * Emit the name of the 8bit high register
234 static void emit_8bit_register_high(const arch_register_t *reg)
236 const char *reg_name = arch_register_get_name(reg);
239 be_emit_char(reg_name[1]);
243 static void emit_16bit_register(const arch_register_t *reg)
245 const char *reg_name = ia32_get_mapped_reg_name(isa->regs_16bit, reg);
248 be_emit_string(reg_name);
252 * emit a register, possible shortened by a mode
254 * @param reg the register
255 * @param mode the mode of the register or NULL for full register
257 static void emit_register(const arch_register_t *reg, const ir_mode *mode)
259 const char *reg_name;
262 int size = get_mode_size_bits(mode);
264 case 8: emit_8bit_register(reg); return;
265 case 16: emit_16bit_register(reg); return;
267 assert(mode_is_float(mode) || size == 32);
270 reg_name = arch_register_get_name(reg);
273 be_emit_string(reg_name);
276 void ia32_emit_source_register(const ir_node *node, int pos)
278 const arch_register_t *reg = get_in_reg(node, pos);
280 emit_register(reg, NULL);
283 static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
285 set_entity_backend_marked(entity, 1);
286 be_gas_emit_entity(entity);
288 if (get_entity_owner(entity) == get_tls_type()) {
289 if (get_entity_visibility(entity) == visibility_external_allocated) {
290 be_emit_cstring("@INDNTPOFF");
292 be_emit_cstring("@NTPOFF");
296 if (do_pic && !no_pic_adjust) {
298 be_emit_string(pic_base_label);
302 static void emit_ia32_Immediate_no_prefix(const ir_node *node)
304 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
306 if (attr->symconst != NULL) {
309 ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
311 if (attr->symconst == NULL || attr->offset != 0) {
312 if (attr->symconst != NULL) {
313 be_emit_irprintf("%+d", attr->offset);
315 be_emit_irprintf("0x%X", attr->offset);
320 static void emit_ia32_Immediate(const ir_node *node)
323 emit_ia32_Immediate_no_prefix(node);
326 void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos)
328 const arch_register_t *reg;
329 const ir_node *in = get_irn_n(node, pos);
330 if (is_ia32_Immediate(in)) {
331 emit_ia32_Immediate(in);
335 reg = get_in_reg(node, pos);
336 emit_8bit_register(reg);
339 void ia32_emit_8bit_high_source_register(const ir_node *node, int pos)
341 const arch_register_t *reg = get_in_reg(node, pos);
342 emit_8bit_register_high(reg);
345 void ia32_emit_16bit_source_register_or_immediate(const ir_node *node, int pos)
347 const arch_register_t *reg;
348 const ir_node *in = get_irn_n(node, pos);
349 if (is_ia32_Immediate(in)) {
350 emit_ia32_Immediate(in);
354 reg = get_in_reg(node, pos);
355 emit_16bit_register(reg);
358 void ia32_emit_dest_register(const ir_node *node, int pos)
360 const arch_register_t *reg = get_out_reg(node, pos);
362 emit_register(reg, NULL);
365 void ia32_emit_dest_register_size(const ir_node *node, int pos)
367 const arch_register_t *reg = get_out_reg(node, pos);
369 emit_register(reg, get_ia32_ls_mode(node));
372 void ia32_emit_8bit_dest_register(const ir_node *node, int pos)
374 const arch_register_t *reg = get_out_reg(node, pos);
376 emit_register(reg, mode_Bu);
379 void ia32_emit_x87_register(const ir_node *node, int pos)
381 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
385 be_emit_string(attr->x87[pos]->name);
388 static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
390 assert(mode_is_int(mode) || mode_is_reference(mode));
391 switch (get_mode_size_bits(mode)) {
392 case 8: be_emit_char('b'); return;
393 case 16: be_emit_char('w'); return;
394 case 32: be_emit_char('l'); return;
395 /* gas docu says q is the suffix but gcc, objdump and icc use ll
397 case 64: be_emit_cstring("ll"); return;
399 panic("Can't output mode_suffix for %+F", mode);
402 void ia32_emit_mode_suffix(const ir_node *node)
404 ir_mode *mode = get_ia32_ls_mode(node);
408 ia32_emit_mode_suffix_mode(mode);
411 void ia32_emit_x87_mode_suffix(const ir_node *node)
415 /* we only need to emit the mode on address mode */
416 if (get_ia32_op_type(node) == ia32_Normal)
419 mode = get_ia32_ls_mode(node);
420 assert(mode != NULL);
422 if (mode_is_float(mode)) {
423 switch (get_mode_size_bits(mode)) {
424 case 32: be_emit_char('s'); return;
425 case 64: be_emit_char('l'); return;
427 case 96: be_emit_char('t'); return;
430 assert(mode_is_int(mode));
431 switch (get_mode_size_bits(mode)) {
432 case 16: be_emit_char('s'); return;
433 case 32: be_emit_char('l'); return;
434 /* gas docu says q is the suffix but gcc, objdump and icc use ll
436 case 64: be_emit_cstring("ll"); return;
439 panic("Can't output mode_suffix for %+F", mode);
442 static char get_xmm_mode_suffix(ir_mode *mode)
444 assert(mode_is_float(mode));
445 switch(get_mode_size_bits(mode)) {
448 default: panic("Invalid XMM mode");
452 void ia32_emit_xmm_mode_suffix(const ir_node *node)
454 ir_mode *mode = get_ia32_ls_mode(node);
455 assert(mode != NULL);
457 be_emit_char(get_xmm_mode_suffix(mode));
460 void ia32_emit_xmm_mode_suffix_s(const ir_node *node)
462 ir_mode *mode = get_ia32_ls_mode(node);
463 assert(mode != NULL);
464 be_emit_char(get_xmm_mode_suffix(mode));
467 void ia32_emit_extend_suffix(const ir_node *node)
469 ir_mode *mode = get_ia32_ls_mode(node);
470 if (get_mode_size_bits(mode) == 32)
472 be_emit_char(mode_is_signed(mode) ? 's' : 'z');
473 ia32_emit_mode_suffix_mode(mode);
476 void ia32_emit_source_register_or_immediate(const ir_node *node, int pos)
478 ir_node *in = get_irn_n(node, pos);
479 if (is_ia32_Immediate(in)) {
480 emit_ia32_Immediate(in);
482 const ir_mode *mode = get_ia32_ls_mode(node);
483 const arch_register_t *reg = get_in_reg(node, pos);
484 emit_register(reg, mode);
489 * Returns the target block for a control flow node.
491 static ir_node *get_cfop_target_block(const ir_node *irn)
493 assert(get_irn_mode(irn) == mode_X);
494 return get_irn_link(irn);
498 * Emits a block label for the given block.
500 static void ia32_emit_block_name(const ir_node *block)
502 if (has_Block_entity(block)) {
503 ir_entity *entity = get_Block_entity(block);
504 be_gas_emit_entity(entity);
506 be_emit_cstring(BLOCK_PREFIX);
507 be_emit_irprintf("%ld", get_irn_node_nr(block));
512 * Emits the target label for a control flow node.
514 static void ia32_emit_cfop_target(const ir_node *node)
516 ir_node *block = get_cfop_target_block(node);
517 ia32_emit_block_name(block);
521 * positive conditions for signed compares
523 static const char *const cmp2condition_s[] = {
524 NULL, /* always false */
531 NULL /* always true */
535 * positive conditions for unsigned compares
537 static const char *const cmp2condition_u[] = {
538 NULL, /* always false */
545 NULL /* always true */
549 * Emit the suffix for a compare instruction.
551 static void ia32_emit_cmp_suffix(int pnc)
555 if (pnc == ia32_pn_Cmp_parity) {
560 if (pnc & ia32_pn_Cmp_float || pnc & ia32_pn_Cmp_unsigned) {
561 str = cmp2condition_u[pnc & 7];
563 str = cmp2condition_s[pnc & 7];
569 typedef enum ia32_emit_mod_t {
570 EMIT_RESPECT_LS = 1U << 0,
571 EMIT_ALTERNATE_AM = 1U << 1,
573 EMIT_HIGH_REG = 1U << 3,
574 EMIT_LOW_REG = 1U << 4
578 * Emits address mode.
580 void ia32_emit_am(const ir_node *node)
582 ir_entity *ent = get_ia32_am_sc(node);
583 int offs = get_ia32_am_offs_int(node);
584 ir_node *base = get_irn_n(node, n_ia32_base);
585 int has_base = !is_ia32_NoReg_GP(base);
586 ir_node *index = get_irn_n(node, n_ia32_index);
587 int has_index = !is_ia32_NoReg_GP(index);
589 /* just to be sure... */
590 assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
594 const ia32_attr_t *attr = get_ia32_attr_const(node);
595 if (is_ia32_am_sc_sign(node))
597 ia32_emit_entity(ent, attr->data.am_sc_no_pic_adjust);
600 /* also handle special case if nothing is set */
601 if (offs != 0 || (ent == NULL && !has_base && !has_index)) {
603 be_emit_irprintf("%+d", offs);
605 be_emit_irprintf("%d", offs);
609 if (has_base || has_index) {
614 const arch_register_t *reg = get_in_reg(node, n_ia32_base);
615 emit_register(reg, NULL);
618 /* emit index + scale */
620 const arch_register_t *reg = get_in_reg(node, n_ia32_index);
623 emit_register(reg, NULL);
625 scale = get_ia32_am_scale(node);
627 be_emit_irprintf(",%d", 1 << scale);
635 * fmt parameter output
636 * ---- ---------------------- ---------------------------------------------
638 * %AM <node> address mode of the node
639 * %AR const arch_register_t* address mode of the node or register
640 * %ASx <node> address mode of the node or source register x
641 * %Dx <node> destination register x
642 * %I <node> immediate of the node
643 * %L <node> control flow target of the node
644 * %M <node> mode suffix of the node
645 * %P int condition code
646 * %R const arch_register_t* register
647 * %Sx <node> source register x
648 * %s const char* string
649 * %u unsigned int unsigned int
650 * %d signed int signed int
653 * # modifier for %ASx, %D, %R, and %S uses ls mode of node to alter register width
654 * * modifier does not prefix immediates with $, but AM with *
655 * l modifier for %lu and %ld
656 * > modifier to output high 8bit register (ah, bh)
657 * < modifier to output low 8bit register (al, bl)
659 static void ia32_emitf(const ir_node *node, const char *fmt, ...)
665 const char *start = fmt;
666 ia32_emit_mod_t mod = 0;
668 while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
671 be_emit_string_len(start, fmt - start);
675 be_emit_finish_line_gas(node);
688 case '*': mod |= EMIT_ALTERNATE_AM; break;
689 case '#': mod |= EMIT_RESPECT_LS; break;
690 case 'l': mod |= EMIT_LONG; break;
691 case '>': mod |= EMIT_HIGH_REG; break;
692 case '<': mod |= EMIT_LOW_REG; break;
708 if (mod & EMIT_ALTERNATE_AM)
715 const arch_register_t *reg = va_arg(ap, const arch_register_t*);
716 if (mod & EMIT_ALTERNATE_AM)
718 if (get_ia32_op_type(node) == ia32_AddrModeS) {
721 emit_register(reg, NULL);
727 if (get_ia32_op_type(node) == ia32_AddrModeS) {
728 if (mod & EMIT_ALTERNATE_AM)
733 assert(get_ia32_op_type(node) == ia32_Normal);
738 default: goto unknown;
745 const arch_register_t *reg;
747 if (*fmt < '0' || '9' <= *fmt)
751 reg = get_out_reg(node, pos);
752 emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
757 if (!(mod & EMIT_ALTERNATE_AM))
759 emit_ia32_Immediate_no_prefix(node);
763 ia32_emit_cfop_target(node);
767 ia32_emit_mode_suffix_mode(get_ia32_ls_mode(node));
772 int pnc = va_arg(ap, int);
773 ia32_emit_cmp_suffix(pnc);
778 const arch_register_t *reg = va_arg(ap, const arch_register_t*);
779 if (mod & EMIT_HIGH_REG) {
780 emit_8bit_register_high(reg);
781 } else if (mod & EMIT_LOW_REG) {
782 emit_8bit_register(reg);
784 emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
794 if (*fmt < '0' || '9' <= *fmt)
798 in = get_irn_n(node, pos);
799 if (is_ia32_Immediate(in)) {
800 if (!(mod & EMIT_ALTERNATE_AM))
802 emit_ia32_Immediate_no_prefix(in);
804 const arch_register_t *reg;
806 if (mod & EMIT_ALTERNATE_AM)
808 reg = get_in_reg(node, pos);
809 emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
815 const char *str = va_arg(ap, const char*);
821 if (mod & EMIT_LONG) {
822 unsigned long num = va_arg(ap, unsigned long);
823 be_emit_irprintf("%lu", num);
825 unsigned num = va_arg(ap, unsigned);
826 be_emit_irprintf("%u", num);
831 if (mod & EMIT_LONG) {
832 long num = va_arg(ap, long);
833 be_emit_irprintf("%ld", num);
835 int num = va_arg(ap, int);
836 be_emit_irprintf("%d", num);
842 panic("unknown format conversion in ia32_emitf()");
850 * Emits registers and/or address mode of a binary operation.
852 void ia32_emit_binop(const ir_node *node)
854 if (is_ia32_Immediate(get_irn_n(node, n_ia32_binary_right))) {
855 ia32_emitf(node, "%#S4, %#AS3");
857 ia32_emitf(node, "%#AS4, %#S3");
862 * Emits registers and/or address mode of a binary operation.
864 void ia32_emit_x87_binop(const ir_node *node)
866 switch(get_ia32_op_type(node)) {
869 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
870 const arch_register_t *in1 = x87_attr->x87[0];
871 const arch_register_t *in = x87_attr->x87[1];
872 const arch_register_t *out = x87_attr->x87[2];
876 } else if (out == in) {
881 be_emit_string(arch_register_get_name(in));
882 be_emit_cstring(", %");
883 be_emit_string(arch_register_get_name(out));
891 assert(0 && "unsupported op type");
896 * Emits registers and/or address mode of a unary operation.
898 void ia32_emit_unop(const ir_node *node, int pos)
902 ia32_emitf(node, fmt);
905 static void emit_ia32_IMul(const ir_node *node)
907 ir_node *left = get_irn_n(node, n_ia32_IMul_left);
908 const arch_register_t *out_reg = get_out_reg(node, pn_ia32_IMul_res);
910 /* do we need the 3-address form? */
911 if (is_ia32_NoReg_GP(left) ||
912 get_in_reg(node, n_ia32_IMul_left) != out_reg) {
913 ia32_emitf(node, "\timul%M %#S4, %#AS3, %#D0\n");
915 ia32_emitf(node, "\timul%M %#AS4, %#S3\n");
920 * walks up a tree of copies/perms/spills/reloads to find the original value
921 * that is moved around
923 static ir_node *find_original_value(ir_node *node)
925 if (irn_visited(node))
928 mark_irn_visited(node);
929 if (be_is_Copy(node)) {
930 return find_original_value(be_get_Copy_op(node));
931 } else if (be_is_CopyKeep(node)) {
932 return find_original_value(be_get_CopyKeep_op(node));
933 } else if (is_Proj(node)) {
934 ir_node *pred = get_Proj_pred(node);
935 if (be_is_Perm(pred)) {
936 return find_original_value(get_irn_n(pred, get_Proj_proj(node)));
937 } else if (be_is_MemPerm(pred)) {
938 return find_original_value(get_irn_n(pred, get_Proj_proj(node) + 1));
939 } else if (is_ia32_Load(pred)) {
940 return find_original_value(get_irn_n(pred, n_ia32_Load_mem));
944 } else if (is_ia32_Store(node)) {
945 return find_original_value(get_irn_n(node, n_ia32_Store_val));
946 } else if (is_Phi(node)) {
948 arity = get_irn_arity(node);
949 for (i = 0; i < arity; ++i) {
950 ir_node *in = get_irn_n(node, i);
951 ir_node *res = find_original_value(in);
962 static int determine_final_pnc(const ir_node *node, int flags_pos,
965 ir_node *flags = get_irn_n(node, flags_pos);
966 const ia32_attr_t *flags_attr;
967 flags = skip_Proj(flags);
969 if (is_ia32_Sahf(flags)) {
970 ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
971 if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
972 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
973 inc_irg_visited(current_ir_graph);
974 cmp = find_original_value(cmp);
976 assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
977 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
980 flags_attr = get_ia32_attr_const(cmp);
981 if (flags_attr->data.ins_permuted)
982 pnc = get_mirrored_pnc(pnc);
983 pnc |= ia32_pn_Cmp_float;
984 } else if (is_ia32_Ucomi(flags) || is_ia32_Fucomi(flags)
985 || is_ia32_Fucompi(flags)) {
986 flags_attr = get_ia32_attr_const(flags);
988 if (flags_attr->data.ins_permuted)
989 pnc = get_mirrored_pnc(pnc);
990 pnc |= ia32_pn_Cmp_float;
992 flags_attr = get_ia32_attr_const(flags);
994 if (flags_attr->data.ins_permuted)
995 pnc = get_mirrored_pnc(pnc);
996 if (flags_attr->data.cmp_unsigned)
997 pnc |= ia32_pn_Cmp_unsigned;
1003 static pn_Cmp ia32_get_negated_pnc(pn_Cmp pnc)
1005 ir_mode *mode = pnc & ia32_pn_Cmp_float ? mode_F : mode_Iu;
1006 return get_negated_pnc(pnc, mode);
1009 void ia32_emit_cmp_suffix_node(const ir_node *node,
1012 const ia32_attr_t *attr = get_ia32_attr_const(node);
1014 pn_Cmp pnc = get_ia32_condcode(node);
1016 pnc = determine_final_pnc(node, flags_pos, pnc);
1017 if (attr->data.ins_permuted)
1018 pnc = ia32_get_negated_pnc(pnc);
1020 ia32_emit_cmp_suffix(pnc);
1024 * Emits an exception label for a given node.
1026 static void ia32_emit_exc_label(const ir_node *node)
1028 be_emit_string(be_gas_insn_label_prefix());
1029 be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
1033 * Returns the Proj with projection number proj and NOT mode_M
1035 static ir_node *get_proj(const ir_node *node, long proj)
1037 const ir_edge_t *edge;
1040 assert(get_irn_mode(node) == mode_T && "expected mode_T node");
1042 foreach_out_edge(node, edge) {
1043 src = get_edge_src_irn(edge);
1045 assert(is_Proj(src) && "Proj expected");
1046 if (get_irn_mode(src) == mode_M)
1049 if (get_Proj_proj(src) == proj)
1055 static int can_be_fallthrough(const ir_node *node)
1057 ir_node *target_block = get_cfop_target_block(node);
1058 ir_node *block = get_nodes_block(node);
1059 return get_prev_block_sched(target_block) == block;
1063 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
1065 static void emit_ia32_Jcc(const ir_node *node)
1067 int need_parity_label = 0;
1068 const ir_node *proj_true;
1069 const ir_node *proj_false;
1070 const ir_node *block;
1071 pn_Cmp pnc = get_ia32_condcode(node);
1073 pnc = determine_final_pnc(node, 0, pnc);
1075 /* get both Projs */
1076 proj_true = get_proj(node, pn_ia32_Jcc_true);
1077 assert(proj_true && "Jcc without true Proj");
1079 proj_false = get_proj(node, pn_ia32_Jcc_false);
1080 assert(proj_false && "Jcc without false Proj");
1082 block = get_nodes_block(node);
1084 if (can_be_fallthrough(proj_true)) {
1085 /* exchange both proj's so the second one can be omitted */
1086 const ir_node *t = proj_true;
1088 proj_true = proj_false;
1090 pnc = ia32_get_negated_pnc(pnc);
1093 if (pnc & ia32_pn_Cmp_float) {
1094 /* Some floating point comparisons require a test of the parity flag,
1095 * which indicates that the result is unordered */
1096 switch (pnc & 0x0f) {
1098 ia32_emitf(proj_true, "\tjp %L\n");
1103 ia32_emitf(proj_true, "\tjnp %L\n");
1109 /* we need a local label if the false proj is a fallthrough
1110 * as the falseblock might have no label emitted then */
1111 if (can_be_fallthrough(proj_false)) {
1112 need_parity_label = 1;
1113 ia32_emitf(proj_false, "\tjp 1f\n");
1115 ia32_emitf(proj_false, "\tjp %L\n");
1122 ia32_emitf(proj_true, "\tjp %L\n");
1130 ia32_emitf(proj_true, "\tj%P %L\n", pnc);
1133 if (need_parity_label) {
1134 ia32_emitf(NULL, "1:\n");
1137 /* the second Proj might be a fallthrough */
1138 if (can_be_fallthrough(proj_false)) {
1139 ia32_emitf(proj_false, "\t/* fallthrough to %L */\n");
1141 ia32_emitf(proj_false, "\tjmp %L\n");
1146 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
1149 static void emit_ia32_Setcc(const ir_node *node)
1151 const arch_register_t *dreg = get_out_reg(node, pn_ia32_Setcc_res);
1153 pn_Cmp pnc = get_ia32_condcode(node);
1154 pnc = determine_final_pnc(node, n_ia32_Setcc_eflags, pnc);
1155 if (pnc & ia32_pn_Cmp_float) {
1156 switch (pnc & 0x0f) {
1158 ia32_emitf(node, "\tsetp %#R\n", dreg);
1162 ia32_emitf(node, "\tsetnp %#R\n", dreg);
1168 ia32_emitf(node, "\tset%P %<R\n", pnc, dreg);
1169 ia32_emitf(node, "\tsetnp %>R\n", dreg);
1170 ia32_emitf(node, "\tandb %>R, %<R\n", dreg, dreg);
1176 ia32_emitf(node, "\tset%P %<R\n", pnc, dreg);
1177 ia32_emitf(node, "\tsetp %>R\n", dreg);
1178 ia32_emitf(node, "\torb %>R, %<R\n", dreg, dreg);
1185 ia32_emitf(node, "\tset%P %#R\n", pnc, dreg);
1188 static void emit_ia32_CMovcc(const ir_node *node)
1190 const ia32_attr_t *attr = get_ia32_attr_const(node);
1191 int ins_permuted = attr->data.ins_permuted;
1192 const arch_register_t *out = arch_irn_get_register(node, pn_ia32_res);
1193 pn_Cmp pnc = get_ia32_condcode(node);
1194 const arch_register_t *in_true;
1195 const arch_register_t *in_false;
1197 pnc = determine_final_pnc(node, n_ia32_CMovcc_eflags, pnc);
1199 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
1200 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
1202 /* should be same constraint fullfilled? */
1203 if (out == in_false) {
1204 /* yes -> nothing to do */
1205 } else if (out == in_true) {
1206 const arch_register_t *tmp;
1208 assert(get_ia32_op_type(node) == ia32_Normal);
1210 ins_permuted = !ins_permuted;
1217 ia32_emitf(node, "\tmovl %R, %R\n", in_false, out);
1221 pnc = ia32_get_negated_pnc(pnc);
1223 /* TODO: handling of Nans isn't correct yet */
1225 ia32_emitf(node, "\tcmov%P %#AR, %#R\n", pnc, in_true, out);
1228 /*********************************************************
1231 * ___ _ __ ___ _| |_ _ _ _ _ __ ___ _ __ ___
1232 * / _ \ '_ ` _ \| | __| | | | | | '_ ` _ \| '_ \/ __|
1233 * | __/ | | | | | | |_ | | |_| | | | | | | |_) \__ \
1234 * \___|_| |_| |_|_|\__| | |\__,_|_| |_| |_| .__/|___/
1237 *********************************************************/
1239 /* jump table entry (target and corresponding number) */
1240 typedef struct _branch_t {
1245 /* jump table for switch generation */
1246 typedef struct _jmp_tbl_t {
1247 ir_node *defProj; /**< default target */
1248 long min_value; /**< smallest switch case */
1249 long max_value; /**< largest switch case */
1250 long num_branches; /**< number of jumps */
1251 char label[SNPRINTF_BUF_LEN]; /**< label of the jump table */
1252 branch_t *branches; /**< jump array */
1256 * Compare two variables of type branch_t. Used to sort all switch cases
1258 static int ia32_cmp_branch_t(const void *a, const void *b)
1260 branch_t *b1 = (branch_t *)a;
1261 branch_t *b2 = (branch_t *)b;
1263 if (b1->value <= b2->value)
1269 static void generate_jump_table(jmp_tbl_t *tbl, const ir_node *node)
1275 const ir_edge_t *edge;
1277 /* fill the table structure */
1278 get_unique_label(tbl->label, SNPRINTF_BUF_LEN, ".TBL_");
1279 tbl->defProj = NULL;
1280 tbl->num_branches = get_irn_n_edges(node) - 1;
1281 tbl->branches = XMALLOCNZ(branch_t, tbl->num_branches);
1282 tbl->min_value = LONG_MAX;
1283 tbl->max_value = LONG_MIN;
1285 default_pn = get_ia32_condcode(node);
1287 /* go over all proj's and collect them */
1288 foreach_out_edge(node, edge) {
1289 proj = get_edge_src_irn(edge);
1290 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
1292 pnc = get_Proj_proj(proj);
1294 /* check for default proj */
1295 if (pnc == default_pn) {
1296 assert(tbl->defProj == NULL && "found two default Projs at SwitchJmp");
1297 tbl->defProj = proj;
1299 tbl->min_value = pnc < tbl->min_value ? pnc : tbl->min_value;
1300 tbl->max_value = pnc > tbl->max_value ? pnc : tbl->max_value;
1302 /* create branch entry */
1303 tbl->branches[i].target = proj;
1304 tbl->branches[i].value = pnc;
1309 assert(i == tbl->num_branches);
1311 /* sort the branches by their number */
1312 qsort(tbl->branches, tbl->num_branches, sizeof(tbl->branches[0]), ia32_cmp_branch_t);
1316 * Emits code for a SwitchJmp (creates a jump table if
1317 * possible otherwise a cmp-jmp cascade). Port from
1320 static void emit_ia32_SwitchJmp(const ir_node *node)
1322 unsigned long interval;
1326 /* fill the table structure */
1327 generate_jump_table(&tbl, node);
1329 /* two-complement's magic make this work without overflow */
1330 interval = tbl.max_value - tbl.min_value;
1332 /* emit the table */
1333 ia32_emitf(node, "\tcmpl $%u, %S0\n", interval);
1334 ia32_emitf(tbl.defProj, "\tja %L\n");
1336 if (tbl.num_branches > 1) {
1338 ia32_emitf(node, "\tjmp *%s(,%S0,4)\n", tbl.label);
1340 be_gas_emit_switch_section(GAS_SECTION_RODATA);
1341 ia32_emitf(NULL, "\t.align 4\n");
1342 ia32_emitf(NULL, "%s:\n", tbl.label);
1344 last_value = tbl.branches[0].value;
1345 for (i = 0; i != tbl.num_branches; ++i) {
1346 while (last_value != tbl.branches[i].value) {
1347 ia32_emitf(tbl.defProj, ".long %L\n");
1350 ia32_emitf(tbl.branches[i].target, ".long %L\n");
1353 be_gas_emit_switch_section(GAS_SECTION_TEXT);
1355 /* one jump is enough */
1356 ia32_emitf(tbl.branches[0].target, "\tjmp %L\n");
1363 * Emits code for a unconditional jump.
1365 static void emit_ia32_Jmp(const ir_node *node)
1369 /* for now, the code works for scheduled and non-schedules blocks */
1370 block = get_nodes_block(node);
1372 /* we have a block schedule */
1373 if (can_be_fallthrough(node)) {
1374 ia32_emitf(node, "\t/* fallthrough to %L */\n");
1376 ia32_emitf(node, "\tjmp %L\n");
1381 * Emit an inline assembler operand.
1383 * @param node the ia32_ASM node
1384 * @param s points to the operand (a %c)
1386 * @return pointer to the first char in s NOT in the current operand
1388 static const char* emit_asm_operand(const ir_node *node, const char *s)
1390 const ia32_attr_t *ia32_attr = get_ia32_attr_const(node);
1391 const ia32_asm_attr_t *attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
1393 const arch_register_t *reg;
1394 const ia32_asm_reg_t *asm_regs = attr->register_map;
1395 const ia32_asm_reg_t *asm_reg;
1396 const char *reg_name;
1405 /* parse modifiers */
1408 ir_fprintf(stderr, "Warning: asm text (%+F) ends with %%\n", node);
1433 "Warning: asm text (%+F) contains unknown modifier '%c' for asm op\n",
1440 sscanf(s, "%d%n", &num, &p);
1442 ir_fprintf(stderr, "Warning: Couldn't parse assembler operand (%+F)\n",
1449 if (num < 0 || ARR_LEN(asm_regs) <= num) {
1451 "Error: Custom assembler references invalid input/output (%+F)\n",
1455 asm_reg = & asm_regs[num];
1456 assert(asm_reg->valid);
1459 if (asm_reg->use_input == 0) {
1460 reg = get_out_reg(node, asm_reg->inout_pos);
1462 ir_node *pred = get_irn_n(node, asm_reg->inout_pos);
1464 /* might be an immediate value */
1465 if (is_ia32_Immediate(pred)) {
1466 emit_ia32_Immediate(pred);
1469 reg = get_in_reg(node, asm_reg->inout_pos);
1473 "Warning: no register assigned for %d asm op (%+F)\n",
1478 if (asm_reg->memory) {
1483 if (modifier != 0) {
1487 reg_name = ia32_get_mapped_reg_name(isa->regs_8bit, reg);
1490 reg_name = ia32_get_mapped_reg_name(isa->regs_8bit_high, reg);
1493 reg_name = ia32_get_mapped_reg_name(isa->regs_16bit, reg);
1496 panic("Invalid asm op modifier");
1498 be_emit_string(reg_name);
1500 emit_register(reg, asm_reg->mode);
1503 if (asm_reg->memory) {
1511 * Emits code for an ASM pseudo op.
1513 static void emit_ia32_Asm(const ir_node *node)
1515 const void *gen_attr = get_irn_generic_attr_const(node);
1516 const ia32_asm_attr_t *attr
1517 = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, gen_attr);
1518 ident *asm_text = attr->asm_text;
1519 const char *s = get_id_str(asm_text);
1521 ia32_emitf(node, "#APP\t\n");
1528 s = emit_asm_operand(node, s);
1534 ia32_emitf(NULL, "\n#NO_APP\n");
1537 /**********************************
1540 * | | ___ _ __ _ _| |_) |
1541 * | | / _ \| '_ \| | | | _ <
1542 * | |___| (_) | |_) | |_| | |_) |
1543 * \_____\___/| .__/ \__, |____/
1546 **********************************/
1549 * Emit movsb/w instructions to make mov count divideable by 4
1551 static void emit_CopyB_prolog(unsigned size)
1554 ia32_emitf(NULL, "\tmovsb\n");
1556 ia32_emitf(NULL, "\tmovsw\n");
1560 * Emit rep movsd instruction for memcopy.
1562 static void emit_ia32_CopyB(const ir_node *node)
1564 unsigned size = get_ia32_copyb_size(node);
1566 emit_CopyB_prolog(size);
1567 ia32_emitf(node, "\trep movsd\n");
1571 * Emits unrolled memcopy.
1573 static void emit_ia32_CopyB_i(const ir_node *node)
1575 unsigned size = get_ia32_copyb_size(node);
1577 emit_CopyB_prolog(size);
1581 ia32_emitf(NULL, "\tmovsd\n");
1587 /***************************
1591 * | | / _ \| '_ \ \ / /
1592 * | |___| (_) | | | \ V /
1593 * \_____\___/|_| |_|\_/
1595 ***************************/
1598 * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1600 static void emit_ia32_Conv_with_FP(const ir_node *node, const char* conv_f,
1603 ir_mode *ls_mode = get_ia32_ls_mode(node);
1604 int ls_bits = get_mode_size_bits(ls_mode);
1605 const char *conv = ls_bits == 32 ? conv_f : conv_d;
1607 ia32_emitf(node, "\tcvt%s %AS3, %D0\n", conv);
1610 static void emit_ia32_Conv_I2FP(const ir_node *node)
1612 emit_ia32_Conv_with_FP(node, "si2ss", "si2sd");
1615 static void emit_ia32_Conv_FP2I(const ir_node *node)
1617 emit_ia32_Conv_with_FP(node, "ss2si", "sd2si");
1620 static void emit_ia32_Conv_FP2FP(const ir_node *node)
1622 emit_ia32_Conv_with_FP(node, "sd2ss", "ss2sd");
1626 * Emits code for an Int conversion.
1628 static void emit_ia32_Conv_I2I(const ir_node *node)
1630 ir_mode *smaller_mode = get_ia32_ls_mode(node);
1631 int signed_mode = mode_is_signed(smaller_mode);
1632 const char *sign_suffix;
1634 assert(!mode_is_float(smaller_mode));
1636 sign_suffix = signed_mode ? "s" : "z";
1637 ia32_emitf(node, "\tmov%s%Ml %#AS3, %D0\n", sign_suffix);
1643 static void emit_ia32_Call(const ir_node *node)
1645 /* Special case: Call must not have its immediates prefixed by $, instead
1646 * address mode is prefixed by *. */
1647 ia32_emitf(node, "\tcall %*AS3\n");
1651 /*******************************************
1654 * | |__ ___ _ __ ___ __| | ___ ___
1655 * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
1656 * | |_) | __/ | | | (_) | (_| | __/\__ \
1657 * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
1659 *******************************************/
1662 * Emits code to increase stack pointer.
1664 static void emit_be_IncSP(const ir_node *node)
1666 int offs = be_get_IncSP_offset(node);
1672 ia32_emitf(node, "\tsubl $%u, %D0\n", offs);
1674 ia32_emitf(node, "\taddl $%u, %D0\n", -offs);
1678 static inline bool is_unknown_reg(const arch_register_t *reg)
1680 if(reg == &ia32_gp_regs[REG_GP_UKNWN]
1681 || reg == &ia32_xmm_regs[REG_XMM_UKNWN]
1682 || reg == &ia32_vfp_regs[REG_VFP_UKNWN])
1689 * Emits code for Copy/CopyKeep.
1691 static void Copy_emitter(const ir_node *node, const ir_node *op)
1693 const arch_register_t *in = arch_get_irn_register(op);
1694 const arch_register_t *out = arch_get_irn_register(node);
1699 if (is_unknown_reg(in))
1701 /* copies of vf nodes aren't real... */
1702 if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
1705 if (get_irn_mode(node) == mode_E) {
1706 ia32_emitf(node, "\tmovsd %R, %R\n", in, out);
1708 ia32_emitf(node, "\tmovl %R, %R\n", in, out);
1712 static void emit_be_Copy(const ir_node *node)
1714 Copy_emitter(node, be_get_Copy_op(node));
1717 static void emit_be_CopyKeep(const ir_node *node)
1719 Copy_emitter(node, be_get_CopyKeep_op(node));
1723 * Emits code for exchange.
1725 static void emit_be_Perm(const ir_node *node)
1727 const arch_register_t *in0, *in1;
1728 const arch_register_class_t *cls0, *cls1;
1730 in0 = arch_get_irn_register(get_irn_n(node, 0));
1731 in1 = arch_get_irn_register(get_irn_n(node, 1));
1733 cls0 = arch_register_get_class(in0);
1734 cls1 = arch_register_get_class(in1);
1736 assert(cls0 == cls1 && "Register class mismatch at Perm");
1738 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
1739 ia32_emitf(node, "\txchg %R, %R\n", in1, in0);
1740 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1741 ia32_emitf(NULL, "\txorpd %R, %R\n", in1, in0);
1742 ia32_emitf(NULL, "\txorpd %R, %R\n", in0, in1);
1743 ia32_emitf(node, "\txorpd %R, %R\n", in1, in0);
1744 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
1746 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
1749 panic("unexpected register class in be_Perm (%+F)", node);
1754 * Emits code for Constant loading.
1756 static void emit_ia32_Const(const ir_node *node)
1758 ia32_emitf(node, "\tmovl %I, %D0\n");
1762 * Emits code to load the TLS base
1764 static void emit_ia32_LdTls(const ir_node *node)
1766 ia32_emitf(node, "\tmovl %%gs:0, %D0\n");
1769 /* helper function for emit_ia32_Minus64Bit */
1770 static void emit_mov(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1772 ia32_emitf(node, "\tmovl %R, %R\n", src, dst);
1775 /* helper function for emit_ia32_Minus64Bit */
1776 static void emit_neg(const ir_node* node, const arch_register_t *reg)
1778 ia32_emitf(node, "\tnegl %R\n", reg);
1781 /* helper function for emit_ia32_Minus64Bit */
1782 static void emit_sbb0(const ir_node* node, const arch_register_t *reg)
1784 ia32_emitf(node, "\tsbbl $0, %R\n", reg);
1787 /* helper function for emit_ia32_Minus64Bit */
1788 static void emit_sbb(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1790 ia32_emitf(node, "\tsbbl %R, %R\n", src, dst);
1793 /* helper function for emit_ia32_Minus64Bit */
1794 static void emit_xchg(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1796 ia32_emitf(node, "\txchgl %R, %R\n", src, dst);
1799 /* helper function for emit_ia32_Minus64Bit */
1800 static void emit_zero(const ir_node* node, const arch_register_t *reg)
1802 ia32_emitf(node, "\txorl %R, %R\n", reg, reg);
1805 static void emit_ia32_Minus64Bit(const ir_node *node)
1807 const arch_register_t *in_lo = get_in_reg(node, 0);
1808 const arch_register_t *in_hi = get_in_reg(node, 1);
1809 const arch_register_t *out_lo = get_out_reg(node, 0);
1810 const arch_register_t *out_hi = get_out_reg(node, 1);
1812 if (out_lo == in_lo) {
1813 if (out_hi != in_hi) {
1814 /* a -> a, b -> d */
1817 /* a -> a, b -> b */
1820 } else if (out_lo == in_hi) {
1821 if (out_hi == in_lo) {
1822 /* a -> b, b -> a */
1823 emit_xchg(node, in_lo, in_hi);
1826 /* a -> b, b -> d */
1827 emit_mov(node, in_hi, out_hi);
1828 emit_mov(node, in_lo, out_lo);
1832 if (out_hi == in_lo) {
1833 /* a -> c, b -> a */
1834 emit_mov(node, in_lo, out_lo);
1836 } else if (out_hi == in_hi) {
1837 /* a -> c, b -> b */
1838 emit_mov(node, in_lo, out_lo);
1841 /* a -> c, b -> d */
1842 emit_mov(node, in_lo, out_lo);
1848 emit_neg( node, out_hi);
1849 emit_neg( node, out_lo);
1850 emit_sbb0(node, out_hi);
1854 emit_zero(node, out_hi);
1855 emit_neg( node, out_lo);
1856 emit_sbb( node, in_hi, out_hi);
1859 static void emit_ia32_GetEIP(const ir_node *node)
1861 ia32_emitf(node, "\tcall %s\n", pic_base_label);
1862 ia32_emitf(NULL, "%s:\n", pic_base_label);
1863 ia32_emitf(node, "\tpopl %D0\n");
1866 static void emit_ia32_ClimbFrame(const ir_node *node)
1868 const ia32_climbframe_attr_t *attr = get_ia32_climbframe_attr_const(node);
1870 ia32_emitf(node, "\tmovl %S0, %D0\n");
1871 ia32_emitf(node, "\tmovl $%u, %S1\n", attr->count);
1872 ia32_emitf(NULL, BLOCK_PREFIX "%ld:\n", get_irn_node_nr(node));
1873 ia32_emitf(node, "\tmovl (%D0), %D0\n");
1874 ia32_emitf(node, "\tdec %S1\n");
1875 ia32_emitf(node, "\tjnz " BLOCK_PREFIX "%ld\n", get_irn_node_nr(node));
1878 static void emit_be_Return(const ir_node *node)
1880 unsigned pop = be_Return_get_pop(node);
1882 if (pop > 0 || be_Return_get_emit_pop(node)) {
1883 ia32_emitf(node, "\tret $%u\n", pop);
1885 ia32_emitf(node, "\tret\n");
1889 static void emit_Nothing(const ir_node *node)
1895 /***********************************************************************************
1898 * _ __ ___ __ _ _ _ __ | |_ _ __ __ _ _ __ ___ _____ _____ _ __| | __
1899 * | '_ ` _ \ / _` | | '_ \ | _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
1900 * | | | | | | (_| | | | | | | | | | | (_| | | | | | | __/\ V V / (_) | | | <
1901 * |_| |_| |_|\__,_|_|_| |_| |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
1903 ***********************************************************************************/
1906 * Enters the emitter functions for handled nodes into the generic
1907 * pointer of an opcode.
1909 static void ia32_register_emitters(void)
1911 #define IA32_EMIT2(a,b) op_ia32_##a->ops.generic = (op_func)emit_ia32_##b
1912 #define IA32_EMIT(a) IA32_EMIT2(a,a)
1913 #define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
1914 #define IGN(a) op_##a->ops.generic = (op_func)emit_Nothing
1915 #define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
1916 #define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing
1918 /* first clear the generic function pointer for all ops */
1919 clear_irp_opcodes_generic_func();
1921 /* register all emitter functions defined in spec */
1922 ia32_register_spec_emitters();
1924 /* other ia32 emitter functions */
1925 IA32_EMIT2(Conv_I2I8Bit, Conv_I2I);
1930 IA32_EMIT(Conv_FP2FP);
1931 IA32_EMIT(Conv_FP2I);
1932 IA32_EMIT(Conv_I2FP);
1933 IA32_EMIT(Conv_I2I);
1941 IA32_EMIT(Minus64Bit);
1942 IA32_EMIT(SwitchJmp);
1943 IA32_EMIT(ClimbFrame);
1946 /* benode emitter */
1967 typedef void (*emit_func_ptr) (const ir_node *);
1970 * Assign and emit an exception label if the current instruction can fail.
1972 static void ia32_assign_exc_label(ir_node *node)
1974 /* assign a new ID to the instruction */
1975 set_ia32_exc_label_id(node, ++exc_label_id);
1977 ia32_emit_exc_label(node);
1979 be_emit_pad_comment();
1980 be_emit_cstring("/* exception to Block ");
1981 ia32_emit_cfop_target(node);
1982 be_emit_cstring(" */\n");
1983 be_emit_write_line();
1987 * Emits code for a node.
1989 static void ia32_emit_node(ir_node *node)
1991 ir_op *op = get_irn_op(node);
1993 DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
1995 if (is_ia32_irn(node)) {
1996 if (get_ia32_exc_label(node)) {
1997 /* emit the exception label of this instruction */
1998 ia32_assign_exc_label(node);
2000 if (mark_spill_reload) {
2001 if (is_ia32_is_spill(node)) {
2002 ia32_emitf(NULL, "\txchg %ebx, %ebx /* spill mark */\n");
2004 if (is_ia32_is_reload(node)) {
2005 ia32_emitf(NULL, "\txchg %edx, %edx /* reload mark */\n");
2007 if (is_ia32_is_remat(node)) {
2008 ia32_emitf(NULL, "\txchg %ecx, %ecx /* remat mark */\n");
2012 if (op->ops.generic) {
2013 emit_func_ptr func = (emit_func_ptr) op->ops.generic;
2015 be_dbg_set_dbg_info(get_irn_dbg_info(node));
2020 ir_fprintf(stderr, "Error: No emit handler for node %+F (%+G, graph %+F)\n", node, node, current_ir_graph);
2026 * Emits gas alignment directives
2028 static void ia32_emit_alignment(unsigned align, unsigned skip)
2030 ia32_emitf(NULL, "\t.p2align %u,,%u\n", align, skip);
2034 * Emits gas alignment directives for Labels depended on cpu architecture.
2036 static void ia32_emit_align_label(void)
2038 unsigned align = ia32_cg_config.label_alignment;
2039 unsigned maximum_skip = ia32_cg_config.label_alignment_max_skip;
2040 ia32_emit_alignment(align, maximum_skip);
2044 * Test whether a block should be aligned.
2045 * For cpus in the P4/Athlon class it is useful to align jump labels to
2046 * 16 bytes. However we should only do that if the alignment nops before the
2047 * label aren't executed more often than we have jumps to the label.
2049 static int should_align_block(const ir_node *block)
2051 static const double DELTA = .0001;
2052 ir_exec_freq *exec_freq = cg->birg->exec_freq;
2053 ir_node *prev = get_prev_block_sched(block);
2055 double prev_freq = 0; /**< execfreq of the fallthrough block */
2056 double jmp_freq = 0; /**< execfreq of all non-fallthrough blocks */
2059 if (exec_freq == NULL)
2061 if (ia32_cg_config.label_alignment_factor <= 0)
2064 block_freq = get_block_execfreq(exec_freq, block);
2065 if (block_freq < DELTA)
2068 n_cfgpreds = get_Block_n_cfgpreds(block);
2069 for(i = 0; i < n_cfgpreds; ++i) {
2070 const ir_node *pred = get_Block_cfgpred_block(block, i);
2071 double pred_freq = get_block_execfreq(exec_freq, pred);
2074 prev_freq += pred_freq;
2076 jmp_freq += pred_freq;
2080 if (prev_freq < DELTA && !(jmp_freq < DELTA))
2083 jmp_freq /= prev_freq;
2085 return jmp_freq > ia32_cg_config.label_alignment_factor;
2089 * Emit the block header for a block.
2091 * @param block the block
2092 * @param prev_block the previous block
2094 static void ia32_emit_block_header(ir_node *block)
2096 ir_graph *irg = current_ir_graph;
2097 int need_label = block_needs_label(block);
2099 ir_exec_freq *exec_freq = cg->birg->exec_freq;
2101 if (block == get_irg_end_block(irg))
2104 if (ia32_cg_config.label_alignment > 0) {
2105 /* align the current block if:
2106 * a) if should be aligned due to its execution frequency
2107 * b) there is no fall-through here
2109 if (should_align_block(block)) {
2110 ia32_emit_align_label();
2112 /* if the predecessor block has no fall-through,
2113 we can always align the label. */
2115 int has_fallthrough = 0;
2117 for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
2118 ir_node *cfg_pred = get_Block_cfgpred(block, i);
2119 if (can_be_fallthrough(cfg_pred)) {
2120 has_fallthrough = 1;
2125 if (!has_fallthrough)
2126 ia32_emit_align_label();
2131 ia32_emit_block_name(block);
2134 be_emit_pad_comment();
2135 be_emit_cstring(" /* ");
2137 be_emit_cstring("\t/* ");
2138 ia32_emit_block_name(block);
2139 be_emit_cstring(": ");
2142 be_emit_cstring("preds:");
2144 /* emit list of pred blocks in comment */
2145 arity = get_irn_arity(block);
2147 be_emit_cstring(" none");
2149 for (i = 0; i < arity; ++i) {
2150 ir_node *predblock = get_Block_cfgpred_block(block, i);
2151 be_emit_irprintf(" %d", get_irn_node_nr(predblock));
2154 if (exec_freq != NULL) {
2155 be_emit_irprintf(", freq: %f",
2156 get_block_execfreq(exec_freq, block));
2158 be_emit_cstring(" */\n");
2159 be_emit_write_line();
2163 * Walks over the nodes in a block connected by scheduling edges
2164 * and emits code for each node.
2166 static void ia32_gen_block(ir_node *block)
2170 ia32_emit_block_header(block);
2172 /* emit the contents of the block */
2173 be_dbg_set_dbg_info(get_irn_dbg_info(block));
2174 sched_foreach(block, node) {
2175 ia32_emit_node(node);
2179 typedef struct exc_entry {
2180 ir_node *exc_instr; /** The instruction that can issue an exception. */
2181 ir_node *block; /** The block to call then. */
2186 * Sets labels for control flow nodes (jump target).
2187 * Links control predecessors to there destination blocks.
2189 static void ia32_gen_labels(ir_node *block, void *data)
2191 exc_entry **exc_list = data;
2195 for (n = get_Block_n_cfgpreds(block) - 1; n >= 0; --n) {
2196 pred = get_Block_cfgpred(block, n);
2197 set_irn_link(pred, block);
2199 pred = skip_Proj(pred);
2200 if (is_ia32_irn(pred) && get_ia32_exc_label(pred)) {
2205 ARR_APP1(exc_entry, *exc_list, e);
2206 set_irn_link(pred, block);
2212 * Compare two exception_entries.
2214 static int cmp_exc_entry(const void *a, const void *b)
2216 const exc_entry *ea = a;
2217 const exc_entry *eb = b;
2219 if (get_ia32_exc_label_id(ea->exc_instr) < get_ia32_exc_label_id(eb->exc_instr))
2225 * Main driver. Emits the code for one routine.
2227 void ia32_gen_routine(ia32_code_gen_t *ia32_cg, ir_graph *irg)
2229 ir_entity *entity = get_irg_entity(irg);
2230 exc_entry *exc_list = NEW_ARR_F(exc_entry, 0);
2235 do_pic = cg->birg->main_env->options->pic;
2237 ia32_register_emitters();
2239 get_unique_label(pic_base_label, sizeof(pic_base_label), ".PIC_BASE");
2241 be_dbg_method_begin(entity, be_abi_get_stack_layout(cg->birg->abi));
2242 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment);
2244 /* we use links to point to target blocks */
2245 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
2246 irg_block_walk_graph(irg, ia32_gen_labels, NULL, &exc_list);
2248 /* initialize next block links */
2249 n = ARR_LEN(cg->blk_sched);
2250 for (i = 0; i < n; ++i) {
2251 ir_node *block = cg->blk_sched[i];
2252 ir_node *prev = i > 0 ? cg->blk_sched[i-1] : NULL;
2254 set_irn_link(block, prev);
2257 for (i = 0; i < n; ++i) {
2258 ir_node *block = cg->blk_sched[i];
2260 ia32_gen_block(block);
2263 be_gas_emit_function_epilog(entity);
2264 be_dbg_method_end();
2266 be_emit_write_line();
2268 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
2270 /* Sort the exception table using the exception label id's.
2271 Those are ascending with ascending addresses. */
2272 qsort(exc_list, ARR_LEN(exc_list), sizeof(exc_list[0]), cmp_exc_entry);
2276 for (i = 0; i < ARR_LEN(exc_list); ++i) {
2277 be_emit_cstring("\t.long ");
2278 ia32_emit_exc_label(exc_list[i].exc_instr);
2280 be_emit_cstring("\t.long ");
2281 ia32_emit_block_name(exc_list[i].block);
2285 DEL_ARR_F(exc_list);
2288 static const lc_opt_table_entry_t ia32_emitter_options[] = {
2289 LC_OPT_ENT_BOOL("mark_spill_reload", "mark spills and reloads with ud opcodes", &mark_spill_reload),
2293 /* ==== Experimental binary emitter ==== */
2295 static unsigned char reg_gp_map[N_ia32_gp_REGS];
2296 //static unsigned char reg_mmx_map[N_ia32_mmx_REGS];
2297 //static unsigned char reg_sse_map[N_ia32_xmm_REGS];
2298 static unsigned char pnc_map_signed[8];
2299 static unsigned char pnc_map_unsigned[8];
2301 static void build_reg_map(void)
2303 reg_gp_map[REG_EAX] = 0x0;
2304 reg_gp_map[REG_ECX] = 0x1;
2305 reg_gp_map[REG_EDX] = 0x2;
2306 reg_gp_map[REG_EBX] = 0x3;
2307 reg_gp_map[REG_ESP] = 0x4;
2308 reg_gp_map[REG_EBP] = 0x5;
2309 reg_gp_map[REG_ESI] = 0x6;
2310 reg_gp_map[REG_EDI] = 0x7;
2312 pnc_map_signed[pn_Cmp_Eq] = 0x04;
2313 pnc_map_signed[pn_Cmp_Lt] = 0x0C;
2314 pnc_map_signed[pn_Cmp_Le] = 0x0E;
2315 pnc_map_signed[pn_Cmp_Gt] = 0x0F;
2316 pnc_map_signed[pn_Cmp_Ge] = 0x0D;
2317 pnc_map_signed[pn_Cmp_Lg] = 0x05;
2319 pnc_map_unsigned[pn_Cmp_Eq] = 0x04;
2320 pnc_map_unsigned[pn_Cmp_Lt] = 0x02;
2321 pnc_map_unsigned[pn_Cmp_Le] = 0x06;
2322 pnc_map_unsigned[pn_Cmp_Gt] = 0x07;
2323 pnc_map_unsigned[pn_Cmp_Ge] = 0x03;
2324 pnc_map_unsigned[pn_Cmp_Lg] = 0x05;
2327 static unsigned char pnc2cc(int pnc)
2330 if (pnc == ia32_pn_Cmp_parity) {
2332 } else if (pnc & ia32_pn_Cmp_float || pnc & ia32_pn_Cmp_unsigned) {
2333 cc = pnc_map_unsigned[pnc & 0x07];
2335 cc = pnc_map_signed[pnc & 0x07];
2341 /** Sign extension bit values for binops */
2343 UNSIGNED_IMM = 0, /**< unsigned immediate */
2344 SIGNEXT_IMM = 2, /**< sign extended immediate */
2347 /** The mod encoding of the ModR/M */
2349 MOD_IND = 0x00, /**< [reg1] */
2350 MOD_IND_BYTE_OFS = 0x40, /**< [reg1 + byte ofs] */
2351 MOD_IND_WORD_OFS = 0x80, /**< [reg1 + word ofs] */
2352 MOD_REG = 0xC0 /**< reg1 */
2355 /** create R/M encoding for ModR/M */
2356 #define ENC_RM(x) (x)
2357 /** create REG encoding for ModR/M */
2358 #define ENC_REG(x) ((x) << 3)
2360 /** create encoding for a SIB byte */
2361 #define ENC_SIB(scale, index, base) ((scale) << 6 | (index) << 3 | (base))
2363 /* Node: The following routines are supposed to append bytes, words, dwords
2364 to the output stream.
2365 Currently the implementation is stupid in that it still creates output
2366 for an "assembler" in the form of .byte, .long
2367 We will change this when enough infrastructure is there to create complete
2368 machine code in memory/object files */
2370 static void bemit8(const unsigned char byte)
2372 be_emit_irprintf("\t.byte 0x%x\n", byte);
2373 be_emit_write_line();
2376 static void bemit16(const unsigned short u16)
2378 be_emit_irprintf("\t.word 0x%x\n", u16);
2379 be_emit_write_line();
2382 static void bemit32(const unsigned u32)
2384 be_emit_irprintf("\t.long 0x%x\n", u32);
2385 be_emit_write_line();
2389 * Emit address of an entity. If @p is_relative is true then a relative
2390 * offset from behind the address to the entity is created.
2392 static void bemit_entity(ir_entity *entity, bool entity_sign, int offset,
2395 if (entity == NULL) {
2400 /* the final version should remember the position in the bytestream
2401 and patch it with the correct address at linktime... */
2402 be_emit_cstring("\t.long ");
2405 set_entity_backend_marked(entity, 1);
2406 be_gas_emit_entity(entity);
2408 if (get_entity_owner(entity) == get_tls_type()) {
2409 if (get_entity_visibility(entity) == visibility_external_allocated) {
2410 be_emit_cstring("@INDNTPOFF");
2412 be_emit_cstring("@NTPOFF");
2417 be_emit_cstring("-.");
2422 be_emit_irprintf("%+d", offset);
2425 be_emit_write_line();
2428 static void bemit_jmp_destination(const ir_node *dest_block)
2430 be_emit_cstring("\t.long ");
2431 ia32_emit_block_name(dest_block);
2432 be_emit_cstring(" - . - 4\n");
2433 be_emit_write_line();
2436 /* end emit routines, all emitters following here should only use the functions
2439 /** Create a ModR/M byte for src1,src2 registers */
2440 static void bemit_modrr(const arch_register_t *src1,
2441 const arch_register_t *src2)
2443 unsigned char modrm = MOD_REG;
2444 modrm |= ENC_RM(reg_gp_map[src1->index]);
2445 modrm |= ENC_REG(reg_gp_map[src2->index]);
2449 /** Create a ModR/M byte for one register and extension */
2450 static void bemit_modru(const arch_register_t *reg, unsigned ext)
2452 unsigned char modrm = MOD_REG;
2454 modrm |= ENC_RM(reg_gp_map[reg->index]);
2455 modrm |= ENC_REG(ext);
2460 * Calculate the size of an signed immediate in bytes.
2462 * @param offset an offset
2464 static unsigned get_signed_imm_size(int offset)
2466 if (-128 <= offset && offset < 128) {
2468 } else if (-32768 <= offset && offset < 32768) {
2476 * Emit an address mode.
2478 * @param reg content of the reg field: either a register index or an opcode extension
2479 * @param node the node
2481 static void bemit_mod_am(unsigned reg, const ir_node *node)
2483 ir_entity *ent = get_ia32_am_sc(node);
2484 int offs = get_ia32_am_offs_int(node);
2485 ir_node *base = get_irn_n(node, n_ia32_base);
2486 int has_base = !is_ia32_NoReg_GP(base);
2487 ir_node *index = get_irn_n(node, n_ia32_index);
2488 int has_index = !is_ia32_NoReg_GP(index);
2491 unsigned emitoffs = 0;
2492 bool emitsib = false;
2495 /* set the mod part depending on displacement */
2497 modrm |= MOD_IND_WORD_OFS;
2499 } else if (offs == 0) {
2502 } else if (-128 <= offs && offs < 128) {
2503 modrm |= MOD_IND_BYTE_OFS;
2506 modrm |= MOD_IND_WORD_OFS;
2511 const arch_register_t *base_reg = arch_get_irn_register(base);
2512 base_enc = reg_gp_map[base_reg->index];
2514 /* Use the EBP encoding + MOD_IND if NO base register. There is
2515 * always a 32bit offset present in this case. */
2521 /* Determine if we need a SIB byte. */
2523 const arch_register_t *reg_index = arch_get_irn_register(index);
2524 int scale = get_ia32_am_scale(node);
2526 /* R/M set to ESP means SIB in 32bit mode. */
2527 modrm |= ENC_RM(0x04);
2528 sib = ENC_SIB(scale, reg_gp_map[reg_index->index], base_enc);
2530 } else if (base_enc == 0x04) {
2531 /* for the above reason we are forced to emit a SIB when base is ESP.
2532 * Only the base is used, index must be ESP too, which means no index.
2534 modrm |= ENC_RM(0x04);
2535 sib = ENC_SIB(0, 0x04, 0x04);
2538 modrm |= ENC_RM(base_enc);
2541 /* We are forced to emit an 8bit offset as EBP base without offset is a
2542 * special case for SIB without base register. */
2543 if (base_enc == 0x05 && emitoffs == 0) {
2544 modrm |= MOD_IND_BYTE_OFS;
2548 modrm |= ENC_REG(reg);
2554 /* emit displacement */
2555 if (emitoffs == 8) {
2556 bemit8((unsigned) offs);
2557 } else if (emitoffs == 32) {
2558 bemit_entity(ent, is_ia32_am_sc_sign(node), offs, false);
2563 * Emit a binop with a immediate operand.
2565 * @param node the node to emit
2566 * @param opcode_eax the opcode for the op eax, imm variant
2567 * @param opcode the opcode for the reg, imm variant
2568 * @param ruval the opcode extension for opcode
2570 static void bemit_binop_with_imm(
2571 const ir_node *node,
2572 unsigned char opcode_ax,
2573 unsigned char opcode, unsigned char ruval)
2575 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2576 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2577 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2580 /* Some instructions (test) have no short form with 32bit value + 8bit
2582 if (attr->symconst != NULL || opcode & SIGNEXT_IMM) {
2585 /* check for sign extension */
2586 size = get_signed_imm_size(attr->offset);
2591 bemit8(opcode | SIGNEXT_IMM);
2592 /* cmp has this special mode */
2593 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2594 bemit_mod_am(ruval, node);
2596 const arch_register_t *reg = get_in_reg(node, n_ia32_binary_left);
2597 bemit_modru(reg, ruval);
2599 bemit8((unsigned char)attr->offset);
2603 /* check for eax variant: this variant is shorter for 32bit immediates only */
2604 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2606 bemit_mod_am(ruval, node);
2608 const arch_register_t *reg = get_in_reg(node, n_ia32_binary_left);
2609 if (reg->index == REG_EAX) {
2613 bemit_modru(reg, ruval);
2616 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2619 panic("invalid imm size?!?");
2625 static void bemit_binop_2(const ir_node *node, unsigned code)
2627 const arch_register_t *out = get_in_reg(node, n_ia32_binary_left);
2629 if (get_ia32_op_type(node) == ia32_Normal) {
2630 const arch_register_t *op2 = get_in_reg(node, n_ia32_binary_right);
2631 bemit_modrr(op2, out);
2633 bemit_mod_am(reg_gp_map[out->index], node);
2640 static void bemit_binop(const ir_node *node, const unsigned char opcodes[4])
2642 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2643 if (is_ia32_Immediate(right)) {
2644 bemit_binop_with_imm(node, opcodes[1], opcodes[2], opcodes[3]);
2646 bemit_binop_2(node, opcodes[0]);
2653 static void bemit_unop(const ir_node *node, unsigned char code, unsigned char ext, int input)
2656 if (get_ia32_op_type(node) == ia32_Normal) {
2657 const arch_register_t *in = get_in_reg(node, input);
2658 bemit_modru(in, ext);
2660 bemit_mod_am(ext, node);
2664 static void bemit_unop_reg(const ir_node *node, unsigned char code, int input)
2666 const arch_register_t *out = get_out_reg(node, 0);
2667 bemit_unop(node, code, reg_gp_map[out->index], input);
2670 static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned char ext)
2672 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2675 bemit8(size == 8 ? code : code + 1);
2676 bemit_mod_am(ext, node);
2679 static void bemit_immediate(const ir_node *node, bool relative)
2681 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
2682 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, relative);
2685 static void bemit_copy(const ir_node *copy)
2687 const arch_register_t *in = get_in_reg(copy, 0);
2688 const arch_register_t *out = get_out_reg(copy, 0);
2690 if (in == out || is_unknown_reg(in))
2692 /* copies of vf nodes aren't real... */
2693 if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
2696 if (get_irn_mode(copy) == mode_E) {
2699 assert(arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_gp]);
2701 bemit_modrr(in, out);
2705 static void bemit_perm(const ir_node *node)
2707 const arch_register_t *in0 = arch_get_irn_register(get_irn_n(node, 0));
2708 const arch_register_t *in1 = arch_get_irn_register(get_irn_n(node, 1));
2709 const arch_register_class_t *cls0 = arch_register_get_class(in0);
2711 assert(cls0 == arch_register_get_class(in1) && "Register class mismatch at Perm");
2713 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
2714 if (in0->index == REG_EAX) {
2715 bemit8(0x90 + reg_gp_map[in1->index]);
2716 } else if (in1->index == REG_EAX) {
2717 bemit8(0x90 + reg_gp_map[in0->index]);
2720 bemit_modrr(in0, in1);
2722 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
2723 panic("unimplemented"); // TODO implement
2724 //ia32_emitf(NULL, "\txorpd %R, %R\n", in1, in0);
2725 //ia32_emitf(NULL, "\txorpd %R, %R\n", in0, in1);
2726 //ia32_emitf(node, "\txorpd %R, %R\n", in1, in0);
2727 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
2729 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
2732 panic("unexpected register class in be_Perm (%+F)", node);
2736 static void bemit_xor0(const ir_node *node)
2738 const arch_register_t *out = get_out_reg(node, 0);
2740 bemit_modrr(out, out);
2743 static void bemit_mov_const(const ir_node *node)
2745 const arch_register_t *out = get_out_reg(node, 0);
2746 bemit8(0xB8 + reg_gp_map[out->index]);
2747 bemit_immediate(node, false);
2751 * Creates a function for a Binop with 3 possible encodings.
2753 #define BINOP(op, op0, op1, op2, op2_ext) \
2754 static void bemit_ ## op(const ir_node *node) { \
2755 static const unsigned char op ## _codes[] = {op0, op1, op2, op2_ext}; \
2756 bemit_binop(node, op ## _codes); \
2759 /* insn def eax,imm imm */
2760 BINOP(add, 0x03, 0x05, 0x81, 0)
2761 BINOP(or, 0x0B, 0x0D, 0x81, 1)
2762 BINOP(adc, 0x13, 0x15, 0x81, 2)
2763 BINOP(sbb, 0x1B, 0x1D, 0x81, 3)
2764 BINOP(and, 0x23, 0x25, 0x81, 4)
2765 BINOP(sub, 0x2B, 0x2D, 0x81, 5)
2766 BINOP(xor, 0x33, 0x35, 0x81, 6)
2767 BINOP(test, 0x85, 0xA9, 0xF7, 0)
2769 #define BINOPMEM(op, ext) \
2770 static void bemit_##op(const ir_node *node) \
2773 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2776 val = get_irn_n(node, n_ia32_unary_op); \
2777 if (is_ia32_Immediate(val)) { \
2778 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(val); \
2779 int offset = attr->offset; \
2780 if (attr->symconst == NULL && get_signed_imm_size(offset) == 1) { \
2782 bemit_mod_am(ext, node); \
2786 bemit_mod_am(ext, node); \
2790 bemit_entity(attr->symconst, attr->sc_sign, offset, false); \
2794 bemit8(ext << 3 | 1); \
2795 bemit_mod_am(reg_gp_map[get_out_reg(val, 0)->index], node); \
2799 static void bemit_##op##8bit(const ir_node *node) \
2801 ir_node *val = get_irn_n(node, n_ia32_unary_op); \
2802 if (is_ia32_Immediate(val)) { \
2804 bemit_mod_am(ext, node); \
2805 bemit8(get_ia32_immediate_attr_const(val)->offset); \
2808 bemit_mod_am(reg_gp_map[get_out_reg(val, 0)->index], node); \
2820 * Creates a function for an Unop with code /ext encoding.
2822 #define UNOP(op, code, ext, input) \
2823 static void bemit_ ## op(const ir_node *node) { \
2824 bemit_unop(node, code, ext, input); \
2827 UNOP(not, 0xF7, 2, n_ia32_Not_val)
2828 UNOP(neg, 0xF7, 3, n_ia32_Neg_val)
2829 UNOP(mul, 0xF7, 4, n_ia32_Mul_right)
2830 UNOP(imul1op, 0xF7, 5, n_ia32_IMul1OP_right)
2831 UNOP(div, 0xF7, 6, n_ia32_Div_divisor)
2832 UNOP(idiv, 0xF7, 7, n_ia32_IDiv_divisor)
2834 /* TODO: am support for IJmp */
2835 UNOP(ijmp, 0xFF, 4, n_ia32_IJmp_target)
2837 #define SHIFT(op, ext) \
2838 static void bemit_##op(const ir_node *node) \
2840 const arch_register_t *out = get_out_reg(node, 0); \
2841 ir_node *count = get_irn_n(node, 1); \
2842 if (is_ia32_Immediate(count)) { \
2843 int offset = get_ia32_immediate_attr_const(count)->offset; \
2844 if (offset == 1) { \
2846 bemit_modru(out, ext); \
2849 bemit_modru(out, ext); \
2854 bemit_modru(out, ext); \
2858 static void bemit_##op##mem(const ir_node *node) \
2861 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2864 count = get_irn_n(node, 1); \
2865 if (is_ia32_Immediate(count)) { \
2866 int offset = get_ia32_immediate_attr_const(count)->offset; \
2867 if (offset == 1) { \
2868 bemit8(size == 8 ? 0xD0 : 0xD1); \
2869 bemit_mod_am(ext, node); \
2871 bemit8(size == 8 ? 0xC0 : 0xC1); \
2872 bemit_mod_am(ext, node); \
2876 bemit8(size == 8 ? 0xD2 : 0xD3); \
2877 bemit_mod_am(ext, node); \
2887 static void bemit_shld(const ir_node *node)
2889 const arch_register_t *in = get_in_reg(node, n_ia32_ShlD_val_low);
2890 const arch_register_t *out = get_out_reg(node, pn_ia32_ShlD_res);
2891 ir_node *count = get_irn_n(node, n_ia32_ShlD_count);
2893 if (is_ia32_Immediate(count)) {
2895 bemit_modrr(out, in);
2896 bemit8(get_ia32_immediate_attr_const(count)->offset);
2899 bemit_modrr(out, in);
2903 static void bemit_shrd(const ir_node *node)
2905 const arch_register_t *in = get_in_reg(node, n_ia32_ShrD_val_low);
2906 const arch_register_t *out = get_out_reg(node, pn_ia32_ShrD_res);
2907 ir_node *count = get_irn_n(node, n_ia32_ShrD_count);
2909 if (is_ia32_Immediate(count)) {
2911 bemit_modrr(out, in);
2912 bemit8(get_ia32_immediate_attr_const(count)->offset);
2915 bemit_modrr(out, in);
2919 static void bemit_cmovcc(const ir_node *node)
2921 const ia32_attr_t *attr = get_ia32_attr_const(node);
2922 int ins_permuted = attr->data.ins_permuted;
2923 const arch_register_t *out = arch_irn_get_register(node, pn_ia32_res);
2924 pn_Cmp pnc = get_ia32_condcode(node);
2925 const arch_register_t *in_true;
2926 const arch_register_t *in_false;
2928 pnc = determine_final_pnc(node, n_ia32_CMovcc_eflags, pnc);
2930 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
2931 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
2933 /* should be same constraint fullfilled? */
2934 if (out == in_false) {
2935 /* yes -> nothing to do */
2936 } else if (out == in_true) {
2937 assert(get_ia32_op_type(node) == ia32_Normal);
2938 ins_permuted = !ins_permuted;
2942 bemit8(0x8B); // mov %in_false, %out
2943 bemit_modrr(in_false, out);
2947 pnc = ia32_get_negated_pnc(pnc);
2949 /* TODO: handling of Nans isn't correct yet */
2952 bemit8(0x40 + pnc2cc(pnc));
2953 if (get_ia32_op_type(node) == ia32_Normal) {
2954 bemit_modrr(in_true, out);
2956 bemit_mod_am(reg_gp_map[out->index], node);
2960 static void bemit_cmp(const ir_node *node)
2962 unsigned ls_size = get_mode_size_bits(get_ia32_ls_mode(node));
2968 right = get_irn_n(node, n_ia32_binary_right);
2969 if (is_ia32_Immediate(right)) {
2970 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2971 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2972 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2975 if (attr->symconst != NULL) {
2978 /* check for sign extension */
2979 size = get_signed_imm_size(attr->offset);
2984 bemit8(0x81 | SIGNEXT_IMM);
2985 /* cmp has this special mode */
2986 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2987 bemit_mod_am(7, node);
2989 const arch_register_t *reg = get_in_reg(node, n_ia32_binary_left);
2990 bemit_modru(reg, 7);
2992 bemit8((unsigned char)attr->offset);
2996 /* check for eax variant: this variant is shorter for 32bit immediates only */
2997 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2999 bemit_mod_am(7, node);
3001 const arch_register_t *reg = get_in_reg(node, n_ia32_binary_left);
3002 if (reg->index == REG_EAX) {
3006 bemit_modru(reg, 7);
3009 if (ls_size == 16) {
3010 bemit16(attr->offset);
3012 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
3016 panic("invalid imm size?!?");
3018 const arch_register_t *out = get_in_reg(node, n_ia32_binary_left);
3020 if (get_ia32_op_type(node) == ia32_Normal) {
3021 const arch_register_t *op2 = get_in_reg(node, n_ia32_binary_right);
3022 bemit_modrr(op2, out);
3024 bemit_mod_am(reg_gp_map[out->index], node);
3029 static void bemit_cmp8bit(const ir_node *node)
3031 ir_node *right = get_irn_n(node, n_ia32_binary_right);
3032 if (is_ia32_Immediate(right)) {
3033 if (get_ia32_op_type(node) == ia32_Normal) {
3034 const arch_register_t *out = get_in_reg(node, n_ia32_Cmp_left);
3035 if (out->index == REG_EAX) {
3039 bemit_modru(out, 7);
3043 bemit_mod_am(7, node);
3045 bemit8(get_ia32_immediate_attr_const(right)->offset);
3047 const arch_register_t *out = get_in_reg(node, n_ia32_Cmp_left);
3049 if (get_ia32_op_type(node) == ia32_Normal) {
3050 const arch_register_t *in = get_in_reg(node, n_ia32_Cmp_right);
3051 bemit_modrr(out, in);
3053 bemit_mod_am(reg_gp_map[out->index], node);
3058 static void bemit_test8bit(const ir_node *node)
3060 ir_node *right = get_irn_n(node, n_ia32_Test8Bit_right);
3061 if (is_ia32_Immediate(right)) {
3062 if (get_ia32_op_type(node) == ia32_Normal) {
3063 const arch_register_t *out = get_in_reg(node, n_ia32_Test8Bit_left);
3064 if (out->index == REG_EAX) {
3068 bemit_modru(out, 0);
3072 bemit_mod_am(0, node);
3074 bemit8(get_ia32_immediate_attr_const(right)->offset);
3076 const arch_register_t *out = get_in_reg(node, n_ia32_Test8Bit_left);
3078 if (get_ia32_op_type(node) == ia32_Normal) {
3079 const arch_register_t *in = get_in_reg(node, n_ia32_Test8Bit_right);
3080 bemit_modrr(out, in);
3082 bemit_mod_am(reg_gp_map[out->index], node);
3087 static void bemit_imul(const ir_node *node)
3089 ir_node *right = get_irn_n(node, n_ia32_IMul_right);
3090 /* Do we need the immediate form? */
3091 if (is_ia32_Immediate(right)) {
3092 int imm = get_ia32_immediate_attr_const(right)->offset;
3093 if (get_signed_imm_size(imm) == 1) {
3094 bemit_unop_reg(node, 0x6B, n_ia32_IMul_left);
3097 bemit_unop_reg(node, 0x69, n_ia32_IMul_left);
3102 bemit_unop_reg(node, 0xAF, n_ia32_IMul_right);
3106 static void bemit_dec(const ir_node *node)
3108 const arch_register_t *out = get_out_reg(node, pn_ia32_Dec_res);
3109 bemit8(0x48 + reg_gp_map[out->index]);
3112 static void bemit_inc(const ir_node *node)
3114 const arch_register_t *out = get_out_reg(node, pn_ia32_Inc_res);
3115 bemit8(0x40 + reg_gp_map[out->index]);
3118 #define UNOPMEM(op, code, ext) \
3119 static void bemit_##op(const ir_node *node) \
3121 bemit_unop_mem(node, code, ext); \
3124 UNOPMEM(notmem, 0xF6, 2)
3125 UNOPMEM(negmem, 0xF6, 3)
3126 UNOPMEM(incmem, 0xFE, 0)
3127 UNOPMEM(decmem, 0xFE, 1)
3129 static void bemit_setcc(const ir_node *node)
3135 pnc = get_ia32_condcode(node);
3136 pnc = determine_final_pnc(node, n_ia32_Setcc_eflags, pnc);
3138 /* TODO: all the special casing for float compares is missing */
3139 if (pnc & ia32_pn_Cmp_float)
3140 panic("binary setcc from float compare not implemented yet");
3142 bemit8(0x90 + pnc2cc(pnc));
3143 bemit_modru(get_out_reg(node, pn_ia32_Setcc_res), 2);
3146 static void bemit_ldtls(const ir_node *node)
3148 const arch_register_t *out = get_out_reg(node, 0);
3150 bemit8(0x65); // gs:
3151 if (out->index == REG_EAX) {
3152 bemit8(0xA1); // movl 0, %eax
3154 bemit8(0x8B); // movl 0, %reg
3155 bemit8(MOD_IND | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x05));
3163 static void bemit_lea(const ir_node *node)
3165 const arch_register_t *out = get_out_reg(node, 0);
3167 bemit_mod_am(reg_gp_map[out->index], node);
3170 /* helper function for bemit_minus64bit */
3171 static void bemit_helper_mov(const arch_register_t *src, const arch_register_t *dst)
3173 bemit8(0x8B); // movl %src, %dst
3174 bemit_modrr(src, dst);
3177 /* helper function for bemit_minus64bit */
3178 static void bemit_helper_neg(const arch_register_t *reg)
3180 bemit8(0xF7); // negl %reg
3181 bemit_modru(reg, 3);
3184 /* helper function for bemit_minus64bit */
3185 static void bemit_helper_sbb0(const arch_register_t *reg)
3187 bemit8(0x83); // sbbl $0, %reg
3188 bemit_modru(reg, 3);
3192 /* helper function for bemit_minus64bit */
3193 static void bemit_helper_sbb(const arch_register_t *src, const arch_register_t *dst)
3195 bemit8(0x1B); // sbbl %src, %dst
3196 bemit_modrr(src, dst);
3199 /* helper function for bemit_minus64bit */
3200 static void bemit_helper_xchg(const arch_register_t *src, const arch_register_t *dst)
3202 if (src->index == REG_EAX) {
3203 bemit8(0x90 + reg_gp_map[dst->index]); // xchgl %eax, %dst
3204 } else if (dst->index == REG_EAX) {
3205 bemit8(0x90 + reg_gp_map[src->index]); // xchgl %src, %eax
3207 bemit8(0x87); // xchgl %src, %dst
3208 bemit_modrr(src, dst);
3212 /* helper function for bemit_minus64bit */
3213 static void bemit_helper_zero(const arch_register_t *reg)
3215 bemit8(0x33); // xorl %reg, %reg
3216 bemit_modrr(reg, reg);
3219 static void bemit_minus64bit(const ir_node *node)
3221 const arch_register_t *in_lo = get_in_reg(node, 0);
3222 const arch_register_t *in_hi = get_in_reg(node, 1);
3223 const arch_register_t *out_lo = get_out_reg(node, 0);
3224 const arch_register_t *out_hi = get_out_reg(node, 1);
3226 if (out_lo == in_lo) {
3227 if (out_hi != in_hi) {
3228 /* a -> a, b -> d */
3231 /* a -> a, b -> b */
3234 } else if (out_lo == in_hi) {
3235 if (out_hi == in_lo) {
3236 /* a -> b, b -> a */
3237 bemit_helper_xchg(in_lo, in_hi);
3240 /* a -> b, b -> d */
3241 bemit_helper_mov(in_hi, out_hi);
3242 bemit_helper_mov(in_lo, out_lo);
3246 if (out_hi == in_lo) {
3247 /* a -> c, b -> a */
3248 bemit_helper_mov(in_lo, out_lo);
3250 } else if (out_hi == in_hi) {
3251 /* a -> c, b -> b */
3252 bemit_helper_mov(in_lo, out_lo);
3255 /* a -> c, b -> d */
3256 bemit_helper_mov(in_lo, out_lo);
3262 bemit_helper_neg( out_hi);
3263 bemit_helper_neg( out_lo);
3264 bemit_helper_sbb0(out_hi);
3268 bemit_helper_zero(out_hi);
3269 bemit_helper_neg( out_lo);
3270 bemit_helper_sbb( in_hi, out_hi);
3274 * Emit a single opcode.
3276 #define EMIT_SINGLEOP(op, code) \
3277 static void bemit_ ## op(const ir_node *node) { \
3282 //EMIT_SINGLEOP(daa, 0x27)
3283 //EMIT_SINGLEOP(das, 0x2F)
3284 //EMIT_SINGLEOP(aaa, 0x37)
3285 //EMIT_SINGLEOP(aas, 0x3F)
3286 //EMIT_SINGLEOP(nop, 0x90)
3287 EMIT_SINGLEOP(cwtl, 0x98)
3288 EMIT_SINGLEOP(cltd, 0x99)
3289 //EMIT_SINGLEOP(fwait, 0x9B)
3290 EMIT_SINGLEOP(sahf, 0x9E)
3291 //EMIT_SINGLEOP(popf, 0x9D)
3292 EMIT_SINGLEOP(leave, 0xC9)
3293 EMIT_SINGLEOP(int3, 0xCC)
3294 //EMIT_SINGLEOP(iret, 0xCF)
3295 //EMIT_SINGLEOP(xlat, 0xD7)
3296 //EMIT_SINGLEOP(lock, 0xF0)
3297 EMIT_SINGLEOP(rep, 0xF3)
3298 //EMIT_SINGLEOP(halt, 0xF4)
3299 EMIT_SINGLEOP(cmc, 0xF5)
3300 EMIT_SINGLEOP(stc, 0xF9)
3301 //EMIT_SINGLEOP(cli, 0xFA)
3302 //EMIT_SINGLEOP(sti, 0xFB)
3303 //EMIT_SINGLEOP(std, 0xFD)
3306 * Emits a MOV out, [MEM].
3308 static void bemit_load(const ir_node *node)
3310 const arch_register_t *out = get_out_reg(node, 0);
3312 if (out->index == REG_EAX) {
3313 ir_node *base = get_irn_n(node, n_ia32_base);
3314 int has_base = !is_ia32_NoReg_GP(base);
3315 ir_node *index = get_irn_n(node, n_ia32_index);
3316 int has_index = !is_ia32_NoReg_GP(index);
3317 if (!has_base && !has_index) {
3318 ir_entity *ent = get_ia32_am_sc(node);
3319 int offs = get_ia32_am_offs_int(node);
3320 /* load from constant address to EAX can be encoded
3323 bemit_entity(ent, 0, offs, false);
3328 bemit_mod_am(reg_gp_map[out->index], node);
3332 * Emits a MOV [mem], in.
3334 static void bemit_store(const ir_node *node)
3336 const ir_node *value = get_irn_n(node, n_ia32_Store_val);
3337 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
3339 if (is_ia32_Immediate(value)) {
3342 bemit_mod_am(0, node);
3343 bemit8(get_ia32_immediate_attr_const(value)->offset);
3344 } else if (size == 16) {
3347 bemit_mod_am(0, node);
3348 bemit16(get_ia32_immediate_attr_const(value)->offset);
3351 bemit_mod_am(0, node);
3352 bemit_immediate(value, false);
3355 const arch_register_t *in = get_in_reg(node, n_ia32_Store_val);
3357 if (in->index == REG_EAX) {
3358 ir_node *base = get_irn_n(node, n_ia32_base);
3359 int has_base = !is_ia32_NoReg_GP(base);
3360 ir_node *index = get_irn_n(node, n_ia32_index);
3361 int has_index = !is_ia32_NoReg_GP(index);
3362 if (!has_base && !has_index) {
3363 ir_entity *ent = get_ia32_am_sc(node);
3364 int offs = get_ia32_am_offs_int(node);
3365 /* store to constant address from EAX can be encoded as
3366 * 0xA2/0xA3 [offset]*/
3374 bemit_entity(ent, 0, offs, false);
3386 bemit_mod_am(reg_gp_map[in->index], node);
3390 static void bemit_conv_i2i(const ir_node *node)
3392 ir_mode *smaller_mode = get_ia32_ls_mode(node);
3401 if (mode_is_signed(smaller_mode)) opcode |= 0x08;
3402 if (get_mode_size_bits(smaller_mode) == 16) opcode |= 0x01;
3403 bemit_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
3409 static void bemit_push(const ir_node *node)
3411 const ir_node *value = get_irn_n(node, n_ia32_Push_val);
3413 if (is_ia32_Immediate(value)) {
3414 const ia32_immediate_attr_t *attr
3415 = get_ia32_immediate_attr_const(value);
3416 unsigned size = get_signed_imm_size(attr->offset);
3422 bemit8((unsigned char)attr->offset);
3427 bemit_immediate(value, false);
3430 } else if (is_ia32_NoReg_GP(value)) {
3432 bemit_mod_am(6, node);
3434 const arch_register_t *reg = get_in_reg(node, n_ia32_Push_val);
3435 bemit8(0x50 + reg_gp_map[reg->index]);
3442 static void bemit_pop(const ir_node *node)
3444 const arch_register_t *reg = get_out_reg(node, pn_ia32_Pop_res);
3445 bemit8(0x58 + reg_gp_map[reg->index]);
3448 static void bemit_popmem(const ir_node *node)
3451 bemit_mod_am(0, node);
3454 static void bemit_call(const ir_node *node)
3456 ir_node *proc = get_irn_n(node, n_ia32_Call_addr);
3458 if (is_ia32_Immediate(proc)) {
3460 bemit_immediate(proc, true);
3462 bemit_unop(node, 0xFF, 2, n_ia32_Call_addr);
3466 static void bemit_jmp(const ir_node *dest_block)
3469 bemit_jmp_destination(dest_block);
3472 static void bemit_jump(const ir_node *node)
3474 if (can_be_fallthrough(node))
3477 bemit_jmp(get_cfop_target_block(node));
3480 static void bemit_jcc(int pnc, const ir_node *dest_block)
3482 unsigned char cc = pnc2cc(pnc);
3485 bemit_jmp_destination(dest_block);
3488 static void bemit_jp(bool odd, const ir_node *dest_block)
3492 bemit_jmp_destination(dest_block);
3495 static void bemit_ia32_jcc(const ir_node *node)
3497 int pnc = get_ia32_condcode(node);
3498 const ir_node *proj_true;
3499 const ir_node *proj_false;
3500 const ir_node *dest_true;
3501 const ir_node *dest_false;
3502 const ir_node *block;
3504 pnc = determine_final_pnc(node, 0, pnc);
3506 /* get both Projs */
3507 proj_true = get_proj(node, pn_ia32_Jcc_true);
3508 assert(proj_true && "Jcc without true Proj");
3510 proj_false = get_proj(node, pn_ia32_Jcc_false);
3511 assert(proj_false && "Jcc without false Proj");
3513 block = get_nodes_block(node);
3515 if (can_be_fallthrough(proj_true)) {
3516 /* exchange both proj's so the second one can be omitted */
3517 const ir_node *t = proj_true;
3519 proj_true = proj_false;
3521 pnc = ia32_get_negated_pnc(pnc);
3524 dest_true = get_cfop_target_block(proj_true);
3525 dest_false = get_cfop_target_block(proj_false);
3527 if (pnc & ia32_pn_Cmp_float) {
3528 /* Some floating point comparisons require a test of the parity flag,
3529 * which indicates that the result is unordered */
3532 bemit_jp(false, dest_true);
3537 bemit_jp(true, dest_true);
3543 /* we need a local label if the false proj is a fallthrough
3544 * as the falseblock might have no label emitted then */
3545 if (can_be_fallthrough(proj_false)) {
3547 bemit8(0x06); // jp + 6
3549 bemit_jp(false, dest_false);
3556 bemit_jp(false, dest_true);
3564 bemit_jcc(pnc, dest_true);
3567 /* the second Proj might be a fallthrough */
3568 if (can_be_fallthrough(proj_false)) {
3569 /* it's a fallthrough */
3571 bemit_jmp(dest_false);
3575 static void bemit_switchjmp(const ir_node *node)
3577 unsigned long interval;
3581 const arch_register_t *in;
3583 /* fill the table structure */
3584 generate_jump_table(&tbl, node);
3586 /* two-complement's magic make this work without overflow */
3587 interval = tbl.max_value - tbl.min_value;
3589 in = get_in_reg(node, 0);
3590 /* emit the table */
3591 if (get_signed_imm_size(interval) == 1) {
3592 bemit8(0x83); // cmpl $imm8, %in
3596 bemit8(0x81); // cmpl $imm32, %in
3600 bemit8(0x0F); // ja tbl.defProj
3602 ia32_emitf(tbl.defProj, ".long %L - . - 4\n");
3604 if (tbl.num_branches > 1) {
3606 bemit8(0xFF); // jmp *tbl.label(,%in,4)
3607 bemit8(MOD_IND | ENC_REG(4) | ENC_RM(0x04));
3608 bemit8(ENC_SIB(2, reg_gp_map[in->index], 0x05));
3609 be_emit_irprintf("\t.long %s\n", tbl.label);
3611 be_gas_emit_switch_section(GAS_SECTION_RODATA);
3612 be_emit_cstring(".align 4\n");
3613 be_emit_irprintf("%s:\n", tbl.label);
3615 last_value = tbl.branches[0].value;
3616 for (i = 0; i != tbl.num_branches; ++i) {
3617 while (last_value != tbl.branches[i].value) {
3618 ia32_emitf(tbl.defProj, ".long %L\n");
3621 ia32_emitf(tbl.branches[i].target, ".long %L\n");
3624 be_gas_emit_switch_section(GAS_SECTION_TEXT);
3626 /* one jump is enough */
3627 panic("switch only has one case");
3628 //ia32_emitf(tbl.branches[0].target, "\tjmp %L\n");
3631 be_emit_write_line();
3639 static void bemit_return(const ir_node *node)
3641 unsigned pop = be_Return_get_pop(node);
3642 if (pop > 0 || be_Return_get_emit_pop(node)) {
3644 assert(pop <= 0xffff);
3651 static void bemit_subsp(const ir_node *node)
3653 const arch_register_t *out;
3656 /* mov %esp, %out */
3658 out = get_out_reg(node, 1);
3659 bemit8(MOD_REG | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x04));
3662 static void bemit_incsp(const ir_node *node)
3665 const arch_register_t *reg;
3669 offs = be_get_IncSP_offset(node);
3680 size = get_signed_imm_size(offs);
3681 bemit8(size == 1 ? 0x83 : 0x81);
3683 reg = get_out_reg(node, 0);
3684 bemit_modru(reg, ext);
3693 static void bemit_copybi(const ir_node *node)
3695 unsigned size = get_ia32_copyb_size(node);
3697 bemit8(0xA4); // movsb
3700 bemit8(0xA5); // movsw
3704 bemit8(0xA5); // movsl
3708 static void bemit_fbinop(const ir_node *node, unsigned code, unsigned code_to)
3710 if (get_ia32_op_type(node) == ia32_Normal) {
3711 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
3712 const arch_register_t *in1 = x87_attr->x87[0];
3713 const arch_register_t *in = x87_attr->x87[1];
3714 const arch_register_t *out = x87_attr->x87[2];
3718 } else if (out == in) {
3722 if (out->index == 0) {
3724 bemit8(MOD_REG | ENC_REG(code) | ENC_RM(in->index));
3727 bemit8(MOD_REG | ENC_REG(code_to) | ENC_RM(out->index));
3730 if (get_mode_size_bits(get_ia32_ls_mode(node)) == 32) {
3735 bemit_mod_am(code, node);
3739 static void bemit_fbinopp(const ir_node *node, unsigned const code)
3741 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
3742 const arch_register_t *out = x87_attr->x87[2];
3744 bemit8(code + out->index);
3747 static void bemit_fabs(const ir_node *node)
3755 static void bemit_fadd(const ir_node *node)
3757 bemit_fbinop(node, 0, 0);
3760 static void bemit_faddp(const ir_node *node)
3762 bemit_fbinopp(node, 0xC0);
3765 static void bemit_fchs(const ir_node *node)
3773 static void bemit_fdiv(const ir_node *node)
3775 bemit_fbinop(node, 6, 7);
3778 static void bemit_fdivp(const ir_node *node)
3780 bemit_fbinopp(node, 0xF8);
3783 static void bemit_fdivr(const ir_node *node)
3785 bemit_fbinop(node, 7, 6);
3788 static void bemit_fdivrp(const ir_node *node)
3790 bemit_fbinopp(node, 0xF0);
3793 static void bemit_fild(const ir_node *node)
3795 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3797 bemit8(0xDF); // filds
3798 bemit_mod_am(0, node);
3802 bemit8(0xDB); // fildl
3803 bemit_mod_am(0, node);
3807 bemit8(0xDF); // fildll
3808 bemit_mod_am(5, node);
3812 panic("invalid mode size");
3816 static void bemit_fist(const ir_node *node)
3818 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3820 bemit8(0xDF); // fists
3824 bemit8(0xDB); // fistl
3828 panic("invalid mode size");
3830 bemit_mod_am(2, node);
3833 static void bemit_fistp(const ir_node *node)
3835 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3837 bemit8(0xDF); // fistps
3838 bemit_mod_am(3, node);
3842 bemit8(0xDB); // fistpl
3843 bemit_mod_am(3, node);
3847 bemit8(0xDF); // fistpll
3848 bemit_mod_am(7, node);
3852 panic("invalid mode size");
3856 static void bemit_fld(const ir_node *node)
3858 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3860 bemit8(0xD9); // flds
3861 bemit_mod_am(0, node);
3865 bemit8(0xDD); // fldl
3866 bemit_mod_am(0, node);
3871 bemit8(0xDB); // fldt
3872 bemit_mod_am(5, node);
3876 panic("invalid mode size");
3880 static void bemit_fld1(const ir_node *node)
3884 bemit8(0xE8); // fld1
3887 static void bemit_fldcw(const ir_node *node)
3889 bemit8(0xD9); // fldcw
3890 bemit_mod_am(5, node);
3893 static void bemit_fldz(const ir_node *node)
3897 bemit8(0xEE); // fldz
3900 static void bemit_fmul(const ir_node *node)
3902 bemit_fbinop(node, 1, 1);
3905 static void bemit_fmulp(const ir_node *node)
3907 bemit_fbinopp(node, 0xC8);
3910 static void bemit_fpop(const ir_node *node)
3912 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3914 bemit8(0xD8 + attr->x87[0]->index);
3917 static void bemit_fpush(const ir_node *node)
3919 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3921 bemit8(0xC0 + attr->x87[0]->index);
3924 static void bemit_fpushcopy(const ir_node *node)
3926 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3928 bemit8(0xC0 + attr->x87[0]->index);
3931 static void bemit_fst(const ir_node *node)
3933 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3935 bemit8(0xD9); // fsts
3939 bemit8(0xDD); // fstl
3943 panic("invalid mode size");
3945 bemit_mod_am(2, node);
3948 static void bemit_fstp(const ir_node *node)
3950 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3952 bemit8(0xD9); // fstps
3953 bemit_mod_am(3, node);
3957 bemit8(0xDD); // fstpl
3958 bemit_mod_am(3, node);
3963 bemit8(0xDB); // fstpt
3964 bemit_mod_am(7, node);
3968 panic("invalid mode size");
3972 static void bemit_fsub(const ir_node *node)
3974 bemit_fbinop(node, 4, 5);
3977 static void bemit_fsubp(const ir_node *node)
3979 bemit_fbinopp(node, 0xE8);
3982 static void bemit_fsubr(const ir_node *node)
3984 bemit_fbinop(node, 5, 4);
3987 static void bemit_fsubrp(const ir_node *node)
3989 bemit_fbinopp(node, 0xE0);
3992 static void bemit_fnstcw(const ir_node *node)
3994 bemit8(0xD9); // fnstcw
3995 bemit_mod_am(7, node);
3998 static void bemit_fnstsw(void)
4000 bemit8(0xDF); // fnstsw %ax
4004 static void bemit_ftstfnstsw(const ir_node *node)
4008 bemit8(0xD9); // ftst
4013 static void bemit_fucomi(const ir_node *node)
4015 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
4016 bemit8(0xDB); // fucomi
4017 bemit8(0xE8 + attr->x87[1]->index);
4020 static void bemit_fucomip(const ir_node *node)
4022 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
4023 bemit8(0xDF); // fucomip
4024 bemit8(0xE8 + attr->x87[1]->index);
4027 static void bemit_fucomfnstsw(const ir_node *node)
4029 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
4030 bemit8(0xDD); // fucom
4031 bemit8(0xE0 + attr->x87[1]->index);
4035 static void bemit_fucompfnstsw(const ir_node *node)
4037 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
4038 bemit8(0xDD); // fucomp
4039 bemit8(0xE8 + attr->x87[1]->index);
4043 static void bemit_fucomppfnstsw(const ir_node *node)
4047 bemit8(0xDA); // fucompp
4052 static void bemit_fxch(const ir_node *node)
4054 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
4056 bemit8(0xC8 + attr->x87[0]->index);
4060 * The type of a emitter function.
4062 typedef void (*emit_func) (const ir_node *);
4065 * Set a node emitter. Make it a bit more type safe.
4067 static void register_emitter(ir_op *op, emit_func func)
4069 op->ops.generic = (op_func) func;
4072 static void ia32_register_binary_emitters(void)
4074 /* first clear the generic function pointer for all ops */
4075 clear_irp_opcodes_generic_func();
4077 /* benode emitter */
4078 register_emitter(op_be_Copy, bemit_copy);
4079 register_emitter(op_be_CopyKeep, bemit_copy);
4080 register_emitter(op_be_IncSP, bemit_incsp);
4081 register_emitter(op_be_Perm, bemit_perm);
4082 register_emitter(op_be_Return, bemit_return);
4083 register_emitter(op_ia32_Adc, bemit_adc);
4084 register_emitter(op_ia32_Add, bemit_add);
4085 register_emitter(op_ia32_AddMem, bemit_addmem);
4086 register_emitter(op_ia32_AddMem8Bit, bemit_addmem8bit);
4087 register_emitter(op_ia32_And, bemit_and);
4088 register_emitter(op_ia32_AndMem, bemit_andmem);
4089 register_emitter(op_ia32_AndMem8Bit, bemit_andmem8bit);
4090 register_emitter(op_ia32_Breakpoint, bemit_int3);
4091 register_emitter(op_ia32_CMovcc, bemit_cmovcc);
4092 register_emitter(op_ia32_Call, bemit_call);
4093 register_emitter(op_ia32_Cltd, bemit_cltd);
4094 register_emitter(op_ia32_Cmc, bemit_cmc);
4095 register_emitter(op_ia32_Cmp, bemit_cmp);
4096 register_emitter(op_ia32_Cmp8Bit, bemit_cmp8bit);
4097 register_emitter(op_ia32_Const, bemit_mov_const);
4098 register_emitter(op_ia32_Conv_I2I, bemit_conv_i2i);
4099 register_emitter(op_ia32_Conv_I2I8Bit, bemit_conv_i2i);
4100 register_emitter(op_ia32_CopyB_i, bemit_copybi);
4101 register_emitter(op_ia32_Cwtl, bemit_cwtl);
4102 register_emitter(op_ia32_Dec, bemit_dec);
4103 register_emitter(op_ia32_DecMem, bemit_decmem);
4104 register_emitter(op_ia32_Div, bemit_div);
4105 register_emitter(op_ia32_FldCW, bemit_fldcw);
4106 register_emitter(op_ia32_FnstCW, bemit_fnstcw);
4107 register_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw);
4108 register_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw);
4109 register_emitter(op_ia32_Fucomi, bemit_fucomi);
4110 register_emitter(op_ia32_FucompFnstsw, bemit_fucompfnstsw);
4111 register_emitter(op_ia32_Fucompi, bemit_fucomip);
4112 register_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw);
4113 register_emitter(op_ia32_IDiv, bemit_idiv);
4114 register_emitter(op_ia32_IJmp, bemit_ijmp);
4115 register_emitter(op_ia32_IMul, bemit_imul);
4116 register_emitter(op_ia32_IMul1OP, bemit_imul1op);
4117 register_emitter(op_ia32_Inc, bemit_inc);
4118 register_emitter(op_ia32_IncMem, bemit_incmem);
4119 register_emitter(op_ia32_Jcc, bemit_ia32_jcc);
4120 register_emitter(op_ia32_Jmp, bemit_jump);
4121 register_emitter(op_ia32_LdTls, bemit_ldtls);
4122 register_emitter(op_ia32_Lea, bemit_lea);
4123 register_emitter(op_ia32_Leave, bemit_leave);
4124 register_emitter(op_ia32_Load, bemit_load);
4125 register_emitter(op_ia32_Minus64Bit, bemit_minus64bit);
4126 register_emitter(op_ia32_Mul, bemit_mul);
4127 register_emitter(op_ia32_Neg, bemit_neg);
4128 register_emitter(op_ia32_NegMem, bemit_negmem);
4129 register_emitter(op_ia32_Not, bemit_not);
4130 register_emitter(op_ia32_NotMem, bemit_notmem);
4131 register_emitter(op_ia32_Or, bemit_or);
4132 register_emitter(op_ia32_OrMem, bemit_ormem);
4133 register_emitter(op_ia32_OrMem8Bit, bemit_ormem8bit);
4134 register_emitter(op_ia32_Pop, bemit_pop);
4135 register_emitter(op_ia32_PopEbp, bemit_pop);
4136 register_emitter(op_ia32_PopMem, bemit_popmem);
4137 register_emitter(op_ia32_Push, bemit_push);
4138 register_emitter(op_ia32_RepPrefix, bemit_rep);
4139 register_emitter(op_ia32_Rol, bemit_rol);
4140 register_emitter(op_ia32_RolMem, bemit_rolmem);
4141 register_emitter(op_ia32_Ror, bemit_ror);
4142 register_emitter(op_ia32_RorMem, bemit_rormem);
4143 register_emitter(op_ia32_Sahf, bemit_sahf);
4144 register_emitter(op_ia32_Sar, bemit_sar);
4145 register_emitter(op_ia32_SarMem, bemit_sarmem);
4146 register_emitter(op_ia32_Sbb, bemit_sbb);
4147 register_emitter(op_ia32_Setcc, bemit_setcc);
4148 register_emitter(op_ia32_Shl, bemit_shl);
4149 register_emitter(op_ia32_ShlD, bemit_shld);
4150 register_emitter(op_ia32_ShlMem, bemit_shlmem);
4151 register_emitter(op_ia32_Shr, bemit_shr);
4152 register_emitter(op_ia32_ShrD, bemit_shrd);
4153 register_emitter(op_ia32_ShrMem, bemit_shrmem);
4154 register_emitter(op_ia32_Stc, bemit_stc);
4155 register_emitter(op_ia32_Store, bemit_store);
4156 register_emitter(op_ia32_Store8Bit, bemit_store);
4157 register_emitter(op_ia32_Sub, bemit_sub);
4158 register_emitter(op_ia32_SubMem, bemit_submem);
4159 register_emitter(op_ia32_SubMem8Bit, bemit_submem8bit);
4160 register_emitter(op_ia32_SubSP, bemit_subsp);
4161 register_emitter(op_ia32_SwitchJmp, bemit_switchjmp);
4162 register_emitter(op_ia32_Test, bemit_test);
4163 register_emitter(op_ia32_Test8Bit, bemit_test8bit);
4164 register_emitter(op_ia32_Xor, bemit_xor);
4165 register_emitter(op_ia32_Xor0, bemit_xor0);
4166 register_emitter(op_ia32_XorMem, bemit_xormem);
4167 register_emitter(op_ia32_XorMem8Bit, bemit_xormem8bit);
4168 register_emitter(op_ia32_fabs, bemit_fabs);
4169 register_emitter(op_ia32_fadd, bemit_fadd);
4170 register_emitter(op_ia32_faddp, bemit_faddp);
4171 register_emitter(op_ia32_fchs, bemit_fchs);
4172 register_emitter(op_ia32_fdiv, bemit_fdiv);
4173 register_emitter(op_ia32_fdivp, bemit_fdivp);
4174 register_emitter(op_ia32_fdivr, bemit_fdivr);
4175 register_emitter(op_ia32_fdivrp, bemit_fdivrp);
4176 register_emitter(op_ia32_fild, bemit_fild);
4177 register_emitter(op_ia32_fist, bemit_fist);
4178 register_emitter(op_ia32_fistp, bemit_fistp);
4179 register_emitter(op_ia32_fld, bemit_fld);
4180 register_emitter(op_ia32_fld1, bemit_fld1);
4181 register_emitter(op_ia32_fldz, bemit_fldz);
4182 register_emitter(op_ia32_fmul, bemit_fmul);
4183 register_emitter(op_ia32_fmulp, bemit_fmulp);
4184 register_emitter(op_ia32_fpop, bemit_fpop);
4185 register_emitter(op_ia32_fpush, bemit_fpush);
4186 register_emitter(op_ia32_fpushCopy, bemit_fpushcopy);
4187 register_emitter(op_ia32_fst, bemit_fst);
4188 register_emitter(op_ia32_fstp, bemit_fstp);
4189 register_emitter(op_ia32_fsub, bemit_fsub);
4190 register_emitter(op_ia32_fsubp, bemit_fsubp);
4191 register_emitter(op_ia32_fsubr, bemit_fsubr);
4192 register_emitter(op_ia32_fsubrp, bemit_fsubrp);
4193 register_emitter(op_ia32_fxch, bemit_fxch);
4195 /* ignore the following nodes */
4196 register_emitter(op_ia32_ProduceVal, emit_Nothing);
4197 register_emitter(op_be_Barrier, emit_Nothing);
4198 register_emitter(op_be_Keep, emit_Nothing);
4199 register_emitter(op_be_Start, emit_Nothing);
4200 register_emitter(op_Phi, emit_Nothing);
4201 register_emitter(op_Start, emit_Nothing);
4204 static void gen_binary_block(ir_node *block)
4208 ia32_emit_block_header(block);
4210 /* emit the contents of the block */
4211 sched_foreach(block, node) {
4212 ia32_emit_node(node);
4216 void ia32_gen_binary_routine(ia32_code_gen_t *ia32_cg, ir_graph *irg)
4218 ir_entity *entity = get_irg_entity(irg);
4224 ia32_register_binary_emitters();
4226 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment);
4228 /* we use links to point to target blocks */
4229 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
4230 irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
4232 /* initialize next block links */
4233 n = ARR_LEN(cg->blk_sched);
4234 for (i = 0; i < n; ++i) {
4235 ir_node *block = cg->blk_sched[i];
4236 ir_node *prev = i > 0 ? cg->blk_sched[i-1] : NULL;
4238 set_irn_link(block, prev);
4241 for (i = 0; i < n; ++i) {
4242 ir_node *block = cg->blk_sched[i];
4243 gen_binary_block(block);
4246 be_gas_emit_function_epilog(entity);
4247 be_dbg_method_end();
4249 be_emit_write_line();
4251 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
4257 void ia32_init_emitter(void)
4259 lc_opt_entry_t *be_grp;
4260 lc_opt_entry_t *ia32_grp;
4262 be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
4263 ia32_grp = lc_opt_get_grp(be_grp, "ia32");
4265 lc_opt_add_table(ia32_grp, ia32_emitter_options);
4269 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");