Commit b5dc7732e1cc2fb549e48b7b5d664f2c79628e2e
1 parent
a37ee56c
More efficient target register / TC accesses.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4794 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
16 changed files
with
327 additions
and
246 deletions
cpu-exec.c
| ... | ... | @@ -197,7 +197,7 @@ static inline TranslationBlock *tb_find_fast(void) |
| 197 | 197 | #elif defined(TARGET_MIPS) |
| 198 | 198 | flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK); |
| 199 | 199 | cs_base = 0; |
| 200 | - pc = env->PC[env->current_tc]; | |
| 200 | + pc = env->active_tc.PC; | |
| 201 | 201 | #elif defined(TARGET_M68K) |
| 202 | 202 | flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */ |
| 203 | 203 | | (env->sr & SR_S) /* Bit 13 */ | ... | ... |
gdbstub.c
| ... | ... | @@ -704,17 +704,17 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) |
| 704 | 704 | ptr = mem_buf; |
| 705 | 705 | for (i = 0; i < 32; i++) |
| 706 | 706 | { |
| 707 | - *(target_ulong *)ptr = tswapl(env->gpr[env->current_tc][i]); | |
| 707 | + *(target_ulong *)ptr = tswapl(env->active_tc.gpr[i]); | |
| 708 | 708 | ptr += sizeof(target_ulong); |
| 709 | 709 | } |
| 710 | 710 | |
| 711 | 711 | *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_Status); |
| 712 | 712 | ptr += sizeof(target_ulong); |
| 713 | 713 | |
| 714 | - *(target_ulong *)ptr = tswapl(env->LO[env->current_tc][0]); | |
| 714 | + *(target_ulong *)ptr = tswapl(env->active_tc.LO[0]); | |
| 715 | 715 | ptr += sizeof(target_ulong); |
| 716 | 716 | |
| 717 | - *(target_ulong *)ptr = tswapl(env->HI[env->current_tc][0]); | |
| 717 | + *(target_ulong *)ptr = tswapl(env->active_tc.HI[0]); | |
| 718 | 718 | ptr += sizeof(target_ulong); |
| 719 | 719 | |
| 720 | 720 | *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr); |
| ... | ... | @@ -723,7 +723,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) |
| 723 | 723 | *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_Cause); |
| 724 | 724 | ptr += sizeof(target_ulong); |
| 725 | 725 | |
| 726 | - *(target_ulong *)ptr = tswapl(env->PC[env->current_tc]); | |
| 726 | + *(target_ulong *)ptr = tswapl(env->active_tc.PC); | |
| 727 | 727 | ptr += sizeof(target_ulong); |
| 728 | 728 | |
| 729 | 729 | if (env->CP0_Config1 & (1 << CP0C1_FP)) |
| ... | ... | @@ -781,17 +781,17 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) |
| 781 | 781 | ptr = mem_buf; |
| 782 | 782 | for (i = 0; i < 32; i++) |
| 783 | 783 | { |
| 784 | - env->gpr[env->current_tc][i] = tswapl(*(target_ulong *)ptr); | |
| 784 | + env->active_tc.gpr[i] = tswapl(*(target_ulong *)ptr); | |
| 785 | 785 | ptr += sizeof(target_ulong); |
| 786 | 786 | } |
| 787 | 787 | |
| 788 | 788 | env->CP0_Status = tswapl(*(target_ulong *)ptr); |
| 789 | 789 | ptr += sizeof(target_ulong); |
| 790 | 790 | |
| 791 | - env->LO[env->current_tc][0] = tswapl(*(target_ulong *)ptr); | |
| 791 | + env->active_tc.LO[0] = tswapl(*(target_ulong *)ptr); | |
| 792 | 792 | ptr += sizeof(target_ulong); |
| 793 | 793 | |
| 794 | - env->HI[env->current_tc][0] = tswapl(*(target_ulong *)ptr); | |
| 794 | + env->active_tc.HI[0] = tswapl(*(target_ulong *)ptr); | |
| 795 | 795 | ptr += sizeof(target_ulong); |
| 796 | 796 | |
| 797 | 797 | env->CP0_BadVAddr = tswapl(*(target_ulong *)ptr); |
| ... | ... | @@ -800,7 +800,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) |
| 800 | 800 | env->CP0_Cause = tswapl(*(target_ulong *)ptr); |
| 801 | 801 | ptr += sizeof(target_ulong); |
| 802 | 802 | |
| 803 | - env->PC[env->current_tc] = tswapl(*(target_ulong *)ptr); | |
| 803 | + env->active_tc.PC = tswapl(*(target_ulong *)ptr); | |
| 804 | 804 | ptr += sizeof(target_ulong); |
| 805 | 805 | |
| 806 | 806 | if (env->CP0_Config1 & (1 << CP0C1_FP)) |
| ... | ... | @@ -1003,7 +1003,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) |
| 1003 | 1003 | #elif defined (TARGET_SH4) |
| 1004 | 1004 | env->pc = addr; |
| 1005 | 1005 | #elif defined (TARGET_MIPS) |
| 1006 | - env->PC[env->current_tc] = addr; | |
| 1006 | + env->active_tc.PC = addr; | |
| 1007 | 1007 | #elif defined (TARGET_CRIS) |
| 1008 | 1008 | env->pc = addr; |
| 1009 | 1009 | #endif |
| ... | ... | @@ -1040,7 +1040,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) |
| 1040 | 1040 | #elif defined (TARGET_SH4) |
| 1041 | 1041 | env->pc = addr; |
| 1042 | 1042 | #elif defined (TARGET_MIPS) |
| 1043 | - env->PC[env->current_tc] = addr; | |
| 1043 | + env->active_tc.PC = addr; | |
| 1044 | 1044 | #elif defined (TARGET_CRIS) |
| 1045 | 1045 | env->pc = addr; |
| 1046 | 1046 | #endif | ... | ... |
hw/mips_mipssim.c
| ... | ... | @@ -65,7 +65,7 @@ static void load_kernel (CPUState *env) |
| 65 | 65 | if (kernel_size >= 0) { |
| 66 | 66 | if ((entry & ~0x7fffffffULL) == 0x80000000) |
| 67 | 67 | entry = (int32_t)entry; |
| 68 | - env->PC[env->current_tc] = entry; | |
| 68 | + env->active_tc.PC = entry; | |
| 69 | 69 | } else { |
| 70 | 70 | fprintf(stderr, "qemu: could not load kernel '%s'\n", |
| 71 | 71 | loaderparams.kernel_filename); |
| ... | ... | @@ -152,7 +152,7 @@ mips_mipssim_init (ram_addr_t ram_size, int vga_ram_size, |
| 152 | 152 | cpu_register_physical_memory(0x1fc00000LL, |
| 153 | 153 | bios_size, bios_offset | IO_MEM_ROM); |
| 154 | 154 | /* We have a boot vector start address. */ |
| 155 | - env->PC[env->current_tc] = (target_long)(int32_t)0xbfc00000; | |
| 155 | + env->active_tc.PC = (target_long)(int32_t)0xbfc00000; | |
| 156 | 156 | } |
| 157 | 157 | |
| 158 | 158 | if (kernel_filename) { | ... | ... |
hw/mips_r4k.c
| ... | ... | @@ -87,7 +87,7 @@ static void load_kernel (CPUState *env) |
| 87 | 87 | if (kernel_size >= 0) { |
| 88 | 88 | if ((entry & ~0x7fffffffULL) == 0x80000000) |
| 89 | 89 | entry = (int32_t)entry; |
| 90 | - env->PC[env->current_tc] = entry; | |
| 90 | + env->active_tc.PC = entry; | |
| 91 | 91 | } else { |
| 92 | 92 | fprintf(stderr, "qemu: could not load kernel '%s'\n", |
| 93 | 93 | loaderparams.kernel_filename); | ... | ... |
linux-user/main.c
| ... | ... | @@ -1779,8 +1779,8 @@ void cpu_loop(CPUMIPSState *env) |
| 1779 | 1779 | trapnr = cpu_mips_exec(env); |
| 1780 | 1780 | switch(trapnr) { |
| 1781 | 1781 | case EXCP_SYSCALL: |
| 1782 | - syscall_num = env->gpr[env->current_tc][2] - 4000; | |
| 1783 | - env->PC[env->current_tc] += 4; | |
| 1782 | + syscall_num = env->active_tc.gpr[2] - 4000; | |
| 1783 | + env->active_tc.PC += 4; | |
| 1784 | 1784 | if (syscall_num >= sizeof(mips_syscall_args)) { |
| 1785 | 1785 | ret = -ENOSYS; |
| 1786 | 1786 | } else { |
| ... | ... | @@ -1789,7 +1789,7 @@ void cpu_loop(CPUMIPSState *env) |
| 1789 | 1789 | abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0; |
| 1790 | 1790 | |
| 1791 | 1791 | nb_args = mips_syscall_args[syscall_num]; |
| 1792 | - sp_reg = env->gpr[env->current_tc][29]; | |
| 1792 | + sp_reg = env->active_tc.gpr[29]; | |
| 1793 | 1793 | switch (nb_args) { |
| 1794 | 1794 | /* these arguments are taken from the stack */ |
| 1795 | 1795 | /* FIXME - what to do if get_user() fails? */ |
| ... | ... | @@ -1800,20 +1800,20 @@ void cpu_loop(CPUMIPSState *env) |
| 1800 | 1800 | default: |
| 1801 | 1801 | break; |
| 1802 | 1802 | } |
| 1803 | - ret = do_syscall(env, env->gpr[env->current_tc][2], | |
| 1804 | - env->gpr[env->current_tc][4], | |
| 1805 | - env->gpr[env->current_tc][5], | |
| 1806 | - env->gpr[env->current_tc][6], | |
| 1807 | - env->gpr[env->current_tc][7], | |
| 1803 | + ret = do_syscall(env, env->active_tc.gpr[2], | |
| 1804 | + env->active_tc.gpr[4], | |
| 1805 | + env->active_tc.gpr[5], | |
| 1806 | + env->active_tc.gpr[6], | |
| 1807 | + env->active_tc.gpr[7], | |
| 1808 | 1808 | arg5, arg6/*, arg7, arg8*/); |
| 1809 | 1809 | } |
| 1810 | 1810 | if ((unsigned int)ret >= (unsigned int)(-1133)) { |
| 1811 | - env->gpr[env->current_tc][7] = 1; /* error flag */ | |
| 1811 | + env->active_tc.gpr[7] = 1; /* error flag */ | |
| 1812 | 1812 | ret = -ret; |
| 1813 | 1813 | } else { |
| 1814 | - env->gpr[env->current_tc][7] = 0; /* error flag */ | |
| 1814 | + env->active_tc.gpr[7] = 0; /* error flag */ | |
| 1815 | 1815 | } |
| 1816 | - env->gpr[env->current_tc][2] = ret; | |
| 1816 | + env->active_tc.gpr[2] = ret; | |
| 1817 | 1817 | break; |
| 1818 | 1818 | case EXCP_TLBL: |
| 1819 | 1819 | case EXCP_TLBS: |
| ... | ... | @@ -2566,9 +2566,9 @@ int main(int argc, char **argv) |
| 2566 | 2566 | int i; |
| 2567 | 2567 | |
| 2568 | 2568 | for(i = 0; i < 32; i++) { |
| 2569 | - env->gpr[env->current_tc][i] = regs->regs[i]; | |
| 2569 | + env->active_tc.gpr[i] = regs->regs[i]; | |
| 2570 | 2570 | } |
| 2571 | - env->PC[env->current_tc] = regs->cp0_epc; | |
| 2571 | + env->active_tc.PC = regs->cp0_epc; | |
| 2572 | 2572 | } |
| 2573 | 2573 | #elif defined(TARGET_SH4) |
| 2574 | 2574 | { | ... | ... |
linux-user/mips/target_signal.h
linux-user/mips64/target_signal.h
linux-user/mipsn32/target_signal.h
linux-user/signal.c
| ... | ... | @@ -2290,10 +2290,10 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc) |
| 2290 | 2290 | { |
| 2291 | 2291 | int err = 0; |
| 2292 | 2292 | |
| 2293 | - err |= __put_user(regs->PC[regs->current_tc], &sc->sc_pc); | |
| 2293 | + err |= __put_user(regs->active_tc.PC, &sc->sc_pc); | |
| 2294 | 2294 | |
| 2295 | -#define save_gp_reg(i) do { \ | |
| 2296 | - err |= __put_user(regs->gpr[regs->current_tc][i], &sc->sc_regs[i]); \ | |
| 2295 | +#define save_gp_reg(i) do { \ | |
| 2296 | + err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \ | |
| 2297 | 2297 | } while(0) |
| 2298 | 2298 | __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); |
| 2299 | 2299 | save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); |
| ... | ... | @@ -2306,8 +2306,8 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc) |
| 2306 | 2306 | save_gp_reg(31); |
| 2307 | 2307 | #undef save_gp_reg |
| 2308 | 2308 | |
| 2309 | - err |= __put_user(regs->HI[regs->current_tc][0], &sc->sc_mdhi); | |
| 2310 | - err |= __put_user(regs->LO[regs->current_tc][0], &sc->sc_mdlo); | |
| 2309 | + err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi); | |
| 2310 | + err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo); | |
| 2311 | 2311 | |
| 2312 | 2312 | /* Not used yet, but might be useful if we ever have DSP suppport */ |
| 2313 | 2313 | #if 0 |
| ... | ... | @@ -2367,11 +2367,11 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc) |
| 2367 | 2367 | |
| 2368 | 2368 | err |= __get_user(regs->CP0_EPC, &sc->sc_pc); |
| 2369 | 2369 | |
| 2370 | - err |= __get_user(regs->HI[regs->current_tc][0], &sc->sc_mdhi); | |
| 2371 | - err |= __get_user(regs->LO[regs->current_tc][0], &sc->sc_mdlo); | |
| 2370 | + err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi); | |
| 2371 | + err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo); | |
| 2372 | 2372 | |
| 2373 | 2373 | #define restore_gp_reg(i) do { \ |
| 2374 | - err |= __get_user(regs->gpr[regs->current_tc][i], &sc->sc_regs[i]); \ | |
| 2374 | + err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \ | |
| 2375 | 2375 | } while(0) |
| 2376 | 2376 | restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); |
| 2377 | 2377 | restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); |
| ... | ... | @@ -2437,7 +2437,7 @@ get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size) |
| 2437 | 2437 | unsigned long sp; |
| 2438 | 2438 | |
| 2439 | 2439 | /* Default to using normal stack */ |
| 2440 | - sp = regs->gpr[regs->current_tc][29]; | |
| 2440 | + sp = regs->active_tc.gpr[29]; | |
| 2441 | 2441 | |
| 2442 | 2442 | /* |
| 2443 | 2443 | * FPU emulator may have it's own trampoline active just |
| ... | ... | @@ -2486,15 +2486,15 @@ static void setup_frame(int sig, struct target_sigaction * ka, |
| 2486 | 2486 | * $25 and PC point to the signal handler, $29 points to the |
| 2487 | 2487 | * struct sigframe. |
| 2488 | 2488 | */ |
| 2489 | - regs->gpr[regs->current_tc][ 4] = sig; | |
| 2490 | - regs->gpr[regs->current_tc][ 5] = 0; | |
| 2491 | - regs->gpr[regs->current_tc][ 6] = frame_addr + offsetof(struct sigframe, sf_sc); | |
| 2492 | - regs->gpr[regs->current_tc][29] = frame_addr; | |
| 2493 | - regs->gpr[regs->current_tc][31] = frame_addr + offsetof(struct sigframe, sf_code); | |
| 2489 | + regs->active_tc.gpr[ 4] = sig; | |
| 2490 | + regs->active_tc.gpr[ 5] = 0; | |
| 2491 | + regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc); | |
| 2492 | + regs->active_tc.gpr[29] = frame_addr; | |
| 2493 | + regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code); | |
| 2494 | 2494 | /* The original kernel code sets CP0_EPC to the handler |
| 2495 | 2495 | * since it returns to userland using eret |
| 2496 | 2496 | * we cannot do this here, and we must set PC directly */ |
| 2497 | - regs->PC[regs->current_tc] = regs->gpr[regs->current_tc][25] = ka->_sa_handler; | |
| 2497 | + regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler; | |
| 2498 | 2498 | unlock_user_struct(frame, frame_addr, 1); |
| 2499 | 2499 | return; |
| 2500 | 2500 | |
| ... | ... | @@ -2515,7 +2515,7 @@ long do_sigreturn(CPUState *regs) |
| 2515 | 2515 | #if defined(DEBUG_SIGNAL) |
| 2516 | 2516 | fprintf(stderr, "do_sigreturn\n"); |
| 2517 | 2517 | #endif |
| 2518 | - frame_addr = regs->gpr[regs->current_tc][29]; | |
| 2518 | + frame_addr = regs->active_tc.gpr[29]; | |
| 2519 | 2519 | if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) |
| 2520 | 2520 | goto badframe; |
| 2521 | 2521 | |
| ... | ... | @@ -2542,7 +2542,7 @@ long do_sigreturn(CPUState *regs) |
| 2542 | 2542 | /* Unreached */ |
| 2543 | 2543 | #endif |
| 2544 | 2544 | |
| 2545 | - regs->PC[regs->current_tc] = regs->CP0_EPC; | |
| 2545 | + regs->active_tc.PC = regs->CP0_EPC; | |
| 2546 | 2546 | /* I am not sure this is right, but it seems to work |
| 2547 | 2547 | * maybe a problem with nested signals ? */ |
| 2548 | 2548 | regs->CP0_EPC = 0; | ... | ... |
linux-user/syscall.c
| ... | ... | @@ -3686,7 +3686,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 3686 | 3686 | if (!is_error(ret)) { |
| 3687 | 3687 | #if defined(TARGET_MIPS) |
| 3688 | 3688 | CPUMIPSState *env = (CPUMIPSState*)cpu_env; |
| 3689 | - env->gpr[env->current_tc][3] = host_pipe[1]; | |
| 3689 | + env->active_tc.gpr[3] = host_pipe[1]; | |
| 3690 | 3690 | ret = host_pipe[0]; |
| 3691 | 3691 | #elif defined(TARGET_SH4) |
| 3692 | 3692 | ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; | ... | ... |
monitor.c
| ... | ... | @@ -316,7 +316,7 @@ static void do_info_cpus(void) |
| 316 | 316 | #elif defined(TARGET_SPARC) |
| 317 | 317 | term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc); |
| 318 | 318 | #elif defined(TARGET_MIPS) |
| 319 | - term_printf(" PC=0x" TARGET_FMT_lx, env->PC[env->current_tc]); | |
| 319 | + term_printf(" PC=0x" TARGET_FMT_lx, env->active_tc.PC); | |
| 320 | 320 | #endif |
| 321 | 321 | if (env->halted) |
| 322 | 322 | term_printf(" (halted)"); | ... | ... |
target-mips/cpu.h
| ... | ... | @@ -134,29 +134,53 @@ typedef struct mips_def_t mips_def_t; |
| 134 | 134 | #define MIPS_TC_MAX 5 |
| 135 | 135 | #define MIPS_DSP_ACC 4 |
| 136 | 136 | |
| 137 | +typedef struct TCState TCState; | |
| 138 | +struct TCState { | |
| 139 | + target_ulong gpr[32]; | |
| 140 | + target_ulong PC; | |
| 141 | + target_ulong HI[MIPS_DSP_ACC]; | |
| 142 | + target_ulong LO[MIPS_DSP_ACC]; | |
| 143 | + target_ulong ACX[MIPS_DSP_ACC]; | |
| 144 | + target_ulong DSPControl; | |
| 145 | + int32_t CP0_TCStatus; | |
| 146 | +#define CP0TCSt_TCU3 31 | |
| 147 | +#define CP0TCSt_TCU2 30 | |
| 148 | +#define CP0TCSt_TCU1 29 | |
| 149 | +#define CP0TCSt_TCU0 28 | |
| 150 | +#define CP0TCSt_TMX 27 | |
| 151 | +#define CP0TCSt_RNST 23 | |
| 152 | +#define CP0TCSt_TDS 21 | |
| 153 | +#define CP0TCSt_DT 20 | |
| 154 | +#define CP0TCSt_DA 15 | |
| 155 | +#define CP0TCSt_A 13 | |
| 156 | +#define CP0TCSt_TKSU 11 | |
| 157 | +#define CP0TCSt_IXMT 10 | |
| 158 | +#define CP0TCSt_TASID 0 | |
| 159 | + int32_t CP0_TCBind; | |
| 160 | +#define CP0TCBd_CurTC 21 | |
| 161 | +#define CP0TCBd_TBE 17 | |
| 162 | +#define CP0TCBd_CurVPE 0 | |
| 163 | + target_ulong CP0_TCHalt; | |
| 164 | + target_ulong CP0_TCContext; | |
| 165 | + target_ulong CP0_TCSchedule; | |
| 166 | + target_ulong CP0_TCScheFBack; | |
| 167 | + int32_t CP0_Debug_tcstatus; | |
| 168 | +}; | |
| 169 | + | |
| 137 | 170 | typedef struct CPUMIPSState CPUMIPSState; |
| 138 | 171 | struct CPUMIPSState { |
| 139 | - /* General integer registers */ | |
| 140 | - target_ulong gpr[MIPS_SHADOW_SET_MAX][32]; | |
| 141 | - /* Special registers */ | |
| 142 | - target_ulong PC[MIPS_TC_MAX]; | |
| 172 | + TCState active_tc; | |
| 173 | + | |
| 143 | 174 | /* temporary hack for FP globals */ |
| 144 | 175 | #ifndef USE_HOST_FLOAT_REGS |
| 145 | 176 | fpr_t ft0; |
| 146 | 177 | fpr_t ft1; |
| 147 | 178 | fpr_t ft2; |
| 148 | 179 | #endif |
| 149 | - target_ulong HI[MIPS_TC_MAX][MIPS_DSP_ACC]; | |
| 150 | - target_ulong LO[MIPS_TC_MAX][MIPS_DSP_ACC]; | |
| 151 | - target_ulong ACX[MIPS_TC_MAX][MIPS_DSP_ACC]; | |
| 152 | - target_ulong DSPControl[MIPS_TC_MAX]; | |
| 153 | - | |
| 154 | 180 | CPUMIPSMVPContext *mvp; |
| 155 | 181 | CPUMIPSTLBContext *tlb; |
| 156 | 182 | CPUMIPSFPUContext *fpu; |
| 157 | 183 | uint32_t current_tc; |
| 158 | - target_ulong *current_tc_gprs; | |
| 159 | - target_ulong *current_tc_hi; | |
| 160 | 184 | |
| 161 | 185 | uint32_t SEGBITS; |
| 162 | 186 | target_ulong SEGMask; |
| ... | ... | @@ -206,28 +230,6 @@ struct CPUMIPSState { |
| 206 | 230 | #define CP0VPEOpt_DWX1 1 |
| 207 | 231 | #define CP0VPEOpt_DWX0 0 |
| 208 | 232 | target_ulong CP0_EntryLo0; |
| 209 | - int32_t CP0_TCStatus[MIPS_TC_MAX]; | |
| 210 | -#define CP0TCSt_TCU3 31 | |
| 211 | -#define CP0TCSt_TCU2 30 | |
| 212 | -#define CP0TCSt_TCU1 29 | |
| 213 | -#define CP0TCSt_TCU0 28 | |
| 214 | -#define CP0TCSt_TMX 27 | |
| 215 | -#define CP0TCSt_RNST 23 | |
| 216 | -#define CP0TCSt_TDS 21 | |
| 217 | -#define CP0TCSt_DT 20 | |
| 218 | -#define CP0TCSt_DA 15 | |
| 219 | -#define CP0TCSt_A 13 | |
| 220 | -#define CP0TCSt_TKSU 11 | |
| 221 | -#define CP0TCSt_IXMT 10 | |
| 222 | -#define CP0TCSt_TASID 0 | |
| 223 | - int32_t CP0_TCBind[MIPS_TC_MAX]; | |
| 224 | -#define CP0TCBd_CurTC 21 | |
| 225 | -#define CP0TCBd_TBE 17 | |
| 226 | -#define CP0TCBd_CurVPE 0 | |
| 227 | - target_ulong CP0_TCHalt[MIPS_TC_MAX]; | |
| 228 | - target_ulong CP0_TCContext[MIPS_TC_MAX]; | |
| 229 | - target_ulong CP0_TCSchedule[MIPS_TC_MAX]; | |
| 230 | - target_ulong CP0_TCScheFBack[MIPS_TC_MAX]; | |
| 231 | 233 | target_ulong CP0_EntryLo1; |
| 232 | 234 | target_ulong CP0_Context; |
| 233 | 235 | int32_t CP0_PageMask; |
| ... | ... | @@ -398,7 +400,6 @@ struct CPUMIPSState { |
| 398 | 400 | #define CP0DB_DDBL 2 |
| 399 | 401 | #define CP0DB_DBp 1 |
| 400 | 402 | #define CP0DB_DSS 0 |
| 401 | - int32_t CP0_Debug_tcstatus[MIPS_TC_MAX]; | |
| 402 | 403 | target_ulong CP0_DEPC; |
| 403 | 404 | int32_t CP0_Performance0; |
| 404 | 405 | int32_t CP0_TagLo; |
| ... | ... | @@ -407,6 +408,8 @@ struct CPUMIPSState { |
| 407 | 408 | int32_t CP0_DataHi; |
| 408 | 409 | target_ulong CP0_ErrorEPC; |
| 409 | 410 | int32_t CP0_DESAVE; |
| 411 | + /* We waste some space so we can handle shadow registers like TCs. */ | |
| 412 | + TCState tcs[MIPS_SHADOW_SET_MAX]; | |
| 410 | 413 | /* Qemu */ |
| 411 | 414 | int interrupt_request; |
| 412 | 415 | int error_code; |
| ... | ... | @@ -501,9 +504,9 @@ static inline int cpu_mmu_index (CPUState *env) |
| 501 | 504 | static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) |
| 502 | 505 | { |
| 503 | 506 | if (newsp) |
| 504 | - env->gpr[env->current_tc][29] = newsp; | |
| 505 | - env->gpr[env->current_tc][7] = 0; | |
| 506 | - env->gpr[env->current_tc][2] = 0; | |
| 507 | + env->active_tc.gpr[29] = newsp; | |
| 508 | + env->active_tc.gpr[7] = 0; | |
| 509 | + env->active_tc.gpr[2] = 0; | |
| 507 | 510 | } |
| 508 | 511 | #endif |
| 509 | 512 | ... | ... |
target-mips/helper.c
| ... | ... | @@ -241,7 +241,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 241 | 241 | cpu_dump_state(env, logfile, fprintf, 0); |
| 242 | 242 | #endif |
| 243 | 243 | fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n", |
| 244 | - __func__, env->PC[env->current_tc], address, rw, mmu_idx, is_softmmu); | |
| 244 | + __func__, env->active_tc.PC, address, rw, mmu_idx, is_softmmu); | |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | 247 | rw &= 1; |
| ... | ... | @@ -370,7 +370,7 @@ void do_interrupt (CPUState *env) |
| 370 | 370 | name = excp_names[env->exception_index]; |
| 371 | 371 | |
| 372 | 372 | fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n", |
| 373 | - __func__, env->PC[env->current_tc], env->CP0_EPC, name); | |
| 373 | + __func__, env->active_tc.PC, env->CP0_EPC, name); | |
| 374 | 374 | } |
| 375 | 375 | if (env->exception_index == EXCP_EXT_INTERRUPT && |
| 376 | 376 | (env->hflags & MIPS_HFLAG_DM)) |
| ... | ... | @@ -384,7 +384,7 @@ void do_interrupt (CPUState *env) |
| 384 | 384 | * (but we assume the pc has always been updated during |
| 385 | 385 | * code translation). |
| 386 | 386 | */ |
| 387 | - env->CP0_DEPC = env->PC[env->current_tc]; | |
| 387 | + env->CP0_DEPC = env->active_tc.PC; | |
| 388 | 388 | goto enter_debug_mode; |
| 389 | 389 | case EXCP_DINT: |
| 390 | 390 | env->CP0_Debug |= 1 << CP0DB_DINT; |
| ... | ... | @@ -404,10 +404,10 @@ void do_interrupt (CPUState *env) |
| 404 | 404 | if (env->hflags & MIPS_HFLAG_BMASK) { |
| 405 | 405 | /* If the exception was raised from a delay slot, |
| 406 | 406 | come back to the jump. */ |
| 407 | - env->CP0_DEPC = env->PC[env->current_tc] - 4; | |
| 407 | + env->CP0_DEPC = env->active_tc.PC - 4; | |
| 408 | 408 | env->hflags &= ~MIPS_HFLAG_BMASK; |
| 409 | 409 | } else { |
| 410 | - env->CP0_DEPC = env->PC[env->current_tc]; | |
| 410 | + env->CP0_DEPC = env->active_tc.PC; | |
| 411 | 411 | } |
| 412 | 412 | enter_debug_mode: |
| 413 | 413 | env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0; |
| ... | ... | @@ -415,7 +415,7 @@ void do_interrupt (CPUState *env) |
| 415 | 415 | /* EJTAG probe trap enable is not implemented... */ |
| 416 | 416 | if (!(env->CP0_Status & (1 << CP0St_EXL))) |
| 417 | 417 | env->CP0_Cause &= ~(1 << CP0Ca_BD); |
| 418 | - env->PC[env->current_tc] = (int32_t)0xBFC00480; | |
| 418 | + env->active_tc.PC = (int32_t)0xBFC00480; | |
| 419 | 419 | break; |
| 420 | 420 | case EXCP_RESET: |
| 421 | 421 | cpu_reset(env); |
| ... | ... | @@ -430,17 +430,17 @@ void do_interrupt (CPUState *env) |
| 430 | 430 | if (env->hflags & MIPS_HFLAG_BMASK) { |
| 431 | 431 | /* If the exception was raised from a delay slot, |
| 432 | 432 | come back to the jump. */ |
| 433 | - env->CP0_ErrorEPC = env->PC[env->current_tc] - 4; | |
| 433 | + env->CP0_ErrorEPC = env->active_tc.PC - 4; | |
| 434 | 434 | env->hflags &= ~MIPS_HFLAG_BMASK; |
| 435 | 435 | } else { |
| 436 | - env->CP0_ErrorEPC = env->PC[env->current_tc]; | |
| 436 | + env->CP0_ErrorEPC = env->active_tc.PC; | |
| 437 | 437 | } |
| 438 | 438 | env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); |
| 439 | 439 | env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; |
| 440 | 440 | env->hflags &= ~(MIPS_HFLAG_KSU); |
| 441 | 441 | if (!(env->CP0_Status & (1 << CP0St_EXL))) |
| 442 | 442 | env->CP0_Cause &= ~(1 << CP0Ca_BD); |
| 443 | - env->PC[env->current_tc] = (int32_t)0xBFC00000; | |
| 443 | + env->active_tc.PC = (int32_t)0xBFC00000; | |
| 444 | 444 | break; |
| 445 | 445 | case EXCP_EXT_INTERRUPT: |
| 446 | 446 | cause = 0; |
| ... | ... | @@ -545,10 +545,10 @@ void do_interrupt (CPUState *env) |
| 545 | 545 | if (env->hflags & MIPS_HFLAG_BMASK) { |
| 546 | 546 | /* If the exception was raised from a delay slot, |
| 547 | 547 | come back to the jump. */ |
| 548 | - env->CP0_EPC = env->PC[env->current_tc] - 4; | |
| 548 | + env->CP0_EPC = env->active_tc.PC - 4; | |
| 549 | 549 | env->CP0_Cause |= (1 << CP0Ca_BD); |
| 550 | 550 | } else { |
| 551 | - env->CP0_EPC = env->PC[env->current_tc]; | |
| 551 | + env->CP0_EPC = env->active_tc.PC; | |
| 552 | 552 | env->CP0_Cause &= ~(1 << CP0Ca_BD); |
| 553 | 553 | } |
| 554 | 554 | env->CP0_Status |= (1 << CP0St_EXL); |
| ... | ... | @@ -557,11 +557,11 @@ void do_interrupt (CPUState *env) |
| 557 | 557 | } |
| 558 | 558 | env->hflags &= ~MIPS_HFLAG_BMASK; |
| 559 | 559 | if (env->CP0_Status & (1 << CP0St_BEV)) { |
| 560 | - env->PC[env->current_tc] = (int32_t)0xBFC00200; | |
| 560 | + env->active_tc.PC = (int32_t)0xBFC00200; | |
| 561 | 561 | } else { |
| 562 | - env->PC[env->current_tc] = (int32_t)(env->CP0_EBase & ~0x3ff); | |
| 562 | + env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff); | |
| 563 | 563 | } |
| 564 | - env->PC[env->current_tc] += offset; | |
| 564 | + env->active_tc.PC += offset; | |
| 565 | 565 | env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC); |
| 566 | 566 | break; |
| 567 | 567 | default: |
| ... | ... | @@ -575,7 +575,7 @@ void do_interrupt (CPUState *env) |
| 575 | 575 | if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { |
| 576 | 576 | fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" |
| 577 | 577 | " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", |
| 578 | - __func__, env->PC[env->current_tc], env->CP0_EPC, cause, | |
| 578 | + __func__, env->active_tc.PC, env->CP0_EPC, cause, | |
| 579 | 579 | env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, |
| 580 | 580 | env->CP0_DEPC); |
| 581 | 581 | } | ... | ... |
target-mips/op_helper.c
| ... | ... | @@ -89,25 +89,25 @@ target_ulong do_dclz (target_ulong t0) |
| 89 | 89 | /* 64 bits arithmetic for 32 bits hosts */ |
| 90 | 90 | static always_inline uint64_t get_HILO (void) |
| 91 | 91 | { |
| 92 | - return ((uint64_t)(env->HI[env->current_tc][0]) << 32) | (uint32_t)env->LO[env->current_tc][0]; | |
| 92 | + return ((uint64_t)(env->active_tc.HI[0]) << 32) | (uint32_t)env->active_tc.LO[0]; | |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | static always_inline void set_HILO (uint64_t HILO) |
| 96 | 96 | { |
| 97 | - env->LO[env->current_tc][0] = (int32_t)HILO; | |
| 98 | - env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); | |
| 97 | + env->active_tc.LO[0] = (int32_t)HILO; | |
| 98 | + env->active_tc.HI[0] = (int32_t)(HILO >> 32); | |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | 101 | static always_inline void set_HIT0_LO (target_ulong t0, uint64_t HILO) |
| 102 | 102 | { |
| 103 | - env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); | |
| 104 | - t0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); | |
| 103 | + env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); | |
| 104 | + t0 = env->active_tc.HI[0] = (int32_t)(HILO >> 32); | |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | static always_inline void set_HI_LOT0 (target_ulong t0, uint64_t HILO) |
| 108 | 108 | { |
| 109 | - t0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); | |
| 110 | - env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); | |
| 109 | + t0 = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); | |
| 110 | + env->active_tc.HI[0] = (int32_t)(HILO >> 32); | |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | #if TARGET_LONG_BITS > HOST_LONG_BITS |
| ... | ... | @@ -246,12 +246,12 @@ target_ulong do_mulshiu (target_ulong t0, target_ulong t1) |
| 246 | 246 | #ifdef TARGET_MIPS64 |
| 247 | 247 | void do_dmult (target_ulong t0, target_ulong t1) |
| 248 | 248 | { |
| 249 | - muls64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), t0, t1); | |
| 249 | + muls64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), t0, t1); | |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | 252 | void do_dmultu (target_ulong t0, target_ulong t1) |
| 253 | 253 | { |
| 254 | - mulu64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), t0, t1); | |
| 254 | + mulu64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), t0, t1); | |
| 255 | 255 | } |
| 256 | 256 | #endif |
| 257 | 257 | |
| ... | ... | @@ -672,86 +672,107 @@ target_ulong do_mfc0_random (void) |
| 672 | 672 | |
| 673 | 673 | target_ulong do_mfc0_tcstatus (void) |
| 674 | 674 | { |
| 675 | - return env->CP0_TCStatus[env->current_tc]; | |
| 675 | + return env->active_tc.CP0_TCStatus; | |
| 676 | 676 | } |
| 677 | 677 | |
| 678 | 678 | target_ulong do_mftc0_tcstatus(void) |
| 679 | 679 | { |
| 680 | 680 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 681 | 681 | |
| 682 | - return env->CP0_TCStatus[other_tc]; | |
| 682 | + if (other_tc == env->current_tc) | |
| 683 | + return env->active_tc.CP0_TCStatus; | |
| 684 | + else | |
| 685 | + return env->tcs[other_tc].CP0_TCStatus; | |
| 683 | 686 | } |
| 684 | 687 | |
| 685 | 688 | target_ulong do_mfc0_tcbind (void) |
| 686 | 689 | { |
| 687 | - return env->CP0_TCBind[env->current_tc]; | |
| 690 | + return env->active_tc.CP0_TCBind; | |
| 688 | 691 | } |
| 689 | 692 | |
| 690 | 693 | target_ulong do_mftc0_tcbind(void) |
| 691 | 694 | { |
| 692 | 695 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 693 | 696 | |
| 694 | - return env->CP0_TCBind[other_tc]; | |
| 697 | + if (other_tc == env->current_tc) | |
| 698 | + return env->active_tc.CP0_TCBind; | |
| 699 | + else | |
| 700 | + return env->tcs[other_tc].CP0_TCBind; | |
| 695 | 701 | } |
| 696 | 702 | |
| 697 | 703 | target_ulong do_mfc0_tcrestart (void) |
| 698 | 704 | { |
| 699 | - return env->PC[env->current_tc]; | |
| 705 | + return env->active_tc.PC; | |
| 700 | 706 | } |
| 701 | 707 | |
| 702 | 708 | target_ulong do_mftc0_tcrestart(void) |
| 703 | 709 | { |
| 704 | 710 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 705 | 711 | |
| 706 | - return env->PC[other_tc]; | |
| 712 | + if (other_tc == env->current_tc) | |
| 713 | + return env->active_tc.PC; | |
| 714 | + else | |
| 715 | + return env->tcs[other_tc].PC; | |
| 707 | 716 | } |
| 708 | 717 | |
| 709 | 718 | target_ulong do_mfc0_tchalt (void) |
| 710 | 719 | { |
| 711 | - return env->CP0_TCHalt[env->current_tc]; | |
| 720 | + return env->active_tc.CP0_TCHalt; | |
| 712 | 721 | } |
| 713 | 722 | |
| 714 | 723 | target_ulong do_mftc0_tchalt(void) |
| 715 | 724 | { |
| 716 | 725 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 717 | 726 | |
| 718 | - return env->CP0_TCHalt[other_tc]; | |
| 727 | + if (other_tc == env->current_tc) | |
| 728 | + return env->active_tc.CP0_TCHalt; | |
| 729 | + else | |
| 730 | + return env->tcs[other_tc].CP0_TCHalt; | |
| 719 | 731 | } |
| 720 | 732 | |
| 721 | 733 | target_ulong do_mfc0_tccontext (void) |
| 722 | 734 | { |
| 723 | - return env->CP0_TCContext[env->current_tc]; | |
| 735 | + return env->active_tc.CP0_TCContext; | |
| 724 | 736 | } |
| 725 | 737 | |
| 726 | 738 | target_ulong do_mftc0_tccontext(void) |
| 727 | 739 | { |
| 728 | 740 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 729 | 741 | |
| 730 | - return env->CP0_TCContext[other_tc]; | |
| 742 | + if (other_tc == env->current_tc) | |
| 743 | + return env->active_tc.CP0_TCContext; | |
| 744 | + else | |
| 745 | + return env->tcs[other_tc].CP0_TCContext; | |
| 731 | 746 | } |
| 732 | 747 | |
| 733 | 748 | target_ulong do_mfc0_tcschedule (void) |
| 734 | 749 | { |
| 735 | - return env->CP0_TCSchedule[env->current_tc]; | |
| 750 | + return env->active_tc.CP0_TCSchedule; | |
| 736 | 751 | } |
| 737 | 752 | |
| 738 | 753 | target_ulong do_mftc0_tcschedule(void) |
| 739 | 754 | { |
| 740 | 755 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 741 | 756 | |
| 742 | - return env->CP0_TCSchedule[other_tc]; | |
| 757 | + if (other_tc == env->current_tc) | |
| 758 | + return env->active_tc.CP0_TCSchedule; | |
| 759 | + else | |
| 760 | + return env->tcs[other_tc].CP0_TCSchedule; | |
| 743 | 761 | } |
| 744 | 762 | |
| 745 | 763 | target_ulong do_mfc0_tcschefback (void) |
| 746 | 764 | { |
| 747 | - return env->CP0_TCScheFBack[env->current_tc]; | |
| 765 | + return env->active_tc.CP0_TCScheFBack; | |
| 748 | 766 | } |
| 749 | 767 | |
| 750 | 768 | target_ulong do_mftc0_tcschefback(void) |
| 751 | 769 | { |
| 752 | 770 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 753 | 771 | |
| 754 | - return env->CP0_TCScheFBack[other_tc]; | |
| 772 | + if (other_tc == env->current_tc) | |
| 773 | + return env->active_tc.CP0_TCScheFBack; | |
| 774 | + else | |
| 775 | + return env->tcs[other_tc].CP0_TCScheFBack; | |
| 755 | 776 | } |
| 756 | 777 | |
| 757 | 778 | target_ulong do_mfc0_count (void) |
| ... | ... | @@ -762,15 +783,26 @@ target_ulong do_mfc0_count (void) |
| 762 | 783 | target_ulong do_mftc0_entryhi(void) |
| 763 | 784 | { |
| 764 | 785 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 786 | + int32_t tcstatus; | |
| 765 | 787 | |
| 766 | - return (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff); | |
| 788 | + if (other_tc == env->current_tc) | |
| 789 | + tcstatus = env->active_tc.CP0_TCStatus; | |
| 790 | + else | |
| 791 | + tcstatus = env->tcs[other_tc].CP0_TCStatus; | |
| 792 | + | |
| 793 | + return (env->CP0_EntryHi & ~0xff) | (tcstatus & 0xff); | |
| 767 | 794 | } |
| 768 | 795 | |
| 769 | 796 | target_ulong do_mftc0_status(void) |
| 770 | 797 | { |
| 771 | 798 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 772 | - uint32_t tcstatus = env->CP0_TCStatus[other_tc]; | |
| 773 | 799 | target_ulong t0; |
| 800 | + int32_t tcstatus; | |
| 801 | + | |
| 802 | + if (other_tc == env->current_tc) | |
| 803 | + tcstatus = env->active_tc.CP0_TCStatus; | |
| 804 | + else | |
| 805 | + tcstatus = env->tcs[other_tc].CP0_TCStatus; | |
| 774 | 806 | |
| 775 | 807 | t0 = env->CP0_Status & ~0xf1000018; |
| 776 | 808 | t0 |= tcstatus & (0xf << CP0TCSt_TCU0); |
| ... | ... | @@ -807,37 +839,42 @@ target_ulong do_mfc0_debug (void) |
| 807 | 839 | target_ulong do_mftc0_debug(void) |
| 808 | 840 | { |
| 809 | 841 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 842 | + int32_t tcstatus; | |
| 843 | + | |
| 844 | + if (other_tc == env->current_tc) | |
| 845 | + tcstatus = env->active_tc.CP0_Debug_tcstatus; | |
| 846 | + else | |
| 847 | + tcstatus = env->tcs[other_tc].CP0_Debug_tcstatus; | |
| 810 | 848 | |
| 811 | 849 | /* XXX: Might be wrong, check with EJTAG spec. */ |
| 812 | 850 | return (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | |
| 813 | - (env->CP0_Debug_tcstatus[other_tc] & | |
| 814 | - ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); | |
| 851 | + (tcstatus & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); | |
| 815 | 852 | } |
| 816 | 853 | |
| 817 | 854 | #if defined(TARGET_MIPS64) |
| 818 | 855 | target_ulong do_dmfc0_tcrestart (void) |
| 819 | 856 | { |
| 820 | - return env->PC[env->current_tc]; | |
| 857 | + return env->active_tc.PC; | |
| 821 | 858 | } |
| 822 | 859 | |
| 823 | 860 | target_ulong do_dmfc0_tchalt (void) |
| 824 | 861 | { |
| 825 | - return env->CP0_TCHalt[env->current_tc]; | |
| 862 | + return env->active_tc.CP0_TCHalt; | |
| 826 | 863 | } |
| 827 | 864 | |
| 828 | 865 | target_ulong do_dmfc0_tccontext (void) |
| 829 | 866 | { |
| 830 | - return env->CP0_TCContext[env->current_tc]; | |
| 867 | + return env->active_tc.CP0_TCContext; | |
| 831 | 868 | } |
| 832 | 869 | |
| 833 | 870 | target_ulong do_dmfc0_tcschedule (void) |
| 834 | 871 | { |
| 835 | - return env->CP0_TCSchedule[env->current_tc]; | |
| 872 | + return env->active_tc.CP0_TCSchedule; | |
| 836 | 873 | } |
| 837 | 874 | |
| 838 | 875 | target_ulong do_dmfc0_tcschefback (void) |
| 839 | 876 | { |
| 840 | - return env->CP0_TCScheFBack[env->current_tc]; | |
| 877 | + return env->active_tc.CP0_TCScheFBack; | |
| 841 | 878 | } |
| 842 | 879 | |
| 843 | 880 | target_ulong do_dmfc0_lladdr (void) |
| ... | ... | @@ -955,11 +992,11 @@ void do_mtc0_tcstatus (target_ulong t0) |
| 955 | 992 | uint32_t mask = env->CP0_TCStatus_rw_bitmask; |
| 956 | 993 | uint32_t newval; |
| 957 | 994 | |
| 958 | - newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (t0 & mask); | |
| 995 | + newval = (env->active_tc.CP0_TCStatus & ~mask) | (t0 & mask); | |
| 959 | 996 | |
| 960 | 997 | // TODO: Sync with CP0_Status. |
| 961 | 998 | |
| 962 | - env->CP0_TCStatus[env->current_tc] = newval; | |
| 999 | + env->active_tc.CP0_TCStatus = newval; | |
| 963 | 1000 | } |
| 964 | 1001 | |
| 965 | 1002 | void do_mttc0_tcstatus (target_ulong t0) |
| ... | ... | @@ -968,7 +1005,10 @@ void do_mttc0_tcstatus (target_ulong t0) |
| 968 | 1005 | |
| 969 | 1006 | // TODO: Sync with CP0_Status. |
| 970 | 1007 | |
| 971 | - env->CP0_TCStatus[other_tc] = t0; | |
| 1008 | + if (other_tc == env->current_tc) | |
| 1009 | + env->active_tc.CP0_TCStatus = t0; | |
| 1010 | + else | |
| 1011 | + env->tcs[other_tc].CP0_TCStatus = t0; | |
| 972 | 1012 | } |
| 973 | 1013 | |
| 974 | 1014 | void do_mtc0_tcbind (target_ulong t0) |
| ... | ... | @@ -978,8 +1018,8 @@ void do_mtc0_tcbind (target_ulong t0) |
| 978 | 1018 | |
| 979 | 1019 | if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) |
| 980 | 1020 | mask |= (1 << CP0TCBd_CurVPE); |
| 981 | - newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (t0 & mask); | |
| 982 | - env->CP0_TCBind[env->current_tc] = newval; | |
| 1021 | + newval = (env->active_tc.CP0_TCBind & ~mask) | (t0 & mask); | |
| 1022 | + env->active_tc.CP0_TCBind = newval; | |
| 983 | 1023 | } |
| 984 | 1024 | |
| 985 | 1025 | void do_mttc0_tcbind (target_ulong t0) |
| ... | ... | @@ -990,14 +1030,19 @@ void do_mttc0_tcbind (target_ulong t0) |
| 990 | 1030 | |
| 991 | 1031 | if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) |
| 992 | 1032 | mask |= (1 << CP0TCBd_CurVPE); |
| 993 | - newval = (env->CP0_TCBind[other_tc] & ~mask) | (t0 & mask); | |
| 994 | - env->CP0_TCBind[other_tc] = newval; | |
| 1033 | + if (other_tc == env->current_tc) { | |
| 1034 | + newval = (env->active_tc.CP0_TCBind & ~mask) | (t0 & mask); | |
| 1035 | + env->active_tc.CP0_TCBind = newval; | |
| 1036 | + } else { | |
| 1037 | + newval = (env->tcs[other_tc].CP0_TCBind & ~mask) | (t0 & mask); | |
| 1038 | + env->tcs[other_tc].CP0_TCBind = newval; | |
| 1039 | + } | |
| 995 | 1040 | } |
| 996 | 1041 | |
| 997 | 1042 | void do_mtc0_tcrestart (target_ulong t0) |
| 998 | 1043 | { |
| 999 | - env->PC[env->current_tc] = t0; | |
| 1000 | - env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS); | |
| 1044 | + env->active_tc.PC = t0; | |
| 1045 | + env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS); | |
| 1001 | 1046 | env->CP0_LLAddr = 0ULL; |
| 1002 | 1047 | /* MIPS16 not implemented. */ |
| 1003 | 1048 | } |
| ... | ... | @@ -1006,15 +1051,22 @@ void do_mttc0_tcrestart (target_ulong t0) |
| 1006 | 1051 | { |
| 1007 | 1052 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1008 | 1053 | |
| 1009 | - env->PC[other_tc] = t0; | |
| 1010 | - env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS); | |
| 1011 | - env->CP0_LLAddr = 0ULL; | |
| 1012 | - /* MIPS16 not implemented. */ | |
| 1054 | + if (other_tc == env->current_tc) { | |
| 1055 | + env->active_tc.PC = t0; | |
| 1056 | + env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS); | |
| 1057 | + env->CP0_LLAddr = 0ULL; | |
| 1058 | + /* MIPS16 not implemented. */ | |
| 1059 | + } else { | |
| 1060 | + env->tcs[other_tc].PC = t0; | |
| 1061 | + env->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS); | |
| 1062 | + env->CP0_LLAddr = 0ULL; | |
| 1063 | + /* MIPS16 not implemented. */ | |
| 1064 | + } | |
| 1013 | 1065 | } |
| 1014 | 1066 | |
| 1015 | 1067 | void do_mtc0_tchalt (target_ulong t0) |
| 1016 | 1068 | { |
| 1017 | - env->CP0_TCHalt[env->current_tc] = t0 & 0x1; | |
| 1069 | + env->active_tc.CP0_TCHalt = t0 & 0x1; | |
| 1018 | 1070 | |
| 1019 | 1071 | // TODO: Halt TC / Restart (if allocated+active) TC. |
| 1020 | 1072 | } |
| ... | ... | @@ -1025,43 +1077,55 @@ void do_mttc0_tchalt (target_ulong t0) |
| 1025 | 1077 | |
| 1026 | 1078 | // TODO: Halt TC / Restart (if allocated+active) TC. |
| 1027 | 1079 | |
| 1028 | - env->CP0_TCHalt[other_tc] = t0; | |
| 1080 | + if (other_tc == env->current_tc) | |
| 1081 | + env->active_tc.CP0_TCHalt = t0; | |
| 1082 | + else | |
| 1083 | + env->tcs[other_tc].CP0_TCHalt = t0; | |
| 1029 | 1084 | } |
| 1030 | 1085 | |
| 1031 | 1086 | void do_mtc0_tccontext (target_ulong t0) |
| 1032 | 1087 | { |
| 1033 | - env->CP0_TCContext[env->current_tc] = t0; | |
| 1088 | + env->active_tc.CP0_TCContext = t0; | |
| 1034 | 1089 | } |
| 1035 | 1090 | |
| 1036 | 1091 | void do_mttc0_tccontext (target_ulong t0) |
| 1037 | 1092 | { |
| 1038 | 1093 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1039 | 1094 | |
| 1040 | - env->CP0_TCContext[other_tc] = t0; | |
| 1095 | + if (other_tc == env->current_tc) | |
| 1096 | + env->active_tc.CP0_TCContext = t0; | |
| 1097 | + else | |
| 1098 | + env->tcs[other_tc].CP0_TCContext = t0; | |
| 1041 | 1099 | } |
| 1042 | 1100 | |
| 1043 | 1101 | void do_mtc0_tcschedule (target_ulong t0) |
| 1044 | 1102 | { |
| 1045 | - env->CP0_TCSchedule[env->current_tc] = t0; | |
| 1103 | + env->active_tc.CP0_TCSchedule = t0; | |
| 1046 | 1104 | } |
| 1047 | 1105 | |
| 1048 | 1106 | void do_mttc0_tcschedule (target_ulong t0) |
| 1049 | 1107 | { |
| 1050 | 1108 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1051 | 1109 | |
| 1052 | - env->CP0_TCSchedule[other_tc] = t0; | |
| 1110 | + if (other_tc == env->current_tc) | |
| 1111 | + env->active_tc.CP0_TCSchedule = t0; | |
| 1112 | + else | |
| 1113 | + env->tcs[other_tc].CP0_TCSchedule = t0; | |
| 1053 | 1114 | } |
| 1054 | 1115 | |
| 1055 | 1116 | void do_mtc0_tcschefback (target_ulong t0) |
| 1056 | 1117 | { |
| 1057 | - env->CP0_TCScheFBack[env->current_tc] = t0; | |
| 1118 | + env->active_tc.CP0_TCScheFBack = t0; | |
| 1058 | 1119 | } |
| 1059 | 1120 | |
| 1060 | 1121 | void do_mttc0_tcschefback (target_ulong t0) |
| 1061 | 1122 | { |
| 1062 | 1123 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1063 | 1124 | |
| 1064 | - env->CP0_TCScheFBack[other_tc] = t0; | |
| 1125 | + if (other_tc == env->current_tc) | |
| 1126 | + env->active_tc.CP0_TCScheFBack = t0; | |
| 1127 | + else | |
| 1128 | + env->tcs[other_tc].CP0_TCScheFBack = t0; | |
| 1065 | 1129 | } |
| 1066 | 1130 | |
| 1067 | 1131 | void do_mtc0_entrylo1 (target_ulong t0) |
| ... | ... | @@ -1142,8 +1206,8 @@ void do_mtc0_entryhi (target_ulong t0) |
| 1142 | 1206 | old = env->CP0_EntryHi; |
| 1143 | 1207 | env->CP0_EntryHi = val; |
| 1144 | 1208 | if (env->CP0_Config3 & (1 << CP0C3_MT)) { |
| 1145 | - uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff; | |
| 1146 | - env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff); | |
| 1209 | + uint32_t tcst = env->active_tc.CP0_TCStatus & ~0xff; | |
| 1210 | + env->active_tc.CP0_TCStatus = tcst | (val & 0xff); | |
| 1147 | 1211 | } |
| 1148 | 1212 | /* If the ASID changes, flush qemu's TLB. */ |
| 1149 | 1213 | if ((old & 0xFF) != (val & 0xFF)) |
| ... | ... | @@ -1153,9 +1217,16 @@ void do_mtc0_entryhi (target_ulong t0) |
| 1153 | 1217 | void do_mttc0_entryhi(target_ulong t0) |
| 1154 | 1218 | { |
| 1155 | 1219 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1220 | + int32_t tcstatus; | |
| 1156 | 1221 | |
| 1157 | 1222 | env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (t0 & ~0xff); |
| 1158 | - env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (t0 & 0xff); | |
| 1223 | + if (other_tc == env->current_tc) { | |
| 1224 | + tcstatus = (env->active_tc.CP0_TCStatus & ~0xff) | (t0 & 0xff); | |
| 1225 | + env->active_tc.CP0_TCStatus = tcstatus; | |
| 1226 | + } else { | |
| 1227 | + tcstatus = (env->tcs[other_tc].CP0_TCStatus & ~0xff) | (t0 & 0xff); | |
| 1228 | + env->tcs[other_tc].CP0_TCStatus = tcstatus; | |
| 1229 | + } | |
| 1159 | 1230 | } |
| 1160 | 1231 | |
| 1161 | 1232 | void do_mtc0_compare (target_ulong t0) |
| ... | ... | @@ -1180,13 +1251,16 @@ void do_mtc0_status (target_ulong t0) |
| 1180 | 1251 | void do_mttc0_status(target_ulong t0) |
| 1181 | 1252 | { |
| 1182 | 1253 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1183 | - uint32_t tcstatus = env->CP0_TCStatus[other_tc]; | |
| 1254 | + int32_t tcstatus = env->tcs[other_tc].CP0_TCStatus; | |
| 1184 | 1255 | |
| 1185 | 1256 | env->CP0_Status = t0 & ~0xf1000018; |
| 1186 | 1257 | tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (t0 & (0xf << CP0St_CU0)); |
| 1187 | 1258 | tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((t0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX)); |
| 1188 | 1259 | tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((t0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU)); |
| 1189 | - env->CP0_TCStatus[other_tc] = tcstatus; | |
| 1260 | + if (other_tc == env->current_tc) | |
| 1261 | + env->active_tc.CP0_TCStatus = tcstatus; | |
| 1262 | + else | |
| 1263 | + env->tcs[other_tc].CP0_TCStatus = tcstatus; | |
| 1190 | 1264 | } |
| 1191 | 1265 | |
| 1192 | 1266 | void do_mtc0_intctl (target_ulong t0) |
| ... | ... | @@ -1279,9 +1353,13 @@ void do_mtc0_debug (target_ulong t0) |
| 1279 | 1353 | void do_mttc0_debug(target_ulong t0) |
| 1280 | 1354 | { |
| 1281 | 1355 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1356 | + uint32_t val = t0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); | |
| 1282 | 1357 | |
| 1283 | 1358 | /* XXX: Might be wrong, check with EJTAG spec. */ |
| 1284 | - env->CP0_Debug_tcstatus[other_tc] = t0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); | |
| 1359 | + if (other_tc == env->current_tc) | |
| 1360 | + env->active_tc.CP0_Debug_tcstatus = val; | |
| 1361 | + else | |
| 1362 | + env->tcs[other_tc].CP0_Debug_tcstatus = val; | |
| 1285 | 1363 | env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | |
| 1286 | 1364 | (t0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); |
| 1287 | 1365 | } |
| ... | ... | @@ -1336,70 +1414,100 @@ target_ulong do_mftgpr(target_ulong t0, uint32_t sel) |
| 1336 | 1414 | { |
| 1337 | 1415 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1338 | 1416 | |
| 1339 | - return env->gpr[other_tc][sel]; | |
| 1417 | + if (other_tc == env->current_tc) | |
| 1418 | + return env->active_tc.gpr[sel]; | |
| 1419 | + else | |
| 1420 | + return env->tcs[other_tc].gpr[sel]; | |
| 1340 | 1421 | } |
| 1341 | 1422 | |
| 1342 | 1423 | target_ulong do_mftlo(target_ulong t0, uint32_t sel) |
| 1343 | 1424 | { |
| 1344 | 1425 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1345 | 1426 | |
| 1346 | - return env->LO[other_tc][sel]; | |
| 1427 | + if (other_tc == env->current_tc) | |
| 1428 | + return env->active_tc.LO[sel]; | |
| 1429 | + else | |
| 1430 | + return env->tcs[other_tc].LO[sel]; | |
| 1347 | 1431 | } |
| 1348 | 1432 | |
| 1349 | 1433 | target_ulong do_mfthi(target_ulong t0, uint32_t sel) |
| 1350 | 1434 | { |
| 1351 | 1435 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1352 | 1436 | |
| 1353 | - return env->HI[other_tc][sel]; | |
| 1437 | + if (other_tc == env->current_tc) | |
| 1438 | + return env->active_tc.HI[sel]; | |
| 1439 | + else | |
| 1440 | + return env->tcs[other_tc].HI[sel]; | |
| 1354 | 1441 | } |
| 1355 | 1442 | |
| 1356 | 1443 | target_ulong do_mftacx(target_ulong t0, uint32_t sel) |
| 1357 | 1444 | { |
| 1358 | 1445 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1359 | 1446 | |
| 1360 | - return env->ACX[other_tc][sel]; | |
| 1447 | + if (other_tc == env->current_tc) | |
| 1448 | + return env->active_tc.ACX[sel]; | |
| 1449 | + else | |
| 1450 | + return env->tcs[other_tc].ACX[sel]; | |
| 1361 | 1451 | } |
| 1362 | 1452 | |
| 1363 | 1453 | target_ulong do_mftdsp(target_ulong t0) |
| 1364 | 1454 | { |
| 1365 | 1455 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1366 | 1456 | |
| 1367 | - return env->DSPControl[other_tc]; | |
| 1457 | + if (other_tc == env->current_tc) | |
| 1458 | + return env->active_tc.DSPControl; | |
| 1459 | + else | |
| 1460 | + return env->tcs[other_tc].DSPControl; | |
| 1368 | 1461 | } |
| 1369 | 1462 | |
| 1370 | 1463 | void do_mttgpr(target_ulong t0, uint32_t sel) |
| 1371 | 1464 | { |
| 1372 | 1465 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1373 | 1466 | |
| 1374 | - env->gpr[other_tc][sel] = t0; | |
| 1467 | + if (other_tc == env->current_tc) | |
| 1468 | + env->active_tc.gpr[sel] = t0; | |
| 1469 | + else | |
| 1470 | + env->tcs[other_tc].gpr[sel] = t0; | |
| 1375 | 1471 | } |
| 1376 | 1472 | |
| 1377 | 1473 | void do_mttlo(target_ulong t0, uint32_t sel) |
| 1378 | 1474 | { |
| 1379 | 1475 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1380 | 1476 | |
| 1381 | - env->LO[other_tc][sel] = t0; | |
| 1477 | + if (other_tc == env->current_tc) | |
| 1478 | + env->active_tc.LO[sel] = t0; | |
| 1479 | + else | |
| 1480 | + env->tcs[other_tc].LO[sel] = t0; | |
| 1382 | 1481 | } |
| 1383 | 1482 | |
| 1384 | 1483 | void do_mtthi(target_ulong t0, uint32_t sel) |
| 1385 | 1484 | { |
| 1386 | 1485 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1387 | 1486 | |
| 1388 | - env->HI[other_tc][sel] = t0; | |
| 1487 | + if (other_tc == env->current_tc) | |
| 1488 | + env->active_tc.HI[sel] = t0; | |
| 1489 | + else | |
| 1490 | + env->tcs[other_tc].HI[sel] = t0; | |
| 1389 | 1491 | } |
| 1390 | 1492 | |
| 1391 | 1493 | void do_mttacx(target_ulong t0, uint32_t sel) |
| 1392 | 1494 | { |
| 1393 | 1495 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1394 | 1496 | |
| 1395 | - env->ACX[other_tc][sel] = t0; | |
| 1497 | + if (other_tc == env->current_tc) | |
| 1498 | + env->active_tc.ACX[sel] = t0; | |
| 1499 | + else | |
| 1500 | + env->tcs[other_tc].ACX[sel] = t0; | |
| 1396 | 1501 | } |
| 1397 | 1502 | |
| 1398 | 1503 | void do_mttdsp(target_ulong t0) |
| 1399 | 1504 | { |
| 1400 | 1505 | int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); |
| 1401 | 1506 | |
| 1402 | - env->DSPControl[other_tc] = t0; | |
| 1507 | + if (other_tc == env->current_tc) | |
| 1508 | + env->active_tc.DSPControl = t0; | |
| 1509 | + else | |
| 1510 | + env->tcs[other_tc].DSPControl = t0; | |
| 1403 | 1511 | } |
| 1404 | 1512 | |
| 1405 | 1513 | /* MIPS MT functions */ |
| ... | ... | @@ -1452,7 +1560,7 @@ target_ulong do_yield(target_ulong t0) |
| 1452 | 1560 | /* No scheduling policy implemented. */ |
| 1453 | 1561 | if (t0 != -2) { |
| 1454 | 1562 | if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) && |
| 1455 | - env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) { | |
| 1563 | + env->active_tc.CP0_TCStatus & (1 << CP0TCSt_DT)) { | |
| 1456 | 1564 | env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); |
| 1457 | 1565 | env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT; |
| 1458 | 1566 | do_raise_exception(EXCP_THREAD); |
| ... | ... | @@ -1659,7 +1767,7 @@ target_ulong do_ei (target_ulong t0) |
| 1659 | 1767 | void debug_pre_eret (void) |
| 1660 | 1768 | { |
| 1661 | 1769 | fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, |
| 1662 | - env->PC[env->current_tc], env->CP0_EPC); | |
| 1770 | + env->active_tc.PC, env->CP0_EPC); | |
| 1663 | 1771 | if (env->CP0_Status & (1 << CP0St_ERL)) |
| 1664 | 1772 | fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); |
| 1665 | 1773 | if (env->hflags & MIPS_HFLAG_DM) |
| ... | ... | @@ -1670,7 +1778,7 @@ void debug_pre_eret (void) |
| 1670 | 1778 | void debug_post_eret (void) |
| 1671 | 1779 | { |
| 1672 | 1780 | fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, |
| 1673 | - env->PC[env->current_tc], env->CP0_EPC); | |
| 1781 | + env->active_tc.PC, env->CP0_EPC); | |
| 1674 | 1782 | if (env->CP0_Status & (1 << CP0St_ERL)) |
| 1675 | 1783 | fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); |
| 1676 | 1784 | if (env->hflags & MIPS_HFLAG_DM) |
| ... | ... | @@ -1688,10 +1796,10 @@ void do_eret (void) |
| 1688 | 1796 | if (loglevel & CPU_LOG_EXEC) |
| 1689 | 1797 | debug_pre_eret(); |
| 1690 | 1798 | if (env->CP0_Status & (1 << CP0St_ERL)) { |
| 1691 | - env->PC[env->current_tc] = env->CP0_ErrorEPC; | |
| 1799 | + env->active_tc.PC = env->CP0_ErrorEPC; | |
| 1692 | 1800 | env->CP0_Status &= ~(1 << CP0St_ERL); |
| 1693 | 1801 | } else { |
| 1694 | - env->PC[env->current_tc] = env->CP0_EPC; | |
| 1802 | + env->active_tc.PC = env->CP0_EPC; | |
| 1695 | 1803 | env->CP0_Status &= ~(1 << CP0St_EXL); |
| 1696 | 1804 | } |
| 1697 | 1805 | compute_hflags(env); |
| ... | ... | @@ -1704,7 +1812,7 @@ void do_deret (void) |
| 1704 | 1812 | { |
| 1705 | 1813 | if (loglevel & CPU_LOG_EXEC) |
| 1706 | 1814 | debug_pre_eret(); |
| 1707 | - env->PC[env->current_tc] = env->CP0_DEPC; | |
| 1815 | + env->active_tc.PC = env->CP0_DEPC; | |
| 1708 | 1816 | env->hflags &= MIPS_HFLAG_DM; |
| 1709 | 1817 | compute_hflags(env); |
| 1710 | 1818 | if (loglevel & CPU_LOG_EXEC) |
| ... | ... | @@ -1804,21 +1912,21 @@ void do_pmon (int function) |
| 1804 | 1912 | function /= 2; |
| 1805 | 1913 | switch (function) { |
| 1806 | 1914 | case 2: /* TODO: char inbyte(int waitflag); */ |
| 1807 | - if (env->gpr[env->current_tc][4] == 0) | |
| 1808 | - env->gpr[env->current_tc][2] = -1; | |
| 1915 | + if (env->active_tc.gpr[4] == 0) | |
| 1916 | + env->active_tc.gpr[2] = -1; | |
| 1809 | 1917 | /* Fall through */ |
| 1810 | 1918 | case 11: /* TODO: char inbyte (void); */ |
| 1811 | - env->gpr[env->current_tc][2] = -1; | |
| 1919 | + env->active_tc.gpr[2] = -1; | |
| 1812 | 1920 | break; |
| 1813 | 1921 | case 3: |
| 1814 | 1922 | case 12: |
| 1815 | - printf("%c", (char)(env->gpr[env->current_tc][4] & 0xFF)); | |
| 1923 | + printf("%c", (char)(env->active_tc.gpr[4] & 0xFF)); | |
| 1816 | 1924 | break; |
| 1817 | 1925 | case 17: |
| 1818 | 1926 | break; |
| 1819 | 1927 | case 158: |
| 1820 | 1928 | { |
| 1821 | - unsigned char *fmt = (void *)(unsigned long)env->gpr[env->current_tc][4]; | |
| 1929 | + unsigned char *fmt = (void *)(unsigned long)env->active_tc.gpr[4]; | |
| 1822 | 1930 | printf("%s", fmt); |
| 1823 | 1931 | } |
| 1824 | 1932 | break; | ... | ... |
target-mips/translate.c
| ... | ... | @@ -423,7 +423,7 @@ enum { |
| 423 | 423 | }; |
| 424 | 424 | |
| 425 | 425 | /* global register indices */ |
| 426 | -static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu; | |
| 426 | +static TCGv cpu_env, current_fpu; | |
| 427 | 427 | |
| 428 | 428 | /* FPU TNs, global for now. */ |
| 429 | 429 | static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3]; |
| ... | ... | @@ -563,40 +563,40 @@ static inline void gen_load_gpr (TCGv t, int reg) |
| 563 | 563 | if (reg == 0) |
| 564 | 564 | tcg_gen_movi_tl(t, 0); |
| 565 | 565 | else |
| 566 | - tcg_gen_ld_tl(t, current_tc_gprs, sizeof(target_ulong) * reg); | |
| 566 | + tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) + | |
| 567 | + sizeof(target_ulong) * reg); | |
| 567 | 568 | } |
| 568 | 569 | |
| 569 | 570 | static inline void gen_store_gpr (TCGv t, int reg) |
| 570 | 571 | { |
| 571 | 572 | if (reg != 0) |
| 572 | - tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg); | |
| 573 | + tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) + | |
| 574 | + sizeof(target_ulong) * reg); | |
| 573 | 575 | } |
| 574 | 576 | |
| 575 | 577 | /* Moves to/from HI and LO registers. */ |
| 576 | 578 | static inline void gen_load_LO (TCGv t, int reg) |
| 577 | 579 | { |
| 578 | - tcg_gen_ld_tl(t, current_tc_hi, | |
| 579 | - offsetof(CPUState, LO) | |
| 580 | - - offsetof(CPUState, HI) | |
| 581 | - + sizeof(target_ulong) * reg); | |
| 580 | + tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) + | |
| 581 | + sizeof(target_ulong) * reg); | |
| 582 | 582 | } |
| 583 | 583 | |
| 584 | 584 | static inline void gen_store_LO (TCGv t, int reg) |
| 585 | 585 | { |
| 586 | - tcg_gen_st_tl(t, current_tc_hi, | |
| 587 | - offsetof(CPUState, LO) | |
| 588 | - - offsetof(CPUState, HI) | |
| 589 | - + sizeof(target_ulong) * reg); | |
| 586 | + tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) + | |
| 587 | + sizeof(target_ulong) * reg); | |
| 590 | 588 | } |
| 591 | 589 | |
| 592 | 590 | static inline void gen_load_HI (TCGv t, int reg) |
| 593 | 591 | { |
| 594 | - tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg); | |
| 592 | + tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) + | |
| 593 | + sizeof(target_ulong) * reg); | |
| 595 | 594 | } |
| 596 | 595 | |
| 597 | 596 | static inline void gen_store_HI (TCGv t, int reg) |
| 598 | 597 | { |
| 599 | - tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg); | |
| 598 | + tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) + | |
| 599 | + sizeof(target_ulong) * reg); | |
| 600 | 600 | } |
| 601 | 601 | |
| 602 | 602 | /* Moves to/from shadow registers. */ |
| ... | ... | @@ -805,38 +805,18 @@ OP_CONDZ(ltz, TCG_COND_LT); |
| 805 | 805 | static inline void gen_save_pc(target_ulong pc) |
| 806 | 806 | { |
| 807 | 807 | TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL); |
| 808 | - TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32); | |
| 809 | - TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 810 | - TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 811 | 808 | |
| 812 | 809 | tcg_gen_movi_tl(r_tmp, pc); |
| 813 | - tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc)); | |
| 814 | - tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong)); | |
| 815 | - tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off); | |
| 816 | - tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr); | |
| 817 | - tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC)); | |
| 818 | - tcg_temp_free(r_tc_off); | |
| 819 | - tcg_temp_free(r_tc_off_ptr); | |
| 820 | - tcg_temp_free(r_ptr); | |
| 810 | + tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, active_tc.PC)); | |
| 821 | 811 | tcg_temp_free(r_tmp); |
| 822 | 812 | } |
| 823 | 813 | |
| 824 | 814 | static inline void gen_breg_pc(void) |
| 825 | 815 | { |
| 826 | 816 | TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL); |
| 827 | - TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32); | |
| 828 | - TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 829 | - TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 830 | 817 | |
| 831 | 818 | tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget)); |
| 832 | - tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc)); | |
| 833 | - tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong)); | |
| 834 | - tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off); | |
| 835 | - tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr); | |
| 836 | - tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC)); | |
| 837 | - tcg_temp_free(r_tc_off); | |
| 838 | - tcg_temp_free(r_tc_off_ptr); | |
| 839 | - tcg_temp_free(r_ptr); | |
| 819 | + tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, active_tc.PC)); | |
| 840 | 820 | tcg_temp_free(r_tmp); |
| 841 | 821 | } |
| 842 | 822 | |
| ... | ... | @@ -5202,8 +5182,8 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd, |
| 5202 | 5182 | TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); |
| 5203 | 5183 | |
| 5204 | 5184 | if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && |
| 5205 | - ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) != | |
| 5206 | - (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE)))) | |
| 5185 | + ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != | |
| 5186 | + (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) | |
| 5207 | 5187 | tcg_gen_movi_tl(t0, -1); |
| 5208 | 5188 | else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > |
| 5209 | 5189 | (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) |
| ... | ... | @@ -5371,8 +5351,8 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, |
| 5371 | 5351 | |
| 5372 | 5352 | gen_load_gpr(t0, rt); |
| 5373 | 5353 | if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && |
| 5374 | - ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) != | |
| 5375 | - (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE)))) | |
| 5354 | + ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != | |
| 5355 | + (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) | |
| 5376 | 5356 | /* NOP */ ; |
| 5377 | 5357 | else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > |
| 5378 | 5358 | (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) |
| ... | ... | @@ -8009,8 +7989,8 @@ void dump_fpu (CPUState *env) |
| 8009 | 7989 | "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx |
| 8010 | 7990 | " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx |
| 8011 | 7991 | " %04x\n", |
| 8012 | - env->PC[env->current_tc], env->HI[env->current_tc][0], | |
| 8013 | - env->LO[env->current_tc][0], env->hflags, env->btarget, | |
| 7992 | + env->active_tc.PC, env->active_tc.HI[0], | |
| 7993 | + env->active_tc.LO[0], env->hflags, env->btarget, | |
| 8014 | 7994 | env->bcond); |
| 8015 | 7995 | fpu_dump_state(env, logfile, fprintf, 0); |
| 8016 | 7996 | } |
| ... | ... | @@ -8028,18 +8008,18 @@ void cpu_mips_check_sign_extensions (CPUState *env, FILE *f, |
| 8028 | 8008 | { |
| 8029 | 8009 | int i; |
| 8030 | 8010 | |
| 8031 | - if (!SIGN_EXT_P(env->PC[env->current_tc])) | |
| 8032 | - cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]); | |
| 8033 | - if (!SIGN_EXT_P(env->HI[env->current_tc][0])) | |
| 8034 | - cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]); | |
| 8035 | - if (!SIGN_EXT_P(env->LO[env->current_tc][0])) | |
| 8036 | - cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]); | |
| 8011 | + if (!SIGN_EXT_P(env->active_tc.PC)) | |
| 8012 | + cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC); | |
| 8013 | + if (!SIGN_EXT_P(env->active_tc.HI[0])) | |
| 8014 | + cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]); | |
| 8015 | + if (!SIGN_EXT_P(env->active_tc.LO[0])) | |
| 8016 | + cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]); | |
| 8037 | 8017 | if (!SIGN_EXT_P(env->btarget)) |
| 8038 | 8018 | cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget); |
| 8039 | 8019 | |
| 8040 | 8020 | for (i = 0; i < 32; i++) { |
| 8041 | - if (!SIGN_EXT_P(env->gpr[env->current_tc][i])) | |
| 8042 | - cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]); | |
| 8021 | + if (!SIGN_EXT_P(env->active_tc.gpr[i])) | |
| 8022 | + cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]); | |
| 8043 | 8023 | } |
| 8044 | 8024 | |
| 8045 | 8025 | if (!SIGN_EXT_P(env->CP0_EPC)) |
| ... | ... | @@ -8056,11 +8036,11 @@ void cpu_dump_state (CPUState *env, FILE *f, |
| 8056 | 8036 | int i; |
| 8057 | 8037 | |
| 8058 | 8038 | cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n", |
| 8059 | - env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond); | |
| 8039 | + env->active_tc.PC, env->active_tc.HI, env->active_tc.LO, env->hflags, env->btarget, env->bcond); | |
| 8060 | 8040 | for (i = 0; i < 32; i++) { |
| 8061 | 8041 | if ((i & 3) == 0) |
| 8062 | 8042 | cpu_fprintf(f, "GPR%02d:", i); |
| 8063 | - cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]); | |
| 8043 | + cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]); | |
| 8064 | 8044 | if ((i & 3) == 3) |
| 8065 | 8045 | cpu_fprintf(f, "\n"); |
| 8066 | 8046 | } |
| ... | ... | @@ -8085,14 +8065,6 @@ static void mips_tcg_init(void) |
| 8085 | 8065 | return; |
| 8086 | 8066 | |
| 8087 | 8067 | cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env"); |
| 8088 | - current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR, | |
| 8089 | - TCG_AREG0, | |
| 8090 | - offsetof(CPUState, current_tc_gprs), | |
| 8091 | - "current_tc_gprs"); | |
| 8092 | - current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR, | |
| 8093 | - TCG_AREG0, | |
| 8094 | - offsetof(CPUState, current_tc_hi), | |
| 8095 | - "current_tc_hi"); | |
| 8096 | 8068 | current_fpu = tcg_global_mem_new(TCG_TYPE_PTR, |
| 8097 | 8069 | TCG_AREG0, |
| 8098 | 8070 | offsetof(CPUState, fpu), |
| ... | ... | @@ -8149,11 +8121,11 @@ void cpu_reset (CPUMIPSState *env) |
| 8149 | 8121 | if (env->hflags & MIPS_HFLAG_BMASK) { |
| 8150 | 8122 | /* If the exception was raised from a delay slot, |
| 8151 | 8123 | * come back to the jump. */ |
| 8152 | - env->CP0_ErrorEPC = env->PC[env->current_tc] - 4; | |
| 8124 | + env->CP0_ErrorEPC = env->active_tc.PC - 4; | |
| 8153 | 8125 | } else { |
| 8154 | - env->CP0_ErrorEPC = env->PC[env->current_tc]; | |
| 8126 | + env->CP0_ErrorEPC = env->active_tc.PC; | |
| 8155 | 8127 | } |
| 8156 | - env->PC[env->current_tc] = (int32_t)0xBFC00000; | |
| 8128 | + env->active_tc.PC = (int32_t)0xBFC00000; | |
| 8157 | 8129 | env->CP0_Wired = 0; |
| 8158 | 8130 | /* SMP not implemented */ |
| 8159 | 8131 | env->CP0_EBase = 0x80000000; |
| ... | ... | @@ -8187,7 +8159,7 @@ void cpu_reset (CPUMIPSState *env) |
| 8187 | 8159 | void gen_pc_load(CPUState *env, TranslationBlock *tb, |
| 8188 | 8160 | unsigned long searched_pc, int pc_pos, void *puc) |
| 8189 | 8161 | { |
| 8190 | - env->PC[env->current_tc] = gen_opc_pc[pc_pos]; | |
| 8162 | + env->active_tc.PC = gen_opc_pc[pc_pos]; | |
| 8191 | 8163 | env->hflags &= ~MIPS_HFLAG_BMASK; |
| 8192 | 8164 | env->hflags |= gen_opc_hflags[pc_pos]; |
| 8193 | 8165 | } | ... | ... |
target-mips/translate_init.c
| ... | ... | @@ -546,8 +546,6 @@ static int cpu_mips_register (CPUMIPSState *env, const mips_def_t *def) |
| 546 | 546 | env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask; |
| 547 | 547 | env->CP0_SRSCtl = def->CP0_SRSCtl; |
| 548 | 548 | env->current_tc = 0; |
| 549 | - env->current_tc_gprs = &env->gpr[env->current_tc][0]; | |
| 550 | - env->current_tc_hi = &env->HI[env->current_tc][0]; | |
| 551 | 549 | env->SEGBITS = def->SEGBITS; |
| 552 | 550 | env->SEGMask = (target_ulong)((1ULL << def->SEGBITS) - 1); |
| 553 | 551 | #if defined(TARGET_MIPS64) | ... | ... |