2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the ia32 node emitter.
23 * @author Christian Wuerdig, Matthias Braun
25 * Summary table for x86 floatingpoint compares:
26 * (remember effect of unordered on x86: ZF=1, PF=1, CF=1)
34 * pnc_Leg => NP (ordered)
56 #include "iredges_t.h"
60 #include "raw_bitset.h"
69 #include "beemitter.h"
73 #include "ia32_emitter.h"
74 #include "ia32_common_transform.h"
75 #include "gen_ia32_emitter.h"
76 #include "gen_ia32_regalloc_if.h"
77 #include "ia32_nodes_attr.h"
78 #include "ia32_new_nodes.h"
79 #include "ia32_architecture.h"
80 #include "bearch_ia32_t.h"
82 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
84 #define SNPRINTF_BUF_LEN 128
86 static const ia32_isa_t *isa;
87 static char pic_base_label[128];
88 static ir_label_t exc_label_id;
89 static int mark_spill_reload = 0;
92 static bool sp_relative;
93 static int frame_type_size;
94 static int callframe_offset;
96 /** Return the next block in Block schedule */
97 static ir_node *get_prev_block_sched(const ir_node *block)
99 return (ir_node*)get_irn_link(block);
102 /** Checks if the current block is a fall-through target. */
103 static int is_fallthrough(const ir_node *cfgpred)
107 if (!is_Proj(cfgpred))
109 pred = get_Proj_pred(cfgpred);
110 if (is_ia32_SwitchJmp(pred))
117 * returns non-zero if the given block needs a label
118 * because of being a jump-target (and not a fall-through)
120 static int block_needs_label(const ir_node *block)
123 int n_cfgpreds = get_Block_n_cfgpreds(block);
125 if (get_Block_entity(block) != NULL)
128 if (n_cfgpreds == 0) {
130 } else if (n_cfgpreds == 1) {
131 ir_node *cfgpred = get_Block_cfgpred(block, 0);
132 ir_node *cfgpred_block = get_nodes_block(cfgpred);
134 if (get_prev_block_sched(block) == cfgpred_block
135 && is_fallthrough(cfgpred)) {
144 * Add a number to a prefix. This number will not be used a second time.
146 static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
148 static unsigned long id = 0;
149 snprintf(buf, buflen, "%s%s%lu", be_gas_get_private_prefix(), prefix, ++id);
154 * Emit the name of the 8bit low register
156 static void emit_8bit_register(const arch_register_t *reg)
158 const char *reg_name = arch_register_get_name(reg);
159 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
160 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
163 be_emit_char(reg_name[1]); /* get the basic name of the register */
168 * Emit the name of the 8bit high register
170 static void emit_8bit_register_high(const arch_register_t *reg)
172 const char *reg_name = arch_register_get_name(reg);
173 assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
174 || reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
177 be_emit_char(reg_name[1]); /* get the basic name of the register */
181 static void emit_16bit_register(const arch_register_t *reg)
183 const char *reg_name = arch_register_get_name(reg);
186 be_emit_string(reg_name+1); /* skip the 'e' prefix of the 32bit names */
190 * emit a register, possible shortened by a mode
192 * @param reg the register
193 * @param mode the mode of the register or NULL for full register
195 static void emit_register(const arch_register_t *reg, const ir_mode *mode)
197 const char *reg_name;
200 int size = get_mode_size_bits(mode);
202 case 8: emit_8bit_register(reg); return;
203 case 16: emit_16bit_register(reg); return;
205 assert(mode_is_float(mode) || size == 32);
208 reg_name = arch_register_get_name(reg);
211 be_emit_string(reg_name);
214 void ia32_emit_source_register(const ir_node *node, int pos)
216 const arch_register_t *reg = arch_get_irn_register_in(node, pos);
218 emit_register(reg, NULL);
221 static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
223 be_gas_emit_entity(entity);
225 if (get_entity_owner(entity) == get_tls_type()) {
226 if (!entity_has_definition(entity)) {
227 be_emit_cstring("@INDNTPOFF");
229 be_emit_cstring("@NTPOFF");
233 if (do_pic && !no_pic_adjust) {
235 be_emit_string(pic_base_label);
239 static void emit_ia32_Immediate_no_prefix(const ir_node *node)
241 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
243 if (attr->symconst != NULL) {
246 ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
248 if (attr->symconst == NULL || attr->offset != 0) {
249 if (attr->symconst != NULL) {
250 be_emit_irprintf("%+d", attr->offset);
252 be_emit_irprintf("0x%X", attr->offset);
257 static void emit_ia32_Immediate(const ir_node *node)
260 emit_ia32_Immediate_no_prefix(node);
263 void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos)
265 const arch_register_t *reg;
266 const ir_node *in = get_irn_n(node, pos);
267 if (is_ia32_Immediate(in)) {
268 emit_ia32_Immediate(in);
272 reg = arch_get_irn_register_in(node, pos);
273 emit_8bit_register(reg);
276 void ia32_emit_8bit_high_source_register(const ir_node *node, int pos)
278 const arch_register_t *reg = arch_get_irn_register_in(node, pos);
279 emit_8bit_register_high(reg);
282 void ia32_emit_16bit_source_register_or_immediate(const ir_node *node, int pos)
284 const arch_register_t *reg;
285 const ir_node *in = get_irn_n(node, pos);
286 if (is_ia32_Immediate(in)) {
287 emit_ia32_Immediate(in);
291 reg = arch_get_irn_register_in(node, pos);
292 emit_16bit_register(reg);
295 void ia32_emit_dest_register(const ir_node *node, int pos)
297 const arch_register_t *reg = arch_get_irn_register_out(node, pos);
299 emit_register(reg, NULL);
302 void ia32_emit_dest_register_size(const ir_node *node, int pos)
304 const arch_register_t *reg = arch_get_irn_register_out(node, pos);
306 emit_register(reg, get_ia32_ls_mode(node));
309 void ia32_emit_8bit_dest_register(const ir_node *node, int pos)
311 const arch_register_t *reg = arch_get_irn_register_out(node, pos);
313 emit_register(reg, mode_Bu);
316 void ia32_emit_x87_register(const ir_node *node, int pos)
318 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
322 be_emit_string(attr->x87[pos]->name);
325 static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
327 assert(mode_is_int(mode) || mode_is_reference(mode));
328 switch (get_mode_size_bits(mode)) {
329 case 8: be_emit_char('b'); return;
330 case 16: be_emit_char('w'); return;
331 case 32: be_emit_char('l'); return;
332 /* gas docu says q is the suffix but gcc, objdump and icc use ll
334 case 64: be_emit_cstring("ll"); return;
336 panic("Can't output mode_suffix for %+F", mode);
339 void ia32_emit_mode_suffix(const ir_node *node)
341 ir_mode *mode = get_ia32_ls_mode(node);
345 ia32_emit_mode_suffix_mode(mode);
348 void ia32_emit_x87_mode_suffix(const ir_node *node)
352 /* we only need to emit the mode on address mode */
353 if (get_ia32_op_type(node) == ia32_Normal)
356 mode = get_ia32_ls_mode(node);
357 assert(mode != NULL);
359 if (mode_is_float(mode)) {
360 switch (get_mode_size_bits(mode)) {
361 case 32: be_emit_char('s'); return;
362 case 64: be_emit_char('l'); return;
363 /* long doubles have different sizes due to alignment on different
367 case 128: be_emit_char('t'); return;
370 assert(mode_is_int(mode) || mode_is_reference(mode));
371 switch (get_mode_size_bits(mode)) {
372 case 16: be_emit_char('s'); return;
373 case 32: be_emit_char('l'); return;
374 /* gas docu says q is the suffix but gcc, objdump and icc use ll
376 case 64: be_emit_cstring("ll"); return;
379 panic("Can't output mode_suffix for %+F", mode);
382 static char get_xmm_mode_suffix(ir_mode *mode)
384 assert(mode_is_float(mode));
385 switch (get_mode_size_bits(mode)) {
388 default: panic("Invalid XMM mode");
392 void ia32_emit_xmm_mode_suffix(const ir_node *node)
394 ir_mode *mode = get_ia32_ls_mode(node);
395 assert(mode != NULL);
397 be_emit_char(get_xmm_mode_suffix(mode));
400 void ia32_emit_xmm_mode_suffix_s(const ir_node *node)
402 ir_mode *mode = get_ia32_ls_mode(node);
403 assert(mode != NULL);
404 be_emit_char(get_xmm_mode_suffix(mode));
407 void ia32_emit_extend_suffix(const ir_node *node)
409 ir_mode *mode = get_ia32_ls_mode(node);
410 if (get_mode_size_bits(mode) == 32)
412 be_emit_char(mode_is_signed(mode) ? 's' : 'z');
413 ia32_emit_mode_suffix_mode(mode);
416 void ia32_emit_source_register_or_immediate(const ir_node *node, int pos)
418 ir_node *in = get_irn_n(node, pos);
419 if (is_ia32_Immediate(in)) {
420 emit_ia32_Immediate(in);
422 const ir_mode *mode = get_ia32_ls_mode(node);
423 const arch_register_t *reg = arch_get_irn_register_in(node, pos);
424 emit_register(reg, mode);
429 * Returns the target block for a control flow node.
431 static ir_node *get_cfop_target_block(const ir_node *irn)
433 assert(get_irn_mode(irn) == mode_X);
434 return (ir_node*)get_irn_link(irn);
438 * Emits the target label for a control flow node.
440 static void ia32_emit_cfop_target(const ir_node *node)
442 ir_node *block = get_cfop_target_block(node);
443 be_gas_emit_block_name(block);
447 * Emit the suffix for a compare instruction.
449 static void ia32_emit_condition_code(ia32_condition_code_t cc)
452 case ia32_cc_overflow: be_emit_cstring("o"); return;
453 case ia32_cc_not_overflow: be_emit_cstring("no"); return;
454 case ia32_cc_float_below:
455 case ia32_cc_float_unordered_below:
456 case ia32_cc_below: be_emit_cstring("b"); return;
457 case ia32_cc_float_above_equal:
458 case ia32_cc_float_unordered_above_equal:
459 case ia32_cc_above_equal: be_emit_cstring("ae"); return;
460 case ia32_cc_float_equal:
461 case ia32_cc_equal: be_emit_cstring("e"); return;
462 case ia32_cc_float_not_equal:
463 case ia32_cc_not_equal: be_emit_cstring("ne"); return;
464 case ia32_cc_float_below_equal:
465 case ia32_cc_float_unordered_below_equal:
466 case ia32_cc_below_equal: be_emit_cstring("be"); return;
467 case ia32_cc_float_above:
468 case ia32_cc_float_unordered_above:
469 case ia32_cc_above: be_emit_cstring("a"); return;
470 case ia32_cc_sign: be_emit_cstring("s"); return;
471 case ia32_cc_not_sign: be_emit_cstring("ns"); return;
472 case ia32_cc_parity: be_emit_cstring("p"); return;
473 case ia32_cc_not_parity: be_emit_cstring("np"); return;
474 case ia32_cc_less: be_emit_cstring("l"); return;
475 case ia32_cc_greater_equal: be_emit_cstring("ge"); return;
476 case ia32_cc_less_equal: be_emit_cstring("le"); return;
477 case ia32_cc_greater: be_emit_cstring("g"); return;
478 case ia32_cc_float_parity_cases:
479 case ia32_cc_additional_float_cases:
482 panic("Invalid ia32 condition code");
485 typedef enum ia32_emit_mod_t {
487 EMIT_RESPECT_LS = 1U << 0,
488 EMIT_ALTERNATE_AM = 1U << 1,
490 EMIT_HIGH_REG = 1U << 3,
491 EMIT_LOW_REG = 1U << 4
493 ENUM_BITSET(ia32_emit_mod_t)
496 * Emits address mode.
498 void ia32_emit_am(const ir_node *node)
500 ir_entity *ent = get_ia32_am_sc(node);
501 int offs = get_ia32_am_offs_int(node);
502 ir_node *base = get_irn_n(node, n_ia32_base);
503 int has_base = !is_ia32_NoReg_GP(base);
504 ir_node *idx = get_irn_n(node, n_ia32_index);
505 int has_index = !is_ia32_NoReg_GP(idx);
507 /* just to be sure... */
508 assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
510 if (get_ia32_am_tls_segment(node))
511 be_emit_cstring("%gs:");
515 const ia32_attr_t *attr = get_ia32_attr_const(node);
516 if (is_ia32_am_sc_sign(node))
518 ia32_emit_entity(ent, attr->data.am_sc_no_pic_adjust);
521 /* also handle special case if nothing is set */
522 if (offs != 0 || (ent == NULL && !has_base && !has_index)) {
524 be_emit_irprintf("%+d", offs);
526 be_emit_irprintf("%d", offs);
530 if (has_base || has_index) {
535 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
536 emit_register(reg, NULL);
539 /* emit index + scale */
541 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
544 emit_register(reg, NULL);
546 scale = get_ia32_am_scale(node);
548 be_emit_irprintf(",%d", 1 << scale);
556 * fmt parameter output
557 * ---- ---------------------- ---------------------------------------------
559 * %AM <node> address mode of the node
560 * %AR const arch_register_t* address mode of the node or register
561 * %ASx <node> address mode of the node or source register x
562 * %Dx <node> destination register x
563 * %I <node> immediate of the node
564 * %L <node> control flow target of the node
565 * %M <node> mode suffix of the node
566 * %P int condition code
567 * %R const arch_register_t* register
568 * %Sx <node> source register x
569 * %s const char* string
570 * %u unsigned int unsigned int
571 * %d signed int signed int
574 * # modifier for %ASx, %D, %R, and %S uses ls mode of node to alter register width
575 * * modifier does not prefix immediates with $, but AM with *
576 * l modifier for %lu and %ld
577 * > modifier to output high 8bit register (ah, bh)
578 * < modifier to output low 8bit register (al, bl)
580 static void ia32_emitf(const ir_node *node, const char *fmt, ...)
586 const char *start = fmt;
587 ia32_emit_mod_t mod = EMIT_NONE;
589 while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
592 be_emit_string_len(start, fmt - start);
596 be_emit_finish_line_gas(node);
609 case '*': mod |= EMIT_ALTERNATE_AM; break;
610 case '#': mod |= EMIT_RESPECT_LS; break;
611 case 'l': mod |= EMIT_LONG; break;
612 case '>': mod |= EMIT_HIGH_REG; break;
613 case '<': mod |= EMIT_LOW_REG; break;
622 arch_register_t const *reg;
633 if (mod & EMIT_ALTERNATE_AM)
639 reg = va_arg(ap, const arch_register_t*);
640 if (get_ia32_op_type(node) == ia32_AddrModeS) {
647 if (get_ia32_op_type(node) == ia32_AddrModeS) {
651 assert(get_ia32_op_type(node) == ia32_Normal);
655 default: goto unknown;
661 if (*fmt < '0' || '9' <= *fmt)
663 reg = arch_get_irn_register_out(node, *fmt++ - '0');
669 if (!(mod & EMIT_ALTERNATE_AM))
671 emit_ia32_Immediate_no_prefix(imm);
675 ia32_emit_cfop_target(node);
679 ia32_emit_mode_suffix_mode(get_ia32_ls_mode(node));
683 ia32_condition_code_t cc = va_arg(ap, ia32_condition_code_t);
684 ia32_emit_condition_code(cc);
689 reg = va_arg(ap, const arch_register_t*);
691 if (mod & EMIT_ALTERNATE_AM)
693 if (mod & EMIT_HIGH_REG) {
694 emit_8bit_register_high(reg);
695 } else if (mod & EMIT_LOW_REG) {
696 emit_8bit_register(reg);
698 emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
706 if (*fmt < '0' || '9' <= *fmt)
710 imm = get_irn_n(node, pos);
711 if (is_ia32_Immediate(imm)) {
714 reg = arch_get_irn_register_in(node, pos);
720 const char *str = va_arg(ap, const char*);
726 if (mod & EMIT_LONG) {
727 unsigned long num = va_arg(ap, unsigned long);
728 be_emit_irprintf("%lu", num);
730 unsigned num = va_arg(ap, unsigned);
731 be_emit_irprintf("%u", num);
736 if (mod & EMIT_LONG) {
737 long num = va_arg(ap, long);
738 be_emit_irprintf("%ld", num);
740 int num = va_arg(ap, int);
741 be_emit_irprintf("%d", num);
747 panic("unknown format conversion in ia32_emitf()");
755 * Emits registers and/or address mode of a binary operation.
757 void ia32_emit_binop(const ir_node *node)
759 if (is_ia32_Immediate(get_irn_n(node, n_ia32_binary_right))) {
760 ia32_emitf(node, "%#S4, %#AS3");
762 ia32_emitf(node, "%#AS4, %#S3");
767 * Emits registers and/or address mode of a binary operation.
769 void ia32_emit_x87_binop(const ir_node *node)
771 switch (get_ia32_op_type(node)) {
774 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
775 const arch_register_t *in1 = x87_attr->x87[0];
776 const arch_register_t *in = x87_attr->x87[1];
777 const arch_register_t *out = x87_attr->x87[2];
781 } else if (out == in) {
786 be_emit_string(arch_register_get_name(in));
787 be_emit_cstring(", %");
788 be_emit_string(arch_register_get_name(out));
796 assert(0 && "unsupported op type");
801 * Emits registers and/or address mode of a unary operation.
803 void ia32_emit_unop(const ir_node *node, int pos)
807 ia32_emitf(node, fmt);
810 static void emit_ia32_IMul(const ir_node *node)
812 ir_node *left = get_irn_n(node, n_ia32_IMul_left);
813 const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
815 /* do we need the 3-address form? */
816 if (is_ia32_NoReg_GP(left) ||
817 arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
818 ia32_emitf(node, "\timul%M %#S4, %#AS3, %#D0\n");
820 ia32_emitf(node, "\timul%M %#AS4, %#S3\n");
825 * walks up a tree of copies/perms/spills/reloads to find the original value
826 * that is moved around
828 static ir_node *find_original_value(ir_node *node)
830 if (irn_visited(node))
833 mark_irn_visited(node);
834 if (be_is_Copy(node)) {
835 return find_original_value(be_get_Copy_op(node));
836 } else if (be_is_CopyKeep(node)) {
837 return find_original_value(be_get_CopyKeep_op(node));
838 } else if (is_Proj(node)) {
839 ir_node *pred = get_Proj_pred(node);
840 if (be_is_Perm(pred)) {
841 return find_original_value(get_irn_n(pred, get_Proj_proj(node)));
842 } else if (be_is_MemPerm(pred)) {
843 return find_original_value(get_irn_n(pred, get_Proj_proj(node) + 1));
844 } else if (is_ia32_Load(pred)) {
845 return find_original_value(get_irn_n(pred, n_ia32_Load_mem));
846 } else if (is_ia32_Store(pred)) {
847 return find_original_value(get_irn_n(pred, n_ia32_Store_val));
851 } else if (is_Phi(node)) {
853 arity = get_irn_arity(node);
854 for (i = 0; i < arity; ++i) {
855 ir_node *in = get_irn_n(node, i);
856 ir_node *res = find_original_value(in);
867 static int determine_final_cc(const ir_node *node, int flags_pos, int cc)
869 ir_node *flags = get_irn_n(node, flags_pos);
870 const ia32_attr_t *flags_attr;
871 flags = skip_Proj(flags);
873 if (is_ia32_Sahf(flags)) {
874 ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
875 if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
876 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
877 inc_irg_visited(current_ir_graph);
878 cmp = find_original_value(cmp);
880 assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
881 || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
884 flags_attr = get_ia32_attr_const(cmp);
886 flags_attr = get_ia32_attr_const(flags);
889 if (flags_attr->data.ins_permuted)
890 cc = ia32_invert_condition_code(cc);
894 void ia32_emit_cmp_suffix_node(const ir_node *node, int flags_pos)
896 ia32_condition_code_t cc = get_ia32_condcode(node);
897 cc = determine_final_cc(node, flags_pos, cc);
899 ia32_emit_condition_code(cc);
903 * Emits an exception label for a given node.
905 static void ia32_emit_exc_label(const ir_node *node)
907 be_emit_string(be_gas_insn_label_prefix());
908 be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
912 * Returns the Proj with projection number proj and NOT mode_M
914 static ir_node *get_proj(const ir_node *node, long proj)
916 const ir_edge_t *edge;
919 assert(get_irn_mode(node) == mode_T && "expected mode_T node");
921 foreach_out_edge(node, edge) {
922 src = get_edge_src_irn(edge);
924 assert(is_Proj(src) && "Proj expected");
925 if (get_irn_mode(src) == mode_M)
928 if (get_Proj_proj(src) == proj)
934 static int can_be_fallthrough(const ir_node *node)
936 ir_node *target_block = get_cfop_target_block(node);
937 ir_node *block = get_nodes_block(node);
938 return get_prev_block_sched(target_block) == block;
942 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
944 static void emit_ia32_Jcc(const ir_node *node)
946 int need_parity_label = 0;
947 ia32_condition_code_t cc = get_ia32_condcode(node);
948 const ir_node *proj_true;
949 const ir_node *proj_false;
951 cc = determine_final_cc(node, 0, cc);
954 proj_true = get_proj(node, pn_ia32_Jcc_true);
955 assert(proj_true && "Jcc without true Proj");
957 proj_false = get_proj(node, pn_ia32_Jcc_false);
958 assert(proj_false && "Jcc without false Proj");
960 if (can_be_fallthrough(proj_true)) {
961 /* exchange both proj's so the second one can be omitted */
962 const ir_node *t = proj_true;
964 proj_true = proj_false;
966 cc = ia32_negate_condition_code(cc);
969 if (cc & ia32_cc_float_parity_cases) {
970 /* Some floating point comparisons require a test of the parity flag,
971 * which indicates that the result is unordered */
972 if (cc & ia32_cc_negated) {
973 ia32_emitf(proj_true, "\tjp %L\n");
975 /* we need a local label if the false proj is a fallthrough
976 * as the falseblock might have no label emitted then */
977 if (can_be_fallthrough(proj_false)) {
978 need_parity_label = 1;
979 ia32_emitf(proj_false, "\tjp 1f\n");
981 ia32_emitf(proj_false, "\tjp %L\n");
985 ia32_emitf(proj_true, "\tj%P %L\n", cc);
986 if (need_parity_label) {
987 ia32_emitf(NULL, "1:\n");
990 /* the second Proj might be a fallthrough */
991 if (can_be_fallthrough(proj_false)) {
992 ia32_emitf(proj_false, "\t/* fallthrough to %L */\n");
994 ia32_emitf(proj_false, "\tjmp %L\n");
999 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
1002 static void emit_ia32_Setcc(const ir_node *node)
1004 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
1006 ia32_condition_code_t cc = get_ia32_condcode(node);
1007 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
1008 if (cc & ia32_cc_float_parity_cases) {
1009 if (cc & ia32_cc_negated) {
1010 ia32_emitf(node, "\tset%P %<R\n", cc, dreg);
1011 ia32_emitf(node, "\tsetp %>R\n", dreg);
1012 ia32_emitf(node, "\torb %>R, %<R\n", dreg, dreg);
1014 ia32_emitf(node, "\tset%P %<R\n", cc, dreg);
1015 ia32_emitf(node, "\tsetnp %>R\n", dreg);
1016 ia32_emitf(node, "\tandb %>R, %<R\n", dreg, dreg);
1019 ia32_emitf(node, "\tset%P %#R\n", cc, dreg);
1023 static void emit_ia32_CMovcc(const ir_node *node)
1025 const ia32_attr_t *attr = get_ia32_attr_const(node);
1026 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
1027 ia32_condition_code_t cc = get_ia32_condcode(node);
1028 const arch_register_t *in_true;
1029 const arch_register_t *in_false;
1031 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
1032 /* although you can't set ins_permuted in the constructor it might still
1033 * be set by memory operand folding
1034 * Permuting inputs of a cmov means the condition is negated!
1036 if (attr->data.ins_permuted)
1037 cc = ia32_negate_condition_code(cc);
1039 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
1040 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
1042 /* should be same constraint fullfilled? */
1043 if (out == in_false) {
1044 /* yes -> nothing to do */
1045 } else if (out == in_true) {
1046 const arch_register_t *tmp;
1048 assert(get_ia32_op_type(node) == ia32_Normal);
1050 cc = ia32_negate_condition_code(cc);
1057 ia32_emitf(node, "\tmovl %R, %R\n", in_false, out);
1060 if (cc & ia32_cc_float_parity_cases) {
1061 panic("CMov with floatingpoint compare/parity not supported yet");
1064 ia32_emitf(node, "\tcmov%P %#AR, %#R\n", cc, in_true, out);
1068 * Emits code for a SwitchJmp
1070 static void emit_ia32_SwitchJmp(const ir_node *node)
1072 ir_entity *jump_table = get_ia32_am_sc(node);
1073 const ir_switch_table *table = get_ia32_switch_table(node);
1075 ia32_emitf(node, "\tjmp %*AM\n");
1076 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
1080 * Emits code for a unconditional jump.
1082 static void emit_ia32_Jmp(const ir_node *node)
1084 /* we have a block schedule */
1085 if (can_be_fallthrough(node)) {
1086 ia32_emitf(node, "\t/* fallthrough to %L */\n");
1088 ia32_emitf(node, "\tjmp %L\n");
1093 * Emit an inline assembler operand.
1095 * @param node the ia32_ASM node
1096 * @param s points to the operand (a %c)
1098 * @return pointer to the first char in s NOT in the current operand
1100 static const char* emit_asm_operand(const ir_node *node, const char *s)
1102 const ia32_attr_t *ia32_attr = get_ia32_attr_const(node);
1103 const ia32_asm_attr_t *attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
1105 const arch_register_t *reg;
1106 const ia32_asm_reg_t *asm_regs = attr->register_map;
1107 const ia32_asm_reg_t *asm_reg;
1116 /* parse modifiers */
1119 ir_fprintf(stderr, "Warning: asm text (%+F) ends with %%\n", node);
1144 "Warning: asm text (%+F) contains unknown modifier '%c' for asm op\n",
1151 if (sscanf(s, "%d%n", &num, &p) != 1) {
1152 ir_fprintf(stderr, "Warning: Couldn't parse assembler operand (%+F)\n",
1159 if (num < 0 || ARR_LEN(asm_regs) <= (size_t)num) {
1161 "Error: Custom assembler references invalid input/output (%+F)\n",
1165 asm_reg = & asm_regs[num];
1166 assert(asm_reg->valid);
1169 if (asm_reg->use_input == 0) {
1170 reg = arch_get_irn_register_out(node, asm_reg->inout_pos);
1172 ir_node *pred = get_irn_n(node, asm_reg->inout_pos);
1174 /* might be an immediate value */
1175 if (is_ia32_Immediate(pred)) {
1176 emit_ia32_Immediate(pred);
1179 reg = arch_get_irn_register_in(node, asm_reg->inout_pos);
1183 "Warning: no register assigned for %d asm op (%+F)\n",
1188 if (asm_reg->memory) {
1193 if (modifier != 0) {
1196 emit_8bit_register(reg);
1199 emit_8bit_register_high(reg);
1202 emit_16bit_register(reg);
1205 panic("Invalid asm op modifier");
1208 emit_register(reg, asm_reg->memory ? mode_Iu : asm_reg->mode);
1211 if (asm_reg->memory) {
1219 * Emits code for an ASM pseudo op.
1221 static void emit_ia32_Asm(const ir_node *node)
1223 const void *gen_attr = get_irn_generic_attr_const(node);
1224 const ia32_asm_attr_t *attr
1225 = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, gen_attr);
1226 ident *asm_text = attr->asm_text;
1227 const char *s = get_id_str(asm_text);
1229 ia32_emitf(node, "#APP\t\n");
1236 s = emit_asm_operand(node, s);
1242 ia32_emitf(NULL, "\n#NO_APP\n");
1247 * Emit movsb/w instructions to make mov count divideable by 4
1249 static void emit_CopyB_prolog(unsigned size)
1252 ia32_emitf(NULL, "\tmovsb\n");
1254 ia32_emitf(NULL, "\tmovsw\n");
1258 * Emit rep movsd instruction for memcopy.
1260 static void emit_ia32_CopyB(const ir_node *node)
1262 unsigned size = get_ia32_copyb_size(node);
1264 emit_CopyB_prolog(size);
1265 ia32_emitf(node, "\trep movsd\n");
1269 * Emits unrolled memcopy.
1271 static void emit_ia32_CopyB_i(const ir_node *node)
1273 unsigned size = get_ia32_copyb_size(node);
1275 emit_CopyB_prolog(size);
1279 ia32_emitf(NULL, "\tmovsd\n");
1285 * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1287 static void emit_ia32_Conv_with_FP(const ir_node *node, const char* conv_f,
1290 ir_mode *ls_mode = get_ia32_ls_mode(node);
1291 int ls_bits = get_mode_size_bits(ls_mode);
1292 const char *conv = ls_bits == 32 ? conv_f : conv_d;
1294 ia32_emitf(node, "\tcvt%s %AS3, %D0\n", conv);
1297 static void emit_ia32_Conv_I2FP(const ir_node *node)
1299 emit_ia32_Conv_with_FP(node, "si2ss", "si2sd");
1302 static void emit_ia32_Conv_FP2I(const ir_node *node)
1304 emit_ia32_Conv_with_FP(node, "ss2si", "sd2si");
1307 static void emit_ia32_Conv_FP2FP(const ir_node *node)
1309 emit_ia32_Conv_with_FP(node, "sd2ss", "ss2sd");
1313 * Emits code for an Int conversion.
1315 static void emit_ia32_Conv_I2I(const ir_node *node)
1317 ir_mode *smaller_mode = get_ia32_ls_mode(node);
1318 int signed_mode = mode_is_signed(smaller_mode);
1319 const char *sign_suffix;
1321 assert(!mode_is_float(smaller_mode));
1323 sign_suffix = signed_mode ? "s" : "z";
1324 ia32_emitf(node, "\tmov%s%Ml %#AS3, %D0\n", sign_suffix);
1330 static void emit_ia32_Call(const ir_node *node)
1332 /* Special case: Call must not have its immediates prefixed by $, instead
1333 * address mode is prefixed by *. */
1334 ia32_emitf(node, "\tcall %*AS3\n");
1339 * Emits code to increase stack pointer.
1341 static void emit_be_IncSP(const ir_node *node)
1343 int offs = be_get_IncSP_offset(node);
1349 ia32_emitf(node, "\tsubl $%u, %D0\n", offs);
1351 ia32_emitf(node, "\taddl $%u, %D0\n", -offs);
1356 * Emits code for Copy/CopyKeep.
1358 static void Copy_emitter(const ir_node *node, const ir_node *op)
1360 const arch_register_t *in = arch_get_irn_register(op);
1361 const arch_register_t *out = arch_get_irn_register(node);
1366 /* copies of vf nodes aren't real... */
1367 if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
1370 ia32_emitf(node, "\tmovl %R, %R\n", in, out);
1373 static void emit_be_Copy(const ir_node *node)
1375 Copy_emitter(node, be_get_Copy_op(node));
1378 static void emit_be_CopyKeep(const ir_node *node)
1380 Copy_emitter(node, be_get_CopyKeep_op(node));
1384 * Emits code for exchange.
1386 static void emit_be_Perm(const ir_node *node)
1388 const arch_register_t *in0, *in1;
1389 const arch_register_class_t *cls0, *cls1;
1391 in0 = arch_get_irn_register(get_irn_n(node, 0));
1392 in1 = arch_get_irn_register(get_irn_n(node, 1));
1394 cls0 = arch_register_get_class(in0);
1395 cls1 = arch_register_get_class(in1);
1397 assert(cls0 == cls1 && "Register class mismatch at Perm");
1399 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
1400 ia32_emitf(node, "\txchg %R, %R\n", in1, in0);
1401 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1402 ia32_emitf(NULL, "\txorpd %R, %R\n", in1, in0);
1403 ia32_emitf(NULL, "\txorpd %R, %R\n", in0, in1);
1404 ia32_emitf(node, "\txorpd %R, %R\n", in1, in0);
1405 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
1407 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
1410 panic("unexpected register class in be_Perm (%+F)", node);
1415 * Emits code for Constant loading.
1417 static void emit_ia32_Const(const ir_node *node)
1419 ia32_emitf(node, "\tmovl %I, %D0\n");
1422 /* helper function for emit_ia32_Minus64Bit */
1423 static void emit_mov(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1425 ia32_emitf(node, "\tmovl %R, %R\n", src, dst);
1428 /* helper function for emit_ia32_Minus64Bit */
1429 static void emit_neg(const ir_node* node, const arch_register_t *reg)
1431 ia32_emitf(node, "\tnegl %R\n", reg);
1434 /* helper function for emit_ia32_Minus64Bit */
1435 static void emit_sbb0(const ir_node* node, const arch_register_t *reg)
1437 ia32_emitf(node, "\tsbbl $0, %R\n", reg);
1440 /* helper function for emit_ia32_Minus64Bit */
1441 static void emit_sbb(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1443 ia32_emitf(node, "\tsbbl %R, %R\n", src, dst);
1446 /* helper function for emit_ia32_Minus64Bit */
1447 static void emit_xchg(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1449 ia32_emitf(node, "\txchgl %R, %R\n", src, dst);
1452 /* helper function for emit_ia32_Minus64Bit */
1453 static void emit_zero(const ir_node* node, const arch_register_t *reg)
1455 ia32_emitf(node, "\txorl %R, %R\n", reg, reg);
1458 static void emit_ia32_Minus64Bit(const ir_node *node)
1460 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
1461 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
1462 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
1463 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
1465 if (out_lo == in_lo) {
1466 if (out_hi != in_hi) {
1467 /* a -> a, b -> d */
1470 /* a -> a, b -> b */
1473 } else if (out_lo == in_hi) {
1474 if (out_hi == in_lo) {
1475 /* a -> b, b -> a */
1476 emit_xchg(node, in_lo, in_hi);
1479 /* a -> b, b -> d */
1480 emit_mov(node, in_hi, out_hi);
1481 emit_mov(node, in_lo, out_lo);
1485 if (out_hi == in_lo) {
1486 /* a -> c, b -> a */
1487 emit_mov(node, in_lo, out_lo);
1489 } else if (out_hi == in_hi) {
1490 /* a -> c, b -> b */
1491 emit_mov(node, in_lo, out_lo);
1494 /* a -> c, b -> d */
1495 emit_mov(node, in_lo, out_lo);
1501 emit_neg( node, out_hi);
1502 emit_neg( node, out_lo);
1503 emit_sbb0(node, out_hi);
1507 emit_zero(node, out_hi);
1508 emit_neg( node, out_lo);
1509 emit_sbb( node, in_hi, out_hi);
1512 static void emit_ia32_GetEIP(const ir_node *node)
1514 ia32_emitf(node, "\tcall %s\n", pic_base_label);
1515 ia32_emitf(NULL, "%s:\n", pic_base_label);
1516 ia32_emitf(node, "\tpopl %D0\n");
1519 static void emit_ia32_ClimbFrame(const ir_node *node)
1521 const ia32_climbframe_attr_t *attr = get_ia32_climbframe_attr_const(node);
1523 ia32_emitf(node, "\tmovl %S0, %D0\n");
1524 ia32_emitf(node, "\tmovl $%u, %S1\n", attr->count);
1525 be_gas_emit_block_name(node);
1526 be_emit_cstring(":\n");
1527 be_emit_write_line();
1528 ia32_emitf(node, "\tmovl (%D0), %D0\n");
1529 ia32_emitf(node, "\tdec %S1\n");
1530 be_emit_cstring("\tjnz ");
1531 be_gas_emit_block_name(node);
1532 be_emit_finish_line_gas(node);
1535 static void emit_be_Return(const ir_node *node)
1537 unsigned pop = be_Return_get_pop(node);
1539 if (pop > 0 || be_Return_get_emit_pop(node)) {
1540 ia32_emitf(node, "\tret $%u\n", pop);
1542 ia32_emitf(node, "\tret\n");
1546 static void emit_Nothing(const ir_node *node)
1553 * Enters the emitter functions for handled nodes into the generic
1554 * pointer of an opcode.
1556 static void ia32_register_emitters(void)
1558 #define IA32_EMIT2(a,b) op_ia32_##a->ops.generic = (op_func)emit_ia32_##b
1559 #define IA32_EMIT(a) IA32_EMIT2(a,a)
1560 #define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
1561 #define IGN(a) op_##a->ops.generic = (op_func)emit_Nothing
1562 #define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
1563 #define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing
1565 /* first clear the generic function pointer for all ops */
1566 ir_clear_opcodes_generic_func();
1568 /* register all emitter functions defined in spec */
1569 ia32_register_spec_emitters();
1571 /* other ia32 emitter functions */
1572 IA32_EMIT2(Conv_I2I8Bit, Conv_I2I);
1577 IA32_EMIT(Conv_FP2FP);
1578 IA32_EMIT(Conv_FP2I);
1579 IA32_EMIT(Conv_I2FP);
1580 IA32_EMIT(Conv_I2I);
1587 IA32_EMIT(Minus64Bit);
1588 IA32_EMIT(SwitchJmp);
1589 IA32_EMIT(ClimbFrame);
1592 /* benode emitter */
1612 typedef void (*emit_func_ptr) (const ir_node *);
1615 * Assign and emit an exception label if the current instruction can fail.
1617 static void ia32_assign_exc_label(ir_node *node)
1619 /* assign a new ID to the instruction */
1620 set_ia32_exc_label_id(node, ++exc_label_id);
1622 ia32_emit_exc_label(node);
1624 be_emit_pad_comment();
1625 be_emit_cstring("/* exception to Block ");
1626 ia32_emit_cfop_target(node);
1627 be_emit_cstring(" */\n");
1628 be_emit_write_line();
1632 * Emits code for a node.
1634 static void ia32_emit_node(ir_node *node)
1636 ir_op *op = get_irn_op(node);
1638 DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
1640 if (is_ia32_irn(node)) {
1641 if (get_ia32_exc_label(node)) {
1642 /* emit the exception label of this instruction */
1643 ia32_assign_exc_label(node);
1645 if (mark_spill_reload) {
1646 if (is_ia32_is_spill(node)) {
1647 ia32_emitf(NULL, "\txchg %ebx, %ebx /* spill mark */\n");
1649 if (is_ia32_is_reload(node)) {
1650 ia32_emitf(NULL, "\txchg %edx, %edx /* reload mark */\n");
1652 if (is_ia32_is_remat(node)) {
1653 ia32_emitf(NULL, "\txchg %ecx, %ecx /* remat mark */\n");
1657 if (op->ops.generic) {
1658 emit_func_ptr func = (emit_func_ptr) op->ops.generic;
1660 be_dwarf_location(get_irn_dbg_info(node));
1665 ir_fprintf(stderr, "Error: No emit handler for node %+F (%+G, graph %+F)\n", node, node, current_ir_graph);
1670 int sp_change = arch_get_sp_bias(node);
1671 if (sp_change != 0) {
1672 assert(sp_change != SP_BIAS_RESET);
1673 callframe_offset += sp_change;
1674 be_dwarf_callframe_offset(callframe_offset);
1680 * Emits gas alignment directives
1682 static void ia32_emit_alignment(unsigned align, unsigned skip)
1684 ia32_emitf(NULL, "\t.p2align %u,,%u\n", align, skip);
1688 * Emits gas alignment directives for Labels depended on cpu architecture.
1690 static void ia32_emit_align_label(void)
1692 unsigned align = ia32_cg_config.label_alignment;
1693 unsigned maximum_skip = ia32_cg_config.label_alignment_max_skip;
1694 ia32_emit_alignment(align, maximum_skip);
1698 * Test whether a block should be aligned.
1699 * For cpus in the P4/Athlon class it is useful to align jump labels to
1700 * 16 bytes. However we should only do that if the alignment nops before the
1701 * label aren't executed more often than we have jumps to the label.
1703 static int should_align_block(const ir_node *block)
1705 static const double DELTA = .0001;
1706 ir_graph *irg = get_irn_irg(block);
1707 ir_exec_freq *exec_freq = be_get_irg_exec_freq(irg);
1708 ir_node *prev = get_prev_block_sched(block);
1710 double prev_freq = 0; /**< execfreq of the fallthrough block */
1711 double jmp_freq = 0; /**< execfreq of all non-fallthrough blocks */
1714 if (exec_freq == NULL)
1716 if (ia32_cg_config.label_alignment_factor <= 0)
1719 block_freq = get_block_execfreq(exec_freq, block);
1720 if (block_freq < DELTA)
1723 n_cfgpreds = get_Block_n_cfgpreds(block);
1724 for (i = 0; i < n_cfgpreds; ++i) {
1725 const ir_node *pred = get_Block_cfgpred_block(block, i);
1726 double pred_freq = get_block_execfreq(exec_freq, pred);
1729 prev_freq += pred_freq;
1731 jmp_freq += pred_freq;
1735 if (prev_freq < DELTA && !(jmp_freq < DELTA))
1738 jmp_freq /= prev_freq;
1740 return jmp_freq > ia32_cg_config.label_alignment_factor;
1744 * Emit the block header for a block.
1746 * @param block the block
1747 * @param prev_block the previous block
1749 static void ia32_emit_block_header(ir_node *block)
1751 ir_graph *irg = current_ir_graph;
1752 int need_label = block_needs_label(block);
1753 ir_exec_freq *exec_freq = be_get_irg_exec_freq(irg);
1756 if (block == get_irg_end_block(irg))
1759 if (ia32_cg_config.label_alignment > 0) {
1760 /* align the current block if:
1761 * a) if should be aligned due to its execution frequency
1762 * b) there is no fall-through here
1764 if (should_align_block(block)) {
1765 ia32_emit_align_label();
1767 /* if the predecessor block has no fall-through,
1768 we can always align the label. */
1770 int has_fallthrough = 0;
1772 for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
1773 ir_node *cfg_pred = get_Block_cfgpred(block, i);
1774 if (can_be_fallthrough(cfg_pred)) {
1775 has_fallthrough = 1;
1780 if (!has_fallthrough)
1781 ia32_emit_align_label();
1786 be_gas_emit_block_name(block);
1789 be_emit_pad_comment();
1790 be_emit_cstring(" /* ");
1792 be_emit_cstring("\t/* ");
1793 be_gas_emit_block_name(block);
1794 be_emit_cstring(": ");
1797 be_emit_cstring("preds:");
1799 /* emit list of pred blocks in comment */
1800 arity = get_irn_arity(block);
1802 be_emit_cstring(" none");
1805 for (i = 0; i < arity; ++i) {
1806 ir_node *predblock = get_Block_cfgpred_block(block, i);
1807 be_emit_irprintf(" %d", get_irn_node_nr(predblock));
1810 if (exec_freq != NULL) {
1811 be_emit_irprintf(", freq: %f",
1812 get_block_execfreq(exec_freq, block));
1814 be_emit_cstring(" */\n");
1815 be_emit_write_line();
1819 * Walks over the nodes in a block connected by scheduling edges
1820 * and emits code for each node.
1822 static void ia32_gen_block(ir_node *block)
1826 ia32_emit_block_header(block);
1829 ir_graph *irg = get_irn_irg(block);
1830 callframe_offset = 4; /* 4 bytes for the return address */
1831 /* ESP guessing, TODO perform a real ESP simulation */
1832 if (block != get_irg_start_block(irg)) {
1833 callframe_offset += frame_type_size;
1835 be_dwarf_callframe_offset(callframe_offset);
1838 /* emit the contents of the block */
1839 be_dwarf_location(get_irn_dbg_info(block));
1840 sched_foreach(block, node) {
1841 ia32_emit_node(node);
1845 typedef struct exc_entry {
1846 ir_node *exc_instr; /** The instruction that can issue an exception. */
1847 ir_node *block; /** The block to call then. */
1852 * Sets labels for control flow nodes (jump target).
1853 * Links control predecessors to there destination blocks.
1855 static void ia32_gen_labels(ir_node *block, void *data)
1857 exc_entry **exc_list = (exc_entry**)data;
1861 for (n = get_Block_n_cfgpreds(block) - 1; n >= 0; --n) {
1862 pred = get_Block_cfgpred(block, n);
1863 set_irn_link(pred, block);
1865 pred = skip_Proj(pred);
1866 if (is_ia32_irn(pred) && get_ia32_exc_label(pred)) {
1871 ARR_APP1(exc_entry, *exc_list, e);
1872 set_irn_link(pred, block);
1878 * Compare two exception_entries.
1880 static int cmp_exc_entry(const void *a, const void *b)
1882 const exc_entry *ea = (const exc_entry*)a;
1883 const exc_entry *eb = (const exc_entry*)b;
1885 if (get_ia32_exc_label_id(ea->exc_instr) < get_ia32_exc_label_id(eb->exc_instr))
1890 static parameter_dbg_info_t *construct_parameter_infos(ir_graph *irg)
1892 ir_entity *entity = get_irg_entity(irg);
1893 ir_type *type = get_entity_type(entity);
1894 size_t n_params = get_method_n_params(type);
1895 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
1896 ir_type *arg_type = layout->arg_type;
1897 size_t n_members = get_compound_n_members(arg_type);
1898 parameter_dbg_info_t *infos = XMALLOCNZ(parameter_dbg_info_t, n_params);
1901 for (i = 0; i < n_members; ++i) {
1902 ir_entity *member = get_compound_member(arg_type, i);
1904 if (!is_parameter_entity(member))
1906 param = get_entity_parameter_number(member);
1907 if (param == IR_VA_START_PARAMETER_NUMBER)
1909 assert(infos[param].entity == NULL && infos[param].reg == NULL);
1910 infos[param].reg = NULL;
1911 infos[param].entity = member;
1918 * Main driver. Emits the code for one routine.
1920 void ia32_gen_routine(ir_graph *irg)
1922 ir_entity *entity = get_irg_entity(irg);
1923 exc_entry *exc_list = NEW_ARR_F(exc_entry, 0);
1924 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
1925 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
1926 ir_node **blk_sched = irg_data->blk_sched;
1927 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
1928 parameter_dbg_info_t *infos;
1931 isa = (ia32_isa_t*) arch_env;
1932 do_pic = be_get_irg_options(irg)->pic;
1934 be_gas_elf_type_char = '@';
1936 ia32_register_emitters();
1938 get_unique_label(pic_base_label, sizeof(pic_base_label), "PIC_BASE");
1940 infos = construct_parameter_infos(irg);
1941 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
1945 sp_relative = layout->sp_relative;
1946 if (layout->sp_relative) {
1947 ir_type *frame_type = get_irg_frame_type(irg);
1948 frame_type_size = get_type_size_bytes(frame_type);
1949 be_dwarf_callframe_register(&ia32_registers[REG_ESP]);
1951 /* well not entirely correct here, we should emit this after the
1952 * "movl esp, ebp" */
1953 be_dwarf_callframe_register(&ia32_registers[REG_EBP]);
1954 /* TODO: do not hardcode the following */
1955 be_dwarf_callframe_offset(8);
1956 be_dwarf_callframe_spilloffset(&ia32_registers[REG_EBP], -8);
1959 /* we use links to point to target blocks */
1960 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
1961 irg_block_walk_graph(irg, ia32_gen_labels, NULL, &exc_list);
1963 /* initialize next block links */
1964 n = ARR_LEN(blk_sched);
1965 for (i = 0; i < n; ++i) {
1966 ir_node *block = blk_sched[i];
1967 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
1969 set_irn_link(block, prev);
1972 for (i = 0; i < n; ++i) {
1973 ir_node *block = blk_sched[i];
1975 ia32_gen_block(block);
1978 be_gas_emit_function_epilog(entity);
1980 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
1982 /* Sort the exception table using the exception label id's.
1983 Those are ascending with ascending addresses. */
1984 qsort(exc_list, ARR_LEN(exc_list), sizeof(exc_list[0]), cmp_exc_entry);
1988 for (e = 0; e < ARR_LEN(exc_list); ++e) {
1989 be_emit_cstring("\t.long ");
1990 ia32_emit_exc_label(exc_list[e].exc_instr);
1992 be_emit_cstring("\t.long ");
1993 be_gas_emit_block_name(exc_list[e].block);
1997 DEL_ARR_F(exc_list);
2000 static const lc_opt_table_entry_t ia32_emitter_options[] = {
2001 LC_OPT_ENT_BOOL("mark_spill_reload", "mark spills and reloads with ud opcodes", &mark_spill_reload),
2005 /* ==== Experimental binary emitter ==== */
2007 static unsigned char reg_gp_map[N_ia32_gp_REGS];
2008 //static unsigned char reg_mmx_map[N_ia32_mmx_REGS];
2009 //static unsigned char reg_sse_map[N_ia32_xmm_REGS];
2011 static void build_reg_map(void)
2013 reg_gp_map[REG_GP_EAX] = 0x0;
2014 reg_gp_map[REG_GP_ECX] = 0x1;
2015 reg_gp_map[REG_GP_EDX] = 0x2;
2016 reg_gp_map[REG_GP_EBX] = 0x3;
2017 reg_gp_map[REG_GP_ESP] = 0x4;
2018 reg_gp_map[REG_GP_EBP] = 0x5;
2019 reg_gp_map[REG_GP_ESI] = 0x6;
2020 reg_gp_map[REG_GP_EDI] = 0x7;
2023 /** Returns the encoding for a pnc field. */
2024 static unsigned char pnc2cc(ia32_condition_code_t cc)
2029 /** Sign extension bit values for binops */
2031 UNSIGNED_IMM = 0, /**< unsigned immediate */
2032 SIGNEXT_IMM = 2, /**< sign extended immediate */
2035 /** The mod encoding of the ModR/M */
2037 MOD_IND = 0x00, /**< [reg1] */
2038 MOD_IND_BYTE_OFS = 0x40, /**< [reg1 + byte ofs] */
2039 MOD_IND_WORD_OFS = 0x80, /**< [reg1 + word ofs] */
2040 MOD_REG = 0xC0 /**< reg1 */
2043 /** create R/M encoding for ModR/M */
2044 #define ENC_RM(x) (x)
2045 /** create REG encoding for ModR/M */
2046 #define ENC_REG(x) ((x) << 3)
2048 /** create encoding for a SIB byte */
2049 #define ENC_SIB(scale, index, base) ((scale) << 6 | (index) << 3 | (base))
2051 /* Node: The following routines are supposed to append bytes, words, dwords
2052 to the output stream.
2053 Currently the implementation is stupid in that it still creates output
2054 for an "assembler" in the form of .byte, .long
2055 We will change this when enough infrastructure is there to create complete
2056 machine code in memory/object files */
2058 static void bemit8(const unsigned char byte)
2060 be_emit_irprintf("\t.byte 0x%x\n", byte);
2061 be_emit_write_line();
2064 static void bemit16(const unsigned short u16)
2066 be_emit_irprintf("\t.word 0x%x\n", u16);
2067 be_emit_write_line();
2070 static void bemit32(const unsigned u32)
2072 be_emit_irprintf("\t.long 0x%x\n", u32);
2073 be_emit_write_line();
2077 * Emit address of an entity. If @p is_relative is true then a relative
2078 * offset from behind the address to the entity is created.
2080 static void bemit_entity(ir_entity *entity, bool entity_sign, int offset,
2083 if (entity == NULL) {
2088 /* the final version should remember the position in the bytestream
2089 and patch it with the correct address at linktime... */
2090 be_emit_cstring("\t.long ");
2093 be_gas_emit_entity(entity);
2095 if (get_entity_owner(entity) == get_tls_type()) {
2096 if (!entity_has_definition(entity)) {
2097 be_emit_cstring("@INDNTPOFF");
2099 be_emit_cstring("@NTPOFF");
2104 be_emit_cstring("-.");
2109 be_emit_irprintf("%+d", offset);
2112 be_emit_write_line();
2115 static void bemit_jmp_destination(const ir_node *dest_block)
2117 be_emit_cstring("\t.long ");
2118 be_gas_emit_block_name(dest_block);
2119 be_emit_cstring(" - . - 4\n");
2120 be_emit_write_line();
2123 /* end emit routines, all emitters following here should only use the functions
2126 typedef enum reg_modifier {
2131 /** Create a ModR/M byte for src1,src2 registers */
2132 static void bemit_modrr(const arch_register_t *src1,
2133 const arch_register_t *src2)
2135 unsigned char modrm = MOD_REG;
2136 modrm |= ENC_RM(reg_gp_map[src1->index]);
2137 modrm |= ENC_REG(reg_gp_map[src2->index]);
2141 /** Create a ModR/M8 byte for src1,src2 registers */
2142 static void bemit_modrr8(reg_modifier_t high_part1, const arch_register_t *src1,
2143 reg_modifier_t high_part2, const arch_register_t *src2)
2145 unsigned char modrm = MOD_REG;
2146 modrm |= ENC_RM(reg_gp_map[src1->index] + (high_part1 == REG_HIGH ? 4 : 0));
2147 modrm |= ENC_REG(reg_gp_map[src2->index] + (high_part2 == REG_HIGH ? 4 : 0));
2151 /** Create a ModR/M byte for one register and extension */
2152 static void bemit_modru(const arch_register_t *reg, unsigned ext)
2154 unsigned char modrm = MOD_REG;
2156 modrm |= ENC_RM(reg_gp_map[reg->index]);
2157 modrm |= ENC_REG(ext);
2161 /** Create a ModR/M8 byte for one register */
2162 static void bemit_modrm8(reg_modifier_t high_part, const arch_register_t *reg)
2164 unsigned char modrm = MOD_REG;
2165 assert(reg_gp_map[reg->index] < 4);
2166 modrm |= ENC_RM(reg_gp_map[reg->index] + (high_part == REG_HIGH ? 4 : 0));
2172 * Calculate the size of an signed immediate in bytes.
2174 * @param offset an offset
2176 static unsigned get_signed_imm_size(int offset)
2178 if (-128 <= offset && offset < 128) {
2180 } else if (-32768 <= offset && offset < 32768) {
2188 * Emit an address mode.
2190 * @param reg content of the reg field: either a register index or an opcode extension
2191 * @param node the node
2193 static void bemit_mod_am(unsigned reg, const ir_node *node)
2195 ir_entity *ent = get_ia32_am_sc(node);
2196 int offs = get_ia32_am_offs_int(node);
2197 ir_node *base = get_irn_n(node, n_ia32_base);
2198 int has_base = !is_ia32_NoReg_GP(base);
2199 ir_node *idx = get_irn_n(node, n_ia32_index);
2200 int has_index = !is_ia32_NoReg_GP(idx);
2203 unsigned emitoffs = 0;
2204 bool emitsib = false;
2207 /* set the mod part depending on displacement */
2209 modrm |= MOD_IND_WORD_OFS;
2211 } else if (offs == 0) {
2214 } else if (-128 <= offs && offs < 128) {
2215 modrm |= MOD_IND_BYTE_OFS;
2218 modrm |= MOD_IND_WORD_OFS;
2223 const arch_register_t *base_reg = arch_get_irn_register(base);
2224 base_enc = reg_gp_map[base_reg->index];
2226 /* Use the EBP encoding + MOD_IND if NO base register. There is
2227 * always a 32bit offset present in this case. */
2233 /* Determine if we need a SIB byte. */
2235 const arch_register_t *reg_index = arch_get_irn_register(idx);
2236 int scale = get_ia32_am_scale(node);
2238 /* R/M set to ESP means SIB in 32bit mode. */
2239 modrm |= ENC_RM(0x04);
2240 sib = ENC_SIB(scale, reg_gp_map[reg_index->index], base_enc);
2242 } else if (base_enc == 0x04) {
2243 /* for the above reason we are forced to emit a SIB when base is ESP.
2244 * Only the base is used, index must be ESP too, which means no index.
2246 modrm |= ENC_RM(0x04);
2247 sib = ENC_SIB(0, 0x04, 0x04);
2250 modrm |= ENC_RM(base_enc);
2253 /* We are forced to emit an 8bit offset as EBP base without offset is a
2254 * special case for SIB without base register. */
2255 if (base_enc == 0x05 && emitoffs == 0) {
2256 modrm |= MOD_IND_BYTE_OFS;
2260 modrm |= ENC_REG(reg);
2266 /* emit displacement */
2267 if (emitoffs == 8) {
2268 bemit8((unsigned) offs);
2269 } else if (emitoffs == 32) {
2270 bemit_entity(ent, is_ia32_am_sc_sign(node), offs, false);
2275 * Emit a binop with a immediate operand.
2277 * @param node the node to emit
2278 * @param opcode_eax the opcode for the op eax, imm variant
2279 * @param opcode the opcode for the reg, imm variant
2280 * @param ruval the opcode extension for opcode
2282 static void bemit_binop_with_imm(
2283 const ir_node *node,
2284 unsigned char opcode_ax,
2285 unsigned char opcode, unsigned char ruval)
2287 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2288 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2289 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2292 /* Some instructions (test) have no short form with 32bit value + 8bit
2294 if (attr->symconst != NULL || opcode & SIGNEXT_IMM) {
2297 /* check for sign extension */
2298 size = get_signed_imm_size(attr->offset);
2303 bemit8(opcode | SIGNEXT_IMM);
2304 /* cmp has this special mode */
2305 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2306 bemit_mod_am(ruval, node);
2308 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2309 bemit_modru(reg, ruval);
2311 bemit8((unsigned char)attr->offset);
2315 /* check for eax variant: this variant is shorter for 32bit immediates only */
2316 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2318 bemit_mod_am(ruval, node);
2320 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2321 if (reg->index == REG_GP_EAX) {
2325 bemit_modru(reg, ruval);
2328 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2331 panic("invalid imm size?!?");
2337 static void bemit_binop_2(const ir_node *node, unsigned code)
2339 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2341 if (get_ia32_op_type(node) == ia32_Normal) {
2342 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2343 bemit_modrr(op2, out);
2345 bemit_mod_am(reg_gp_map[out->index], node);
2352 static void bemit_binop(const ir_node *node, const unsigned char opcodes[4])
2354 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2355 if (is_ia32_Immediate(right)) {
2356 bemit_binop_with_imm(node, opcodes[1], opcodes[2], opcodes[3]);
2358 bemit_binop_2(node, opcodes[0]);
2365 static void bemit_unop(const ir_node *node, unsigned char code, unsigned char ext, int input)
2368 if (get_ia32_op_type(node) == ia32_Normal) {
2369 const arch_register_t *in = arch_get_irn_register_in(node, input);
2370 bemit_modru(in, ext);
2372 bemit_mod_am(ext, node);
2376 static void bemit_unop_reg(const ir_node *node, unsigned char code, int input)
2378 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2379 bemit_unop(node, code, reg_gp_map[out->index], input);
2382 static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned char ext)
2384 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
2387 bemit8(size == 8 ? code : code + 1);
2388 bemit_mod_am(ext, node);
2391 static void bemit_immediate(const ir_node *node, bool relative)
2393 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
2394 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, relative);
2397 static void bemit_copy(const ir_node *copy)
2399 const arch_register_t *in = arch_get_irn_register_in(copy, 0);
2400 const arch_register_t *out = arch_get_irn_register_out(copy, 0);
2404 /* copies of vf nodes aren't real... */
2405 if (arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
2408 assert(arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_gp]);
2410 bemit_modrr(in, out);
2413 static void bemit_perm(const ir_node *node)
2415 const arch_register_t *in0 = arch_get_irn_register(get_irn_n(node, 0));
2416 const arch_register_t *in1 = arch_get_irn_register(get_irn_n(node, 1));
2417 const arch_register_class_t *cls0 = arch_register_get_class(in0);
2419 assert(cls0 == arch_register_get_class(in1) && "Register class mismatch at Perm");
2421 if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
2422 if (in0->index == REG_GP_EAX) {
2423 bemit8(0x90 + reg_gp_map[in1->index]);
2424 } else if (in1->index == REG_GP_EAX) {
2425 bemit8(0x90 + reg_gp_map[in0->index]);
2428 bemit_modrr(in0, in1);
2430 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
2431 panic("unimplemented"); // TODO implement
2432 //ia32_emitf(NULL, "\txorpd %R, %R\n", in1, in0);
2433 //ia32_emitf(NULL, "\txorpd %R, %R\n", in0, in1);
2434 //ia32_emitf(node, "\txorpd %R, %R\n", in1, in0);
2435 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
2437 } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
2440 panic("unexpected register class in be_Perm (%+F)", node);
2444 static void bemit_xor0(const ir_node *node)
2446 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2448 bemit_modrr(out, out);
2451 static void bemit_mov_const(const ir_node *node)
2453 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2454 bemit8(0xB8 + reg_gp_map[out->index]);
2455 bemit_immediate(node, false);
2459 * Creates a function for a Binop with 3 possible encodings.
2461 #define BINOP(op, op0, op1, op2, op2_ext) \
2462 static void bemit_ ## op(const ir_node *node) { \
2463 static const unsigned char op ## _codes[] = {op0, op1, op2, op2_ext}; \
2464 bemit_binop(node, op ## _codes); \
2467 /* insn def eax,imm imm */
2468 BINOP(add, 0x03, 0x05, 0x81, 0)
2469 BINOP(or, 0x0B, 0x0D, 0x81, 1)
2470 BINOP(adc, 0x13, 0x15, 0x81, 2)
2471 BINOP(sbb, 0x1B, 0x1D, 0x81, 3)
2472 BINOP(and, 0x23, 0x25, 0x81, 4)
2473 BINOP(sub, 0x2B, 0x2D, 0x81, 5)
2474 BINOP(xor, 0x33, 0x35, 0x81, 6)
2475 BINOP(test, 0x85, 0xA9, 0xF7, 0)
2477 #define BINOPMEM(op, ext) \
2478 static void bemit_##op(const ir_node *node) \
2481 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2484 val = get_irn_n(node, n_ia32_unary_op); \
2485 if (is_ia32_Immediate(val)) { \
2486 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(val); \
2487 int offset = attr->offset; \
2488 if (attr->symconst == NULL && get_signed_imm_size(offset) == 1) { \
2490 bemit_mod_am(ext, node); \
2494 bemit_mod_am(ext, node); \
2498 bemit_entity(attr->symconst, attr->sc_sign, offset, false); \
2502 bemit8(ext << 3 | 1); \
2503 bemit_mod_am(reg_gp_map[arch_get_irn_register_out(val, 0)->index], node); \
2507 static void bemit_##op##8bit(const ir_node *node) \
2509 ir_node *val = get_irn_n(node, n_ia32_unary_op); \
2510 if (is_ia32_Immediate(val)) { \
2512 bemit_mod_am(ext, node); \
2513 bemit8(get_ia32_immediate_attr_const(val)->offset); \
2516 bemit_mod_am(reg_gp_map[arch_get_irn_register_out(val, 0)->index], node); \
2528 * Creates a function for an Unop with code /ext encoding.
2530 #define UNOP(op, code, ext, input) \
2531 static void bemit_ ## op(const ir_node *node) { \
2532 bemit_unop(node, code, ext, input); \
2535 UNOP(not, 0xF7, 2, n_ia32_Not_val)
2536 UNOP(neg, 0xF7, 3, n_ia32_Neg_val)
2537 UNOP(mul, 0xF7, 4, n_ia32_Mul_right)
2538 UNOP(imul1op, 0xF7, 5, n_ia32_IMul1OP_right)
2539 UNOP(div, 0xF7, 6, n_ia32_Div_divisor)
2540 UNOP(idiv, 0xF7, 7, n_ia32_IDiv_divisor)
2542 /* TODO: am support for IJmp */
2543 UNOP(ijmp, 0xFF, 4, n_ia32_IJmp_target)
2545 #define SHIFT(op, ext) \
2546 static void bemit_##op(const ir_node *node) \
2548 const arch_register_t *out = arch_get_irn_register_out(node, 0); \
2549 ir_node *count = get_irn_n(node, 1); \
2550 if (is_ia32_Immediate(count)) { \
2551 int offset = get_ia32_immediate_attr_const(count)->offset; \
2552 if (offset == 1) { \
2554 bemit_modru(out, ext); \
2557 bemit_modru(out, ext); \
2562 bemit_modru(out, ext); \
2566 static void bemit_##op##mem(const ir_node *node) \
2569 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
2572 count = get_irn_n(node, 1); \
2573 if (is_ia32_Immediate(count)) { \
2574 int offset = get_ia32_immediate_attr_const(count)->offset; \
2575 if (offset == 1) { \
2576 bemit8(size == 8 ? 0xD0 : 0xD1); \
2577 bemit_mod_am(ext, node); \
2579 bemit8(size == 8 ? 0xC0 : 0xC1); \
2580 bemit_mod_am(ext, node); \
2584 bemit8(size == 8 ? 0xD2 : 0xD3); \
2585 bemit_mod_am(ext, node); \
2595 static void bemit_shld(const ir_node *node)
2597 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShlD_val_low);
2598 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShlD_res);
2599 ir_node *count = get_irn_n(node, n_ia32_ShlD_count);
2601 if (is_ia32_Immediate(count)) {
2603 bemit_modrr(out, in);
2604 bemit8(get_ia32_immediate_attr_const(count)->offset);
2607 bemit_modrr(out, in);
2611 static void bemit_shrd(const ir_node *node)
2613 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_ShrD_val_low);
2614 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_ShrD_res);
2615 ir_node *count = get_irn_n(node, n_ia32_ShrD_count);
2617 if (is_ia32_Immediate(count)) {
2619 bemit_modrr(out, in);
2620 bemit8(get_ia32_immediate_attr_const(count)->offset);
2623 bemit_modrr(out, in);
2628 * binary emitter for setcc.
2630 static void bemit_setcc(const ir_node *node)
2632 const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
2634 ia32_condition_code_t cc = get_ia32_condcode(node);
2635 cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
2636 if (cc & ia32_cc_float_parity_cases) {
2637 if (cc & ia32_cc_negated) {
2640 bemit8(0x90 | pnc2cc(cc));
2641 bemit_modrm8(REG_LOW, dreg);
2646 bemit_modrm8(REG_HIGH, dreg);
2648 /* orb %>dreg, %<dreg */
2650 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2654 bemit8(0x90 | pnc2cc(cc));
2655 bemit_modrm8(REG_LOW, dreg);
2660 bemit_modrm8(REG_HIGH, dreg);
2662 /* andb %>dreg, %<dreg */
2664 bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
2669 bemit8(0x90 | pnc2cc(cc));
2670 bemit_modrm8(REG_LOW, dreg);
2674 static void bemit_cmovcc(const ir_node *node)
2676 const ia32_attr_t *attr = get_ia32_attr_const(node);
2677 int ins_permuted = attr->data.ins_permuted;
2678 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_res);
2679 ia32_condition_code_t cc = get_ia32_condcode(node);
2680 const arch_register_t *in_true;
2681 const arch_register_t *in_false;
2683 cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
2685 in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
2686 in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
2688 /* should be same constraint fullfilled? */
2689 if (out == in_false) {
2690 /* yes -> nothing to do */
2691 } else if (out == in_true) {
2692 assert(get_ia32_op_type(node) == ia32_Normal);
2693 ins_permuted = !ins_permuted;
2697 bemit8(0x8B); // mov %in_false, %out
2698 bemit_modrr(in_false, out);
2702 cc = ia32_negate_condition_code(cc);
2704 if (cc & ia32_cc_float_parity_cases)
2705 panic("cmov can't handle parity float cases");
2708 bemit8(0x40 | pnc2cc(cc));
2709 if (get_ia32_op_type(node) == ia32_Normal) {
2710 bemit_modrr(in_true, out);
2712 bemit_mod_am(reg_gp_map[out->index], node);
2716 static void bemit_cmp(const ir_node *node)
2718 unsigned ls_size = get_mode_size_bits(get_ia32_ls_mode(node));
2724 right = get_irn_n(node, n_ia32_binary_right);
2725 if (is_ia32_Immediate(right)) {
2726 /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
2727 const ir_node *op = get_irn_n(node, n_ia32_binary_right);
2728 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
2731 if (attr->symconst != NULL) {
2734 /* check for sign extension */
2735 size = get_signed_imm_size(attr->offset);
2740 bemit8(0x81 | SIGNEXT_IMM);
2741 /* cmp has this special mode */
2742 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2743 bemit_mod_am(7, node);
2745 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2746 bemit_modru(reg, 7);
2748 bemit8((unsigned char)attr->offset);
2752 /* check for eax variant: this variant is shorter for 32bit immediates only */
2753 if (get_ia32_op_type(node) == ia32_AddrModeS) {
2755 bemit_mod_am(7, node);
2757 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
2758 if (reg->index == REG_GP_EAX) {
2762 bemit_modru(reg, 7);
2765 if (ls_size == 16) {
2766 bemit16(attr->offset);
2768 bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
2772 panic("invalid imm size?!?");
2774 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
2776 if (get_ia32_op_type(node) == ia32_Normal) {
2777 const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
2778 bemit_modrr(op2, out);
2780 bemit_mod_am(reg_gp_map[out->index], node);
2785 static void bemit_cmp8bit(const ir_node *node)
2787 ir_node *right = get_irn_n(node, n_ia32_binary_right);
2788 if (is_ia32_Immediate(right)) {
2789 if (get_ia32_op_type(node) == ia32_Normal) {
2790 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2791 if (out->index == REG_GP_EAX) {
2795 bemit_modru(out, 7);
2799 bemit_mod_am(7, node);
2801 bemit8(get_ia32_immediate_attr_const(right)->offset);
2803 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
2805 if (get_ia32_op_type(node) == ia32_Normal) {
2806 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Cmp_right);
2807 bemit_modrr(out, in);
2809 bemit_mod_am(reg_gp_map[out->index], node);
2814 static void bemit_test8bit(const ir_node *node)
2816 ir_node *right = get_irn_n(node, n_ia32_Test8Bit_right);
2817 if (is_ia32_Immediate(right)) {
2818 if (get_ia32_op_type(node) == ia32_Normal) {
2819 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
2820 if (out->index == REG_GP_EAX) {
2824 bemit_modru(out, 0);
2828 bemit_mod_am(0, node);
2830 bemit8(get_ia32_immediate_attr_const(right)->offset);
2832 const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Test8Bit_left);
2834 if (get_ia32_op_type(node) == ia32_Normal) {
2835 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Test8Bit_right);
2836 bemit_modrr(out, in);
2838 bemit_mod_am(reg_gp_map[out->index], node);
2843 static void bemit_imul(const ir_node *node)
2845 ir_node *right = get_irn_n(node, n_ia32_IMul_right);
2846 /* Do we need the immediate form? */
2847 if (is_ia32_Immediate(right)) {
2848 int imm = get_ia32_immediate_attr_const(right)->offset;
2849 if (get_signed_imm_size(imm) == 1) {
2850 bemit_unop_reg(node, 0x6B, n_ia32_IMul_left);
2853 bemit_unop_reg(node, 0x69, n_ia32_IMul_left);
2858 bemit_unop_reg(node, 0xAF, n_ia32_IMul_right);
2862 static void bemit_dec(const ir_node *node)
2864 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Dec_res);
2865 bemit8(0x48 + reg_gp_map[out->index]);
2868 static void bemit_inc(const ir_node *node)
2870 const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Inc_res);
2871 bemit8(0x40 + reg_gp_map[out->index]);
2874 #define UNOPMEM(op, code, ext) \
2875 static void bemit_##op(const ir_node *node) \
2877 bemit_unop_mem(node, code, ext); \
2880 UNOPMEM(notmem, 0xF6, 2)
2881 UNOPMEM(negmem, 0xF6, 3)
2882 UNOPMEM(incmem, 0xFE, 0)
2883 UNOPMEM(decmem, 0xFE, 1)
2885 static void bemit_ldtls(const ir_node *node)
2887 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2889 bemit8(0x65); // gs:
2890 if (out->index == REG_GP_EAX) {
2891 bemit8(0xA1); // movl 0, %eax
2893 bemit8(0x8B); // movl 0, %reg
2894 bemit8(MOD_IND | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x05));
2902 static void bemit_lea(const ir_node *node)
2904 const arch_register_t *out = arch_get_irn_register_out(node, 0);
2906 bemit_mod_am(reg_gp_map[out->index], node);
2909 /* helper function for bemit_minus64bit */
2910 static void bemit_helper_mov(const arch_register_t *src, const arch_register_t *dst)
2912 bemit8(0x8B); // movl %src, %dst
2913 bemit_modrr(src, dst);
2916 /* helper function for bemit_minus64bit */
2917 static void bemit_helper_neg(const arch_register_t *reg)
2919 bemit8(0xF7); // negl %reg
2920 bemit_modru(reg, 3);
2923 /* helper function for bemit_minus64bit */
2924 static void bemit_helper_sbb0(const arch_register_t *reg)
2926 bemit8(0x83); // sbbl $0, %reg
2927 bemit_modru(reg, 3);
2931 /* helper function for bemit_minus64bit */
2932 static void bemit_helper_sbb(const arch_register_t *src, const arch_register_t *dst)
2934 bemit8(0x1B); // sbbl %src, %dst
2935 bemit_modrr(src, dst);
2938 /* helper function for bemit_minus64bit */
2939 static void bemit_helper_xchg(const arch_register_t *src, const arch_register_t *dst)
2941 if (src->index == REG_GP_EAX) {
2942 bemit8(0x90 + reg_gp_map[dst->index]); // xchgl %eax, %dst
2943 } else if (dst->index == REG_GP_EAX) {
2944 bemit8(0x90 + reg_gp_map[src->index]); // xchgl %src, %eax
2946 bemit8(0x87); // xchgl %src, %dst
2947 bemit_modrr(src, dst);
2951 /* helper function for bemit_minus64bit */
2952 static void bemit_helper_zero(const arch_register_t *reg)
2954 bemit8(0x33); // xorl %reg, %reg
2955 bemit_modrr(reg, reg);
2958 static void bemit_minus64bit(const ir_node *node)
2960 const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
2961 const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
2962 const arch_register_t *out_lo = arch_get_irn_register_out(node, 0);
2963 const arch_register_t *out_hi = arch_get_irn_register_out(node, 1);
2965 if (out_lo == in_lo) {
2966 if (out_hi != in_hi) {
2967 /* a -> a, b -> d */
2970 /* a -> a, b -> b */
2973 } else if (out_lo == in_hi) {
2974 if (out_hi == in_lo) {
2975 /* a -> b, b -> a */
2976 bemit_helper_xchg(in_lo, in_hi);
2979 /* a -> b, b -> d */
2980 bemit_helper_mov(in_hi, out_hi);
2981 bemit_helper_mov(in_lo, out_lo);
2985 if (out_hi == in_lo) {
2986 /* a -> c, b -> a */
2987 bemit_helper_mov(in_lo, out_lo);
2989 } else if (out_hi == in_hi) {
2990 /* a -> c, b -> b */
2991 bemit_helper_mov(in_lo, out_lo);
2994 /* a -> c, b -> d */
2995 bemit_helper_mov(in_lo, out_lo);
3001 bemit_helper_neg( out_hi);
3002 bemit_helper_neg( out_lo);
3003 bemit_helper_sbb0(out_hi);
3007 bemit_helper_zero(out_hi);
3008 bemit_helper_neg( out_lo);
3009 bemit_helper_sbb( in_hi, out_hi);
3013 * Emit a single opcode.
3015 #define EMIT_SINGLEOP(op, code) \
3016 static void bemit_ ## op(const ir_node *node) { \
3021 //EMIT_SINGLEOP(daa, 0x27)
3022 //EMIT_SINGLEOP(das, 0x2F)
3023 //EMIT_SINGLEOP(aaa, 0x37)
3024 //EMIT_SINGLEOP(aas, 0x3F)
3025 //EMIT_SINGLEOP(nop, 0x90)
3026 EMIT_SINGLEOP(cwtl, 0x98)
3027 EMIT_SINGLEOP(cltd, 0x99)
3028 //EMIT_SINGLEOP(fwait, 0x9B)
3029 EMIT_SINGLEOP(sahf, 0x9E)
3030 //EMIT_SINGLEOP(popf, 0x9D)
3031 EMIT_SINGLEOP(leave, 0xC9)
3032 EMIT_SINGLEOP(int3, 0xCC)
3033 //EMIT_SINGLEOP(iret, 0xCF)
3034 //EMIT_SINGLEOP(xlat, 0xD7)
3035 //EMIT_SINGLEOP(lock, 0xF0)
3036 EMIT_SINGLEOP(rep, 0xF3)
3037 //EMIT_SINGLEOP(halt, 0xF4)
3038 EMIT_SINGLEOP(cmc, 0xF5)
3039 EMIT_SINGLEOP(stc, 0xF9)
3040 //EMIT_SINGLEOP(cli, 0xFA)
3041 //EMIT_SINGLEOP(sti, 0xFB)
3042 //EMIT_SINGLEOP(std, 0xFD)
3045 * Emits a MOV out, [MEM].
3047 static void bemit_load(const ir_node *node)
3049 const arch_register_t *out = arch_get_irn_register_out(node, 0);
3051 if (out->index == REG_GP_EAX) {
3052 ir_node *base = get_irn_n(node, n_ia32_base);
3053 int has_base = !is_ia32_NoReg_GP(base);
3054 ir_node *idx = get_irn_n(node, n_ia32_index);
3055 int has_index = !is_ia32_NoReg_GP(idx);
3056 if (!has_base && !has_index) {
3057 ir_entity *ent = get_ia32_am_sc(node);
3058 int offs = get_ia32_am_offs_int(node);
3059 /* load from constant address to EAX can be encoded
3062 bemit_entity(ent, 0, offs, false);
3067 bemit_mod_am(reg_gp_map[out->index], node);
3071 * Emits a MOV [mem], in.
3073 static void bemit_store(const ir_node *node)
3075 const ir_node *value = get_irn_n(node, n_ia32_Store_val);
3076 unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
3078 if (is_ia32_Immediate(value)) {
3081 bemit_mod_am(0, node);
3082 bemit8(get_ia32_immediate_attr_const(value)->offset);
3083 } else if (size == 16) {
3086 bemit_mod_am(0, node);
3087 bemit16(get_ia32_immediate_attr_const(value)->offset);
3090 bemit_mod_am(0, node);
3091 bemit_immediate(value, false);
3094 const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Store_val);
3096 if (in->index == REG_GP_EAX) {
3097 ir_node *base = get_irn_n(node, n_ia32_base);
3098 int has_base = !is_ia32_NoReg_GP(base);
3099 ir_node *idx = get_irn_n(node, n_ia32_index);
3100 int has_index = !is_ia32_NoReg_GP(idx);
3101 if (!has_base && !has_index) {
3102 ir_entity *ent = get_ia32_am_sc(node);
3103 int offs = get_ia32_am_offs_int(node);
3104 /* store to constant address from EAX can be encoded as
3105 * 0xA2/0xA3 [offset]*/
3113 bemit_entity(ent, 0, offs, false);
3125 bemit_mod_am(reg_gp_map[in->index], node);
3129 static void bemit_conv_i2i(const ir_node *node)
3131 ir_mode *smaller_mode = get_ia32_ls_mode(node);
3140 if (mode_is_signed(smaller_mode)) opcode |= 0x08;
3141 if (get_mode_size_bits(smaller_mode) == 16) opcode |= 0x01;
3142 bemit_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
3148 static void bemit_push(const ir_node *node)
3150 const ir_node *value = get_irn_n(node, n_ia32_Push_val);
3152 if (is_ia32_Immediate(value)) {
3153 const ia32_immediate_attr_t *attr
3154 = get_ia32_immediate_attr_const(value);
3155 unsigned size = get_signed_imm_size(attr->offset);
3161 bemit8((unsigned char)attr->offset);
3166 bemit_immediate(value, false);
3169 } else if (is_ia32_NoReg_GP(value)) {
3171 bemit_mod_am(6, node);
3173 const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_Push_val);
3174 bemit8(0x50 + reg_gp_map[reg->index]);
3181 static void bemit_pop(const ir_node *node)
3183 const arch_register_t *reg = arch_get_irn_register_out(node, pn_ia32_Pop_res);
3184 bemit8(0x58 + reg_gp_map[reg->index]);
3187 static void bemit_popmem(const ir_node *node)
3190 bemit_mod_am(0, node);
3193 static void bemit_call(const ir_node *node)
3195 ir_node *proc = get_irn_n(node, n_ia32_Call_addr);
3197 if (is_ia32_Immediate(proc)) {
3199 bemit_immediate(proc, true);
3201 bemit_unop(node, 0xFF, 2, n_ia32_Call_addr);
3205 static void bemit_jmp(const ir_node *dest_block)
3208 bemit_jmp_destination(dest_block);
3211 static void bemit_jump(const ir_node *node)
3213 if (can_be_fallthrough(node))
3216 bemit_jmp(get_cfop_target_block(node));
3219 static void bemit_jcc(int pnc, const ir_node *dest_block)
3221 unsigned char cc = pnc2cc(pnc);
3224 bemit_jmp_destination(dest_block);
3227 static void bemit_jp(bool odd, const ir_node *dest_block)
3231 bemit_jmp_destination(dest_block);
3234 static void bemit_ia32_jcc(const ir_node *node)
3236 ia32_condition_code_t cc = get_ia32_condcode(node);
3237 const ir_node *proj_true;
3238 const ir_node *proj_false;
3239 const ir_node *dest_true;
3240 const ir_node *dest_false;
3242 cc = determine_final_cc(node, 0, cc);
3244 /* get both Projs */
3245 proj_true = get_proj(node, pn_ia32_Jcc_true);
3246 assert(proj_true && "Jcc without true Proj");
3248 proj_false = get_proj(node, pn_ia32_Jcc_false);
3249 assert(proj_false && "Jcc without false Proj");
3251 if (can_be_fallthrough(proj_true)) {
3252 /* exchange both proj's so the second one can be omitted */
3253 const ir_node *t = proj_true;
3255 proj_true = proj_false;
3257 cc = ia32_negate_condition_code(cc);
3260 dest_true = get_cfop_target_block(proj_true);
3261 dest_false = get_cfop_target_block(proj_false);
3263 if (cc & ia32_cc_float_parity_cases) {
3264 /* Some floating point comparisons require a test of the parity flag,
3265 * which indicates that the result is unordered */
3266 if (cc & ia32_cc_negated) {
3267 bemit_jp(false, dest_true);
3269 /* we need a local label if the false proj is a fallthrough
3270 * as the falseblock might have no label emitted then */
3271 if (can_be_fallthrough(proj_false)) {
3273 bemit8(0x06); // jp + 6
3275 bemit_jp(false, dest_false);
3279 bemit_jcc(cc, dest_true);
3281 /* the second Proj might be a fallthrough */
3282 if (can_be_fallthrough(proj_false)) {
3283 /* it's a fallthrough */
3285 bemit_jmp(dest_false);
3289 static void bemit_switchjmp(const ir_node *node)
3291 ir_entity *jump_table = get_ia32_am_sc(node);
3292 const ir_switch_table *table = get_ia32_switch_table(node);
3294 bemit8(0xFF); // jmp *tbl.label(,%in,4)
3295 bemit_mod_am(0x05, node);
3297 be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
3303 static void bemit_return(const ir_node *node)
3305 unsigned pop = be_Return_get_pop(node);
3306 if (pop > 0 || be_Return_get_emit_pop(node)) {
3308 assert(pop <= 0xffff);
3315 static void bemit_subsp(const ir_node *node)
3317 const arch_register_t *out;
3320 /* mov %esp, %out */
3322 out = arch_get_irn_register_out(node, 1);
3323 bemit8(MOD_REG | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x04));
3326 static void bemit_incsp(const ir_node *node)
3329 const arch_register_t *reg;
3333 offs = be_get_IncSP_offset(node);
3344 size = get_signed_imm_size(offs);
3345 bemit8(size == 1 ? 0x83 : 0x81);
3347 reg = arch_get_irn_register_out(node, 0);
3348 bemit_modru(reg, ext);
3357 static void bemit_copybi(const ir_node *node)
3359 unsigned size = get_ia32_copyb_size(node);
3361 bemit8(0xA4); // movsb
3364 bemit8(0xA5); // movsw
3368 bemit8(0xA5); // movsl
3372 static void bemit_fbinop(const ir_node *node, unsigned code, unsigned code_to)
3374 if (get_ia32_op_type(node) == ia32_Normal) {
3375 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
3376 const arch_register_t *in1 = x87_attr->x87[0];
3377 const arch_register_t *in = x87_attr->x87[1];
3378 const arch_register_t *out = x87_attr->x87[2];
3382 } else if (out == in) {
3386 if (out->index == 0) {
3388 bemit8(MOD_REG | ENC_REG(code) | ENC_RM(in->index));
3391 bemit8(MOD_REG | ENC_REG(code_to) | ENC_RM(out->index));
3394 if (get_mode_size_bits(get_ia32_ls_mode(node)) == 32) {
3399 bemit_mod_am(code, node);
3403 static void bemit_fbinopp(const ir_node *node, unsigned const code)
3405 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
3406 const arch_register_t *out = x87_attr->x87[2];
3408 bemit8(code + out->index);
3411 static void bemit_fabs(const ir_node *node)
3419 static void bemit_fadd(const ir_node *node)
3421 bemit_fbinop(node, 0, 0);
3424 static void bemit_faddp(const ir_node *node)
3426 bemit_fbinopp(node, 0xC0);
3429 static void bemit_fchs(const ir_node *node)
3437 static void bemit_fdiv(const ir_node *node)
3439 bemit_fbinop(node, 6, 7);
3442 static void bemit_fdivp(const ir_node *node)
3444 bemit_fbinopp(node, 0xF8);
3447 static void bemit_fdivr(const ir_node *node)
3449 bemit_fbinop(node, 7, 6);
3452 static void bemit_fdivrp(const ir_node *node)
3454 bemit_fbinopp(node, 0xF0);
3457 static void bemit_fild(const ir_node *node)
3459 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3461 bemit8(0xDF); // filds
3462 bemit_mod_am(0, node);
3466 bemit8(0xDB); // fildl
3467 bemit_mod_am(0, node);
3471 bemit8(0xDF); // fildll
3472 bemit_mod_am(5, node);
3476 panic("invalid mode size");
3480 static void bemit_fist(const ir_node *node)
3482 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3484 bemit8(0xDF); // fists
3488 bemit8(0xDB); // fistl
3492 panic("invalid mode size");
3494 bemit_mod_am(2, node);
3497 static void bemit_fistp(const ir_node *node)
3499 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3501 bemit8(0xDF); // fistps
3502 bemit_mod_am(3, node);
3506 bemit8(0xDB); // fistpl
3507 bemit_mod_am(3, node);
3511 bemit8(0xDF); // fistpll
3512 bemit_mod_am(7, node);
3516 panic("invalid mode size");
3520 static void bemit_fld(const ir_node *node)
3522 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3524 bemit8(0xD9); // flds
3525 bemit_mod_am(0, node);
3529 bemit8(0xDD); // fldl
3530 bemit_mod_am(0, node);
3535 bemit8(0xDB); // fldt
3536 bemit_mod_am(5, node);
3540 panic("invalid mode size");
3544 static void bemit_fld1(const ir_node *node)
3548 bemit8(0xE8); // fld1
3551 static void bemit_fldcw(const ir_node *node)
3553 bemit8(0xD9); // fldcw
3554 bemit_mod_am(5, node);
3557 static void bemit_fldz(const ir_node *node)
3561 bemit8(0xEE); // fldz
3564 static void bemit_fmul(const ir_node *node)
3566 bemit_fbinop(node, 1, 1);
3569 static void bemit_fmulp(const ir_node *node)
3571 bemit_fbinopp(node, 0xC8);
3574 static void bemit_fpop(const ir_node *node)
3576 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3578 bemit8(0xD8 + attr->x87[0]->index);
3581 static void bemit_fpush(const ir_node *node)
3583 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3585 bemit8(0xC0 + attr->x87[0]->index);
3588 static void bemit_fpushcopy(const ir_node *node)
3590 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3592 bemit8(0xC0 + attr->x87[0]->index);
3595 static void bemit_fst(const ir_node *node)
3597 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3599 bemit8(0xD9); // fsts
3603 bemit8(0xDD); // fstl
3607 panic("invalid mode size");
3609 bemit_mod_am(2, node);
3612 static void bemit_fstp(const ir_node *node)
3614 switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
3616 bemit8(0xD9); // fstps
3617 bemit_mod_am(3, node);
3621 bemit8(0xDD); // fstpl
3622 bemit_mod_am(3, node);
3627 bemit8(0xDB); // fstpt
3628 bemit_mod_am(7, node);
3632 panic("invalid mode size");
3636 static void bemit_fsub(const ir_node *node)
3638 bemit_fbinop(node, 4, 5);
3641 static void bemit_fsubp(const ir_node *node)
3643 bemit_fbinopp(node, 0xE8);
3646 static void bemit_fsubr(const ir_node *node)
3648 bemit_fbinop(node, 5, 4);
3651 static void bemit_fsubrp(const ir_node *node)
3653 bemit_fbinopp(node, 0xE0);
3656 static void bemit_fnstcw(const ir_node *node)
3658 bemit8(0xD9); // fnstcw
3659 bemit_mod_am(7, node);
3662 static void bemit_fnstsw(void)
3664 bemit8(0xDF); // fnstsw %ax
3668 static void bemit_ftstfnstsw(const ir_node *node)
3672 bemit8(0xD9); // ftst
3677 static void bemit_fucomi(const ir_node *node)
3679 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3680 bemit8(0xDB); // fucomi
3681 bemit8(0xE8 + attr->x87[1]->index);
3684 static void bemit_fucomip(const ir_node *node)
3686 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3687 bemit8(0xDF); // fucomip
3688 bemit8(0xE8 + attr->x87[1]->index);
3691 static void bemit_fucomfnstsw(const ir_node *node)
3693 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3694 bemit8(0xDD); // fucom
3695 bemit8(0xE0 + attr->x87[1]->index);
3699 static void bemit_fucompfnstsw(const ir_node *node)
3701 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3702 bemit8(0xDD); // fucomp
3703 bemit8(0xE8 + attr->x87[1]->index);
3707 static void bemit_fucomppfnstsw(const ir_node *node)
3711 bemit8(0xDA); // fucompp
3716 static void bemit_fxch(const ir_node *node)
3718 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
3720 bemit8(0xC8 + attr->x87[0]->index);
3724 * The type of a emitter function.
3726 typedef void (*emit_func) (const ir_node *);
3729 * Set a node emitter. Make it a bit more type safe.
3731 static void register_emitter(ir_op *op, emit_func func)
3733 op->ops.generic = (op_func) func;
3736 static void ia32_register_binary_emitters(void)
3738 /* first clear the generic function pointer for all ops */
3739 ir_clear_opcodes_generic_func();
3741 /* benode emitter */
3742 register_emitter(op_be_Copy, bemit_copy);
3743 register_emitter(op_be_CopyKeep, bemit_copy);
3744 register_emitter(op_be_IncSP, bemit_incsp);
3745 register_emitter(op_be_Perm, bemit_perm);
3746 register_emitter(op_be_Return, bemit_return);
3747 register_emitter(op_ia32_Adc, bemit_adc);
3748 register_emitter(op_ia32_Add, bemit_add);
3749 register_emitter(op_ia32_AddMem, bemit_addmem);
3750 register_emitter(op_ia32_AddMem8Bit, bemit_addmem8bit);
3751 register_emitter(op_ia32_And, bemit_and);
3752 register_emitter(op_ia32_AndMem, bemit_andmem);
3753 register_emitter(op_ia32_AndMem8Bit, bemit_andmem8bit);
3754 register_emitter(op_ia32_Breakpoint, bemit_int3);
3755 register_emitter(op_ia32_CMovcc, bemit_cmovcc);
3756 register_emitter(op_ia32_Call, bemit_call);
3757 register_emitter(op_ia32_Cltd, bemit_cltd);
3758 register_emitter(op_ia32_Cmc, bemit_cmc);
3759 register_emitter(op_ia32_Cmp, bemit_cmp);
3760 register_emitter(op_ia32_Cmp8Bit, bemit_cmp8bit);
3761 register_emitter(op_ia32_Const, bemit_mov_const);
3762 register_emitter(op_ia32_Conv_I2I, bemit_conv_i2i);
3763 register_emitter(op_ia32_Conv_I2I8Bit, bemit_conv_i2i);
3764 register_emitter(op_ia32_CopyB_i, bemit_copybi);
3765 register_emitter(op_ia32_Cwtl, bemit_cwtl);
3766 register_emitter(op_ia32_Dec, bemit_dec);
3767 register_emitter(op_ia32_DecMem, bemit_decmem);
3768 register_emitter(op_ia32_Div, bemit_div);
3769 register_emitter(op_ia32_FldCW, bemit_fldcw);
3770 register_emitter(op_ia32_FnstCW, bemit_fnstcw);
3771 register_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw);
3772 register_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw);
3773 register_emitter(op_ia32_Fucomi, bemit_fucomi);
3774 register_emitter(op_ia32_FucompFnstsw, bemit_fucompfnstsw);
3775 register_emitter(op_ia32_Fucompi, bemit_fucomip);
3776 register_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw);
3777 register_emitter(op_ia32_IDiv, bemit_idiv);
3778 register_emitter(op_ia32_IJmp, bemit_ijmp);
3779 register_emitter(op_ia32_IMul, bemit_imul);
3780 register_emitter(op_ia32_IMul1OP, bemit_imul1op);
3781 register_emitter(op_ia32_Inc, bemit_inc);
3782 register_emitter(op_ia32_IncMem, bemit_incmem);
3783 register_emitter(op_ia32_Jcc, bemit_ia32_jcc);
3784 register_emitter(op_ia32_Jmp, bemit_jump);
3785 register_emitter(op_ia32_LdTls, bemit_ldtls);
3786 register_emitter(op_ia32_Lea, bemit_lea);
3787 register_emitter(op_ia32_Leave, bemit_leave);
3788 register_emitter(op_ia32_Load, bemit_load);
3789 register_emitter(op_ia32_Minus64Bit, bemit_minus64bit);
3790 register_emitter(op_ia32_Mul, bemit_mul);
3791 register_emitter(op_ia32_Neg, bemit_neg);
3792 register_emitter(op_ia32_NegMem, bemit_negmem);
3793 register_emitter(op_ia32_Not, bemit_not);
3794 register_emitter(op_ia32_NotMem, bemit_notmem);
3795 register_emitter(op_ia32_Or, bemit_or);
3796 register_emitter(op_ia32_OrMem, bemit_ormem);
3797 register_emitter(op_ia32_OrMem8Bit, bemit_ormem8bit);
3798 register_emitter(op_ia32_Pop, bemit_pop);
3799 register_emitter(op_ia32_PopEbp, bemit_pop);
3800 register_emitter(op_ia32_PopMem, bemit_popmem);
3801 register_emitter(op_ia32_Push, bemit_push);
3802 register_emitter(op_ia32_RepPrefix, bemit_rep);
3803 register_emitter(op_ia32_Rol, bemit_rol);
3804 register_emitter(op_ia32_RolMem, bemit_rolmem);
3805 register_emitter(op_ia32_Ror, bemit_ror);
3806 register_emitter(op_ia32_RorMem, bemit_rormem);
3807 register_emitter(op_ia32_Sahf, bemit_sahf);
3808 register_emitter(op_ia32_Sar, bemit_sar);
3809 register_emitter(op_ia32_SarMem, bemit_sarmem);
3810 register_emitter(op_ia32_Sbb, bemit_sbb);
3811 register_emitter(op_ia32_Setcc, bemit_setcc);
3812 register_emitter(op_ia32_Shl, bemit_shl);
3813 register_emitter(op_ia32_ShlD, bemit_shld);
3814 register_emitter(op_ia32_ShlMem, bemit_shlmem);
3815 register_emitter(op_ia32_Shr, bemit_shr);
3816 register_emitter(op_ia32_ShrD, bemit_shrd);
3817 register_emitter(op_ia32_ShrMem, bemit_shrmem);
3818 register_emitter(op_ia32_Stc, bemit_stc);
3819 register_emitter(op_ia32_Store, bemit_store);
3820 register_emitter(op_ia32_Store8Bit, bemit_store);
3821 register_emitter(op_ia32_Sub, bemit_sub);
3822 register_emitter(op_ia32_SubMem, bemit_submem);
3823 register_emitter(op_ia32_SubMem8Bit, bemit_submem8bit);
3824 register_emitter(op_ia32_SubSP, bemit_subsp);
3825 register_emitter(op_ia32_SwitchJmp, bemit_switchjmp);
3826 register_emitter(op_ia32_Test, bemit_test);
3827 register_emitter(op_ia32_Test8Bit, bemit_test8bit);
3828 register_emitter(op_ia32_Xor, bemit_xor);
3829 register_emitter(op_ia32_Xor0, bemit_xor0);
3830 register_emitter(op_ia32_XorMem, bemit_xormem);
3831 register_emitter(op_ia32_XorMem8Bit, bemit_xormem8bit);
3832 register_emitter(op_ia32_fabs, bemit_fabs);
3833 register_emitter(op_ia32_fadd, bemit_fadd);
3834 register_emitter(op_ia32_faddp, bemit_faddp);
3835 register_emitter(op_ia32_fchs, bemit_fchs);
3836 register_emitter(op_ia32_fdiv, bemit_fdiv);
3837 register_emitter(op_ia32_fdivp, bemit_fdivp);
3838 register_emitter(op_ia32_fdivr, bemit_fdivr);
3839 register_emitter(op_ia32_fdivrp, bemit_fdivrp);
3840 register_emitter(op_ia32_fild, bemit_fild);
3841 register_emitter(op_ia32_fist, bemit_fist);
3842 register_emitter(op_ia32_fistp, bemit_fistp);
3843 register_emitter(op_ia32_fld, bemit_fld);
3844 register_emitter(op_ia32_fld1, bemit_fld1);
3845 register_emitter(op_ia32_fldz, bemit_fldz);
3846 register_emitter(op_ia32_fmul, bemit_fmul);
3847 register_emitter(op_ia32_fmulp, bemit_fmulp);
3848 register_emitter(op_ia32_fpop, bemit_fpop);
3849 register_emitter(op_ia32_fpush, bemit_fpush);
3850 register_emitter(op_ia32_fpushCopy, bemit_fpushcopy);
3851 register_emitter(op_ia32_fst, bemit_fst);
3852 register_emitter(op_ia32_fstp, bemit_fstp);
3853 register_emitter(op_ia32_fsub, bemit_fsub);
3854 register_emitter(op_ia32_fsubp, bemit_fsubp);
3855 register_emitter(op_ia32_fsubr, bemit_fsubr);
3856 register_emitter(op_ia32_fsubrp, bemit_fsubrp);
3857 register_emitter(op_ia32_fxch, bemit_fxch);
3859 /* ignore the following nodes */
3860 register_emitter(op_ia32_ProduceVal, emit_Nothing);
3861 register_emitter(op_be_Keep, emit_Nothing);
3862 register_emitter(op_be_Start, emit_Nothing);
3863 register_emitter(op_Phi, emit_Nothing);
3864 register_emitter(op_Start, emit_Nothing);
3867 static void gen_binary_block(ir_node *block)
3871 ia32_emit_block_header(block);
3873 /* emit the contents of the block */
3874 sched_foreach(block, node) {
3875 ia32_emit_node(node);
3879 void ia32_gen_binary_routine(ir_graph *irg)
3881 ir_entity *entity = get_irg_entity(irg);
3882 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
3883 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
3884 ir_node **blk_sched = irg_data->blk_sched;
3886 parameter_dbg_info_t *infos;
3888 isa = (ia32_isa_t*) arch_env;
3890 ia32_register_binary_emitters();
3892 infos = construct_parameter_infos(irg);
3893 be_gas_emit_function_prolog(entity, ia32_cg_config.function_alignment,
3897 /* we use links to point to target blocks */
3898 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
3899 irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
3901 /* initialize next block links */
3902 n = ARR_LEN(blk_sched);
3903 for (i = 0; i < n; ++i) {
3904 ir_node *block = blk_sched[i];
3905 ir_node *prev = i > 0 ? blk_sched[i-1] : NULL;
3907 set_irn_link(block, prev);
3910 for (i = 0; i < n; ++i) {
3911 ir_node *block = blk_sched[i];
3912 gen_binary_block(block);
3915 be_gas_emit_function_epilog(entity);
3917 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
3921 void ia32_init_emitter(void)
3923 lc_opt_entry_t *be_grp;
3924 lc_opt_entry_t *ia32_grp;
3926 be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
3927 ia32_grp = lc_opt_get_grp(be_grp, "ia32");
3929 lc_opt_add_table(ia32_grp, ia32_emitter_options);
3933 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");