target-m68k: Optimize gen_flush_flags
Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
parent
9d896621c1
commit
36f0399d46
@ -458,18 +458,66 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base)
|
||||
|
||||
static void gen_flush_flags(DisasContext *s)
|
||||
{
|
||||
TCGv tmp;
|
||||
TCGv t0, t1;
|
||||
|
||||
switch (s->cc_op) {
|
||||
case CC_OP_FLAGS:
|
||||
return;
|
||||
|
||||
case CC_OP_ADD:
|
||||
tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
|
||||
tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
|
||||
/* Compute signed overflow for addition. */
|
||||
t0 = tcg_temp_new();
|
||||
t1 = tcg_temp_new();
|
||||
tcg_gen_sub_i32(t0, QREG_CC_N, QREG_CC_V);
|
||||
tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V);
|
||||
tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
|
||||
tcg_temp_free(t0);
|
||||
tcg_gen_andc_i32(QREG_CC_V, t1, QREG_CC_V);
|
||||
tcg_temp_free(t1);
|
||||
break;
|
||||
|
||||
case CC_OP_SUB:
|
||||
tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
|
||||
tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
|
||||
/* Compute signed overflow for subtraction. */
|
||||
t0 = tcg_temp_new();
|
||||
t1 = tcg_temp_new();
|
||||
tcg_gen_add_i32(t0, QREG_CC_N, QREG_CC_V);
|
||||
tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V);
|
||||
tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
|
||||
tcg_temp_free(t0);
|
||||
tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t1);
|
||||
tcg_temp_free(t1);
|
||||
break;
|
||||
|
||||
case CC_OP_CMP:
|
||||
tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_C, QREG_CC_N, QREG_CC_V);
|
||||
tcg_gen_sub_i32(QREG_CC_Z, QREG_CC_N, QREG_CC_V);
|
||||
/* Compute signed overflow for subtraction. */
|
||||
t0 = tcg_temp_new();
|
||||
tcg_gen_xor_i32(t0, QREG_CC_Z, QREG_CC_N);
|
||||
tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, QREG_CC_N);
|
||||
tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t0);
|
||||
tcg_temp_free(t0);
|
||||
tcg_gen_mov_i32(QREG_CC_N, QREG_CC_Z);
|
||||
break;
|
||||
|
||||
case CC_OP_LOGIC:
|
||||
tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
|
||||
tcg_gen_movi_i32(QREG_CC_C, 0);
|
||||
tcg_gen_movi_i32(QREG_CC_V, 0);
|
||||
break;
|
||||
|
||||
case CC_OP_DYNAMIC:
|
||||
gen_helper_flush_flags(cpu_env, QREG_CC_OP);
|
||||
break;
|
||||
|
||||
default:
|
||||
tmp = tcg_const_i32(s->cc_op);
|
||||
gen_helper_flush_flags(cpu_env, tmp);
|
||||
tcg_temp_free(tmp);
|
||||
t0 = tcg_const_i32(s->cc_op);
|
||||
gen_helper_flush_flags(cpu_env, t0);
|
||||
tcg_temp_free(t0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user