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,7 +194,7 @@ static inline TranslationBlock *tb_find_fast(void)
194 #elif defined(TARGET_MIPS) 194 #elif defined(TARGET_MIPS)
195 flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK); 195 flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
196 cs_base = 0; 196 cs_base = 0;
197 - pc = env->PC; 197 + pc = env->PC[env->current_tc];
198 #elif defined(TARGET_M68K) 198 #elif defined(TARGET_M68K)
199 flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */ 199 flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
200 | (env->sr & SR_S) /* Bit 13 */ 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,17 +559,17 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
559 ptr = mem_buf; 559 ptr = mem_buf;
560 for (i = 0; i < 32; i++) 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 ptr += sizeof(target_ulong); 563 ptr += sizeof(target_ulong);
564 } 564 }
565 565
566 *(target_ulong *)ptr = tswapl(env->CP0_Status); 566 *(target_ulong *)ptr = tswapl(env->CP0_Status);
567 ptr += sizeof(target_ulong); 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 ptr += sizeof(target_ulong); 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 ptr += sizeof(target_ulong); 573 ptr += sizeof(target_ulong);
574 574
575 *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr); 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,21 +578,21 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
578 *(target_ulong *)ptr = tswapl(env->CP0_Cause); 578 *(target_ulong *)ptr = tswapl(env->CP0_Cause);
579 ptr += sizeof(target_ulong); 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 ptr += sizeof(target_ulong); 582 ptr += sizeof(target_ulong);
583 583
584 if (env->CP0_Config1 & (1 << CP0C1_FP)) 584 if (env->CP0_Config1 & (1 << CP0C1_FP))
585 { 585 {
586 for (i = 0; i < 32; i++) 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 ptr += sizeof(target_ulong); 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 ptr += sizeof(target_ulong); 593 ptr += sizeof(target_ulong);
594 594
595 - *(target_ulong *)ptr = tswapl(env->fcr0); 595 + *(target_ulong *)ptr = tswapl(env->fpu->fcr0);
596 ptr += sizeof(target_ulong); 596 ptr += sizeof(target_ulong);
597 } 597 }
598 598
@@ -611,7 +611,7 @@ static unsigned int ieee_rm[] = @@ -611,7 +611,7 @@ static unsigned int ieee_rm[] =
611 float_round_down 611 float_round_down
612 }; 612 };
613 #define RESTORE_ROUNDING_MODE \ 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 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) 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,17 +621,17 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
621 ptr = mem_buf; 621 ptr = mem_buf;
622 for (i = 0; i < 32; i++) 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 ptr += sizeof(target_ulong); 625 ptr += sizeof(target_ulong);
626 } 626 }
627 627
628 env->CP0_Status = tswapl(*(target_ulong *)ptr); 628 env->CP0_Status = tswapl(*(target_ulong *)ptr);
629 ptr += sizeof(target_ulong); 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 ptr += sizeof(target_ulong); 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 ptr += sizeof(target_ulong); 635 ptr += sizeof(target_ulong);
636 636
637 env->CP0_BadVAddr = tswapl(*(target_ulong *)ptr); 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,21 +640,21 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
640 env->CP0_Cause = tswapl(*(target_ulong *)ptr); 640 env->CP0_Cause = tswapl(*(target_ulong *)ptr);
641 ptr += sizeof(target_ulong); 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 ptr += sizeof(target_ulong); 644 ptr += sizeof(target_ulong);
645 645
646 if (env->CP0_Config1 & (1 << CP0C1_FP)) 646 if (env->CP0_Config1 & (1 << CP0C1_FP))
647 { 647 {
648 for (i = 0; i < 32; i++) 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 ptr += sizeof(target_ulong); 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 ptr += sizeof(target_ulong); 655 ptr += sizeof(target_ulong);
656 656
657 - env->fcr0 = tswapl(*(target_ulong *)ptr); 657 + env->fpu->fcr0 = tswapl(*(target_ulong *)ptr);
658 ptr += sizeof(target_ulong); 658 ptr += sizeof(target_ulong);
659 659
660 /* set rounding mode */ 660 /* set rounding mode */
@@ -775,7 +775,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) @@ -775,7 +775,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
775 #elif defined (TARGET_SH4) 775 #elif defined (TARGET_SH4)
776 env->pc = addr; 776 env->pc = addr;
777 #elif defined (TARGET_MIPS) 777 #elif defined (TARGET_MIPS)
778 - env->PC = addr; 778 + env->PC[env->current_tc] = addr;
779 #endif 779 #endif
780 } 780 }
781 #ifdef CONFIG_USER_ONLY 781 #ifdef CONFIG_USER_ONLY
@@ -799,7 +799,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) @@ -799,7 +799,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
799 #elif defined (TARGET_SH4) 799 #elif defined (TARGET_SH4)
800 env->pc = addr; 800 env->pc = addr;
801 #elif defined (TARGET_MIPS) 801 #elif defined (TARGET_MIPS)
802 - env->PC = addr; 802 + env->PC[env->current_tc] = addr;
803 #endif 803 #endif
804 } 804 }
805 cpu_single_step(env, 1); 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,7 +77,7 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
77 if (kernel_size >= 0) { 77 if (kernel_size >= 0) {
78 if ((entry & ~0x7fffffffULL) == 0x80000000) 78 if ((entry & ~0x7fffffffULL) == 0x80000000)
79 entry = (int32_t)entry; 79 entry = (int32_t)entry;
80 - env->PC = entry; 80 + env->PC[env->current_tc] = entry;
81 } else { 81 } else {
82 fprintf(stderr, "qemu: could not load kernel '%s'\n", 82 fprintf(stderr, "qemu: could not load kernel '%s'\n",
83 kernel_filename); 83 kernel_filename);
hw/mips_timer.c
@@ -10,7 +10,7 @@ uint32_t cpu_mips_get_random (CPUState *env) @@ -10,7 +10,7 @@ uint32_t cpu_mips_get_random (CPUState *env)
10 static uint32_t seed = 0; 10 static uint32_t seed = 0;
11 uint32_t idx; 11 uint32_t idx;
12 seed = seed * 314159 + 1; 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 return idx; 14 return idx;
15 } 15 }
16 16
linux-user/main.c
@@ -1374,8 +1374,8 @@ void cpu_loop(CPUMIPSState *env) @@ -1374,8 +1374,8 @@ void cpu_loop(CPUMIPSState *env)
1374 trapnr = cpu_mips_exec(env); 1374 trapnr = cpu_mips_exec(env);
1375 switch(trapnr) { 1375 switch(trapnr) {
1376 case EXCP_SYSCALL: 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 if (syscall_num >= sizeof(mips_syscall_args)) { 1379 if (syscall_num >= sizeof(mips_syscall_args)) {
1380 ret = -ENOSYS; 1380 ret = -ENOSYS;
1381 } else { 1381 } else {
@@ -1384,7 +1384,7 @@ void cpu_loop(CPUMIPSState *env) @@ -1384,7 +1384,7 @@ void cpu_loop(CPUMIPSState *env)
1384 target_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0; 1384 target_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
1385 1385
1386 nb_args = mips_syscall_args[syscall_num]; 1386 nb_args = mips_syscall_args[syscall_num];
1387 - sp_reg = env->gpr[29]; 1387 + sp_reg = env->gpr[29][env->current_tc];
1388 switch (nb_args) { 1388 switch (nb_args) {
1389 /* these arguments are taken from the stack */ 1389 /* these arguments are taken from the stack */
1390 case 8: arg8 = tgetl(sp_reg + 28); 1390 case 8: arg8 = tgetl(sp_reg + 28);
@@ -1394,18 +1394,20 @@ void cpu_loop(CPUMIPSState *env) @@ -1394,18 +1394,20 @@ void cpu_loop(CPUMIPSState *env)
1394 default: 1394 default:
1395 break; 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 arg5, arg6/*, arg7, arg8*/); 1402 arg5, arg6/*, arg7, arg8*/);
1401 } 1403 }
1402 if ((unsigned int)ret >= (unsigned int)(-1133)) { 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 ret = -ret; 1406 ret = -ret;
1405 } else { 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 break; 1411 break;
1410 case EXCP_TLBL: 1412 case EXCP_TLBL:
1411 case EXCP_TLBS: 1413 case EXCP_TLBS:
@@ -2053,9 +2055,9 @@ int main(int argc, char **argv) @@ -2053,9 +2055,9 @@ int main(int argc, char **argv)
2053 cpu_mips_register(env, def); 2055 cpu_mips_register(env, def);
2054 2056
2055 for(i = 0; i < 32; i++) { 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 #elif defined(TARGET_SH4) 2062 #elif defined(TARGET_SH4)
2061 { 2063 {
linux-user/signal.c
@@ -1686,10 +1686,10 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc) @@ -1686,10 +1686,10 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1686 { 1686 {
1687 int err = 0; 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 } while(0) 1693 } while(0)
1694 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); 1694 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
1695 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); 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,8 +1702,8 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1702 save_gp_reg(31); 1702 save_gp_reg(31);
1703 #undef save_gp_reg 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 /* Not used yet, but might be useful if we ever have DSP suppport */ 1708 /* Not used yet, but might be useful if we ever have DSP suppport */
1709 #if 0 1709 #if 0
@@ -1763,11 +1763,11 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc) @@ -1763,11 +1763,11 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1763 1763
1764 err |= __get_user(regs->CP0_EPC, &sc->sc_pc); 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 } while(0) 1771 } while(0)
1772 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); 1772 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
1773 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); 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,7 +1833,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
1833 unsigned long sp; 1833 unsigned long sp;
1834 1834
1835 /* Default to using normal stack */ 1835 /* Default to using normal stack */
1836 - sp = regs->gpr[29]; 1836 + sp = regs->gpr[29][regs->current_tc];
1837 1837
1838 /* 1838 /*
1839 * FPU emulator may have it's own trampoline active just 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,15 +1881,15 @@ static void setup_frame(int sig, struct emulated_sigaction * ka,
1881 * $25 and PC point to the signal handler, $29 points to the 1881 * $25 and PC point to the signal handler, $29 points to the
1882 * struct sigframe. 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 /* The original kernel code sets CP0_EPC to the handler 1889 /* The original kernel code sets CP0_EPC to the handler
1890 * since it returns to userland using eret 1890 * since it returns to userland using eret
1891 * we cannot do this here, and we must set PC directly */ 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 return; 1893 return;
1894 1894
1895 give_sigsegv: 1895 give_sigsegv:
@@ -1907,7 +1907,7 @@ long do_sigreturn(CPUState *regs) @@ -1907,7 +1907,7 @@ long do_sigreturn(CPUState *regs)
1907 #if defined(DEBUG_SIGNAL) 1907 #if defined(DEBUG_SIGNAL)
1908 fprintf(stderr, "do_sigreturn\n"); 1908 fprintf(stderr, "do_sigreturn\n");
1909 #endif 1909 #endif
1910 - frame = (struct sigframe *) regs->gpr[29]; 1910 + frame = (struct sigframe *) regs->gpr[29][regs->current_tc];
1911 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 1911 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
1912 goto badframe; 1912 goto badframe;
1913 1913
@@ -1934,7 +1934,7 @@ long do_sigreturn(CPUState *regs) @@ -1934,7 +1934,7 @@ long do_sigreturn(CPUState *regs)
1934 /* Unreached */ 1934 /* Unreached */
1935 #endif 1935 #endif
1936 1936
1937 - regs->PC = regs->CP0_EPC; 1937 + regs->PC[regs->current_tc] = regs->CP0_EPC;
1938 /* I am not sure this is right, but it seems to work 1938 /* I am not sure this is right, but it seems to work
1939 * maybe a problem with nested signals ? */ 1939 * maybe a problem with nested signals ? */
1940 regs->CP0_EPC = 0; 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,8 +2189,8 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
2189 /* ??? is this sufficient? */ 2189 /* ??? is this sufficient? */
2190 #elif defined(TARGET_MIPS) 2190 #elif defined(TARGET_MIPS)
2191 if (!newsp) 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 #elif defined(TARGET_PPC) 2194 #elif defined(TARGET_PPC)
2195 if (!newsp) 2195 if (!newsp)
2196 newsp = env->gpr[1]; 2196 newsp = env->gpr[1];
@@ -2777,7 +2777,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2777,7 +2777,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2777 ret = get_errno(pipe(host_pipe)); 2777 ret = get_errno(pipe(host_pipe));
2778 if (!is_error(ret)) { 2778 if (!is_error(ret)) {
2779 #if defined(TARGET_MIPS) 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 ret = host_pipe[0]; 2782 ret = host_pipe[0];
2782 #else 2783 #else
2783 tput32(arg1, host_pipe[0]); 2784 tput32(arg1, host_pipe[0]);
monitor.c
@@ -309,6 +309,10 @@ static void do_info_cpus(void) @@ -309,6 +309,10 @@ static void do_info_cpus(void)
309 term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc); 309 term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
310 if (env->halted) 310 if (env->halted)
311 term_printf(" (halted)"); 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 #endif 316 #endif
313 term_printf("\n"); 317 term_printf("\n");
314 } 318 }
target-mips/cpu.h
@@ -17,21 +17,7 @@ typedef unsigned char uint_fast8_t; @@ -17,21 +17,7 @@ typedef unsigned char uint_fast8_t;
17 typedef unsigned int uint_fast16_t; 17 typedef unsigned int uint_fast16_t;
18 #endif 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 typedef struct r4k_tlb_t r4k_tlb_t; 22 typedef struct r4k_tlb_t r4k_tlb_t;
37 struct r4k_tlb_t { 23 struct r4k_tlb_t {
@@ -48,20 +34,40 @@ struct r4k_tlb_t { @@ -48,20 +34,40 @@ struct r4k_tlb_t {
48 target_ulong PFN[2]; 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 #endif 67 #endif
64 - target_ulong HI, LO; 68 +
  69 +typedef struct CPUMIPSFPUContext CPUMIPSFPUContext;
  70 +struct CPUMIPSFPUContext {
65 /* Floating point registers */ 71 /* Floating point registers */
66 fpr_t fpr[32]; 72 fpr_t fpr[32];
67 #ifndef USE_HOST_FLOAT_REGS 73 #ifndef USE_HOST_FLOAT_REGS
@@ -99,30 +105,161 @@ struct CPUMIPSState { @@ -99,30 +105,161 @@ struct CPUMIPSState {
99 #define FP_DIV0 8 105 #define FP_DIV0 8
100 #define FP_INVALID 16 106 #define FP_INVALID 16
101 #define FP_UNIMPLEMENTED 32 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 uint32_t SEGBITS; 161 uint32_t SEGBITS;
106 target_ulong SEGMask; 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 int32_t CP0_Index; 164 int32_t CP0_Index;
  165 + /* CP0_MVP* are per MVP registers. */
119 int32_t CP0_Random; 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 target_ulong CP0_EntryLo0; 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 target_ulong CP0_EntryLo1; 229 target_ulong CP0_EntryLo1;
122 target_ulong CP0_Context; 230 target_ulong CP0_Context;
123 int32_t CP0_PageMask; 231 int32_t CP0_PageMask;
124 int32_t CP0_PageGrain; 232 int32_t CP0_PageGrain;
125 int32_t CP0_Wired; 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 int32_t CP0_HWREna; 263 int32_t CP0_HWREna;
127 target_ulong CP0_BadVAddr; 264 target_ulong CP0_BadVAddr;
128 int32_t CP0_Count; 265 int32_t CP0_Count;
@@ -152,8 +289,24 @@ struct CPUMIPSState { @@ -152,8 +289,24 @@ struct CPUMIPSState {
152 #define CP0St_EXL 1 289 #define CP0St_EXL 1
153 #define CP0St_IE 0 290 #define CP0St_IE 0
154 int32_t CP0_IntCtl; 291 int32_t CP0_IntCtl;
  292 +#define CP0IntCtl_IPTI 29
  293 +#define CP0IntCtl_IPPC1 26
  294 +#define CP0IntCtl_VS 5
155 int32_t CP0_SRSCtl; 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 int32_t CP0_SRSMap; 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 int32_t CP0_Cause; 310 int32_t CP0_Cause;
158 #define CP0Ca_BD 31 311 #define CP0Ca_BD 31
159 #define CP0Ca_TI 30 312 #define CP0Ca_TI 30
@@ -219,13 +372,14 @@ struct CPUMIPSState { @@ -219,13 +372,14 @@ struct CPUMIPSState {
219 #define CP0C3_TL 0 372 #define CP0C3_TL 0
220 int32_t CP0_Config6; 373 int32_t CP0_Config6;
221 int32_t CP0_Config7; 374 int32_t CP0_Config7;
  375 + /* XXX: Maybe make LLAddr per-TC? */
222 target_ulong CP0_LLAddr; 376 target_ulong CP0_LLAddr;
223 target_ulong CP0_WatchLo[8]; 377 target_ulong CP0_WatchLo[8];
224 int32_t CP0_WatchHi[8]; 378 int32_t CP0_WatchHi[8];
225 target_ulong CP0_XContext; 379 target_ulong CP0_XContext;
226 int32_t CP0_Framemask; 380 int32_t CP0_Framemask;
227 int32_t CP0_Debug; 381 int32_t CP0_Debug;
228 -#define CPDB_DBD 31 382 +#define CP0DB_DBD 31
229 #define CP0DB_DM 30 383 #define CP0DB_DM 30
230 #define CP0DB_LSNM 28 384 #define CP0DB_LSNM 28
231 #define CP0DB_Doze 27 385 #define CP0DB_Doze 27
@@ -243,6 +397,7 @@ struct CPUMIPSState { @@ -243,6 +397,7 @@ struct CPUMIPSState {
243 #define CP0DB_DDBL 2 397 #define CP0DB_DDBL 2
244 #define CP0DB_DBp 1 398 #define CP0DB_DBp 1
245 #define CP0DB_DSS 0 399 #define CP0DB_DSS 0
  400 + int32_t CP0_Debug_tcstatus[MIPS_TC_MAX];
246 target_ulong CP0_DEPC; 401 target_ulong CP0_DEPC;
247 int32_t CP0_Performance0; 402 int32_t CP0_Performance0;
248 int32_t CP0_TagLo; 403 int32_t CP0_TagLo;
@@ -284,7 +439,8 @@ struct CPUMIPSState { @@ -284,7 +439,8 @@ struct CPUMIPSState {
284 439
285 int SYNCI_Step; /* Address step size for SYNCI */ 440 int SYNCI_Step; /* Address step size for SYNCI */
286 int CCRes; /* Cycle count resolution/divisor */ 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 #ifdef CONFIG_USER_ONLY 445 #ifdef CONFIG_USER_ONLY
290 target_ulong tls_value; 446 target_ulong tls_value;
@@ -376,6 +532,7 @@ enum { @@ -376,6 +532,7 @@ enum {
376 EXCP_TLBS, 532 EXCP_TLBS,
377 EXCP_DBE, 533 EXCP_DBE,
378 EXCP_DDBL, 534 EXCP_DDBL,
  535 + EXCP_THREAD,
379 EXCP_MTCP0 = 0x104, /* mtmsr instruction: */ 536 EXCP_MTCP0 = 0x104, /* mtmsr instruction: */
380 /* may change privilege level */ 537 /* may change privilege level */
381 EXCP_BRANCH = 0x108, /* branch instruction */ 538 EXCP_BRANCH = 0x108, /* branch instruction */
target-mips/exec.h
@@ -23,24 +23,24 @@ register target_ulong T2 asm(AREG3); @@ -23,24 +23,24 @@ register target_ulong T2 asm(AREG3);
23 #if defined (USE_HOST_FLOAT_REGS) 23 #if defined (USE_HOST_FLOAT_REGS)
24 #error "implement me." 24 #error "implement me."
25 #else 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 #endif 44 #endif
45 45
46 #if defined (DEBUG_OP) 46 #if defined (DEBUG_OP)
@@ -157,7 +157,8 @@ void cpu_mips_update_irq (CPUState *env); @@ -157,7 +157,8 @@ void cpu_mips_update_irq (CPUState *env);
157 void cpu_mips_clock_init (CPUState *env); 157 void cpu_mips_clock_init (CPUState *env);
158 void cpu_mips_tlb_flush (CPUState *env, int flush_global); 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 #define FOP_PROTO(op) \ 163 #define FOP_PROTO(op) \
163 void do_float_ ## op ## _s(void); \ 164 void do_float_ ## op ## _s(void); \
target-mips/fop_template.c
@@ -24,14 +24,14 @@ @@ -24,14 +24,14 @@
24 #define OP_WLOAD_FREG(treg, tregname, FREG) \ 24 #define OP_WLOAD_FREG(treg, tregname, FREG) \
25 void glue(glue(op_load_fpr_,tregname), FREG) (void) \ 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 RETURN(); \ 28 RETURN(); \
29 } 29 }
30 30
31 #define OP_WSTORE_FREG(treg, tregname, FREG) \ 31 #define OP_WSTORE_FREG(treg, tregname, FREG) \
32 void glue(glue(op_store_fpr_,tregname), FREG) (void) \ 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 RETURN(); \ 35 RETURN(); \
36 } 36 }
37 37
@@ -50,10 +50,10 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG) @@ -50,10 +50,10 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
50 void glue(glue(op_load_fpr_,tregname), FREG) (void) \ 50 void glue(glue(op_load_fpr_,tregname), FREG) (void) \
51 { \ 51 { \
52 if (env->hflags & MIPS_HFLAG_F64) \ 52 if (env->hflags & MIPS_HFLAG_F64) \
53 - treg = env->fpr[FREG].fd; \ 53 + treg = env->fpu->fpr[FREG].fd; \
54 else \ 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 RETURN(); \ 57 RETURN(); \
58 } 58 }
59 59
@@ -61,10 +61,10 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG) @@ -61,10 +61,10 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
61 void glue(glue(op_store_fpr_,tregname), FREG) (void) \ 61 void glue(glue(op_store_fpr_,tregname), FREG) (void) \
62 { \ 62 { \
63 if (env->hflags & MIPS_HFLAG_F64) \ 63 if (env->hflags & MIPS_HFLAG_F64) \
64 - env->fpr[FREG].fd = treg; \ 64 + env->fpu->fpr[FREG].fd = treg; \
65 else { \ 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 RETURN(); \ 69 RETURN(); \
70 } 70 }
@@ -81,14 +81,14 @@ OP_DSTORE_FREG(DT2, DT2_fpr, FREG) @@ -81,14 +81,14 @@ OP_DSTORE_FREG(DT2, DT2_fpr, FREG)
81 #define OP_PSLOAD_FREG(treg, tregname, FREG) \ 81 #define OP_PSLOAD_FREG(treg, tregname, FREG) \
82 void glue(glue(op_load_fpr_,tregname), FREG) (void) \ 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 RETURN(); \ 85 RETURN(); \
86 } 86 }
87 87
88 #define OP_PSSTORE_FREG(treg, tregname, FREG) \ 88 #define OP_PSSTORE_FREG(treg, tregname, FREG) \
89 void glue(glue(op_store_fpr_,tregname), FREG) (void) \ 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 RETURN(); \ 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,8 +70,8 @@ int r4k_map_address (CPUState *env, target_ulong *physical, int *prot,
70 uint8_t ASID = env->CP0_EntryHi & 0xFF; 70 uint8_t ASID = env->CP0_EntryHi & 0xFF;
71 int i; 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 /* 1k pages are not supported. */ 75 /* 1k pages are not supported. */
76 target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); 76 target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
77 target_ulong tag = address & ~mask; 77 target_ulong tag = address & ~mask;
@@ -134,7 +134,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical, @@ -134,7 +134,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
134 *physical = address & 0xFFFFFFFF; 134 *physical = address & 0xFFFFFFFF;
135 *prot = PAGE_READ | PAGE_WRITE; 135 *prot = PAGE_READ | PAGE_WRITE;
136 } else { 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 #ifdef TARGET_MIPS64 139 #ifdef TARGET_MIPS64
140 /* 140 /*
@@ -144,14 +144,14 @@ static int get_physical_address (CPUState *env, target_ulong *physical, @@ -144,14 +144,14 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
144 } else if (address < 0x3FFFFFFFFFFFFFFFULL) { 144 } else if (address < 0x3FFFFFFFFFFFFFFFULL) {
145 /* xuseg */ 145 /* xuseg */
146 if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) { 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 } else { 148 } else {
149 ret = TLBRET_BADADDR; 149 ret = TLBRET_BADADDR;
150 } 150 }
151 } else if (address < 0x7FFFFFFFFFFFFFFFULL) { 151 } else if (address < 0x7FFFFFFFFFFFFFFFULL) {
152 /* xsseg */ 152 /* xsseg */
153 if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) { 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 } else { 155 } else {
156 ret = TLBRET_BADADDR; 156 ret = TLBRET_BADADDR;
157 } 157 }
@@ -169,7 +169,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical, @@ -169,7 +169,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
169 /* xkseg */ 169 /* xkseg */
170 /* XXX: check supervisor mode */ 170 /* XXX: check supervisor mode */
171 if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) { 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 } else { 173 } else {
174 ret = TLBRET_BADADDR; 174 ret = TLBRET_BADADDR;
175 } 175 }
@@ -186,12 +186,12 @@ static int get_physical_address (CPUState *env, target_ulong *physical, @@ -186,12 +186,12 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
186 *prot = PAGE_READ | PAGE_WRITE; 186 *prot = PAGE_READ | PAGE_WRITE;
187 } else if (address < (int32_t)0xE0000000UL) { 187 } else if (address < (int32_t)0xE0000000UL) {
188 /* kseg2 */ 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 } else { 190 } else {
191 /* kseg3 */ 191 /* kseg3 */
192 /* XXX: check supervisor mode */ 192 /* XXX: check supervisor mode */
193 /* XXX: debug segment is not emulated */ 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 #if 0 196 #if 0
197 if (logfile) { 197 if (logfile) {
@@ -238,7 +238,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -238,7 +238,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
238 cpu_dump_state(env, logfile, fprintf, 0); 238 cpu_dump_state(env, logfile, fprintf, 0);
239 #endif 239 #endif
240 fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d is_user %d smmu %d\n", 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 rw &= 1; 244 rw &= 1;
@@ -328,7 +328,7 @@ void do_interrupt (CPUState *env) @@ -328,7 +328,7 @@ void do_interrupt (CPUState *env)
328 328
329 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { 329 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
330 fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n", 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 if (env->exception_index == EXCP_EXT_INTERRUPT && 333 if (env->exception_index == EXCP_EXT_INTERRUPT &&
334 (env->hflags & MIPS_HFLAG_DM)) 334 (env->hflags & MIPS_HFLAG_DM))
@@ -342,7 +342,7 @@ void do_interrupt (CPUState *env) @@ -342,7 +342,7 @@ void do_interrupt (CPUState *env)
342 * (but we assume the pc has always been updated during 342 * (but we assume the pc has always been updated during
343 * code translation). 343 * code translation).
344 */ 344 */
345 - env->CP0_DEPC = env->PC; 345 + env->CP0_DEPC = env->PC[env->current_tc];
346 goto enter_debug_mode; 346 goto enter_debug_mode;
347 case EXCP_DINT: 347 case EXCP_DINT:
348 env->CP0_Debug |= 1 << CP0DB_DINT; 348 env->CP0_Debug |= 1 << CP0DB_DINT;
@@ -362,10 +362,10 @@ void do_interrupt (CPUState *env) @@ -362,10 +362,10 @@ void do_interrupt (CPUState *env)
362 if (env->hflags & MIPS_HFLAG_BMASK) { 362 if (env->hflags & MIPS_HFLAG_BMASK) {
363 /* If the exception was raised from a delay slot, 363 /* If the exception was raised from a delay slot,
364 come back to the jump. */ 364 come back to the jump. */
365 - env->CP0_DEPC = env->PC - 4; 365 + env->CP0_DEPC = env->PC[env->current_tc] - 4;
366 env->hflags &= ~MIPS_HFLAG_BMASK; 366 env->hflags &= ~MIPS_HFLAG_BMASK;
367 } else { 367 } else {
368 - env->CP0_DEPC = env->PC; 368 + env->CP0_DEPC = env->PC[env->current_tc];
369 } 369 }
370 enter_debug_mode: 370 enter_debug_mode:
371 env->hflags |= MIPS_HFLAG_DM; 371 env->hflags |= MIPS_HFLAG_DM;
@@ -375,7 +375,7 @@ void do_interrupt (CPUState *env) @@ -375,7 +375,7 @@ void do_interrupt (CPUState *env)
375 /* EJTAG probe trap enable is not implemented... */ 375 /* EJTAG probe trap enable is not implemented... */
376 if (!(env->CP0_Status & (1 << CP0St_EXL))) 376 if (!(env->CP0_Status & (1 << CP0St_EXL)))
377 env->CP0_Cause &= ~(1 << CP0Ca_BD); 377 env->CP0_Cause &= ~(1 << CP0Ca_BD);
378 - env->PC = (int32_t)0xBFC00480; 378 + env->PC[env->current_tc] = (int32_t)0xBFC00480;
379 break; 379 break;
380 case EXCP_RESET: 380 case EXCP_RESET:
381 cpu_reset(env); 381 cpu_reset(env);
@@ -390,10 +390,10 @@ void do_interrupt (CPUState *env) @@ -390,10 +390,10 @@ void do_interrupt (CPUState *env)
390 if (env->hflags & MIPS_HFLAG_BMASK) { 390 if (env->hflags & MIPS_HFLAG_BMASK) {
391 /* If the exception was raised from a delay slot, 391 /* If the exception was raised from a delay slot,
392 come back to the jump. */ 392 come back to the jump. */
393 - env->CP0_ErrorEPC = env->PC - 4; 393 + env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
394 env->hflags &= ~MIPS_HFLAG_BMASK; 394 env->hflags &= ~MIPS_HFLAG_BMASK;
395 } else { 395 } else {
396 - env->CP0_ErrorEPC = env->PC; 396 + env->CP0_ErrorEPC = env->PC[env->current_tc];
397 } 397 }
398 env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); 398 env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
399 if ((env->CP0_Config0 & (0x3 << CP0C0_AT))) 399 if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
@@ -401,7 +401,7 @@ void do_interrupt (CPUState *env) @@ -401,7 +401,7 @@ void do_interrupt (CPUState *env)
401 env->hflags &= ~MIPS_HFLAG_UM; 401 env->hflags &= ~MIPS_HFLAG_UM;
402 if (!(env->CP0_Status & (1 << CP0St_EXL))) 402 if (!(env->CP0_Status & (1 << CP0St_EXL)))
403 env->CP0_Cause &= ~(1 << CP0Ca_BD); 403 env->CP0_Cause &= ~(1 << CP0Ca_BD);
404 - env->PC = (int32_t)0xBFC00000; 404 + env->PC[env->current_tc] = (int32_t)0xBFC00000;
405 break; 405 break;
406 case EXCP_MCHECK: 406 case EXCP_MCHECK:
407 cause = 24; 407 cause = 24;
@@ -471,6 +471,9 @@ void do_interrupt (CPUState *env) @@ -471,6 +471,9 @@ void do_interrupt (CPUState *env)
471 goto set_EPC; 471 goto set_EPC;
472 case EXCP_TLBS: 472 case EXCP_TLBS:
473 cause = 3; 473 cause = 3;
  474 + goto set_EPC;
  475 + case EXCP_THREAD:
  476 + cause = 25;
474 if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { 477 if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
475 #ifdef TARGET_MIPS64 478 #ifdef TARGET_MIPS64
476 int R = env->CP0_BadVAddr >> 62; 479 int R = env->CP0_BadVAddr >> 62;
@@ -489,10 +492,10 @@ void do_interrupt (CPUState *env) @@ -489,10 +492,10 @@ void do_interrupt (CPUState *env)
489 if (env->hflags & MIPS_HFLAG_BMASK) { 492 if (env->hflags & MIPS_HFLAG_BMASK) {
490 /* If the exception was raised from a delay slot, 493 /* If the exception was raised from a delay slot,
491 come back to the jump. */ 494 come back to the jump. */
492 - env->CP0_EPC = env->PC - 4; 495 + env->CP0_EPC = env->PC[env->current_tc] - 4;
493 env->CP0_Cause |= (1 << CP0Ca_BD); 496 env->CP0_Cause |= (1 << CP0Ca_BD);
494 } else { 497 } else {
495 - env->CP0_EPC = env->PC; 498 + env->CP0_EPC = env->PC[env->current_tc];
496 env->CP0_Cause &= ~(1 << CP0Ca_BD); 499 env->CP0_Cause &= ~(1 << CP0Ca_BD);
497 } 500 }
498 env->CP0_Status |= (1 << CP0St_EXL); 501 env->CP0_Status |= (1 << CP0St_EXL);
@@ -502,11 +505,11 @@ void do_interrupt (CPUState *env) @@ -502,11 +505,11 @@ void do_interrupt (CPUState *env)
502 } 505 }
503 env->hflags &= ~MIPS_HFLAG_BMASK; 506 env->hflags &= ~MIPS_HFLAG_BMASK;
504 if (env->CP0_Status & (1 << CP0St_BEV)) { 507 if (env->CP0_Status & (1 << CP0St_BEV)) {
505 - env->PC = (int32_t)0xBFC00200; 508 + env->PC[env->current_tc] = (int32_t)0xBFC00200;
506 } else { 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 env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC); 513 env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
511 break; 514 break;
512 default: 515 default:
@@ -520,7 +523,7 @@ void do_interrupt (CPUState *env) @@ -520,7 +523,7 @@ void do_interrupt (CPUState *env)
520 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { 523 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
521 fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n" 524 fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n"
522 " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", 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 env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, 527 env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
525 env->CP0_DEPC); 528 env->CP0_DEPC);
526 } 529 }
@@ -536,19 +539,19 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra) @@ -536,19 +539,19 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra)
536 uint8_t ASID = env->CP0_EntryHi & 0xFF; 539 uint8_t ASID = env->CP0_EntryHi & 0xFF;
537 target_ulong mask; 540 target_ulong mask;
538 541
539 - tlb = &env->mmu.r4k.tlb[idx]; 542 + tlb = &env->tlb->mmu.r4k.tlb[idx];
540 /* The qemu TLB is flushed when the ASID changes, so no need to 543 /* The qemu TLB is flushed when the ASID changes, so no need to
541 flush these entries again. */ 544 flush these entries again. */
542 if (tlb->G == 0 && tlb->ASID != ASID) { 545 if (tlb->G == 0 && tlb->ASID != ASID) {
543 return; 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 /* For tlbwr, we can shadow the discarded entry into 550 /* For tlbwr, we can shadow the discarded entry into
548 a new (fake) TLB entry, as long as the guest can not 551 a new (fake) TLB entry, as long as the guest can not
549 tell that it's there. */ 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 return; 555 return;
553 } 556 }
554 557
target-mips/op.c
@@ -254,25 +254,25 @@ void op_dup_T0 (void) @@ -254,25 +254,25 @@ void op_dup_T0 (void)
254 254
255 void op_load_HI (void) 255 void op_load_HI (void)
256 { 256 {
257 - T0 = env->HI; 257 + T0 = env->HI[PARAM1][env->current_tc];
258 RETURN(); 258 RETURN();
259 } 259 }
260 260
261 void op_store_HI (void) 261 void op_store_HI (void)
262 { 262 {
263 - env->HI = T0; 263 + env->HI[PARAM1][env->current_tc] = T0;
264 RETURN(); 264 RETURN();
265 } 265 }
266 266
267 void op_load_LO (void) 267 void op_load_LO (void)
268 { 268 {
269 - T0 = env->LO; 269 + T0 = env->LO[PARAM1][env->current_tc];
270 RETURN(); 270 RETURN();
271 } 271 }
272 272
273 void op_store_LO (void) 273 void op_store_LO (void)
274 { 274 {
275 - env->LO = T0; 275 + env->LO[PARAM1][env->current_tc] = T0;
276 RETURN(); 276 RETURN();
277 } 277 }
278 278
@@ -363,8 +363,8 @@ void op_div (void) @@ -363,8 +363,8 @@ void op_div (void)
363 void op_div (void) 363 void op_div (void)
364 { 364 {
365 if (T1 != 0) { 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 RETURN(); 369 RETURN();
370 } 370 }
@@ -373,8 +373,8 @@ void op_div (void) @@ -373,8 +373,8 @@ void op_div (void)
373 void op_divu (void) 373 void op_divu (void)
374 { 374 {
375 if (T1 != 0) { 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 RETURN(); 379 RETURN();
380 } 380 }
@@ -442,8 +442,8 @@ void op_ddivu (void) @@ -442,8 +442,8 @@ void op_ddivu (void)
442 void op_ddivu (void) 442 void op_ddivu (void)
443 { 443 {
444 if (T1 != 0) { 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 RETURN(); 448 RETURN();
449 } 449 }
@@ -814,13 +814,14 @@ void op_msubu (void) @@ -814,13 +814,14 @@ void op_msubu (void)
814 814
815 static inline uint64_t get_HILO (void) 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 static inline void set_HILO (uint64_t HILO) 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 void op_mult (void) 827 void op_mult (void)
@@ -875,13 +876,13 @@ void op_msubu (void) @@ -875,13 +876,13 @@ void op_msubu (void)
875 #ifdef TARGET_MIPS64 876 #ifdef TARGET_MIPS64
876 void op_dmult (void) 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 RETURN(); 880 RETURN();
880 } 881 }
881 882
882 void op_dmultu (void) 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 RETURN(); 886 RETURN();
886 } 887 }
887 #endif 888 #endif
@@ -890,27 +891,27 @@ void op_dmultu (void) @@ -890,27 +891,27 @@ void op_dmultu (void)
890 void op_movn (void) 891 void op_movn (void)
891 { 892 {
892 if (T1 != 0) 893 if (T1 != 0)
893 - env->gpr[PARAM1] = T0; 894 + env->gpr[PARAM1][env->current_tc] = T0;
894 RETURN(); 895 RETURN();
895 } 896 }
896 897
897 void op_movz (void) 898 void op_movz (void)
898 { 899 {
899 if (T1 == 0) 900 if (T1 == 0)
900 - env->gpr[PARAM1] = T0; 901 + env->gpr[PARAM1][env->current_tc] = T0;
901 RETURN(); 902 RETURN();
902 } 903 }
903 904
904 void op_movf (void) 905 void op_movf (void)
905 { 906 {
906 - if (!(env->fcr31 & PARAM1)) 907 + if (!(env->fpu->fcr31 & PARAM1))
907 T0 = T1; 908 T0 = T1;
908 RETURN(); 909 RETURN();
909 } 910 }
910 911
911 void op_movt (void) 912 void op_movt (void)
912 { 913 {
913 - if (env->fcr31 & PARAM1) 914 + if (env->fpu->fcr31 & PARAM1)
914 T0 = T1; 915 T0 = T1;
915 RETURN(); 916 RETURN();
916 } 917 }
@@ -966,7 +967,7 @@ void op_restore_breg_target (void) @@ -966,7 +967,7 @@ void op_restore_breg_target (void)
966 967
967 void op_breg (void) 968 void op_breg (void)
968 { 969 {
969 - env->PC = T2; 970 + env->PC[env->current_tc] = T2;
970 RETURN(); 971 RETURN();
971 } 972 }
972 973
@@ -1017,18 +1018,176 @@ void op_mfc0_index (void) @@ -1017,18 +1018,176 @@ void op_mfc0_index (void)
1017 RETURN(); 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 void op_mfc0_random (void) 1039 void op_mfc0_random (void)
1021 { 1040 {
1022 CALL_FROM_TB0(do_mfc0_random); 1041 CALL_FROM_TB0(do_mfc0_random);
1023 RETURN(); 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 void op_mfc0_entrylo0 (void) 1087 void op_mfc0_entrylo0 (void)
1027 { 1088 {
1028 T0 = (int32_t)env->CP0_EntryLo0; 1089 T0 = (int32_t)env->CP0_EntryLo0;
1029 RETURN(); 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 void op_mfc0_entrylo1 (void) 1191 void op_mfc0_entrylo1 (void)
1033 { 1192 {
1034 T0 = (int32_t)env->CP0_EntryLo1; 1193 T0 = (int32_t)env->CP0_EntryLo1;
@@ -1059,6 +1218,36 @@ void op_mfc0_wired (void) @@ -1059,6 +1218,36 @@ void op_mfc0_wired (void)
1059 RETURN(); 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 void op_mfc0_hwrena (void) 1251 void op_mfc0_hwrena (void)
1063 { 1252 {
1064 T0 = env->CP0_HWREna; 1253 T0 = env->CP0_HWREna;
@@ -1083,6 +1272,14 @@ void op_mfc0_entryhi (void) @@ -1083,6 +1272,14 @@ void op_mfc0_entryhi (void)
1083 RETURN(); 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 void op_mfc0_compare (void) 1283 void op_mfc0_compare (void)
1087 { 1284 {
1088 T0 = env->CP0_Compare; 1285 T0 = env->CP0_Compare;
@@ -1095,6 +1292,18 @@ void op_mfc0_status (void) @@ -1095,6 +1292,18 @@ void op_mfc0_status (void)
1095 RETURN(); 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 void op_mfc0_intctl (void) 1307 void op_mfc0_intctl (void)
1099 { 1308 {
1100 T0 = env->CP0_IntCtl; 1309 T0 = env->CP0_IntCtl;
@@ -1211,6 +1420,17 @@ void op_mfc0_debug (void) @@ -1211,6 +1420,17 @@ void op_mfc0_debug (void)
1211 RETURN(); 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 void op_mfc0_depc (void) 1434 void op_mfc0_depc (void)
1215 { 1435 {
1216 T0 = (int32_t)env->CP0_DEPC; 1436 T0 = (int32_t)env->CP0_DEPC;
@@ -1261,7 +1481,105 @@ void op_mfc0_desave (void) @@ -1261,7 +1481,105 @@ void op_mfc0_desave (void)
1261 1481
1262 void op_mtc0_index (void) 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 RETURN(); 1583 RETURN();
1266 } 1584 }
1267 1585
@@ -1273,6 +1591,135 @@ void op_mtc0_entrylo0 (void) @@ -1273,6 +1591,135 @@ void op_mtc0_entrylo0 (void)
1273 RETURN(); 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 void op_mtc0_entrylo1 (void) 1723 void op_mtc0_entrylo1 (void)
1277 { 1724 {
1278 /* Large physaddr not implemented */ 1725 /* Large physaddr not implemented */
@@ -1305,7 +1752,37 @@ void op_mtc0_pagegrain (void) @@ -1305,7 +1752,37 @@ void op_mtc0_pagegrain (void)
1305 1752
1306 void op_mtc0_wired (void) 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 RETURN(); 1786 RETURN();
1310 } 1787 }
1311 1788
@@ -1332,12 +1809,25 @@ void op_mtc0_entryhi (void) @@ -1332,12 +1809,25 @@ void op_mtc0_entryhi (void)
1332 #endif 1809 #endif
1333 old = env->CP0_EntryHi; 1810 old = env->CP0_EntryHi;
1334 env->CP0_EntryHi = val; 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 /* If the ASID changes, flush qemu's TLB. */ 1816 /* If the ASID changes, flush qemu's TLB. */
1336 if ((old & 0xFF) != (val & 0xFF)) 1817 if ((old & 0xFF) != (val & 0xFF))
1337 CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1); 1818 CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1338 RETURN(); 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 void op_mtc0_compare (void) 1831 void op_mtc0_compare (void)
1342 { 1832 {
1343 CALL_FROM_TB2(cpu_mips_store_compare, env, T0); 1833 CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
@@ -1347,9 +1837,8 @@ void op_mtc0_compare (void) @@ -1347,9 +1837,8 @@ void op_mtc0_compare (void)
1347 void op_mtc0_status (void) 1837 void op_mtc0_status (void)
1348 { 1838 {
1349 uint32_t val, old; 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 val = T0 & mask; 1842 val = T0 & mask;
1354 old = env->CP0_Status; 1843 old = env->CP0_Status;
1355 if (!(val & (1 << CP0St_EXL)) && 1844 if (!(val & (1 << CP0St_EXL)) &&
@@ -1379,6 +1868,19 @@ void op_mtc0_status (void) @@ -1379,6 +1868,19 @@ void op_mtc0_status (void)
1379 RETURN(); 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 void op_mtc0_intctl (void) 1884 void op_mtc0_intctl (void)
1383 { 1885 {
1384 /* vectored interrupts not implemented, timer on int 7, 1886 /* vectored interrupts not implemented, timer on int 7,
@@ -1389,15 +1891,14 @@ void op_mtc0_intctl (void) @@ -1389,15 +1891,14 @@ void op_mtc0_intctl (void)
1389 1891
1390 void op_mtc0_srsctl (void) 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 RETURN(); 1896 RETURN();
1395 } 1897 }
1396 1898
1397 void op_mtc0_srsmap (void) 1899 void op_mtc0_srsmap (void)
1398 { 1900 {
1399 - /* shadow registers not implemented */  
1400 - env->CP0_SRSMap = 0; 1901 + env->CP0_SRSMap = T0;
1401 RETURN(); 1902 RETURN();
1402 } 1903 }
1403 1904
@@ -1460,6 +1961,13 @@ void op_mtc0_watchhi (void) @@ -1460,6 +1961,13 @@ void op_mtc0_watchhi (void)
1460 RETURN(); 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 void op_mtc0_framemask (void) 1971 void op_mtc0_framemask (void)
1464 { 1972 {
1465 env->CP0_Framemask = T0; /* XXX */ 1973 env->CP0_Framemask = T0; /* XXX */
@@ -1476,6 +1984,17 @@ void op_mtc0_debug (void) @@ -1476,6 +1984,17 @@ void op_mtc0_debug (void)
1476 RETURN(); 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 void op_mtc0_depc (void) 1998 void op_mtc0_depc (void)
1480 { 1999 {
1481 env->CP0_DEPC = T0; 2000 env->CP0_DEPC = T0;
@@ -1525,10 +2044,21 @@ void op_mtc0_desave (void) @@ -1525,10 +2044,21 @@ void op_mtc0_desave (void)
1525 } 2044 }
1526 2045
1527 #ifdef TARGET_MIPS64 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 RETURN(); 2062 RETURN();
1533 } 2063 }
1534 2064
@@ -1538,6 +2068,36 @@ void op_dmfc0_entrylo0 (void) @@ -1538,6 +2068,36 @@ void op_dmfc0_entrylo0 (void)
1538 RETURN(); 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 void op_dmfc0_entrylo1 (void) 2101 void op_dmfc0_entrylo1 (void)
1542 { 2102 {
1543 T0 = env->CP0_EntryLo1; 2103 T0 = env->CP0_EntryLo1;
@@ -1599,6 +2159,157 @@ void op_dmfc0_errorepc (void) @@ -1599,6 +2159,157 @@ void op_dmfc0_errorepc (void)
1599 } 2159 }
1600 #endif /* TARGET_MIPS64 */ 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 /* CP1 functions */ 2313 /* CP1 functions */
1603 #if 0 2314 #if 0
1604 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) 2315 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
@@ -1617,30 +2328,14 @@ void op_cp0_enabled(void) @@ -1617,30 +2328,14 @@ void op_cp0_enabled(void)
1617 2328
1618 void op_cfc1 (void) 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 DEBUG_FPU_STATE(); 2332 DEBUG_FPU_STATE();
1638 RETURN(); 2333 RETURN();
1639 } 2334 }
1640 2335
1641 void op_ctc1 (void) 2336 void op_ctc1 (void)
1642 { 2337 {
1643 - CALL_FROM_TB0(do_ctc1); 2338 + CALL_FROM_TB1(do_ctc1, PARAM1);
1644 DEBUG_FPU_STATE(); 2339 DEBUG_FPU_STATE();
1645 RETURN(); 2340 RETURN();
1646 } 2341 }
@@ -1842,21 +2537,21 @@ FLOAT_ROUNDOP(floor, w, s) @@ -1842,21 +2537,21 @@ FLOAT_ROUNDOP(floor, w, s)
1842 2537
1843 FLOAT_OP(movf, d) 2538 FLOAT_OP(movf, d)
1844 { 2539 {
1845 - if (!(env->fcr31 & PARAM1)) 2540 + if (!(env->fpu->fcr31 & PARAM1))
1846 DT2 = DT0; 2541 DT2 = DT0;
1847 DEBUG_FPU_STATE(); 2542 DEBUG_FPU_STATE();
1848 RETURN(); 2543 RETURN();
1849 } 2544 }
1850 FLOAT_OP(movf, s) 2545 FLOAT_OP(movf, s)
1851 { 2546 {
1852 - if (!(env->fcr31 & PARAM1)) 2547 + if (!(env->fpu->fcr31 & PARAM1))
1853 WT2 = WT0; 2548 WT2 = WT0;
1854 DEBUG_FPU_STATE(); 2549 DEBUG_FPU_STATE();
1855 RETURN(); 2550 RETURN();
1856 } 2551 }
1857 FLOAT_OP(movf, ps) 2552 FLOAT_OP(movf, ps)
1858 { 2553 {
1859 - if (!(env->fcr31 & PARAM1)) { 2554 + if (!(env->fpu->fcr31 & PARAM1)) {
1860 WT2 = WT0; 2555 WT2 = WT0;
1861 WTH2 = WTH0; 2556 WTH2 = WTH0;
1862 } 2557 }
@@ -1865,21 +2560,21 @@ FLOAT_OP(movf, ps) @@ -1865,21 +2560,21 @@ FLOAT_OP(movf, ps)
1865 } 2560 }
1866 FLOAT_OP(movt, d) 2561 FLOAT_OP(movt, d)
1867 { 2562 {
1868 - if (env->fcr31 & PARAM1) 2563 + if (env->fpu->fcr31 & PARAM1)
1869 DT2 = DT0; 2564 DT2 = DT0;
1870 DEBUG_FPU_STATE(); 2565 DEBUG_FPU_STATE();
1871 RETURN(); 2566 RETURN();
1872 } 2567 }
1873 FLOAT_OP(movt, s) 2568 FLOAT_OP(movt, s)
1874 { 2569 {
1875 - if (env->fcr31 & PARAM1) 2570 + if (env->fpu->fcr31 & PARAM1)
1876 WT2 = WT0; 2571 WT2 = WT0;
1877 DEBUG_FPU_STATE(); 2572 DEBUG_FPU_STATE();
1878 RETURN(); 2573 RETURN();
1879 } 2574 }
1880 FLOAT_OP(movt, ps) 2575 FLOAT_OP(movt, ps)
1881 { 2576 {
1882 - if (env->fcr31 & PARAM1) { 2577 + if (env->fpu->fcr31 & PARAM1) {
1883 WT2 = WT0; 2578 WT2 = WT0;
1884 WTH2 = WTH0; 2579 WTH2 = WTH0;
1885 } 2580 }
@@ -1997,24 +2692,24 @@ FLOAT_HOP(mulr) @@ -1997,24 +2692,24 @@ FLOAT_HOP(mulr)
1997 #define FLOAT_TERNOP(name1, name2) \ 2692 #define FLOAT_TERNOP(name1, name2) \
1998 FLOAT_OP(name1 ## name2, d) \ 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 DEBUG_FPU_STATE(); \ 2697 DEBUG_FPU_STATE(); \
2003 RETURN(); \ 2698 RETURN(); \
2004 } \ 2699 } \
2005 FLOAT_OP(name1 ## name2, s) \ 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 DEBUG_FPU_STATE(); \ 2704 DEBUG_FPU_STATE(); \
2010 RETURN(); \ 2705 RETURN(); \
2011 } \ 2706 } \
2012 FLOAT_OP(name1 ## name2, ps) \ 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 DEBUG_FPU_STATE(); \ 2713 DEBUG_FPU_STATE(); \
2019 RETURN(); \ 2714 RETURN(); \
2020 } 2715 }
@@ -2026,26 +2721,26 @@ FLOAT_TERNOP(mul, sub) @@ -2026,26 +2721,26 @@ FLOAT_TERNOP(mul, sub)
2026 #define FLOAT_NTERNOP(name1, name2) \ 2721 #define FLOAT_NTERNOP(name1, name2) \
2027 FLOAT_OP(n ## name1 ## name2, d) \ 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 FDT2 ^= 1ULL << 63; \ 2726 FDT2 ^= 1ULL << 63; \
2032 DEBUG_FPU_STATE(); \ 2727 DEBUG_FPU_STATE(); \
2033 RETURN(); \ 2728 RETURN(); \
2034 } \ 2729 } \
2035 FLOAT_OP(n ## name1 ## name2, s) \ 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 FST2 ^= 1 << 31; \ 2734 FST2 ^= 1 << 31; \
2040 DEBUG_FPU_STATE(); \ 2735 DEBUG_FPU_STATE(); \
2041 RETURN(); \ 2736 RETURN(); \
2042 } \ 2737 } \
2043 FLOAT_OP(n ## name1 ## name2, ps) \ 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 FST2 ^= 1 << 31; \ 2744 FST2 ^= 1 << 31; \
2050 FSTH2 ^= 1 << 31; \ 2745 FSTH2 ^= 1 << 31; \
2051 DEBUG_FPU_STATE(); \ 2746 DEBUG_FPU_STATE(); \
@@ -2059,13 +2754,13 @@ FLOAT_NTERNOP(mul, sub) @@ -2059,13 +2754,13 @@ FLOAT_NTERNOP(mul, sub)
2059 #define FLOAT_UNOP(name) \ 2754 #define FLOAT_UNOP(name) \
2060 FLOAT_OP(name, d) \ 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 DEBUG_FPU_STATE(); \ 2758 DEBUG_FPU_STATE(); \
2064 RETURN(); \ 2759 RETURN(); \
2065 } \ 2760 } \
2066 FLOAT_OP(name, s) \ 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 DEBUG_FPU_STATE(); \ 2764 DEBUG_FPU_STATE(); \
2070 RETURN(); \ 2765 RETURN(); \
2071 } 2766 }
@@ -2141,9 +2836,9 @@ FLOAT_OP(alnv, ps) @@ -2141,9 +2836,9 @@ FLOAT_OP(alnv, ps)
2141 2836
2142 #ifdef CONFIG_SOFTFLOAT 2837 #ifdef CONFIG_SOFTFLOAT
2143 #define clear_invalid() do { \ 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 flags &= ~float_flag_invalid; \ 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 } while(0) 2842 } while(0)
2148 #else 2843 #else
2149 #define clear_invalid() do { } while(0) 2844 #define clear_invalid() do { } while(0)
@@ -2190,63 +2885,63 @@ CMP_OPS(ngt) @@ -2190,63 +2885,63 @@ CMP_OPS(ngt)
2190 2885
2191 void op_bc1f (void) 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 DEBUG_FPU_STATE(); 2889 DEBUG_FPU_STATE();
2195 RETURN(); 2890 RETURN();
2196 } 2891 }
2197 void op_bc1any2f (void) 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 DEBUG_FPU_STATE(); 2895 DEBUG_FPU_STATE();
2201 RETURN(); 2896 RETURN();
2202 } 2897 }
2203 void op_bc1any4f (void) 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 DEBUG_FPU_STATE(); 2901 DEBUG_FPU_STATE();
2207 RETURN(); 2902 RETURN();
2208 } 2903 }
2209 2904
2210 void op_bc1t (void) 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 DEBUG_FPU_STATE(); 2908 DEBUG_FPU_STATE();
2214 RETURN(); 2909 RETURN();
2215 } 2910 }
2216 void op_bc1any2t (void) 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 DEBUG_FPU_STATE(); 2914 DEBUG_FPU_STATE();
2220 RETURN(); 2915 RETURN();
2221 } 2916 }
2222 void op_bc1any4t (void) 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 DEBUG_FPU_STATE(); 2920 DEBUG_FPU_STATE();
2226 RETURN(); 2921 RETURN();
2227 } 2922 }
2228 2923
2229 void op_tlbwi (void) 2924 void op_tlbwi (void)
2230 { 2925 {
2231 - CALL_FROM_TB0(env->do_tlbwi); 2926 + CALL_FROM_TB0(env->tlb->do_tlbwi);
2232 RETURN(); 2927 RETURN();
2233 } 2928 }
2234 2929
2235 void op_tlbwr (void) 2930 void op_tlbwr (void)
2236 { 2931 {
2237 - CALL_FROM_TB0(env->do_tlbwr); 2932 + CALL_FROM_TB0(env->tlb->do_tlbwr);
2238 RETURN(); 2933 RETURN();
2239 } 2934 }
2240 2935
2241 void op_tlbp (void) 2936 void op_tlbp (void)
2242 { 2937 {
2243 - CALL_FROM_TB0(env->do_tlbp); 2938 + CALL_FROM_TB0(env->tlb->do_tlbp);
2244 RETURN(); 2939 RETURN();
2245 } 2940 }
2246 2941
2247 void op_tlbr (void) 2942 void op_tlbr (void)
2248 { 2943 {
2249 - CALL_FROM_TB0(env->do_tlbr); 2944 + CALL_FROM_TB0(env->tlb->do_tlbr);
2250 RETURN(); 2945 RETURN();
2251 } 2946 }
2252 2947
@@ -2307,10 +3002,10 @@ void op_eret (void) @@ -2307,10 +3002,10 @@ void op_eret (void)
2307 if (loglevel & CPU_LOG_EXEC) 3002 if (loglevel & CPU_LOG_EXEC)
2308 CALL_FROM_TB0(debug_pre_eret); 3003 CALL_FROM_TB0(debug_pre_eret);
2309 if (env->CP0_Status & (1 << CP0St_ERL)) { 3004 if (env->CP0_Status & (1 << CP0St_ERL)) {
2310 - env->PC = env->CP0_ErrorEPC; 3005 + env->PC[env->current_tc] = env->CP0_ErrorEPC;
2311 env->CP0_Status &= ~(1 << CP0St_ERL); 3006 env->CP0_Status &= ~(1 << CP0St_ERL);
2312 } else { 3007 } else {
2313 - env->PC = env->CP0_EPC; 3008 + env->PC[env->current_tc] = env->CP0_EPC;
2314 env->CP0_Status &= ~(1 << CP0St_EXL); 3009 env->CP0_Status &= ~(1 << CP0St_EXL);
2315 } 3010 }
2316 if (!(env->CP0_Status & (1 << CP0St_EXL)) && 3011 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
@@ -2335,7 +3030,7 @@ void op_deret (void) @@ -2335,7 +3030,7 @@ void op_deret (void)
2335 { 3030 {
2336 if (loglevel & CPU_LOG_EXEC) 3031 if (loglevel & CPU_LOG_EXEC)
2337 CALL_FROM_TB0(debug_pre_eret); 3032 CALL_FROM_TB0(debug_pre_eret);
2338 - env->PC = env->CP0_DEPC; 3033 + env->PC[env->current_tc] = env->CP0_DEPC;
2339 env->hflags |= MIPS_HFLAG_DM; 3034 env->hflags |= MIPS_HFLAG_DM;
2340 if (!(env->CP0_Status & (1 << CP0St_EXL)) && 3035 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
2341 !(env->CP0_Status & (1 << CP0St_ERL)) && 3036 !(env->CP0_Status & (1 << CP0St_ERL)) &&
@@ -2407,14 +3102,14 @@ void op_save_state (void) @@ -2407,14 +3102,14 @@ void op_save_state (void)
2407 3102
2408 void op_save_pc (void) 3103 void op_save_pc (void)
2409 { 3104 {
2410 - env->PC = PARAM1; 3105 + env->PC[env->current_tc] = PARAM1;
2411 RETURN(); 3106 RETURN();
2412 } 3107 }
2413 3108
2414 #ifdef TARGET_MIPS64 3109 #ifdef TARGET_MIPS64
2415 void op_save_pc64 (void) 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 RETURN(); 3113 RETURN();
2419 } 3114 }
2420 #endif 3115 #endif
target-mips/op_helper.c
@@ -160,13 +160,13 @@ void do_drotrv (void) @@ -160,13 +160,13 @@ void do_drotrv (void)
160 #if TARGET_LONG_BITS > HOST_LONG_BITS 160 #if TARGET_LONG_BITS > HOST_LONG_BITS
161 static inline uint64_t get_HILO (void) 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 static inline void set_HILO (uint64_t HILO) 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 void do_mult (void) 172 void do_mult (void)
@@ -217,8 +217,8 @@ void do_div (void) @@ -217,8 +217,8 @@ void do_div (void)
217 { 217 {
218 /* 64bit datatypes because we may see overflow/underflow. */ 218 /* 64bit datatypes because we may see overflow/underflow. */
219 if (T1 != 0) { 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 #endif 224 #endif
@@ -228,8 +228,8 @@ void do_ddiv (void) @@ -228,8 +228,8 @@ void do_ddiv (void)
228 { 228 {
229 if (T1 != 0) { 229 if (T1 != 0) {
230 lldiv_t res = lldiv((int64_t)T0, (int64_t)T1); 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,8 +237,8 @@ void do_ddiv (void)
237 void do_ddivu (void) 237 void do_ddivu (void)
238 { 238 {
239 if (T1 != 0) { 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 #endif 244 #endif
@@ -316,10 +316,10 @@ void do_mtc0_status_irqraise_debug(void) @@ -316,10 +316,10 @@ void do_mtc0_status_irqraise_debug(void)
316 void fpu_handle_exception(void) 316 void fpu_handle_exception(void)
317 { 317 {
318 #ifdef CONFIG_SOFTFLOAT 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 unsigned int cpuflags = 0, enable, cause = 0; 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 /* determine current flags */ 324 /* determine current flags */
325 if (flags & float_flag_invalid) { 325 if (flags & float_flag_invalid) {
@@ -342,11 +342,11 @@ void fpu_handle_exception(void) @@ -342,11 +342,11 @@ void fpu_handle_exception(void)
342 cpuflags |= FP_INEXACT; 342 cpuflags |= FP_INEXACT;
343 cause |= FP_INEXACT & enable; 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 #else 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 #endif 350 #endif
351 } 351 }
352 352
@@ -355,14 +355,14 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global) @@ -355,14 +355,14 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global)
355 { 355 {
356 /* Flush qemu's TLB and discard all shadowed entries. */ 356 /* Flush qemu's TLB and discard all shadowed entries. */
357 tlb_flush (env, flush_global); 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 static void r4k_mips_tlb_flush_extra (CPUState *env, int first) 361 static void r4k_mips_tlb_flush_extra (CPUState *env, int first)
362 { 362 {
363 /* Discard entries from env->tlb[first] onwards. */ 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,7 +371,7 @@ static void r4k_fill_tlb (int idx)
371 r4k_tlb_t *tlb; 371 r4k_tlb_t *tlb;
372 372
373 /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */ 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 tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1); 375 tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
376 #ifdef TARGET_MIPS64 376 #ifdef TARGET_MIPS64
377 tlb->VPN &= env->SEGMask; 377 tlb->VPN &= env->SEGMask;
@@ -394,10 +394,10 @@ void r4k_do_tlbwi (void) @@ -394,10 +394,10 @@ void r4k_do_tlbwi (void)
394 /* Discard cached TLB entries. We could avoid doing this if the 394 /* Discard cached TLB entries. We could avoid doing this if the
395 tlbwi is just upgrading access permissions on the current entry; 395 tlbwi is just upgrading access permissions on the current entry;
396 that might be a further win. */ 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 void r4k_do_tlbwr (void) 403 void r4k_do_tlbwr (void)
@@ -418,8 +418,8 @@ void r4k_do_tlbp (void) @@ -418,8 +418,8 @@ void r4k_do_tlbp (void)
418 int i; 418 int i;
419 419
420 ASID = env->CP0_EntryHi & 0xFF; 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 /* 1k pages are not supported. */ 423 /* 1k pages are not supported. */
424 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); 424 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
425 tag = env->CP0_EntryHi & ~mask; 425 tag = env->CP0_EntryHi & ~mask;
@@ -431,10 +431,10 @@ void r4k_do_tlbp (void) @@ -431,10 +431,10 @@ void r4k_do_tlbp (void)
431 break; 431 break;
432 } 432 }
433 } 433 }
434 - if (i == env->nb_tlb) { 434 + if (i == env->tlb->nb_tlb) {
435 /* No match. Discard any shadow entries, if any of them match. */ 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 /* 1k pages are not supported. */ 438 /* 1k pages are not supported. */
439 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); 439 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
440 tag = env->CP0_EntryHi & ~mask; 440 tag = env->CP0_EntryHi & ~mask;
@@ -456,13 +456,13 @@ void r4k_do_tlbr (void) @@ -456,13 +456,13 @@ void r4k_do_tlbr (void)
456 uint8_t ASID; 456 uint8_t ASID;
457 457
458 ASID = env->CP0_EntryHi & 0xFF; 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 /* If this will change the current ASID, flush qemu's TLB. */ 461 /* If this will change the current ASID, flush qemu's TLB. */
462 if (ASID != tlb->ASID) 462 if (ASID != tlb->ASID)
463 cpu_mips_tlb_flush (env, 1); 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 env->CP0_EntryHi = tlb->VPN | tlb->ASID; 467 env->CP0_EntryHi = tlb->VPN | tlb->ASID;
468 env->CP0_PageMask = tlb->PageMask; 468 env->CP0_PageMask = tlb->PageMask;
@@ -491,7 +491,7 @@ void dump_sc (void) @@ -491,7 +491,7 @@ void dump_sc (void)
491 void debug_pre_eret (void) 491 void debug_pre_eret (void)
492 { 492 {
493 fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, 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 if (env->CP0_Status & (1 << CP0St_ERL)) 495 if (env->CP0_Status & (1 << CP0St_ERL))
496 fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); 496 fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
497 if (env->hflags & MIPS_HFLAG_DM) 497 if (env->hflags & MIPS_HFLAG_DM)
@@ -502,7 +502,7 @@ void debug_pre_eret (void) @@ -502,7 +502,7 @@ void debug_pre_eret (void)
502 void debug_post_eret (void) 502 void debug_post_eret (void)
503 { 503 {
504 fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, 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 if (env->CP0_Status & (1 << CP0St_ERL)) 506 if (env->CP0_Status & (1 << CP0St_ERL))
507 fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); 507 fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
508 if (env->hflags & MIPS_HFLAG_DM) 508 if (env->hflags & MIPS_HFLAG_DM)
@@ -518,21 +518,21 @@ void do_pmon (int function) @@ -518,21 +518,21 @@ void do_pmon (int function)
518 function /= 2; 518 function /= 2;
519 switch (function) { 519 switch (function) {
520 case 2: /* TODO: char inbyte(int waitflag); */ 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 /* Fall through */ 523 /* Fall through */
524 case 11: /* TODO: char inbyte (void); */ 524 case 11: /* TODO: char inbyte (void); */
525 - env->gpr[2] = -1; 525 + env->gpr[2][env->current_tc] = -1;
526 break; 526 break;
527 case 3: 527 case 3:
528 case 12: 528 case 12:
529 - printf("%c", (char)(env->gpr[4] & 0xFF)); 529 + printf("%c", (char)(env->gpr[4][env->current_tc] & 0xFF));
530 break; 530 break;
531 case 17: 531 case 17:
532 break; 532 break;
533 case 158: 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 printf("%s", fmt); 536 printf("%s", fmt);
537 } 537 }
538 break; 538 break;
@@ -613,40 +613,61 @@ unsigned int ieee_rm[] = { @@ -613,40 +613,61 @@ unsigned int ieee_rm[] = {
613 }; 613 };
614 614
615 #define RESTORE_ROUNDING_MODE \ 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 case 25: 642 case 25:
622 if (T0 & 0xffffff00) 643 if (T0 & 0xffffff00)
623 return; 644 return;
624 - env->fcr31 = (env->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) | 645 + env->fpu->fcr31 = (env->fpu->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |
625 ((T0 & 0x1) << 23); 646 ((T0 & 0x1) << 23);
626 break; 647 break;
627 case 26: 648 case 26:
628 if (T0 & 0x007c0000) 649 if (T0 & 0x007c0000)
629 return; 650 return;
630 - env->fcr31 = (env->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c); 651 + env->fpu->fcr31 = (env->fpu->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);
631 break; 652 break;
632 case 28: 653 case 28:
633 if (T0 & 0x007c0000) 654 if (T0 & 0x007c0000)
634 return; 655 return;
635 - env->fcr31 = (env->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) | 656 + env->fpu->fcr31 = (env->fpu->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |
636 ((T0 & 0x4) << 22); 657 ((T0 & 0x4) << 22);
637 break; 658 break;
638 case 31: 659 case 31:
639 if (T0 & 0x007c0000) 660 if (T0 & 0x007c0000)
640 return; 661 return;
641 - env->fcr31 = T0; 662 + env->fpu->fcr31 = T0;
642 break; 663 break;
643 default: 664 default:
644 return; 665 return;
645 } 666 }
646 /* set rounding mode */ 667 /* set rounding mode */
647 RESTORE_ROUNDING_MODE; 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 do_raise_exception(EXCP_FPE); 671 do_raise_exception(EXCP_FPE);
651 } 672 }
652 673
@@ -670,325 +691,325 @@ inline char mips_ex_to_ieee(char xcpt) @@ -670,325 +691,325 @@ inline char mips_ex_to_ieee(char xcpt)
670 691
671 inline void update_fcr31(void) 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 do_raise_exception(EXCP_FPE); 698 do_raise_exception(EXCP_FPE);
678 else 699 else
679 - UPDATE_FP_FLAGS(env->fcr31, tmp); 700 + UPDATE_FP_FLAGS(env->fpu->fcr31, tmp);
680 } 701 }
681 702
682 #define FLOAT_OP(name, p) void do_float_##name##_##p(void) 703 #define FLOAT_OP(name, p) void do_float_##name##_##p(void)
683 704
684 FLOAT_OP(cvtd, s) 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 update_fcr31(); 709 update_fcr31();
689 } 710 }
690 FLOAT_OP(cvtd, w) 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 update_fcr31(); 715 update_fcr31();
695 } 716 }
696 FLOAT_OP(cvtd, l) 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 update_fcr31(); 721 update_fcr31();
701 } 722 }
702 FLOAT_OP(cvtl, d) 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 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 729 DT2 = 0x7fffffffffffffffULL;
709 } 730 }
710 FLOAT_OP(cvtl, s) 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 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 737 DT2 = 0x7fffffffffffffffULL;
717 } 738 }
718 739
719 FLOAT_OP(cvtps, pw) 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 update_fcr31(); 745 update_fcr31();
725 } 746 }
726 FLOAT_OP(cvtpw, ps) 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 update_fcr31(); 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 WT2 = 0x7fffffff; 754 WT2 = 0x7fffffff;
734 } 755 }
735 FLOAT_OP(cvts, d) 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 update_fcr31(); 760 update_fcr31();
740 } 761 }
741 FLOAT_OP(cvts, w) 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 update_fcr31(); 766 update_fcr31();
746 } 767 }
747 FLOAT_OP(cvts, l) 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 update_fcr31(); 772 update_fcr31();
752 } 773 }
753 FLOAT_OP(cvts, pl) 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 WT2 = WT0; 777 WT2 = WT0;
757 update_fcr31(); 778 update_fcr31();
758 } 779 }
759 FLOAT_OP(cvts, pu) 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 WT2 = WTH0; 783 WT2 = WTH0;
763 update_fcr31(); 784 update_fcr31();
764 } 785 }
765 FLOAT_OP(cvtw, s) 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 update_fcr31(); 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 WT2 = 0x7fffffff; 792 WT2 = 0x7fffffff;
772 } 793 }
773 FLOAT_OP(cvtw, d) 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 update_fcr31(); 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 WT2 = 0x7fffffff; 800 WT2 = 0x7fffffff;
780 } 801 }
781 802
782 FLOAT_OP(roundl, d) 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 RESTORE_ROUNDING_MODE; 807 RESTORE_ROUNDING_MODE;
787 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 810 DT2 = 0x7fffffffffffffffULL;
790 } 811 }
791 FLOAT_OP(roundl, s) 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 RESTORE_ROUNDING_MODE; 816 RESTORE_ROUNDING_MODE;
796 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 819 DT2 = 0x7fffffffffffffffULL;
799 } 820 }
800 FLOAT_OP(roundw, d) 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 RESTORE_ROUNDING_MODE; 825 RESTORE_ROUNDING_MODE;
805 update_fcr31(); 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 WT2 = 0x7fffffff; 828 WT2 = 0x7fffffff;
808 } 829 }
809 FLOAT_OP(roundw, s) 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 RESTORE_ROUNDING_MODE; 834 RESTORE_ROUNDING_MODE;
814 update_fcr31(); 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 WT2 = 0x7fffffff; 837 WT2 = 0x7fffffff;
817 } 838 }
818 839
819 FLOAT_OP(truncl, d) 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 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 845 DT2 = 0x7fffffffffffffffULL;
825 } 846 }
826 FLOAT_OP(truncl, s) 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 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 852 DT2 = 0x7fffffffffffffffULL;
832 } 853 }
833 FLOAT_OP(truncw, d) 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 update_fcr31(); 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 WT2 = 0x7fffffff; 859 WT2 = 0x7fffffff;
839 } 860 }
840 FLOAT_OP(truncw, s) 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 update_fcr31(); 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 WT2 = 0x7fffffff; 866 WT2 = 0x7fffffff;
846 } 867 }
847 868
848 FLOAT_OP(ceill, d) 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 RESTORE_ROUNDING_MODE; 873 RESTORE_ROUNDING_MODE;
853 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 876 DT2 = 0x7fffffffffffffffULL;
856 } 877 }
857 FLOAT_OP(ceill, s) 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 RESTORE_ROUNDING_MODE; 882 RESTORE_ROUNDING_MODE;
862 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 885 DT2 = 0x7fffffffffffffffULL;
865 } 886 }
866 FLOAT_OP(ceilw, d) 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 RESTORE_ROUNDING_MODE; 891 RESTORE_ROUNDING_MODE;
871 update_fcr31(); 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 WT2 = 0x7fffffff; 894 WT2 = 0x7fffffff;
874 } 895 }
875 FLOAT_OP(ceilw, s) 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 RESTORE_ROUNDING_MODE; 900 RESTORE_ROUNDING_MODE;
880 update_fcr31(); 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 WT2 = 0x7fffffff; 903 WT2 = 0x7fffffff;
883 } 904 }
884 905
885 FLOAT_OP(floorl, d) 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 RESTORE_ROUNDING_MODE; 910 RESTORE_ROUNDING_MODE;
890 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 913 DT2 = 0x7fffffffffffffffULL;
893 } 914 }
894 FLOAT_OP(floorl, s) 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 RESTORE_ROUNDING_MODE; 919 RESTORE_ROUNDING_MODE;
899 update_fcr31(); 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 DT2 = 0x7fffffffffffffffULL; 922 DT2 = 0x7fffffffffffffffULL;
902 } 923 }
903 FLOAT_OP(floorw, d) 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 RESTORE_ROUNDING_MODE; 928 RESTORE_ROUNDING_MODE;
908 update_fcr31(); 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 WT2 = 0x7fffffff; 931 WT2 = 0x7fffffff;
911 } 932 }
912 FLOAT_OP(floorw, s) 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 RESTORE_ROUNDING_MODE; 937 RESTORE_ROUNDING_MODE;
917 update_fcr31(); 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 WT2 = 0x7fffffff; 940 WT2 = 0x7fffffff;
920 } 941 }
921 942
922 /* MIPS specific unary operations */ 943 /* MIPS specific unary operations */
923 FLOAT_OP(recip, d) 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 update_fcr31(); 948 update_fcr31();
928 } 949 }
929 FLOAT_OP(recip, s) 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 update_fcr31(); 954 update_fcr31();
934 } 955 }
935 956
936 FLOAT_OP(rsqrt, d) 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 update_fcr31(); 962 update_fcr31();
942 } 963 }
943 FLOAT_OP(rsqrt, s) 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 update_fcr31(); 969 update_fcr31();
949 } 970 }
950 971
951 FLOAT_OP(recip1, d) 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 update_fcr31(); 976 update_fcr31();
956 } 977 }
957 FLOAT_OP(recip1, s) 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 update_fcr31(); 982 update_fcr31();
962 } 983 }
963 FLOAT_OP(recip1, ps) 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 update_fcr31(); 989 update_fcr31();
969 } 990 }
970 991
971 FLOAT_OP(rsqrt1, d) 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 update_fcr31(); 997 update_fcr31();
977 } 998 }
978 FLOAT_OP(rsqrt1, s) 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 update_fcr31(); 1004 update_fcr31();
984 } 1005 }
985 FLOAT_OP(rsqrt1, ps) 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 update_fcr31(); 1013 update_fcr31();
993 } 1014 }
994 1015
@@ -996,41 +1017,41 @@ FLOAT_OP(rsqrt1, ps) @@ -996,41 +1017,41 @@ FLOAT_OP(rsqrt1, ps)
996 #define FLOAT_BINOP(name) \ 1017 #define FLOAT_BINOP(name) \
997 FLOAT_OP(name, d) \ 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 FLOAT_OP(name, s) \ 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 FLOAT_OP(name, ps) \ 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 update_fcr31(); \ 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,69 +1064,69 @@ FLOAT_BINOP(div)
1043 /* MIPS specific binary operations */ 1064 /* MIPS specific binary operations */
1044 FLOAT_OP(recip2, d) 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 update_fcr31(); 1070 update_fcr31();
1050 } 1071 }
1051 FLOAT_OP(recip2, s) 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 update_fcr31(); 1077 update_fcr31();
1057 } 1078 }
1058 FLOAT_OP(recip2, ps) 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 update_fcr31(); 1086 update_fcr31();
1066 } 1087 }
1067 1088
1068 FLOAT_OP(rsqrt2, d) 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 update_fcr31(); 1095 update_fcr31();
1075 } 1096 }
1076 FLOAT_OP(rsqrt2, s) 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 update_fcr31(); 1103 update_fcr31();
1083 } 1104 }
1084 FLOAT_OP(rsqrt2, ps) 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 update_fcr31(); 1114 update_fcr31();
1094 } 1115 }
1095 1116
1096 FLOAT_OP(addr, ps) 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 update_fcr31(); 1122 update_fcr31();
1102 } 1123 }
1103 1124
1104 FLOAT_OP(mulr, ps) 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 update_fcr31(); 1130 update_fcr31();
1110 } 1131 }
1111 1132
@@ -1116,9 +1137,9 @@ void do_cmp_d_ ## op (long cc) \ @@ -1116,9 +1137,9 @@ void do_cmp_d_ ## op (long cc) \
1116 int c = cond; \ 1137 int c = cond; \
1117 update_fcr31(); \ 1138 update_fcr31(); \
1118 if (c) \ 1139 if (c) \
1119 - SET_FP_COND(cc, env); \ 1140 + SET_FP_COND(cc, env->fpu); \
1120 else \ 1141 else \
1121 - CLEAR_FP_COND(cc, env); \ 1142 + CLEAR_FP_COND(cc, env->fpu); \
1122 } \ 1143 } \
1123 void do_cmpabs_d_ ## op (long cc) \ 1144 void do_cmpabs_d_ ## op (long cc) \
1124 { \ 1145 { \
@@ -1128,9 +1149,9 @@ void do_cmpabs_d_ ## op (long cc) \ @@ -1128,9 +1149,9 @@ void do_cmpabs_d_ ## op (long cc) \
1128 c = cond; \ 1149 c = cond; \
1129 update_fcr31(); \ 1150 update_fcr31(); \
1130 if (c) \ 1151 if (c) \
1131 - SET_FP_COND(cc, env); \ 1152 + SET_FP_COND(cc, env->fpu); \
1132 else \ 1153 else \
1133 - CLEAR_FP_COND(cc, env); \ 1154 + CLEAR_FP_COND(cc, env->fpu); \
1134 } 1155 }
1135 1156
1136 int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM) 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,24 +1170,24 @@ int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
1149 1170
1150 /* NOTE: the comma operator will make "cond" to eval to false, 1171 /* NOTE: the comma operator will make "cond" to eval to false,
1151 * but float*_is_unordered() is still called. */ 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 /* NOTE: the comma operator will make "cond" to eval to false, 1181 /* NOTE: the comma operator will make "cond" to eval to false,
1161 * but float*_is_unordered() is still called. */ 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 #define FOP_COND_S(op, cond) \ 1192 #define FOP_COND_S(op, cond) \
1172 void do_cmp_s_ ## op (long cc) \ 1193 void do_cmp_s_ ## op (long cc) \
@@ -1174,9 +1195,9 @@ void do_cmp_s_ ## op (long cc) \ @@ -1174,9 +1195,9 @@ void do_cmp_s_ ## op (long cc) \
1174 int c = cond; \ 1195 int c = cond; \
1175 update_fcr31(); \ 1196 update_fcr31(); \
1176 if (c) \ 1197 if (c) \
1177 - SET_FP_COND(cc, env); \ 1198 + SET_FP_COND(cc, env->fpu); \
1178 else \ 1199 else \
1179 - CLEAR_FP_COND(cc, env); \ 1200 + CLEAR_FP_COND(cc, env->fpu); \
1180 } \ 1201 } \
1181 void do_cmpabs_s_ ## op (long cc) \ 1202 void do_cmpabs_s_ ## op (long cc) \
1182 { \ 1203 { \
@@ -1186,9 +1207,9 @@ void do_cmpabs_s_ ## op (long cc) \ @@ -1186,9 +1207,9 @@ void do_cmpabs_s_ ## op (long cc) \
1186 c = cond; \ 1207 c = cond; \
1187 update_fcr31(); \ 1208 update_fcr31(); \
1188 if (c) \ 1209 if (c) \
1189 - SET_FP_COND(cc, env); \ 1210 + SET_FP_COND(cc, env->fpu); \
1190 else \ 1211 else \
1191 - CLEAR_FP_COND(cc, env); \ 1212 + CLEAR_FP_COND(cc, env->fpu); \
1192 } 1213 }
1193 1214
1194 flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM) 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,24 +1228,24 @@ flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
1207 1228
1208 /* NOTE: the comma operator will make "cond" to eval to false, 1229 /* NOTE: the comma operator will make "cond" to eval to false,
1209 * but float*_is_unordered() is still called. */ 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 /* NOTE: the comma operator will make "cond" to eval to false, 1239 /* NOTE: the comma operator will make "cond" to eval to false,
1219 * but float*_is_unordered() is still called. */ 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 #define FOP_COND_PS(op, condl, condh) \ 1250 #define FOP_COND_PS(op, condl, condh) \
1230 void do_cmp_ps_ ## op (long cc) \ 1251 void do_cmp_ps_ ## op (long cc) \
@@ -1233,13 +1254,13 @@ void do_cmp_ps_ ## op (long cc) \ @@ -1233,13 +1254,13 @@ void do_cmp_ps_ ## op (long cc) \
1233 int ch = condh; \ 1254 int ch = condh; \
1234 update_fcr31(); \ 1255 update_fcr31(); \
1235 if (cl) \ 1256 if (cl) \
1236 - SET_FP_COND(cc, env); \ 1257 + SET_FP_COND(cc, env->fpu); \
1237 else \ 1258 else \
1238 - CLEAR_FP_COND(cc, env); \ 1259 + CLEAR_FP_COND(cc, env->fpu); \
1239 if (ch) \ 1260 if (ch) \
1240 - SET_FP_COND(cc + 1, env); \ 1261 + SET_FP_COND(cc + 1, env->fpu); \
1241 else \ 1262 else \
1242 - CLEAR_FP_COND(cc + 1, env); \ 1263 + CLEAR_FP_COND(cc + 1, env->fpu); \
1243 } \ 1264 } \
1244 void do_cmpabs_ps_ ## op (long cc) \ 1265 void do_cmpabs_ps_ ## op (long cc) \
1245 { \ 1266 { \
@@ -1252,48 +1273,48 @@ void do_cmpabs_ps_ ## op (long cc) \ @@ -1252,48 +1273,48 @@ void do_cmpabs_ps_ ## op (long cc) \
1252 ch = condh; \ 1273 ch = condh; \
1253 update_fcr31(); \ 1274 update_fcr31(); \
1254 if (cl) \ 1275 if (cl) \
1255 - SET_FP_COND(cc, env); \ 1276 + SET_FP_COND(cc, env->fpu); \
1256 else \ 1277 else \
1257 - CLEAR_FP_COND(cc, env); \ 1278 + CLEAR_FP_COND(cc, env->fpu); \
1258 if (ch) \ 1279 if (ch) \
1259 - SET_FP_COND(cc + 1, env); \ 1280 + SET_FP_COND(cc + 1, env->fpu); \
1260 else \ 1281 else \
1261 - CLEAR_FP_COND(cc + 1, env); \ 1282 + CLEAR_FP_COND(cc + 1, env->fpu); \
1262 } 1283 }
1263 1284
1264 /* NOTE: the comma operator will make "cond" to eval to false, 1285 /* NOTE: the comma operator will make "cond" to eval to false,
1265 * but float*_is_unordered() is still called. */ 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 /* NOTE: the comma operator will make "cond" to eval to false, 1303 /* NOTE: the comma operator will make "cond" to eval to false,
1283 * but float*_is_unordered() is still called. */ 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,31 +21,44 @@
21 #if defined(REG) 21 #if defined(REG)
22 void glue(op_load_gpr_T0_gpr, REG) (void) 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 RETURN(); 25 RETURN();
26 } 26 }
27 27
28 void glue(op_store_T0_gpr_gpr, REG) (void) 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 RETURN(); 31 RETURN();
32 } 32 }
33 33
34 void glue(op_load_gpr_T1_gpr, REG) (void) 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 RETURN(); 37 RETURN();
38 } 38 }
39 39
40 void glue(op_store_T1_gpr_gpr, REG) (void) 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 RETURN(); 43 RETURN();
44 } 44 }
45 45
46 void glue(op_load_gpr_T2_gpr, REG) (void) 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 RETURN(); 62 RETURN();
50 } 63 }
51 #endif 64 #endif
target-mips/translate.c
@@ -266,6 +266,8 @@ enum { @@ -266,6 +266,8 @@ enum {
266 OPC_DINSM = 0x05 | OPC_SPECIAL3, 266 OPC_DINSM = 0x05 | OPC_SPECIAL3,
267 OPC_DINSU = 0x06 | OPC_SPECIAL3, 267 OPC_DINSU = 0x06 | OPC_SPECIAL3,
268 OPC_DINS = 0x07 | OPC_SPECIAL3, 268 OPC_DINS = 0x07 | OPC_SPECIAL3,
  269 + OPC_FORK = 0x08 | OPC_SPECIAL3,
  270 + OPC_YIELD = 0x09 | OPC_SPECIAL3,
269 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 271 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
270 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 272 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
271 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 273 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
@@ -296,8 +298,10 @@ enum { @@ -296,8 +298,10 @@ enum {
296 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 298 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
297 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 299 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
298 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 300 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
  301 + OPC_MFTR = (0x08 << 21) | OPC_CP0,
299 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 302 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
300 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 303 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
  304 + OPC_MTTR = (0x0C << 21) | OPC_CP0,
301 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 305 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
302 OPC_C0 = (0x10 << 21) | OPC_CP0, 306 OPC_C0 = (0x10 << 21) | OPC_CP0,
303 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0, 307 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
@@ -308,6 +312,10 @@ enum { @@ -308,6 +312,10 @@ enum {
308 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF) 312 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
309 313
310 enum { 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 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 319 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
312 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 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,6 +449,10 @@ GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
441 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr); 449 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
442 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr); 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 static const char *fregnames[] = 456 static const char *fregnames[] =
445 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 457 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
446 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 458 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
@@ -569,6 +581,15 @@ do { \ @@ -569,6 +581,15 @@ do { \
569 } \ 581 } \
570 } while (0) 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 #ifdef TARGET_MIPS64 593 #ifdef TARGET_MIPS64
573 #define GEN_LOAD_IMM_TN(Tn, Imm) \ 594 #define GEN_LOAD_IMM_TN(Tn, Imm) \
574 do { \ 595 do { \
@@ -598,6 +619,13 @@ do { \ @@ -598,6 +619,13 @@ do { \
598 } \ 619 } \
599 } while (0) 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 #define GEN_LOAD_FREG_FTN(FTn, Fn) \ 629 #define GEN_LOAD_FREG_FTN(FTn, Fn) \
602 do { \ 630 do { \
603 glue(gen_op_load_fpr_, FTn)(Fn); \ 631 glue(gen_op_load_fpr_, FTn)(Fn); \
@@ -740,6 +768,14 @@ static inline void check_mips_r2(CPUState *env, DisasContext *ctx) @@ -740,6 +768,14 @@ static inline void check_mips_r2(CPUState *env, DisasContext *ctx)
740 generate_exception(ctx, EXCP_RI); 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 #if defined(CONFIG_USER_ONLY) 779 #if defined(CONFIG_USER_ONLY)
744 #define op_ldst(name) gen_op_##name##_raw() 780 #define op_ldst(name) gen_op_##name##_raw()
745 #define OP_LD_TABLE(width) 781 #define OP_LD_TABLE(width)
@@ -806,8 +842,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -806,8 +842,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
806 gen_op_addr_add(); 842 gen_op_addr_add();
807 } 843 }
808 /* Don't do NOP if destination is zero: we must perform the actual 844 /* Don't do NOP if destination is zero: we must perform the actual
809 - * memory access  
810 - */ 845 + memory access. */
811 switch (opc) { 846 switch (opc) {
812 #ifdef TARGET_MIPS64 847 #ifdef TARGET_MIPS64
813 case OPC_LWU: 848 case OPC_LWU:
@@ -958,8 +993,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, @@ -958,8 +993,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
958 gen_op_addr_add(); 993 gen_op_addr_add();
959 } 994 }
960 /* Don't do NOP if destination is zero: we must perform the actual 995 /* Don't do NOP if destination is zero: we must perform the actual
961 - * memory access  
962 - */ 996 + memory access. */
963 switch (opc) { 997 switch (opc) {
964 case OPC_LWC1: 998 case OPC_LWC1:
965 op_ldst(lwc1); 999 op_ldst(lwc1);
@@ -997,9 +1031,8 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, @@ -997,9 +1031,8 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
997 const char *opn = "imm arith"; 1031 const char *opn = "imm arith";
998 1032
999 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 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 MIPS_DEBUG("NOP"); 1036 MIPS_DEBUG("NOP");
1004 return; 1037 return;
1005 } 1038 }
@@ -1175,9 +1208,8 @@ static void gen_arith (DisasContext *ctx, uint32_t opc, @@ -1175,9 +1208,8 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
1175 1208
1176 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 1209 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1177 && opc != OPC_DADD && opc != OPC_DSUB) { 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 MIPS_DEBUG("NOP"); 1213 MIPS_DEBUG("NOP");
1182 return; 1214 return;
1183 } 1215 }
@@ -1324,29 +1356,29 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) @@ -1324,29 +1356,29 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1324 const char *opn = "hilo"; 1356 const char *opn = "hilo";
1325 1357
1326 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 1358 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1327 - /* Treat as a NOP */ 1359 + /* Treat as NOP. */
1328 MIPS_DEBUG("NOP"); 1360 MIPS_DEBUG("NOP");
1329 return; 1361 return;
1330 } 1362 }
1331 switch (opc) { 1363 switch (opc) {
1332 case OPC_MFHI: 1364 case OPC_MFHI:
1333 - gen_op_load_HI(); 1365 + gen_op_load_HI(0);
1334 GEN_STORE_TN_REG(reg, T0); 1366 GEN_STORE_TN_REG(reg, T0);
1335 opn = "mfhi"; 1367 opn = "mfhi";
1336 break; 1368 break;
1337 case OPC_MFLO: 1369 case OPC_MFLO:
1338 - gen_op_load_LO(); 1370 + gen_op_load_LO(0);
1339 GEN_STORE_TN_REG(reg, T0); 1371 GEN_STORE_TN_REG(reg, T0);
1340 opn = "mflo"; 1372 opn = "mflo";
1341 break; 1373 break;
1342 case OPC_MTHI: 1374 case OPC_MTHI:
1343 GEN_LOAD_REG_TN(T0, reg); 1375 GEN_LOAD_REG_TN(T0, reg);
1344 - gen_op_store_HI(); 1376 + gen_op_store_HI(0);
1345 opn = "mthi"; 1377 opn = "mthi";
1346 break; 1378 break;
1347 case OPC_MTLO: 1379 case OPC_MTLO:
1348 GEN_LOAD_REG_TN(T0, reg); 1380 GEN_LOAD_REG_TN(T0, reg);
1349 - gen_op_store_LO(); 1381 + gen_op_store_LO(0);
1350 opn = "mtlo"; 1382 opn = "mtlo";
1351 break; 1383 break;
1352 default: 1384 default:
@@ -1428,7 +1460,7 @@ static void gen_cl (DisasContext *ctx, uint32_t opc, @@ -1428,7 +1460,7 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
1428 { 1460 {
1429 const char *opn = "CLx"; 1461 const char *opn = "CLx";
1430 if (rd == 0) { 1462 if (rd == 0) {
1431 - /* Treat as a NOP */ 1463 + /* Treat as NOP. */
1432 MIPS_DEBUG("NOP"); 1464 MIPS_DEBUG("NOP");
1433 return; 1465 return;
1434 } 1466 }
@@ -1514,7 +1546,7 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, @@ -1514,7 +1546,7 @@ static void gen_trap (DisasContext *ctx, uint32_t opc,
1514 case OPC_TLTIU: /* r0 < 0 unsigned */ 1546 case OPC_TLTIU: /* r0 < 0 unsigned */
1515 case OPC_TNE: /* rs != rs */ 1547 case OPC_TNE: /* rs != rs */
1516 case OPC_TNEI: /* r0 != 0 */ 1548 case OPC_TNEI: /* r0 != 0 */
1517 - /* Never trap: treat as NOP */ 1549 + /* Never trap: treat as NOP. */
1518 return; 1550 return;
1519 default: 1551 default:
1520 MIPS_INVAL("trap"); 1552 MIPS_INVAL("trap");
@@ -1674,7 +1706,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, @@ -1674,7 +1706,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1674 case OPC_BNE: /* rx != rx */ 1706 case OPC_BNE: /* rx != rx */
1675 case OPC_BGTZ: /* 0 > 0 */ 1707 case OPC_BGTZ: /* 0 > 0 */
1676 case OPC_BLTZ: /* 0 < 0 */ 1708 case OPC_BLTZ: /* 0 < 0 */
1677 - /* Treated as NOP */ 1709 + /* Treat as NOP. */
1678 MIPS_DEBUG("bnever (NOP)"); 1710 MIPS_DEBUG("bnever (NOP)");
1679 return; 1711 return;
1680 case OPC_BLTZAL: /* 0 < 0 */ 1712 case OPC_BLTZAL: /* 0 < 0 */
@@ -1886,17 +1918,20 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -1886,17 +1918,20 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1886 rn = "Index"; 1918 rn = "Index";
1887 break; 1919 break;
1888 case 1: 1920 case 1:
1889 -// gen_op_mfc0_mvpcontrol(); /* MT ASE */ 1921 + check_mips_mt(env, ctx);
  1922 + gen_op_mfc0_mvpcontrol();
1890 rn = "MVPControl"; 1923 rn = "MVPControl";
1891 -// break; 1924 + break;
1892 case 2: 1925 case 2:
1893 -// gen_op_mfc0_mvpconf0(); /* MT ASE */ 1926 + check_mips_mt(env, ctx);
  1927 + gen_op_mfc0_mvpconf0();
1894 rn = "MVPConf0"; 1928 rn = "MVPConf0";
1895 -// break; 1929 + break;
1896 case 3: 1930 case 3:
1897 -// gen_op_mfc0_mvpconf1(); /* MT ASE */ 1931 + check_mips_mt(env, ctx);
  1932 + gen_op_mfc0_mvpconf1();
1898 rn = "MVPConf1"; 1933 rn = "MVPConf1";
1899 -// break; 1934 + break;
1900 default: 1935 default:
1901 goto die; 1936 goto die;
1902 } 1937 }
@@ -1908,33 +1943,40 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -1908,33 +1943,40 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1908 rn = "Random"; 1943 rn = "Random";
1909 break; 1944 break;
1910 case 1: 1945 case 1:
1911 -// gen_op_mfc0_vpecontrol(); /* MT ASE */ 1946 + check_mips_mt(env, ctx);
  1947 + gen_op_mfc0_vpecontrol();
1912 rn = "VPEControl"; 1948 rn = "VPEControl";
1913 -// break; 1949 + break;
1914 case 2: 1950 case 2:
1915 -// gen_op_mfc0_vpeconf0(); /* MT ASE */ 1951 + check_mips_mt(env, ctx);
  1952 + gen_op_mfc0_vpeconf0();
1916 rn = "VPEConf0"; 1953 rn = "VPEConf0";
1917 -// break; 1954 + break;
1918 case 3: 1955 case 3:
1919 -// gen_op_mfc0_vpeconf1(); /* MT ASE */ 1956 + check_mips_mt(env, ctx);
  1957 + gen_op_mfc0_vpeconf1();
1920 rn = "VPEConf1"; 1958 rn = "VPEConf1";
1921 -// break; 1959 + break;
1922 case 4: 1960 case 4:
1923 -// gen_op_mfc0_YQMask(); /* MT ASE */ 1961 + check_mips_mt(env, ctx);
  1962 + gen_op_mfc0_yqmask();
1924 rn = "YQMask"; 1963 rn = "YQMask";
1925 -// break; 1964 + break;
1926 case 5: 1965 case 5:
1927 -// gen_op_mfc0_vpeschedule(); /* MT ASE */ 1966 + check_mips_mt(env, ctx);
  1967 + gen_op_mfc0_vpeschedule();
1928 rn = "VPESchedule"; 1968 rn = "VPESchedule";
1929 -// break; 1969 + break;
1930 case 6: 1970 case 6:
1931 -// gen_op_mfc0_vpeschefback(); /* MT ASE */ 1971 + check_mips_mt(env, ctx);
  1972 + gen_op_mfc0_vpeschefback();
1932 rn = "VPEScheFBack"; 1973 rn = "VPEScheFBack";
1933 -// break; 1974 + break;
1934 case 7: 1975 case 7:
1935 -// gen_op_mfc0_vpeopt(); /* MT ASE */ 1976 + check_mips_mt(env, ctx);
  1977 + gen_op_mfc0_vpeopt();
1936 rn = "VPEOpt"; 1978 rn = "VPEOpt";
1937 -// break; 1979 + break;
1938 default: 1980 default:
1939 goto die; 1981 goto die;
1940 } 1982 }
@@ -1946,33 +1988,40 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -1946,33 +1988,40 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1946 rn = "EntryLo0"; 1988 rn = "EntryLo0";
1947 break; 1989 break;
1948 case 1: 1990 case 1:
1949 -// gen_op_mfc0_tcstatus(); /* MT ASE */ 1991 + check_mips_mt(env, ctx);
  1992 + gen_op_mfc0_tcstatus();
1950 rn = "TCStatus"; 1993 rn = "TCStatus";
1951 -// break; 1994 + break;
1952 case 2: 1995 case 2:
1953 -// gen_op_mfc0_tcbind(); /* MT ASE */ 1996 + check_mips_mt(env, ctx);
  1997 + gen_op_mfc0_tcbind();
1954 rn = "TCBind"; 1998 rn = "TCBind";
1955 -// break; 1999 + break;
1956 case 3: 2000 case 3:
1957 -// gen_op_mfc0_tcrestart(); /* MT ASE */ 2001 + check_mips_mt(env, ctx);
  2002 + gen_op_mfc0_tcrestart();
1958 rn = "TCRestart"; 2003 rn = "TCRestart";
1959 -// break; 2004 + break;
1960 case 4: 2005 case 4:
1961 -// gen_op_mfc0_tchalt(); /* MT ASE */ 2006 + check_mips_mt(env, ctx);
  2007 + gen_op_mfc0_tchalt();
1962 rn = "TCHalt"; 2008 rn = "TCHalt";
1963 -// break; 2009 + break;
1964 case 5: 2010 case 5:
1965 -// gen_op_mfc0_tccontext(); /* MT ASE */ 2011 + check_mips_mt(env, ctx);
  2012 + gen_op_mfc0_tccontext();
1966 rn = "TCContext"; 2013 rn = "TCContext";
1967 -// break; 2014 + break;
1968 case 6: 2015 case 6:
1969 -// gen_op_mfc0_tcschedule(); /* MT ASE */ 2016 + check_mips_mt(env, ctx);
  2017 + gen_op_mfc0_tcschedule();
1970 rn = "TCSchedule"; 2018 rn = "TCSchedule";
1971 -// break; 2019 + break;
1972 case 7: 2020 case 7:
1973 -// gen_op_mfc0_tcschefback(); /* MT ASE */ 2021 + check_mips_mt(env, ctx);
  2022 + gen_op_mfc0_tcschefback();
1974 rn = "TCScheFBack"; 2023 rn = "TCScheFBack";
1975 -// break; 2024 + break;
1976 default: 2025 default:
1977 goto die; 2026 goto die;
1978 } 2027 }
@@ -2023,25 +2072,25 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -2023,25 +2072,25 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2023 rn = "Wired"; 2072 rn = "Wired";
2024 break; 2073 break;
2025 case 1: 2074 case 1:
2026 -// gen_op_mfc0_srsconf0(); /* shadow registers */ 2075 + gen_op_mfc0_srsconf0();
2027 rn = "SRSConf0"; 2076 rn = "SRSConf0";
2028 -// break; 2077 + break;
2029 case 2: 2078 case 2:
2030 -// gen_op_mfc0_srsconf1(); /* shadow registers */ 2079 + gen_op_mfc0_srsconf1();
2031 rn = "SRSConf1"; 2080 rn = "SRSConf1";
2032 -// break; 2081 + break;
2033 case 3: 2082 case 3:
2034 -// gen_op_mfc0_srsconf2(); /* shadow registers */ 2083 + gen_op_mfc0_srsconf2();
2035 rn = "SRSConf2"; 2084 rn = "SRSConf2";
2036 -// break; 2085 + break;
2037 case 4: 2086 case 4:
2038 -// gen_op_mfc0_srsconf3(); /* shadow registers */ 2087 + gen_op_mfc0_srsconf3();
2039 rn = "SRSConf3"; 2088 rn = "SRSConf3";
2040 -// break; 2089 + break;
2041 case 5: 2090 case 5:
2042 -// gen_op_mfc0_srsconf4(); /* shadow registers */ 2091 + gen_op_mfc0_srsconf4();
2043 rn = "SRSConf4"; 2092 rn = "SRSConf4";
2044 -// break; 2093 + break;
2045 default: 2094 default:
2046 goto die; 2095 goto die;
2047 } 2096 }
@@ -2430,17 +2479,20 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -2430,17 +2479,20 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2430 rn = "Index"; 2479 rn = "Index";
2431 break; 2480 break;
2432 case 1: 2481 case 1:
2433 -// gen_op_mtc0_mvpcontrol(); /* MT ASE */ 2482 + check_mips_mt(env, ctx);
  2483 + gen_op_mtc0_mvpcontrol();
2434 rn = "MVPControl"; 2484 rn = "MVPControl";
2435 -// break; 2485 + break;
2436 case 2: 2486 case 2:
2437 -// gen_op_mtc0_mvpconf0(); /* MT ASE */ 2487 + check_mips_mt(env, ctx);
  2488 + /* ignored */
2438 rn = "MVPConf0"; 2489 rn = "MVPConf0";
2439 -// break; 2490 + break;
2440 case 3: 2491 case 3:
2441 -// gen_op_mtc0_mvpconf1(); /* MT ASE */ 2492 + check_mips_mt(env, ctx);
  2493 + /* ignored */
2442 rn = "MVPConf1"; 2494 rn = "MVPConf1";
2443 -// break; 2495 + break;
2444 default: 2496 default:
2445 goto die; 2497 goto die;
2446 } 2498 }
@@ -2452,33 +2504,40 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -2452,33 +2504,40 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2452 rn = "Random"; 2504 rn = "Random";
2453 break; 2505 break;
2454 case 1: 2506 case 1:
2455 -// gen_op_mtc0_vpecontrol(); /* MT ASE */ 2507 + check_mips_mt(env, ctx);
  2508 + gen_op_mtc0_vpecontrol();
2456 rn = "VPEControl"; 2509 rn = "VPEControl";
2457 -// break; 2510 + break;
2458 case 2: 2511 case 2:
2459 -// gen_op_mtc0_vpeconf0(); /* MT ASE */ 2512 + check_mips_mt(env, ctx);
  2513 + gen_op_mtc0_vpeconf0();
2460 rn = "VPEConf0"; 2514 rn = "VPEConf0";
2461 -// break; 2515 + break;
2462 case 3: 2516 case 3:
2463 -// gen_op_mtc0_vpeconf1(); /* MT ASE */ 2517 + check_mips_mt(env, ctx);
  2518 + gen_op_mtc0_vpeconf1();
2464 rn = "VPEConf1"; 2519 rn = "VPEConf1";
2465 -// break; 2520 + break;
2466 case 4: 2521 case 4:
2467 -// gen_op_mtc0_YQMask(); /* MT ASE */ 2522 + check_mips_mt(env, ctx);
  2523 + gen_op_mtc0_yqmask();
2468 rn = "YQMask"; 2524 rn = "YQMask";
2469 -// break; 2525 + break;
2470 case 5: 2526 case 5:
2471 -// gen_op_mtc0_vpeschedule(); /* MT ASE */ 2527 + check_mips_mt(env, ctx);
  2528 + gen_op_mtc0_vpeschedule();
2472 rn = "VPESchedule"; 2529 rn = "VPESchedule";
2473 -// break; 2530 + break;
2474 case 6: 2531 case 6:
2475 -// gen_op_mtc0_vpeschefback(); /* MT ASE */ 2532 + check_mips_mt(env, ctx);
  2533 + gen_op_mtc0_vpeschefback();
2476 rn = "VPEScheFBack"; 2534 rn = "VPEScheFBack";
2477 -// break; 2535 + break;
2478 case 7: 2536 case 7:
2479 -// gen_op_mtc0_vpeopt(); /* MT ASE */ 2537 + check_mips_mt(env, ctx);
  2538 + gen_op_mtc0_vpeopt();
2480 rn = "VPEOpt"; 2539 rn = "VPEOpt";
2481 -// break; 2540 + break;
2482 default: 2541 default:
2483 goto die; 2542 goto die;
2484 } 2543 }
@@ -2490,33 +2549,40 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -2490,33 +2549,40 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2490 rn = "EntryLo0"; 2549 rn = "EntryLo0";
2491 break; 2550 break;
2492 case 1: 2551 case 1:
2493 -// gen_op_mtc0_tcstatus(); /* MT ASE */ 2552 + check_mips_mt(env, ctx);
  2553 + gen_op_mtc0_tcstatus();
2494 rn = "TCStatus"; 2554 rn = "TCStatus";
2495 -// break; 2555 + break;
2496 case 2: 2556 case 2:
2497 -// gen_op_mtc0_tcbind(); /* MT ASE */ 2557 + check_mips_mt(env, ctx);
  2558 + gen_op_mtc0_tcbind();
2498 rn = "TCBind"; 2559 rn = "TCBind";
2499 -// break; 2560 + break;
2500 case 3: 2561 case 3:
2501 -// gen_op_mtc0_tcrestart(); /* MT ASE */ 2562 + check_mips_mt(env, ctx);
  2563 + gen_op_mtc0_tcrestart();
2502 rn = "TCRestart"; 2564 rn = "TCRestart";
2503 -// break; 2565 + break;
2504 case 4: 2566 case 4:
2505 -// gen_op_mtc0_tchalt(); /* MT ASE */ 2567 + check_mips_mt(env, ctx);
  2568 + gen_op_mtc0_tchalt();
2506 rn = "TCHalt"; 2569 rn = "TCHalt";
2507 -// break; 2570 + break;
2508 case 5: 2571 case 5:
2509 -// gen_op_mtc0_tccontext(); /* MT ASE */ 2572 + check_mips_mt(env, ctx);
  2573 + gen_op_mtc0_tccontext();
2510 rn = "TCContext"; 2574 rn = "TCContext";
2511 -// break; 2575 + break;
2512 case 6: 2576 case 6:
2513 -// gen_op_mtc0_tcschedule(); /* MT ASE */ 2577 + check_mips_mt(env, ctx);
  2578 + gen_op_mtc0_tcschedule();
2514 rn = "TCSchedule"; 2579 rn = "TCSchedule";
2515 -// break; 2580 + break;
2516 case 7: 2581 case 7:
2517 -// gen_op_mtc0_tcschefback(); /* MT ASE */ 2582 + check_mips_mt(env, ctx);
  2583 + gen_op_mtc0_tcschefback();
2518 rn = "TCScheFBack"; 2584 rn = "TCScheFBack";
2519 -// break; 2585 + break;
2520 default: 2586 default:
2521 goto die; 2587 goto die;
2522 } 2588 }
@@ -2567,25 +2633,25 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -2567,25 +2633,25 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2567 rn = "Wired"; 2633 rn = "Wired";
2568 break; 2634 break;
2569 case 1: 2635 case 1:
2570 -// gen_op_mtc0_srsconf0(); /* shadow registers */ 2636 + gen_op_mtc0_srsconf0();
2571 rn = "SRSConf0"; 2637 rn = "SRSConf0";
2572 -// break; 2638 + break;
2573 case 2: 2639 case 2:
2574 -// gen_op_mtc0_srsconf1(); /* shadow registers */ 2640 + gen_op_mtc0_srsconf1();
2575 rn = "SRSConf1"; 2641 rn = "SRSConf1";
2576 -// break; 2642 + break;
2577 case 3: 2643 case 3:
2578 -// gen_op_mtc0_srsconf2(); /* shadow registers */ 2644 + gen_op_mtc0_srsconf2();
2579 rn = "SRSConf2"; 2645 rn = "SRSConf2";
2580 -// break; 2646 + break;
2581 case 4: 2647 case 4:
2582 -// gen_op_mtc0_srsconf3(); /* shadow registers */ 2648 + gen_op_mtc0_srsconf3();
2583 rn = "SRSConf3"; 2649 rn = "SRSConf3";
2584 -// break; 2650 + break;
2585 case 5: 2651 case 5:
2586 -// gen_op_mtc0_srsconf4(); /* shadow registers */ 2652 + gen_op_mtc0_srsconf4();
2587 rn = "SRSConf4"; 2653 rn = "SRSConf4";
2588 -// break; 2654 + break;
2589 default: 2655 default:
2590 goto die; 2656 goto die;
2591 } 2657 }
@@ -3006,17 +3072,20 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3006,17 +3072,20 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3006 rn = "Index"; 3072 rn = "Index";
3007 break; 3073 break;
3008 case 1: 3074 case 1:
3009 -// gen_op_dmfc0_mvpcontrol(); /* MT ASE */ 3075 + check_mips_mt(env, ctx);
  3076 + gen_op_mfc0_mvpcontrol();
3010 rn = "MVPControl"; 3077 rn = "MVPControl";
3011 -// break; 3078 + break;
3012 case 2: 3079 case 2:
3013 -// gen_op_dmfc0_mvpconf0(); /* MT ASE */ 3080 + check_mips_mt(env, ctx);
  3081 + gen_op_mfc0_mvpconf0();
3014 rn = "MVPConf0"; 3082 rn = "MVPConf0";
3015 -// break; 3083 + break;
3016 case 3: 3084 case 3:
3017 -// gen_op_dmfc0_mvpconf1(); /* MT ASE */ 3085 + check_mips_mt(env, ctx);
  3086 + gen_op_mfc0_mvpconf1();
3018 rn = "MVPConf1"; 3087 rn = "MVPConf1";
3019 -// break; 3088 + break;
3020 default: 3089 default:
3021 goto die; 3090 goto die;
3022 } 3091 }
@@ -3028,33 +3097,40 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3028,33 +3097,40 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3028 rn = "Random"; 3097 rn = "Random";
3029 break; 3098 break;
3030 case 1: 3099 case 1:
3031 -// gen_op_dmfc0_vpecontrol(); /* MT ASE */ 3100 + check_mips_mt(env, ctx);
  3101 + gen_op_mfc0_vpecontrol();
3032 rn = "VPEControl"; 3102 rn = "VPEControl";
3033 -// break; 3103 + break;
3034 case 2: 3104 case 2:
3035 -// gen_op_dmfc0_vpeconf0(); /* MT ASE */ 3105 + check_mips_mt(env, ctx);
  3106 + gen_op_mfc0_vpeconf0();
3036 rn = "VPEConf0"; 3107 rn = "VPEConf0";
3037 -// break; 3108 + break;
3038 case 3: 3109 case 3:
3039 -// gen_op_dmfc0_vpeconf1(); /* MT ASE */ 3110 + check_mips_mt(env, ctx);
  3111 + gen_op_mfc0_vpeconf1();
3040 rn = "VPEConf1"; 3112 rn = "VPEConf1";
3041 -// break; 3113 + break;
3042 case 4: 3114 case 4:
3043 -// gen_op_dmfc0_YQMask(); /* MT ASE */ 3115 + check_mips_mt(env, ctx);
  3116 + gen_op_dmfc0_yqmask();
3044 rn = "YQMask"; 3117 rn = "YQMask";
3045 -// break; 3118 + break;
3046 case 5: 3119 case 5:
3047 -// gen_op_dmfc0_vpeschedule(); /* MT ASE */ 3120 + check_mips_mt(env, ctx);
  3121 + gen_op_dmfc0_vpeschedule();
3048 rn = "VPESchedule"; 3122 rn = "VPESchedule";
3049 -// break; 3123 + break;
3050 case 6: 3124 case 6:
3051 -// gen_op_dmfc0_vpeschefback(); /* MT ASE */ 3125 + check_mips_mt(env, ctx);
  3126 + gen_op_dmfc0_vpeschefback();
3052 rn = "VPEScheFBack"; 3127 rn = "VPEScheFBack";
3053 -// break; 3128 + break;
3054 case 7: 3129 case 7:
3055 -// gen_op_dmfc0_vpeopt(); /* MT ASE */ 3130 + check_mips_mt(env, ctx);
  3131 + gen_op_mfc0_vpeopt();
3056 rn = "VPEOpt"; 3132 rn = "VPEOpt";
3057 -// break; 3133 + break;
3058 default: 3134 default:
3059 goto die; 3135 goto die;
3060 } 3136 }
@@ -3066,33 +3142,40 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3066,33 +3142,40 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3066 rn = "EntryLo0"; 3142 rn = "EntryLo0";
3067 break; 3143 break;
3068 case 1: 3144 case 1:
3069 -// gen_op_dmfc0_tcstatus(); /* MT ASE */ 3145 + check_mips_mt(env, ctx);
  3146 + gen_op_mfc0_tcstatus();
3070 rn = "TCStatus"; 3147 rn = "TCStatus";
3071 -// break; 3148 + break;
3072 case 2: 3149 case 2:
3073 -// gen_op_dmfc0_tcbind(); /* MT ASE */ 3150 + check_mips_mt(env, ctx);
  3151 + gen_op_mfc0_tcbind();
3074 rn = "TCBind"; 3152 rn = "TCBind";
3075 -// break; 3153 + break;
3076 case 3: 3154 case 3:
3077 -// gen_op_dmfc0_tcrestart(); /* MT ASE */ 3155 + check_mips_mt(env, ctx);
  3156 + gen_op_dmfc0_tcrestart();
3078 rn = "TCRestart"; 3157 rn = "TCRestart";
3079 -// break; 3158 + break;
3080 case 4: 3159 case 4:
3081 -// gen_op_dmfc0_tchalt(); /* MT ASE */ 3160 + check_mips_mt(env, ctx);
  3161 + gen_op_dmfc0_tchalt();
3082 rn = "TCHalt"; 3162 rn = "TCHalt";
3083 -// break; 3163 + break;
3084 case 5: 3164 case 5:
3085 -// gen_op_dmfc0_tccontext(); /* MT ASE */ 3165 + check_mips_mt(env, ctx);
  3166 + gen_op_dmfc0_tccontext();
3086 rn = "TCContext"; 3167 rn = "TCContext";
3087 -// break; 3168 + break;
3088 case 6: 3169 case 6:
3089 -// gen_op_dmfc0_tcschedule(); /* MT ASE */ 3170 + check_mips_mt(env, ctx);
  3171 + gen_op_dmfc0_tcschedule();
3090 rn = "TCSchedule"; 3172 rn = "TCSchedule";
3091 -// break; 3173 + break;
3092 case 7: 3174 case 7:
3093 -// gen_op_dmfc0_tcschefback(); /* MT ASE */ 3175 + check_mips_mt(env, ctx);
  3176 + gen_op_dmfc0_tcschefback();
3094 rn = "TCScheFBack"; 3177 rn = "TCScheFBack";
3095 -// break; 3178 + break;
3096 default: 3179 default:
3097 goto die; 3180 goto die;
3098 } 3181 }
@@ -3143,25 +3226,25 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3143,25 +3226,25 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3143 rn = "Wired"; 3226 rn = "Wired";
3144 break; 3227 break;
3145 case 1: 3228 case 1:
3146 -// gen_op_dmfc0_srsconf0(); /* shadow registers */ 3229 + gen_op_mfc0_srsconf0();
3147 rn = "SRSConf0"; 3230 rn = "SRSConf0";
3148 -// break; 3231 + break;
3149 case 2: 3232 case 2:
3150 -// gen_op_dmfc0_srsconf1(); /* shadow registers */ 3233 + gen_op_mfc0_srsconf1();
3151 rn = "SRSConf1"; 3234 rn = "SRSConf1";
3152 -// break; 3235 + break;
3153 case 3: 3236 case 3:
3154 -// gen_op_dmfc0_srsconf2(); /* shadow registers */ 3237 + gen_op_mfc0_srsconf2();
3155 rn = "SRSConf2"; 3238 rn = "SRSConf2";
3156 -// break; 3239 + break;
3157 case 4: 3240 case 4:
3158 -// gen_op_dmfc0_srsconf3(); /* shadow registers */ 3241 + gen_op_mfc0_srsconf3();
3159 rn = "SRSConf3"; 3242 rn = "SRSConf3";
3160 -// break; 3243 + break;
3161 case 5: 3244 case 5:
3162 -// gen_op_dmfc0_srsconf4(); /* shadow registers */ 3245 + gen_op_mfc0_srsconf4();
3163 rn = "SRSConf4"; 3246 rn = "SRSConf4";
3164 -// break; 3247 + break;
3165 default: 3248 default:
3166 goto die; 3249 goto die;
3167 } 3250 }
@@ -3237,7 +3320,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3237,7 +3320,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3237 break; 3320 break;
3238 case 3: 3321 case 3:
3239 check_mips_r2(env, ctx); 3322 check_mips_r2(env, ctx);
3240 - gen_op_mfc0_srsmap(); /* shadow registers */ 3323 + gen_op_mfc0_srsmap();
3241 rn = "SRSMap"; 3324 rn = "SRSMap";
3242 break; 3325 break;
3243 default: 3326 default:
@@ -3537,17 +3620,20 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3537,17 +3620,20 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3537 rn = "Index"; 3620 rn = "Index";
3538 break; 3621 break;
3539 case 1: 3622 case 1:
3540 -// gen_op_mtc0_mvpcontrol(); /* MT ASE */ 3623 + check_mips_mt(env, ctx);
  3624 + gen_op_mtc0_mvpcontrol();
3541 rn = "MVPControl"; 3625 rn = "MVPControl";
3542 -// break; 3626 + break;
3543 case 2: 3627 case 2:
3544 -// gen_op_mtc0_mvpconf0(); /* MT ASE */ 3628 + check_mips_mt(env, ctx);
  3629 + /* ignored */
3545 rn = "MVPConf0"; 3630 rn = "MVPConf0";
3546 -// break; 3631 + break;
3547 case 3: 3632 case 3:
3548 -// gen_op_mtc0_mvpconf1(); /* MT ASE */ 3633 + check_mips_mt(env, ctx);
  3634 + /* ignored */
3549 rn = "MVPConf1"; 3635 rn = "MVPConf1";
3550 -// break; 3636 + break;
3551 default: 3637 default:
3552 goto die; 3638 goto die;
3553 } 3639 }
@@ -3559,33 +3645,40 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3559,33 +3645,40 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3559 rn = "Random"; 3645 rn = "Random";
3560 break; 3646 break;
3561 case 1: 3647 case 1:
3562 -// gen_op_mtc0_vpecontrol(); /* MT ASE */ 3648 + check_mips_mt(env, ctx);
  3649 + gen_op_mtc0_vpecontrol();
3563 rn = "VPEControl"; 3650 rn = "VPEControl";
3564 -// break; 3651 + break;
3565 case 2: 3652 case 2:
3566 -// gen_op_mtc0_vpeconf0(); /* MT ASE */ 3653 + check_mips_mt(env, ctx);
  3654 + gen_op_mtc0_vpeconf0();
3567 rn = "VPEConf0"; 3655 rn = "VPEConf0";
3568 -// break; 3656 + break;
3569 case 3: 3657 case 3:
3570 -// gen_op_mtc0_vpeconf1(); /* MT ASE */ 3658 + check_mips_mt(env, ctx);
  3659 + gen_op_mtc0_vpeconf1();
3571 rn = "VPEConf1"; 3660 rn = "VPEConf1";
3572 -// break; 3661 + break;
3573 case 4: 3662 case 4:
3574 -// gen_op_mtc0_YQMask(); /* MT ASE */ 3663 + check_mips_mt(env, ctx);
  3664 + gen_op_mtc0_yqmask();
3575 rn = "YQMask"; 3665 rn = "YQMask";
3576 -// break; 3666 + break;
3577 case 5: 3667 case 5:
3578 -// gen_op_mtc0_vpeschedule(); /* MT ASE */ 3668 + check_mips_mt(env, ctx);
  3669 + gen_op_mtc0_vpeschedule();
3579 rn = "VPESchedule"; 3670 rn = "VPESchedule";
3580 -// break; 3671 + break;
3581 case 6: 3672 case 6:
3582 -// gen_op_mtc0_vpeschefback(); /* MT ASE */ 3673 + check_mips_mt(env, ctx);
  3674 + gen_op_mtc0_vpeschefback();
3583 rn = "VPEScheFBack"; 3675 rn = "VPEScheFBack";
3584 -// break; 3676 + break;
3585 case 7: 3677 case 7:
3586 -// gen_op_mtc0_vpeopt(); /* MT ASE */ 3678 + check_mips_mt(env, ctx);
  3679 + gen_op_mtc0_vpeopt();
3587 rn = "VPEOpt"; 3680 rn = "VPEOpt";
3588 -// break; 3681 + break;
3589 default: 3682 default:
3590 goto die; 3683 goto die;
3591 } 3684 }
@@ -3597,33 +3690,40 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3597,33 +3690,40 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3597 rn = "EntryLo0"; 3690 rn = "EntryLo0";
3598 break; 3691 break;
3599 case 1: 3692 case 1:
3600 -// gen_op_mtc0_tcstatus(); /* MT ASE */ 3693 + check_mips_mt(env, ctx);
  3694 + gen_op_mtc0_tcstatus();
3601 rn = "TCStatus"; 3695 rn = "TCStatus";
3602 -// break; 3696 + break;
3603 case 2: 3697 case 2:
3604 -// gen_op_mtc0_tcbind(); /* MT ASE */ 3698 + check_mips_mt(env, ctx);
  3699 + gen_op_mtc0_tcbind();
3605 rn = "TCBind"; 3700 rn = "TCBind";
3606 -// break; 3701 + break;
3607 case 3: 3702 case 3:
3608 -// gen_op_mtc0_tcrestart(); /* MT ASE */ 3703 + check_mips_mt(env, ctx);
  3704 + gen_op_mtc0_tcrestart();
3609 rn = "TCRestart"; 3705 rn = "TCRestart";
3610 -// break; 3706 + break;
3611 case 4: 3707 case 4:
3612 -// gen_op_mtc0_tchalt(); /* MT ASE */ 3708 + check_mips_mt(env, ctx);
  3709 + gen_op_mtc0_tchalt();
3613 rn = "TCHalt"; 3710 rn = "TCHalt";
3614 -// break; 3711 + break;
3615 case 5: 3712 case 5:
3616 -// gen_op_mtc0_tccontext(); /* MT ASE */ 3713 + check_mips_mt(env, ctx);
  3714 + gen_op_mtc0_tccontext();
3617 rn = "TCContext"; 3715 rn = "TCContext";
3618 -// break; 3716 + break;
3619 case 6: 3717 case 6:
3620 -// gen_op_mtc0_tcschedule(); /* MT ASE */ 3718 + check_mips_mt(env, ctx);
  3719 + gen_op_mtc0_tcschedule();
3621 rn = "TCSchedule"; 3720 rn = "TCSchedule";
3622 -// break; 3721 + break;
3623 case 7: 3722 case 7:
3624 -// gen_op_mtc0_tcschefback(); /* MT ASE */ 3723 + check_mips_mt(env, ctx);
  3724 + gen_op_mtc0_tcschefback();
3625 rn = "TCScheFBack"; 3725 rn = "TCScheFBack";
3626 -// break; 3726 + break;
3627 default: 3727 default:
3628 goto die; 3728 goto die;
3629 } 3729 }
@@ -3674,25 +3774,25 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) @@ -3674,25 +3774,25 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3674 rn = "Wired"; 3774 rn = "Wired";
3675 break; 3775 break;
3676 case 1: 3776 case 1:
3677 -// gen_op_mtc0_srsconf0(); /* shadow registers */ 3777 + gen_op_mtc0_srsconf0();
3678 rn = "SRSConf0"; 3778 rn = "SRSConf0";
3679 -// break; 3779 + break;
3680 case 2: 3780 case 2:
3681 -// gen_op_mtc0_srsconf1(); /* shadow registers */ 3781 + gen_op_mtc0_srsconf1();
3682 rn = "SRSConf1"; 3782 rn = "SRSConf1";
3683 -// break; 3783 + break;
3684 case 3: 3784 case 3:
3685 -// gen_op_mtc0_srsconf2(); /* shadow registers */ 3785 + gen_op_mtc0_srsconf2();
3686 rn = "SRSConf2"; 3786 rn = "SRSConf2";
3687 -// break; 3787 + break;
3688 case 4: 3788 case 4:
3689 -// gen_op_mtc0_srsconf3(); /* shadow registers */ 3789 + gen_op_mtc0_srsconf3();
3690 rn = "SRSConf3"; 3790 rn = "SRSConf3";
3691 -// break; 3791 + break;
3692 case 5: 3792 case 5:
3693 -// gen_op_mtc0_srsconf4(); /* shadow registers */ 3793 + gen_op_mtc0_srsconf4();
3694 rn = "SRSConf4"; 3794 rn = "SRSConf4";
3695 -// break; 3795 + break;
3696 default: 3796 default:
3697 goto die; 3797 goto die;
3698 } 3798 }
@@ -4086,6 +4186,334 @@ die: @@ -4086,6 +4186,334 @@ die:
4086 } 4186 }
4087 #endif /* TARGET_MIPS64 */ 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 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd) 4517 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4090 { 4518 {
4091 const char *opn = "ldst"; 4519 const char *opn = "ldst";
@@ -4093,7 +4521,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int @@ -4093,7 +4521,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4093 switch (opc) { 4521 switch (opc) {
4094 case OPC_MFC0: 4522 case OPC_MFC0:
4095 if (rt == 0) { 4523 if (rt == 0) {
4096 - /* Treat as NOP */ 4524 + /* Treat as NOP. */
4097 return; 4525 return;
4098 } 4526 }
4099 gen_mfc0(env, ctx, rd, ctx->opcode & 0x7); 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,7 +4538,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4110 if (!(ctx->hflags & MIPS_HFLAG_64)) 4538 if (!(ctx->hflags & MIPS_HFLAG_64))
4111 generate_exception(ctx, EXCP_RI); 4539 generate_exception(ctx, EXCP_RI);
4112 if (rt == 0) { 4540 if (rt == 0) {
4113 - /* Treat as NOP */ 4541 + /* Treat as NOP. */
4114 return; 4542 return;
4115 } 4543 }
4116 gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7); 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,31 +4549,49 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4121 if (!(ctx->hflags & MIPS_HFLAG_64)) 4549 if (!(ctx->hflags & MIPS_HFLAG_64))
4122 generate_exception(ctx, EXCP_RI); 4550 generate_exception(ctx, EXCP_RI);
4123 GEN_LOAD_REG_TN(T0, rt); 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 opn = "dmtc0"; 4553 opn = "dmtc0";
4126 break; 4554 break;
4127 #endif 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 case OPC_TLBWI: 4574 case OPC_TLBWI:
4129 opn = "tlbwi"; 4575 opn = "tlbwi";
4130 - if (!env->do_tlbwi) 4576 + if (!env->tlb->do_tlbwi)
4131 goto die; 4577 goto die;
4132 gen_op_tlbwi(); 4578 gen_op_tlbwi();
4133 break; 4579 break;
4134 case OPC_TLBWR: 4580 case OPC_TLBWR:
4135 opn = "tlbwr"; 4581 opn = "tlbwr";
4136 - if (!env->do_tlbwr) 4582 + if (!env->tlb->do_tlbwr)
4137 goto die; 4583 goto die;
4138 gen_op_tlbwr(); 4584 gen_op_tlbwr();
4139 break; 4585 break;
4140 case OPC_TLBP: 4586 case OPC_TLBP:
4141 opn = "tlbp"; 4587 opn = "tlbp";
4142 - if (!env->do_tlbp) 4588 + if (!env->tlb->do_tlbp)
4143 goto die; 4589 goto die;
4144 gen_op_tlbp(); 4590 gen_op_tlbp();
4145 break; 4591 break;
4146 case OPC_TLBR: 4592 case OPC_TLBR:
4147 opn = "tlbr"; 4593 opn = "tlbr";
4148 - if (!env->do_tlbr) 4594 + if (!env->tlb->do_tlbr)
4149 goto die; 4595 goto die;
4150 gen_op_tlbr(); 4596 gen_op_tlbr();
4151 break; 4597 break;
@@ -4263,15 +4709,13 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) @@ -4263,15 +4709,13 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4263 opn = "mtc1"; 4709 opn = "mtc1";
4264 break; 4710 break;
4265 case OPC_CFC1: 4711 case OPC_CFC1:
4266 - GEN_LOAD_IMM_TN(T1, fs);  
4267 - gen_op_cfc1(); 4712 + gen_op_cfc1(fs);
4268 GEN_STORE_TN_REG(rt, T0); 4713 GEN_STORE_TN_REG(rt, T0);
4269 opn = "cfc1"; 4714 opn = "cfc1";
4270 break; 4715 break;
4271 case OPC_CTC1: 4716 case OPC_CTC1:
4272 - GEN_LOAD_IMM_TN(T1, fs);  
4273 GEN_LOAD_REG_TN(T0, rt); 4717 GEN_LOAD_REG_TN(T0, rt);
4274 - gen_op_ctc1(); 4718 + gen_op_ctc1(fs);
4275 opn = "ctc1"; 4719 opn = "ctc1";
4276 break; 4720 break;
4277 case OPC_DMFC1: 4721 case OPC_DMFC1:
@@ -5171,8 +5615,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, @@ -5171,8 +5615,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5171 gen_op_addr_add(); 5615 gen_op_addr_add();
5172 } 5616 }
5173 /* Don't do NOP if destination is zero: we must perform the actual 5617 /* Don't do NOP if destination is zero: we must perform the actual
5174 - * memory access  
5175 - */ 5618 + memory access. */
5176 switch (opc) { 5619 switch (opc) {
5177 case OPC_LWXC1: 5620 case OPC_LWXC1:
5178 op_ldst(lwc1); 5621 op_ldst(lwc1);
@@ -5456,7 +5899,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5456,7 +5899,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5456 #endif 5899 #endif
5457 break; 5900 break;
5458 case OPC_SYNC: 5901 case OPC_SYNC:
5459 - /* Treat as a noop. */ 5902 + /* Treat as NOP. */
5460 break; 5903 break;
5461 5904
5462 case OPC_MOVCI: 5905 case OPC_MOVCI:
@@ -5521,7 +5964,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5521,7 +5964,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5521 } else { 5964 } else {
5522 generate_exception(ctx, EXCP_DBp); 5965 generate_exception(ctx, EXCP_DBp);
5523 } 5966 }
5524 - /* Treat as a noop */ 5967 + /* Treat as NOP. */
5525 break; 5968 break;
5526 #ifdef TARGET_MIPS64 5969 #ifdef TARGET_MIPS64
5527 case OPC_DCLZ ... OPC_DCLO: 5970 case OPC_DCLZ ... OPC_DCLO:
@@ -5586,7 +6029,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5586,7 +6029,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5586 break; 6029 break;
5587 case 29: 6030 case 29:
5588 #if defined (CONFIG_USER_ONLY) 6031 #if defined (CONFIG_USER_ONLY)
5589 - gen_op_tls_value (); 6032 + gen_op_tls_value();
5590 break; 6033 break;
5591 #endif 6034 #endif
5592 default: /* Invalid */ 6035 default: /* Invalid */
@@ -5596,6 +6039,18 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5596,6 +6039,18 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5596 } 6039 }
5597 GEN_STORE_TN_REG(rt, T0); 6040 GEN_STORE_TN_REG(rt, T0);
5598 break; 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 #ifdef TARGET_MIPS64 6054 #ifdef TARGET_MIPS64
5600 case OPC_DEXTM ... OPC_DEXT: 6055 case OPC_DEXTM ... OPC_DEXT:
5601 case OPC_DINSM ... OPC_DINS: 6056 case OPC_DINSM ... OPC_DINS:
@@ -5642,7 +6097,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5642,7 +6097,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5642 break; 6097 break;
5643 case OPC_SYNCI: 6098 case OPC_SYNCI:
5644 check_mips_r2(env, ctx); 6099 check_mips_r2(env, ctx);
5645 - /* treat as noop */ 6100 + /* Treat as NOP. */
5646 break; 6101 break;
5647 default: /* Invalid */ 6102 default: /* Invalid */
5648 MIPS_INVAL("regimm"); 6103 MIPS_INVAL("regimm");
@@ -5657,6 +6112,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5657,6 +6112,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5657 switch (op1) { 6112 switch (op1) {
5658 case OPC_MFC0: 6113 case OPC_MFC0:
5659 case OPC_MTC0: 6114 case OPC_MTC0:
  6115 + case OPC_MFTR:
  6116 + case OPC_MTTR:
5660 #ifdef TARGET_MIPS64 6117 #ifdef TARGET_MIPS64
5661 case OPC_DMFC0: 6118 case OPC_DMFC0:
5662 case OPC_DMTC0: 6119 case OPC_DMTC0:
@@ -5670,6 +6127,22 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5670,6 +6127,22 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5670 check_mips_r2(env, ctx); 6127 check_mips_r2(env, ctx);
5671 op2 = MASK_MFMC0(ctx->opcode); 6128 op2 = MASK_MFMC0(ctx->opcode);
5672 switch (op2) { 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 case OPC_DI: 6146 case OPC_DI:
5674 gen_op_di(); 6147 gen_op_di();
5675 /* Stop translation as we may have switched the execution mode */ 6148 /* Stop translation as we may have switched the execution mode */
@@ -5688,11 +6161,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5688,11 +6161,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5688 GEN_STORE_TN_REG(rt, T0); 6161 GEN_STORE_TN_REG(rt, T0);
5689 break; 6162 break;
5690 case OPC_RDPGPR: 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 case OPC_WRPGPR: 6168 case OPC_WRPGPR:
5692 check_mips_r2(env, ctx); 6169 check_mips_r2(env, ctx);
5693 - /* Shadow registers not implemented. */  
5694 GEN_LOAD_REG_TN(T0, rt); 6170 GEN_LOAD_REG_TN(T0, rt);
5695 - GEN_STORE_TN_REG(rd, T0); 6171 + GEN_STORE_TN_SRSREG(rd, T0);
5696 break; 6172 break;
5697 default: 6173 default:
5698 MIPS_INVAL("cp0"); 6174 MIPS_INVAL("cp0");
@@ -5719,10 +6195,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5719,10 +6195,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5719 gen_ldst(ctx, op, rt, rs, imm); 6195 gen_ldst(ctx, op, rt, rs, imm);
5720 break; 6196 break;
5721 case OPC_CACHE: 6197 case OPC_CACHE:
5722 - /* Treat as a noop */ 6198 + /* Treat as NOP. */
5723 break; 6199 break;
5724 case OPC_PREF: 6200 case OPC_PREF:
5725 - /* Treat as a noop */ 6201 + /* Treat as NOP. */
5726 break; 6202 break;
5727 6203
5728 /* Floating point (COP1). */ 6204 /* Floating point (COP1). */
@@ -5807,7 +6283,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -5807,7 +6283,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5807 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 6283 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5808 break; 6284 break;
5809 case OPC_PREFX: 6285 case OPC_PREFX:
5810 - /* treat as noop */ 6286 + /* Treat as NOP. */
5811 break; 6287 break;
5812 case OPC_ALNV_PS: 6288 case OPC_ALNV_PS:
5813 case OPC_MADD_S: 6289 case OPC_MADD_S:
@@ -6079,13 +6555,14 @@ void fpu_dump_state(CPUState *env, FILE *f, @@ -6079,13 +6555,14 @@ void fpu_dump_state(CPUState *env, FILE *f,
6079 6555
6080 6556
6081 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n", 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 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { 6563 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6087 fpu_fprintf(f, "%3s: ", fregnames[i]); 6564 fpu_fprintf(f, "%3s: ", fregnames[i]);
6088 - printfpr(&env->fpr[i]); 6565 + printfpr(&env->fpu->fpr[i]);
6089 } 6566 }
6090 6567
6091 #undef printfpr 6568 #undef printfpr
@@ -6095,7 +6572,7 @@ void dump_fpu (CPUState *env) @@ -6095,7 +6572,7 @@ void dump_fpu (CPUState *env)
6095 { 6572 {
6096 if (loglevel) { 6573 if (loglevel) {
6097 fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n", 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 fpu_dump_state(env, logfile, fprintf, 0); 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,18 +6589,18 @@ void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6112 { 6589 {
6113 int i; 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 if (!SIGN_EXT_P(env->btarget)) 6598 if (!SIGN_EXT_P(env->btarget))
6122 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget); 6599 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6123 6600
6124 for (i = 0; i < 32; i++) { 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 if (!SIGN_EXT_P(env->CP0_EPC)) 6606 if (!SIGN_EXT_P(env->CP0_EPC))
@@ -6140,11 +6617,11 @@ void cpu_dump_state (CPUState *env, FILE *f, @@ -6140,11 +6617,11 @@ void cpu_dump_state (CPUState *env, FILE *f,
6140 int i; 6617 int i;
6141 6618
6142 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", 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 for (i = 0; i < 32; i++) { 6621 for (i = 0; i < 32; i++) {
6145 if ((i & 3) == 0) 6622 if ((i & 3) == 0)
6146 cpu_fprintf(f, "GPR%02d:", i); 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 if ((i & 3) == 3) 6625 if ((i & 3) == 3)
6149 cpu_fprintf(f, "\n"); 6626 cpu_fprintf(f, "\n");
6150 } 6627 }
@@ -6183,12 +6660,12 @@ void cpu_reset (CPUMIPSState *env) @@ -6183,12 +6660,12 @@ void cpu_reset (CPUMIPSState *env)
6183 if (env->hflags & MIPS_HFLAG_BMASK) { 6660 if (env->hflags & MIPS_HFLAG_BMASK) {
6184 /* If the exception was raised from a delay slot, 6661 /* If the exception was raised from a delay slot,
6185 * come back to the jump. */ 6662 * come back to the jump. */
6186 - env->CP0_ErrorEPC = env->PC - 4; 6663 + env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6187 } else { 6664 } else {
6188 - env->CP0_ErrorEPC = env->PC; 6665 + env->CP0_ErrorEPC = env->PC[env->current_tc];
6189 } 6666 }
6190 env->hflags = 0; 6667 env->hflags = 0;
6191 - env->PC = (int32_t)0xBFC00000; 6668 + env->PC[env->current_tc] = (int32_t)0xBFC00000;
6192 env->CP0_Wired = 0; 6669 env->CP0_Wired = 0;
6193 /* SMP not implemented */ 6670 /* SMP not implemented */
6194 env->CP0_EBase = 0x80000000; 6671 env->CP0_EBase = 0x80000000;
target-mips/translate_init.c
@@ -43,11 +43,11 @@ @@ -43,11 +43,11 @@
43 43
44 /* No config4, no DSP ASE, no large physaddr, 44 /* No config4, no DSP ASE, no large physaddr,
45 no external interrupt controller, no vectored interupts, 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 #define MIPS_CONFIG3 \ 47 #define MIPS_CONFIG3 \
48 ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ 48 ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \
49 (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ 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 /* Define a implementation number of 1. 52 /* Define a implementation number of 1.
53 Define a major version 1, minor version 0. */ 53 Define a major version 1, minor version 0. */
@@ -65,9 +65,21 @@ struct mips_def_t { @@ -65,9 +65,21 @@ struct mips_def_t {
65 int32_t CP0_Config7; 65 int32_t CP0_Config7;
66 int32_t SYNCI_Step; 66 int32_t SYNCI_Step;
67 int32_t CCRes; 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 int32_t CP1_fcr0; 71 int32_t CP1_fcr0;
70 int32_t SEGBITS; 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,7 +97,7 @@ static mips_def_t mips_defs[] =
85 .CP0_Config3 = MIPS_CONFIG3, 97 .CP0_Config3 = MIPS_CONFIG3,
86 .SYNCI_Step = 32, 98 .SYNCI_Step = 32,
87 .CCRes = 2, 99 .CCRes = 2,
88 - .Status_rw_bitmask = 0x3278FF17, 100 + .CP0_Status_rw_bitmask = 0x1278FF17,
89 }, 101 },
90 { 102 {
91 .name = "4KEcR1", 103 .name = "4KEcR1",
@@ -98,7 +110,7 @@ static mips_def_t mips_defs[] = @@ -98,7 +110,7 @@ static mips_def_t mips_defs[] =
98 .CP0_Config3 = MIPS_CONFIG3, 110 .CP0_Config3 = MIPS_CONFIG3,
99 .SYNCI_Step = 32, 111 .SYNCI_Step = 32,
100 .CCRes = 2, 112 .CCRes = 2,
101 - .Status_rw_bitmask = 0x3278FF17, 113 + .CP0_Status_rw_bitmask = 0x1278FF17,
102 }, 114 },
103 { 115 {
104 .name = "4KEc", 116 .name = "4KEc",
@@ -108,10 +120,10 @@ static mips_def_t mips_defs[] = @@ -108,10 +120,10 @@ static mips_def_t mips_defs[] =
108 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | 120 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
109 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA), 121 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
110 .CP0_Config2 = MIPS_CONFIG2, 122 .CP0_Config2 = MIPS_CONFIG2,
111 - .CP0_Config3 = MIPS_CONFIG3, 123 + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
112 .SYNCI_Step = 32, 124 .SYNCI_Step = 32,
113 .CCRes = 2, 125 .CCRes = 2,
114 - .Status_rw_bitmask = 0x3278FF17, 126 + .CP0_Status_rw_bitmask = 0x1278FF17,
115 }, 127 },
116 { 128 {
117 .name = "24Kc", 129 .name = "24Kc",
@@ -121,10 +133,11 @@ static mips_def_t mips_defs[] = @@ -121,10 +133,11 @@ static mips_def_t mips_defs[] =
121 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | 133 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
122 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA), 134 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
123 .CP0_Config2 = MIPS_CONFIG2, 135 .CP0_Config2 = MIPS_CONFIG2,
124 - .CP0_Config3 = MIPS_CONFIG3, 136 + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
125 .SYNCI_Step = 32, 137 .SYNCI_Step = 32,
126 .CCRes = 2, 138 .CCRes = 2,
127 - .Status_rw_bitmask = 0x3278FF17, 139 + /* No DSP implemented. */
  140 + .CP0_Status_rw_bitmask = 0x1278FF17,
128 }, 141 },
129 { 142 {
130 .name = "24Kf", 143 .name = "24Kf",
@@ -134,13 +147,53 @@ static mips_def_t mips_defs[] = @@ -134,13 +147,53 @@ static mips_def_t mips_defs[] =
134 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | 147 (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
135 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA), 148 (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
136 .CP0_Config2 = MIPS_CONFIG2, 149 .CP0_Config2 = MIPS_CONFIG2,
137 - .CP0_Config3 = MIPS_CONFIG3, 150 + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
138 .SYNCI_Step = 32, 151 .SYNCI_Step = 32,
139 .CCRes = 2, 152 .CCRes = 2,
140 - .Status_rw_bitmask = 0x3678FF17, 153 + /* No DSP implemented. */
  154 + .CP0_Status_rw_bitmask = 0x3678FF17,
141 .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | 155 .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
142 (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), 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 #ifdef TARGET_MIPS64 197 #ifdef TARGET_MIPS64
145 { 198 {
146 .name = "R4000", 199 .name = "R4000",
@@ -153,7 +206,7 @@ static mips_def_t mips_defs[] = @@ -153,7 +206,7 @@ static mips_def_t mips_defs[] =
153 .CP0_Config3 = MIPS_CONFIG3, 206 .CP0_Config3 = MIPS_CONFIG3,
154 .SYNCI_Step = 16, 207 .SYNCI_Step = 16,
155 .CCRes = 2, 208 .CCRes = 2,
156 - .Status_rw_bitmask = 0x3678FFFF, 209 + .CP0_Status_rw_bitmask = 0x3678FFFF,
157 /* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */ 210 /* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
158 .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV), 211 .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
159 .SEGBITS = 40, 212 .SEGBITS = 40,
@@ -170,7 +223,7 @@ static mips_def_t mips_defs[] = @@ -170,7 +223,7 @@ static mips_def_t mips_defs[] =
170 .CP0_Config3 = MIPS_CONFIG3, 223 .CP0_Config3 = MIPS_CONFIG3,
171 .SYNCI_Step = 32, 224 .SYNCI_Step = 32,
172 .CCRes = 2, 225 .CCRes = 2,
173 - .Status_rw_bitmask = 0x32F8FFFF, 226 + .CP0_Status_rw_bitmask = 0x32F8FFFF,
174 .SEGBITS = 42, 227 .SEGBITS = 42,
175 }, 228 },
176 { 229 {
@@ -185,7 +238,7 @@ static mips_def_t mips_defs[] = @@ -185,7 +238,7 @@ static mips_def_t mips_defs[] =
185 .CP0_Config3 = MIPS_CONFIG3, 238 .CP0_Config3 = MIPS_CONFIG3,
186 .SYNCI_Step = 32, 239 .SYNCI_Step = 32,
187 .CCRes = 2, 240 .CCRes = 2,
188 - .Status_rw_bitmask = 0x36F8FFFF, 241 + .CP0_Status_rw_bitmask = 0x36F8FFFF,
189 /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */ 242 /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
190 .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) | 243 .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
191 (0x81 << FCR0_PRID) | (0x0 << FCR0_REV), 244 (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
@@ -205,7 +258,7 @@ static mips_def_t mips_defs[] = @@ -205,7 +258,7 @@ static mips_def_t mips_defs[] =
205 .CP0_Config3 = MIPS_CONFIG3, 258 .CP0_Config3 = MIPS_CONFIG3,
206 .SYNCI_Step = 32, 259 .SYNCI_Step = 32,
207 .CCRes = 2, 260 .CCRes = 2,
208 - .Status_rw_bitmask = 0x36FBFFFF, 261 + .CP0_Status_rw_bitmask = 0x36FBFFFF,
209 /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */ 262 /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */
210 .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) | 263 .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
211 (1 << FCR0_D) | (1 << FCR0_S) | 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,27 +298,88 @@ void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
245 #ifndef CONFIG_USER_ONLY 298 #ifndef CONFIG_USER_ONLY
246 static void no_mmu_init (CPUMIPSState *env, mips_def_t *def) 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 static void fixed_mmu_init (CPUMIPSState *env, mips_def_t *def) 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 static void r4k_mmu_init (CPUMIPSState *env, mips_def_t *def) 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 #endif /* CONFIG_USER_ONLY */ 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 int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) 383 int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
270 { 384 {
271 if (!def) 385 if (!def)
@@ -285,8 +399,9 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) @@ -285,8 +399,9 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
285 env->CP0_Config7 = def->CP0_Config7; 399 env->CP0_Config7 = def->CP0_Config7;
286 env->SYNCI_Step = def->SYNCI_Step; 400 env->SYNCI_Step = def->SYNCI_Step;
287 env->CCRes = def->CCRes; 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 #ifdef TARGET_MIPS64 405 #ifdef TARGET_MIPS64
291 if ((env->CP0_Config0 & (0x3 << CP0C0_AT))) 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,31 +413,21 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
298 env->SEGMask = 0xFFFFFFFF; 413 env->SEGMask = 0xFFFFFFFF;
299 } 414 }
300 #endif 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 return 0; 432 return 0;
328 } 433 }
translate-all.c
@@ -305,7 +305,7 @@ int cpu_restore_state(TranslationBlock *tb, @@ -305,7 +305,7 @@ int cpu_restore_state(TranslationBlock *tb,
305 #elif defined(TARGET_M68K) 305 #elif defined(TARGET_M68K)
306 env->pc = gen_opc_pc[j]; 306 env->pc = gen_opc_pc[j];
307 #elif defined(TARGET_MIPS) 307 #elif defined(TARGET_MIPS)
308 - env->PC = gen_opc_pc[j]; 308 + env->PC[env->current_tc] = gen_opc_pc[j];
309 env->hflags &= ~MIPS_HFLAG_BMASK; 309 env->hflags &= ~MIPS_HFLAG_BMASK;
310 env->hflags |= gen_opc_hflags[j]; 310 env->hflags |= gen_opc_hflags[j];
311 #elif defined(TARGET_ALPHA) 311 #elif defined(TARGET_ALPHA)