aboutsummaryrefslogtreecommitdiff
path: root/target-sh4/op.c
diff options
context:
space:
mode:
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2008-03-11 23:22:37 +0000
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2008-03-11 23:22:37 +0000
commit24988dc24169b581fe6563d7ed619bd50a2af40b (patch)
treeb9ee1602c534c243c6ed74bd3183b489c0642e15 /target-sh4/op.c
parent0954d0d9e242b4bc122eeaefb8825cc8f8eb3ab5 (diff)
SH4, fix several instructions
fix instruction code for frchg, fschg, ocbp. fix addressing mode handling for @Rn+, @-Rn, @(disp,gbr). fix operation for div0s. fix comments for mov imm, add imm, @(r0+,gbr), mac.l @Rm+,@Rn+. fix ldb to ldub for or/tst/xor.b #imm,@(r0,gbr). add fmov extended operations. add fcmp/eq, fcmp/gt, fneg, fabs, fsqrt, fcnvsd, fcnvds. (Takashi Yoshii) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4040 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sh4/op.c')
-rw-r--r--target-sh4/op.c90
1 files changed, 78 insertions, 12 deletions
diff --git a/target-sh4/op.c b/target-sh4/op.c
index 955610a90a..615d30ad51 100644
--- a/target-sh4/op.c
+++ b/target-sh4/op.c
@@ -45,13 +45,7 @@ void OPPROTO op_movl_imm_T0(void)
void OPPROTO op_movl_imm_T1(void)
{
- T0 = (uint32_t) PARAM1;
- RETURN();
-}
-
-void OPPROTO op_movl_imm_T2(void)
-{
- T0 = (uint32_t) PARAM1;
+ T1 = (uint32_t) PARAM1;
RETURN();
}
@@ -240,6 +234,12 @@ void OPPROTO op_xtrct_T0_T1(void)
RETURN();
}
+void OPPROTO op_add_T0_T1(void)
+{
+ T1 += T0;
+ RETURN();
+}
+
void OPPROTO op_addc_T0_T1(void)
{
helper_addc_T0_T1();
@@ -355,13 +355,13 @@ void OPPROTO op_mull_T0_T1(void)
void OPPROTO op_mulsw_T0_T1(void)
{
- env->macl = (int32_t) T0 *(int32_t) T1;
+ env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1;
RETURN();
}
void OPPROTO op_muluw_T0_T1(void)
{
- env->macl = (uint32_t) T0 *(uint32_t) T1;
+ env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1;
RETURN();
}
@@ -382,7 +382,7 @@ void OPPROTO op_shad_T0_T1(void)
if ((T0 & 0x80000000) == 0)
T1 <<= (T0 & 0x1f);
else if ((T0 & 0x1f) == 0)
- T1 = 0;
+ T1 = (T1 & 0x80000000)? 0xffffffff : 0;
else
T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
RETURN();
@@ -539,7 +539,7 @@ void OPPROTO op_shal_Rn(void)
void OPPROTO op_shar_Rn(void)
{
cond_t(env->gregs[PARAM1] & 1);
- env->gregs[PARAM1] >>= 1;
+ *(int32_t *)&env->gregs[PARAM1] >>= 1;
RETURN();
}
@@ -767,6 +767,30 @@ void OPPROTO op_fdiv_DT(void)
RETURN();
}
+void OPPROTO op_fcmp_eq_FT(void)
+{
+ cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
+ RETURN();
+}
+
+void OPPROTO op_fcmp_eq_DT(void)
+{
+ cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
+ RETURN();
+}
+
+void OPPROTO op_fcmp_gt_FT(void)
+{
+ cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
+ RETURN();
+}
+
+void OPPROTO op_fcmp_gt_DT(void)
+{
+ cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
+ RETURN();
+}
+
void OPPROTO op_float_FT(void)
{
FT0 = int32_to_float32(env->fpul, &env->fp_status);
@@ -791,9 +815,51 @@ void OPPROTO op_ftrc_DT(void)
RETURN();
}
+void OPPROTO op_fneg_frN(void)
+{
+ env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
+ RETURN();
+}
+
+void OPPROTO op_fabs_FT(void)
+{
+ FT0 = float32_abs(FT0);
+ RETURN();
+}
+
+void OPPROTO op_fabs_DT(void)
+{
+ DT0 = float64_abs(DT0);
+ RETURN();
+}
+
+void OPPROTO op_fcnvsd_FT_DT(void)
+{
+ DT0 = float32_to_float64(FT0, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fcnvds_DT_FT(void)
+{
+ FT0 = float64_to_float32(DT0, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fsqrt_FT(void)
+{
+ FT0 = float32_sqrt(FT0, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fsqrt_DT(void)
+{
+ DT0 = float64_sqrt(DT0, &env->fp_status);
+ RETURN();
+}
+
void OPPROTO op_fmov_T0_frN(void)
{
- *(unsigned int *)&env->fregs[PARAM1] = T0;
+ *(uint32_t *)&env->fregs[PARAM1] = T0;
RETURN();
}