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