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