Revision b5dc7732
b/cpu-exec.c | ||
---|---|---|
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 */ |
b/gdbstub.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 |
b/hw/mips_mipssim.c | ||
---|---|---|
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 | 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) { |
b/hw/mips_r4k.c | ||
---|---|---|
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); |
b/linux-user/main.c | ||
---|---|---|
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 | 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 | 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 | 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 |
{ |
b/linux-user/mips/target_signal.h | ||
---|---|---|
23 | 23 |
|
24 | 24 |
static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) |
25 | 25 |
{ |
26 |
return state->gpr[state->current_tc][29];
|
|
26 |
return state->active_tc.gpr[29];
|
|
27 | 27 |
} |
28 | 28 |
|
29 | 29 |
#endif /* TARGET_SIGNAL_H */ |
b/linux-user/mips64/target_signal.h | ||
---|---|---|
23 | 23 |
|
24 | 24 |
static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) |
25 | 25 |
{ |
26 |
return state->gpr[state->current_tc][29];
|
|
26 |
return state->active_tc.gpr[29];
|
|
27 | 27 |
} |
28 | 28 |
|
29 | 29 |
#endif /* TARGET_SIGNAL_H */ |
b/linux-user/mipsn32/target_signal.h | ||
---|---|---|
23 | 23 |
|
24 | 24 |
static inline target_ulong get_sp_from_cpustate(CPUMIPSState *state) |
25 | 25 |
{ |
26 |
return state->gpr[state->current_tc][29];
|
|
26 |
return state->active_tc.gpr[29];
|
|
27 | 27 |
} |
28 | 28 |
|
29 | 29 |
#endif /* TARGET_SIGNAL_H */ |
b/linux-user/signal.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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; |
b/linux-user/syscall.c | ||
---|---|---|
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]; |
b/monitor.c | ||
---|---|---|
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)"); |
b/target-mips/cpu.h | ||
---|---|---|
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 | 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 | 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 | 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 | 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 |
|
b/target-mips/helper.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 |
} |
b/target-mips/op_helper.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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; |
b/target-mips/translate.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 |
} |
b/target-mips/translate_init.c | ||
---|---|---|
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) |
Also available in: Unified diff