3 #include "ia32_emitter.h"
4 #include "ia32_nodes_attr.h"
5 #include "ia32_new_nodes.h"
7 #define TARVAL_SNPRINTF_BUF_LEN 1024
9 const char *get_dest_reg_name(ir_node *n, int num) {
10 return get_ia32_out_reg_name(n, --num);
13 const char *get_source_reg_name(ir_node *n, int num) {
14 return get_ia32_in_reg_name(n, --num);
17 char *node_const_to_str(ir_node *n) {
18 char *buf = malloc(TARVAL_SNPRINTF_BUF_LEN);
19 tarval_snprintf(buf, TARVAL_SNPRINTF_BUF_LEN, get_ia32_Immop_tarval(n));
23 char *node_offset_to_str(ir_node *n) {
24 char *buf = malloc(TARVAL_SNPRINTF_BUF_LEN);
25 tarval_snprintf(buf, TARVAL_SNPRINTF_BUF_LEN, get_ia32_offs(n));
29 void equalize_dest_src(FILE *F, ir_node *n) {
30 if (get_ia32_out_regnr(n, 0) != get_ia32_in_regnr(n, 0))
31 fprintf(F, "\tmovl %%%s, %%%s\t\t\t/* src -> dest for 2 address code */\n", get_source_reg_name(n, 1), get_dest_reg_name(n, 1));
35 * coding of conditions
37 struct cmp2conditon_t {
43 * positive conditions for signed compares
45 static const struct cmp2conditon_t cmp2condition_s[] = {
46 { NULL, pn_Cmp_False }, /* always false */
47 { "e", pn_Cmp_Eq }, /* == */
48 { "l", pn_Cmp_Lt }, /* < */
49 { "le", pn_Cmp_Le }, /* <= */
50 { "g", pn_Cmp_Gt }, /* > */
51 { "ge", pn_Cmp_Ge }, /* >= */
52 { "ne", pn_Cmp_Lg }, /* != */
53 { "ordered", pn_Cmp_Leg }, /* Floating point: ordered */
54 { "unordered", pn_Cmp_Uo }, /* FLoting point: unordered */
55 { "unordered or ==", pn_Cmp_Ue }, /* Floating point: unordered or == */
56 { "unordered or <", pn_Cmp_Ul }, /* Floating point: unordered or < */
57 { "unordered or <=", pn_Cmp_Ule }, /* Floating point: unordered or <= */
58 { "unordered or >", pn_Cmp_Ug }, /* Floating point: unordered or > */
59 { "unordered or >=", pn_Cmp_Uge }, /* Floating point: unordered or >= */
60 { "unordered or !=", pn_Cmp_Ne }, /* Floating point: unordered or != */
61 { NULL, pn_Cmp_True }, /* always true */
65 * positive conditions for unsigned compares
67 static const struct cmp2conditon_t cmp2condition_u[] = {
68 { NULL, pn_Cmp_False }, /* always false */
69 { "e", pn_Cmp_Eq }, /* == */
70 { "b", pn_Cmp_Lt }, /* < */
71 { "be", pn_Cmp_Le }, /* <= */
72 { "a", pn_Cmp_Gt }, /* > */
73 { "ae", pn_Cmp_Ge }, /* >= */
74 { "ne", pn_Cmp_Lg }, /* != */
75 { "ordered", pn_Cmp_Leg }, /* Floating point: ordered */
76 { "unordered", pn_Cmp_Uo }, /* FLoting point: unordered */
77 { "unordered or ==", pn_Cmp_Ue }, /* Floating point: unordered or == */
78 { "unordered or <", pn_Cmp_Ul }, /* Floating point: unordered or < */
79 { "unordered or <=", pn_Cmp_Ule }, /* Floating point: unordered or <= */
80 { "unordered or >", pn_Cmp_Ug }, /* Floating point: unordered or > */
81 { "unordered or >=", pn_Cmp_Uge }, /* Floating point: unordered or >= */
82 { "unordered or !=", pn_Cmp_Ne }, /* Floating point: unordered or != */
83 { NULL, pn_Cmp_True }, /* always true */
87 * returns the condition code
89 const char *get_cmp_suffix(int cmp_code, int unsigned_cmp)
91 assert(cmp2condition_s[cmp_code].num == cmp_code);
92 assert(cmp2condition_u[cmp_code].num == cmp_code);
94 return unsigned_cmp ? cmp2condition_u[cmp_code & 7].name : cmp2condition_s[cmp_code & 7].name;
97 void emit_ia32_Proj_Cond(FILE *F, ir_node *n, ir_node *cond) {
98 ir_node *succ_block = get_edge_src_irn(get_irn_out_edge_first(n));
99 ir_node *sel = get_Cond_selector(cond);
100 ir_mode *sel_mode = get_irn_mode(sel);
102 assert(succ_block && "Target block of Proj_Cond missing!");
104 if (sel_mode == mode_b) { // Boolean condition
105 int label = get_irn_node_nr(succ_block);
106 int nr = get_Proj_proj(n);
107 fprintf(F, "j%s%s Label%d\t\t\t/* if (%sCond) goto Label */\n",
108 nr == pn_Cond_true ? "" : "n",
109 get_cmp_suffix(get_Proj_proj(sel), mode_is_signed(sel_mode)),
111 nr == pn_Cond_true ? "" : "!");