diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-03-11 23:22:37 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-03-11 23:22:37 +0000 |
commit | 24988dc24169b581fe6563d7ed619bd50a2af40b (patch) | |
tree | b9ee1602c534c243c6ed74bd3183b489c0642e15 /target-sh4/op.c | |
parent | 0954d0d9e242b4bc122eeaefb8825cc8f8eb3ab5 (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.c | 90 |
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(); } |