Commit 6e35d5243c893200e958ef1b6f25519b62cd7d76
1 parent
7889270a
target-ppc: fix mtfsb0 and mtfsb1
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6032 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
26 additions
and
4 deletions
target-ppc/helper.h
| @@ -58,6 +58,7 @@ DEF_HELPER_0(reset_fpstatus, void) | @@ -58,6 +58,7 @@ DEF_HELPER_0(reset_fpstatus, void) | ||
| 58 | #endif | 58 | #endif |
| 59 | DEF_HELPER_2(compute_fprf, i32, i64, i32) | 59 | DEF_HELPER_2(compute_fprf, i32, i64, i32) |
| 60 | DEF_HELPER_2(store_fpscr, void, i64, i32) | 60 | DEF_HELPER_2(store_fpscr, void, i64, i32) |
| 61 | +DEF_HELPER_1(fpscr_clrbit, void, i32) | ||
| 61 | DEF_HELPER_1(fpscr_setbit, void, i32) | 62 | DEF_HELPER_1(fpscr_setbit, void, i32) |
| 62 | DEF_HELPER_1(float64_to_float32, i32, i64) | 63 | DEF_HELPER_1(float64_to_float32, i32, i64) |
| 63 | DEF_HELPER_1(float32_to_float64, i64, i32) | 64 | DEF_HELPER_1(float32_to_float64, i64, i32) |
target-ppc/op_helper.c
| @@ -843,6 +843,24 @@ static always_inline void fpscr_set_rounding_mode (void) | @@ -843,6 +843,24 @@ static always_inline void fpscr_set_rounding_mode (void) | ||
| 843 | set_float_rounding_mode(rnd_type, &env->fp_status); | 843 | set_float_rounding_mode(rnd_type, &env->fp_status); |
| 844 | } | 844 | } |
| 845 | 845 | ||
| 846 | +void helper_fpscr_clrbit (uint32_t bit) | ||
| 847 | +{ | ||
| 848 | + int prev; | ||
| 849 | + | ||
| 850 | + prev = (env->fpscr >> bit) & 1; | ||
| 851 | + env->fpscr &= ~(1 << bit); | ||
| 852 | + if (prev == 1) { | ||
| 853 | + switch (bit) { | ||
| 854 | + case FPSCR_RN1: | ||
| 855 | + case FPSCR_RN: | ||
| 856 | + fpscr_set_rounding_mode(); | ||
| 857 | + break; | ||
| 858 | + default: | ||
| 859 | + break; | ||
| 860 | + } | ||
| 861 | + } | ||
| 862 | +} | ||
| 863 | + | ||
| 846 | void helper_fpscr_setbit (uint32_t bit) | 864 | void helper_fpscr_setbit (uint32_t bit) |
| 847 | { | 865 | { |
| 848 | int prev; | 866 | int prev; |
target-ppc/translate.c
| @@ -2355,11 +2355,14 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) | @@ -2355,11 +2355,14 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) | ||
| 2355 | gen_exception(ctx, POWERPC_EXCP_FPU); | 2355 | gen_exception(ctx, POWERPC_EXCP_FPU); |
| 2356 | return; | 2356 | return; |
| 2357 | } | 2357 | } |
| 2358 | - crb = 32 - (crbD(ctx->opcode) >> 2); | 2358 | + crb = 31 - crbD(ctx->opcode); |
| 2359 | gen_optimize_fprf(); | 2359 | gen_optimize_fprf(); |
| 2360 | gen_reset_fpstatus(); | 2360 | gen_reset_fpstatus(); |
| 2361 | - if (likely(crb != 30 && crb != 29)) | ||
| 2362 | - tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(1 << crb)); | 2361 | + if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) { |
| 2362 | + TCGv_i32 t0 = tcg_const_i32(crb); | ||
| 2363 | + gen_helper_fpscr_clrbit(t0); | ||
| 2364 | + tcg_temp_free_i32(t0); | ||
| 2365 | + } | ||
| 2363 | if (unlikely(Rc(ctx->opcode) != 0)) { | 2366 | if (unlikely(Rc(ctx->opcode) != 0)) { |
| 2364 | tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); | 2367 | tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); |
| 2365 | } | 2368 | } |
| @@ -2374,7 +2377,7 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) | @@ -2374,7 +2377,7 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) | ||
| 2374 | gen_exception(ctx, POWERPC_EXCP_FPU); | 2377 | gen_exception(ctx, POWERPC_EXCP_FPU); |
| 2375 | return; | 2378 | return; |
| 2376 | } | 2379 | } |
| 2377 | - crb = 32 - (crbD(ctx->opcode) >> 2); | 2380 | + crb = 31 - crbD(ctx->opcode); |
| 2378 | gen_optimize_fprf(); | 2381 | gen_optimize_fprf(); |
| 2379 | gen_reset_fpstatus(); | 2382 | gen_reset_fpstatus(); |
| 2380 | /* XXX: we pretend we can only do IEEE floating-point computations */ | 2383 | /* XXX: we pretend we can only do IEEE floating-point computations */ |