/**
* This file implements the node emitter.
- *
+ * @author Christian Wuerdig
* $Id$
*/
assert(0 && "unsupported op type");
}
-#undef PRODUCES_RESULT
-
return buf;
}
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%C", n);
}
else {
- lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D", n);
+ if (is_ia32_MulS(n) || is_ia32_Mulh(n)) {
+ /* MulS and Mulh implicitly multiply by EAX */
+ lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S", n);
+ }
+ else
+ lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D", n);
}
break;
case ia32_AddrModeD:
/* the first Proj must always be created */
if (get_Proj_proj(proj1) == pn_Cond_true) {
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_cmp_suffix(get_ia32_pncode(irn), ! mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
get_cfop_target(proj1, buf));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* cmp(a, b) == TRUE */");
}
else {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
get_cmp_suffix(get_negated_pnc(get_ia32_pncode(irn), mode),
- !mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
+ ! mode_is_signed(get_irn_mode(get_irn_n(irn, 0)))),
get_cfop_target(proj1, buf));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* cmp(a, b) == FALSE */");
}
finish_CondJmp(F, irn, get_ia32_res_mode(irn));
}
+/**
+ * Emits code for conditional SSE floating point jump with two variables.
+ */
+static void emit_ia32_xCondJmp(ir_node *irn, ia32_emit_env_t *env) {
+ FILE *F = env->out;
+ char cmd_buf[SNPRINTF_BUF_LEN];
+ char cmnt_buf[SNPRINTF_BUF_LEN];
+
+ lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "ucomis%M %s", irn, ia32_emit_binop(irn, env));
+ lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
+ IA32_DO_EMIT(irn);
+ finish_CondJmp(F, irn, get_ia32_res_mode(irn));
+
+}
+
/**
* Emits code for conditional x87 floating point jump with two variables.
*/
if (reverse)
set_ia32_pncode(irn, (long)get_negated_pnc(get_ia32_pncode(irn), mode_Is));
- snprintf(cmd_buf, SNPRINTF_BUF_LEN, "%s %s", instr, reg);
+ snprintf(cmd_buf, SNPRINTF_BUF_LEN, "%s %%%s", instr, reg);
lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
IA32_DO_EMIT(irn);
lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "fnstsw %%ax", irn);
FILE *F = env->out;
const lc_arg_env_t *arg_env = ia32_get_arg_env();
const char *cmp_suffix = get_cmp_suffix(get_ia32_pncode(irn), ! mode_is_signed(get_irn_mode(get_irn_n(irn, 0))));
+ int is_PsiCondCMov = is_ia32_PsiCondCMov(irn);
char cmd_buf[SNPRINTF_BUF_LEN];
char cmnt_buf[SNPRINTF_BUF_LEN];
const arch_register_t *in1, *in2, *out;
out = arch_get_irn_register(env->arch_env, irn);
- in1 = arch_get_irn_register(env->arch_env, get_irn_n(irn, 2));
- in2 = arch_get_irn_register(env->arch_env, get_irn_n(irn, 3));
+ in1 = arch_get_irn_register(env->arch_env, get_irn_n(irn, 2 - is_PsiCondCMov));
+ in2 = arch_get_irn_register(env->arch_env, get_irn_n(irn, 3 - is_PsiCondCMov));
/* we have to emit the cmp first, because the destination register */
/* could be one of the compare registers */
else if (is_ia32_xCmpCMov(irn)) {
lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "ucomis%M %1S, %2S", get_irn_n(irn, 0), irn, irn);
}
- else if (is_ia32_PsiCondCMov(irn)) {
+ else if (is_PsiCondCMov) {
/* omit compare because flags are already set by And/Or */
snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
}
IA32_EMIT(xCmp);
IA32_EMIT(xCmpSet);
IA32_EMIT(xCmpCMov);
+ IA32_EMIT(xCondJmp);
IA32_EMIT2(fcomJmp, x87CondJmp);
IA32_EMIT2(fcompJmp, x87CondJmp);
IA32_EMIT2(fcomppJmp, x87CondJmp);