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