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;) | ... | ... |