提交 ad8d25a1 编写于 作者: A Aurelien Jarno

target-sh4: implement addv and subv using TCG

addv and subv helpers implementation is directly copied from the SH4
manual and looks quite complex. It is however possible to explain it
without branches, and is therefore possible to implement it with TCG.
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>
上级 22b88fd7
......@@ -13,8 +13,6 @@ DEF_HELPER_3(movcal, void, env, i32, i32)
DEF_HELPER_1(discard_movcal_backup, void, env)
DEF_HELPER_2(ocbi, void, env, i32)
DEF_HELPER_3(addv, i32, env, i32, i32)
DEF_HELPER_3(subv, i32, env, i32, i32)
DEF_HELPER_3(div1, i32, env, i32, i32)
DEF_HELPER_3(macl, void, env, i32, i32)
DEF_HELPER_3(macw, void, env, i32, i32)
......
......@@ -177,35 +177,6 @@ void helper_ocbi(CPUSH4State *env, uint32_t address)
}
}
uint32_t helper_addv(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
{
uint32_t dest, src, ans;
if ((int32_t) arg1 >= 0)
dest = 0;
else
dest = 1;
if ((int32_t) arg0 >= 0)
src = 0;
else
src = 1;
src += dest;
arg1 += arg0;
if ((int32_t) arg1 >= 0)
ans = 0;
else
ans = 1;
ans += dest;
if (src == 0 || src == 2) {
if (ans == 1)
env->sr |= SR_T;
else
env->sr &= ~SR_T;
} else
env->sr &= ~SR_T;
return arg1;
}
#define T (env->sr & SR_T)
#define Q (env->sr & SR_Q ? 1 : 0)
#define M (env->sr & SR_M ? 1 : 0)
......@@ -359,35 +330,6 @@ void helper_macw(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
}
}
uint32_t helper_subv(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
{
int32_t dest, src, ans;
if ((int32_t) arg1 >= 0)
dest = 0;
else
dest = 1;
if ((int32_t) arg0 >= 0)
src = 0;
else
src = 1;
src += dest;
arg1 -= arg0;
if ((int32_t) arg1 >= 0)
ans = 0;
else
ans = 1;
ans += dest;
if (src == 1) {
if (ans == 1)
env->sr |= SR_T;
else
env->sr &= ~SR_T;
} else
env->sr &= ~SR_T;
return arg1;
}
static inline void set_t(CPUSH4State *env)
{
env->sr |= SR_T;
......
......@@ -781,7 +781,23 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0x300f: /* addv Rm,Rn */
gen_helper_addv(REG(B11_8), cpu_env, REG(B7_4), REG(B11_8));
{
TCGv t0, t1, t2;
t0 = tcg_temp_new();
tcg_gen_add_i32(t0, REG(B7_4), REG(B11_8));
t1 = tcg_temp_new();
tcg_gen_xor_i32(t1, t0, REG(B11_8));
t2 = tcg_temp_new();
tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
tcg_gen_andc_i32(t1, t1, t2);
tcg_temp_free(t2);
tcg_gen_shri_i32(t1, t1, 31);
tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
tcg_gen_or_i32(cpu_sr, cpu_sr, t1);
tcg_temp_free(t1);
tcg_gen_mov_i32(REG(B7_4), t0);
tcg_temp_free(t0);
}
return;
case 0x2009: /* and Rm,Rn */
tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
......@@ -1050,7 +1066,23 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0x300b: /* subv Rm,Rn */
gen_helper_subv(REG(B11_8), cpu_env, REG(B7_4), REG(B11_8));
{
TCGv t0, t1, t2;
t0 = tcg_temp_new();
tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
t1 = tcg_temp_new();
tcg_gen_xor_i32(t1, t0, REG(B7_4));
t2 = tcg_temp_new();
tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
tcg_gen_and_i32(t1, t1, t2);
tcg_temp_free(t2);
tcg_gen_shri_i32(t1, t1, 31);
tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
tcg_gen_or_i32(cpu_sr, cpu_sr, t1);
tcg_temp_free(t1);
tcg_gen_mov_i32(REG(B11_8), t0);
tcg_temp_free(t0);
}
return;
case 0x2008: /* tst Rm,Rn */
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册