Commit 6e35d5243c893200e958ef1b6f25519b62cd7d76

Authored by aurel32
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
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 */