[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 04/11] target-sh4: implement addv and subv using TCG
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH 04/11] target-sh4: implement addv and subv using TCG |
Date: |
Mon, 17 Sep 2012 01:11:53 +0200 |
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: Aurelien Jarno <address@hidden>
---
target-sh4/helper.h | 2 --
target-sh4/op_helper.c | 58 ------------------------------------------------
target-sh4/translate.c | 36 ++++++++++++++++++++++++++++--
3 files changed, 34 insertions(+), 62 deletions(-)
diff --git a/target-sh4/helper.h b/target-sh4/helper.h
index 92d6dd7..a00b7dd 100644
--- a/target-sh4/helper.h
+++ b/target-sh4/helper.h
@@ -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)
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 3ad10ba..4f1f754 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -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;
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 92f9b46..41a1f22 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -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 */
{
--
1.7.10.4
- [Qemu-devel] [PATCH 00/11] target-sh4: misc optimizations and cleanup, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 02/11] target-sh4: use float32_muladd() to implement fmac, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 01/11] target-sh4: mark a few helpers const and pure, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 06/11] target-sh4: optimize swap.w, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 03/11] target-sh4: implement addc and subc using TCG, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 05/11] target-sh4: optimize xtrct, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 04/11] target-sh4: implement addv and subv using TCG,
Aurelien Jarno <=
- [Qemu-devel] [PATCH 10/11] target-sh4: remove useless code, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 08/11] target-sh4: rework exceptions handling, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 09/11] target-sh4: cleanup DisasContext, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 11/11] gdbstub/sh4: fix build with USE_SOFTFLOAT_STRUCT_TYPES, Aurelien Jarno, 2012/09/16
- [Qemu-devel] [PATCH 07/11] target-sh4: remove gen_clr_t() and gen_set_t(), Aurelien Jarno, 2012/09/16