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 */ |