+static int get_n_out_edges(const ir_node *irn) {
+ const ir_edge_t *edge;
+ int cnt = 0;
+
+ foreach_out_edge(irn, edge) {
+ cnt++;
+ }
+
+ return cnt;
+}
+
+static ir_node *belower_skip_proj(ir_node *irn) {
+ while(is_Proj(irn))
+ irn = get_Proj_pred(irn);
+ return irn;
+}
+
+static void fix_in(ir_node *irn, ir_node *old, ir_node *nw) {
+ int i, n = get_irn_arity(irn);
+
+ irn = belower_skip_proj(irn);
+
+ for (i = 0; i < n; i++) {
+ if (get_irn_n(irn, i) == old) {
+ set_irn_n(irn, i, nw);
+ break;
+ }
+ }
+}
+
+static void gen_assure_different_pattern(ir_node *irn, be_irg_t *birg, ir_node *other_different) {
+ const arch_env_t *arch_env = birg->main_env->arch_env;
+ ir_node *in[2], *keep, *cpy, *temp;
+ ir_node *block = get_nodes_block(irn);
+ firm_dbg_module_t *mod = firm_dbg_register("firm.be.lower");
+ const arch_register_class_t *cls = arch_get_irn_reg_class(arch_env, other_different, -1);
+
+ if (arch_irn_is_ignore(arch_env, other_different)) {
+ DBG((mod, LEVEL_1, "ignore constraint for %+F because other_irn is ignore\n", irn));
+ return;
+ }
+
+ /* Make a not spillable copy of the different node */
+ /* this is needed because the different irn could be */
+ /* in block far far away */
+ /* The copy is optimized later if not needed */
+
+ temp = new_rd_Unknown(birg->irg, get_irn_mode(other_different));
+ cpy = be_new_Copy(cls, birg->irg, block, temp);
+ be_node_set_flags(cpy, BE_OUT_POS(0), arch_irn_flags_dont_spill);
+
+ in[0] = irn;
+ in[1] = cpy;
+
+ /* Add the Keep resp. CopyKeep and reroute the users */
+ /* of the other_different irn in case of CopyKeep. */
+ if (get_n_out_edges(other_different) == 1) {
+ keep = be_new_Keep(cls, birg->irg, block, 2, in);
+ }
+ else {
+ keep = be_new_CopyKeep(cls, birg->irg, block, cpy, 2, in, get_irn_mode(other_different));
+ edges_reroute(other_different, keep, birg->irg);
+ }
+
+ /* after rerouting: let the copy point to the other_different irn */
+ set_irn_n(cpy, 0, other_different);
+
+ /* Let the irn use the copy instead of the old other_different */
+ fix_in(irn, other_different, cpy);
+
+ DBG((mod, LEVEL_1, "created %+F for %+F to assure should_be_different\n", keep, irn));
+}
+
/**
* Checks if node has a should_be_different constraint in output
* and adds a Keep then to assure the constraint.
*/
-static void assure_different_constraint(ir_node *irn, be_irg_t *birg) {
+static void assure_different_constraints(ir_node *irn, be_irg_t *birg) {
const arch_env_t *arch_env = birg->main_env->arch_env;
const arch_register_req_t *req;
arch_register_req_t req_temp;
- ir_node *in[2], *keep;
- firm_dbg_module_t *mod = firm_dbg_register("firm.be.lower");
+ int i, n;
req = arch_get_register_req(arch_env, &req_temp, irn, -1);
- if (req && arch_register_req_is(req, should_be_different)) {
- /* We found a should_be_different constraint. */
- assert(req->other_different && "missing irn for constraint");
-
- in[0] = irn;
- in[1] = req->other_different;
-
- keep = be_new_Keep(req->cls, birg->irg, get_nodes_block(irn), 2, in);
- DBG((mod, LEVEL_1, "created %+F for %+F to assure should_be_different\n", keep, irn));
+ if (req) {
+ if (arch_register_req_is(req, should_be_different)) {
+ gen_assure_different_pattern(irn, birg, req->other_different);
+ }
+ else if (arch_register_req_is(req, should_be_different_from_all)) {
+ n = get_irn_arity(belower_skip_proj(irn));
+ for (i = 0; i < n; i++) {
+ gen_assure_different_pattern(irn, birg, get_irn_n(belower_skip_proj(irn), i));
+ }
+ }
}
}
return;
if (mode_is_datab(get_irn_mode(irn)))
- assure_different_constraint(irn, walk_env);
+ assure_different_constraints(irn, walk_env);
return;
}
if (mode) {
switch (get_mode_size_bits(mode)) {
case 8:
- obstack_printf(obst, "BYTE PTR ");
+ obstack_printf(obst, "BYTE ");
break;
case 16:
- obstack_printf(obst, "WORD PTR ");
+ obstack_printf(obst, "WORD ");
break;
default:
break;
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
get_cmp_suffix(get_ia32_pncode(irn), !mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
get_cfop_target(proj, buf));
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* cmp(a, b) == TRUE */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; cmp(a, b) == TRUE");
}
else {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jn%s %s",
get_cmp_suffix(get_ia32_pncode(irn), !mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
get_cfop_target(proj, buf));
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* cmp(a, b) == FALSE */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; cmp(a, b) == FALSE");
}
IA32_DO_EMIT;
proj = get_edge_src_irn(edge);
assert(is_Proj(proj) && "CondJmp with a non-Proj");
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(proj, buf));
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* otherwise */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; otherwise");
IA32_DO_EMIT;
}
char cmnt_buf[SNPRINTF_BUF_LEN];
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmp %s", ia32_emit_binop(irn, env));
- lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "; %+F", irn);
IA32_DO_EMIT;
finish_CondJmp(F, irn);
}
if (tbl.min_value != 0) {
lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "cmpl %lu, -%d(%1S)",
interval, tbl.min_value, irn);
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* first switch value is not 0 */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; first switch value is not 0");
IA32_DO_EMIT;
}
else {
lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "cmpl %lu, %1S", interval, irn);
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* compare for switch */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; compare for switch");
IA32_DO_EMIT;
}
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "ja %s", get_cfop_target(tbl.defProj, buf));
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default jump if out of range */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; default jump if out of range ");
IA32_DO_EMIT;
if (tbl.num_branches > 1) {
/* create table */
lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "jmp [%1S*4+%s]", irn, tbl.label);
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* get jump table entry as target */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; get jump table entry as target");
IA32_DO_EMIT;
fprintf(F, "\t.section\t.rodata\n");
for (i = 1; i < tbl.num_branches; ++i) {
while (++last_value < tbl.branches[i].value) {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.defProj, buf));
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default case */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; default case");
IA32_DO_EMIT;
}
snprintf(cmd_buf, SNPRINTF_BUF_LEN, ".long %s", get_cfop_target(tbl.branches[i].target, buf), last_value);
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */", last_value);
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; case %d", last_value);
IA32_DO_EMIT;
}
else {
/* one jump is enough */
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(tbl.branches[0].target, buf));
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* only one case given */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; only one case given");
IA32_DO_EMIT;
}
}
else { // no jump table
for (i = 0; i < tbl.num_branches; ++i) {
lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "cmpl %d, %1S", tbl.branches[i].value, irn);
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */", i);
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; case %d", i);
IA32_DO_EMIT;
fprintf(F, "\tje %s\n", get_cfop_target(tbl.branches[i].target, buf));
}
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(tbl.defProj, buf));
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* default case */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; default case");
IA32_DO_EMIT;
}
char buf[SNPRINTF_BUF_LEN], cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(irn, buf), get_irn_link(irn));
- lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%+F) */", irn, get_irn_link(irn));
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "; %+F(%+F)", irn, get_irn_link(irn));
IA32_DO_EMIT;
}
switch(rem) {
case 1:
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsb");
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 1 */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; memcopy remainder 1");
break;
case 2:
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsw");
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 2 */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; memcopy remainder 2");
break;
case 3:
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsb");
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 3 */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; memcopy remainder 3");
IA32_DO_EMIT;
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsw");
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy remainder 3 */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; memcopy remainder 3");
break;
}
emit_CopyB_prolog(F, rem, size);
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "rep movsd");
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; memcopy");
IA32_DO_EMIT;
}
size >>= 2;
while (size--) {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "movsd");
- snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* memcopy unrolled */");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "; memcopy unrolled");
IA32_DO_EMIT;
}
}
}
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cvt%s2%s %s", from, to, buf);
- lc_esnprintf(env, cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%+F, %+F) */", irn, src_mode, tgt_mode);
+ lc_esnprintf(env, cmnt_buf, SNPRINTF_BUF_LEN, "; %+F(%+F, %+F)", irn, src_mode, tgt_mode);
IA32_DO_EMIT;
}
lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "%1D", get_irn_n(irn, be_pos_Call_ptr));
}
- lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (be_Call) */", irn);
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "; %+F (be_Call)", irn);
IA32_DO_EMIT;
}
if (offs) {
lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1S,%s%u", irn,
(dir == be_stack_dir_along) ? " -" : " ", offs);
- lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (IncSP) */", irn);
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "; %+F (IncSP)", irn);
}
else {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
- lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* omitted %+F (IncSP) with 0 */", irn);
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "; omitted %+F (IncSP) with 0", irn);
}
IA32_DO_EMIT;
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, %3S", irn, irn);
- lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (restore SP) */", irn);
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "; %+F (restore SP)", irn);
IA32_DO_EMIT;
}
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %1D, %1S", irn, irn);
- lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "; %+F", irn);
IA32_DO_EMIT;
}
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "xchg %1S, %2S", irn, irn);
- lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%1A, %2A) */", irn, irn, irn);
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "; %+F(%1A, %2A)", irn, irn, irn);
IA32_DO_EMIT;
}
(*emit)(irn, env);
}
else {
- ir_fprintf(F, "\t%35s /* %+F */\n", " ", irn);
+ ir_fprintf(F, "\t%35s ; %+F \n", " ", irn);
}
}
* Emits code for function start.
*/
static void ia32_emit_func_prolog(FILE *F, ir_graph *irg) {
- const char *irg_name = get_entity_name(get_irg_entity(irg));
+ entity *irg_ent = get_irg_entity(irg);
+ const char *irg_name = get_entity_name(irg_ent);
- fprintf(F, "\t.text\n");
- fprintf(F, ".globl %s\n", irg_name);
- fprintf(F, "\t.type\t%s, @function\n", irg_name);
+// fprintf(F, "\t.text\n");
+ if (get_entity_visibility(irg_ent) == visibility_external_visible) {
+ fprintf(F, "global %s\n", irg_name);
+ }
+// fprintf(F, "\t.type\t%s, @function\n", irg_name);
fprintf(F, "%s:\n", irg_name);
}
const char *irg_name = get_entity_name(get_irg_entity(irg));
fprintf(F, "\tret\n");
- fprintf(F, "\t.size\t%s, .-%s\n\n", irg_name, irg_name);
+ //printf(F, "\t.size\t%s, .-%s\n\n", irg_name, irg_name);
}
/**
$arch = "ia32";
+# this string marks the beginning of a comment in emit
+$comment_string = ';';
+
# The node description is done as a perl hash initializer with the
# following structure:
#
"comment" => "construct Add: Add(a, b) = Add(b, a) = a + b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. add %ia32_emit_binop\t\t\t/* Add(%A1, %A2) -> %D1 */'
+ "emit" => '. add %ia32_emit_binop\t\t\t ; Add(%A1, %A2) -> %D1 '
},
"Mul" => {
"comment" => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. imul %ia32_emit_binop\t\t\t/* Mul(%A1, %A2) -> %D1 */'
+ "emit" => '. imul %ia32_emit_binop ; Mul(%A1, %A2) -> %D1 '
},
# Mulh is an exception from the 4 INs with AM because the target is always EAX:EDX
"comment" => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r3", "edx in_r4" ] },
- "emit" => '. imul %ia32_emit_unop\t\t\t/* Mulh(%A1, %A2) -> %D1 */ '
+ "emit" => '. imul %ia32_emit_unop ; Mulh(%A1, %A2) -> %D1 '
},
"And" => {
"comment" => "construct And: And(a, b) = And(b, a) = a AND b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. and %ia32_emit_binop\t\t\t/* And(%A1, %A2) -> %D1 */'
+ "emit" => '. and %ia32_emit_binop ; And(%A1, %A2) -> %D1 '
},
"Or" => {
"comment" => "construct Or: Or(a, b) = Or(b, a) = a OR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. or %ia32_emit_binop\t\t\t/* Or(%A1, %A2) -> %D1 */'
+ "emit" => '. or %ia32_emit_binop ; Or(%A1, %A2) -> %D1 '
},
"Eor" => {
"comment" => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. xor %ia32_emit_binop\t\t\t/* Xor(%A1, %A2) -> %D1 */'
+ "emit" => '. xor %ia32_emit_binop ; Xor(%A1, %A2) -> %D1 '
},
"Max" => {
"comment" => "construct Max: Max(a, b) = Max(b, a) = a > b ? a : b",
"reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
"emit" =>
-'2. cmp %S1, %S2\t\t\t/* prepare Max (%S1 - %S2), (%A1, %A2) */
+'2. cmp %S1, %S2 ; prepare Max (%S1 - %S2), (%A1, %A2)
if (mode_is_signed(get_irn_mode(n))) {
-4. cmovl %D1, %S2\t\t\t/* %S1 is less %S2 */
+4. cmovl %D1, %S2 ; %S1 is less %S2
}
else {
-4. cmovb %D1, %S2\t\t\t/* %S1 is below %S2 */
+4. cmovb %D1, %S2 ; %S1 is below %S2
}
'
},
"comment" => "construct Min: Min(a, b) = Min(b, a) = a < b ? a : b",
"reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
"emit" =>
-'2. cmp %S1, %S2\t\t\t/* prepare Min (%S1 - %S2), (%A1, %A2) */
+'2. cmp %S1, %S2 ; prepare Min (%S1 - %S2), (%A1, %A2)
if (mode_is_signed(get_irn_mode(n))) {
-2. cmovg %D1, %S2\t\t\t/* %S1 is greater %S2 */
+2. cmovg %D1, %S2 ; %S1 is greater %S2
}
else {
-2. cmova %D1, %S2, %D1\t\t\t/* %S1 is above %S2 */
+2. cmova %D1, %S2, %D1 ; %S1 is above %S2
}
'
},
"comment" => "construct Mux: Mux(sel, a, b) == sel ? a : b",
"reg_req" => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r2" ] },
"emit" =>
-'. cmp %S1, 0\t\t\t/* compare Sel for CMov (%A2, %A3) */
-. cmovne %D1, %S3\t\t\t/* sel == true -> return %S3 */
+'. cmp %S1, 0 ; compare Sel for CMov (%A2, %A3)
+. cmovne %D1, %S3 ; sel == true -> return %S3
'
},
"comment" => "construct Sub: Sub(a, b) = a - b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. sub %ia32_emit_binop\t\t\t/* Sub(%A1, %A2) -> %D1 */'
+ "emit" => '. sub %ia32_emit_binop ; Sub(%A1, %A2) -> %D1 '
},
"DivMod" => {
"reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "eax in_r1", "edx in_r3" ] },
"emit" =>
' if (mode_is_signed(get_irn_mode(n))) {
-4. idiv %S2\t\t\t/* signed DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
+4. idiv %S2 ; signed DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3)
}
else {
-4. div %S2\t\t\t/* unsigned DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
+4. div %S2 ; unsigned DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3)
}
'
},
"comment" => "construct Shl: Shl(a, b) = a << b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. shl %ia32_emit_binop\t\t\t/* Shl(%A1, %A2) -> %D1 */'
+ "emit" => '. shl %ia32_emit_binop ; Shl(%A1, %A2) -> %D1 '
},
"Shr" => {
"comment" => "construct Shr: Shr(a, b) = a >> b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. shr %ia32_emit_binop\t\t\t/* Shr(%A1, %A2) -> %D1 */'
+ "emit" => '. shr %ia32_emit_binop ; Shr(%A1, %A2) -> %D1 '
},
"Shrs" => {
"comment" => "construct Shrs: Shrs(a, b) = a >> b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. sar %ia32_emit_binop\t\t\t/* Shrs(%A1, %A2) -> %D1 */'
+ "emit" => '. sar %ia32_emit_binop ; Shrs(%A1, %A2) -> %D1 '
},
"RotR" => {
"comment" => "construct RotR: RotR(a, b) = a ROTR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. ror %ia32_emit_binop\t\t\t/* RotR(%A1, %A2) -> %D1 */'
+ "emit" => '. ror %ia32_emit_binop ; RotR(%A1, %A2) -> %D1 '
},
"RotL" => {
"comment" => "construct RotL: RotL(a, b) = a ROTL b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. rol %ia32_emit_binop\t\t\t/* RotL(%A1, %A2) -> %D1 */'
+ "emit" => '. rol %ia32_emit_binop ; RotL(%A1, %A2) -> %D1 '
},
# unary operations
"comment" => "construct Minus: Minus(a) = -a",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. neg %ia32_emit_unop\t\t\t/* Neg(%A1) -> %D1, (%A1) */'
+ "emit" => '. neg %ia32_emit_unop ; Neg(%A1) -> %D1, (%A1) '
},
"Inc" => {
"comment" => "construct Increment: Inc(a) = a++",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. inc %ia32_emit_unop\t\t\t/* Inc(%S1) -> %D1, (%A1) */'
+ "emit" => '. inc %ia32_emit_unop ; Inc(%S1) -> %D1, (%A1) '
},
"Dec" => {
"comment" => "construct Decrement: Dec(a) = a--",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. dec %ia32_emit_unop\t\t\t/* Dec(%S1) -> %D1, (%A1) */'
+ "emit" => '. dec %ia32_emit_unop ; Dec(%S1) -> %D1, (%A1) '
},
"Not" => {
"comment" => "construct Not: Not(a) = !a",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. not %ia32_emit_unop\t\t\t/* Not(%S1) -> %D1, (%A1) */'
+ "emit" => '. not %ia32_emit_unop ; Not(%S1) -> %D1, (%A1) '
},
# other operations
"reg_req" => { "out" => [ "gp" ] },
"emit" =>
' if (get_ia32_Immop_tarval(n) == get_tarval_null(get_irn_mode(n))) {
-4. sub %D1, %D1\t\t\t/* optimized mov 0 to register */
+4. sub %D1, %D1 ; optimized mov 0 to register
}
else {
-4. mov %D1, %C\t\t\t/* Mov Const into register */
+4. mov %D1, %C ; Mov Const into register
}
',
},
"irn_flags" => "R",
"comment" => "construct CDQ: sign extend EAX -> EDX:EAX",
"reg_req" => { "in" => [ "gp" ], "out" => [ "eax in_r1", "edx" ] },
- "emit" => '. cdq\t\t\t/* sign extend EAX -> EDX:EAX, (%A1) */'
+ "emit" => '. cdq ; sign extend EAX -> EDX:EAX, (%A1) '
},
# Load / Store
"reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
"emit" =>
' if (get_mode_size_bits(get_ia32_ls_mode(n)) < 32) {
-4. mov%Mx %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */
+4. mov%Mx %D1, %ia32_emit_am ; Load((%A1)) -> %D1
}
else {
-4. mov %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */
+4. mov %D1, %ia32_emit_am ; Load((%A1)) -> %D1
}
'
},
"comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "none" ] },
- "emit" => '. mov %ia32_emit_binop\t\t\t/* Store(%A3) -> (%A1) */'
+ "emit" => '. mov %ia32_emit_binop ; Store(%A3) -> (%A1) '
},
"Lea" => {
"comment" => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
- "emit" => '. lea %D1, %ia32_emit_am\t\t/* LEA(%A1, %A2) */'
+ "emit" => '. lea %D1, %ia32_emit_am ; LEA(%A1, %A2) '
},
#--------------------------------------------------------#
"comment" => "construct SSE Add: Add(a, b) = Add(b, a) = a + b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. adds%M %ia32_emit_binop\t\t\t/* SSE Add(%A3, %A4) -> %D1 */'
+ "emit" => '. adds%M %ia32_emit_binop ; SSE Add(%A3, %A4) -> %D1 '
},
"fMul" => {
"comment" => "construct SSE Mul: Mul(a, b) = Mul(b, a) = a * b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. muls%M %ia32_emit_binop\t\t\t/* SSE Mul(%A3, %A4) -> %D1 */'
+ "emit" => '. muls%M %ia32_emit_binop ; SSE Mul(%A3, %A4) -> %D1 '
},
"fMax" => {
"comment" => "construct SSE Max: Max(a, b) = Max(b, a) = a > b ? a : b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. maxs%M %ia32_emit_binop\t\t\t/* SSE Max(%A3, %A4) -> %D1 */'
+ "emit" => '. maxs%M %ia32_emit_binop ; SSE Max(%A3, %A4) -> %D1 '
},
"fMin" => {
"comment" => "construct SSE Min: Min(a, b) = Min(b, a) = a < b ? a : b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. mins%M %ia32_emit_binop\t\t\t/* SSE Min(%A3, %A4) -> %D1 */'
+ "emit" => '. mins%M %ia32_emit_binop ; SSE Min(%A3, %A4) -> %D1 '
},
"fAnd" => {
"comment" => "construct SSE And: And(a, b) = a AND b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. andp%M %ia32_emit_binop\t\t\t/* SSE And(%A3, %A4) -> %D1 */'
+ "emit" => '. andp%M %ia32_emit_binop ; SSE And(%A3, %A4) -> %D1 '
},
"fOr" => {
"comment" => "construct SSE Or: Or(a, b) = a OR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. orp%M %ia32_emit_binop\t\t\t/* SSE Or(%A3, %A4) -> %D1 */'
+ "emit" => '. orp%M %ia32_emit_binop ; SSE Or(%A3, %A4) -> %D1 '
},
"fEor" => {
"comment" => "construct SSE Eor: Eor(a, b) = a XOR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. xorp%M %ia32_emit_binop\t\t\t/* SSE Xor(%A3, %A4) -> %D1 */'
+ "emit" => '. xorp%M %ia32_emit_binop ; SSE Xor(%A3, %A4) -> %D1 '
},
# not commutative operations
"comment" => "construct SSE Sub: Sub(a, b) = a - b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. subs%M %ia32_emit_binop\t\t\t/* SSE Sub(%A1, %A2) -> %D1 */'
+ "emit" => '. subs%M %ia32_emit_binop ; SSE Sub(%A1, %A2) -> %D1 '
},
"fDiv" => {
"comment" => "construct SSE Div: Div(a, b) = a / b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. divs%M %ia32_emit_binop\t\t\t/* SSE Div(%A1, %A2) -> %D1 */'
+ "emit" => '. divs%M %ia32_emit_binop ; SSE Div(%A1, %A2) -> %D1 '
},
# other operations
"comment" => "represents a SSE constant",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "out" => [ "fp" ] },
- "emit" => '. mov%M %D1, %C\t\t\t/* Load fConst into register */',
+ "emit" => '. mov%M %D1, %C ; Load fConst into register ',
},
# Load / Store
"comment" => "construct SSE Load: Load(ptr, mem) = LD ptr",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "fp" ] },
- "emit" => '. movs%M %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */'
+ "emit" => '. movs%M %D1, %ia32_emit_am ; Load((%A1)) -> %D1 '
},
"fStore" => {
"comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "none" ] },
- "emit" => '. movs%M %ia32_emit_am, %S3\t\t\t/* Store(%S3) -> (%A1) */'
+ "emit" => '. movs%M %ia32_emit_am, %S3 ; Store(%S3) -> (%A1) '
},
# CopyB