Commit ead9360e2fbcaae10a8ca3d8bfed885422205dca

Authored by ths
1 parent 606b41e7

Partial support for 34K multithreading, not functional yet.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3156 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
... ... @@ -194,7 +194,7 @@ static inline TranslationBlock *tb_find_fast(void)
194 194 #elif defined(TARGET_MIPS)
195 195 flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
196 196 cs_base = 0;
197   - pc = env->PC;
  197 + pc = env->PC[env->current_tc];
198 198 #elif defined(TARGET_M68K)
199 199 flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
200 200 | (env->sr & SR_S) /* Bit 13 */
... ...
gdbstub.c
... ... @@ -559,17 +559,17 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
559 559 ptr = mem_buf;
560 560 for (i = 0; i < 32; i++)
561 561 {
562   - *(target_ulong *)ptr = tswapl(env->gpr[i]);
  562 + *(target_ulong *)ptr = tswapl(env->gpr[i][env->current_tc]);
563 563 ptr += sizeof(target_ulong);
564 564 }
565 565  
566 566 *(target_ulong *)ptr = tswapl(env->CP0_Status);
567 567 ptr += sizeof(target_ulong);
568 568  
569   - *(target_ulong *)ptr = tswapl(env->LO);
  569 + *(target_ulong *)ptr = tswapl(env->LO[0][env->current_tc]);
570 570 ptr += sizeof(target_ulong);
571 571  
572   - *(target_ulong *)ptr = tswapl(env->HI);
  572 + *(target_ulong *)ptr = tswapl(env->HI[0][env->current_tc]);
573 573 ptr += sizeof(target_ulong);
574 574  
575 575 *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr);
... ... @@ -578,21 +578,21 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
578 578 *(target_ulong *)ptr = tswapl(env->CP0_Cause);
579 579 ptr += sizeof(target_ulong);
580 580  
581   - *(target_ulong *)ptr = tswapl(env->PC);
  581 + *(target_ulong *)ptr = tswapl(env->PC[env->current_tc]);
582 582 ptr += sizeof(target_ulong);
583 583  
584 584 if (env->CP0_Config1 & (1 << CP0C1_FP))
585 585 {
586 586 for (i = 0; i < 32; i++)
587 587 {
588   - *(target_ulong *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]);
  588 + *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].fs[FP_ENDIAN_IDX]);
589 589 ptr += sizeof(target_ulong);
590 590 }
591 591  
592   - *(target_ulong *)ptr = tswapl(env->fcr31);
  592 + *(target_ulong *)ptr = tswapl(env->fpu->fcr31);
593 593 ptr += sizeof(target_ulong);
594 594  
595   - *(target_ulong *)ptr = tswapl(env->fcr0);
  595 + *(target_ulong *)ptr = tswapl(env->fpu->fcr0);
596 596 ptr += sizeof(target_ulong);
597 597 }
598 598  
... ... @@ -611,7 +611,7 @@ static unsigned int ieee_rm[] =
611 611 float_round_down
612 612 };
613 613 #define RESTORE_ROUNDING_MODE \
614   - set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
  614 + set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)
615 615  
616 616 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
617 617 {
... ... @@ -621,17 +621,17 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
621 621 ptr = mem_buf;
622 622 for (i = 0; i < 32; i++)
623 623 {
624   - env->gpr[i] = tswapl(*(target_ulong *)ptr);
  624 + env->gpr[i][env->current_tc] = tswapl(*(target_ulong *)ptr);
625 625 ptr += sizeof(target_ulong);
626 626 }
627 627  
628 628 env->CP0_Status = tswapl(*(target_ulong *)ptr);
629 629 ptr += sizeof(target_ulong);
630 630  
631   - env->LO = tswapl(*(target_ulong *)ptr);
  631 + env->LO[0][env->current_tc] = tswapl(*(target_ulong *)ptr);
632 632 ptr += sizeof(target_ulong);
633 633  
634   - env->HI = tswapl(*(target_ulong *)ptr);
  634 + env->HI[0][env->current_tc] = tswapl(*(target_ulong *)ptr);
635 635 ptr += sizeof(target_ulong);
636 636  
637 637 env->CP0_BadVAddr = tswapl(*(target_ulong *)ptr);
... ... @@ -640,21 +640,21 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
640 640 env->CP0_Cause = tswapl(*(target_ulong *)ptr);
641 641 ptr += sizeof(target_ulong);
642 642  
643   - env->PC = tswapl(*(target_ulong *)ptr);
  643 + env->PC[env->current_tc] = tswapl(*(target_ulong *)ptr);
644 644 ptr += sizeof(target_ulong);
645 645  
646 646 if (env->CP0_Config1 & (1 << CP0C1_FP))
647 647 {
648 648 for (i = 0; i < 32; i++)
649 649 {
650   - env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
  650 + env->fpu->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
651 651 ptr += sizeof(target_ulong);
652 652 }
653 653  
654   - env->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
  654 + env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
655 655 ptr += sizeof(target_ulong);
656 656  
657   - env->fcr0 = tswapl(*(target_ulong *)ptr);
  657 + env->fpu->fcr0 = tswapl(*(target_ulong *)ptr);
658 658 ptr += sizeof(target_ulong);
659 659  
660 660 /* set rounding mode */
... ... @@ -775,7 +775,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
775 775 #elif defined (TARGET_SH4)
776 776 env->pc = addr;
777 777 #elif defined (TARGET_MIPS)
778   - env->PC = addr;
  778 + env->PC[env->current_tc] = addr;
779 779 #endif
780 780 }
781 781 #ifdef CONFIG_USER_ONLY
... ... @@ -799,7 +799,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
799 799 #elif defined (TARGET_SH4)
800 800 env->pc = addr;
801 801 #elif defined (TARGET_MIPS)
802   - env->PC = addr;
  802 + env->PC[env->current_tc] = addr;
803 803 #endif
804 804 }
805 805 cpu_single_step(env, 1);
... ...
hw/mips_r4k.c
... ... @@ -77,7 +77,7 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
77 77 if (kernel_size >= 0) {
78 78 if ((entry & ~0x7fffffffULL) == 0x80000000)
79 79 entry = (int32_t)entry;
80   - env->PC = entry;
  80 + env->PC[env->current_tc] = entry;
81 81 } else {
82 82 fprintf(stderr, "qemu: could not load kernel '%s'\n",
83 83 kernel_filename);
... ...
hw/mips_timer.c
... ... @@ -10,7 +10,7 @@ uint32_t cpu_mips_get_random (CPUState *env)
10 10 static uint32_t seed = 0;
11 11 uint32_t idx;
12 12 seed = seed * 314159 + 1;
13   - idx = (seed >> 16) % (env->nb_tlb - env->CP0_Wired) + env->CP0_Wired;
  13 + idx = (seed >> 16) % (env->tlb->nb_tlb - env->CP0_Wired) + env->CP0_Wired;
14 14 return idx;
15 15 }
16 16  
... ...
linux-user/main.c
... ... @@ -1374,8 +1374,8 @@ void cpu_loop(CPUMIPSState *env)
1374 1374 trapnr = cpu_mips_exec(env);
1375 1375 switch(trapnr) {
1376 1376 case EXCP_SYSCALL:
1377   - syscall_num = env->gpr[2] - 4000;
1378   - env->PC += 4;
  1377 + syscall_num = env->gpr[2][env->current_tc] - 4000;
  1378 + env->PC[env->current_tc] += 4;
1379 1379 if (syscall_num >= sizeof(mips_syscall_args)) {
1380 1380 ret = -ENOSYS;
1381 1381 } else {
... ... @@ -1384,7 +1384,7 @@ void cpu_loop(CPUMIPSState *env)
1384 1384 target_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
1385 1385  
1386 1386 nb_args = mips_syscall_args[syscall_num];
1387   - sp_reg = env->gpr[29];
  1387 + sp_reg = env->gpr[29][env->current_tc];
1388 1388 switch (nb_args) {
1389 1389 /* these arguments are taken from the stack */
1390 1390 case 8: arg8 = tgetl(sp_reg + 28);
... ... @@ -1394,18 +1394,20 @@ void cpu_loop(CPUMIPSState *env)
1394 1394 default:
1395 1395 break;
1396 1396 }
1397   - ret = do_syscall(env, env->gpr[2],
1398   - env->gpr[4], env->gpr[5],
1399   - env->gpr[6], env->gpr[7],
  1397 + ret = do_syscall(env, env->gpr[2][env->current_tc],
  1398 + env->gpr[4][env->current_tc],
  1399 + env->gpr[5][env->current_tc],
  1400 + env->gpr[6][env->current_tc],
  1401 + env->gpr[7][env->current_tc],
1400 1402 arg5, arg6/*, arg7, arg8*/);
1401 1403 }
1402 1404 if ((unsigned int)ret >= (unsigned int)(-1133)) {
1403   - env->gpr[7] = 1; /* error flag */
  1405 + env->gpr[7][env->current_tc] = 1; /* error flag */
1404 1406 ret = -ret;
1405 1407 } else {
1406   - env->gpr[7] = 0; /* error flag */
  1408 + env->gpr[7][env->current_tc] = 0; /* error flag */
1407 1409 }
1408   - env->gpr[2] = ret;
  1410 + env->gpr[2][env->current_tc] = ret;
1409 1411 break;
1410 1412 case EXCP_TLBL:
1411 1413 case EXCP_TLBS:
... ... @@ -2053,9 +2055,9 @@ int main(int argc, char **argv)
2053 2055 cpu_mips_register(env, def);
2054 2056  
2055 2057 for(i = 0; i < 32; i++) {
2056   - env->gpr[i] = regs->regs[i];
  2058 + env->gpr[i][env->current_tc] = regs->regs[i];
2057 2059 }
2058   - env->PC = regs->cp0_epc;
  2060 + env->PC[env->current_tc] = regs->cp0_epc;
2059 2061 }
2060 2062 #elif defined(TARGET_SH4)
2061 2063 {
... ...
linux-user/signal.c
... ... @@ -1686,10 +1686,10 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1686 1686 {
1687 1687 int err = 0;
1688 1688  
1689   - err |= __put_user(regs->PC, &sc->sc_pc);
  1689 + err |= __put_user(regs->PC[regs->current_tc], &sc->sc_pc);
1690 1690  
1691   -#define save_gp_reg(i) do { \
1692   - err |= __put_user(regs->gpr[i], &sc->sc_regs[i]); \
  1691 +#define save_gp_reg(i) do { \
  1692 + err |= __put_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]); \
1693 1693 } while(0)
1694 1694 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
1695 1695 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
... ... @@ -1702,8 +1702,8 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1702 1702 save_gp_reg(31);
1703 1703 #undef save_gp_reg
1704 1704  
1705   - err |= __put_user(regs->HI, &sc->sc_mdhi);
1706   - err |= __put_user(regs->LO, &sc->sc_mdlo);
  1705 + err |= __put_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi);
  1706 + err |= __put_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);
1707 1707  
1708 1708 /* Not used yet, but might be useful if we ever have DSP suppport */
1709 1709 #if 0
... ... @@ -1763,11 +1763,11 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1763 1763  
1764 1764 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
1765 1765  
1766   - err |= __get_user(regs->HI, &sc->sc_mdhi);
1767   - err |= __get_user(regs->LO, &sc->sc_mdlo);
  1766 + err |= __get_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi);
  1767 + err |= __get_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);
1768 1768  
1769   -#define restore_gp_reg(i) do { \
1770   - err |= __get_user(regs->gpr[i], &sc->sc_regs[i]); \
  1769 +#define restore_gp_reg(i) do { \
  1770 + err |= __get_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]); \
1771 1771 } while(0)
1772 1772 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
1773 1773 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
... ... @@ -1833,7 +1833,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
1833 1833 unsigned long sp;
1834 1834  
1835 1835 /* Default to using normal stack */
1836   - sp = regs->gpr[29];
  1836 + sp = regs->gpr[29][regs->current_tc];
1837 1837  
1838 1838 /*
1839 1839 * FPU emulator may have it's own trampoline active just
... ... @@ -1881,15 +1881,15 @@ static void setup_frame(int sig, struct emulated_sigaction * ka,
1881 1881 * $25 and PC point to the signal handler, $29 points to the
1882 1882 * struct sigframe.
1883 1883 */
1884   - regs->gpr[ 4] = sig;
1885   - regs->gpr[ 5] = 0;
1886   - regs->gpr[ 6] = h2g(&frame->sf_sc);
1887   - regs->gpr[29] = h2g(frame);
1888   - regs->gpr[31] = h2g(frame->sf_code);
  1884 + regs->gpr[ 4][regs->current_tc] = sig;
  1885 + regs->gpr[ 5][regs->current_tc] = 0;
  1886 + regs->gpr[ 6][regs->current_tc] = h2g(&frame->sf_sc);
  1887 + regs->gpr[29][regs->current_tc] = h2g(frame);
  1888 + regs->gpr[31][regs->current_tc] = h2g(frame->sf_code);
1889 1889 /* The original kernel code sets CP0_EPC to the handler
1890 1890 * since it returns to userland using eret
1891 1891 * we cannot do this here, and we must set PC directly */
1892   - regs->PC = regs->gpr[25] = ka->sa._sa_handler;
  1892 + regs->PC[regs->current_tc] = regs->gpr[25][regs->current_tc] = ka->sa._sa_handler;
1893 1893 return;
1894 1894  
1895 1895 give_sigsegv:
... ... @@ -1907,7 +1907,7 @@ long do_sigreturn(CPUState *regs)
1907 1907 #if defined(DEBUG_SIGNAL)
1908 1908 fprintf(stderr, "do_sigreturn\n");
1909 1909 #endif
1910   - frame = (struct sigframe *) regs->gpr[29];
  1910 + frame = (struct sigframe *) regs->gpr[29][regs->current_tc];
1911 1911 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
1912 1912 goto badframe;
1913 1913  
... ... @@ -1934,7 +1934,7 @@ long do_sigreturn(CPUState *regs)
1934 1934 /* Unreached */
1935 1935 #endif
1936 1936  
1937   - regs->PC = regs->CP0_EPC;
  1937 + regs->PC[regs->current_tc] = regs->CP0_EPC;
1938 1938 /* I am not sure this is right, but it seems to work
1939 1939 * maybe a problem with nested signals ? */
1940 1940 regs->CP0_EPC = 0;
... ...
linux-user/syscall.c
... ... @@ -2189,8 +2189,8 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
2189 2189 /* ??? is this sufficient? */
2190 2190 #elif defined(TARGET_MIPS)
2191 2191 if (!newsp)
2192   - newsp = env->gpr[29];
2193   - new_env->gpr[29] = newsp;
  2192 + newsp = env->gpr[29][env->current_tc];
  2193 + new_env->gpr[29][env->current_tc] = newsp;
2194 2194 #elif defined(TARGET_PPC)
2195 2195 if (!newsp)
2196 2196 newsp = env->gpr[1];
... ... @@ -2777,7 +2777,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2777 2777 ret = get_errno(pipe(host_pipe));
2778 2778 if (!is_error(ret)) {
2779 2779 #if defined(TARGET_MIPS)
2780   - ((CPUMIPSState*)cpu_env)->gpr[3] = host_pipe[1];
  2780 + CPUMIPSState *env = (CPUMIPSState*)cpu_env;
  2781 + env->gpr[3][env->current_tc] = host_pipe[1];
2781 2782 ret = host_pipe[0];
2782 2783 #else
2783 2784 tput32(arg1, host_pipe[0]);
... ...
monitor.c
... ... @@ -309,6 +309,10 @@ static void do_info_cpus(void)
309 309 term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
310 310 if (env->halted)
311 311 term_printf(" (halted)");
  312 +#elif defined(TARGET_MIPS)
  313 + term_printf(" PC=0x" TARGET_FMT_lx, env->PC[env->current_tc]);
  314 + if (env->halted)
  315 + term_printf(" (halted)");
312 316 #endif
313 317 term_printf("\n");
314 318 }
... ...
target-mips/cpu.h
... ... @@ -17,21 +17,7 @@ typedef unsigned char uint_fast8_t;
17 17 typedef unsigned int uint_fast16_t;
18 18 #endif
19 19  
20   -typedef union fpr_t fpr_t;
21   -union fpr_t {
22   - float64 fd; /* ieee double precision */
23   - float32 fs[2];/* ieee single precision */
24   - uint64_t d; /* binary double fixed-point */
25   - uint32_t w[2]; /* binary single fixed-point */
26   -};
27   -/* define FP_ENDIAN_IDX to access the same location
28   - * in the fpr_t union regardless of the host endianess
29   - */
30   -#if defined(WORDS_BIGENDIAN)
31   -# define FP_ENDIAN_IDX 1
32   -#else
33   -# define FP_ENDIAN_IDX 0
34   -#endif
  20 +struct CPUMIPSState;
35 21  
36 22 typedef struct r4k_tlb_t r4k_tlb_t;
37 23 struct r4k_tlb_t {
... ... @@ -48,20 +34,40 @@ struct r4k_tlb_t {
48 34 target_ulong PFN[2];
49 35 };
50 36  
51   -typedef struct mips_def_t mips_def_t;
  37 +typedef struct CPUMIPSTLBContext CPUMIPSTLBContext;
  38 +struct CPUMIPSTLBContext {
  39 + uint32_t nb_tlb;
  40 + uint32_t tlb_in_use;
  41 + int (*map_address) (struct CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
  42 + void (*do_tlbwi) (void);
  43 + void (*do_tlbwr) (void);
  44 + void (*do_tlbp) (void);
  45 + void (*do_tlbr) (void);
  46 + union {
  47 + struct {
  48 + r4k_tlb_t tlb[MIPS_TLB_MAX];
  49 + } r4k;
  50 + } mmu;
  51 +};
52 52  
53   -typedef struct CPUMIPSState CPUMIPSState;
54   -struct CPUMIPSState {
55   - /* General integer registers */
56   - target_ulong gpr[32];
57   - /* Special registers */
58   - target_ulong PC;
59   -#if TARGET_LONG_BITS > HOST_LONG_BITS
60   - target_ulong t0;
61   - target_ulong t1;
62   - target_ulong t2;
  53 +typedef union fpr_t fpr_t;
  54 +union fpr_t {
  55 + float64 fd; /* ieee double precision */
  56 + float32 fs[2];/* ieee single precision */
  57 + uint64_t d; /* binary double fixed-point */
  58 + uint32_t w[2]; /* binary single fixed-point */
  59 +};
  60 +/* define FP_ENDIAN_IDX to access the same location
  61 + * in the fpr_t union regardless of the host endianess
  62 + */
  63 +#if defined(WORDS_BIGENDIAN)
  64 +# define FP_ENDIAN_IDX 1
  65 +#else
  66 +# define FP_ENDIAN_IDX 0
63 67 #endif
64   - target_ulong HI, LO;
  68 +
  69 +typedef struct CPUMIPSFPUContext CPUMIPSFPUContext;
  70 +struct CPUMIPSFPUContext {
65 71 /* Floating point registers */
66 72 fpr_t fpr[32];
67 73 #ifndef USE_HOST_FLOAT_REGS
... ... @@ -99,30 +105,161 @@ struct CPUMIPSState {
99 105 #define FP_DIV0 8
100 106 #define FP_INVALID 16
101 107 #define FP_UNIMPLEMENTED 32
  108 +};
  109 +
  110 +typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
  111 +struct CPUMIPSMVPContext {
  112 + int32_t CP0_MVPControl;
  113 +#define CP0MVPCo_CPA 3
  114 +#define CP0MVPCo_STLB 2
  115 +#define CP0MVPCo_VPC 1
  116 +#define CP0MVPCo_EVP 0
  117 + int32_t CP0_MVPConf0;
  118 +#define CP0MVPC0_M 31
  119 +#define CP0MVPC0_TLBS 29
  120 +#define CP0MVPC0_GS 28
  121 +#define CP0MVPC0_PCP 27
  122 +#define CP0MVPC0_PTLBE 16
  123 +#define CP0MVPC0_TCA 15
  124 +#define CP0MVPC0_PVPE 10
  125 +#define CP0MVPC0_PTC 0
  126 + int32_t CP0_MVPConf1;
  127 +#define CP0MVPC1_CIM 31
  128 +#define CP0MVPC1_CIF 30
  129 +#define CP0MVPC1_PCX 20
  130 +#define CP0MVPC1_PCP2 10
  131 +#define CP0MVPC1_PCP1 0
  132 +};
  133 +
  134 +typedef struct mips_def_t mips_def_t;
  135 +
  136 +#define MIPS_SHADOW_SET_MAX 16
  137 +#define MIPS_TC_MAX 5
  138 +#define MIPS_DSP_ACC 4
  139 +
  140 +typedef struct CPUMIPSState CPUMIPSState;
  141 +struct CPUMIPSState {
  142 + /* General integer registers */
  143 + target_ulong gpr[32][MIPS_SHADOW_SET_MAX];
  144 + /* Special registers */
  145 + target_ulong PC[MIPS_TC_MAX];
  146 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  147 + target_ulong t0;
  148 + target_ulong t1;
  149 + target_ulong t2;
  150 +#endif
  151 + target_ulong HI[MIPS_DSP_ACC][MIPS_TC_MAX];
  152 + target_ulong LO[MIPS_DSP_ACC][MIPS_TC_MAX];
  153 + target_ulong ACX[MIPS_DSP_ACC][MIPS_TC_MAX];
  154 + target_ulong DSPControl[MIPS_TC_MAX];
  155 +
  156 + CPUMIPSMVPContext *mvp;
  157 + CPUMIPSTLBContext *tlb;
  158 + CPUMIPSFPUContext *fpu;
  159 + uint32_t current_tc;
102 160  
103   - uint32_t nb_tlb;
104   - uint32_t tlb_in_use;
105 161 uint32_t SEGBITS;
106 162 target_ulong SEGMask;
107   - int (*map_address) (CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
108   - void (*do_tlbwi) (void);
109   - void (*do_tlbwr) (void);
110   - void (*do_tlbp) (void);
111   - void (*do_tlbr) (void);
112   - union {
113   - struct {
114   - r4k_tlb_t tlb[MIPS_TLB_MAX];
115   - } r4k;
116   - } mmu;
117 163  
118 164 int32_t CP0_Index;
  165 + /* CP0_MVP* are per MVP registers. */
119 166 int32_t CP0_Random;
  167 + int32_t CP0_VPEControl;
  168 +#define CP0VPECo_YSI 21
  169 +#define CP0VPECo_GSI 20
  170 +#define CP0VPECo_EXCPT 16
  171 +#define CP0VPECo_TE 15
  172 +#define CP0VPECo_TargTC 0
  173 + int32_t CP0_VPEConf0;
  174 +#define CP0VPEC0_M 31
  175 +#define CP0VPEC0_XTC 21
  176 +#define CP0VPEC0_TCS 19
  177 +#define CP0VPEC0_SCS 18
  178 +#define CP0VPEC0_DSC 17
  179 +#define CP0VPEC0_ICS 16
  180 +#define CP0VPEC0_MVP 1
  181 +#define CP0VPEC0_VPA 0
  182 + int32_t CP0_VPEConf1;
  183 +#define CP0VPEC1_NCX 20
  184 +#define CP0VPEC1_NCP2 10
  185 +#define CP0VPEC1_NCP1 0
  186 + target_ulong CP0_YQMask;
  187 + target_ulong CP0_VPESchedule;
  188 + target_ulong CP0_VPEScheFBack;
  189 + int32_t CP0_VPEOpt;
  190 +#define CP0VPEOpt_IWX7 15
  191 +#define CP0VPEOpt_IWX6 14
  192 +#define CP0VPEOpt_IWX5 13
  193 +#define CP0VPEOpt_IWX4 12
  194 +#define CP0VPEOpt_IWX3 11
  195 +#define CP0VPEOpt_IWX2 10
  196 +#define CP0VPEOpt_IWX1 9
  197 +#define CP0VPEOpt_IWX0 8
  198 +#define CP0VPEOpt_DWX7 7
  199 +#define CP0VPEOpt_DWX6 6
  200 +#define CP0VPEOpt_DWX5 5
  201 +#define CP0VPEOpt_DWX4 4
  202 +#define CP0VPEOpt_DWX3 3
  203 +#define CP0VPEOpt_DWX2 2
  204 +#define CP0VPEOpt_DWX1 1
  205 +#define CP0VPEOpt_DWX0 0
120 206 target_ulong CP0_EntryLo0;
  207 + int32_t CP0_TCStatus[MIPS_TC_MAX];
  208 +#define CP0TCSt_TCU3 31
  209 +#define CP0TCSt_TCU2 30
  210 +#define CP0TCSt_TCU1 29
  211 +#define CP0TCSt_TCU0 28
  212 +#define CP0TCSt_TMX 27
  213 +#define CP0TCSt_RNST 23
  214 +#define CP0TCSt_TDS 21
  215 +#define CP0TCSt_DT 20
  216 +#define CP0TCSt_DA 15
  217 +#define CP0TCSt_A 13
  218 +#define CP0TCSt_TKSU 11
  219 +#define CP0TCSt_IXMT 10
  220 +#define CP0TCSt_TASID 0
  221 + int32_t CP0_TCBind[MIPS_TC_MAX];
  222 +#define CP0TCBd_CurTC 21
  223 +#define CP0TCBd_TBE 17
  224 +#define CP0TCBd_CurVPE 0
  225 + target_ulong CP0_TCHalt[MIPS_TC_MAX];
  226 + target_ulong CP0_TCContext[MIPS_TC_MAX];
  227 + target_ulong CP0_TCSchedule[MIPS_TC_MAX];
  228 + target_ulong CP0_TCScheFBack[MIPS_TC_MAX];
121 229 target_ulong CP0_EntryLo1;
122 230 target_ulong CP0_Context;
123 231 int32_t CP0_PageMask;
124 232 int32_t CP0_PageGrain;
125 233 int32_t CP0_Wired;
  234 + int32_t CP0_SRSConf0_rw_bitmask;
  235 + int32_t CP0_SRSConf0;
  236 +#define CP0SRSC0_M 31
  237 +#define CP0SRSC0_SRS3 20
  238 +#define CP0SRSC0_SRS2 10
  239 +#define CP0SRSC0_SRS1 0
  240 + int32_t CP0_SRSConf1_rw_bitmask;
  241 + int32_t CP0_SRSConf1;
  242 +#define CP0SRSC1_M 31
  243 +#define CP0SRSC1_SRS6 20
  244 +#define CP0SRSC1_SRS5 10
  245 +#define CP0SRSC1_SRS4 0
  246 + int32_t CP0_SRSConf2_rw_bitmask;
  247 + int32_t CP0_SRSConf2;
  248 +#define CP0SRSC2_M 31
  249 +#define CP0SRSC2_SRS9 20
  250 +#define CP0SRSC2_SRS8 10
  251 +#define CP0SRSC2_SRS7 0
  252 + int32_t CP0_SRSConf3_rw_bitmask;
  253 + int32_t CP0_SRSConf3;
  254 +#define CP0SRSC3_M 31
  255 +#define CP0SRSC3_SRS12 20
  256 +#define CP0SRSC3_SRS11 10
  257 +#define CP0SRSC3_SRS10 0
  258 + int32_t CP0_SRSConf4_rw_bitmask;
  259 + int32_t CP0_SRSConf4;
  260 +#define CP0SRSC4_SRS15 20
  261 +#define CP0SRSC4_SRS14 10
  262 +#define CP0SRSC4_SRS13 0
126 263 int32_t CP0_HWREna;
127 264 target_ulong CP0_BadVAddr;
128 265 int32_t CP0_Count;
... ... @@ -152,8 +289,24 @@ struct CPUMIPSState {
152 289 #define CP0St_EXL 1
153 290 #define CP0St_IE 0
154 291 int32_t CP0_IntCtl;
  292 +#define CP0IntCtl_IPTI 29
  293 +#define CP0IntCtl_IPPC1 26
  294 +#define CP0IntCtl_VS 5
155 295 int32_t CP0_SRSCtl;
  296 +#define CP0SRSCtl_HSS 26
  297 +#define CP0SRSCtl_EICSS 18
  298 +#define CP0SRSCtl_ESS 12
  299 +#define CP0SRSCtl_PSS 6
  300 +#define CP0SRSCtl_CSS 0
156 301 int32_t CP0_SRSMap;
  302 +#define CP0SRSMap_SSV7 28
  303 +#define CP0SRSMap_SSV6 24
  304 +#define CP0SRSMap_SSV5 20
  305 +#define CP0SRSMap_SSV4 16
  306 +#define CP0SRSMap_SSV3 12
  307 +#define CP0SRSMap_SSV2 8
  308 +#define CP0SRSMap_SSV1 4
  309 +#define CP0SRSMap_SSV0 0
157 310 int32_t CP0_Cause;
158 311 #define CP0Ca_BD 31
159 312 #define CP0Ca_TI 30
... ... @@ -219,13 +372,14 @@ struct CPUMIPSState {
219 372 #define CP0C3_TL 0
220 373 int32_t CP0_Config6;
221 374 int32_t CP0_Config7;
  375 + /* XXX: Maybe make LLAddr per-TC? */
222 376 target_ulong CP0_LLAddr;
223 377 target_ulong CP0_WatchLo[8];
224 378 int32_t CP0_WatchHi[8];
225 379 target_ulong CP0_XContext;
226 380 int32_t CP0_Framemask;
227 381 int32_t CP0_Debug;
228   -#define CPDB_DBD 31
  382 +#define CP0DB_DBD 31
229 383 #define CP0DB_DM 30
230 384 #define CP0DB_LSNM 28
231 385 #define CP0DB_Doze 27
... ... @@ -243,6 +397,7 @@ struct CPUMIPSState {
243 397 #define CP0DB_DDBL 2
244 398 #define CP0DB_DBp 1
245 399 #define CP0DB_DSS 0
  400 + int32_t CP0_Debug_tcstatus[MIPS_TC_MAX];
246 401 target_ulong CP0_DEPC;
247 402 int32_t CP0_Performance0;
248 403 int32_t CP0_TagLo;
... ... @@ -284,7 +439,8 @@ struct CPUMIPSState {
284 439  
285 440 int SYNCI_Step; /* Address step size for SYNCI */
286 441 int CCRes; /* Cycle count resolution/divisor */
287   - int Status_rw_bitmask; /* Read/write bits in CP0_Status */
  442 + uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */
  443 + uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
288 444  
289 445 #ifdef CONFIG_USER_ONLY
290 446 target_ulong tls_value;
... ... @@ -376,6 +532,7 @@ enum {
376 532 EXCP_TLBS,
377 533 EXCP_DBE,
378 534 EXCP_DDBL,
  535 + EXCP_THREAD,
379 536 EXCP_MTCP0 = 0x104, /* mtmsr instruction: */
380 537 /* may change privilege level */
381 538 EXCP_BRANCH = 0x108, /* branch instruction */
... ...
target-mips/exec.h
... ... @@ -23,24 +23,24 @@ register target_ulong T2 asm(AREG3);
23 23 #if defined (USE_HOST_FLOAT_REGS)
24 24 #error "implement me."
25 25 #else
26   -#define FDT0 (env->ft0.fd)
27   -#define FDT1 (env->ft1.fd)
28   -#define FDT2 (env->ft2.fd)
29   -#define FST0 (env->ft0.fs[FP_ENDIAN_IDX])
30   -#define FST1 (env->ft1.fs[FP_ENDIAN_IDX])
31   -#define FST2 (env->ft2.fs[FP_ENDIAN_IDX])
32   -#define FSTH0 (env->ft0.fs[!FP_ENDIAN_IDX])
33   -#define FSTH1 (env->ft1.fs[!FP_ENDIAN_IDX])
34   -#define FSTH2 (env->ft2.fs[!FP_ENDIAN_IDX])
35   -#define DT0 (env->ft0.d)
36   -#define DT1 (env->ft1.d)
37   -#define DT2 (env->ft2.d)
38   -#define WT0 (env->ft0.w[FP_ENDIAN_IDX])
39   -#define WT1 (env->ft1.w[FP_ENDIAN_IDX])
40   -#define WT2 (env->ft2.w[FP_ENDIAN_IDX])
41   -#define WTH0 (env->ft0.w[!FP_ENDIAN_IDX])
42   -#define WTH1 (env->ft1.w[!FP_ENDIAN_IDX])
43   -#define WTH2 (env->ft2.w[!FP_ENDIAN_IDX])
  26 +#define FDT0 (env->fpu->ft0.fd)
  27 +#define FDT1 (env->fpu->ft1.fd)
  28 +#define FDT2 (env->fpu->ft2.fd)
  29 +#define FST0 (env->fpu->ft0.fs[FP_ENDIAN_IDX])
  30 +#define FST1 (env->fpu->ft1.fs[FP_ENDIAN_IDX])
  31 +#define FST2 (env->fpu->ft2.fs[FP_ENDIAN_IDX])
  32 +#define FSTH0 (env->fpu->ft0.fs[!FP_ENDIAN_IDX])
  33 +#define FSTH1 (env->fpu->ft1.fs[!FP_ENDIAN_IDX])
  34 +#define FSTH2 (env->fpu->ft2.fs[!FP_ENDIAN_IDX])
  35 +#define DT0 (env->fpu->ft0.d)
  36 +#define DT1 (env->fpu->ft1.d)
  37 +#define DT2 (env->fpu->ft2.d)
  38 +#define WT0 (env->fpu->ft0.w[FP_ENDIAN_IDX])
  39 +#define WT1 (env->fpu->ft1.w[FP_ENDIAN_IDX])
  40 +#define WT2 (env->fpu->ft2.w[FP_ENDIAN_IDX])
  41 +#define WTH0 (env->fpu->ft0.w[!FP_ENDIAN_IDX])
  42 +#define WTH1 (env->fpu->ft1.w[!FP_ENDIAN_IDX])
  43 +#define WTH2 (env->fpu->ft2.w[!FP_ENDIAN_IDX])
44 44 #endif
45 45  
46 46 #if defined (DEBUG_OP)
... ... @@ -157,7 +157,8 @@ void cpu_mips_update_irq (CPUState *env);
157 157 void cpu_mips_clock_init (CPUState *env);
158 158 void cpu_mips_tlb_flush (CPUState *env, int flush_global);
159 159  
160   -void do_ctc1 (void);
  160 +void do_cfc1 (int reg);
  161 +void do_ctc1 (int reg);
161 162  
162 163 #define FOP_PROTO(op) \
163 164 void do_float_ ## op ## _s(void); \
... ...
target-mips/fop_template.c
... ... @@ -24,14 +24,14 @@
24 24 #define OP_WLOAD_FREG(treg, tregname, FREG) \
25 25 void glue(glue(op_load_fpr_,tregname), FREG) (void) \
26 26 { \
27   - treg = env->fpr[FREG].fs[FP_ENDIAN_IDX]; \
  27 + treg = env->fpu->fpr[FREG].fs[FP_ENDIAN_IDX]; \
28 28 RETURN(); \
29 29 }
30 30  
31 31 #define OP_WSTORE_FREG(treg, tregname, FREG) \
32 32 void glue(glue(op_store_fpr_,tregname), FREG) (void) \
33 33 { \
34   - env->fpr[FREG].fs[FP_ENDIAN_IDX] = treg; \
  34 + env->fpu->fpr[FREG].fs[FP_ENDIAN_IDX] = treg; \
35 35 RETURN(); \
36 36 }
37 37  
... ... @@ -50,10 +50,10 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
50 50 void glue(glue(op_load_fpr_,tregname), FREG) (void) \
51 51 { \
52 52 if (env->hflags & MIPS_HFLAG_F64) \
53   - treg = env->fpr[FREG].fd; \
  53 + treg = env->fpu->fpr[FREG].fd; \
54 54 else \
55   - treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
56   - env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
  55 + treg = (uint64_t)(env->fpu->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
  56 + env->fpu->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
57 57 RETURN(); \
58 58 }
59 59  
... ... @@ -61,10 +61,10 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
61 61 void glue(glue(op_store_fpr_,tregname), FREG) (void) \
62 62 { \
63 63 if (env->hflags & MIPS_HFLAG_F64) \
64   - env->fpr[FREG].fd = treg; \
  64 + env->fpu->fpr[FREG].fd = treg; \
65 65 else { \
66   - env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
67   - env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg; \
  66 + env->fpu->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
  67 + env->fpu->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg; \
68 68 } \
69 69 RETURN(); \
70 70 }
... ... @@ -81,14 +81,14 @@ OP_DSTORE_FREG(DT2, DT2_fpr, FREG)
81 81 #define OP_PSLOAD_FREG(treg, tregname, FREG) \
82 82 void glue(glue(op_load_fpr_,tregname), FREG) (void) \
83 83 { \
84   - treg = env->fpr[FREG].fs[!FP_ENDIAN_IDX]; \
  84 + treg = env->fpu->fpr[FREG].fs[!FP_ENDIAN_IDX]; \
85 85 RETURN(); \
86 86 }
87 87  
88 88 #define OP_PSSTORE_FREG(treg, tregname, FREG) \
89 89 void glue(glue(op_store_fpr_,tregname), FREG) (void) \
90 90 { \
91   - env->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg; \
  91 + env->fpu->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg; \
92 92 RETURN(); \
93 93 }
94 94  
... ...
target-mips/helper.c
... ... @@ -70,8 +70,8 @@ int r4k_map_address (CPUState *env, target_ulong *physical, int *prot,
70 70 uint8_t ASID = env->CP0_EntryHi & 0xFF;
71 71 int i;
72 72  
73   - for (i = 0; i < env->tlb_in_use; i++) {
74   - r4k_tlb_t *tlb = &env->mmu.r4k.tlb[i];
  73 + for (i = 0; i < env->tlb->tlb_in_use; i++) {
  74 + r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i];
75 75 /* 1k pages are not supported. */
76 76 target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
77 77 target_ulong tag = address & ~mask;
... ... @@ -134,7 +134,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
134 134 *physical = address & 0xFFFFFFFF;
135 135 *prot = PAGE_READ | PAGE_WRITE;
136 136 } else {
137   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  137 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
138 138 }
139 139 #ifdef TARGET_MIPS64
140 140 /*
... ... @@ -144,14 +144,14 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
144 144 } else if (address < 0x3FFFFFFFFFFFFFFFULL) {
145 145 /* xuseg */
146 146 if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
147   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  147 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
148 148 } else {
149 149 ret = TLBRET_BADADDR;
150 150 }
151 151 } else if (address < 0x7FFFFFFFFFFFFFFFULL) {
152 152 /* xsseg */
153 153 if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
154   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  154 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
155 155 } else {
156 156 ret = TLBRET_BADADDR;
157 157 }
... ... @@ -169,7 +169,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
169 169 /* xkseg */
170 170 /* XXX: check supervisor mode */
171 171 if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
172   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  172 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
173 173 } else {
174 174 ret = TLBRET_BADADDR;
175 175 }
... ... @@ -186,12 +186,12 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
186 186 *prot = PAGE_READ | PAGE_WRITE;
187 187 } else if (address < (int32_t)0xE0000000UL) {
188 188 /* kseg2 */
189   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  189 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
190 190 } else {
191 191 /* kseg3 */
192 192 /* XXX: check supervisor mode */
193 193 /* XXX: debug segment is not emulated */
194   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  194 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
195 195 }
196 196 #if 0
197 197 if (logfile) {
... ... @@ -238,7 +238,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
238 238 cpu_dump_state(env, logfile, fprintf, 0);
239 239 #endif
240 240 fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d is_user %d smmu %d\n",
241   - __func__, env->PC, address, rw, is_user, is_softmmu);
  241 + __func__, env->PC[env->current_tc], address, rw, is_user, is_softmmu);
242 242 }
243 243  
244 244 rw &= 1;
... ... @@ -328,7 +328,7 @@ void do_interrupt (CPUState *env)
328 328  
329 329 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
330 330 fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n",
331   - __func__, env->PC, env->CP0_EPC, cause, env->exception_index);
  331 + __func__, env->PC[env->current_tc], env->CP0_EPC, cause, env->exception_index);
332 332 }
333 333 if (env->exception_index == EXCP_EXT_INTERRUPT &&
334 334 (env->hflags & MIPS_HFLAG_DM))
... ... @@ -342,7 +342,7 @@ void do_interrupt (CPUState *env)
342 342 * (but we assume the pc has always been updated during
343 343 * code translation).
344 344 */
345   - env->CP0_DEPC = env->PC;
  345 + env->CP0_DEPC = env->PC[env->current_tc];
346 346 goto enter_debug_mode;
347 347 case EXCP_DINT:
348 348 env->CP0_Debug |= 1 << CP0DB_DINT;
... ... @@ -362,10 +362,10 @@ void do_interrupt (CPUState *env)
362 362 if (env->hflags & MIPS_HFLAG_BMASK) {
363 363 /* If the exception was raised from a delay slot,
364 364 come back to the jump. */
365   - env->CP0_DEPC = env->PC - 4;
  365 + env->CP0_DEPC = env->PC[env->current_tc] - 4;
366 366 env->hflags &= ~MIPS_HFLAG_BMASK;
367 367 } else {
368   - env->CP0_DEPC = env->PC;
  368 + env->CP0_DEPC = env->PC[env->current_tc];
369 369 }
370 370 enter_debug_mode:
371 371 env->hflags |= MIPS_HFLAG_DM;
... ... @@ -375,7 +375,7 @@ void do_interrupt (CPUState *env)
375 375 /* EJTAG probe trap enable is not implemented... */
376 376 if (!(env->CP0_Status & (1 << CP0St_EXL)))
377 377 env->CP0_Cause &= ~(1 << CP0Ca_BD);
378   - env->PC = (int32_t)0xBFC00480;
  378 + env->PC[env->current_tc] = (int32_t)0xBFC00480;
379 379 break;
380 380 case EXCP_RESET:
381 381 cpu_reset(env);
... ... @@ -390,10 +390,10 @@ void do_interrupt (CPUState *env)
390 390 if (env->hflags & MIPS_HFLAG_BMASK) {
391 391 /* If the exception was raised from a delay slot,
392 392 come back to the jump. */
393   - env->CP0_ErrorEPC = env->PC - 4;
  393 + env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
394 394 env->hflags &= ~MIPS_HFLAG_BMASK;
395 395 } else {
396   - env->CP0_ErrorEPC = env->PC;
  396 + env->CP0_ErrorEPC = env->PC[env->current_tc];
397 397 }
398 398 env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
399 399 if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
... ... @@ -401,7 +401,7 @@ void do_interrupt (CPUState *env)
401 401 env->hflags &= ~MIPS_HFLAG_UM;
402 402 if (!(env->CP0_Status & (1 << CP0St_EXL)))
403 403 env->CP0_Cause &= ~(1 << CP0Ca_BD);
404   - env->PC = (int32_t)0xBFC00000;
  404 + env->PC[env->current_tc] = (int32_t)0xBFC00000;
405 405 break;
406 406 case EXCP_MCHECK:
407 407 cause = 24;
... ... @@ -471,6 +471,9 @@ void do_interrupt (CPUState *env)
471 471 goto set_EPC;
472 472 case EXCP_TLBS:
473 473 cause = 3;
  474 + goto set_EPC;
  475 + case EXCP_THREAD:
  476 + cause = 25;
474 477 if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
475 478 #ifdef TARGET_MIPS64
476 479 int R = env->CP0_BadVAddr >> 62;
... ... @@ -489,10 +492,10 @@ void do_interrupt (CPUState *env)
489 492 if (env->hflags & MIPS_HFLAG_BMASK) {
490 493 /* If the exception was raised from a delay slot,
491 494 come back to the jump. */
492   - env->CP0_EPC = env->PC - 4;
  495 + env->CP0_EPC = env->PC[env->current_tc] - 4;
493 496 env->CP0_Cause |= (1 << CP0Ca_BD);
494 497 } else {
495   - env->CP0_EPC = env->PC;
  498 + env->CP0_EPC = env->PC[env->current_tc];
496 499 env->CP0_Cause &= ~(1 << CP0Ca_BD);
497 500 }
498 501 env->CP0_Status |= (1 << CP0St_EXL);
... ... @@ -502,11 +505,11 @@ void do_interrupt (CPUState *env)
502 505 }
503 506 env->hflags &= ~MIPS_HFLAG_BMASK;
504 507 if (env->CP0_Status & (1 << CP0St_BEV)) {
505   - env->PC = (int32_t)0xBFC00200;
  508 + env->PC[env->current_tc] = (int32_t)0xBFC00200;
506 509 } else {
507   - env->PC = (int32_t)(env->CP0_EBase & ~0x3ff);
  510 + env->PC[env->current_tc] = (int32_t)(env->CP0_EBase & ~0x3ff);
508 511 }
509   - env->PC += offset;
  512 + env->PC[env->current_tc] += offset;
510 513 env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
511 514 break;
512 515 default:
... ... @@ -520,7 +523,7 @@ void do_interrupt (CPUState *env)
520 523 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
521 524 fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n"
522 525 " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n",
523   - __func__, env->PC, env->CP0_EPC, cause, env->exception_index,
  526 + __func__, env->PC[env->current_tc], env->CP0_EPC, cause, env->exception_index,
524 527 env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
525 528 env->CP0_DEPC);
526 529 }
... ... @@ -536,19 +539,19 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra)
536 539 uint8_t ASID = env->CP0_EntryHi & 0xFF;
537 540 target_ulong mask;
538 541  
539   - tlb = &env->mmu.r4k.tlb[idx];
  542 + tlb = &env->tlb->mmu.r4k.tlb[idx];
540 543 /* The qemu TLB is flushed when the ASID changes, so no need to
541 544 flush these entries again. */
542 545 if (tlb->G == 0 && tlb->ASID != ASID) {
543 546 return;
544 547 }
545 548  
546   - if (use_extra && env->tlb_in_use < MIPS_TLB_MAX) {
  549 + if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) {
547 550 /* For tlbwr, we can shadow the discarded entry into
548 551 a new (fake) TLB entry, as long as the guest can not
549 552 tell that it's there. */
550   - env->mmu.r4k.tlb[env->tlb_in_use] = *tlb;
551   - env->tlb_in_use++;
  553 + env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb;
  554 + env->tlb->tlb_in_use++;
552 555 return;
553 556 }
554 557  
... ...
target-mips/op.c
... ... @@ -254,25 +254,25 @@ void op_dup_T0 (void)
254 254  
255 255 void op_load_HI (void)
256 256 {
257   - T0 = env->HI;
  257 + T0 = env->HI[PARAM1][env->current_tc];
258 258 RETURN();
259 259 }
260 260  
261 261 void op_store_HI (void)
262 262 {
263   - env->HI = T0;
  263 + env->HI[PARAM1][env->current_tc] = T0;
264 264 RETURN();
265 265 }
266 266  
267 267 void op_load_LO (void)
268 268 {
269   - T0 = env->LO;
  269 + T0 = env->LO[PARAM1][env->current_tc];
270 270 RETURN();
271 271 }
272 272  
273 273 void op_store_LO (void)
274 274 {
275   - env->LO = T0;
  275 + env->LO[PARAM1][env->current_tc] = T0;
276 276 RETURN();
277 277 }
278 278  
... ... @@ -363,8 +363,8 @@ void op_div (void)
363 363 void op_div (void)
364 364 {
365 365 if (T1 != 0) {
366   - env->LO = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
367   - env->HI = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
  366 + env->LO[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
  367 + env->HI[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
368 368 }
369 369 RETURN();
370 370 }
... ... @@ -373,8 +373,8 @@ void op_div (void)
373 373 void op_divu (void)
374 374 {
375 375 if (T1 != 0) {
376   - env->LO = (int32_t)((uint32_t)T0 / (uint32_t)T1);
377   - env->HI = (int32_t)((uint32_t)T0 % (uint32_t)T1);
  376 + env->LO[0][env->current_tc] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
  377 + env->HI[0][env->current_tc] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
378 378 }
379 379 RETURN();
380 380 }
... ... @@ -442,8 +442,8 @@ void op_ddivu (void)
442 442 void op_ddivu (void)
443 443 {
444 444 if (T1 != 0) {
445   - env->LO = T0 / T1;
446   - env->HI = T0 % T1;
  445 + env->LO[0][env->current_tc] = T0 / T1;
  446 + env->HI[0][env->current_tc] = T0 % T1;
447 447 }
448 448 RETURN();
449 449 }
... ... @@ -814,13 +814,14 @@ void op_msubu (void)
814 814  
815 815 static inline uint64_t get_HILO (void)
816 816 {
817   - return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO);
  817 + return ((uint64_t)env->HI[0][env->current_tc] << 32) |
  818 + ((uint64_t)(uint32_t)env->LO[0][env->current_tc]);
818 819 }
819 820  
820 821 static inline void set_HILO (uint64_t HILO)
821 822 {
822   - env->LO = (int32_t)(HILO & 0xFFFFFFFF);
823   - env->HI = (int32_t)(HILO >> 32);
  823 + env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
  824 + env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
824 825 }
825 826  
826 827 void op_mult (void)
... ... @@ -875,13 +876,13 @@ void op_msubu (void)
875 876 #ifdef TARGET_MIPS64
876 877 void op_dmult (void)
877 878 {
878   - CALL_FROM_TB4(muls64, &(env->HI), &(env->LO), T0, T1);
  879 + CALL_FROM_TB4(muls64, &(env->HI[0][env->current_tc]), &(env->LO[0][env->current_tc]), T0, T1);
879 880 RETURN();
880 881 }
881 882  
882 883 void op_dmultu (void)
883 884 {
884   - CALL_FROM_TB4(mulu64, &(env->HI), &(env->LO), T0, T1);
  885 + CALL_FROM_TB4(mulu64, &(env->HI[0][env->current_tc]), &(env->LO[0][env->current_tc]), T0, T1);
885 886 RETURN();
886 887 }
887 888 #endif
... ... @@ -890,27 +891,27 @@ void op_dmultu (void)
890 891 void op_movn (void)
891 892 {
892 893 if (T1 != 0)
893   - env->gpr[PARAM1] = T0;
  894 + env->gpr[PARAM1][env->current_tc] = T0;
894 895 RETURN();
895 896 }
896 897  
897 898 void op_movz (void)
898 899 {
899 900 if (T1 == 0)
900   - env->gpr[PARAM1] = T0;
  901 + env->gpr[PARAM1][env->current_tc] = T0;
901 902 RETURN();
902 903 }
903 904  
904 905 void op_movf (void)
905 906 {
906   - if (!(env->fcr31 & PARAM1))
  907 + if (!(env->fpu->fcr31 & PARAM1))
907 908 T0 = T1;
908 909 RETURN();
909 910 }
910 911  
911 912 void op_movt (void)
912 913 {
913   - if (env->fcr31 & PARAM1)
  914 + if (env->fpu->fcr31 & PARAM1)
914 915 T0 = T1;
915 916 RETURN();
916 917 }
... ... @@ -966,7 +967,7 @@ void op_restore_breg_target (void)
966 967  
967 968 void op_breg (void)
968 969 {
969   - env->PC = T2;
  970 + env->PC[env->current_tc] = T2;
970 971 RETURN();
971 972 }
972 973  
... ... @@ -1017,18 +1018,176 @@ void op_mfc0_index (void)
1017 1018 RETURN();
1018 1019 }
1019 1020  
  1021 +void op_mfc0_mvpcontrol (void)
  1022 +{
  1023 + T0 = env->mvp->CP0_MVPControl;
  1024 + RETURN();
  1025 +}
  1026 +
  1027 +void op_mfc0_mvpconf0 (void)
  1028 +{
  1029 + T0 = env->mvp->CP0_MVPConf0;
  1030 + RETURN();
  1031 +}
  1032 +
  1033 +void op_mfc0_mvpconf1 (void)
  1034 +{
  1035 + T0 = env->mvp->CP0_MVPConf1;
  1036 + RETURN();
  1037 +}
  1038 +
1020 1039 void op_mfc0_random (void)
1021 1040 {
1022 1041 CALL_FROM_TB0(do_mfc0_random);
1023 1042 RETURN();
1024 1043 }
1025 1044  
  1045 +void op_mfc0_vpecontrol (void)
  1046 +{
  1047 + T0 = env->CP0_VPEControl;
  1048 + RETURN();
  1049 +}
  1050 +
  1051 +void op_mfc0_vpeconf0 (void)
  1052 +{
  1053 + T0 = env->CP0_VPEConf0;
  1054 + RETURN();
  1055 +}
  1056 +
  1057 +void op_mfc0_vpeconf1 (void)
  1058 +{
  1059 + T0 = env->CP0_VPEConf1;
  1060 + RETURN();
  1061 +}
  1062 +
  1063 +void op_mfc0_yqmask (void)
  1064 +{
  1065 + T0 = env->CP0_YQMask;
  1066 + RETURN();
  1067 +}
  1068 +
  1069 +void op_mfc0_vpeschedule (void)
  1070 +{
  1071 + T0 = env->CP0_VPESchedule;
  1072 + RETURN();
  1073 +}
  1074 +
  1075 +void op_mfc0_vpeschefback (void)
  1076 +{
  1077 + T0 = env->CP0_VPEScheFBack;
  1078 + RETURN();
  1079 +}
  1080 +
  1081 +void op_mfc0_vpeopt (void)
  1082 +{
  1083 + T0 = env->CP0_VPEOpt;
  1084 + RETURN();
  1085 +}
  1086 +
1026 1087 void op_mfc0_entrylo0 (void)
1027 1088 {
1028 1089 T0 = (int32_t)env->CP0_EntryLo0;
1029 1090 RETURN();
1030 1091 }
1031 1092  
  1093 +void op_mfc0_tcstatus (void)
  1094 +{
  1095 + T0 = env->CP0_TCStatus[env->current_tc];
  1096 + RETURN();
  1097 +}
  1098 +
  1099 +void op_mftc0_tcstatus(void)
  1100 +{
  1101 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1102 +
  1103 + T0 = env->CP0_TCStatus[other_tc];
  1104 + RETURN();
  1105 +}
  1106 +
  1107 +void op_mfc0_tcbind (void)
  1108 +{
  1109 + T0 = env->CP0_TCBind[env->current_tc];
  1110 + RETURN();
  1111 +}
  1112 +
  1113 +void op_mftc0_tcbind(void)
  1114 +{
  1115 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1116 +
  1117 + T0 = env->CP0_TCBind[other_tc];
  1118 + RETURN();
  1119 +}
  1120 +
  1121 +void op_mfc0_tcrestart (void)
  1122 +{
  1123 + T0 = env->PC[env->current_tc];
  1124 + RETURN();
  1125 +}
  1126 +
  1127 +void op_mftc0_tcrestart(void)
  1128 +{
  1129 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1130 +
  1131 + T0 = env->PC[other_tc];
  1132 + RETURN();
  1133 +}
  1134 +
  1135 +void op_mfc0_tchalt (void)
  1136 +{
  1137 + T0 = env->CP0_TCHalt[env->current_tc];
  1138 + RETURN();
  1139 +}
  1140 +
  1141 +void op_mftc0_tchalt(void)
  1142 +{
  1143 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1144 +
  1145 + T0 = env->CP0_TCHalt[other_tc];
  1146 + RETURN();
  1147 +}
  1148 +
  1149 +void op_mfc0_tccontext (void)
  1150 +{
  1151 + T0 = env->CP0_TCContext[env->current_tc];
  1152 + RETURN();
  1153 +}
  1154 +
  1155 +void op_mftc0_tccontext(void)
  1156 +{
  1157 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1158 +
  1159 + T0 = env->CP0_TCContext[other_tc];
  1160 + RETURN();
  1161 +}
  1162 +
  1163 +void op_mfc0_tcschedule (void)
  1164 +{
  1165 + T0 = env->CP0_TCSchedule[env->current_tc];
  1166 + RETURN();
  1167 +}
  1168 +
  1169 +void op_mftc0_tcschedule(void)
  1170 +{
  1171 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1172 +
  1173 + T0 = env->CP0_TCSchedule[other_tc];
  1174 + RETURN();
  1175 +}
  1176 +
  1177 +void op_mfc0_tcschefback (void)
  1178 +{
  1179 + T0 = env->CP0_TCScheFBack[env->current_tc];
  1180 + RETURN();
  1181 +}
  1182 +
  1183 +void op_mftc0_tcschefback(void)
  1184 +{
  1185 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1186 +
  1187 + T0 = env->CP0_TCScheFBack[other_tc];
  1188 + RETURN();
  1189 +}
  1190 +
1032 1191 void op_mfc0_entrylo1 (void)
1033 1192 {
1034 1193 T0 = (int32_t)env->CP0_EntryLo1;
... ... @@ -1059,6 +1218,36 @@ void op_mfc0_wired (void)
1059 1218 RETURN();
1060 1219 }
1061 1220  
  1221 +void op_mfc0_srsconf0 (void)
  1222 +{
  1223 + T0 = env->CP0_SRSConf0;
  1224 + RETURN();
  1225 +}
  1226 +
  1227 +void op_mfc0_srsconf1 (void)
  1228 +{
  1229 + T0 = env->CP0_SRSConf1;
  1230 + RETURN();
  1231 +}
  1232 +
  1233 +void op_mfc0_srsconf2 (void)
  1234 +{
  1235 + T0 = env->CP0_SRSConf2;
  1236 + RETURN();
  1237 +}
  1238 +
  1239 +void op_mfc0_srsconf3 (void)
  1240 +{
  1241 + T0 = env->CP0_SRSConf3;
  1242 + RETURN();
  1243 +}
  1244 +
  1245 +void op_mfc0_srsconf4 (void)
  1246 +{
  1247 + T0 = env->CP0_SRSConf4;
  1248 + RETURN();
  1249 +}
  1250 +
1062 1251 void op_mfc0_hwrena (void)
1063 1252 {
1064 1253 T0 = env->CP0_HWREna;
... ... @@ -1083,6 +1272,14 @@ void op_mfc0_entryhi (void)
1083 1272 RETURN();
1084 1273 }
1085 1274  
  1275 +void op_mftc0_entryhi(void)
  1276 +{
  1277 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1278 +
  1279 + T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
  1280 + RETURN();
  1281 +}
  1282 +
1086 1283 void op_mfc0_compare (void)
1087 1284 {
1088 1285 T0 = env->CP0_Compare;
... ... @@ -1095,6 +1292,18 @@ void op_mfc0_status (void)
1095 1292 RETURN();
1096 1293 }
1097 1294  
  1295 +void op_mftc0_status(void)
  1296 +{
  1297 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1298 + uint32_t tcstatus = env->CP0_TCStatus[other_tc];
  1299 +
  1300 + T0 = env->CP0_Status & ~0xf1000018;
  1301 + T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
  1302 + T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
  1303 + T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_R0);
  1304 + RETURN();
  1305 +}
  1306 +
1098 1307 void op_mfc0_intctl (void)
1099 1308 {
1100 1309 T0 = env->CP0_IntCtl;
... ... @@ -1211,6 +1420,17 @@ void op_mfc0_debug (void)
1211 1420 RETURN();
1212 1421 }
1213 1422  
  1423 +void op_mftc0_debug(void)
  1424 +{
  1425 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1426 +
  1427 + /* XXX: Might be wrong, check with EJTAG spec. */
  1428 + T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
  1429 + (env->CP0_Debug_tcstatus[other_tc] &
  1430 + ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
  1431 + RETURN();
  1432 +}
  1433 +
1214 1434 void op_mfc0_depc (void)
1215 1435 {
1216 1436 T0 = (int32_t)env->CP0_DEPC;
... ... @@ -1261,7 +1481,105 @@ void op_mfc0_desave (void)
1261 1481  
1262 1482 void op_mtc0_index (void)
1263 1483 {
1264   - env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 % env->nb_tlb);
  1484 + env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 % env->tlb->nb_tlb);
  1485 + RETURN();
  1486 +}
  1487 +
  1488 +void op_mtc0_mvpcontrol (void)
  1489 +{
  1490 + uint32_t mask = 0;
  1491 + uint32_t newval;
  1492 +
  1493 + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
  1494 + mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
  1495 + (1 << CP0MVPCo_EVP);
  1496 + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
  1497 + mask |= (1 << CP0MVPCo_STLB);
  1498 + newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
  1499 +
  1500 + // TODO: Enable/disable shared TLB, enable/disable VPEs.
  1501 +
  1502 + env->mvp->CP0_MVPControl = newval;
  1503 + RETURN();
  1504 +}
  1505 +
  1506 +void op_mtc0_vpecontrol (void)
  1507 +{
  1508 + uint32_t mask;
  1509 + uint32_t newval;
  1510 +
  1511 + mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
  1512 + (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
  1513 + newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
  1514 +
  1515 + /* Yield scheduler intercept not implemented. */
  1516 + /* Gating storage scheduler intercept not implemented. */
  1517 +
  1518 + // TODO: Enable/disable TCs.
  1519 +
  1520 + env->CP0_VPEControl = newval;
  1521 + RETURN();
  1522 +}
  1523 +
  1524 +void op_mtc0_vpeconf0 (void)
  1525 +{
  1526 + uint32_t mask = 0;
  1527 + uint32_t newval;
  1528 +
  1529 + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
  1530 + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
  1531 + mask |= (0xff << CP0VPEC0_XTC);
  1532 + mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
  1533 + }
  1534 + newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
  1535 +
  1536 + // TODO: TC exclusive handling due to ERL/EXL.
  1537 +
  1538 + env->CP0_VPEConf0 = newval;
  1539 + RETURN();
  1540 +}
  1541 +
  1542 +void op_mtc0_vpeconf1 (void)
  1543 +{
  1544 + uint32_t mask = 0;
  1545 + uint32_t newval;
  1546 +
  1547 + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
  1548 + mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
  1549 + (0xff << CP0VPEC1_NCP1);
  1550 + newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
  1551 +
  1552 + /* UDI not implemented. */
  1553 + /* CP2 not implemented. */
  1554 +
  1555 + // TODO: Handle FPU (CP1) binding.
  1556 +
  1557 + env->CP0_VPEConf1 = newval;
  1558 + RETURN();
  1559 +}
  1560 +
  1561 +void op_mtc0_yqmask (void)
  1562 +{
  1563 + /* Yield qualifier inputs not implemented. */
  1564 + env->CP0_YQMask = 0x00000000;
  1565 + RETURN();
  1566 +}
  1567 +
  1568 +void op_mtc0_vpeschedule (void)
  1569 +{
  1570 + env->CP0_VPESchedule = T0;
  1571 + RETURN();
  1572 +}
  1573 +
  1574 +void op_mtc0_vpeschefback (void)
  1575 +{
  1576 + env->CP0_VPEScheFBack = T0;
  1577 + RETURN();
  1578 +}
  1579 +
  1580 +void op_mtc0_vpeopt (void)
  1581 +{
  1582 + env->CP0_VPEOpt = T0 & 0x0000ffff;
1265 1583 RETURN();
1266 1584 }
1267 1585  
... ... @@ -1273,6 +1591,135 @@ void op_mtc0_entrylo0 (void)
1273 1591 RETURN();
1274 1592 }
1275 1593  
  1594 +void op_mtc0_tcstatus (void)
  1595 +{
  1596 + uint32_t mask = env->CP0_TCStatus_rw_bitmask;
  1597 + uint32_t newval;
  1598 +
  1599 + newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
  1600 +
  1601 + // TODO: Sync with CP0_Status.
  1602 +
  1603 + env->CP0_TCStatus[env->current_tc] = newval;
  1604 + RETURN();
  1605 +}
  1606 +
  1607 +void op_mttc0_tcstatus (void)
  1608 +{
  1609 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1610 +
  1611 + // TODO: Sync with CP0_Status.
  1612 +
  1613 + env->CP0_TCStatus[other_tc] = T0;
  1614 + RETURN();
  1615 +}
  1616 +
  1617 +void op_mtc0_tcbind (void)
  1618 +{
  1619 + uint32_t mask = (1 << CP0TCBd_TBE);
  1620 + uint32_t newval;
  1621 +
  1622 + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
  1623 + mask |= (1 << CP0TCBd_CurVPE);
  1624 + newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
  1625 + env->CP0_TCBind[env->current_tc] = newval;
  1626 + RETURN();
  1627 +}
  1628 +
  1629 +void op_mttc0_tcbind (void)
  1630 +{
  1631 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1632 + uint32_t mask = (1 << CP0TCBd_TBE);
  1633 + uint32_t newval;
  1634 +
  1635 + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
  1636 + mask |= (1 << CP0TCBd_CurVPE);
  1637 + newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
  1638 + env->CP0_TCBind[other_tc] = newval;
  1639 + RETURN();
  1640 +}
  1641 +
  1642 +void op_mtc0_tcrestart (void)
  1643 +{
  1644 + env->PC[env->current_tc] = T0;
  1645 + env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
  1646 + env->CP0_LLAddr = 0ULL;
  1647 + /* MIPS16 not implemented. */
  1648 + RETURN();
  1649 +}
  1650 +
  1651 +void op_mttc0_tcrestart (void)
  1652 +{
  1653 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1654 +
  1655 + env->PC[other_tc] = T0;
  1656 + env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
  1657 + env->CP0_LLAddr = 0ULL;
  1658 + /* MIPS16 not implemented. */
  1659 + RETURN();
  1660 +}
  1661 +
  1662 +void op_mtc0_tchalt (void)
  1663 +{
  1664 + env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
  1665 +
  1666 + // TODO: Halt TC / Restart (if allocated+active) TC.
  1667 +
  1668 + RETURN();
  1669 +}
  1670 +
  1671 +void op_mttc0_tchalt (void)
  1672 +{
  1673 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1674 +
  1675 + // TODO: Halt TC / Restart (if allocated+active) TC.
  1676 +
  1677 + env->CP0_TCHalt[other_tc] = T0;
  1678 + RETURN();
  1679 +}
  1680 +
  1681 +void op_mtc0_tccontext (void)
  1682 +{
  1683 + env->CP0_TCContext[env->current_tc] = T0;
  1684 + RETURN();
  1685 +}
  1686 +
  1687 +void op_mttc0_tccontext (void)
  1688 +{
  1689 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1690 +
  1691 + env->CP0_TCContext[other_tc] = T0;
  1692 + RETURN();
  1693 +}
  1694 +
  1695 +void op_mtc0_tcschedule (void)
  1696 +{
  1697 + env->CP0_TCSchedule[env->current_tc] = T0;
  1698 + RETURN();
  1699 +}
  1700 +
  1701 +void op_mttc0_tcschedule (void)
  1702 +{
  1703 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1704 +
  1705 + env->CP0_TCSchedule[other_tc] = T0;
  1706 + RETURN();
  1707 +}
  1708 +
  1709 +void op_mtc0_tcschefback (void)
  1710 +{
  1711 + env->CP0_TCScheFBack[env->current_tc] = T0;
  1712 + RETURN();
  1713 +}
  1714 +
  1715 +void op_mttc0_tcschefback (void)
  1716 +{
  1717 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1718 +
  1719 + env->CP0_TCScheFBack[other_tc] = T0;
  1720 + RETURN();
  1721 +}
  1722 +
1276 1723 void op_mtc0_entrylo1 (void)
1277 1724 {
1278 1725 /* Large physaddr not implemented */
... ... @@ -1305,7 +1752,37 @@ void op_mtc0_pagegrain (void)
1305 1752  
1306 1753 void op_mtc0_wired (void)
1307 1754 {
1308   - env->CP0_Wired = T0 % env->nb_tlb;
  1755 + env->CP0_Wired = T0 % env->tlb->nb_tlb;
  1756 + RETURN();
  1757 +}
  1758 +
  1759 +void op_mtc0_srsconf0 (void)
  1760 +{
  1761 + env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
  1762 + RETURN();
  1763 +}
  1764 +
  1765 +void op_mtc0_srsconf1 (void)
  1766 +{
  1767 + env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
  1768 + RETURN();
  1769 +}
  1770 +
  1771 +void op_mtc0_srsconf2 (void)
  1772 +{
  1773 + env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
  1774 + RETURN();
  1775 +}
  1776 +
  1777 +void op_mtc0_srsconf3 (void)
  1778 +{
  1779 + env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
  1780 + RETURN();
  1781 +}
  1782 +
  1783 +void op_mtc0_srsconf4 (void)
  1784 +{
  1785 + env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1309 1786 RETURN();
1310 1787 }
1311 1788  
... ... @@ -1332,12 +1809,25 @@ void op_mtc0_entryhi (void)
1332 1809 #endif
1333 1810 old = env->CP0_EntryHi;
1334 1811 env->CP0_EntryHi = val;
  1812 + if (env->CP0_Config3 & (1 << CP0C3_MT)) {
  1813 + uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
  1814 + env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
  1815 + }
1335 1816 /* If the ASID changes, flush qemu's TLB. */
1336 1817 if ((old & 0xFF) != (val & 0xFF))
1337 1818 CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1338 1819 RETURN();
1339 1820 }
1340 1821  
  1822 +void op_mttc0_entryhi(void)
  1823 +{
  1824 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1825 +
  1826 + env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
  1827 + env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
  1828 + RETURN();
  1829 +}
  1830 +
1341 1831 void op_mtc0_compare (void)
1342 1832 {
1343 1833 CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
... ... @@ -1347,9 +1837,8 @@ void op_mtc0_compare (void)
1347 1837 void op_mtc0_status (void)
1348 1838 {
1349 1839 uint32_t val, old;
1350   - uint32_t mask = env->Status_rw_bitmask;
  1840 + uint32_t mask = env->CP0_Status_rw_bitmask;
1351 1841  
1352   - /* No reverse endianness, no MDMX/DSP implemented. */
1353 1842 val = T0 & mask;
1354 1843 old = env->CP0_Status;
1355 1844 if (!(val & (1 << CP0St_EXL)) &&
... ... @@ -1379,6 +1868,19 @@ void op_mtc0_status (void)
1379 1868 RETURN();
1380 1869 }
1381 1870  
  1871 +void op_mttc0_status(void)
  1872 +{
  1873 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1874 + uint32_t tcstatus = env->CP0_TCStatus[other_tc];
  1875 +
  1876 + env->CP0_Status = T0 & ~0xf1000018;
  1877 + tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
  1878 + tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
  1879 + tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_R0)) << (CP0TCSt_TKSU - CP0St_R0));
  1880 + env->CP0_TCStatus[other_tc] = tcstatus;
  1881 + RETURN();
  1882 +}
  1883 +
1382 1884 void op_mtc0_intctl (void)
1383 1885 {
1384 1886 /* vectored interrupts not implemented, timer on int 7,
... ... @@ -1389,15 +1891,14 @@ void op_mtc0_intctl (void)
1389 1891  
1390 1892 void op_mtc0_srsctl (void)
1391 1893 {
1392   - /* shadow registers not implemented */
1393   - env->CP0_SRSCtl = 0;
  1894 + uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
  1895 + env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1394 1896 RETURN();
1395 1897 }
1396 1898  
1397 1899 void op_mtc0_srsmap (void)
1398 1900 {
1399   - /* shadow registers not implemented */
1400   - env->CP0_SRSMap = 0;
  1901 + env->CP0_SRSMap = T0;
1401 1902 RETURN();
1402 1903 }
1403 1904  
... ... @@ -1460,6 +1961,13 @@ void op_mtc0_watchhi (void)
1460 1961 RETURN();
1461 1962 }
1462 1963  
  1964 +void op_mtc0_xcontext (void)
  1965 +{
  1966 + target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
  1967 + env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
  1968 + RETURN();
  1969 +}
  1970 +
1463 1971 void op_mtc0_framemask (void)
1464 1972 {
1465 1973 env->CP0_Framemask = T0; /* XXX */
... ... @@ -1476,6 +1984,17 @@ void op_mtc0_debug (void)
1476 1984 RETURN();
1477 1985 }
1478 1986  
  1987 +void op_mttc0_debug(void)
  1988 +{
  1989 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1990 +
  1991 + /* XXX: Might be wrong, check with EJTAG spec. */
  1992 + env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
  1993 + env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
  1994 + (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
  1995 + RETURN();
  1996 +}
  1997 +
1479 1998 void op_mtc0_depc (void)
1480 1999 {
1481 2000 env->CP0_DEPC = T0;
... ... @@ -1525,10 +2044,21 @@ void op_mtc0_desave (void)
1525 2044 }
1526 2045  
1527 2046 #ifdef TARGET_MIPS64
1528   -void op_mtc0_xcontext (void)
  2047 +void op_dmfc0_yqmask (void)
1529 2048 {
1530   - target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1531   - env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
  2049 + T0 = env->CP0_YQMask;
  2050 + RETURN();
  2051 +}
  2052 +
  2053 +void op_dmfc0_vpeschedule (void)
  2054 +{
  2055 + T0 = env->CP0_VPESchedule;
  2056 + RETURN();
  2057 +}
  2058 +
  2059 +void op_dmfc0_vpeschefback (void)
  2060 +{
  2061 + T0 = env->CP0_VPEScheFBack;
1532 2062 RETURN();
1533 2063 }
1534 2064  
... ... @@ -1538,6 +2068,36 @@ void op_dmfc0_entrylo0 (void)
1538 2068 RETURN();
1539 2069 }
1540 2070  
  2071 +void op_dmfc0_tcrestart (void)
  2072 +{
  2073 + T0 = env->PC[env->current_tc];
  2074 + RETURN();
  2075 +}
  2076 +
  2077 +void op_dmfc0_tchalt (void)
  2078 +{
  2079 + T0 = env->CP0_TCHalt[env->current_tc];
  2080 + RETURN();
  2081 +}
  2082 +
  2083 +void op_dmfc0_tccontext (void)
  2084 +{
  2085 + T0 = env->CP0_TCContext[env->current_tc];
  2086 + RETURN();
  2087 +}
  2088 +
  2089 +void op_dmfc0_tcschedule (void)
  2090 +{
  2091 + T0 = env->CP0_TCSchedule[env->current_tc];
  2092 + RETURN();
  2093 +}
  2094 +
  2095 +void op_dmfc0_tcschefback (void)
  2096 +{
  2097 + T0 = env->CP0_TCScheFBack[env->current_tc];
  2098 + RETURN();
  2099 +}
  2100 +
1541 2101 void op_dmfc0_entrylo1 (void)
1542 2102 {
1543 2103 T0 = env->CP0_EntryLo1;
... ... @@ -1599,6 +2159,157 @@ void op_dmfc0_errorepc (void)
1599 2159 }
1600 2160 #endif /* TARGET_MIPS64 */
1601 2161  
  2162 +/* MIPS MT functions */
  2163 +void op_mftgpr(void)
  2164 +{
  2165 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2166 +
  2167 + T0 = env->gpr[PARAM1][other_tc];
  2168 + RETURN();
  2169 +}
  2170 +
  2171 +void op_mftlo(void)
  2172 +{
  2173 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2174 +
  2175 + T0 = env->LO[PARAM1][other_tc];
  2176 + RETURN();
  2177 +}
  2178 +
  2179 +void op_mfthi(void)
  2180 +{
  2181 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2182 +
  2183 + T0 = env->HI[PARAM1][other_tc];
  2184 + RETURN();
  2185 +}
  2186 +
  2187 +void op_mftacx(void)
  2188 +{
  2189 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2190 +
  2191 + T0 = env->ACX[PARAM1][other_tc];
  2192 + RETURN();
  2193 +}
  2194 +
  2195 +void op_mftdsp(void)
  2196 +{
  2197 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2198 +
  2199 + T0 = env->DSPControl[other_tc];
  2200 + RETURN();
  2201 +}
  2202 +
  2203 +void op_mttgpr(void)
  2204 +{
  2205 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2206 +
  2207 + T0 = env->gpr[PARAM1][other_tc];
  2208 + RETURN();
  2209 +}
  2210 +
  2211 +void op_mttlo(void)
  2212 +{
  2213 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2214 +
  2215 + T0 = env->LO[PARAM1][other_tc];
  2216 + RETURN();
  2217 +}
  2218 +
  2219 +void op_mtthi(void)
  2220 +{
  2221 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2222 +
  2223 + T0 = env->HI[PARAM1][other_tc];
  2224 + RETURN();
  2225 +}
  2226 +
  2227 +void op_mttacx(void)
  2228 +{
  2229 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2230 +
  2231 + T0 = env->ACX[PARAM1][other_tc];
  2232 + RETURN();
  2233 +}
  2234 +
  2235 +void op_mttdsp(void)
  2236 +{
  2237 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2238 +
  2239 + T0 = env->DSPControl[other_tc];
  2240 + RETURN();
  2241 +}
  2242 +
  2243 +
  2244 +void op_dmt(void)
  2245 +{
  2246 + // TODO
  2247 + T0 = 0;
  2248 + // rt = T0
  2249 + RETURN();
  2250 +}
  2251 +
  2252 +void op_emt(void)
  2253 +{
  2254 + // TODO
  2255 + T0 = 0;
  2256 + // rt = T0
  2257 + RETURN();
  2258 +}
  2259 +
  2260 +void op_dvpe(void)
  2261 +{
  2262 + // TODO
  2263 + T0 = 0;
  2264 + // rt = T0
  2265 + RETURN();
  2266 +}
  2267 +
  2268 +void op_evpe(void)
  2269 +{
  2270 + // TODO
  2271 + T0 = 0;
  2272 + // rt = T0
  2273 + RETURN();
  2274 +}
  2275 +
  2276 +void op_fork(void)
  2277 +{
  2278 + // T0 = rt, T1 = rs
  2279 + T0 = 0;
  2280 + // TODO: store to TC register
  2281 + RETURN();
  2282 +}
  2283 +
  2284 +void op_yield(void)
  2285 +{
  2286 + if (T0 < 0) {
  2287 + /* No scheduling policy implemented. */
  2288 + if (T0 != -2) {
  2289 + if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
  2290 + env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
  2291 + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
  2292 + env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
  2293 + CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
  2294 + }
  2295 + }
  2296 + } else if (T0 == 0) {
  2297 + if (0 /* TODO: TC underflow */) {
  2298 + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
  2299 + CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
  2300 + } else {
  2301 + // TODO: Deallocate TC
  2302 + }
  2303 + } else if (T0 > 0) {
  2304 + /* Yield qualifier inputs not implemented. */
  2305 + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
  2306 + env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
  2307 + CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
  2308 + }
  2309 + T0 = env->CP0_YQMask;
  2310 + RETURN();
  2311 +}
  2312 +
1602 2313 /* CP1 functions */
1603 2314 #if 0
1604 2315 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
... ... @@ -1617,30 +2328,14 @@ void op_cp0_enabled(void)
1617 2328  
1618 2329 void op_cfc1 (void)
1619 2330 {
1620   - switch (T1) {
1621   - case 0:
1622   - T0 = (int32_t)env->fcr0;
1623   - break;
1624   - case 25:
1625   - T0 = ((env->fcr31 >> 24) & 0xfe) | ((env->fcr31 >> 23) & 0x1);
1626   - break;
1627   - case 26:
1628   - T0 = env->fcr31 & 0x0003f07c;
1629   - break;
1630   - case 28:
1631   - T0 = (env->fcr31 & 0x00000f83) | ((env->fcr31 >> 22) & 0x4);
1632   - break;
1633   - default:
1634   - T0 = (int32_t)env->fcr31;
1635   - break;
1636   - }
  2331 + CALL_FROM_TB1(do_cfc1, PARAM1);
1637 2332 DEBUG_FPU_STATE();
1638 2333 RETURN();
1639 2334 }
1640 2335  
1641 2336 void op_ctc1 (void)
1642 2337 {
1643   - CALL_FROM_TB0(do_ctc1);
  2338 + CALL_FROM_TB1(do_ctc1, PARAM1);
1644 2339 DEBUG_FPU_STATE();
1645 2340 RETURN();
1646 2341 }
... ... @@ -1842,21 +2537,21 @@ FLOAT_ROUNDOP(floor, w, s)
1842 2537  
1843 2538 FLOAT_OP(movf, d)
1844 2539 {
1845   - if (!(env->fcr31 & PARAM1))
  2540 + if (!(env->fpu->fcr31 & PARAM1))
1846 2541 DT2 = DT0;
1847 2542 DEBUG_FPU_STATE();
1848 2543 RETURN();
1849 2544 }
1850 2545 FLOAT_OP(movf, s)
1851 2546 {
1852   - if (!(env->fcr31 & PARAM1))
  2547 + if (!(env->fpu->fcr31 & PARAM1))
1853 2548 WT2 = WT0;
1854 2549 DEBUG_FPU_STATE();
1855 2550 RETURN();
1856 2551 }
1857 2552 FLOAT_OP(movf, ps)
1858 2553 {
1859   - if (!(env->fcr31 & PARAM1)) {
  2554 + if (!(env->fpu->fcr31 & PARAM1)) {
1860 2555 WT2 = WT0;
1861 2556 WTH2 = WTH0;
1862 2557 }
... ... @@ -1865,21 +2560,21 @@ FLOAT_OP(movf, ps)
1865 2560 }
1866 2561 FLOAT_OP(movt, d)
1867 2562 {
1868   - if (env->fcr31 & PARAM1)
  2563 + if (env->fpu->fcr31 & PARAM1)
1869 2564 DT2 = DT0;
1870 2565 DEBUG_FPU_STATE();
1871 2566 RETURN();
1872 2567 }
1873 2568 FLOAT_OP(movt, s)
1874 2569 {
1875   - if (env->fcr31 & PARAM1)
  2570 + if (env->fpu->fcr31 & PARAM1)
1876 2571 WT2 = WT0;
1877 2572 DEBUG_FPU_STATE();
1878 2573 RETURN();
1879 2574 }
1880 2575 FLOAT_OP(movt, ps)
1881 2576 {
1882   - if (env->fcr31 & PARAM1) {
  2577 + if (env->fpu->fcr31 & PARAM1) {
1883 2578 WT2 = WT0;
1884 2579 WTH2 = WTH0;
1885 2580 }
... ... @@ -1997,24 +2692,24 @@ FLOAT_HOP(mulr)
1997 2692 #define FLOAT_TERNOP(name1, name2) \
1998 2693 FLOAT_OP(name1 ## name2, d) \
1999 2694 { \
2000   - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status); \
2001   - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status); \
  2695 + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
  2696 + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2002 2697 DEBUG_FPU_STATE(); \
2003 2698 RETURN(); \
2004 2699 } \
2005 2700 FLOAT_OP(name1 ## name2, s) \
2006 2701 { \
2007   - FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2008   - FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
  2702 + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
  2703 + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2009 2704 DEBUG_FPU_STATE(); \
2010 2705 RETURN(); \
2011 2706 } \
2012 2707 FLOAT_OP(name1 ## name2, ps) \
2013 2708 { \
2014   - FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2015   - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
2016   - FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
2017   - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
  2709 + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
  2710 + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
  2711 + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
  2712 + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2018 2713 DEBUG_FPU_STATE(); \
2019 2714 RETURN(); \
2020 2715 }
... ... @@ -2026,26 +2721,26 @@ FLOAT_TERNOP(mul, sub)
2026 2721 #define FLOAT_NTERNOP(name1, name2) \
2027 2722 FLOAT_OP(n ## name1 ## name2, d) \
2028 2723 { \
2029   - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status); \
2030   - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status); \
  2724 + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
  2725 + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2031 2726 FDT2 ^= 1ULL << 63; \
2032 2727 DEBUG_FPU_STATE(); \
2033 2728 RETURN(); \
2034 2729 } \
2035 2730 FLOAT_OP(n ## name1 ## name2, s) \
2036 2731 { \
2037   - FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2038   - FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
  2732 + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
  2733 + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2039 2734 FST2 ^= 1 << 31; \
2040 2735 DEBUG_FPU_STATE(); \
2041 2736 RETURN(); \
2042 2737 } \
2043 2738 FLOAT_OP(n ## name1 ## name2, ps) \
2044 2739 { \
2045   - FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2046   - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
2047   - FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
2048   - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
  2740 + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
  2741 + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
  2742 + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
  2743 + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2049 2744 FST2 ^= 1 << 31; \
2050 2745 FSTH2 ^= 1 << 31; \
2051 2746 DEBUG_FPU_STATE(); \
... ... @@ -2059,13 +2754,13 @@ FLOAT_NTERNOP(mul, sub)
2059 2754 #define FLOAT_UNOP(name) \
2060 2755 FLOAT_OP(name, d) \
2061 2756 { \
2062   - FDT2 = float64_ ## name(FDT0, &env->fp_status); \
  2757 + FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2063 2758 DEBUG_FPU_STATE(); \
2064 2759 RETURN(); \
2065 2760 } \
2066 2761 FLOAT_OP(name, s) \
2067 2762 { \
2068   - FST2 = float32_ ## name(FST0, &env->fp_status); \
  2763 + FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2069 2764 DEBUG_FPU_STATE(); \
2070 2765 RETURN(); \
2071 2766 }
... ... @@ -2141,9 +2836,9 @@ FLOAT_OP(alnv, ps)
2141 2836  
2142 2837 #ifdef CONFIG_SOFTFLOAT
2143 2838 #define clear_invalid() do { \
2144   - int flags = get_float_exception_flags(&env->fp_status); \
  2839 + int flags = get_float_exception_flags(&env->fpu->fp_status); \
2145 2840 flags &= ~float_flag_invalid; \
2146   - set_float_exception_flags(flags, &env->fp_status); \
  2841 + set_float_exception_flags(flags, &env->fpu->fp_status); \
2147 2842 } while(0)
2148 2843 #else
2149 2844 #define clear_invalid() do { } while(0)
... ... @@ -2190,63 +2885,63 @@ CMP_OPS(ngt)
2190 2885  
2191 2886 void op_bc1f (void)
2192 2887 {
2193   - T0 = !!(~GET_FP_COND(env) & (0x1 << PARAM1));
  2888 + T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2194 2889 DEBUG_FPU_STATE();
2195 2890 RETURN();
2196 2891 }
2197 2892 void op_bc1any2f (void)
2198 2893 {
2199   - T0 = !!(~GET_FP_COND(env) & (0x3 << PARAM1));
  2894 + T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2200 2895 DEBUG_FPU_STATE();
2201 2896 RETURN();
2202 2897 }
2203 2898 void op_bc1any4f (void)
2204 2899 {
2205   - T0 = !!(~GET_FP_COND(env) & (0xf << PARAM1));
  2900 + T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
2206 2901 DEBUG_FPU_STATE();
2207 2902 RETURN();
2208 2903 }
2209 2904  
2210 2905 void op_bc1t (void)
2211 2906 {
2212   - T0 = !!(GET_FP_COND(env) & (0x1 << PARAM1));
  2907 + T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2213 2908 DEBUG_FPU_STATE();
2214 2909 RETURN();
2215 2910 }
2216 2911 void op_bc1any2t (void)
2217 2912 {
2218   - T0 = !!(GET_FP_COND(env) & (0x3 << PARAM1));
  2913 + T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2219 2914 DEBUG_FPU_STATE();
2220 2915 RETURN();
2221 2916 }
2222 2917 void op_bc1any4t (void)
2223 2918 {
2224   - T0 = !!(GET_FP_COND(env) & (0xf << PARAM1));
  2919 + T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2225 2920 DEBUG_FPU_STATE();
2226 2921 RETURN();
2227 2922 }
2228 2923  
2229 2924 void op_tlbwi (void)
2230 2925 {
2231   - CALL_FROM_TB0(env->do_tlbwi);
  2926 + CALL_FROM_TB0(env->tlb->do_tlbwi);
2232 2927 RETURN();
2233 2928 }
2234 2929  
2235 2930 void op_tlbwr (void)
2236 2931 {
2237   - CALL_FROM_TB0(env->do_tlbwr);
  2932 + CALL_FROM_TB0(env->tlb->do_tlbwr);
2238 2933 RETURN();
2239 2934 }
2240 2935  
2241 2936 void op_tlbp (void)
2242 2937 {
2243   - CALL_FROM_TB0(env->do_tlbp);
  2938 + CALL_FROM_TB0(env->tlb->do_tlbp);
2244 2939 RETURN();
2245 2940 }
2246 2941  
2247 2942 void op_tlbr (void)
2248 2943 {
2249   - CALL_FROM_TB0(env->do_tlbr);
  2944 + CALL_FROM_TB0(env->tlb->do_tlbr);
2250 2945 RETURN();
2251 2946 }
2252 2947  
... ... @@ -2307,10 +3002,10 @@ void op_eret (void)
2307 3002 if (loglevel & CPU_LOG_EXEC)
2308 3003 CALL_FROM_TB0(debug_pre_eret);
2309 3004 if (env->CP0_Status & (1 << CP0St_ERL)) {
2310   - env->PC = env->CP0_ErrorEPC;
  3005 + env->PC[env->current_tc] = env->CP0_ErrorEPC;
2311 3006 env->CP0_Status &= ~(1 << CP0St_ERL);
2312 3007 } else {
2313   - env->PC = env->CP0_EPC;
  3008 + env->PC[env->current_tc] = env->CP0_EPC;
2314 3009 env->CP0_Status &= ~(1 << CP0St_EXL);
2315 3010 }
2316 3011 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
... ... @@ -2335,7 +3030,7 @@ void op_deret (void)
2335 3030 {
2336 3031 if (loglevel & CPU_LOG_EXEC)
2337 3032 CALL_FROM_TB0(debug_pre_eret);
2338   - env->PC = env->CP0_DEPC;
  3033 + env->PC[env->current_tc] = env->CP0_DEPC;
2339 3034 env->hflags |= MIPS_HFLAG_DM;
2340 3035 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
2341 3036 !(env->CP0_Status & (1 << CP0St_ERL)) &&
... ... @@ -2407,14 +3102,14 @@ void op_save_state (void)
2407 3102  
2408 3103 void op_save_pc (void)
2409 3104 {
2410   - env->PC = PARAM1;
  3105 + env->PC[env->current_tc] = PARAM1;
2411 3106 RETURN();
2412 3107 }
2413 3108  
2414 3109 #ifdef TARGET_MIPS64
2415 3110 void op_save_pc64 (void)
2416 3111 {
2417   - env->PC = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
  3112 + env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
2418 3113 RETURN();
2419 3114 }
2420 3115 #endif
... ...
target-mips/op_helper.c
... ... @@ -160,13 +160,13 @@ void do_drotrv (void)
160 160 #if TARGET_LONG_BITS > HOST_LONG_BITS
161 161 static inline uint64_t get_HILO (void)
162 162 {
163   - return (env->HI << 32) | (uint32_t)env->LO;
  163 + return (env->HI[0][env->current_tc] << 32) | (uint32_t)env->LO[0][env->current_tc];
164 164 }
165 165  
166 166 static inline void set_HILO (uint64_t HILO)
167 167 {
168   - env->LO = (int32_t)HILO;
169   - env->HI = (int32_t)(HILO >> 32);
  168 + env->LO[0][env->current_tc] = (int32_t)HILO;
  169 + env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
170 170 }
171 171  
172 172 void do_mult (void)
... ... @@ -217,8 +217,8 @@ void do_div (void)
217 217 {
218 218 /* 64bit datatypes because we may see overflow/underflow. */
219 219 if (T1 != 0) {
220   - env->LO = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
221   - env->HI = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
  220 + env->LO[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
  221 + env->HI[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
222 222 }
223 223 }
224 224 #endif
... ... @@ -228,8 +228,8 @@ void do_ddiv (void)
228 228 {
229 229 if (T1 != 0) {
230 230 lldiv_t res = lldiv((int64_t)T0, (int64_t)T1);
231   - env->LO = res.quot;
232   - env->HI = res.rem;
  231 + env->LO[0][env->current_tc] = res.quot;
  232 + env->HI[0][env->current_tc] = res.rem;
233 233 }
234 234 }
235 235  
... ... @@ -237,8 +237,8 @@ void do_ddiv (void)
237 237 void do_ddivu (void)
238 238 {
239 239 if (T1 != 0) {
240   - env->LO = T0 / T1;
241   - env->HI = T0 % T1;
  240 + env->LO[0][env->current_tc] = T0 / T1;
  241 + env->HI[0][env->current_tc] = T0 % T1;
242 242 }
243 243 }
244 244 #endif
... ... @@ -316,10 +316,10 @@ void do_mtc0_status_irqraise_debug(void)
316 316 void fpu_handle_exception(void)
317 317 {
318 318 #ifdef CONFIG_SOFTFLOAT
319   - int flags = get_float_exception_flags(&env->fp_status);
  319 + int flags = get_float_exception_flags(&env->fpu->fp_status);
320 320 unsigned int cpuflags = 0, enable, cause = 0;
321 321  
322   - enable = GET_FP_ENABLE(env->fcr31);
  322 + enable = GET_FP_ENABLE(env->fpu->fcr31);
323 323  
324 324 /* determine current flags */
325 325 if (flags & float_flag_invalid) {
... ... @@ -342,11 +342,11 @@ void fpu_handle_exception(void)
342 342 cpuflags |= FP_INEXACT;
343 343 cause |= FP_INEXACT & enable;
344 344 }
345   - SET_FP_FLAGS(env->fcr31, cpuflags);
346   - SET_FP_CAUSE(env->fcr31, cause);
  345 + SET_FP_FLAGS(env->fpu->fcr31, cpuflags);
  346 + SET_FP_CAUSE(env->fpu->fcr31, cause);
347 347 #else
348   - SET_FP_FLAGS(env->fcr31, 0);
349   - SET_FP_CAUSE(env->fcr31, 0);
  348 + SET_FP_FLAGS(env->fpu->fcr31, 0);
  349 + SET_FP_CAUSE(env->fpu->fcr31, 0);
350 350 #endif
351 351 }
352 352  
... ... @@ -355,14 +355,14 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global)
355 355 {
356 356 /* Flush qemu's TLB and discard all shadowed entries. */
357 357 tlb_flush (env, flush_global);
358   - env->tlb_in_use = env->nb_tlb;
  358 + env->tlb->tlb_in_use = env->tlb->nb_tlb;
359 359 }
360 360  
361 361 static void r4k_mips_tlb_flush_extra (CPUState *env, int first)
362 362 {
363 363 /* Discard entries from env->tlb[first] onwards. */
364   - while (env->tlb_in_use > first) {
365   - r4k_invalidate_tlb(env, --env->tlb_in_use, 0);
  364 + while (env->tlb->tlb_in_use > first) {
  365 + r4k_invalidate_tlb(env, --env->tlb->tlb_in_use, 0);
366 366 }
367 367 }
368 368  
... ... @@ -371,7 +371,7 @@ static void r4k_fill_tlb (int idx)
371 371 r4k_tlb_t *tlb;
372 372  
373 373 /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
374   - tlb = &env->mmu.r4k.tlb[idx];
  374 + tlb = &env->tlb->mmu.r4k.tlb[idx];
375 375 tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
376 376 #ifdef TARGET_MIPS64
377 377 tlb->VPN &= env->SEGMask;
... ... @@ -394,10 +394,10 @@ void r4k_do_tlbwi (void)
394 394 /* Discard cached TLB entries. We could avoid doing this if the
395 395 tlbwi is just upgrading access permissions on the current entry;
396 396 that might be a further win. */
397   - r4k_mips_tlb_flush_extra (env, env->nb_tlb);
  397 + r4k_mips_tlb_flush_extra (env, env->tlb->nb_tlb);
398 398  
399   - r4k_invalidate_tlb(env, env->CP0_Index % env->nb_tlb, 0);
400   - r4k_fill_tlb(env->CP0_Index % env->nb_tlb);
  399 + r4k_invalidate_tlb(env, env->CP0_Index % env->tlb->nb_tlb, 0);
  400 + r4k_fill_tlb(env->CP0_Index % env->tlb->nb_tlb);
401 401 }
402 402  
403 403 void r4k_do_tlbwr (void)
... ... @@ -418,8 +418,8 @@ void r4k_do_tlbp (void)
418 418 int i;
419 419  
420 420 ASID = env->CP0_EntryHi & 0xFF;
421   - for (i = 0; i < env->nb_tlb; i++) {
422   - tlb = &env->mmu.r4k.tlb[i];
  421 + for (i = 0; i < env->tlb->nb_tlb; i++) {
  422 + tlb = &env->tlb->mmu.r4k.tlb[i];
423 423 /* 1k pages are not supported. */
424 424 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
425 425 tag = env->CP0_EntryHi & ~mask;
... ... @@ -431,10 +431,10 @@ void r4k_do_tlbp (void)
431 431 break;
432 432 }
433 433 }
434   - if (i == env->nb_tlb) {
  434 + if (i == env->tlb->nb_tlb) {
435 435 /* No match. Discard any shadow entries, if any of them match. */
436   - for (i = env->nb_tlb; i < env->tlb_in_use; i++) {
437   - tlb = &env->mmu.r4k.tlb[i];
  436 + for (i = env->tlb->nb_tlb; i < env->tlb->tlb_in_use; i++) {
  437 + tlb = &env->tlb->mmu.r4k.tlb[i];
438 438 /* 1k pages are not supported. */
439 439 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
440 440 tag = env->CP0_EntryHi & ~mask;
... ... @@ -456,13 +456,13 @@ void r4k_do_tlbr (void)
456 456 uint8_t ASID;
457 457  
458 458 ASID = env->CP0_EntryHi & 0xFF;
459   - tlb = &env->mmu.r4k.tlb[env->CP0_Index % env->nb_tlb];
  459 + tlb = &env->tlb->mmu.r4k.tlb[env->CP0_Index % env->tlb->nb_tlb];
460 460  
461 461 /* If this will change the current ASID, flush qemu's TLB. */
462 462 if (ASID != tlb->ASID)
463 463 cpu_mips_tlb_flush (env, 1);
464 464  
465   - r4k_mips_tlb_flush_extra(env, env->nb_tlb);
  465 + r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
466 466  
467 467 env->CP0_EntryHi = tlb->VPN | tlb->ASID;
468 468 env->CP0_PageMask = tlb->PageMask;
... ... @@ -491,7 +491,7 @@ void dump_sc (void)
491 491 void debug_pre_eret (void)
492 492 {
493 493 fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
494   - env->PC, env->CP0_EPC);
  494 + env->PC[env->current_tc], env->CP0_EPC);
495 495 if (env->CP0_Status & (1 << CP0St_ERL))
496 496 fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
497 497 if (env->hflags & MIPS_HFLAG_DM)
... ... @@ -502,7 +502,7 @@ void debug_pre_eret (void)
502 502 void debug_post_eret (void)
503 503 {
504 504 fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
505   - env->PC, env->CP0_EPC);
  505 + env->PC[env->current_tc], env->CP0_EPC);
506 506 if (env->CP0_Status & (1 << CP0St_ERL))
507 507 fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
508 508 if (env->hflags & MIPS_HFLAG_DM)
... ... @@ -518,21 +518,21 @@ void do_pmon (int function)
518 518 function /= 2;
519 519 switch (function) {
520 520 case 2: /* TODO: char inbyte(int waitflag); */
521   - if (env->gpr[4] == 0)
522   - env->gpr[2] = -1;
  521 + if (env->gpr[4][env->current_tc] == 0)
  522 + env->gpr[2][env->current_tc] = -1;
523 523 /* Fall through */
524 524 case 11: /* TODO: char inbyte (void); */
525   - env->gpr[2] = -1;
  525 + env->gpr[2][env->current_tc] = -1;
526 526 break;
527 527 case 3:
528 528 case 12:
529   - printf("%c", (char)(env->gpr[4] & 0xFF));
  529 + printf("%c", (char)(env->gpr[4][env->current_tc] & 0xFF));
530 530 break;
531 531 case 17:
532 532 break;
533 533 case 158:
534 534 {
535   - unsigned char *fmt = (void *)(unsigned long)env->gpr[4];
  535 + unsigned char *fmt = (void *)(unsigned long)env->gpr[4][env->current_tc];
536 536 printf("%s", fmt);
537 537 }
538 538 break;
... ... @@ -613,40 +613,61 @@ unsigned int ieee_rm[] = {
613 613 };
614 614  
615 615 #define RESTORE_ROUNDING_MODE \
616   - set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
  616 + set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)
617 617  
618   -void do_ctc1 (void)
  618 +void do_cfc1 (int reg)
619 619 {
620   - switch(T1) {
  620 + switch (reg) {
  621 + case 0:
  622 + T0 = (int32_t)env->fpu->fcr0;
  623 + break;
  624 + case 25:
  625 + T0 = ((env->fpu->fcr31 >> 24) & 0xfe) | ((env->fpu->fcr31 >> 23) & 0x1);
  626 + break;
  627 + case 26:
  628 + T0 = env->fpu->fcr31 & 0x0003f07c;
  629 + break;
  630 + case 28:
  631 + T0 = (env->fpu->fcr31 & 0x00000f83) | ((env->fpu->fcr31 >> 22) & 0x4);
  632 + break;
  633 + default:
  634 + T0 = (int32_t)env->fpu->fcr31;
  635 + break;
  636 + }
  637 +}
  638 +
  639 +void do_ctc1 (int reg)
  640 +{
  641 + switch(reg) {
621 642 case 25:
622 643 if (T0 & 0xffffff00)
623 644 return;
624   - env->fcr31 = (env->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |
  645 + env->fpu->fcr31 = (env->fpu->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |
625 646 ((T0 & 0x1) << 23);
626 647 break;
627 648 case 26:
628 649 if (T0 & 0x007c0000)
629 650 return;
630   - env->fcr31 = (env->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);
  651 + env->fpu->fcr31 = (env->fpu->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);
631 652 break;
632 653 case 28:
633 654 if (T0 & 0x007c0000)
634 655 return;
635   - env->fcr31 = (env->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |
  656 + env->fpu->fcr31 = (env->fpu->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |
636 657 ((T0 & 0x4) << 22);
637 658 break;
638 659 case 31:
639 660 if (T0 & 0x007c0000)
640 661 return;
641   - env->fcr31 = T0;
  662 + env->fpu->fcr31 = T0;
642 663 break;
643 664 default:
644 665 return;
645 666 }
646 667 /* set rounding mode */
647 668 RESTORE_ROUNDING_MODE;
648   - set_float_exception_flags(0, &env->fp_status);
649   - if ((GET_FP_ENABLE(env->fcr31) | 0x20) & GET_FP_CAUSE(env->fcr31))
  669 + set_float_exception_flags(0, &env->fpu->fp_status);
  670 + if ((GET_FP_ENABLE(env->fpu->fcr31) | 0x20) & GET_FP_CAUSE(env->fpu->fcr31))
650 671 do_raise_exception(EXCP_FPE);
651 672 }
652 673  
... ... @@ -670,325 +691,325 @@ inline char mips_ex_to_ieee(char xcpt)
670 691  
671 692 inline void update_fcr31(void)
672 693 {
673   - int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fp_status));
  694 + int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fpu->fp_status));
674 695  
675   - SET_FP_CAUSE(env->fcr31, tmp);
676   - if (GET_FP_ENABLE(env->fcr31) & tmp)
  696 + SET_FP_CAUSE(env->fpu->fcr31, tmp);
  697 + if (GET_FP_ENABLE(env->fpu->fcr31) & tmp)
677 698 do_raise_exception(EXCP_FPE);
678 699 else
679   - UPDATE_FP_FLAGS(env->fcr31, tmp);
  700 + UPDATE_FP_FLAGS(env->fpu->fcr31, tmp);
680 701 }
681 702  
682 703 #define FLOAT_OP(name, p) void do_float_##name##_##p(void)
683 704  
684 705 FLOAT_OP(cvtd, s)
685 706 {
686   - set_float_exception_flags(0, &env->fp_status);
687   - FDT2 = float32_to_float64(FST0, &env->fp_status);
  707 + set_float_exception_flags(0, &env->fpu->fp_status);
  708 + FDT2 = float32_to_float64(FST0, &env->fpu->fp_status);
688 709 update_fcr31();
689 710 }
690 711 FLOAT_OP(cvtd, w)
691 712 {
692   - set_float_exception_flags(0, &env->fp_status);
693   - FDT2 = int32_to_float64(WT0, &env->fp_status);
  713 + set_float_exception_flags(0, &env->fpu->fp_status);
  714 + FDT2 = int32_to_float64(WT0, &env->fpu->fp_status);
694 715 update_fcr31();
695 716 }
696 717 FLOAT_OP(cvtd, l)
697 718 {
698   - set_float_exception_flags(0, &env->fp_status);
699   - FDT2 = int64_to_float64(DT0, &env->fp_status);
  719 + set_float_exception_flags(0, &env->fpu->fp_status);
  720 + FDT2 = int64_to_float64(DT0, &env->fpu->fp_status);
700 721 update_fcr31();
701 722 }
702 723 FLOAT_OP(cvtl, d)
703 724 {
704   - set_float_exception_flags(0, &env->fp_status);
705   - DT2 = float64_to_int64(FDT0, &env->fp_status);
  725 + set_float_exception_flags(0, &env->fpu->fp_status);
  726 + DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);
706 727 update_fcr31();
707   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  728 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
708 729 DT2 = 0x7fffffffffffffffULL;
709 730 }
710 731 FLOAT_OP(cvtl, s)
711 732 {
712   - set_float_exception_flags(0, &env->fp_status);
713   - DT2 = float32_to_int64(FST0, &env->fp_status);
  733 + set_float_exception_flags(0, &env->fpu->fp_status);
  734 + DT2 = float32_to_int64(FST0, &env->fpu->fp_status);
714 735 update_fcr31();
715   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  736 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
716 737 DT2 = 0x7fffffffffffffffULL;
717 738 }
718 739  
719 740 FLOAT_OP(cvtps, pw)
720 741 {
721   - set_float_exception_flags(0, &env->fp_status);
722   - FST2 = int32_to_float32(WT0, &env->fp_status);
723   - FSTH2 = int32_to_float32(WTH0, &env->fp_status);
  742 + set_float_exception_flags(0, &env->fpu->fp_status);
  743 + FST2 = int32_to_float32(WT0, &env->fpu->fp_status);
  744 + FSTH2 = int32_to_float32(WTH0, &env->fpu->fp_status);
724 745 update_fcr31();
725 746 }
726 747 FLOAT_OP(cvtpw, ps)
727 748 {
728   - set_float_exception_flags(0, &env->fp_status);
729   - WT2 = float32_to_int32(FST0, &env->fp_status);
730   - WTH2 = float32_to_int32(FSTH0, &env->fp_status);
  749 + set_float_exception_flags(0, &env->fpu->fp_status);
  750 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
  751 + WTH2 = float32_to_int32(FSTH0, &env->fpu->fp_status);
731 752 update_fcr31();
732   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  753 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
733 754 WT2 = 0x7fffffff;
734 755 }
735 756 FLOAT_OP(cvts, d)
736 757 {
737   - set_float_exception_flags(0, &env->fp_status);
738   - FST2 = float64_to_float32(FDT0, &env->fp_status);
  758 + set_float_exception_flags(0, &env->fpu->fp_status);
  759 + FST2 = float64_to_float32(FDT0, &env->fpu->fp_status);
739 760 update_fcr31();
740 761 }
741 762 FLOAT_OP(cvts, w)
742 763 {
743   - set_float_exception_flags(0, &env->fp_status);
744   - FST2 = int32_to_float32(WT0, &env->fp_status);
  764 + set_float_exception_flags(0, &env->fpu->fp_status);
  765 + FST2 = int32_to_float32(WT0, &env->fpu->fp_status);
745 766 update_fcr31();
746 767 }
747 768 FLOAT_OP(cvts, l)
748 769 {
749   - set_float_exception_flags(0, &env->fp_status);
750   - FST2 = int64_to_float32(DT0, &env->fp_status);
  770 + set_float_exception_flags(0, &env->fpu->fp_status);
  771 + FST2 = int64_to_float32(DT0, &env->fpu->fp_status);
751 772 update_fcr31();
752 773 }
753 774 FLOAT_OP(cvts, pl)
754 775 {
755   - set_float_exception_flags(0, &env->fp_status);
  776 + set_float_exception_flags(0, &env->fpu->fp_status);
756 777 WT2 = WT0;
757 778 update_fcr31();
758 779 }
759 780 FLOAT_OP(cvts, pu)
760 781 {
761   - set_float_exception_flags(0, &env->fp_status);
  782 + set_float_exception_flags(0, &env->fpu->fp_status);
762 783 WT2 = WTH0;
763 784 update_fcr31();
764 785 }
765 786 FLOAT_OP(cvtw, s)
766 787 {
767   - set_float_exception_flags(0, &env->fp_status);
768   - WT2 = float32_to_int32(FST0, &env->fp_status);
  788 + set_float_exception_flags(0, &env->fpu->fp_status);
  789 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
769 790 update_fcr31();
770   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  791 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
771 792 WT2 = 0x7fffffff;
772 793 }
773 794 FLOAT_OP(cvtw, d)
774 795 {
775   - set_float_exception_flags(0, &env->fp_status);
776   - WT2 = float64_to_int32(FDT0, &env->fp_status);
  796 + set_float_exception_flags(0, &env->fpu->fp_status);
  797 + WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);
777 798 update_fcr31();
778   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  799 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
779 800 WT2 = 0x7fffffff;
780 801 }
781 802  
782 803 FLOAT_OP(roundl, d)
783 804 {
784   - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
785   - DT2 = float64_to_int64(FDT0, &env->fp_status);
  805 + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
  806 + DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);
786 807 RESTORE_ROUNDING_MODE;
787 808 update_fcr31();
788   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  809 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
789 810 DT2 = 0x7fffffffffffffffULL;
790 811 }
791 812 FLOAT_OP(roundl, s)
792 813 {
793   - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
794   - DT2 = float32_to_int64(FST0, &env->fp_status);
  814 + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
  815 + DT2 = float32_to_int64(FST0, &env->fpu->fp_status);
795 816 RESTORE_ROUNDING_MODE;
796 817 update_fcr31();
797   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  818 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
798 819 DT2 = 0x7fffffffffffffffULL;
799 820 }
800 821 FLOAT_OP(roundw, d)
801 822 {
802   - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
803   - WT2 = float64_to_int32(FDT0, &env->fp_status);
  823 + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
  824 + WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);
804 825 RESTORE_ROUNDING_MODE;
805 826 update_fcr31();
806   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  827 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
807 828 WT2 = 0x7fffffff;
808 829 }
809 830 FLOAT_OP(roundw, s)
810 831 {
811   - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
812   - WT2 = float32_to_int32(FST0, &env->fp_status);
  832 + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
  833 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
813 834 RESTORE_ROUNDING_MODE;
814 835 update_fcr31();
815   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  836 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
816 837 WT2 = 0x7fffffff;
817 838 }
818 839  
819 840 FLOAT_OP(truncl, d)
820 841 {
821   - DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
  842 + DT2 = float64_to_int64_round_to_zero(FDT0, &env->fpu->fp_status);
822 843 update_fcr31();
823   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  844 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
824 845 DT2 = 0x7fffffffffffffffULL;
825 846 }
826 847 FLOAT_OP(truncl, s)
827 848 {
828   - DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
  849 + DT2 = float32_to_int64_round_to_zero(FST0, &env->fpu->fp_status);
829 850 update_fcr31();
830   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  851 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
831 852 DT2 = 0x7fffffffffffffffULL;
832 853 }
833 854 FLOAT_OP(truncw, d)
834 855 {
835   - WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
  856 + WT2 = float64_to_int32_round_to_zero(FDT0, &env->fpu->fp_status);
836 857 update_fcr31();
837   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  858 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
838 859 WT2 = 0x7fffffff;
839 860 }
840 861 FLOAT_OP(truncw, s)
841 862 {
842   - WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
  863 + WT2 = float32_to_int32_round_to_zero(FST0, &env->fpu->fp_status);
843 864 update_fcr31();
844   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  865 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
845 866 WT2 = 0x7fffffff;
846 867 }
847 868  
848 869 FLOAT_OP(ceill, d)
849 870 {
850   - set_float_rounding_mode(float_round_up, &env->fp_status);
851   - DT2 = float64_to_int64(FDT0, &env->fp_status);
  871 + set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
  872 + DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);
852 873 RESTORE_ROUNDING_MODE;
853 874 update_fcr31();
854   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  875 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
855 876 DT2 = 0x7fffffffffffffffULL;
856 877 }
857 878 FLOAT_OP(ceill, s)
858 879 {
859   - set_float_rounding_mode(float_round_up, &env->fp_status);
860   - DT2 = float32_to_int64(FST0, &env->fp_status);
  880 + set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
  881 + DT2 = float32_to_int64(FST0, &env->fpu->fp_status);
861 882 RESTORE_ROUNDING_MODE;
862 883 update_fcr31();
863   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  884 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
864 885 DT2 = 0x7fffffffffffffffULL;
865 886 }
866 887 FLOAT_OP(ceilw, d)
867 888 {
868   - set_float_rounding_mode(float_round_up, &env->fp_status);
869   - WT2 = float64_to_int32(FDT0, &env->fp_status);
  889 + set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
  890 + WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);
870 891 RESTORE_ROUNDING_MODE;
871 892 update_fcr31();
872   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  893 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
873 894 WT2 = 0x7fffffff;
874 895 }
875 896 FLOAT_OP(ceilw, s)
876 897 {
877   - set_float_rounding_mode(float_round_up, &env->fp_status);
878   - WT2 = float32_to_int32(FST0, &env->fp_status);
  898 + set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
  899 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
879 900 RESTORE_ROUNDING_MODE;
880 901 update_fcr31();
881   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  902 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
882 903 WT2 = 0x7fffffff;
883 904 }
884 905  
885 906 FLOAT_OP(floorl, d)
886 907 {
887   - set_float_rounding_mode(float_round_down, &env->fp_status);
888   - DT2 = float64_to_int64(FDT0, &env->fp_status);
  908 + set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
  909 + DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);
889 910 RESTORE_ROUNDING_MODE;
890 911 update_fcr31();
891   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  912 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
892 913 DT2 = 0x7fffffffffffffffULL;
893 914 }
894 915 FLOAT_OP(floorl, s)
895 916 {
896   - set_float_rounding_mode(float_round_down, &env->fp_status);
897   - DT2 = float32_to_int64(FST0, &env->fp_status);
  917 + set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
  918 + DT2 = float32_to_int64(FST0, &env->fpu->fp_status);
898 919 RESTORE_ROUNDING_MODE;
899 920 update_fcr31();
900   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  921 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
901 922 DT2 = 0x7fffffffffffffffULL;
902 923 }
903 924 FLOAT_OP(floorw, d)
904 925 {
905   - set_float_rounding_mode(float_round_down, &env->fp_status);
906   - WT2 = float64_to_int32(FDT0, &env->fp_status);
  926 + set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
  927 + WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);
907 928 RESTORE_ROUNDING_MODE;
908 929 update_fcr31();
909   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  930 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
910 931 WT2 = 0x7fffffff;
911 932 }
912 933 FLOAT_OP(floorw, s)
913 934 {
914   - set_float_rounding_mode(float_round_down, &env->fp_status);
915   - WT2 = float32_to_int32(FST0, &env->fp_status);
  935 + set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
  936 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
916 937 RESTORE_ROUNDING_MODE;
917 938 update_fcr31();
918   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  939 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
919 940 WT2 = 0x7fffffff;
920 941 }
921 942  
922 943 /* MIPS specific unary operations */
923 944 FLOAT_OP(recip, d)
924 945 {
925   - set_float_exception_flags(0, &env->fp_status);
926   - FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
  946 + set_float_exception_flags(0, &env->fpu->fp_status);
  947 + FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fpu->fp_status);
927 948 update_fcr31();
928 949 }
929 950 FLOAT_OP(recip, s)
930 951 {
931   - set_float_exception_flags(0, &env->fp_status);
932   - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
  952 + set_float_exception_flags(0, &env->fpu->fp_status);
  953 + FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status);
933 954 update_fcr31();
934 955 }
935 956  
936 957 FLOAT_OP(rsqrt, d)
937 958 {
938   - set_float_exception_flags(0, &env->fp_status);
939   - FDT2 = float64_sqrt(FDT0, &env->fp_status);
940   - FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
  959 + set_float_exception_flags(0, &env->fpu->fp_status);
  960 + FDT2 = float64_sqrt(FDT0, &env->fpu->fp_status);
  961 + FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fpu->fp_status);
941 962 update_fcr31();
942 963 }
943 964 FLOAT_OP(rsqrt, s)
944 965 {
945   - set_float_exception_flags(0, &env->fp_status);
946   - FST2 = float32_sqrt(FST0, &env->fp_status);
947   - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
  966 + set_float_exception_flags(0, &env->fpu->fp_status);
  967 + FST2 = float32_sqrt(FST0, &env->fpu->fp_status);
  968 + FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status);
948 969 update_fcr31();
949 970 }
950 971  
951 972 FLOAT_OP(recip1, d)
952 973 {
953   - set_float_exception_flags(0, &env->fp_status);
954   - FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
  974 + set_float_exception_flags(0, &env->fpu->fp_status);
  975 + FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fpu->fp_status);
955 976 update_fcr31();
956 977 }
957 978 FLOAT_OP(recip1, s)
958 979 {
959   - set_float_exception_flags(0, &env->fp_status);
960   - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
  980 + set_float_exception_flags(0, &env->fpu->fp_status);
  981 + FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status);
961 982 update_fcr31();
962 983 }
963 984 FLOAT_OP(recip1, ps)
964 985 {
965   - set_float_exception_flags(0, &env->fp_status);
966   - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
967   - FSTH2 = float32_div(FLOAT_ONE32, FSTH0, &env->fp_status);
  986 + set_float_exception_flags(0, &env->fpu->fp_status);
  987 + FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status);
  988 + FSTH2 = float32_div(FLOAT_ONE32, FSTH0, &env->fpu->fp_status);
968 989 update_fcr31();
969 990 }
970 991  
971 992 FLOAT_OP(rsqrt1, d)
972 993 {
973   - set_float_exception_flags(0, &env->fp_status);
974   - FDT2 = float64_sqrt(FDT0, &env->fp_status);
975   - FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
  994 + set_float_exception_flags(0, &env->fpu->fp_status);
  995 + FDT2 = float64_sqrt(FDT0, &env->fpu->fp_status);
  996 + FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fpu->fp_status);
976 997 update_fcr31();
977 998 }
978 999 FLOAT_OP(rsqrt1, s)
979 1000 {
980   - set_float_exception_flags(0, &env->fp_status);
981   - FST2 = float32_sqrt(FST0, &env->fp_status);
982   - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
  1001 + set_float_exception_flags(0, &env->fpu->fp_status);
  1002 + FST2 = float32_sqrt(FST0, &env->fpu->fp_status);
  1003 + FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status);
983 1004 update_fcr31();
984 1005 }
985 1006 FLOAT_OP(rsqrt1, ps)
986 1007 {
987   - set_float_exception_flags(0, &env->fp_status);
988   - FST2 = float32_sqrt(FST0, &env->fp_status);
989   - FSTH2 = float32_sqrt(FSTH0, &env->fp_status);
990   - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
991   - FSTH2 = float32_div(FLOAT_ONE32, FSTH2, &env->fp_status);
  1008 + set_float_exception_flags(0, &env->fpu->fp_status);
  1009 + FST2 = float32_sqrt(FST0, &env->fpu->fp_status);
  1010 + FSTH2 = float32_sqrt(FSTH0, &env->fpu->fp_status);
  1011 + FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status);
  1012 + FSTH2 = float32_div(FLOAT_ONE32, FSTH2, &env->fpu->fp_status);
992 1013 update_fcr31();
993 1014 }
994 1015  
... ... @@ -996,41 +1017,41 @@ FLOAT_OP(rsqrt1, ps)
996 1017 #define FLOAT_BINOP(name) \
997 1018 FLOAT_OP(name, d) \
998 1019 { \
999   - set_float_exception_flags(0, &env->fp_status); \
1000   - FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status); \
1001   - update_fcr31(); \
1002   - if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) \
1003   - FDT2 = 0x7ff7ffffffffffffULL; \
1004   - else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
1005   - if ((env->fcr31 & 0x3) == 0) \
1006   - FDT2 &= FLOAT_SIGN64; \
  1020 + set_float_exception_flags(0, &env->fpu->fp_status); \
  1021 + FDT2 = float64_ ## name (FDT0, FDT1, &env->fpu->fp_status); \
  1022 + update_fcr31(); \
  1023 + if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) \
  1024 + FDT2 = 0x7ff7ffffffffffffULL; \
  1025 + else if (GET_FP_CAUSE(env->fpu->fcr31) & FP_UNDERFLOW) { \
  1026 + if ((env->fpu->fcr31 & 0x3) == 0) \
  1027 + FDT2 &= FLOAT_SIGN64; \
1007 1028 } \
1008 1029 } \
1009 1030 FLOAT_OP(name, s) \
1010 1031 { \
1011   - set_float_exception_flags(0, &env->fp_status); \
1012   - FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
1013   - update_fcr31(); \
1014   - if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) \
1015   - FST2 = 0x7fbfffff; \
1016   - else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
1017   - if ((env->fcr31 & 0x3) == 0) \
1018   - FST2 &= FLOAT_SIGN32; \
  1032 + set_float_exception_flags(0, &env->fpu->fp_status); \
  1033 + FST2 = float32_ ## name (FST0, FST1, &env->fpu->fp_status); \
  1034 + update_fcr31(); \
  1035 + if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) \
  1036 + FST2 = 0x7fbfffff; \
  1037 + else if (GET_FP_CAUSE(env->fpu->fcr31) & FP_UNDERFLOW) { \
  1038 + if ((env->fpu->fcr31 & 0x3) == 0) \
  1039 + FST2 &= FLOAT_SIGN32; \
1019 1040 } \
1020 1041 } \
1021 1042 FLOAT_OP(name, ps) \
1022 1043 { \
1023   - set_float_exception_flags(0, &env->fp_status); \
1024   - FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
1025   - FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \
  1044 + set_float_exception_flags(0, &env->fpu->fp_status); \
  1045 + FST2 = float32_ ## name (FST0, FST1, &env->fpu->fp_status); \
  1046 + FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fpu->fp_status); \
1026 1047 update_fcr31(); \
1027   - if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) { \
1028   - FST2 = 0x7fbfffff; \
1029   - FSTH2 = 0x7fbfffff; \
1030   - } else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
1031   - if ((env->fcr31 & 0x3) == 0) { \
1032   - FST2 &= FLOAT_SIGN32; \
1033   - FSTH2 &= FLOAT_SIGN32; \
  1048 + if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) { \
  1049 + FST2 = 0x7fbfffff; \
  1050 + FSTH2 = 0x7fbfffff; \
  1051 + } else if (GET_FP_CAUSE(env->fpu->fcr31) & FP_UNDERFLOW) { \
  1052 + if ((env->fpu->fcr31 & 0x3) == 0) { \
  1053 + FST2 &= FLOAT_SIGN32; \
  1054 + FSTH2 &= FLOAT_SIGN32; \
1034 1055 } \
1035 1056 } \
1036 1057 }
... ... @@ -1043,69 +1064,69 @@ FLOAT_BINOP(div)
1043 1064 /* MIPS specific binary operations */
1044 1065 FLOAT_OP(recip2, d)
1045 1066 {
1046   - set_float_exception_flags(0, &env->fp_status);
1047   - FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
1048   - FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status) ^ FLOAT_SIGN64;
  1067 + set_float_exception_flags(0, &env->fpu->fp_status);
  1068 + FDT2 = float64_mul(FDT0, FDT2, &env->fpu->fp_status);
  1069 + FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fpu->fp_status) ^ FLOAT_SIGN64;
1049 1070 update_fcr31();
1050 1071 }
1051 1072 FLOAT_OP(recip2, s)
1052 1073 {
1053   - set_float_exception_flags(0, &env->fp_status);
1054   - FST2 = float32_mul(FST0, FST2, &env->fp_status);
1055   - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
  1074 + set_float_exception_flags(0, &env->fpu->fp_status);
  1075 + FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status);
  1076 + FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
1056 1077 update_fcr31();
1057 1078 }
1058 1079 FLOAT_OP(recip2, ps)
1059 1080 {
1060   - set_float_exception_flags(0, &env->fp_status);
1061   - FST2 = float32_mul(FST0, FST2, &env->fp_status);
1062   - FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
1063   - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
1064   - FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
  1081 + set_float_exception_flags(0, &env->fpu->fp_status);
  1082 + FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status);
  1083 + FSTH2 = float32_mul(FSTH0, FSTH2, &env->fpu->fp_status);
  1084 + FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
  1085 + FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
1065 1086 update_fcr31();
1066 1087 }
1067 1088  
1068 1089 FLOAT_OP(rsqrt2, d)
1069 1090 {
1070   - set_float_exception_flags(0, &env->fp_status);
1071   - FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
1072   - FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status);
1073   - FDT2 = float64_div(FDT2, FLOAT_TWO64, &env->fp_status) ^ FLOAT_SIGN64;
  1091 + set_float_exception_flags(0, &env->fpu->fp_status);
  1092 + FDT2 = float64_mul(FDT0, FDT2, &env->fpu->fp_status);
  1093 + FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fpu->fp_status);
  1094 + FDT2 = float64_div(FDT2, FLOAT_TWO64, &env->fpu->fp_status) ^ FLOAT_SIGN64;
1074 1095 update_fcr31();
1075 1096 }
1076 1097 FLOAT_OP(rsqrt2, s)
1077 1098 {
1078   - set_float_exception_flags(0, &env->fp_status);
1079   - FST2 = float32_mul(FST0, FST2, &env->fp_status);
1080   - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
1081   - FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
  1099 + set_float_exception_flags(0, &env->fpu->fp_status);
  1100 + FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status);
  1101 + FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status);
  1102 + FST2 = float32_div(FST2, FLOAT_TWO32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
1082 1103 update_fcr31();
1083 1104 }
1084 1105 FLOAT_OP(rsqrt2, ps)
1085 1106 {
1086   - set_float_exception_flags(0, &env->fp_status);
1087   - FST2 = float32_mul(FST0, FST2, &env->fp_status);
1088   - FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
1089   - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
1090   - FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status);
1091   - FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
1092   - FSTH2 = float32_div(FSTH2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
  1107 + set_float_exception_flags(0, &env->fpu->fp_status);
  1108 + FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status);
  1109 + FSTH2 = float32_mul(FSTH0, FSTH2, &env->fpu->fp_status);
  1110 + FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status);
  1111 + FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fpu->fp_status);
  1112 + FST2 = float32_div(FST2, FLOAT_TWO32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
  1113 + FSTH2 = float32_div(FSTH2, FLOAT_TWO32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
1093 1114 update_fcr31();
1094 1115 }
1095 1116  
1096 1117 FLOAT_OP(addr, ps)
1097 1118 {
1098   - set_float_exception_flags(0, &env->fp_status);
1099   - FST2 = float32_add (FST0, FSTH0, &env->fp_status);
1100   - FSTH2 = float32_add (FST1, FSTH1, &env->fp_status);
  1119 + set_float_exception_flags(0, &env->fpu->fp_status);
  1120 + FST2 = float32_add (FST0, FSTH0, &env->fpu->fp_status);
  1121 + FSTH2 = float32_add (FST1, FSTH1, &env->fpu->fp_status);
1101 1122 update_fcr31();
1102 1123 }
1103 1124  
1104 1125 FLOAT_OP(mulr, ps)
1105 1126 {
1106   - set_float_exception_flags(0, &env->fp_status);
1107   - FST2 = float32_mul (FST0, FSTH0, &env->fp_status);
1108   - FSTH2 = float32_mul (FST1, FSTH1, &env->fp_status);
  1127 + set_float_exception_flags(0, &env->fpu->fp_status);
  1128 + FST2 = float32_mul (FST0, FSTH0, &env->fpu->fp_status);
  1129 + FSTH2 = float32_mul (FST1, FSTH1, &env->fpu->fp_status);
1109 1130 update_fcr31();
1110 1131 }
1111 1132  
... ... @@ -1116,9 +1137,9 @@ void do_cmp_d_ ## op (long cc) \
1116 1137 int c = cond; \
1117 1138 update_fcr31(); \
1118 1139 if (c) \
1119   - SET_FP_COND(cc, env); \
  1140 + SET_FP_COND(cc, env->fpu); \
1120 1141 else \
1121   - CLEAR_FP_COND(cc, env); \
  1142 + CLEAR_FP_COND(cc, env->fpu); \
1122 1143 } \
1123 1144 void do_cmpabs_d_ ## op (long cc) \
1124 1145 { \
... ... @@ -1128,9 +1149,9 @@ void do_cmpabs_d_ ## op (long cc) \
1128 1149 c = cond; \
1129 1150 update_fcr31(); \
1130 1151 if (c) \
1131   - SET_FP_COND(cc, env); \
  1152 + SET_FP_COND(cc, env->fpu); \
1132 1153 else \
1133   - CLEAR_FP_COND(cc, env); \
  1154 + CLEAR_FP_COND(cc, env->fpu); \
1134 1155 }
1135 1156  
1136 1157 int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
... ... @@ -1149,24 +1170,24 @@ int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
1149 1170  
1150 1171 /* NOTE: the comma operator will make "cond" to eval to false,
1151 1172 * but float*_is_unordered() is still called. */
1152   -FOP_COND_D(f, (float64_is_unordered(0, FDT1, FDT0, &env->fp_status), 0))
1153   -FOP_COND_D(un, float64_is_unordered(0, FDT1, FDT0, &env->fp_status))
1154   -FOP_COND_D(eq, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
1155   -FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1156   -FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
1157   -FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1158   -FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
1159   -FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
  1173 +FOP_COND_D(f, (float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status), 0))
  1174 +FOP_COND_D(un, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status))
  1175 +FOP_COND_D(eq, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_eq(FDT0, FDT1, &env->fpu->fp_status))
  1176 +FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_eq(FDT0, FDT1, &env->fpu->fp_status))
  1177 +FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_lt(FDT0, FDT1, &env->fpu->fp_status))
  1178 +FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_lt(FDT0, FDT1, &env->fpu->fp_status))
  1179 +FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_le(FDT0, FDT1, &env->fpu->fp_status))
  1180 +FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_le(FDT0, FDT1, &env->fpu->fp_status))
1160 1181 /* NOTE: the comma operator will make "cond" to eval to false,
1161 1182 * but float*_is_unordered() is still called. */
1162   -FOP_COND_D(sf, (float64_is_unordered(1, FDT1, FDT0, &env->fp_status), 0))
1163   -FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fp_status))
1164   -FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
1165   -FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1166   -FOP_COND_D(lt, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
1167   -FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1168   -FOP_COND_D(le, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
1169   -FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
  1183 +FOP_COND_D(sf, (float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status), 0))
  1184 +FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status))
  1185 +FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_eq(FDT0, FDT1, &env->fpu->fp_status))
  1186 +FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_eq(FDT0, FDT1, &env->fpu->fp_status))
  1187 +FOP_COND_D(lt, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_lt(FDT0, FDT1, &env->fpu->fp_status))
  1188 +FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_lt(FDT0, FDT1, &env->fpu->fp_status))
  1189 +FOP_COND_D(le, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_le(FDT0, FDT1, &env->fpu->fp_status))
  1190 +FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_le(FDT0, FDT1, &env->fpu->fp_status))
1170 1191  
1171 1192 #define FOP_COND_S(op, cond) \
1172 1193 void do_cmp_s_ ## op (long cc) \
... ... @@ -1174,9 +1195,9 @@ void do_cmp_s_ ## op (long cc) \
1174 1195 int c = cond; \
1175 1196 update_fcr31(); \
1176 1197 if (c) \
1177   - SET_FP_COND(cc, env); \
  1198 + SET_FP_COND(cc, env->fpu); \
1178 1199 else \
1179   - CLEAR_FP_COND(cc, env); \
  1200 + CLEAR_FP_COND(cc, env->fpu); \
1180 1201 } \
1181 1202 void do_cmpabs_s_ ## op (long cc) \
1182 1203 { \
... ... @@ -1186,9 +1207,9 @@ void do_cmpabs_s_ ## op (long cc) \
1186 1207 c = cond; \
1187 1208 update_fcr31(); \
1188 1209 if (c) \
1189   - SET_FP_COND(cc, env); \
  1210 + SET_FP_COND(cc, env->fpu); \
1190 1211 else \
1191   - CLEAR_FP_COND(cc, env); \
  1212 + CLEAR_FP_COND(cc, env->fpu); \
1192 1213 }
1193 1214  
1194 1215 flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
... ... @@ -1207,24 +1228,24 @@ flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
1207 1228  
1208 1229 /* NOTE: the comma operator will make "cond" to eval to false,
1209 1230 * but float*_is_unordered() is still called. */
1210   -FOP_COND_S(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0))
1211   -FOP_COND_S(un, float32_is_unordered(0, FST1, FST0, &env->fp_status))
1212   -FOP_COND_S(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
1213   -FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1214   -FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
1215   -FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1216   -FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
1217   -FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
  1231 +FOP_COND_S(f, (float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status), 0))
  1232 +FOP_COND_S(un, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status))
  1233 +FOP_COND_S(eq, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status))
  1234 +FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status))
  1235 +FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status))
  1236 +FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status))
  1237 +FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status))
  1238 +FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status))
1218 1239 /* NOTE: the comma operator will make "cond" to eval to false,
1219 1240 * but float*_is_unordered() is still called. */
1220   -FOP_COND_S(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0))
1221   -FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status))
1222   -FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
1223   -FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1224   -FOP_COND_S(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
1225   -FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1226   -FOP_COND_S(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
1227   -FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
  1241 +FOP_COND_S(sf, (float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status), 0))
  1242 +FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status))
  1243 +FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status))
  1244 +FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status))
  1245 +FOP_COND_S(lt, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status))
  1246 +FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status))
  1247 +FOP_COND_S(le, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status))
  1248 +FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status))
1228 1249  
1229 1250 #define FOP_COND_PS(op, condl, condh) \
1230 1251 void do_cmp_ps_ ## op (long cc) \
... ... @@ -1233,13 +1254,13 @@ void do_cmp_ps_ ## op (long cc) \
1233 1254 int ch = condh; \
1234 1255 update_fcr31(); \
1235 1256 if (cl) \
1236   - SET_FP_COND(cc, env); \
  1257 + SET_FP_COND(cc, env->fpu); \
1237 1258 else \
1238   - CLEAR_FP_COND(cc, env); \
  1259 + CLEAR_FP_COND(cc, env->fpu); \
1239 1260 if (ch) \
1240   - SET_FP_COND(cc + 1, env); \
  1261 + SET_FP_COND(cc + 1, env->fpu); \
1241 1262 else \
1242   - CLEAR_FP_COND(cc + 1, env); \
  1263 + CLEAR_FP_COND(cc + 1, env->fpu); \
1243 1264 } \
1244 1265 void do_cmpabs_ps_ ## op (long cc) \
1245 1266 { \
... ... @@ -1252,48 +1273,48 @@ void do_cmpabs_ps_ ## op (long cc) \
1252 1273 ch = condh; \
1253 1274 update_fcr31(); \
1254 1275 if (cl) \
1255   - SET_FP_COND(cc, env); \
  1276 + SET_FP_COND(cc, env->fpu); \
1256 1277 else \
1257   - CLEAR_FP_COND(cc, env); \
  1278 + CLEAR_FP_COND(cc, env->fpu); \
1258 1279 if (ch) \
1259   - SET_FP_COND(cc + 1, env); \
  1280 + SET_FP_COND(cc + 1, env->fpu); \
1260 1281 else \
1261   - CLEAR_FP_COND(cc + 1, env); \
  1282 + CLEAR_FP_COND(cc + 1, env->fpu); \
1262 1283 }
1263 1284  
1264 1285 /* NOTE: the comma operator will make "cond" to eval to false,
1265 1286 * but float*_is_unordered() is still called. */
1266   -FOP_COND_PS(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0),
1267   - (float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status), 0))
1268   -FOP_COND_PS(un, float32_is_unordered(0, FST1, FST0, &env->fp_status),
1269   - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status))
1270   -FOP_COND_PS(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),
1271   - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
1272   -FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),
1273   - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))
1274   -FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),
1275   - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
1276   -FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),
1277   - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))
1278   -FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),
1279   - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
1280   -FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),
1281   - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))
  1287 +FOP_COND_PS(f, (float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status), 0),
  1288 + (float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status), 0))
  1289 +FOP_COND_PS(un, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status),
  1290 + float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status))
  1291 +FOP_COND_PS(eq, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status),
  1292 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_eq(FSTH0, FSTH1, &env->fpu->fp_status))
  1293 +FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status),
  1294 + float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_eq(FSTH0, FSTH1, &env->fpu->fp_status))
  1295 +FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status),
  1296 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_lt(FSTH0, FSTH1, &env->fpu->fp_status))
  1297 +FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status),
  1298 + float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_lt(FSTH0, FSTH1, &env->fpu->fp_status))
  1299 +FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status),
  1300 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_le(FSTH0, FSTH1, &env->fpu->fp_status))
  1301 +FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status),
  1302 + float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_le(FSTH0, FSTH1, &env->fpu->fp_status))
1282 1303 /* NOTE: the comma operator will make "cond" to eval to false,
1283 1304 * but float*_is_unordered() is still called. */
1284   -FOP_COND_PS(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0),
1285   - (float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status), 0))
1286   -FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status),
1287   - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status))
1288   -FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),
1289   - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
1290   -FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),
1291   - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))
1292   -FOP_COND_PS(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),
1293   - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
1294   -FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),
1295   - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))
1296   -FOP_COND_PS(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),
1297   - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
1298   -FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),
1299   - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))
  1305 +FOP_COND_PS(sf, (float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status), 0),
  1306 + (float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status), 0))
  1307 +FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status),
  1308 + float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status))
  1309 +FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status),
  1310 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_eq(FSTH0, FSTH1, &env->fpu->fp_status))
  1311 +FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status),
  1312 + float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_eq(FSTH0, FSTH1, &env->fpu->fp_status))
  1313 +FOP_COND_PS(lt, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status),
  1314 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_lt(FSTH0, FSTH1, &env->fpu->fp_status))
  1315 +FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status),
  1316 + float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_lt(FSTH0, FSTH1, &env->fpu->fp_status))
  1317 +FOP_COND_PS(le, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status),
  1318 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_le(FSTH0, FSTH1, &env->fpu->fp_status))
  1319 +FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status),
  1320 + float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_le(FSTH0, FSTH1, &env->fpu->fp_status))
... ...
target-mips/op_template.c
... ... @@ -21,31 +21,44 @@
21 21 #if defined(REG)
22 22 void glue(op_load_gpr_T0_gpr, REG) (void)
23 23 {
24   - T0 = env->gpr[REG];
  24 + T0 = env->gpr[REG][env->current_tc];
25 25 RETURN();
26 26 }
27 27  
28 28 void glue(op_store_T0_gpr_gpr, REG) (void)
29 29 {
30   - env->gpr[REG] = T0;
  30 + env->gpr[REG][env->current_tc] = T0;
31 31 RETURN();
32 32 }
33 33  
34 34 void glue(op_load_gpr_T1_gpr, REG) (void)
35 35 {
36   - T1 = env->gpr[REG];
  36 + T1 = env->gpr[REG][env->current_tc];
37 37 RETURN();
38 38 }
39 39  
40 40 void glue(op_store_T1_gpr_gpr, REG) (void)
41 41 {
42   - env->gpr[REG] = T1;
  42 + env->gpr[REG][env->current_tc] = T1;
43 43 RETURN();
44 44 }
45 45  
46 46 void glue(op_load_gpr_T2_gpr, REG) (void)
47 47 {
48   - T2 = env->gpr[REG];
  48 + T2 = env->gpr[REG][env->current_tc];
  49 + RETURN();
  50 +}
  51 +
  52 +
  53 +void glue(op_load_srsgpr_T0_gpr, REG) (void)
  54 +{
  55 + T0 = env->gpr[REG][(env->CP0_SRSCtl >> CP0SRSCtl_PSS) & 0xf];
  56 + RETURN();
  57 +}
  58 +
  59 +void glue(op_store_T0_srsgpr_gpr, REG) (void)
  60 +{
  61 + env->gpr[REG][(env->CP0_SRSCtl >> CP0SRSCtl_PSS) & 0xf] = T0;
49 62 RETURN();
50 63 }
51 64 #endif
... ...
target-mips/translate.c
... ... @@ -266,6 +266,8 @@ enum {
266 266 OPC_DINSM = 0x05 | OPC_SPECIAL3,
267 267 OPC_DINSU = 0x06 | OPC_SPECIAL3,
268 268 OPC_DINS = 0x07 | OPC_SPECIAL3,
  269 + OPC_FORK = 0x08 | OPC_SPECIAL3,
  270 + OPC_YIELD = 0x09 | OPC_SPECIAL3,
269 271 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
270 272 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
271 273 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
... ... @@ -296,8 +298,10 @@ enum {
296 298 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
297 299 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
298 300 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
  301 + OPC_MFTR = (0x08 << 21) | OPC_CP0,
299 302 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
300 303 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
  304 + OPC_MTTR = (0x0C << 21) | OPC_CP0,
301 305 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
302 306 OPC_C0 = (0x10 << 21) | OPC_CP0,
303 307 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
... ... @@ -308,6 +312,10 @@ enum {
308 312 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
309 313  
310 314 enum {
  315 + OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
  316 + OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
  317 + OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
  318 + OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
311 319 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
312 320 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
313 321 };
... ... @@ -441,6 +449,10 @@ GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
441 449 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
442 450 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
443 451  
  452 +/* Moves to/from shadow registers */
  453 +GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
  454 +GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
  455 +
444 456 static const char *fregnames[] =
445 457 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
446 458 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
... ... @@ -569,6 +581,15 @@ do { \
569 581 } \
570 582 } while (0)
571 583  
  584 +#define GEN_LOAD_SRSREG_TN(Tn, Rn) \
  585 +do { \
  586 + if (Rn == 0) { \
  587 + glue(gen_op_reset_, Tn)(); \
  588 + } else { \
  589 + glue(gen_op_load_srsgpr_, Tn)(Rn); \
  590 + } \
  591 +} while (0)
  592 +
572 593 #ifdef TARGET_MIPS64
573 594 #define GEN_LOAD_IMM_TN(Tn, Imm) \
574 595 do { \
... ... @@ -598,6 +619,13 @@ do { \
598 619 } \
599 620 } while (0)
600 621  
  622 +#define GEN_STORE_TN_SRSREG(Rn, Tn) \
  623 +do { \
  624 + if (Rn != 0) { \
  625 + glue(glue(gen_op_store_, Tn),_srsgpr)(Rn); \
  626 + } \
  627 +} while (0)
  628 +
601 629 #define GEN_LOAD_FREG_FTN(FTn, Fn) \
602 630 do { \
603 631 glue(gen_op_load_fpr_, FTn)(Fn); \
... ... @@ -740,6 +768,14 @@ static inline void check_mips_r2(CPUState *env, DisasContext *ctx)
740 768 generate_exception(ctx, EXCP_RI);
741 769 }
742 770  
  771 +/* This code generates a "reserved instruction" exception if the
  772 + CPU is not MIPS MT capable. */
  773 +static inline void check_mips_mt(CPUState *env, DisasContext *ctx)
  774 +{
  775 + if (!(env->CP0_Config3 & (1 << CP0C3_MT)))
  776 + generate_exception(ctx, EXCP_RI);
  777 +}
  778 +
743 779 #if defined(CONFIG_USER_ONLY)
744 780 #define op_ldst(name) gen_op_##name##_raw()
745 781 #define OP_LD_TABLE(width)
... ... @@ -806,8 +842,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
806 842 gen_op_addr_add();
807 843 }
808 844 /* Don't do NOP if destination is zero: we must perform the actual
809   - * memory access
810   - */
  845 + memory access. */
811 846 switch (opc) {
812 847 #ifdef TARGET_MIPS64
813 848 case OPC_LWU:
... ... @@ -958,8 +993,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
958 993 gen_op_addr_add();
959 994 }
960 995 /* Don't do NOP if destination is zero: we must perform the actual
961   - * memory access
962   - */
  996 + memory access. */
963 997 switch (opc) {
964 998 case OPC_LWC1:
965 999 op_ldst(lwc1);
... ... @@ -997,9 +1031,8 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
997 1031 const char *opn = "imm arith";
998 1032  
999 1033 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1000   - /* if no destination, treat it as a NOP
1001   - * For addi, we must generate the overflow exception when needed.
1002   - */
  1034 + /* If no destination, treat it as a NOP.
  1035 + For addi, we must generate the overflow exception when needed. */
1003 1036 MIPS_DEBUG("NOP");
1004 1037 return;
1005 1038 }
... ... @@ -1175,9 +1208,8 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
1175 1208  
1176 1209 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1177 1210 && opc != OPC_DADD && opc != OPC_DSUB) {
1178   - /* if no destination, treat it as a NOP
1179   - * For add & sub, we must generate the overflow exception when needed.
1180   - */
  1211 + /* If no destination, treat it as a NOP.
  1212 + For add & sub, we must generate the overflow exception when needed. */
1181 1213 MIPS_DEBUG("NOP");
1182 1214 return;
1183 1215 }
... ... @@ -1324,29 +1356,29 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1324 1356 const char *opn = "hilo";
1325 1357  
1326 1358 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1327   - /* Treat as a NOP */
  1359 + /* Treat as NOP. */
1328 1360 MIPS_DEBUG("NOP");
1329 1361 return;
1330 1362 }
1331 1363 switch (opc) {
1332 1364 case OPC_MFHI:
1333   - gen_op_load_HI();
  1365 + gen_op_load_HI(0);
1334 1366 GEN_STORE_TN_REG(reg, T0);
1335 1367 opn = "mfhi";
1336 1368 break;
1337 1369 case OPC_MFLO:
1338   - gen_op_load_LO();
  1370 + gen_op_load_LO(0);
1339 1371 GEN_STORE_TN_REG(reg, T0);
1340 1372 opn = "mflo";
1341 1373 break;
1342 1374 case OPC_MTHI:
1343 1375 GEN_LOAD_REG_TN(T0, reg);
1344   - gen_op_store_HI();
  1376 + gen_op_store_HI(0);
1345 1377 opn = "mthi";
1346 1378 break;
1347 1379 case OPC_MTLO:
1348 1380 GEN_LOAD_REG_TN(T0, reg);
1349   - gen_op_store_LO();
  1381 + gen_op_store_LO(0);
1350 1382 opn = "mtlo";
1351 1383 break;
1352 1384 default:
... ... @@ -1428,7 +1460,7 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
1428 1460 {
1429 1461 const char *opn = "CLx";
1430 1462 if (rd == 0) {
1431   - /* Treat as a NOP */
  1463 + /* Treat as NOP. */
1432 1464 MIPS_DEBUG("NOP");
1433 1465 return;
1434 1466 }
... ... @@ -1514,7 +1546,7 @@ static void gen_trap (DisasContext *ctx, uint32_t opc,
1514 1546 case OPC_TLTIU: /* r0 < 0 unsigned */
1515 1547 case OPC_TNE: /* rs != rs */
1516 1548 case OPC_TNEI: /* r0 != 0 */
1517   - /* Never trap: treat as NOP */
  1549 + /* Never trap: treat as NOP. */
1518 1550 return;
1519 1551 default:
1520 1552 MIPS_INVAL("trap");
... ... @@ -1674,7 +1706,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1674 1706 case OPC_BNE: /* rx != rx */
1675 1707 case OPC_BGTZ: /* 0 > 0 */
1676 1708 case OPC_BLTZ: /* 0 < 0 */
1677   - /* Treated as NOP */
  1709 + /* Treat as NOP. */
1678 1710 MIPS_DEBUG("bnever (NOP)");
1679 1711 return;
1680 1712 case OPC_BLTZAL: /* 0 < 0 */
... ... @@ -1886,17 +1918,20 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1886 1918 rn = "Index";
1887 1919 break;
1888 1920 case 1:
1889   -// gen_op_mfc0_mvpcontrol(); /* MT ASE */
  1921 + check_mips_mt(env, ctx);
  1922 + gen_op_mfc0_mvpcontrol();
1890 1923 rn = "MVPControl";
1891   -// break;
  1924 + break;
1892 1925 case 2:
1893   -// gen_op_mfc0_mvpconf0(); /* MT ASE */
  1926 + check_mips_mt(env, ctx);
  1927 + gen_op_mfc0_mvpconf0();
1894 1928 rn = "MVPConf0";
1895   -// break;
  1929 + break;
1896 1930 case 3:
1897   -// gen_op_mfc0_mvpconf1(); /* MT ASE */
  1931 + check_mips_mt(env, ctx);
  1932 + gen_op_mfc0_mvpconf1();
1898 1933 rn = "MVPConf1";
1899   -// break;
  1934 + break;
1900 1935 default:
1901 1936 goto die;
1902 1937 }
... ... @@ -1908,33 +1943,40 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1908 1943 rn = "Random";
1909 1944 break;
1910 1945 case 1:
1911   -// gen_op_mfc0_vpecontrol(); /* MT ASE */
  1946 + check_mips_mt(env, ctx);
  1947 + gen_op_mfc0_vpecontrol();
1912 1948 rn = "VPEControl";
1913   -// break;
  1949 + break;
1914 1950 case 2:
1915   -// gen_op_mfc0_vpeconf0(); /* MT ASE */
  1951 + check_mips_mt(env, ctx);
  1952 + gen_op_mfc0_vpeconf0();
1916 1953 rn = "VPEConf0";
1917   -// break;
  1954 + break;
1918 1955 case 3:
1919   -// gen_op_mfc0_vpeconf1(); /* MT ASE */
  1956 + check_mips_mt(env, ctx);
  1957 + gen_op_mfc0_vpeconf1();
1920 1958 rn = "VPEConf1";
1921   -// break;
  1959 + break;
1922 1960 case 4:
1923   -// gen_op_mfc0_YQMask(); /* MT ASE */
  1961 + check_mips_mt(env, ctx);
  1962 + gen_op_mfc0_yqmask();
1924 1963 rn = "YQMask";
1925   -// break;
  1964 + break;
1926 1965 case 5:
1927   -// gen_op_mfc0_vpeschedule(); /* MT ASE */
  1966 + check_mips_mt(env, ctx);
  1967 + gen_op_mfc0_vpeschedule();
1928 1968 rn = "VPESchedule";
1929   -// break;
  1969 + break;
1930 1970 case 6:
1931   -// gen_op_mfc0_vpeschefback(); /* MT ASE */
  1971 + check_mips_mt(env, ctx);
  1972 + gen_op_mfc0_vpeschefback();
1932 1973 rn = "VPEScheFBack";
1933   -// break;
  1974 + break;
1934 1975 case 7:
1935   -// gen_op_mfc0_vpeopt(); /* MT ASE */
  1976 + check_mips_mt(env, ctx);
  1977 + gen_op_mfc0_vpeopt();
1936 1978 rn = "VPEOpt";
1937   -// break;
  1979 + break;
1938 1980 default:
1939 1981 goto die;
1940 1982 }
... ... @@ -1946,33 +1988,40 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1946 1988 rn = "EntryLo0";
1947 1989 break;
1948 1990 case 1:
1949   -// gen_op_mfc0_tcstatus(); /* MT ASE */
  1991 + check_mips_mt(env, ctx);
  1992 + gen_op_mfc0_tcstatus();
1950 1993 rn = "TCStatus";
1951   -// break;
  1994 + break;
1952 1995 case 2:
1953   -// gen_op_mfc0_tcbind(); /* MT ASE */
  1996 + check_mips_mt(env, ctx);
  1997 + gen_op_mfc0_tcbind();
1954 1998 rn = "TCBind";
1955   -// break;
  1999 + break;
1956 2000 case 3:
1957   -// gen_op_mfc0_tcrestart(); /* MT ASE */
  2001 + check_mips_mt(env, ctx);
  2002 + gen_op_mfc0_tcrestart();
1958 2003 rn = "TCRestart";
1959   -// break;
  2004 + break;
1960 2005 case 4:
1961   -// gen_op_mfc0_tchalt(); /* MT ASE */
  2006 + check_mips_mt(env, ctx);
  2007 + gen_op_mfc0_tchalt();
1962 2008 rn = "TCHalt";
1963   -// break;
  2009 + break;
1964 2010 case 5:
1965   -// gen_op_mfc0_tccontext(); /* MT ASE */
  2011 + check_mips_mt(env, ctx);
  2012 + gen_op_mfc0_tccontext();
1966 2013 rn = "TCContext";
1967   -// break;
  2014 + break;
1968 2015 case 6:
1969   -// gen_op_mfc0_tcschedule(); /* MT ASE */
  2016 + check_mips_mt(env, ctx);
  2017 + gen_op_mfc0_tcschedule();
1970 2018 rn = "TCSchedule";
1971   -// break;
  2019 + break;
1972 2020 case 7:
1973   -// gen_op_mfc0_tcschefback(); /* MT ASE */
  2021 + check_mips_mt(env, ctx);
  2022 + gen_op_mfc0_tcschefback();
1974 2023 rn = "TCScheFBack";
1975   -// break;
  2024 + break;
1976 2025 default:
1977 2026 goto die;
1978 2027 }
... ... @@ -2023,25 +2072,25 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2023 2072 rn = "Wired";
2024 2073 break;
2025 2074 case 1:
2026   -// gen_op_mfc0_srsconf0(); /* shadow registers */
  2075 + gen_op_mfc0_srsconf0();
2027 2076 rn = "SRSConf0";
2028   -// break;
  2077 + break;
2029 2078 case 2:
2030   -// gen_op_mfc0_srsconf1(); /* shadow registers */
  2079 + gen_op_mfc0_srsconf1();
2031 2080 rn = "SRSConf1";
2032   -// break;
  2081 + break;
2033 2082 case 3:
2034   -// gen_op_mfc0_srsconf2(); /* shadow registers */
  2083 + gen_op_mfc0_srsconf2();
2035 2084 rn = "SRSConf2";
2036   -// break;
  2085 + break;
2037 2086 case 4:
2038   -// gen_op_mfc0_srsconf3(); /* shadow registers */
  2087 + gen_op_mfc0_srsconf3();
2039 2088 rn = "SRSConf3";
2040   -// break;
  2089 + break;
2041 2090 case 5:
2042   -// gen_op_mfc0_srsconf4(); /* shadow registers */
  2091 + gen_op_mfc0_srsconf4();
2043 2092 rn = "SRSConf4";
2044   -// break;
  2093 + break;
2045 2094 default:
2046 2095 goto die;
2047 2096 }
... ... @@ -2430,17 +2479,20 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2430 2479 rn = "Index";
2431 2480 break;
2432 2481 case 1:
2433   -// gen_op_mtc0_mvpcontrol(); /* MT ASE */
  2482 + check_mips_mt(env, ctx);
  2483 + gen_op_mtc0_mvpcontrol();
2434 2484 rn = "MVPControl";
2435   -// break;
  2485 + break;
2436 2486 case 2:
2437   -// gen_op_mtc0_mvpconf0(); /* MT ASE */
  2487 + check_mips_mt(env, ctx);
  2488 + /* ignored */
2438 2489 rn = "MVPConf0";
2439   -// break;
  2490 + break;
2440 2491 case 3:
2441   -// gen_op_mtc0_mvpconf1(); /* MT ASE */
  2492 + check_mips_mt(env, ctx);
  2493 + /* ignored */
2442 2494 rn = "MVPConf1";
2443   -// break;
  2495 + break;
2444 2496 default:
2445 2497 goto die;
2446 2498 }
... ... @@ -2452,33 +2504,40 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2452 2504 rn = "Random";
2453 2505 break;
2454 2506 case 1:
2455   -// gen_op_mtc0_vpecontrol(); /* MT ASE */
  2507 + check_mips_mt(env, ctx);
  2508 + gen_op_mtc0_vpecontrol();
2456 2509 rn = "VPEControl";
2457   -// break;
  2510 + break;
2458 2511 case 2:
2459   -// gen_op_mtc0_vpeconf0(); /* MT ASE */
  2512 + check_mips_mt(env, ctx);
  2513 + gen_op_mtc0_vpeconf0();
2460 2514 rn = "VPEConf0";
2461   -// break;
  2515 + break;
2462 2516 case 3:
2463   -// gen_op_mtc0_vpeconf1(); /* MT ASE */
  2517 + check_mips_mt(env, ctx);
  2518 + gen_op_mtc0_vpeconf1();
2464 2519 rn = "VPEConf1";
2465   -// break;
  2520 + break;
2466 2521 case 4:
2467   -// gen_op_mtc0_YQMask(); /* MT ASE */
  2522 + check_mips_mt(env, ctx);
  2523 + gen_op_mtc0_yqmask();
2468 2524 rn = "YQMask";
2469   -// break;
  2525 + break;
2470 2526 case 5:
2471   -// gen_op_mtc0_vpeschedule(); /* MT ASE */
  2527 + check_mips_mt(env, ctx);
  2528 + gen_op_mtc0_vpeschedule();
2472 2529 rn = "VPESchedule";
2473   -// break;
  2530 + break;
2474 2531 case 6:
2475   -// gen_op_mtc0_vpeschefback(); /* MT ASE */
  2532 + check_mips_mt(env, ctx);
  2533 + gen_op_mtc0_vpeschefback();
2476 2534 rn = "VPEScheFBack";
2477   -// break;
  2535 + break;
2478 2536 case 7:
2479   -// gen_op_mtc0_vpeopt(); /* MT ASE */
  2537 + check_mips_mt(env, ctx);
  2538 + gen_op_mtc0_vpeopt();
2480 2539 rn = "VPEOpt";
2481   -// break;
  2540 + break;
2482 2541 default:
2483 2542 goto die;
2484 2543 }
... ... @@ -2490,33 +2549,40 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2490 2549 rn = "EntryLo0";
2491 2550 break;
2492 2551 case 1:
2493   -// gen_op_mtc0_tcstatus(); /* MT ASE */
  2552 + check_mips_mt(env, ctx);
  2553 + gen_op_mtc0_tcstatus();
2494 2554 rn = "TCStatus";
2495   -// break;
  2555 + break;
2496 2556 case 2:
2497   -// gen_op_mtc0_tcbind(); /* MT ASE */
  2557 + check_mips_mt(env, ctx);
  2558 + gen_op_mtc0_tcbind();
2498 2559 rn = "TCBind";
2499   -// break;
  2560 + break;
2500 2561 case 3:
2501   -// gen_op_mtc0_tcrestart(); /* MT ASE */
  2562 + check_mips_mt(env, ctx);
  2563 + gen_op_mtc0_tcrestart();
2502 2564 rn = "TCRestart";
2503   -// break;
  2565 + break;
2504 2566 case 4:
2505   -// gen_op_mtc0_tchalt(); /* MT ASE */
  2567 + check_mips_mt(env, ctx);
  2568 + gen_op_mtc0_tchalt();
2506 2569 rn = "TCHalt";
2507   -// break;
  2570 + break;
2508 2571 case 5:
2509   -// gen_op_mtc0_tccontext(); /* MT ASE */
  2572 + check_mips_mt(env, ctx);
  2573 + gen_op_mtc0_tccontext();
2510 2574 rn = "TCContext";
2511   -// break;
  2575 + break;
2512 2576 case 6:
2513   -// gen_op_mtc0_tcschedule(); /* MT ASE */
  2577 + check_mips_mt(env, ctx);
  2578 + gen_op_mtc0_tcschedule();
2514 2579 rn = "TCSchedule";
2515   -// break;
  2580 + break;
2516 2581 case 7:
2517   -// gen_op_mtc0_tcschefback(); /* MT ASE */
  2582 + check_mips_mt(env, ctx);
  2583 + gen_op_mtc0_tcschefback();
2518 2584 rn = "TCScheFBack";
2519   -// break;
  2585 + break;
2520 2586 default:
2521 2587 goto die;
2522 2588 }
... ... @@ -2567,25 +2633,25 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2567 2633 rn = "Wired";
2568 2634 break;
2569 2635 case 1:
2570   -// gen_op_mtc0_srsconf0(); /* shadow registers */
  2636 + gen_op_mtc0_srsconf0();
2571 2637 rn = "SRSConf0";
2572   -// break;
  2638 + break;
2573 2639 case 2:
2574   -// gen_op_mtc0_srsconf1(); /* shadow registers */
  2640 + gen_op_mtc0_srsconf1();
2575 2641 rn = "SRSConf1";
2576   -// break;
  2642 + break;
2577 2643 case 3:
2578   -// gen_op_mtc0_srsconf2(); /* shadow registers */
  2644 + gen_op_mtc0_srsconf2();
2579 2645 rn = "SRSConf2";
2580   -// break;
  2646 + break;
2581 2647 case 4:
2582   -// gen_op_mtc0_srsconf3(); /* shadow registers */
  2648 + gen_op_mtc0_srsconf3();
2583 2649 rn = "SRSConf3";
2584   -// break;
  2650 + break;
2585 2651 case 5:
2586   -// gen_op_mtc0_srsconf4(); /* shadow registers */
  2652 + gen_op_mtc0_srsconf4();
2587 2653 rn = "SRSConf4";
2588   -// break;
  2654 + break;
2589 2655 default:
2590 2656 goto die;
2591 2657 }
... ... @@ -3006,17 +3072,20 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3006 3072 rn = "Index";
3007 3073 break;
3008 3074 case 1:
3009   -// gen_op_dmfc0_mvpcontrol(); /* MT ASE */
  3075 + check_mips_mt(env, ctx);
  3076 + gen_op_mfc0_mvpcontrol();
3010 3077 rn = "MVPControl";
3011   -// break;
  3078 + break;
3012 3079 case 2:
3013   -// gen_op_dmfc0_mvpconf0(); /* MT ASE */
  3080 + check_mips_mt(env, ctx);
  3081 + gen_op_mfc0_mvpconf0();
3014 3082 rn = "MVPConf0";
3015   -// break;
  3083 + break;
3016 3084 case 3:
3017   -// gen_op_dmfc0_mvpconf1(); /* MT ASE */
  3085 + check_mips_mt(env, ctx);
  3086 + gen_op_mfc0_mvpconf1();
3018 3087 rn = "MVPConf1";
3019   -// break;
  3088 + break;
3020 3089 default:
3021 3090 goto die;
3022 3091 }
... ... @@ -3028,33 +3097,40 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3028 3097 rn = "Random";
3029 3098 break;
3030 3099 case 1:
3031   -// gen_op_dmfc0_vpecontrol(); /* MT ASE */
  3100 + check_mips_mt(env, ctx);
  3101 + gen_op_mfc0_vpecontrol();
3032 3102 rn = "VPEControl";
3033   -// break;
  3103 + break;
3034 3104 case 2:
3035   -// gen_op_dmfc0_vpeconf0(); /* MT ASE */
  3105 + check_mips_mt(env, ctx);
  3106 + gen_op_mfc0_vpeconf0();
3036 3107 rn = "VPEConf0";
3037   -// break;
  3108 + break;
3038 3109 case 3:
3039   -// gen_op_dmfc0_vpeconf1(); /* MT ASE */
  3110 + check_mips_mt(env, ctx);
  3111 + gen_op_mfc0_vpeconf1();
3040 3112 rn = "VPEConf1";
3041   -// break;
  3113 + break;
3042 3114 case 4:
3043   -// gen_op_dmfc0_YQMask(); /* MT ASE */
  3115 + check_mips_mt(env, ctx);
  3116 + gen_op_dmfc0_yqmask();
3044 3117 rn = "YQMask";
3045   -// break;
  3118 + break;
3046 3119 case 5:
3047   -// gen_op_dmfc0_vpeschedule(); /* MT ASE */
  3120 + check_mips_mt(env, ctx);
  3121 + gen_op_dmfc0_vpeschedule();
3048 3122 rn = "VPESchedule";
3049   -// break;
  3123 + break;
3050 3124 case 6:
3051   -// gen_op_dmfc0_vpeschefback(); /* MT ASE */
  3125 + check_mips_mt(env, ctx);
  3126 + gen_op_dmfc0_vpeschefback();
3052 3127 rn = "VPEScheFBack";
3053   -// break;
  3128 + break;
3054 3129 case 7:
3055   -// gen_op_dmfc0_vpeopt(); /* MT ASE */
  3130 + check_mips_mt(env, ctx);
  3131 + gen_op_mfc0_vpeopt();
3056 3132 rn = "VPEOpt";
3057   -// break;
  3133 + break;
3058 3134 default:
3059 3135 goto die;
3060 3136 }
... ... @@ -3066,33 +3142,40 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3066 3142 rn = "EntryLo0";
3067 3143 break;
3068 3144 case 1:
3069   -// gen_op_dmfc0_tcstatus(); /* MT ASE */
  3145 + check_mips_mt(env, ctx);
  3146 + gen_op_mfc0_tcstatus();
3070 3147 rn = "TCStatus";
3071   -// break;
  3148 + break;
3072 3149 case 2:
3073   -// gen_op_dmfc0_tcbind(); /* MT ASE */
  3150 + check_mips_mt(env, ctx);
  3151 + gen_op_mfc0_tcbind();
3074 3152 rn = "TCBind";
3075   -// break;
  3153 + break;
3076 3154 case 3:
3077   -// gen_op_dmfc0_tcrestart(); /* MT ASE */
  3155 + check_mips_mt(env, ctx);
  3156 + gen_op_dmfc0_tcrestart();
3078 3157 rn = "TCRestart";
3079   -// break;
  3158 + break;
3080 3159 case 4:
3081   -// gen_op_dmfc0_tchalt(); /* MT ASE */
  3160 + check_mips_mt(env, ctx);
  3161 + gen_op_dmfc0_tchalt();
3082 3162 rn = "TCHalt";
3083   -// break;
  3163 + break;
3084 3164 case 5:
3085   -// gen_op_dmfc0_tccontext(); /* MT ASE */
  3165 + check_mips_mt(env, ctx);
  3166 + gen_op_dmfc0_tccontext();
3086 3167 rn = "TCContext";
3087   -// break;
  3168 + break;
3088 3169 case 6:
3089   -// gen_op_dmfc0_tcschedule(); /* MT ASE */
  3170 + check_mips_mt(env, ctx);
  3171 + gen_op_dmfc0_tcschedule();
3090 3172 rn = "TCSchedule";
3091   -// break;
  3173 + break;
3092 3174 case 7:
3093   -// gen_op_dmfc0_tcschefback(); /* MT ASE */
  3175 + check_mips_mt(env, ctx);
  3176 + gen_op_dmfc0_tcschefback();
3094 3177 rn = "TCScheFBack";
3095   -// break;
  3178 + break;
3096 3179 default:
3097 3180 goto die;
3098 3181 }
... ... @@ -3143,25 +3226,25 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3143 3226 rn = "Wired";
3144 3227 break;
3145 3228 case 1:
3146   -// gen_op_dmfc0_srsconf0(); /* shadow registers */
  3229 + gen_op_mfc0_srsconf0();
3147 3230 rn = "SRSConf0";
3148   -// break;
  3231 + break;
3149 3232 case 2:
3150   -// gen_op_dmfc0_srsconf1(); /* shadow registers */
  3233 + gen_op_mfc0_srsconf1();
3151 3234 rn = "SRSConf1";
3152   -// break;
  3235 + break;
3153 3236 case 3:
3154   -// gen_op_dmfc0_srsconf2(); /* shadow registers */
  3237 + gen_op_mfc0_srsconf2();
3155 3238 rn = "SRSConf2";
3156   -// break;
  3239 + break;
3157 3240 case 4:
3158   -// gen_op_dmfc0_srsconf3(); /* shadow registers */
  3241 + gen_op_mfc0_srsconf3();
3159 3242 rn = "SRSConf3";
3160   -// break;
  3243 + break;
3161 3244 case 5:
3162   -// gen_op_dmfc0_srsconf4(); /* shadow registers */
  3245 + gen_op_mfc0_srsconf4();
3163 3246 rn = "SRSConf4";
3164   -// break;
  3247 + break;
3165 3248 default:
3166 3249 goto die;
3167 3250 }
... ... @@ -3237,7 +3320,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3237 3320 break;
3238 3321 case 3:
3239 3322 check_mips_r2(env, ctx);
3240   - gen_op_mfc0_srsmap(); /* shadow registers */
  3323 + gen_op_mfc0_srsmap();
3241 3324 rn = "SRSMap";
3242 3325 break;
3243 3326 default:
... ... @@ -3537,17 +3620,20 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3537 3620 rn = "Index";
3538 3621 break;
3539 3622 case 1:
3540   -// gen_op_mtc0_mvpcontrol(); /* MT ASE */
  3623 + check_mips_mt(env, ctx);
  3624 + gen_op_mtc0_mvpcontrol();
3541 3625 rn = "MVPControl";
3542   -// break;
  3626 + break;
3543 3627 case 2:
3544   -// gen_op_mtc0_mvpconf0(); /* MT ASE */
  3628 + check_mips_mt(env, ctx);
  3629 + /* ignored */
3545 3630 rn = "MVPConf0";
3546   -// break;
  3631 + break;
3547 3632 case 3:
3548   -// gen_op_mtc0_mvpconf1(); /* MT ASE */
  3633 + check_mips_mt(env, ctx);
  3634 + /* ignored */
3549 3635 rn = "MVPConf1";
3550   -// break;
  3636 + break;
3551 3637 default:
3552 3638 goto die;
3553 3639 }
... ... @@ -3559,33 +3645,40 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3559 3645 rn = "Random";
3560 3646 break;
3561 3647 case 1:
3562   -// gen_op_mtc0_vpecontrol(); /* MT ASE */
  3648 + check_mips_mt(env, ctx);
  3649 + gen_op_mtc0_vpecontrol();
3563 3650 rn = "VPEControl";
3564   -// break;
  3651 + break;
3565 3652 case 2:
3566   -// gen_op_mtc0_vpeconf0(); /* MT ASE */
  3653 + check_mips_mt(env, ctx);
  3654 + gen_op_mtc0_vpeconf0();
3567 3655 rn = "VPEConf0";
3568   -// break;
  3656 + break;
3569 3657 case 3:
3570   -// gen_op_mtc0_vpeconf1(); /* MT ASE */
  3658 + check_mips_mt(env, ctx);
  3659 + gen_op_mtc0_vpeconf1();
3571 3660 rn = "VPEConf1";
3572   -// break;
  3661 + break;
3573 3662 case 4:
3574   -// gen_op_mtc0_YQMask(); /* MT ASE */
  3663 + check_mips_mt(env, ctx);
  3664 + gen_op_mtc0_yqmask();
3575 3665 rn = "YQMask";
3576   -// break;
  3666 + break;
3577 3667 case 5:
3578   -// gen_op_mtc0_vpeschedule(); /* MT ASE */
  3668 + check_mips_mt(env, ctx);
  3669 + gen_op_mtc0_vpeschedule();
3579 3670 rn = "VPESchedule";
3580   -// break;
  3671 + break;
3581 3672 case 6:
3582   -// gen_op_mtc0_vpeschefback(); /* MT ASE */
  3673 + check_mips_mt(env, ctx);
  3674 + gen_op_mtc0_vpeschefback();
3583 3675 rn = "VPEScheFBack";
3584   -// break;
  3676 + break;
3585 3677 case 7:
3586   -// gen_op_mtc0_vpeopt(); /* MT ASE */
  3678 + check_mips_mt(env, ctx);
  3679 + gen_op_mtc0_vpeopt();
3587 3680 rn = "VPEOpt";
3588   -// break;
  3681 + break;
3589 3682 default:
3590 3683 goto die;
3591 3684 }
... ... @@ -3597,33 +3690,40 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3597 3690 rn = "EntryLo0";
3598 3691 break;
3599 3692 case 1:
3600   -// gen_op_mtc0_tcstatus(); /* MT ASE */
  3693 + check_mips_mt(env, ctx);
  3694 + gen_op_mtc0_tcstatus();
3601 3695 rn = "TCStatus";
3602   -// break;
  3696 + break;
3603 3697 case 2:
3604   -// gen_op_mtc0_tcbind(); /* MT ASE */
  3698 + check_mips_mt(env, ctx);
  3699 + gen_op_mtc0_tcbind();
3605 3700 rn = "TCBind";
3606   -// break;
  3701 + break;
3607 3702 case 3:
3608   -// gen_op_mtc0_tcrestart(); /* MT ASE */
  3703 + check_mips_mt(env, ctx);
  3704 + gen_op_mtc0_tcrestart();
3609 3705 rn = "TCRestart";
3610   -// break;
  3706 + break;
3611 3707 case 4:
3612   -// gen_op_mtc0_tchalt(); /* MT ASE */
  3708 + check_mips_mt(env, ctx);
  3709 + gen_op_mtc0_tchalt();
3613 3710 rn = "TCHalt";
3614   -// break;
  3711 + break;
3615 3712 case 5:
3616   -// gen_op_mtc0_tccontext(); /* MT ASE */
  3713 + check_mips_mt(env, ctx);
  3714 + gen_op_mtc0_tccontext();
3617 3715 rn = "TCContext";
3618   -// break;
  3716 + break;
3619 3717 case 6:
3620   -// gen_op_mtc0_tcschedule(); /* MT ASE */
  3718 + check_mips_mt(env, ctx);
  3719 + gen_op_mtc0_tcschedule();
3621 3720 rn = "TCSchedule";
3622   -// break;
  3721 + break;
3623 3722 case 7:
3624   -// gen_op_mtc0_tcschefback(); /* MT ASE */
  3723 + check_mips_mt(env, ctx);
  3724 + gen_op_mtc0_tcschefback();
3625 3725 rn = "TCScheFBack";
3626   -// break;
  3726 + break;
3627 3727 default:
3628 3728 goto die;
3629 3729 }
... ... @@ -3674,25 +3774,25 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3674 3774 rn = "Wired";
3675 3775 break;
3676 3776 case 1:
3677   -// gen_op_mtc0_srsconf0(); /* shadow registers */
  3777 + gen_op_mtc0_srsconf0();
3678 3778 rn = "SRSConf0";
3679   -// break;
  3779 + break;
3680 3780 case 2:
3681   -// gen_op_mtc0_srsconf1(); /* shadow registers */
  3781 + gen_op_mtc0_srsconf1();
3682 3782 rn = "SRSConf1";
3683   -// break;
  3783 + break;
3684 3784 case 3:
3685   -// gen_op_mtc0_srsconf2(); /* shadow registers */
  3785 + gen_op_mtc0_srsconf2();
3686 3786 rn = "SRSConf2";
3687   -// break;
  3787 + break;
3688 3788 case 4:
3689   -// gen_op_mtc0_srsconf3(); /* shadow registers */
  3789 + gen_op_mtc0_srsconf3();
3690 3790 rn = "SRSConf3";
3691   -// break;
  3791 + break;
3692 3792 case 5:
3693   -// gen_op_mtc0_srsconf4(); /* shadow registers */
  3793 + gen_op_mtc0_srsconf4();
3694 3794 rn = "SRSConf4";
3695   -// break;
  3795 + break;
3696 3796 default:
3697 3797 goto die;
3698 3798 }
... ... @@ -4086,6 +4186,334 @@ die:
4086 4186 }
4087 4187 #endif /* TARGET_MIPS64 */
4088 4188  
  4189 +static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
  4190 + int u, int sel, int h)
  4191 +{
  4192 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  4193 +
  4194 + if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
  4195 + ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
  4196 + (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
  4197 + gen_op_set_T0(-1);
  4198 + else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
  4199 + (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
  4200 + gen_op_set_T0(-1);
  4201 + else if (u == 0) {
  4202 + switch (rt) {
  4203 + case 2:
  4204 + switch (sel) {
  4205 + case 1:
  4206 + gen_op_mftc0_tcstatus();
  4207 + break;
  4208 + case 2:
  4209 + gen_op_mftc0_tcbind();
  4210 + break;
  4211 + case 3:
  4212 + gen_op_mftc0_tcrestart();
  4213 + break;
  4214 + case 4:
  4215 + gen_op_mftc0_tchalt();
  4216 + break;
  4217 + case 5:
  4218 + gen_op_mftc0_tccontext();
  4219 + break;
  4220 + case 6:
  4221 + gen_op_mftc0_tcschedule();
  4222 + break;
  4223 + case 7:
  4224 + gen_op_mftc0_tcschefback();
  4225 + break;
  4226 + default:
  4227 + gen_mfc0(env, ctx, rt, sel);
  4228 + break;
  4229 + }
  4230 + break;
  4231 + case 10:
  4232 + switch (sel) {
  4233 + case 0:
  4234 + gen_op_mftc0_entryhi();
  4235 + break;
  4236 + default:
  4237 + gen_mfc0(env, ctx, rt, sel);
  4238 + break;
  4239 + }
  4240 + case 12:
  4241 + switch (sel) {
  4242 + case 0:
  4243 + gen_op_mftc0_status();
  4244 + break;
  4245 + default:
  4246 + gen_mfc0(env, ctx, rt, sel);
  4247 + break;
  4248 + }
  4249 + case 23:
  4250 + switch (sel) {
  4251 + case 0:
  4252 + gen_op_mftc0_debug();
  4253 + break;
  4254 + default:
  4255 + gen_mfc0(env, ctx, rt, sel);
  4256 + break;
  4257 + }
  4258 + break;
  4259 + default:
  4260 + gen_mfc0(env, ctx, rt, sel);
  4261 + }
  4262 + } else switch (sel) {
  4263 + /* GPR registers. */
  4264 + case 0:
  4265 + gen_op_mftgpr(rt);
  4266 + break;
  4267 + /* Auxiliary CPU registers */
  4268 + case 1:
  4269 + switch (rt) {
  4270 + case 0:
  4271 + gen_op_mftlo(0);
  4272 + break;
  4273 + case 1:
  4274 + gen_op_mfthi(0);
  4275 + break;
  4276 + case 2:
  4277 + gen_op_mftacx(0);
  4278 + break;
  4279 + case 4:
  4280 + gen_op_mftlo(1);
  4281 + break;
  4282 + case 5:
  4283 + gen_op_mfthi(1);
  4284 + break;
  4285 + case 6:
  4286 + gen_op_mftacx(1);
  4287 + break;
  4288 + case 8:
  4289 + gen_op_mftlo(2);
  4290 + break;
  4291 + case 9:
  4292 + gen_op_mfthi(2);
  4293 + break;
  4294 + case 10:
  4295 + gen_op_mftacx(2);
  4296 + break;
  4297 + case 12:
  4298 + gen_op_mftlo(3);
  4299 + break;
  4300 + case 13:
  4301 + gen_op_mfthi(3);
  4302 + break;
  4303 + case 14:
  4304 + gen_op_mftacx(3);
  4305 + break;
  4306 + case 16:
  4307 + gen_op_mftdsp();
  4308 + break;
  4309 + default:
  4310 + goto die;
  4311 + }
  4312 + break;
  4313 + /* Floating point (COP1). */
  4314 + case 2:
  4315 + /* XXX: For now we support only a single FPU context. */
  4316 + if (h == 0) {
  4317 + GEN_LOAD_FREG_FTN(WT0, rt);
  4318 + gen_op_mfc1();
  4319 + } else {
  4320 + GEN_LOAD_FREG_FTN(WTH0, rt);
  4321 + gen_op_mfhc1();
  4322 + }
  4323 + break;
  4324 + case 3:
  4325 + /* XXX: For now we support only a single FPU context. */
  4326 + gen_op_cfc1(rt);
  4327 + break;
  4328 + /* COP2: Not implemented. */
  4329 + case 4:
  4330 + case 5:
  4331 + /* fall through */
  4332 + default:
  4333 + goto die;
  4334 + }
  4335 +#if defined MIPS_DEBUG_DISAS
  4336 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  4337 + fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
  4338 + rt, u, sel, h);
  4339 + }
  4340 +#endif
  4341 + return;
  4342 +
  4343 +die:
  4344 +#if defined MIPS_DEBUG_DISAS
  4345 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  4346 + fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
  4347 + rt, u, sel, h);
  4348 + }
  4349 +#endif
  4350 + generate_exception(ctx, EXCP_RI);
  4351 +}
  4352 +
  4353 +static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
  4354 + int u, int sel, int h)
  4355 +{
  4356 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  4357 +
  4358 + if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
  4359 + ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
  4360 + (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
  4361 + /* NOP */ ;
  4362 + else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
  4363 + (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
  4364 + /* NOP */ ;
  4365 + else if (u == 0) {
  4366 + switch (rd) {
  4367 + case 2:
  4368 + switch (sel) {
  4369 + case 1:
  4370 + gen_op_mttc0_tcstatus();
  4371 + break;
  4372 + case 2:
  4373 + gen_op_mttc0_tcbind();
  4374 + break;
  4375 + case 3:
  4376 + gen_op_mttc0_tcrestart();
  4377 + break;
  4378 + case 4:
  4379 + gen_op_mttc0_tchalt();
  4380 + break;
  4381 + case 5:
  4382 + gen_op_mttc0_tccontext();
  4383 + break;
  4384 + case 6:
  4385 + gen_op_mttc0_tcschedule();
  4386 + break;
  4387 + case 7:
  4388 + gen_op_mttc0_tcschefback();
  4389 + break;
  4390 + default:
  4391 + gen_mtc0(env, ctx, rd, sel);
  4392 + break;
  4393 + }
  4394 + break;
  4395 + case 10:
  4396 + switch (sel) {
  4397 + case 0:
  4398 + gen_op_mttc0_entryhi();
  4399 + break;
  4400 + default:
  4401 + gen_mtc0(env, ctx, rd, sel);
  4402 + break;
  4403 + }
  4404 + case 12:
  4405 + switch (sel) {
  4406 + case 0:
  4407 + gen_op_mttc0_status();
  4408 + break;
  4409 + default:
  4410 + gen_mtc0(env, ctx, rd, sel);
  4411 + break;
  4412 + }
  4413 + case 23:
  4414 + switch (sel) {
  4415 + case 0:
  4416 + gen_op_mttc0_debug();
  4417 + break;
  4418 + default:
  4419 + gen_mtc0(env, ctx, rd, sel);
  4420 + break;
  4421 + }
  4422 + break;
  4423 + default:
  4424 + gen_mtc0(env, ctx, rd, sel);
  4425 + }
  4426 + } else switch (sel) {
  4427 + /* GPR registers. */
  4428 + case 0:
  4429 + gen_op_mttgpr(rd);
  4430 + break;
  4431 + /* Auxiliary CPU registers */
  4432 + case 1:
  4433 + switch (rd) {
  4434 + case 0:
  4435 + gen_op_mttlo(0);
  4436 + break;
  4437 + case 1:
  4438 + gen_op_mtthi(0);
  4439 + break;
  4440 + case 2:
  4441 + gen_op_mttacx(0);
  4442 + break;
  4443 + case 4:
  4444 + gen_op_mttlo(1);
  4445 + break;
  4446 + case 5:
  4447 + gen_op_mtthi(1);
  4448 + break;
  4449 + case 6:
  4450 + gen_op_mttacx(1);
  4451 + break;
  4452 + case 8:
  4453 + gen_op_mttlo(2);
  4454 + break;
  4455 + case 9:
  4456 + gen_op_mtthi(2);
  4457 + break;
  4458 + case 10:
  4459 + gen_op_mttacx(2);
  4460 + break;
  4461 + case 12:
  4462 + gen_op_mttlo(3);
  4463 + break;
  4464 + case 13:
  4465 + gen_op_mtthi(3);
  4466 + break;
  4467 + case 14:
  4468 + gen_op_mttacx(3);
  4469 + break;
  4470 + case 16:
  4471 + gen_op_mttdsp();
  4472 + break;
  4473 + default:
  4474 + goto die;
  4475 + }
  4476 + break;
  4477 + /* Floating point (COP1). */
  4478 + case 2:
  4479 + /* XXX: For now we support only a single FPU context. */
  4480 + if (h == 0) {
  4481 + gen_op_mtc1();
  4482 + GEN_STORE_FTN_FREG(rd, WT0);
  4483 + } else {
  4484 + gen_op_mthc1();
  4485 + GEN_STORE_FTN_FREG(rd, WTH0);
  4486 + }
  4487 + break;
  4488 + case 3:
  4489 + /* XXX: For now we support only a single FPU context. */
  4490 + gen_op_ctc1(rd);
  4491 + break;
  4492 + /* COP2: Not implemented. */
  4493 + case 4:
  4494 + case 5:
  4495 + /* fall through */
  4496 + default:
  4497 + goto die;
  4498 + }
  4499 +#if defined MIPS_DEBUG_DISAS
  4500 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  4501 + fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
  4502 + rd, u, sel, h);
  4503 + }
  4504 +#endif
  4505 + return;
  4506 +
  4507 +die:
  4508 +#if defined MIPS_DEBUG_DISAS
  4509 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  4510 + fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
  4511 + rd, u, sel, h);
  4512 + }
  4513 +#endif
  4514 + generate_exception(ctx, EXCP_RI);
  4515 +}
  4516 +
4089 4517 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4090 4518 {
4091 4519 const char *opn = "ldst";
... ... @@ -4093,7 +4521,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4093 4521 switch (opc) {
4094 4522 case OPC_MFC0:
4095 4523 if (rt == 0) {
4096   - /* Treat as NOP */
  4524 + /* Treat as NOP. */
4097 4525 return;
4098 4526 }
4099 4527 gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
... ... @@ -4110,7 +4538,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4110 4538 if (!(ctx->hflags & MIPS_HFLAG_64))
4111 4539 generate_exception(ctx, EXCP_RI);
4112 4540 if (rt == 0) {
4113   - /* Treat as NOP */
  4541 + /* Treat as NOP. */
4114 4542 return;
4115 4543 }
4116 4544 gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
... ... @@ -4121,31 +4549,49 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4121 4549 if (!(ctx->hflags & MIPS_HFLAG_64))
4122 4550 generate_exception(ctx, EXCP_RI);
4123 4551 GEN_LOAD_REG_TN(T0, rt);
4124   - gen_dmtc0(env,ctx, rd, ctx->opcode & 0x7);
  4552 + gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4125 4553 opn = "dmtc0";
4126 4554 break;
4127 4555 #endif
  4556 + case OPC_MFTR:
  4557 + check_mips_mt(env, ctx);
  4558 + if (rd == 0) {
  4559 + /* Treat as NOP. */
  4560 + return;
  4561 + }
  4562 + gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
  4563 + ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
  4564 + gen_op_store_T0_gpr(rd);
  4565 + opn = "mftr";
  4566 + break;
  4567 + case OPC_MTTR:
  4568 + check_mips_mt(env, ctx);
  4569 + GEN_LOAD_REG_TN(T0, rt);
  4570 + gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
  4571 + ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
  4572 + opn = "mttr";
  4573 + break;
4128 4574 case OPC_TLBWI:
4129 4575 opn = "tlbwi";
4130   - if (!env->do_tlbwi)
  4576 + if (!env->tlb->do_tlbwi)
4131 4577 goto die;
4132 4578 gen_op_tlbwi();
4133 4579 break;
4134 4580 case OPC_TLBWR:
4135 4581 opn = "tlbwr";
4136   - if (!env->do_tlbwr)
  4582 + if (!env->tlb->do_tlbwr)
4137 4583 goto die;
4138 4584 gen_op_tlbwr();
4139 4585 break;
4140 4586 case OPC_TLBP:
4141 4587 opn = "tlbp";
4142   - if (!env->do_tlbp)
  4588 + if (!env->tlb->do_tlbp)
4143 4589 goto die;
4144 4590 gen_op_tlbp();
4145 4591 break;
4146 4592 case OPC_TLBR:
4147 4593 opn = "tlbr";
4148   - if (!env->do_tlbr)
  4594 + if (!env->tlb->do_tlbr)
4149 4595 goto die;
4150 4596 gen_op_tlbr();
4151 4597 break;
... ... @@ -4263,15 +4709,13 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4263 4709 opn = "mtc1";
4264 4710 break;
4265 4711 case OPC_CFC1:
4266   - GEN_LOAD_IMM_TN(T1, fs);
4267   - gen_op_cfc1();
  4712 + gen_op_cfc1(fs);
4268 4713 GEN_STORE_TN_REG(rt, T0);
4269 4714 opn = "cfc1";
4270 4715 break;
4271 4716 case OPC_CTC1:
4272   - GEN_LOAD_IMM_TN(T1, fs);
4273 4717 GEN_LOAD_REG_TN(T0, rt);
4274   - gen_op_ctc1();
  4718 + gen_op_ctc1(fs);
4275 4719 opn = "ctc1";
4276 4720 break;
4277 4721 case OPC_DMFC1:
... ... @@ -5171,8 +5615,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5171 5615 gen_op_addr_add();
5172 5616 }
5173 5617 /* Don't do NOP if destination is zero: we must perform the actual
5174   - * memory access
5175   - */
  5618 + memory access. */
5176 5619 switch (opc) {
5177 5620 case OPC_LWXC1:
5178 5621 op_ldst(lwc1);
... ... @@ -5456,7 +5899,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5456 5899 #endif
5457 5900 break;
5458 5901 case OPC_SYNC:
5459   - /* Treat as a noop. */
  5902 + /* Treat as NOP. */
5460 5903 break;
5461 5904  
5462 5905 case OPC_MOVCI:
... ... @@ -5521,7 +5964,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5521 5964 } else {
5522 5965 generate_exception(ctx, EXCP_DBp);
5523 5966 }
5524   - /* Treat as a noop */
  5967 + /* Treat as NOP. */
5525 5968 break;
5526 5969 #ifdef TARGET_MIPS64
5527 5970 case OPC_DCLZ ... OPC_DCLO:
... ... @@ -5586,7 +6029,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5586 6029 break;
5587 6030 case 29:
5588 6031 #if defined (CONFIG_USER_ONLY)
5589   - gen_op_tls_value ();
  6032 + gen_op_tls_value();
5590 6033 break;
5591 6034 #endif
5592 6035 default: /* Invalid */
... ... @@ -5596,6 +6039,18 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5596 6039 }
5597 6040 GEN_STORE_TN_REG(rt, T0);
5598 6041 break;
  6042 + case OPC_FORK:
  6043 + check_mips_mt(env, ctx);
  6044 + GEN_LOAD_REG_TN(T0, rt);
  6045 + GEN_LOAD_REG_TN(T1, rs);
  6046 + gen_op_fork();
  6047 + break;
  6048 + case OPC_YIELD:
  6049 + check_mips_mt(env, ctx);
  6050 + GEN_LOAD_REG_TN(T0, rs);
  6051 + gen_op_yield();
  6052 + GEN_STORE_TN_REG(rd, T0);
  6053 + break;
5599 6054 #ifdef TARGET_MIPS64
5600 6055 case OPC_DEXTM ... OPC_DEXT:
5601 6056 case OPC_DINSM ... OPC_DINS:
... ... @@ -5642,7 +6097,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5642 6097 break;
5643 6098 case OPC_SYNCI:
5644 6099 check_mips_r2(env, ctx);
5645   - /* treat as noop */
  6100 + /* Treat as NOP. */
5646 6101 break;
5647 6102 default: /* Invalid */
5648 6103 MIPS_INVAL("regimm");
... ... @@ -5657,6 +6112,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5657 6112 switch (op1) {
5658 6113 case OPC_MFC0:
5659 6114 case OPC_MTC0:
  6115 + case OPC_MFTR:
  6116 + case OPC_MTTR:
5660 6117 #ifdef TARGET_MIPS64
5661 6118 case OPC_DMFC0:
5662 6119 case OPC_DMTC0:
... ... @@ -5670,6 +6127,22 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5670 6127 check_mips_r2(env, ctx);
5671 6128 op2 = MASK_MFMC0(ctx->opcode);
5672 6129 switch (op2) {
  6130 + case OPC_DMT:
  6131 + check_mips_mt(env, ctx);
  6132 + gen_op_dmt();
  6133 + break;
  6134 + case OPC_EMT:
  6135 + check_mips_mt(env, ctx);
  6136 + gen_op_emt();
  6137 + break;
  6138 + case OPC_DVPE:
  6139 + check_mips_mt(env, ctx);
  6140 + gen_op_dvpe();
  6141 + break;
  6142 + case OPC_EVPE:
  6143 + check_mips_mt(env, ctx);
  6144 + gen_op_evpe();
  6145 + break;
5673 6146 case OPC_DI:
5674 6147 gen_op_di();
5675 6148 /* Stop translation as we may have switched the execution mode */
... ... @@ -5688,11 +6161,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5688 6161 GEN_STORE_TN_REG(rt, T0);
5689 6162 break;
5690 6163 case OPC_RDPGPR:
  6164 + check_mips_r2(env, ctx);
  6165 + GEN_LOAD_SRSREG_TN(T0, rt);
  6166 + GEN_STORE_TN_REG(rd, T0);
  6167 + break;
5691 6168 case OPC_WRPGPR:
5692 6169 check_mips_r2(env, ctx);
5693   - /* Shadow registers not implemented. */
5694 6170 GEN_LOAD_REG_TN(T0, rt);
5695   - GEN_STORE_TN_REG(rd, T0);
  6171 + GEN_STORE_TN_SRSREG(rd, T0);
5696 6172 break;
5697 6173 default:
5698 6174 MIPS_INVAL("cp0");
... ... @@ -5719,10 +6195,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5719 6195 gen_ldst(ctx, op, rt, rs, imm);
5720 6196 break;
5721 6197 case OPC_CACHE:
5722   - /* Treat as a noop */
  6198 + /* Treat as NOP. */
5723 6199 break;
5724 6200 case OPC_PREF:
5725   - /* Treat as a noop */
  6201 + /* Treat as NOP. */
5726 6202 break;
5727 6203  
5728 6204 /* Floating point (COP1). */
... ... @@ -5807,7 +6283,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5807 6283 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5808 6284 break;
5809 6285 case OPC_PREFX:
5810   - /* treat as noop */
  6286 + /* Treat as NOP. */
5811 6287 break;
5812 6288 case OPC_ALNV_PS:
5813 6289 case OPC_MADD_S:
... ... @@ -6079,13 +6555,14 @@ void fpu_dump_state(CPUState *env, FILE *f,
6079 6555  
6080 6556  
6081 6557 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
6082   - env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
6083   - fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
6084   - fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
6085   - fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
  6558 + env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
  6559 + get_float_exception_flags(&env->fpu->fp_status));
  6560 + fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
  6561 + fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
  6562 + fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6086 6563 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6087 6564 fpu_fprintf(f, "%3s: ", fregnames[i]);
6088   - printfpr(&env->fpr[i]);
  6565 + printfpr(&env->fpu->fpr[i]);
6089 6566 }
6090 6567  
6091 6568 #undef printfpr
... ... @@ -6095,7 +6572,7 @@ void dump_fpu (CPUState *env)
6095 6572 {
6096 6573 if (loglevel) {
6097 6574 fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6098   - env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
  6575 + env->PC[env->current_tc], env->HI[0][env->current_tc], env->LO[0][env->current_tc], env->hflags, env->btarget, env->bcond);
6099 6576 fpu_dump_state(env, logfile, fprintf, 0);
6100 6577 }
6101 6578 }
... ... @@ -6112,18 +6589,18 @@ void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6112 6589 {
6113 6590 int i;
6114 6591  
6115   - if (!SIGN_EXT_P(env->PC))
6116   - cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
6117   - if (!SIGN_EXT_P(env->HI))
6118   - cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
6119   - if (!SIGN_EXT_P(env->LO))
6120   - cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
  6592 + if (!SIGN_EXT_P(env->PC[env->current_tc]))
  6593 + cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
  6594 + if (!SIGN_EXT_P(env->HI[env->current_tc]))
  6595 + cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc]);
  6596 + if (!SIGN_EXT_P(env->LO[env->current_tc]))
  6597 + cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc]);
6121 6598 if (!SIGN_EXT_P(env->btarget))
6122 6599 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6123 6600  
6124 6601 for (i = 0; i < 32; i++) {
6125   - if (!SIGN_EXT_P(env->gpr[i]))
6126   - cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
  6602 + if (!SIGN_EXT_P(env->gpr[i][env->current_tc]))
  6603 + cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i][env->current_tc]);
6127 6604 }
6128 6605  
6129 6606 if (!SIGN_EXT_P(env->CP0_EPC))
... ... @@ -6140,11 +6617,11 @@ void cpu_dump_state (CPUState *env, FILE *f,
6140 6617 int i;
6141 6618  
6142 6619 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",
6143   - env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
  6620 + env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6144 6621 for (i = 0; i < 32; i++) {
6145 6622 if ((i & 3) == 0)
6146 6623 cpu_fprintf(f, "GPR%02d:", i);
6147   - cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
  6624 + cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i][env->current_tc]);
6148 6625 if ((i & 3) == 3)
6149 6626 cpu_fprintf(f, "\n");
6150 6627 }
... ... @@ -6183,12 +6660,12 @@ void cpu_reset (CPUMIPSState *env)
6183 6660 if (env->hflags & MIPS_HFLAG_BMASK) {
6184 6661 /* If the exception was raised from a delay slot,
6185 6662 * come back to the jump. */
6186   - env->CP0_ErrorEPC = env->PC - 4;
  6663 + env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6187 6664 } else {
6188   - env->CP0_ErrorEPC = env->PC;
  6665 + env->CP0_ErrorEPC = env->PC[env->current_tc];
6189 6666 }
6190 6667 env->hflags = 0;
6191   - env->PC = (int32_t)0xBFC00000;
  6668 + env->PC[env->current_tc] = (int32_t)0xBFC00000;
6192 6669 env->CP0_Wired = 0;
6193 6670 /* SMP not implemented */
6194 6671 env->CP0_EBase = 0x80000000;
... ...
target-mips/translate_init.c
... ... @@ -43,11 +43,11 @@
43 43  
44 44 /* No config4, no DSP ASE, no large physaddr,
45 45 no external interrupt controller, no vectored interupts,
46   - no 1kb pages, no MT ASE, no SmartMIPS ASE, no trace logic */
  46 + no 1kb pages, no SmartMIPS ASE, no trace logic */
47 47 #define MIPS_CONFIG3 \
48 48 ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \
49 49 (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \
50   - (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL))
  50 + (0 << CP0C3_SM) | (0 << CP0C3_TL))
51 51  
52 52 /* Define a implementation number of 1.
53 53 Define a major version 1, minor version 0. */
... ... @@ -65,9 +65,21 @@ struct mips_def_t {
65 65 int32_t CP0_Config7;
66 66 int32_t SYNCI_Step;
67 67 int32_t CCRes;
68   - int32_t Status_rw_bitmask;
  68 + int32_t CP0_Status_rw_bitmask;
  69 + int32_t CP0_TCStatus_rw_bitmask;
  70 + int32_t CP0_SRSCtl;
69 71 int32_t CP1_fcr0;
70 72 int32_t SEGBITS;
  73 + int32_t CP0_SRSConf0_rw_bitmask;
  74 + int32_t CP0_SRSConf0;
  75 + int32_t CP0_SRSConf1_rw_bitmask;
  76 + int32_t CP0_SRSConf1;
  77 + int32_t CP0_SRSConf2_rw_bitmask;
  78 + int32_t CP0_SRSConf2;
  79 + int32_t CP0_SRSConf3_rw_bitmask;
  80 + int32_t CP0_SRSConf3;
  81 + int32_t CP0_SRSConf4_rw_bitmask;
  82 + int32_t CP0_SRSConf4;
71 83 };
72 84  
73 85 /*****************************************************************************/
... ... @@ -85,7 +97,7 @@ static mips_def_t mips_defs[] =
85 97 .CP0_Config3 = MIPS_CONFIG3,
86 98 .SYNCI_Step = 32,
87 99 .CCRes = 2,
88   - .Status_rw_bitmask = 0x3278FF17,
  100 + .CP0_Status_rw_bitmask = 0x1278FF17,
89 101 },
90 102 {
91 103 .name = "4KEcR1",
... ... @@ -98,7 +110,7 @@ static mips_def_t mips_defs[] =
98 110 .CP0_Config3 = MIPS_CONFIG3,
99 111 .SYNCI_Step = 32,
100 112 .CCRes = 2,
101   - .Status_rw_bitmask = 0x3278FF17,
  113 + .CP0_Status_rw_bitmask = 0x1278FF17,
102 114 },
103 115 {
104 116 .name = "4KEc",
... ... @@ -108,10 +120,10 @@ static mips_def_t mips_defs[] =
108 120 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
109 121 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
110 122 .CP0_Config2 = MIPS_CONFIG2,
111   - .CP0_Config3 = MIPS_CONFIG3,
  123 + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
112 124 .SYNCI_Step = 32,
113 125 .CCRes = 2,
114   - .Status_rw_bitmask = 0x3278FF17,
  126 + .CP0_Status_rw_bitmask = 0x1278FF17,
115 127 },
116 128 {
117 129 .name = "24Kc",
... ... @@ -121,10 +133,11 @@ static mips_def_t mips_defs[] =
121 133 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
122 134 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
123 135 .CP0_Config2 = MIPS_CONFIG2,
124   - .CP0_Config3 = MIPS_CONFIG3,
  136 + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
125 137 .SYNCI_Step = 32,
126 138 .CCRes = 2,
127   - .Status_rw_bitmask = 0x3278FF17,
  139 + /* No DSP implemented. */
  140 + .CP0_Status_rw_bitmask = 0x1278FF17,
128 141 },
129 142 {
130 143 .name = "24Kf",
... ... @@ -134,13 +147,53 @@ static mips_def_t mips_defs[] =
134 147 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
135 148 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
136 149 .CP0_Config2 = MIPS_CONFIG2,
137   - .CP0_Config3 = MIPS_CONFIG3,
  150 + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
138 151 .SYNCI_Step = 32,
139 152 .CCRes = 2,
140   - .Status_rw_bitmask = 0x3678FF17,
  153 + /* No DSP implemented. */
  154 + .CP0_Status_rw_bitmask = 0x3678FF17,
141 155 .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
142 156 (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
143 157 },
  158 + {
  159 + .name = "34Kf",
  160 + .CP0_PRid = 0x00019500,
  161 + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
  162 + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
  163 + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  164 + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
  165 + .CP0_Config2 = MIPS_CONFIG2,
  166 + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_MT),
  167 + .SYNCI_Step = 32,
  168 + .CCRes = 2,
  169 + /* No DSP implemented. */
  170 + .CP0_Status_rw_bitmask = 0x3678FF17,
  171 + /* No DSP implemented. */
  172 + .CP0_TCStatus_rw_bitmask = (0 << CP0TCSt_TCU3) | (0 << CP0TCSt_TCU2) |
  173 + (1 << CP0TCSt_TCU1) | (1 << CP0TCSt_TCU0) |
  174 + (0 << CP0TCSt_TMX) | (1 << CP0TCSt_DT) |
  175 + (1 << CP0TCSt_DA) | (1 << CP0TCSt_A) |
  176 + (0x3 << CP0TCSt_TKSU) | (1 << CP0TCSt_IXMT) |
  177 + (0xff << CP0TCSt_TASID),
  178 + .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
  179 + (1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID),
  180 + .CP0_SRSCtl = (0xf << CP0SRSCtl_HSS),
  181 + .CP0_SRSConf0_rw_bitmask = 0x3fffffff,
  182 + .CP0_SRSConf0 = (1 << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) |
  183 + (0x3fe << CP0SRSC0_SRS2) | (0x3fe << CP0SRSC0_SRS1),
  184 + .CP0_SRSConf1_rw_bitmask = 0x3fffffff,
  185 + .CP0_SRSConf1 = (1 << CP0SRSC1_M) | (0x3fe << CP0SRSC1_SRS6) |
  186 + (0x3fe << CP0SRSC1_SRS5) | (0x3fe << CP0SRSC1_SRS4),
  187 + .CP0_SRSConf2_rw_bitmask = 0x3fffffff,
  188 + .CP0_SRSConf2 = (1 << CP0SRSC2_M) | (0x3fe << CP0SRSC2_SRS9) |
  189 + (0x3fe << CP0SRSC2_SRS8) | (0x3fe << CP0SRSC2_SRS7),
  190 + .CP0_SRSConf3_rw_bitmask = 0x3fffffff,
  191 + .CP0_SRSConf3 = (1 << CP0SRSC3_M) | (0x3fe << CP0SRSC3_SRS12) |
  192 + (0x3fe << CP0SRSC3_SRS11) | (0x3fe << CP0SRSC3_SRS10),
  193 + .CP0_SRSConf4_rw_bitmask = 0x3fffffff,
  194 + .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) |
  195 + (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
  196 + },
144 197 #ifdef TARGET_MIPS64
145 198 {
146 199 .name = "R4000",
... ... @@ -153,7 +206,7 @@ static mips_def_t mips_defs[] =
153 206 .CP0_Config3 = MIPS_CONFIG3,
154 207 .SYNCI_Step = 16,
155 208 .CCRes = 2,
156   - .Status_rw_bitmask = 0x3678FFFF,
  209 + .CP0_Status_rw_bitmask = 0x3678FFFF,
157 210 /* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
158 211 .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
159 212 .SEGBITS = 40,
... ... @@ -170,7 +223,7 @@ static mips_def_t mips_defs[] =
170 223 .CP0_Config3 = MIPS_CONFIG3,
171 224 .SYNCI_Step = 32,
172 225 .CCRes = 2,
173   - .Status_rw_bitmask = 0x32F8FFFF,
  226 + .CP0_Status_rw_bitmask = 0x32F8FFFF,
174 227 .SEGBITS = 42,
175 228 },
176 229 {
... ... @@ -185,7 +238,7 @@ static mips_def_t mips_defs[] =
185 238 .CP0_Config3 = MIPS_CONFIG3,
186 239 .SYNCI_Step = 32,
187 240 .CCRes = 2,
188   - .Status_rw_bitmask = 0x36F8FFFF,
  241 + .CP0_Status_rw_bitmask = 0x36F8FFFF,
189 242 /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
190 243 .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
191 244 (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
... ... @@ -205,7 +258,7 @@ static mips_def_t mips_defs[] =
205 258 .CP0_Config3 = MIPS_CONFIG3,
206 259 .SYNCI_Step = 32,
207 260 .CCRes = 2,
208   - .Status_rw_bitmask = 0x36FBFFFF,
  261 + .CP0_Status_rw_bitmask = 0x36FBFFFF,
209 262 /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */
210 263 .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
211 264 (1 << FCR0_D) | (1 << FCR0_S) |
... ... @@ -245,27 +298,88 @@ void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
245 298 #ifndef CONFIG_USER_ONLY
246 299 static void no_mmu_init (CPUMIPSState *env, mips_def_t *def)
247 300 {
248   - env->nb_tlb = 1;
249   - env->map_address = &no_mmu_map_address;
  301 + env->tlb->nb_tlb = 1;
  302 + env->tlb->map_address = &no_mmu_map_address;
250 303 }
251 304  
252 305 static void fixed_mmu_init (CPUMIPSState *env, mips_def_t *def)
253 306 {
254   - env->nb_tlb = 1;
255   - env->map_address = &fixed_mmu_map_address;
  307 + env->tlb->nb_tlb = 1;
  308 + env->tlb->map_address = &fixed_mmu_map_address;
256 309 }
257 310  
258 311 static void r4k_mmu_init (CPUMIPSState *env, mips_def_t *def)
259 312 {
260   - env->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
261   - env->map_address = &r4k_map_address;
262   - env->do_tlbwi = r4k_do_tlbwi;
263   - env->do_tlbwr = r4k_do_tlbwr;
264   - env->do_tlbp = r4k_do_tlbp;
265   - env->do_tlbr = r4k_do_tlbr;
  313 + env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
  314 + env->tlb->map_address = &r4k_map_address;
  315 + env->tlb->do_tlbwi = r4k_do_tlbwi;
  316 + env->tlb->do_tlbwr = r4k_do_tlbwr;
  317 + env->tlb->do_tlbp = r4k_do_tlbp;
  318 + env->tlb->do_tlbr = r4k_do_tlbr;
  319 +}
  320 +
  321 +static void mmu_init (CPUMIPSState *env, mips_def_t *def)
  322 +{
  323 + env->tlb = qemu_mallocz(sizeof(CPUMIPSTLBContext));
  324 +
  325 + /* There are more full-featured MMU variants in older MIPS CPUs,
  326 + R3000, R6000 and R8000 come to mind. If we ever support them,
  327 + this check will need to look up a different place than those
  328 + newfangled config registers. */
  329 + switch ((env->CP0_Config0 >> CP0C0_MT) & 3) {
  330 + case 0:
  331 + no_mmu_init(env, def);
  332 + break;
  333 + case 1:
  334 + r4k_mmu_init(env, def);
  335 + break;
  336 + case 3:
  337 + fixed_mmu_init(env, def);
  338 + break;
  339 + default:
  340 + cpu_abort(env, "MMU type not supported\n");
  341 + }
  342 + env->CP0_Random = env->tlb->nb_tlb - 1;
  343 + env->tlb->tlb_in_use = env->tlb->nb_tlb;
266 344 }
267 345 #endif /* CONFIG_USER_ONLY */
268 346  
  347 +static void fpu_init (CPUMIPSState *env, mips_def_t *def)
  348 +{
  349 + env->fpu = qemu_mallocz(sizeof(CPUMIPSFPUContext));
  350 +
  351 + env->fpu->fcr0 = def->CP1_fcr0;
  352 +#ifdef CONFIG_USER_ONLY
  353 + if (env->CP0_Config1 & (1 << CP0C1_FP))
  354 + env->hflags |= MIPS_HFLAG_FPU;
  355 + if (env->fpu->fcr0 & (1 << FCR0_F64))
  356 + env->hflags |= MIPS_HFLAG_F64;
  357 +#endif
  358 +}
  359 +
  360 +static void mvp_init (CPUMIPSState *env, mips_def_t *def)
  361 +{
  362 + env->mvp = qemu_mallocz(sizeof(CPUMIPSMVPContext));
  363 +
  364 + /* MVPConf1 implemented, TLB sharable, no gating storage support,
  365 + programmable cache partitioning implemented, number of allocatable
  366 + and sharable TLB entries, MVP has allocatable TCs, 2 VPEs
  367 + implemented, 5 TCs implemented. */
  368 + env->mvp->CP0_MVPConf0 = (1 << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) |
  369 + (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) |
  370 + (env->tlb->nb_tlb << CP0MVPC0_PTLBE) |
  371 +// TODO: actually do 2 VPEs.
  372 +// (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) |
  373 +// (0x04 << CP0MVPC0_PTC);
  374 + (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) |
  375 + (0x04 << CP0MVPC0_PTC);
  376 + /* Allocatable CP1 have media extensions, allocatable CP1 have FP support,
  377 + no UDI implemented, no CP2 implemented, 1 CP1 implemented. */
  378 + env->mvp->CP0_MVPConf1 = (1 << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) |
  379 + (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) |
  380 + (0x1 << CP0MVPC1_PCP1);
  381 +}
  382 +
269 383 int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
270 384 {
271 385 if (!def)
... ... @@ -285,8 +399,9 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
285 399 env->CP0_Config7 = def->CP0_Config7;
286 400 env->SYNCI_Step = def->SYNCI_Step;
287 401 env->CCRes = def->CCRes;
288   - env->Status_rw_bitmask = def->Status_rw_bitmask;
289   - env->fcr0 = def->CP1_fcr0;
  402 + env->CP0_Status_rw_bitmask = def->CP0_Status_rw_bitmask;
  403 + env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask;
  404 + env->CP0_SRSCtl = def->CP0_SRSCtl;
290 405 #ifdef TARGET_MIPS64
291 406 if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
292 407 {
... ... @@ -298,31 +413,21 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
298 413 env->SEGMask = 0xFFFFFFFF;
299 414 }
300 415 #endif
301   -#ifdef CONFIG_USER_ONLY
302   - if (env->CP0_Config1 & (1 << CP0C1_FP))
303   - env->hflags |= MIPS_HFLAG_FPU;
304   - if (env->fcr0 & (1 << FCR0_F64))
305   - env->hflags |= MIPS_HFLAG_F64;
306   -#else
307   - /* There are more full-featured MMU variants in older MIPS CPUs,
308   - R3000, R6000 and R8000 come to mind. If we ever support them,
309   - this check will need to look up a different place than those
310   - newfangled config registers. */
311   - switch ((env->CP0_Config0 >> CP0C0_MT) & 3) {
312   - case 0:
313   - no_mmu_init(env, def);
314   - break;
315   - case 1:
316   - r4k_mmu_init(env, def);
317   - break;
318   - case 3:
319   - fixed_mmu_init(env, def);
320   - break;
321   - default:
322   - cpu_abort(env, "MMU type not supported\n");
323   - }
324   - env->CP0_Random = env->nb_tlb - 1;
325   - env->tlb_in_use = env->nb_tlb;
326   -#endif /* CONFIG_USER_ONLY */
  416 + env->CP0_SRSConf0_rw_bitmask = def->CP0_SRSConf0_rw_bitmask;
  417 + env->CP0_SRSConf0 = def->CP0_SRSConf0;
  418 + env->CP0_SRSConf1_rw_bitmask = def->CP0_SRSConf1_rw_bitmask;
  419 + env->CP0_SRSConf1 = def->CP0_SRSConf1;
  420 + env->CP0_SRSConf2_rw_bitmask = def->CP0_SRSConf2_rw_bitmask;
  421 + env->CP0_SRSConf2 = def->CP0_SRSConf2;
  422 + env->CP0_SRSConf3_rw_bitmask = def->CP0_SRSConf3_rw_bitmask;
  423 + env->CP0_SRSConf3 = def->CP0_SRSConf3;
  424 + env->CP0_SRSConf4_rw_bitmask = def->CP0_SRSConf4_rw_bitmask;
  425 + env->CP0_SRSConf4 = def->CP0_SRSConf4;
  426 +
  427 +#ifndef CONFIG_USER_ONLY
  428 + mmu_init(env, def);
  429 +#endif
  430 + fpu_init(env, def);
  431 + mvp_init(env, def);
327 432 return 0;
328 433 }
... ...
translate-all.c
... ... @@ -305,7 +305,7 @@ int cpu_restore_state(TranslationBlock *tb,
305 305 #elif defined(TARGET_M68K)
306 306 env->pc = gen_opc_pc[j];
307 307 #elif defined(TARGET_MIPS)
308   - env->PC = gen_opc_pc[j];
  308 + env->PC[env->current_tc] = gen_opc_pc[j];
309 309 env->hflags &= ~MIPS_HFLAG_BMASK;
310 310 env->hflags |= gen_opc_hflags[j];
311 311 #elif defined(TARGET_ALPHA)
... ...