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