Commit 7da76bcef228adc68194eeeff07b00fc434a438c
1 parent
06afe2c8
[sh4] code translation bug fix
When a TLB miss occurs while pre-decrement store instruction such as "mov.l Rm, @-Rn" is executed, re-execution of such instruction cause status confusion. Because pre Rn decrement is executed before TLB miss, re-execution decrements Rn again. In other words, in a translated instruction array, register status should not modified before memory access instruction. (Shin-ichiro KAWASAKI) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5069 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
18 additions
and
4 deletions
target-sh4/translate.c
| @@ -390,21 +390,27 @@ void _decode_opc(DisasContext * ctx) | @@ -390,21 +390,27 @@ void _decode_opc(DisasContext * ctx) | ||
| 390 | return; | 390 | return; |
| 391 | case 0x2004: /* mov.b Rm,@-Rn */ | 391 | case 0x2004: /* mov.b Rm,@-Rn */ |
| 392 | gen_op_movl_rN_T0(REG(B7_4)); | 392 | gen_op_movl_rN_T0(REG(B7_4)); |
| 393 | - gen_op_dec1_rN(REG(B11_8)); | 393 | + gen_op_dec1_rN(REG(B11_8)); /* modify register status */ |
| 394 | gen_op_movl_rN_T1(REG(B11_8)); | 394 | gen_op_movl_rN_T1(REG(B11_8)); |
| 395 | - gen_op_stb_T0_T1(ctx); | 395 | + gen_op_inc1_rN(REG(B11_8)); /* recover register status */ |
| 396 | + gen_op_stb_T0_T1(ctx); /* might cause re-execution */ | ||
| 397 | + gen_op_dec1_rN(REG(B11_8)); /* modify register status */ | ||
| 396 | return; | 398 | return; |
| 397 | case 0x2005: /* mov.w Rm,@-Rn */ | 399 | case 0x2005: /* mov.w Rm,@-Rn */ |
| 398 | gen_op_movl_rN_T0(REG(B7_4)); | 400 | gen_op_movl_rN_T0(REG(B7_4)); |
| 399 | gen_op_dec2_rN(REG(B11_8)); | 401 | gen_op_dec2_rN(REG(B11_8)); |
| 400 | gen_op_movl_rN_T1(REG(B11_8)); | 402 | gen_op_movl_rN_T1(REG(B11_8)); |
| 403 | + gen_op_inc2_rN(REG(B11_8)); | ||
| 401 | gen_op_stw_T0_T1(ctx); | 404 | gen_op_stw_T0_T1(ctx); |
| 405 | + gen_op_dec2_rN(REG(B11_8)); | ||
| 402 | return; | 406 | return; |
| 403 | case 0x2006: /* mov.l Rm,@-Rn */ | 407 | case 0x2006: /* mov.l Rm,@-Rn */ |
| 404 | gen_op_movl_rN_T0(REG(B7_4)); | 408 | gen_op_movl_rN_T0(REG(B7_4)); |
| 405 | gen_op_dec4_rN(REG(B11_8)); | 409 | gen_op_dec4_rN(REG(B11_8)); |
| 406 | gen_op_movl_rN_T1(REG(B11_8)); | 410 | gen_op_movl_rN_T1(REG(B11_8)); |
| 411 | + gen_op_inc4_rN(REG(B11_8)); | ||
| 407 | gen_op_stl_T0_T1(ctx); | 412 | gen_op_stl_T0_T1(ctx); |
| 413 | + gen_op_dec4_rN(REG(B11_8)); | ||
| 408 | return; | 414 | return; |
| 409 | case 0x6004: /* mov.b @Rm+,Rn */ | 415 | case 0x6004: /* mov.b @Rm+,Rn */ |
| 410 | gen_op_movl_rN_T0(REG(B7_4)); | 416 | gen_op_movl_rN_T0(REG(B7_4)); |
| @@ -570,20 +576,20 @@ void _decode_opc(DisasContext * ctx) | @@ -570,20 +576,20 @@ void _decode_opc(DisasContext * ctx) | ||
| 570 | gen_op_movl_rN_T0(REG(B11_8)); | 576 | gen_op_movl_rN_T0(REG(B11_8)); |
| 571 | gen_op_ldl_T0_T0(ctx); | 577 | gen_op_ldl_T0_T0(ctx); |
| 572 | gen_op_movl_T0_T1(); | 578 | gen_op_movl_T0_T1(); |
| 573 | - gen_op_inc4_rN(REG(B11_8)); | ||
| 574 | gen_op_movl_rN_T0(REG(B7_4)); | 579 | gen_op_movl_rN_T0(REG(B7_4)); |
| 575 | gen_op_ldl_T0_T0(ctx); | 580 | gen_op_ldl_T0_T0(ctx); |
| 576 | gen_op_macl_T0_T1(); | 581 | gen_op_macl_T0_T1(); |
| 582 | + gen_op_inc4_rN(REG(B11_8)); | ||
| 577 | gen_op_inc4_rN(REG(B7_4)); | 583 | gen_op_inc4_rN(REG(B7_4)); |
| 578 | return; | 584 | return; |
| 579 | case 0x400f: /* mac.w @Rm+,@Rn+ */ | 585 | case 0x400f: /* mac.w @Rm+,@Rn+ */ |
| 580 | gen_op_movl_rN_T0(REG(B11_8)); | 586 | gen_op_movl_rN_T0(REG(B11_8)); |
| 581 | gen_op_ldl_T0_T0(ctx); | 587 | gen_op_ldl_T0_T0(ctx); |
| 582 | gen_op_movl_T0_T1(); | 588 | gen_op_movl_T0_T1(); |
| 583 | - gen_op_inc2_rN(REG(B11_8)); | ||
| 584 | gen_op_movl_rN_T0(REG(B7_4)); | 589 | gen_op_movl_rN_T0(REG(B7_4)); |
| 585 | gen_op_ldl_T0_T0(ctx); | 590 | gen_op_ldl_T0_T0(ctx); |
| 586 | gen_op_macw_T0_T1(); | 591 | gen_op_macw_T0_T1(); |
| 592 | + gen_op_inc2_rN(REG(B11_8)); | ||
| 587 | gen_op_inc2_rN(REG(B7_4)); | 593 | gen_op_inc2_rN(REG(B7_4)); |
| 588 | return; | 594 | return; |
| 589 | case 0x0007: /* mul.l Rm,Rn */ | 595 | case 0x0007: /* mul.l Rm,Rn */ |
| @@ -706,12 +712,16 @@ void _decode_opc(DisasContext * ctx) | @@ -706,12 +712,16 @@ void _decode_opc(DisasContext * ctx) | ||
| 706 | gen_op_dec8_rN(REG(B11_8)); | 712 | gen_op_dec8_rN(REG(B11_8)); |
| 707 | gen_op_fmov_drN_DT0(XREG(B7_4)); | 713 | gen_op_fmov_drN_DT0(XREG(B7_4)); |
| 708 | gen_op_movl_rN_T1(REG(B11_8)); | 714 | gen_op_movl_rN_T1(REG(B11_8)); |
| 715 | + gen_op_inc8_rN(REG(B11_8)); | ||
| 709 | gen_op_stfq_DT0_T1(ctx); | 716 | gen_op_stfq_DT0_T1(ctx); |
| 717 | + gen_op_dec8_rN(REG(B11_8)); | ||
| 710 | } else { | 718 | } else { |
| 711 | gen_op_dec4_rN(REG(B11_8)); | 719 | gen_op_dec4_rN(REG(B11_8)); |
| 712 | gen_op_fmov_frN_FT0(FREG(B7_4)); | 720 | gen_op_fmov_frN_FT0(FREG(B7_4)); |
| 713 | gen_op_movl_rN_T1(REG(B11_8)); | 721 | gen_op_movl_rN_T1(REG(B11_8)); |
| 722 | + gen_op_inc4_rN(REG(B11_8)); | ||
| 714 | gen_op_stfl_FT0_T1(ctx); | 723 | gen_op_stfl_FT0_T1(ctx); |
| 724 | + gen_op_dec4_rN(REG(B11_8)); | ||
| 715 | } | 725 | } |
| 716 | return; | 726 | return; |
| 717 | case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */ | 727 | case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */ |
| @@ -947,7 +957,9 @@ void _decode_opc(DisasContext * ctx) | @@ -947,7 +957,9 @@ void _decode_opc(DisasContext * ctx) | ||
| 947 | gen_op_dec4_rN(REG(B11_8)); | 957 | gen_op_dec4_rN(REG(B11_8)); |
| 948 | gen_op_movl_rN_T1(REG(B11_8)); | 958 | gen_op_movl_rN_T1(REG(B11_8)); |
| 949 | gen_op_movl_rN_T0(ALTREG(B6_4)); | 959 | gen_op_movl_rN_T0(ALTREG(B6_4)); |
| 960 | + gen_op_inc4_rN(REG(B11_8)); | ||
| 950 | gen_op_stl_T0_T1(ctx); | 961 | gen_op_stl_T0_T1(ctx); |
| 962 | + gen_op_dec4_rN(REG(B11_8)); | ||
| 951 | return; | 963 | return; |
| 952 | } | 964 | } |
| 953 | 965 | ||
| @@ -1008,7 +1020,9 @@ void _decode_opc(DisasContext * ctx) | @@ -1008,7 +1020,9 @@ void _decode_opc(DisasContext * ctx) | ||
| 1008 | gen_op_##stop##_##reg##_T0 (); \ | 1020 | gen_op_##stop##_##reg##_T0 (); \ |
| 1009 | gen_op_dec4_rN (REG(B11_8)); \ | 1021 | gen_op_dec4_rN (REG(B11_8)); \ |
| 1010 | gen_op_movl_rN_T1 (REG(B11_8)); \ | 1022 | gen_op_movl_rN_T1 (REG(B11_8)); \ |
| 1023 | + gen_op_inc4_rN (REG(B11_8)); \ | ||
| 1011 | gen_op_stl_T0_T1 (ctx); \ | 1024 | gen_op_stl_T0_T1 (ctx); \ |
| 1025 | + gen_op_dec4_rN (REG(B11_8)); \ | ||
| 1012 | return; | 1026 | return; |
| 1013 | LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate = | 1027 | LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate = |
| 1014 | BS_STOP;) | 1028 | BS_STOP;) |