Commit 8487327a1dabd9ce8899d0e1af151b334980c575
1 parent
5b9693dc
Make sure hflags are updated for CP0_Status changes.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2918 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
42 additions
and
8 deletions
target-mips/translate.c
| ... | ... | @@ -2627,25 +2627,32 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) |
| 2627 | 2627 | switch (sel) { |
| 2628 | 2628 | case 0: |
| 2629 | 2629 | gen_op_mtc0_status(); |
| 2630 | + /* BS_STOP isn't good enough here, hflags may have changed. */ | |
| 2631 | + gen_save_pc(ctx->pc + 4); | |
| 2632 | + ctx->bstate = BS_EXCP; | |
| 2630 | 2633 | rn = "Status"; |
| 2631 | 2634 | break; |
| 2632 | 2635 | case 1: |
| 2633 | 2636 | gen_op_mtc0_intctl(); |
| 2637 | + /* Stop translation as we may have switched the execution mode */ | |
| 2638 | + ctx->bstate = BS_STOP; | |
| 2634 | 2639 | rn = "IntCtl"; |
| 2635 | 2640 | break; |
| 2636 | 2641 | case 2: |
| 2637 | 2642 | gen_op_mtc0_srsctl(); |
| 2643 | + /* Stop translation as we may have switched the execution mode */ | |
| 2644 | + ctx->bstate = BS_STOP; | |
| 2638 | 2645 | rn = "SRSCtl"; |
| 2639 | 2646 | break; |
| 2640 | 2647 | case 3: |
| 2641 | 2648 | gen_op_mtc0_srsmap(); |
| 2649 | + /* Stop translation as we may have switched the execution mode */ | |
| 2650 | + ctx->bstate = BS_STOP; | |
| 2642 | 2651 | rn = "SRSMap"; |
| 2643 | 2652 | break; |
| 2644 | 2653 | default: |
| 2645 | 2654 | goto die; |
| 2646 | 2655 | } |
| 2647 | - /* Stop translation as we may have switched the execution mode */ | |
| 2648 | - ctx->bstate = BS_STOP; | |
| 2649 | 2656 | break; |
| 2650 | 2657 | case 13: |
| 2651 | 2658 | switch (sel) { |
| ... | ... | @@ -2781,29 +2788,40 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) |
| 2781 | 2788 | switch (sel) { |
| 2782 | 2789 | case 0: |
| 2783 | 2790 | gen_op_mtc0_debug(); /* EJTAG support */ |
| 2791 | + /* BS_STOP isn't good enough here, hflags may have changed. */ | |
| 2792 | + gen_save_pc(ctx->pc + 4); | |
| 2793 | + ctx->bstate = BS_EXCP; | |
| 2784 | 2794 | rn = "Debug"; |
| 2785 | 2795 | break; |
| 2786 | 2796 | case 1: |
| 2787 | 2797 | // gen_op_mtc0_tracecontrol(); /* PDtrace support */ |
| 2788 | 2798 | rn = "TraceControl"; |
| 2799 | + /* Stop translation as we may have switched the execution mode */ | |
| 2800 | + ctx->bstate = BS_STOP; | |
| 2789 | 2801 | // break; |
| 2790 | 2802 | case 2: |
| 2791 | 2803 | // gen_op_mtc0_tracecontrol2(); /* PDtrace support */ |
| 2792 | 2804 | rn = "TraceControl2"; |
| 2805 | + /* Stop translation as we may have switched the execution mode */ | |
| 2806 | + ctx->bstate = BS_STOP; | |
| 2793 | 2807 | // break; |
| 2794 | 2808 | case 3: |
| 2809 | + /* Stop translation as we may have switched the execution mode */ | |
| 2810 | + ctx->bstate = BS_STOP; | |
| 2795 | 2811 | // gen_op_mtc0_usertracedata(); /* PDtrace support */ |
| 2796 | 2812 | rn = "UserTraceData"; |
| 2813 | + /* Stop translation as we may have switched the execution mode */ | |
| 2814 | + ctx->bstate = BS_STOP; | |
| 2797 | 2815 | // break; |
| 2798 | 2816 | case 4: |
| 2799 | 2817 | // gen_op_mtc0_debug(); /* PDtrace support */ |
| 2818 | + /* Stop translation as we may have switched the execution mode */ | |
| 2819 | + ctx->bstate = BS_STOP; | |
| 2800 | 2820 | rn = "TraceBPC"; |
| 2801 | 2821 | // break; |
| 2802 | 2822 | default: |
| 2803 | 2823 | goto die; |
| 2804 | 2824 | } |
| 2805 | - /* Stop translation as we may have switched the execution mode */ | |
| 2806 | - ctx->bstate = BS_STOP; | |
| 2807 | 2825 | break; |
| 2808 | 2826 | case 24: |
| 2809 | 2827 | switch (sel) { |
| ... | ... | @@ -3704,25 +3722,32 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) |
| 3704 | 3722 | switch (sel) { |
| 3705 | 3723 | case 0: |
| 3706 | 3724 | gen_op_mtc0_status(); |
| 3725 | + /* BS_STOP isn't good enough here, hflags may have changed. */ | |
| 3726 | + gen_save_pc(ctx->pc + 4); | |
| 3727 | + ctx->bstate = BS_EXCP; | |
| 3707 | 3728 | rn = "Status"; |
| 3708 | 3729 | break; |
| 3709 | 3730 | case 1: |
| 3710 | 3731 | gen_op_mtc0_intctl(); |
| 3732 | + /* Stop translation as we may have switched the execution mode */ | |
| 3733 | + ctx->bstate = BS_STOP; | |
| 3711 | 3734 | rn = "IntCtl"; |
| 3712 | 3735 | break; |
| 3713 | 3736 | case 2: |
| 3714 | 3737 | gen_op_mtc0_srsctl(); |
| 3738 | + /* Stop translation as we may have switched the execution mode */ | |
| 3739 | + ctx->bstate = BS_STOP; | |
| 3715 | 3740 | rn = "SRSCtl"; |
| 3716 | 3741 | break; |
| 3717 | 3742 | case 3: |
| 3718 | 3743 | gen_op_mtc0_srsmap(); |
| 3744 | + /* Stop translation as we may have switched the execution mode */ | |
| 3745 | + ctx->bstate = BS_STOP; | |
| 3719 | 3746 | rn = "SRSMap"; |
| 3720 | 3747 | break; |
| 3721 | 3748 | default: |
| 3722 | 3749 | goto die; |
| 3723 | 3750 | } |
| 3724 | - /* Stop translation as we may have switched the execution mode */ | |
| 3725 | - ctx->bstate = BS_STOP; | |
| 3726 | 3751 | break; |
| 3727 | 3752 | case 13: |
| 3728 | 3753 | switch (sel) { |
| ... | ... | @@ -3849,29 +3874,38 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) |
| 3849 | 3874 | switch (sel) { |
| 3850 | 3875 | case 0: |
| 3851 | 3876 | gen_op_mtc0_debug(); /* EJTAG support */ |
| 3877 | + /* BS_STOP isn't good enough here, hflags may have changed. */ | |
| 3878 | + gen_save_pc(ctx->pc + 4); | |
| 3879 | + ctx->bstate = BS_EXCP; | |
| 3852 | 3880 | rn = "Debug"; |
| 3853 | 3881 | break; |
| 3854 | 3882 | case 1: |
| 3855 | 3883 | // gen_op_mtc0_tracecontrol(); /* PDtrace support */ |
| 3884 | + /* Stop translation as we may have switched the execution mode */ | |
| 3885 | + ctx->bstate = BS_STOP; | |
| 3856 | 3886 | rn = "TraceControl"; |
| 3857 | 3887 | // break; |
| 3858 | 3888 | case 2: |
| 3859 | 3889 | // gen_op_mtc0_tracecontrol2(); /* PDtrace support */ |
| 3890 | + /* Stop translation as we may have switched the execution mode */ | |
| 3891 | + ctx->bstate = BS_STOP; | |
| 3860 | 3892 | rn = "TraceControl2"; |
| 3861 | 3893 | // break; |
| 3862 | 3894 | case 3: |
| 3863 | 3895 | // gen_op_mtc0_usertracedata(); /* PDtrace support */ |
| 3896 | + /* Stop translation as we may have switched the execution mode */ | |
| 3897 | + ctx->bstate = BS_STOP; | |
| 3864 | 3898 | rn = "UserTraceData"; |
| 3865 | 3899 | // break; |
| 3866 | 3900 | case 4: |
| 3867 | 3901 | // gen_op_mtc0_debug(); /* PDtrace support */ |
| 3902 | + /* Stop translation as we may have switched the execution mode */ | |
| 3903 | + ctx->bstate = BS_STOP; | |
| 3868 | 3904 | rn = "TraceBPC"; |
| 3869 | 3905 | // break; |
| 3870 | 3906 | default: |
| 3871 | 3907 | goto die; |
| 3872 | 3908 | } |
| 3873 | - /* Stop translation as we may have switched the execution mode */ | |
| 3874 | - ctx->bstate = BS_STOP; | |
| 3875 | 3909 | break; |
| 3876 | 3910 | case 24: |
| 3877 | 3911 | switch (sel) { | ... | ... |