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 | 390 | return; |
| 391 | 391 | case 0x2004: /* mov.b Rm,@-Rn */ |
| 392 | 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 | 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 | 398 | return; |
| 397 | 399 | case 0x2005: /* mov.w Rm,@-Rn */ |
| 398 | 400 | gen_op_movl_rN_T0(REG(B7_4)); |
| 399 | 401 | gen_op_dec2_rN(REG(B11_8)); |
| 400 | 402 | gen_op_movl_rN_T1(REG(B11_8)); |
| 403 | + gen_op_inc2_rN(REG(B11_8)); | |
| 401 | 404 | gen_op_stw_T0_T1(ctx); |
| 405 | + gen_op_dec2_rN(REG(B11_8)); | |
| 402 | 406 | return; |
| 403 | 407 | case 0x2006: /* mov.l Rm,@-Rn */ |
| 404 | 408 | gen_op_movl_rN_T0(REG(B7_4)); |
| 405 | 409 | gen_op_dec4_rN(REG(B11_8)); |
| 406 | 410 | gen_op_movl_rN_T1(REG(B11_8)); |
| 411 | + gen_op_inc4_rN(REG(B11_8)); | |
| 407 | 412 | gen_op_stl_T0_T1(ctx); |
| 413 | + gen_op_dec4_rN(REG(B11_8)); | |
| 408 | 414 | return; |
| 409 | 415 | case 0x6004: /* mov.b @Rm+,Rn */ |
| 410 | 416 | gen_op_movl_rN_T0(REG(B7_4)); |
| ... | ... | @@ -570,20 +576,20 @@ void _decode_opc(DisasContext * ctx) |
| 570 | 576 | gen_op_movl_rN_T0(REG(B11_8)); |
| 571 | 577 | gen_op_ldl_T0_T0(ctx); |
| 572 | 578 | gen_op_movl_T0_T1(); |
| 573 | - gen_op_inc4_rN(REG(B11_8)); | |
| 574 | 579 | gen_op_movl_rN_T0(REG(B7_4)); |
| 575 | 580 | gen_op_ldl_T0_T0(ctx); |
| 576 | 581 | gen_op_macl_T0_T1(); |
| 582 | + gen_op_inc4_rN(REG(B11_8)); | |
| 577 | 583 | gen_op_inc4_rN(REG(B7_4)); |
| 578 | 584 | return; |
| 579 | 585 | case 0x400f: /* mac.w @Rm+,@Rn+ */ |
| 580 | 586 | gen_op_movl_rN_T0(REG(B11_8)); |
| 581 | 587 | gen_op_ldl_T0_T0(ctx); |
| 582 | 588 | gen_op_movl_T0_T1(); |
| 583 | - gen_op_inc2_rN(REG(B11_8)); | |
| 584 | 589 | gen_op_movl_rN_T0(REG(B7_4)); |
| 585 | 590 | gen_op_ldl_T0_T0(ctx); |
| 586 | 591 | gen_op_macw_T0_T1(); |
| 592 | + gen_op_inc2_rN(REG(B11_8)); | |
| 587 | 593 | gen_op_inc2_rN(REG(B7_4)); |
| 588 | 594 | return; |
| 589 | 595 | case 0x0007: /* mul.l Rm,Rn */ |
| ... | ... | @@ -706,12 +712,16 @@ void _decode_opc(DisasContext * ctx) |
| 706 | 712 | gen_op_dec8_rN(REG(B11_8)); |
| 707 | 713 | gen_op_fmov_drN_DT0(XREG(B7_4)); |
| 708 | 714 | gen_op_movl_rN_T1(REG(B11_8)); |
| 715 | + gen_op_inc8_rN(REG(B11_8)); | |
| 709 | 716 | gen_op_stfq_DT0_T1(ctx); |
| 717 | + gen_op_dec8_rN(REG(B11_8)); | |
| 710 | 718 | } else { |
| 711 | 719 | gen_op_dec4_rN(REG(B11_8)); |
| 712 | 720 | gen_op_fmov_frN_FT0(FREG(B7_4)); |
| 713 | 721 | gen_op_movl_rN_T1(REG(B11_8)); |
| 722 | + gen_op_inc4_rN(REG(B11_8)); | |
| 714 | 723 | gen_op_stfl_FT0_T1(ctx); |
| 724 | + gen_op_dec4_rN(REG(B11_8)); | |
| 715 | 725 | } |
| 716 | 726 | return; |
| 717 | 727 | case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */ |
| ... | ... | @@ -947,7 +957,9 @@ void _decode_opc(DisasContext * ctx) |
| 947 | 957 | gen_op_dec4_rN(REG(B11_8)); |
| 948 | 958 | gen_op_movl_rN_T1(REG(B11_8)); |
| 949 | 959 | gen_op_movl_rN_T0(ALTREG(B6_4)); |
| 960 | + gen_op_inc4_rN(REG(B11_8)); | |
| 950 | 961 | gen_op_stl_T0_T1(ctx); |
| 962 | + gen_op_dec4_rN(REG(B11_8)); | |
| 951 | 963 | return; |
| 952 | 964 | } |
| 953 | 965 | |
| ... | ... | @@ -1008,7 +1020,9 @@ void _decode_opc(DisasContext * ctx) |
| 1008 | 1020 | gen_op_##stop##_##reg##_T0 (); \ |
| 1009 | 1021 | gen_op_dec4_rN (REG(B11_8)); \ |
| 1010 | 1022 | gen_op_movl_rN_T1 (REG(B11_8)); \ |
| 1023 | + gen_op_inc4_rN (REG(B11_8)); \ | |
| 1011 | 1024 | gen_op_stl_T0_T1 (ctx); \ |
| 1025 | + gen_op_dec4_rN (REG(B11_8)); \ | |
| 1012 | 1026 | return; |
| 1013 | 1027 | LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate = |
| 1014 | 1028 | BS_STOP;) | ... | ... |