2 * Copyright (C) 1995-2007 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
41 #include "iredges_t.h"
44 #include "raw_bitset.h"
46 #include "../besched_t.h"
47 #include "../benode_t.h"
49 #include "../be_dbgout.h"
50 #include "../beemitter.h"
51 #include "../begnuas.h"
52 #include "../beirg_t.h"
54 #include "ia32_emitter.h"
55 #include "gen_ia32_emitter.h"
56 #include "gen_ia32_regalloc_if.h"
57 #include "ia32_nodes_attr.h"
58 #include "ia32_new_nodes.h"
59 #include "ia32_map_regs.h"
60 #include "bearch_ia32_t.h"
62 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
64 #define BLOCK_PREFIX ".L"
66 #define SNPRINTF_BUF_LEN 128
69 * Returns the register at in position pos.
72 const arch_register_t *get_in_reg(ia32_emit_env_t *env, const ir_node *irn,
75 const arch_env_t *arch_env = env->arch_env;
77 const arch_register_t *reg = NULL;
79 assert(get_irn_arity(irn) > pos && "Invalid IN position");
81 /* The out register of the operator at position pos is the
82 in register we need. */
83 op = get_irn_n(irn, pos);
85 reg = arch_get_irn_register(arch_env, op);
87 assert(reg && "no in register found");
89 if(reg == &ia32_gp_regs[REG_GP_NOREG])
90 panic("trying to emit noreg for %+F input %d", irn, pos);
92 /* in case of unknown register: just return a valid register */
93 if (reg == &ia32_gp_regs[REG_GP_UKNWN]) {
94 const arch_register_req_t *req;
96 /* ask for the requirements */
97 req = arch_get_register_req(arch_env, irn, pos);
99 if (arch_register_req_is(req, limited)) {
100 /* in case of limited requirements: get the first allowed register */
101 unsigned idx = rbitset_next(req->limited, 0, 1);
102 reg = arch_register_for_index(req->cls, idx);
104 /* otherwise get first register in class */
105 reg = arch_register_for_index(req->cls, 0);
113 * Returns the register at out position pos.
116 const arch_register_t *get_out_reg(ia32_emit_env_t *env, const ir_node *irn,
119 const arch_env_t *arch_env = env->arch_env;
121 const arch_register_t *reg = NULL;
123 /* 1st case: irn is not of mode_T, so it has only */
124 /* one OUT register -> good */
125 /* 2nd case: irn is of mode_T -> collect all Projs and ask the */
126 /* Proj with the corresponding projnum for the register */
128 if (get_irn_mode(irn) != mode_T) {
129 reg = arch_get_irn_register(arch_env, irn);
130 } else if (is_ia32_irn(irn)) {
131 reg = get_ia32_out_reg(irn, pos);
133 const ir_edge_t *edge;
135 foreach_out_edge(irn, edge) {
136 proj = get_edge_src_irn(edge);
137 assert(is_Proj(proj) && "non-Proj from mode_T node");
138 if (get_Proj_proj(proj) == pos) {
139 reg = arch_get_irn_register(arch_env, proj);
145 assert(reg && "no out register found");
150 * Determine the gnu assembler suffix that indicates a mode
153 char get_mode_suffix(const ir_mode *mode) {
154 if(mode_is_float(mode)) {
155 switch(get_mode_size_bits(mode)) {
165 assert(mode_is_int(mode) || mode_is_reference(mode));
166 switch(get_mode_size_bits(mode)) {
177 panic("Can't output mode_suffix for %+F\n", mode);
181 const char *ia32_get_reg_name_for_mode(ia32_emit_env_t *env, ir_mode *mode,
182 const arch_register_t *reg) {
183 switch(get_mode_size_bits(mode)) {
185 return ia32_get_mapped_reg_name(env->isa->regs_8bit, reg);
187 return ia32_get_mapped_reg_name(env->isa->regs_16bit, reg);
189 return (char *)arch_register_get_name(reg);
194 * Add a number to a prefix. This number will not be used a second time.
197 char *get_unique_label(char *buf, size_t buflen, const char *prefix) {
198 static unsigned long id = 0;
199 snprintf(buf, buflen, "%s%lu", prefix, ++id);
203 /*************************************************************
205 * (_) | | / _| | | | |
206 * _ __ _ __ _ _ __ | |_| |_ | |__ ___| |_ __ ___ _ __
207 * | '_ \| '__| | '_ \| __| _| | '_ \ / _ \ | '_ \ / _ \ '__|
208 * | |_) | | | | | | | |_| | | | | | __/ | |_) | __/ |
209 * | .__/|_| |_|_| |_|\__|_| |_| |_|\___|_| .__/ \___|_|
212 *************************************************************/
214 // we have no C++ and can't define an implicit ia32_emit_env_t* cast to
215 // be_emit_env_t* so we cheat a bit...
216 #define be_emit_char(env,c) be_emit_char(env->emit,c)
217 #define be_emit_string(env,s) be_emit_string(env->emit,s)
218 #undef be_emit_cstring
219 #define be_emit_cstring(env,x) { be_emit_string_len(env->emit, x, sizeof(x)-1); }
220 #define be_emit_ident(env,i) be_emit_ident(env->emit,i)
221 #define be_emit_tarval(env,tv) be_emit_tarval(env->emit,tv)
222 #define be_emit_write_line(env) be_emit_write_line(env->emit)
223 #define be_emit_finish_line_gas(env,n) be_emit_finish_line_gas(env->emit,n)
224 #define be_emit_pad_comment(env) be_emit_pad_comment(env->emit)
226 void ia32_emit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos)
228 const arch_register_t *reg = get_in_reg(env, node, pos);
229 const char *reg_name = arch_register_get_name(reg);
231 assert(pos < get_irn_arity(node));
233 be_emit_char(env, '%');
234 be_emit_string(env, reg_name);
237 void ia32_emit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos) {
238 const arch_register_t *reg = get_out_reg(env, node, pos);
239 const char *reg_name = arch_register_get_name(reg);
241 be_emit_char(env, '%');
242 be_emit_string(env, reg_name);
245 static void ia32_emit_register(ia32_emit_env_t *env, const arch_register_t *reg)
247 const char *reg_name = arch_register_get_name(reg);
249 be_emit_char(env, '%');
250 be_emit_string(env, reg_name);
253 void ia32_emit_x87_name(ia32_emit_env_t *env, const ir_node *node, int pos)
255 const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
258 be_emit_char(env, '%');
259 be_emit_string(env, attr->x87[pos]->name);
263 void ia32_emit_mode_suffix_mode(ia32_emit_env_t *env, const ir_mode *mode)
265 be_emit_char(env, get_mode_suffix(mode));
268 void ia32_emit_mode_suffix(ia32_emit_env_t *env, const ir_node *node)
270 ir_mode *mode = get_ia32_ls_mode(node);
274 ia32_emit_mode_suffix_mode(env, mode);
277 void ia32_emit_x87_mode_suffix(ia32_emit_env_t *env, const ir_node *node)
279 ir_mode *mode = get_ia32_ls_mode(node);
281 ia32_emit_mode_suffix_mode(env, mode);
285 char get_xmm_mode_suffix(ir_mode *mode)
287 assert(mode_is_float(mode));
288 switch(get_mode_size_bits(mode)) {
299 void ia32_emit_xmm_mode_suffix(ia32_emit_env_t *env, const ir_node *node)
301 ir_mode *mode = get_ia32_ls_mode(node);
302 assert(mode != NULL);
303 be_emit_char(env, 's');
304 be_emit_char(env, get_xmm_mode_suffix(mode));
307 void ia32_emit_xmm_mode_suffix_s(ia32_emit_env_t *env, const ir_node *node)
309 ir_mode *mode = get_ia32_ls_mode(node);
310 assert(mode != NULL);
311 be_emit_char(env, get_xmm_mode_suffix(mode));
314 void ia32_emit_extend_suffix(ia32_emit_env_t *env, const ir_mode *mode)
316 if(get_mode_size_bits(mode) == 32)
318 if(mode_is_signed(mode)) {
319 be_emit_char(env, 's');
321 be_emit_char(env, 'z');
326 void ia32_emit_function_object(ia32_emit_env_t *env, const char *name)
328 switch (be_gas_flavour) {
329 case GAS_FLAVOUR_NORMAL:
330 be_emit_cstring(env, "\t.type\t");
331 be_emit_string(env, name);
332 be_emit_cstring(env, ", @function\n");
333 be_emit_write_line(env);
335 case GAS_FLAVOUR_MINGW:
336 be_emit_cstring(env, "\t.def\t");
337 be_emit_string(env, name);
338 be_emit_cstring(env, ";\t.scl\t2;\t.type\t32;\t.endef\n");
339 be_emit_write_line(env);
347 void ia32_emit_function_size(ia32_emit_env_t *env, const char *name)
349 switch (be_gas_flavour) {
350 case GAS_FLAVOUR_NORMAL:
351 be_emit_cstring(env, "\t.size\t");
352 be_emit_string(env, name);
353 be_emit_cstring(env, ", .-");
354 be_emit_string(env, name);
355 be_emit_char(env, '\n');
356 be_emit_write_line(env);
365 void emit_ia32_Immediate(ia32_emit_env_t *env, const ir_node *node);
367 void ia32_emit_8bit_source_register(ia32_emit_env_t *env, const ir_node *node,
370 const arch_register_t *reg;
371 const char *reg_name;
374 in = get_irn_n(node, pos);
375 if(is_ia32_Immediate(in)) {
376 emit_ia32_Immediate(env, in);
380 reg = get_in_reg(env, node, pos);
381 reg_name = arch_register_get_name(reg);
383 be_emit_char(env, '%');
384 be_emit_char(env, reg_name[1]);
385 be_emit_char(env, 'l');
388 void ia32_emit_16bit_source_register(ia32_emit_env_t *env, const ir_node *node,
391 const arch_register_t *reg;
392 const char *reg_name;
395 in = get_irn_n(node, pos);
396 if(is_ia32_Immediate(in)) {
397 emit_ia32_Immediate(env, in);
401 reg = get_in_reg(env, node, pos);
402 reg_name = arch_register_get_name(reg);
404 be_emit_char(env, '%');
405 be_emit_string(env, ®_name[1]);
406 be_emit_char(env, 'x');
409 void ia32_emit_8bit_dest_register(ia32_emit_env_t *env, const ir_node *node,
412 const arch_register_t *reg = get_out_reg(env, node, pos);
413 const char *reg_name = arch_register_get_name(reg);
415 be_emit_char(env, '%');
416 be_emit_char(env, reg_name[1]);
417 be_emit_char(env, 'l');
420 void ia32_emit_source_register_or_immediate(ia32_emit_env_t *env,
421 const ir_node *node, int pos)
423 ir_node *in = get_irn_n(node, pos);
424 if(is_ia32_Immediate(in)) {
425 emit_ia32_Immediate(env, in);
427 ia32_emit_source_register(env, node, pos);
432 * Emits registers and/or address mode of a binary operation.
434 void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node, int produces_result) {
435 const ir_node *right_op = get_irn_n(node, n_ia32_binary_right);
437 switch(get_ia32_op_type(node)) {
439 if(is_ia32_Immediate(right_op)) {
440 emit_ia32_Immediate(env, right_op);
441 be_emit_cstring(env, ", ");
442 ia32_emit_source_register(env, node, n_ia32_binary_left);
445 const arch_register_t *in1 = get_in_reg(env, node, n_ia32_binary_left);
446 const arch_register_t *in2 = get_in_reg(env, node, n_ia32_binary_right);
447 const arch_register_t *out = produces_result ? get_out_reg(env, node, 0) : NULL;
448 const arch_register_t *in;
451 in = out ? ((out == in2) ? in1 : in2) : in2;
452 out = out ? out : in1;
453 in_name = arch_register_get_name(in);
455 be_emit_char(env, '%');
456 be_emit_string(env, in_name);
457 be_emit_cstring(env, ", %");
458 be_emit_string(env, arch_register_get_name(out));
462 if(is_ia32_Immediate(right_op)) {
463 assert(!produces_result && "Source AM with Const must not produce result");
465 emit_ia32_Immediate(env, right_op);
466 be_emit_cstring(env, ", ");
467 ia32_emit_am(env, node);
468 } else if (produces_result) {
469 ia32_emit_am(env, node);
470 be_emit_cstring(env, ", ");
471 ia32_emit_dest_register(env, node, 0);
473 ia32_emit_am(env, node);
474 be_emit_cstring(env, ", ");
475 ia32_emit_source_register(env, node, n_ia32_binary_left);
479 panic("DestMode can't be output by %%binop anymore");
482 assert(0 && "unsupported op type");
487 * Emits registers and/or address mode of a binary operation.
489 void ia32_emit_x87_binop(ia32_emit_env_t *env, const ir_node *node) {
490 switch(get_ia32_op_type(node)) {
493 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
494 const arch_register_t *in1 = x87_attr->x87[0];
495 const arch_register_t *in2 = x87_attr->x87[1];
496 const arch_register_t *out = x87_attr->x87[2];
497 const arch_register_t *in;
499 in = out ? ((out == in2) ? in1 : in2) : in2;
500 out = out ? out : in1;
502 be_emit_char(env, '%');
503 be_emit_string(env, arch_register_get_name(in));
504 be_emit_cstring(env, ", %");
505 be_emit_string(env, arch_register_get_name(out));
509 ia32_emit_am(env, node);
513 assert(0 && "unsupported op type");
517 void ia32_emit_am_or_dest_register(ia32_emit_env_t *env, const ir_node *node,
519 if(get_ia32_op_type(node) == ia32_Normal) {
520 ia32_emit_dest_register(env, node, pos);
522 assert(get_ia32_op_type(node) == ia32_AddrModeD);
523 ia32_emit_am(env, node);
528 * Emits registers and/or address mode of a unary operation.
530 void ia32_emit_unop(ia32_emit_env_t *env, const ir_node *node, int pos) {
533 switch(get_ia32_op_type(node)) {
535 op = get_irn_n(node, pos);
536 if (is_ia32_Immediate(op)) {
537 emit_ia32_Immediate(env, op);
539 ia32_emit_source_register(env, node, pos);
544 ia32_emit_am(env, node);
547 assert(0 && "unsupported op type");
552 * Emits address mode.
554 void ia32_emit_am(ia32_emit_env_t *env, const ir_node *node) {
555 ir_entity *ent = get_ia32_am_sc(node);
556 int offs = get_ia32_am_offs_int(node);
557 ir_node *base = get_irn_n(node, 0);
558 int has_base = !is_ia32_NoReg_GP(base);
559 ir_node *index = get_irn_n(node, 1);
560 int has_index = !is_ia32_NoReg_GP(index);
562 /* just to be sure... */
563 assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
569 set_entity_backend_marked(ent, 1);
570 id = get_entity_ld_ident(ent);
571 if (is_ia32_am_sc_sign(node))
572 be_emit_char(env, '-');
573 be_emit_ident(env, id);
575 if(get_entity_owner(ent) == get_tls_type()) {
576 if (get_entity_visibility(ent) == visibility_external_allocated) {
577 be_emit_cstring(env, "@INDNTPOFF");
579 be_emit_cstring(env, "@NTPOFF");
586 be_emit_irprintf(env->emit, "%+d", offs);
588 be_emit_irprintf(env->emit, "%d", offs);
592 if (has_base || has_index) {
593 be_emit_char(env, '(');
597 ia32_emit_source_register(env, node, n_ia32_base);
600 /* emit index + scale */
603 be_emit_char(env, ',');
604 ia32_emit_source_register(env, node, n_ia32_index);
606 scale = get_ia32_am_scale(node);
608 be_emit_irprintf(env->emit, ",%d", 1 << get_ia32_am_scale(node));
611 be_emit_char(env, ')');
614 /* special case if nothing is set */
615 if(ent == NULL && offs == 0 && !has_base && !has_index) {
616 be_emit_char(env, '0');
620 /*************************************************
623 * ___ _ __ ___ _| |_ ___ ___ _ __ __| |
624 * / _ \ '_ ` _ \| | __| / __/ _ \| '_ \ / _` |
625 * | __/ | | | | | | |_ | (_| (_) | | | | (_| |
626 * \___|_| |_| |_|_|\__| \___\___/|_| |_|\__,_|
628 *************************************************/
631 #define IA32_DO_EMIT(irn) ia32_fprintf_format(F, irn, cmd_buf, cmnt_buf)
634 * coding of conditions
636 struct cmp2conditon_t {
642 * positive conditions for signed compares
644 static const struct cmp2conditon_t cmp2condition_s[] = {
645 { NULL, pn_Cmp_False }, /* always false */
646 { "e", pn_Cmp_Eq }, /* == */
647 { "l", pn_Cmp_Lt }, /* < */
648 { "le", pn_Cmp_Le }, /* <= */
649 { "g", pn_Cmp_Gt }, /* > */
650 { "ge", pn_Cmp_Ge }, /* >= */
651 { "ne", pn_Cmp_Lg }, /* != */
652 { NULL, pn_Cmp_Leg}, /* always true */
656 * positive conditions for unsigned compares
658 static const struct cmp2conditon_t cmp2condition_u[] = {
659 { NULL, pn_Cmp_False }, /* always false */
660 { "e", pn_Cmp_Eq }, /* == */
661 { "b", pn_Cmp_Lt }, /* < */
662 { "be", pn_Cmp_Le }, /* <= */
663 { "a", pn_Cmp_Gt }, /* > */
664 { "ae", pn_Cmp_Ge }, /* >= */
665 { "ne", pn_Cmp_Lg }, /* != */
666 { NULL, pn_Cmp_Leg }, /* always true */
670 ia32_pn_Cmp_unsigned = 0x1000,
671 ia32_pn_Cmp_float = 0x2000,
675 * walks up a tree of copies/perms/spills/reloads to find the original value
676 * that is moved around
678 static ir_node *find_original_value(ir_node *node)
680 inc_irg_visited(current_ir_graph);
682 mark_irn_visited(node);
683 if(be_is_Copy(node)) {
684 node = be_get_Copy_op(node);
685 } else if(be_is_CopyKeep(node)) {
686 node = be_get_CopyKeep_op(node);
687 } else if(is_Proj(node)) {
688 ir_node *pred = get_Proj_pred(node);
689 if(be_is_Perm(pred)) {
690 node = get_irn_n(pred, get_Proj_proj(node));
691 } else if(be_is_MemPerm(pred)) {
692 node = get_irn_n(pred, get_Proj_proj(node) + 1);
693 } else if(is_ia32_Load(pred)) {
694 node = get_irn_n(pred, n_ia32_Load_mem);
698 } else if(is_Store(node)) {
699 node = get_irn_n(node, n_ia32_Store_val);
700 } else if(is_Phi(node)) {
702 arity = get_irn_arity(node);
703 for(i = 0; i < arity; ++i) {
704 ir_node *in = get_irn_n(node, i);
717 static int determine_final_pnc(const ir_node *node, int flags_pos,
720 ir_node *flags = get_irn_n(node, flags_pos);
721 const ia32_attr_t *flags_attr;
722 flags = skip_Proj(flags);
724 if(is_ia32_Sahf(flags)) {
725 ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
726 if(!is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
727 || is_ia32_FucomppFnstsw(cmp)) {
728 cmp = find_original_value(cmp);
729 assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
730 || is_ia32_FucomppFnstsw(cmp));
733 flags_attr = get_ia32_attr_const(cmp);
734 if(flags_attr->data.cmp_flipped)
735 pnc = get_mirrored_pnc(pnc);
736 pnc |= ia32_pn_Cmp_float;
737 } else if(is_ia32_Ucomi(flags)) {
738 flags_attr = get_ia32_attr_const(flags);
740 if(flags_attr->data.cmp_flipped)
741 pnc = get_mirrored_pnc(pnc);
742 pnc |= ia32_pn_Cmp_float;
744 assert(is_ia32_Cmp(flags) || is_ia32_Test(flags)
745 || is_ia32_Cmp8Bit(flags) || is_ia32_Test8Bit(flags));
746 flags_attr = get_ia32_attr_const(flags);
748 if(flags_attr->data.cmp_flipped)
749 pnc = get_mirrored_pnc(pnc);
750 if(flags_attr->data.cmp_unsigned)
751 pnc |= ia32_pn_Cmp_unsigned;
757 static void ia32_emit_cmp_suffix(ia32_emit_env_t *env, int pnc)
761 if((pnc & ia32_pn_Cmp_float) || (pnc & ia32_pn_Cmp_unsigned)) {
763 assert(cmp2condition_u[pnc].num == pnc);
764 str = cmp2condition_u[pnc].name;
767 assert(cmp2condition_s[pnc].num == pnc);
768 str = cmp2condition_s[pnc].name;
771 be_emit_string(env, str);
774 void ia32_emit_cmp_suffix_node(ia32_emit_env_t *env, const ir_node *node,
777 pn_Cmp pnc = get_ia32_pncode(node);
779 pnc = determine_final_pnc(node, flags_pos, pnc);
780 ia32_emit_cmp_suffix(env, pnc);
784 * Returns the target block for a control flow node.
787 ir_node *get_cfop_target_block(const ir_node *irn) {
788 return get_irn_link(irn);
792 * Emits a block label for the given block.
795 void ia32_emit_block_name(ia32_emit_env_t *env, const ir_node *block)
797 if (has_Block_label(block)) {
798 be_emit_string(env, be_gas_label_prefix());
799 be_emit_irprintf(env->emit, "%u", (unsigned)get_Block_label(block));
801 be_emit_cstring(env, BLOCK_PREFIX);
802 be_emit_irprintf(env->emit, "%d", get_irn_node_nr(block));
807 * Emits the target label for a control flow node.
810 void ia32_emit_cfop_target(ia32_emit_env_t * env, const ir_node *node) {
811 ir_node *block = get_cfop_target_block(node);
813 ia32_emit_block_name(env, block);
816 /** Return the next block in Block schedule */
817 static ir_node *next_blk_sched(const ir_node *block) {
818 return get_irn_link(block);
822 * Returns the Proj with projection number proj and NOT mode_M
824 static ir_node *get_proj(const ir_node *node, long proj) {
825 const ir_edge_t *edge;
828 assert(get_irn_mode(node) == mode_T && "expected mode_T node");
830 foreach_out_edge(node, edge) {
831 src = get_edge_src_irn(edge);
833 assert(is_Proj(src) && "Proj expected");
834 if (get_irn_mode(src) == mode_M)
837 if (get_Proj_proj(src) == proj)
844 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
846 static void emit_ia32_Jcc(ia32_emit_env_t *env, const ir_node *node)
848 const ir_node *proj_true;
849 const ir_node *proj_false;
850 const ir_node *block;
851 const ir_node *next_block;
852 pn_Cmp pnc = get_ia32_pncode(node);
854 pnc = determine_final_pnc(node, 0, pnc);
857 proj_true = get_proj(node, pn_ia32_Jcc_true);
858 assert(proj_true && "Jcc without true Proj");
860 proj_false = get_proj(node, pn_ia32_Jcc_false);
861 assert(proj_false && "Jcc without false Proj");
863 block = get_nodes_block(node);
864 next_block = next_blk_sched(block);
866 if (get_cfop_target_block(proj_true) == next_block) {
867 /* exchange both proj's so the second one can be omitted */
868 const ir_node *t = proj_true;
870 proj_true = proj_false;
872 if(pnc & ia32_pn_Cmp_float) {
873 pnc = get_negated_pnc(pnc, mode_F);
875 pnc = get_negated_pnc(pnc, mode_Iu);
879 if (pnc & ia32_pn_Cmp_float) {
880 /* Some floating point comparisons require a test of the parity flag,
881 * which indicates that the result is unordered */
884 be_emit_cstring(env, "\tjp ");
885 ia32_emit_cfop_target(env, proj_true);
886 be_emit_finish_line_gas(env, proj_true);
890 be_emit_cstring(env, "\tjnp ");
891 ia32_emit_cfop_target(env, proj_true);
892 be_emit_finish_line_gas(env, proj_true);
898 be_emit_cstring(env, "\tjp ");
899 ia32_emit_cfop_target(env, proj_false);
900 be_emit_finish_line_gas(env, proj_false);
906 be_emit_cstring(env, "\tjp ");
907 ia32_emit_cfop_target(env, proj_true);
908 be_emit_finish_line_gas(env, proj_true);
916 be_emit_cstring(env, "\tj");
917 ia32_emit_cmp_suffix(env, pnc);
918 be_emit_char(env, ' ');
919 ia32_emit_cfop_target(env, proj_true);
920 be_emit_finish_line_gas(env, proj_true);
923 /* the second Proj might be a fallthrough */
924 if (get_cfop_target_block(proj_false) != next_block) {
925 be_emit_cstring(env, "\tjmp ");
926 ia32_emit_cfop_target(env, proj_false);
927 be_emit_finish_line_gas(env, proj_false);
929 be_emit_cstring(env, "\t/* fallthrough to ");
930 ia32_emit_cfop_target(env, proj_false);
931 be_emit_cstring(env, " */");
932 be_emit_finish_line_gas(env, proj_false);
938 * Emits code for conditional SSE floating point jump with two variables.
941 void emit_ia32_xCmpJmp(ia32_emit_env_t *env, const ir_node *node) {
942 be_emit_cstring(env, "\tucomi");
943 ia32_emit_xmm_mode_suffix(env, node);
944 be_emit_char(env, ' ');
945 ia32_emit_binop(env, node, 0);
946 be_emit_finish_line_gas(env, node);
948 finish_CondJmp(env, node, mode_F, get_ia32_pncode(node));
952 * Emits code for conditional x87 floating point jump with two variables.
955 void emit_ia32_x87CmpJmp(ia32_emit_env_t *env, const ir_node *node) {
956 const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
957 const char *reg = x87_attr->x87[1]->name;
958 long pnc = get_ia32_pncode(node);
960 switch (get_ia32_irn_opcode(node)) {
961 case iro_ia32_fcomrJmp:
962 pnc = get_inversed_pnc(pnc);
963 reg = x87_attr->x87[0]->name;
964 case iro_ia32_fcomJmp:
966 be_emit_cstring(env, "\tfucom ");
968 case iro_ia32_fcomrpJmp:
969 pnc = get_inversed_pnc(pnc);
970 reg = x87_attr->x87[0]->name;
971 case iro_ia32_fcompJmp:
972 be_emit_cstring(env, "\tfucomp ");
974 case iro_ia32_fcomrppJmp:
975 pnc = get_inversed_pnc(pnc);
976 case iro_ia32_fcomppJmp:
977 be_emit_cstring(env, "\tfucompp ");
983 be_emit_char(env, '%');
984 be_emit_string(env, reg);
986 be_emit_finish_line_gas(env, node);
988 be_emit_cstring(env, "\tfnstsw %ax");
989 be_emit_finish_line_gas(env, node);
990 be_emit_cstring(env, "\tsahf");
991 be_emit_finish_line_gas(env, node);
993 finish_CondJmp(env, node, mode_E, pnc);
997 static void emit_ia32_CMov(ia32_emit_env_t *env, const ir_node *node)
999 const arch_register_t *out = arch_get_irn_register(env->arch_env, node);
1000 const arch_register_t *in_true;
1001 const arch_register_t *in_false;
1002 pn_Cmp pnc = get_ia32_pncode(node);
1004 pnc = determine_final_pnc(node, n_ia32_CMov_eflags, pnc);
1006 in_true = arch_get_irn_register(env->arch_env,
1007 get_irn_n(node, n_ia32_CMov_val_true));
1008 in_false = arch_get_irn_register(env->arch_env,
1009 get_irn_n(node, n_ia32_CMov_val_false));
1011 /* should be same constraint fullfilled? */
1012 if(out == in_false) {
1013 /* yes -> nothing to do */
1014 } else if(out == in_true) {
1015 const arch_register_t *tmp;
1017 /* swap left/right and negate pnc */
1018 pnc = get_negated_pnc(pnc, mode_Iu);
1025 be_emit_cstring(env, "\tmovl ");
1026 ia32_emit_register(env, in_false);
1027 be_emit_cstring(env, ", ");
1028 ia32_emit_register(env, out);
1029 be_emit_finish_line_gas(env, node);
1032 be_emit_cstring(env, "\tcmov");
1033 ia32_emit_cmp_suffix(env, pnc);
1034 be_emit_char(env, ' ');
1035 if(get_ia32_op_type(node) == ia32_AddrModeS) {
1036 ia32_emit_am(env, node);
1038 ia32_emit_register(env, in_true);
1040 be_emit_cstring(env, ", ");
1041 ia32_emit_register(env, out);
1042 be_emit_finish_line_gas(env, node);
1047 void emit_ia32_xCmp(ia32_emit_env_t *env, const ir_node *node) {
1049 long pnc = get_ia32_pncode(node);
1050 long unord = pnc & pn_Cmp_Uo;
1052 assert( (pnc & ia32_pn_Cmp_Unsigned) == 0);
1055 case pn_Cmp_Leg: /* odered */
1058 case pn_Cmp_Uo: /* unordered */
1062 case pn_Cmp_Eq: /* == */
1066 case pn_Cmp_Lt: /* < */
1070 case pn_Cmp_Le: /* <= */
1074 case pn_Cmp_Gt: /* > */
1078 case pn_Cmp_Ge: /* >= */
1082 case pn_Cmp_Lg: /* != */
1087 assert(sse_pnc >= 0 && "unsupported compare");
1089 if (unord && sse_pnc != 3) {
1091 We need a separate compare against unordered.
1092 Quick and Dirty solution:
1093 - get some memory on stack
1097 - and result and stored result
1100 be_emit_cstring(env, "\tsubl $8, %esp");
1101 be_emit_finish_line_gas(env, node);
1103 be_emit_cstring(env, "\tcmpsd $3, ");
1104 ia32_emit_binop(env, node, 0);
1105 be_emit_finish_line_gas(env, node);
1107 be_emit_cstring(env, "\tmovsd ");
1108 ia32_emit_dest_register(env, node, 0);
1109 be_emit_cstring(env, ", (%esp)");
1110 be_emit_finish_line_gas(env, node);
1113 be_emit_cstring(env, "\tcmpsd ");
1114 be_emit_irprintf(env->emit, "%d, ", sse_pnc);
1115 ia32_emit_binop(env, node, 0);
1116 be_emit_finish_line_gas(env, node);
1118 if (unord && sse_pnc != 3) {
1119 be_emit_cstring(env, "\tandpd (%esp), ");
1120 ia32_emit_dest_register(env, node, 0);
1121 be_emit_finish_line_gas(env, node);
1123 be_emit_cstring(env, "\taddl $8, %esp");
1124 be_emit_finish_line_gas(env, node);
1129 /*********************************************************
1132 * ___ _ __ ___ _| |_ _ _ _ _ __ ___ _ __ ___
1133 * / _ \ '_ ` _ \| | __| | | | | | '_ ` _ \| '_ \/ __|
1134 * | __/ | | | | | | |_ | | |_| | | | | | | |_) \__ \
1135 * \___|_| |_| |_|_|\__| | |\__,_|_| |_| |_| .__/|___/
1138 *********************************************************/
1140 /* jump table entry (target and corresponding number) */
1141 typedef struct _branch_t {
1146 /* jump table for switch generation */
1147 typedef struct _jmp_tbl_t {
1148 ir_node *defProj; /**< default target */
1149 long min_value; /**< smallest switch case */
1150 long max_value; /**< largest switch case */
1151 long num_branches; /**< number of jumps */
1152 char *label; /**< label of the jump table */
1153 branch_t *branches; /**< jump array */
1157 * Compare two variables of type branch_t. Used to sort all switch cases
1160 int ia32_cmp_branch_t(const void *a, const void *b) {
1161 branch_t *b1 = (branch_t *)a;
1162 branch_t *b2 = (branch_t *)b;
1164 if (b1->value <= b2->value)
1171 * Emits code for a SwitchJmp (creates a jump table if
1172 * possible otherwise a cmp-jmp cascade). Port from
1176 void emit_ia32_SwitchJmp(ia32_emit_env_t *env, const ir_node *node) {
1177 unsigned long interval;
1182 const ir_edge_t *edge;
1184 /* fill the table structure */
1185 tbl.label = xmalloc(SNPRINTF_BUF_LEN);
1186 tbl.label = get_unique_label(tbl.label, SNPRINTF_BUF_LEN, ".TBL_");
1188 tbl.num_branches = get_irn_n_edges(node);
1189 tbl.branches = xcalloc(tbl.num_branches, sizeof(tbl.branches[0]));
1190 tbl.min_value = INT_MAX;
1191 tbl.max_value = INT_MIN;
1194 /* go over all proj's and collect them */
1195 foreach_out_edge(node, edge) {
1196 proj = get_edge_src_irn(edge);
1197 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
1199 pnc = get_Proj_proj(proj);
1201 /* create branch entry */
1202 tbl.branches[i].target = proj;
1203 tbl.branches[i].value = pnc;
1205 tbl.min_value = pnc < tbl.min_value ? pnc : tbl.min_value;
1206 tbl.max_value = pnc > tbl.max_value ? pnc : tbl.max_value;
1208 /* check for default proj */
1209 if (pnc == get_ia32_pncode(node)) {
1210 assert(tbl.defProj == NULL && "found two defProjs at SwitchJmp");
1217 /* sort the branches by their number */
1218 qsort(tbl.branches, tbl.num_branches, sizeof(tbl.branches[0]), ia32_cmp_branch_t);
1220 /* two-complement's magic make this work without overflow */
1221 interval = tbl.max_value - tbl.min_value;
1223 /* emit the table */
1224 be_emit_cstring(env, "\tcmpl $");
1225 be_emit_irprintf(env->emit, "%u, ", interval);
1226 ia32_emit_source_register(env, node, 0);
1227 be_emit_finish_line_gas(env, node);
1229 be_emit_cstring(env, "\tja ");
1230 ia32_emit_cfop_target(env, tbl.defProj);
1231 be_emit_finish_line_gas(env, node);
1233 if (tbl.num_branches > 1) {
1235 be_emit_cstring(env, "\tjmp *");
1236 be_emit_string(env, tbl.label);
1237 be_emit_cstring(env, "(,");
1238 ia32_emit_source_register(env, node, 0);
1239 be_emit_cstring(env, ",4)");
1240 be_emit_finish_line_gas(env, node);
1242 be_gas_emit_switch_section(env->emit, GAS_SECTION_RODATA);
1243 be_emit_cstring(env, "\t.align 4\n");
1244 be_emit_write_line(env);
1246 be_emit_string(env, tbl.label);
1247 be_emit_cstring(env, ":\n");
1248 be_emit_write_line(env);
1250 be_emit_cstring(env, ".long ");
1251 ia32_emit_cfop_target(env, tbl.branches[0].target);
1252 be_emit_finish_line_gas(env, NULL);
1254 last_value = tbl.branches[0].value;
1255 for (i = 1; i < tbl.num_branches; ++i) {
1256 while (++last_value < tbl.branches[i].value) {
1257 be_emit_cstring(env, ".long ");
1258 ia32_emit_cfop_target(env, tbl.defProj);
1259 be_emit_finish_line_gas(env, NULL);
1261 be_emit_cstring(env, ".long ");
1262 ia32_emit_cfop_target(env, tbl.branches[i].target);
1263 be_emit_finish_line_gas(env, NULL);
1265 be_gas_emit_switch_section(env->emit, GAS_SECTION_TEXT);
1267 /* one jump is enough */
1268 be_emit_cstring(env, "\tjmp ");
1269 ia32_emit_cfop_target(env, tbl.branches[0].target);
1270 be_emit_finish_line_gas(env, node);
1280 * Emits code for a unconditional jump.
1283 void emit_Jmp(ia32_emit_env_t *env, const ir_node *node) {
1284 ir_node *block, *next_block;
1286 /* for now, the code works for scheduled and non-schedules blocks */
1287 block = get_nodes_block(node);
1289 /* we have a block schedule */
1290 next_block = next_blk_sched(block);
1291 if (get_cfop_target_block(node) != next_block) {
1292 be_emit_cstring(env, "\tjmp ");
1293 ia32_emit_cfop_target(env, node);
1295 be_emit_cstring(env, "\t/* fallthrough to ");
1296 ia32_emit_cfop_target(env, node);
1297 be_emit_cstring(env, " */");
1299 be_emit_finish_line_gas(env, node);
1303 void emit_ia32_Immediate(ia32_emit_env_t *env, const ir_node *node)
1305 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
1307 be_emit_char(env, '$');
1308 if(attr->symconst != NULL) {
1309 ident *id = get_entity_ld_ident(attr->symconst);
1311 if(attr->attr.data.am_sc_sign)
1312 be_emit_char(env, '-');
1313 be_emit_ident(env, id);
1315 if(attr->symconst == NULL || attr->offset != 0) {
1316 if(attr->symconst != NULL)
1317 be_emit_char(env, '+');
1318 be_emit_irprintf(env->emit, "0x%X", attr->offset);
1323 const char* emit_asm_operand(ia32_emit_env_t *env, const ir_node *node,
1326 const arch_register_t *reg;
1327 const char *reg_name;
1331 const ia32_attr_t *attr;
1338 /* parse modifiers */
1341 ir_fprintf(stderr, "Warning: asm text (%+F) ends with %\n", node);
1342 be_emit_char(env, '%');
1345 be_emit_char(env, '%');
1365 ir_fprintf(stderr, "Warning: asm text (%+F) contains unknown modifier "
1366 "'%c' for asm op\n", node, c);
1372 sscanf(s, "%d%n", &num, &p);
1374 ir_fprintf(stderr, "Warning: Couldn't parse assembler operand (%+F)\n",
1382 attr = get_ia32_attr_const(node);
1383 n_outs = ARR_LEN(attr->slots);
1385 reg = get_out_reg(env, node, num);
1388 int in = num - n_outs;
1389 if(in >= get_irn_arity(node)) {
1390 ir_fprintf(stderr, "Warning: Invalid input %d specified in asm "
1391 "op (%+F)\n", num, node);
1394 pred = get_irn_n(node, in);
1395 /* might be an immediate value */
1396 if(is_ia32_Immediate(pred)) {
1397 emit_ia32_Immediate(env, pred);
1400 reg = get_in_reg(env, node, in);
1403 ir_fprintf(stderr, "Warning: no register assigned for %d asm op "
1404 "(%+F)\n", num, node);
1409 be_emit_char(env, '%');
1412 reg_name = arch_register_get_name(reg);
1415 reg_name = ia32_get_mapped_reg_name(env->isa->regs_8bit, reg);
1418 reg_name = ia32_get_mapped_reg_name(env->isa->regs_8bit_high, reg);
1421 reg_name = ia32_get_mapped_reg_name(env->isa->regs_16bit, reg);
1424 panic("Invalid asm op modifier");
1426 be_emit_string(env, reg_name);
1432 * Emits code for an ASM pseudo op.
1435 void emit_ia32_Asm(ia32_emit_env_t *env, const ir_node *node)
1437 const void *gen_attr = get_irn_generic_attr_const(node);
1438 const ia32_asm_attr_t *attr
1439 = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, gen_attr);
1440 ident *asm_text = attr->asm_text;
1441 const char *s = get_id_str(asm_text);
1443 be_emit_cstring(env, "# Begin ASM \t");
1444 be_emit_finish_line_gas(env, node);
1447 be_emit_char(env, '\t');
1451 s = emit_asm_operand(env, node, s);
1454 be_emit_char(env, *s);
1459 be_emit_char(env, '\n');
1460 be_emit_write_line(env);
1462 be_emit_cstring(env, "# End ASM\n");
1463 be_emit_write_line(env);
1466 /**********************************
1469 * | | ___ _ __ _ _| |_) |
1470 * | | / _ \| '_ \| | | | _ <
1471 * | |___| (_) | |_) | |_| | |_) |
1472 * \_____\___/| .__/ \__, |____/
1475 **********************************/
1478 * Emit movsb/w instructions to make mov count divideable by 4
1481 void emit_CopyB_prolog(ia32_emit_env_t *env, int rem) {
1482 be_emit_cstring(env, "\tcld");
1483 be_emit_finish_line_gas(env, NULL);
1487 be_emit_cstring(env, "\tmovsb");
1488 be_emit_finish_line_gas(env, NULL);
1491 be_emit_cstring(env, "\tmovsw");
1492 be_emit_finish_line_gas(env, NULL);
1495 be_emit_cstring(env, "\tmovsb");
1496 be_emit_finish_line_gas(env, NULL);
1497 be_emit_cstring(env, "\tmovsw");
1498 be_emit_finish_line_gas(env, NULL);
1504 * Emit rep movsd instruction for memcopy.
1507 void emit_ia32_CopyB(ia32_emit_env_t *env, const ir_node *node) {
1508 int rem = get_ia32_pncode(node);
1510 emit_CopyB_prolog(env, rem);
1512 be_emit_cstring(env, "\trep movsd");
1513 be_emit_finish_line_gas(env, node);
1517 * Emits unrolled memcopy.
1520 void emit_ia32_CopyB_i(ia32_emit_env_t *env, const ir_node *node) {
1521 int size = get_ia32_pncode(node);
1523 emit_CopyB_prolog(env, size & 0x3);
1527 be_emit_cstring(env, "\tmovsd");
1528 be_emit_finish_line_gas(env, NULL);
1534 /***************************
1538 * | | / _ \| '_ \ \ / /
1539 * | |___| (_) | | | \ V /
1540 * \_____\___/|_| |_|\_/
1542 ***************************/
1545 * Emit code for conversions (I, FP), (FP, I) and (FP, FP).
1548 void emit_ia32_Conv_with_FP(ia32_emit_env_t *env, const ir_node *node) {
1549 ir_mode *ls_mode = get_ia32_ls_mode(node);
1550 int ls_bits = get_mode_size_bits(ls_mode);
1552 be_emit_cstring(env, "\tcvt");
1554 if(is_ia32_Conv_I2FP(node)) {
1556 be_emit_cstring(env, "si2ss");
1558 be_emit_cstring(env, "si2sd");
1560 } else if(is_ia32_Conv_FP2I(node)) {
1562 be_emit_cstring(env, "ss2si");
1564 be_emit_cstring(env, "sd2si");
1567 assert(is_ia32_Conv_FP2FP(node));
1569 be_emit_cstring(env, "sd2ss");
1571 be_emit_cstring(env, "ss2sd");
1574 be_emit_char(env, ' ');
1576 switch(get_ia32_op_type(node)) {
1578 ia32_emit_source_register(env, node, n_ia32_unary_op);
1579 be_emit_cstring(env, ", ");
1580 ia32_emit_dest_register(env, node, 0);
1582 case ia32_AddrModeS:
1583 ia32_emit_dest_register(env, node, 0);
1584 be_emit_cstring(env, ", ");
1585 ia32_emit_am(env, node);
1588 assert(0 && "unsupported op type for Conv");
1590 be_emit_finish_line_gas(env, node);
1594 void emit_ia32_Conv_I2FP(ia32_emit_env_t *env, const ir_node *node) {
1595 emit_ia32_Conv_with_FP(env, node);
1599 void emit_ia32_Conv_FP2I(ia32_emit_env_t *env, const ir_node *node) {
1600 emit_ia32_Conv_with_FP(env, node);
1604 void emit_ia32_Conv_FP2FP(ia32_emit_env_t *env, const ir_node *node) {
1605 emit_ia32_Conv_with_FP(env, node);
1609 * Emits code for an Int conversion.
1612 void emit_ia32_Conv_I2I(ia32_emit_env_t *env, const ir_node *node) {
1613 const char *sign_suffix;
1614 ir_mode *smaller_mode = get_ia32_ls_mode(node);
1615 int smaller_bits = get_mode_size_bits(smaller_mode);
1617 const arch_register_t *in_reg, *out_reg;
1619 assert(!mode_is_float(smaller_mode));
1620 assert(smaller_bits == 8 || smaller_bits == 16 || smaller_bits == 32);
1622 signed_mode = mode_is_signed(smaller_mode);
1623 if(smaller_bits == 32) {
1624 // this should not happen as it's no convert
1628 sign_suffix = signed_mode ? "s" : "z";
1631 switch(get_ia32_op_type(node)) {
1633 in_reg = get_in_reg(env, node, n_ia32_unary_op);
1634 out_reg = get_out_reg(env, node, 0);
1636 if (in_reg == &ia32_gp_regs[REG_EAX] &&
1637 out_reg == &ia32_gp_regs[REG_EAX] &&
1641 /* argument and result are both in EAX and */
1642 /* signedness is ok: -> use the smaller cwtl opcode */
1643 be_emit_cstring(env, "\tcwtl");
1645 const char *sreg = ia32_get_reg_name_for_mode(env, smaller_mode, in_reg);
1647 be_emit_cstring(env, "\tmov");
1648 be_emit_string(env, sign_suffix);
1649 ia32_emit_mode_suffix_mode(env, smaller_mode);
1650 be_emit_cstring(env, "l %");
1651 be_emit_string(env, sreg);
1652 be_emit_cstring(env, ", ");
1653 ia32_emit_dest_register(env, node, 0);
1656 case ia32_AddrModeS: {
1657 be_emit_cstring(env, "\tmov");
1658 be_emit_string(env, sign_suffix);
1659 ia32_emit_mode_suffix_mode(env, smaller_mode);
1660 be_emit_cstring(env, "l ");
1661 ia32_emit_am(env, node);
1662 be_emit_cstring(env, ", ");
1663 ia32_emit_dest_register(env, node, 0);
1667 assert(0 && "unsupported op type for Conv");
1669 be_emit_finish_line_gas(env, node);
1673 * Emits code for an 8Bit Int conversion.
1675 void emit_ia32_Conv_I2I8Bit(ia32_emit_env_t *env, const ir_node *node) {
1676 emit_ia32_Conv_I2I(env, node);
1680 /*******************************************
1683 * | |__ ___ _ __ ___ __| | ___ ___
1684 * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
1685 * | |_) | __/ | | | (_) | (_| | __/\__ \
1686 * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
1688 *******************************************/
1691 * Emits a backend call
1694 void emit_be_Call(ia32_emit_env_t *env, const ir_node *node) {
1695 ir_entity *ent = be_Call_get_entity(node);
1697 be_emit_cstring(env, "\tcall ");
1699 set_entity_backend_marked(ent, 1);
1700 be_emit_string(env, get_entity_ld_name(ent));
1702 be_emit_char(env, '*');
1703 ia32_emit_dest_register(env, get_irn_n(node, be_pos_Call_ptr), 0);
1705 be_emit_finish_line_gas(env, node);
1709 * Emits code to increase stack pointer.
1712 void emit_be_IncSP(ia32_emit_env_t *env, const ir_node *node) {
1713 int offs = be_get_IncSP_offset(node);
1719 be_emit_cstring(env, "\tsubl $");
1720 be_emit_irprintf(env->emit, "%u, ", offs);
1721 ia32_emit_source_register(env, node, 0);
1723 be_emit_cstring(env, "\taddl $");
1724 be_emit_irprintf(env->emit, "%u, ", -offs);
1725 ia32_emit_source_register(env, node, 0);
1727 be_emit_finish_line_gas(env, node);
1731 * Emits code for Copy/CopyKeep.
1734 void Copy_emitter(ia32_emit_env_t *env, const ir_node *node, const ir_node *op)
1736 const arch_env_t *arch_env = env->arch_env;
1737 const arch_register_t *in = arch_get_irn_register(arch_env, op);
1738 const arch_register_t *out = arch_get_irn_register(arch_env, node);
1744 if(is_unknown_reg(in))
1746 /* copies of vf nodes aren't real... */
1747 if(arch_register_get_class(in) == &ia32_reg_classes[CLASS_ia32_vfp])
1750 mode = get_irn_mode(node);
1751 if (mode == mode_E) {
1752 be_emit_cstring(env, "\tmovsd ");
1753 ia32_emit_register(env, in);
1754 be_emit_cstring(env, ", ");
1755 ia32_emit_register(env, out);
1757 be_emit_cstring(env, "\tmovl ");
1758 ia32_emit_register(env, in);
1759 be_emit_cstring(env, ", ");
1760 ia32_emit_register(env, out);
1762 be_emit_finish_line_gas(env, node);
1766 void emit_be_Copy(ia32_emit_env_t *env, const ir_node *node) {
1767 Copy_emitter(env, node, be_get_Copy_op(node));
1771 void emit_be_CopyKeep(ia32_emit_env_t *env, const ir_node *node) {
1772 Copy_emitter(env, node, be_get_CopyKeep_op(node));
1776 * Emits code for exchange.
1779 void emit_be_Perm(ia32_emit_env_t *env, const ir_node *node) {
1780 const arch_register_t *in1, *in2;
1781 const arch_register_class_t *cls1, *cls2;
1783 in1 = arch_get_irn_register(env->arch_env, get_irn_n(node, 0));
1784 in2 = arch_get_irn_register(env->arch_env, get_irn_n(node, 1));
1786 cls1 = arch_register_get_class(in1);
1787 cls2 = arch_register_get_class(in2);
1789 assert(cls1 == cls2 && "Register class mismatch at Perm");
1791 if (cls1 == &ia32_reg_classes[CLASS_ia32_gp]) {
1792 be_emit_cstring(env, "\txchg ");
1793 ia32_emit_source_register(env, node, 1);
1794 be_emit_cstring(env, ", ");
1795 ia32_emit_source_register(env, node, 0);
1796 be_emit_finish_line_gas(env, node);
1797 } else if (cls1 == &ia32_reg_classes[CLASS_ia32_xmm]) {
1798 be_emit_cstring(env, "\txorpd ");
1799 ia32_emit_source_register(env, node, 1);
1800 be_emit_cstring(env, ", ");
1801 ia32_emit_source_register(env, node, 0);
1802 be_emit_finish_line_gas(env, NULL);
1804 be_emit_cstring(env, "\txorpd ");
1805 ia32_emit_source_register(env, node, 0);
1806 be_emit_cstring(env, ", ");
1807 ia32_emit_source_register(env, node, 1);
1808 be_emit_finish_line_gas(env, NULL);
1810 be_emit_cstring(env, "\txorpd ");
1811 ia32_emit_source_register(env, node, 1);
1812 be_emit_cstring(env, ", ");
1813 ia32_emit_source_register(env, node, 0);
1814 be_emit_finish_line_gas(env, node);
1815 } else if (cls1 == &ia32_reg_classes[CLASS_ia32_vfp]) {
1817 } else if (cls1 == &ia32_reg_classes[CLASS_ia32_st]) {
1823 * Emits code for Constant loading.
1826 void emit_ia32_Const(ia32_emit_env_t *env, const ir_node *node) {
1827 const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
1830 if(attr->symconst == NULL && attr->offset == 0) {
1831 assert(get_ia32_flags(node) & arch_irn_flags_modify_flags);
1832 be_emit_cstring(env, "\txorl ");
1833 ia32_emit_dest_register(env, node, 0);
1834 be_emit_cstring(env, ", ");
1835 ia32_emit_dest_register(env, node, 0);
1837 be_emit_cstring(env, "\tmovl ");
1838 emit_ia32_Immediate(env, node);
1839 be_emit_cstring(env, ", ");
1840 ia32_emit_dest_register(env, node, 0);
1843 be_emit_finish_line_gas(env, node);
1847 * Emits code to load the TLS base
1850 void emit_ia32_LdTls(ia32_emit_env_t *env, const ir_node *node) {
1851 be_emit_cstring(env, "\tmovl %gs:0, ");
1852 ia32_emit_dest_register(env, node, 0);
1853 be_emit_finish_line_gas(env, node);
1856 /* helper function for emit_ia32_Minus64Bit */
1857 static void emit_mov(ia32_emit_env_t *env, const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1859 be_emit_cstring(env, "\tmovl ");
1860 ia32_emit_register(env, src);
1861 be_emit_cstring(env, ", ");
1862 ia32_emit_register(env, dst);
1863 be_emit_finish_line_gas(env, node);
1866 /* helper function for emit_ia32_Minus64Bit */
1867 static void emit_neg(ia32_emit_env_t *env, const ir_node* node, const arch_register_t *reg)
1869 be_emit_cstring(env, "\tnegl ");
1870 ia32_emit_register(env, reg);
1871 be_emit_finish_line_gas(env, node);
1874 /* helper function for emit_ia32_Minus64Bit */
1875 static void emit_sbb0(ia32_emit_env_t *env, const ir_node* node, const arch_register_t *reg)
1877 be_emit_cstring(env, "\tsbbl $0, ");
1878 ia32_emit_register(env, reg);
1879 be_emit_finish_line_gas(env, node);
1882 /* helper function for emit_ia32_Minus64Bit */
1883 static void emit_sbb(ia32_emit_env_t *env, const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1885 be_emit_cstring(env, "\tsbbl ");
1886 ia32_emit_register(env, src);
1887 be_emit_cstring(env, ", ");
1888 ia32_emit_register(env, dst);
1889 be_emit_finish_line_gas(env, node);
1892 /* helper function for emit_ia32_Minus64Bit */
1893 static void emit_xchg(ia32_emit_env_t *env, const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
1895 be_emit_cstring(env, "\txchgl ");
1896 ia32_emit_register(env, src);
1897 be_emit_cstring(env, ", ");
1898 ia32_emit_register(env, dst);
1899 be_emit_finish_line_gas(env, node);
1902 /* helper function for emit_ia32_Minus64Bit */
1903 static void emit_zero(ia32_emit_env_t *env, const ir_node* node, const arch_register_t *reg)
1905 be_emit_cstring(env, "\txorl ");
1906 ia32_emit_register(env, reg);
1907 be_emit_cstring(env, ", ");
1908 ia32_emit_register(env, reg);
1909 be_emit_finish_line_gas(env, node);
1912 static void emit_ia32_Minus64Bit(ia32_emit_env_t *env, const ir_node *node)
1914 const arch_register_t *in_lo = get_in_reg( env, node, 0);
1915 const arch_register_t *in_hi = get_in_reg( env, node, 1);
1916 const arch_register_t *out_lo = get_out_reg(env, node, 0);
1917 const arch_register_t *out_hi = get_out_reg(env, node, 1);
1919 if (out_lo == in_lo) {
1920 if (out_hi != in_hi) {
1921 /* a -> a, b -> d */
1924 /* a -> a, b -> b */
1927 } else if (out_lo == in_hi) {
1928 if (out_hi == in_lo) {
1929 /* a -> b, b -> a */
1930 emit_xchg(env, node, in_lo, in_hi);
1933 /* a -> b, b -> d */
1934 emit_mov(env, node, in_hi, out_hi);
1935 emit_mov(env, node, in_lo, out_lo);
1939 if (out_hi == in_lo) {
1940 /* a -> c, b -> a */
1941 emit_mov(env, node, in_lo, out_lo);
1943 } else if (out_hi == in_hi) {
1944 /* a -> c, b -> b */
1945 emit_mov(env, node, in_lo, out_lo);
1948 /* a -> c, b -> d */
1949 emit_mov(env, node, in_lo, out_lo);
1955 emit_neg( env, node, out_hi);
1956 emit_neg( env, node, out_lo);
1957 emit_sbb0(env, node, out_hi);
1961 emit_zero(env, node, out_hi);
1962 emit_neg( env, node, out_lo);
1963 emit_sbb( env, node, in_hi, out_hi);
1967 void emit_be_Return(ia32_emit_env_t *env, const ir_node *node)
1969 be_emit_cstring(env, "\tret");
1970 be_emit_finish_line_gas(env, node);
1974 void emit_Nothing(ia32_emit_env_t *env, const ir_node *node)
1981 /***********************************************************************************
1984 * _ __ ___ __ _ _ _ __ | |_ _ __ __ _ _ __ ___ _____ _____ _ __| | __
1985 * | '_ ` _ \ / _` | | '_ \ | _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
1986 * | | | | | | (_| | | | | | | | | | | (_| | | | | | | __/\ V V / (_) | | | <
1987 * |_| |_| |_|\__,_|_|_| |_| |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
1989 ***********************************************************************************/
1992 * Enters the emitter functions for handled nodes into the generic
1993 * pointer of an opcode.
1996 void ia32_register_emitters(void) {
1998 #define IA32_EMIT2(a,b) op_ia32_##a->ops.generic = (op_func)emit_ia32_##b
1999 #define IA32_EMIT(a) IA32_EMIT2(a,a)
2000 #define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
2001 #define IGN(a) op_##a->ops.generic = (op_func)emit_Nothing
2002 #define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
2003 #define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing
2005 /* first clear the generic function pointer for all ops */
2006 clear_irp_opcodes_generic_func();
2008 /* register all emitter functions defined in spec */
2009 ia32_register_spec_emitters();
2011 /* other ia32 emitter functions */
2014 IA32_EMIT(SwitchJmp);
2017 IA32_EMIT(Conv_I2FP);
2018 IA32_EMIT(Conv_FP2I);
2019 IA32_EMIT(Conv_FP2FP);
2020 IA32_EMIT(Conv_I2I);
2021 IA32_EMIT(Conv_I2I8Bit);
2024 IA32_EMIT(Minus64Bit);
2029 IA32_EMIT2(fcomJmp, x87CmpJmp);
2030 IA32_EMIT2(fcompJmp, x87CmpJmp);
2031 IA32_EMIT2(fcomppJmp, x87CmpJmp);
2032 IA32_EMIT2(fcomrJmp, x87CmpJmp);
2033 IA32_EMIT2(fcomrpJmp, x87CmpJmp);
2034 IA32_EMIT2(fcomrppJmp, x87CmpJmp);
2037 /* benode emitter */
2062 static const char *last_name = NULL;
2063 static unsigned last_line = -1;
2064 static unsigned num = -1;
2067 * Emit the debug support for node node.
2070 void ia32_emit_dbg(ia32_emit_env_t *env, const ir_node *node) {
2071 dbg_info *db = get_irn_dbg_info(node);
2073 const char *fname = be_retrieve_dbg_info(db, &lineno);
2075 if (! env->cg->birg->main_env->options->stabs_debug_support)
2079 if (last_name != fname) {
2081 be_dbg_include_begin(env->cg->birg->main_env->db_handle, fname);
2084 if (last_line != lineno) {
2087 snprintf(name, sizeof(name), ".LM%u", ++num);
2089 be_dbg_line(env->cg->birg->main_env->db_handle, lineno, name);
2090 be_emit_string(env, name);
2091 be_emit_cstring(env, ":\n");
2092 be_emit_write_line(env);
2097 typedef void (*emit_func_ptr) (ia32_emit_env_t *, const ir_node *);
2100 * Emits code for a node.
2103 void ia32_emit_node(ia32_emit_env_t *env, const ir_node *node) {
2104 ir_op *op = get_irn_op(node);
2106 DBG((dbg, LEVEL_1, "emitting code for %+F\n", node));
2108 if (op->ops.generic) {
2109 emit_func_ptr func = (emit_func_ptr) op->ops.generic;
2110 ia32_emit_dbg(env, node);
2111 (*func) (env, node);
2113 emit_Nothing(env, node);
2114 ir_fprintf(stderr, "Error: No emit handler for node %+F (%+G, graph %+F)\n", node, node, current_ir_graph);
2120 * Emits gas alignment directives
2123 void ia32_emit_alignment(ia32_emit_env_t *env, unsigned align, unsigned skip) {
2124 be_emit_cstring(env, "\t.p2align ");
2125 be_emit_irprintf(env->emit, "%u,,%u\n", align, skip);
2126 be_emit_write_line(env);
2130 * Emits gas alignment directives for Functions depended on cpu architecture.
2133 void ia32_emit_align_func(ia32_emit_env_t *env, cpu_support cpu) {
2135 unsigned maximum_skip;
2150 maximum_skip = (1 << align) - 1;
2151 ia32_emit_alignment(env, align, maximum_skip);
2155 * Emits gas alignment directives for Labels depended on cpu architecture.
2158 void ia32_emit_align_label(ia32_emit_env_t *env, cpu_support cpu) {
2159 unsigned align; unsigned maximum_skip;
2174 maximum_skip = (1 << align) - 1;
2175 ia32_emit_alignment(env, align, maximum_skip);
2179 * Test wether a block should be aligned.
2180 * For cpus in the P4/Athlon class it is usefull to align jump labels to
2181 * 16 bytes. However we should only do that if the alignment nops before the
2182 * label aren't executed more often than we have jumps to the label.
2185 int should_align_block(ia32_emit_env_t *env, ir_node *block, ir_node *prev) {
2186 static const double DELTA = .0001;
2187 ir_exec_freq *exec_freq = env->cg->birg->exec_freq;
2189 double prev_freq = 0; /**< execfreq of the fallthrough block */
2190 double jmp_freq = 0; /**< execfreq of all non-fallthrough blocks */
2191 cpu_support cpu = env->isa->opt_arch;
2194 if(exec_freq == NULL)
2196 if(cpu == arch_i386 || cpu == arch_i486)
2199 block_freq = get_block_execfreq(exec_freq, block);
2200 if(block_freq < DELTA)
2203 n_cfgpreds = get_Block_n_cfgpreds(block);
2204 for(i = 0; i < n_cfgpreds; ++i) {
2205 ir_node *pred = get_Block_cfgpred_block(block, i);
2206 double pred_freq = get_block_execfreq(exec_freq, pred);
2209 prev_freq += pred_freq;
2211 jmp_freq += pred_freq;
2215 if(prev_freq < DELTA && !(jmp_freq < DELTA))
2218 jmp_freq /= prev_freq;
2222 case arch_athlon_64:
2224 return jmp_freq > 3;
2226 return jmp_freq > 2;
2231 void ia32_emit_block_header(ia32_emit_env_t *env, ir_node *block, ir_node *prev)
2236 ir_exec_freq *exec_freq = env->cg->birg->exec_freq;
2238 n_cfgpreds = get_Block_n_cfgpreds(block);
2239 need_label = (n_cfgpreds != 0);
2241 if (should_align_block(env, block, prev)) {
2243 ia32_emit_align_label(env, env->isa->opt_arch);
2247 ia32_emit_block_name(env, block);
2248 be_emit_char(env, ':');
2250 be_emit_pad_comment(env);
2251 be_emit_cstring(env, " /* preds:");
2253 /* emit list of pred blocks in comment */
2254 arity = get_irn_arity(block);
2255 for (i = 0; i < arity; ++i) {
2256 ir_node *predblock = get_Block_cfgpred_block(block, i);
2257 be_emit_irprintf(env->emit, " %d", get_irn_node_nr(predblock));
2260 be_emit_cstring(env, "\t/* ");
2261 ia32_emit_block_name(env, block);
2262 be_emit_cstring(env, ": ");
2264 if (exec_freq != NULL) {
2265 be_emit_irprintf(env->emit, " freq: %f",
2266 get_block_execfreq(exec_freq, block));
2268 be_emit_cstring(env, " */\n");
2269 be_emit_write_line(env);
2273 * Walks over the nodes in a block connected by scheduling edges
2274 * and emits code for each node.
2277 void ia32_gen_block(ia32_emit_env_t *env, ir_node *block, ir_node *last_block)
2279 const ir_node *node;
2281 ia32_emit_block_header(env, block, last_block);
2283 /* emit the contents of the block */
2284 ia32_emit_dbg(env, block);
2285 sched_foreach(block, node) {
2286 ia32_emit_node(env, node);
2291 * Emits code for function start.
2294 void ia32_emit_func_prolog(ia32_emit_env_t *env, ir_graph *irg) {
2295 ir_entity *irg_ent = get_irg_entity(irg);
2296 const char *irg_name = get_entity_ld_name(irg_ent);
2297 cpu_support cpu = env->isa->opt_arch;
2298 const be_irg_t *birg = env->cg->birg;
2300 be_emit_write_line(env);
2301 be_gas_emit_switch_section(env->emit, GAS_SECTION_TEXT);
2302 be_dbg_method_begin(birg->main_env->db_handle, irg_ent, be_abi_get_stack_layout(birg->abi));
2303 ia32_emit_align_func(env, cpu);
2304 if (get_entity_visibility(irg_ent) == visibility_external_visible) {
2305 be_emit_cstring(env, ".global ");
2306 be_emit_string(env, irg_name);
2307 be_emit_char(env, '\n');
2308 be_emit_write_line(env);
2310 ia32_emit_function_object(env, irg_name);
2311 be_emit_string(env, irg_name);
2312 be_emit_cstring(env, ":\n");
2313 be_emit_write_line(env);
2317 * Emits code for function end
2320 void ia32_emit_func_epilog(ia32_emit_env_t *env, ir_graph *irg) {
2321 const char *irg_name = get_entity_ld_name(get_irg_entity(irg));
2322 const be_irg_t *birg = env->cg->birg;
2324 ia32_emit_function_size(env, irg_name);
2325 be_dbg_method_end(birg->main_env->db_handle);
2326 be_emit_char(env, '\n');
2327 be_emit_write_line(env);
2332 * Sets labels for control flow nodes (jump target)
2335 void ia32_gen_labels(ir_node *block, void *data)
2338 int n = get_Block_n_cfgpreds(block);
2341 for (n--; n >= 0; n--) {
2342 pred = get_Block_cfgpred(block, n);
2343 set_irn_link(pred, block);
2348 * Emit an exception label if the current instruction can fail.
2350 void ia32_emit_exc_label(ia32_emit_env_t *env, const ir_node *node) {
2351 if (get_ia32_exc_label(node)) {
2352 be_emit_irprintf(env->emit, ".EXL%u\n", 0);
2353 be_emit_write_line(env);
2358 * Main driver. Emits the code for one routine.
2360 void ia32_gen_routine(ia32_code_gen_t *cg, ir_graph *irg) {
2361 ia32_emit_env_t env;
2363 ir_node *last_block = NULL;
2366 env.isa = (ia32_isa_t *)cg->arch_env->isa;
2367 env.emit = &env.isa->emit;
2368 env.arch_env = cg->arch_env;
2371 ia32_register_emitters();
2373 ia32_emit_func_prolog(&env, irg);
2374 irg_block_walk_graph(irg, ia32_gen_labels, NULL, &env);
2376 n = ARR_LEN(cg->blk_sched);
2377 for (i = 0; i < n;) {
2380 block = cg->blk_sched[i];
2382 next_bl = i < n ? cg->blk_sched[i] : NULL;
2384 /* set here the link. the emitter expects to find the next block here */
2385 set_irn_link(block, next_bl);
2386 ia32_gen_block(&env, block, last_block);
2390 ia32_emit_func_epilog(&env, irg);
2393 void ia32_init_emitter(void)
2395 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");