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

Too many changes to show.

To preserve performance only 15 of 18 files are displayed.

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