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 194 #elif defined(TARGET_MIPS)
195 195 flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
196 196 cs_base = 0;
197   - pc = env->PC;
  197 + pc = env->PC[env->current_tc];
198 198 #elif defined(TARGET_M68K)
199 199 flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
200 200 | (env->sr & SR_S) /* Bit 13 */
... ...
gdbstub.c
... ... @@ -559,17 +559,17 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
559 559 ptr = mem_buf;
560 560 for (i = 0; i < 32; i++)
561 561 {
562   - *(target_ulong *)ptr = tswapl(env->gpr[i]);
  562 + *(target_ulong *)ptr = tswapl(env->gpr[i][env->current_tc]);
563 563 ptr += sizeof(target_ulong);
564 564 }
565 565  
566 566 *(target_ulong *)ptr = tswapl(env->CP0_Status);
567 567 ptr += sizeof(target_ulong);
568 568  
569   - *(target_ulong *)ptr = tswapl(env->LO);
  569 + *(target_ulong *)ptr = tswapl(env->LO[0][env->current_tc]);
570 570 ptr += sizeof(target_ulong);
571 571  
572   - *(target_ulong *)ptr = tswapl(env->HI);
  572 + *(target_ulong *)ptr = tswapl(env->HI[0][env->current_tc]);
573 573 ptr += sizeof(target_ulong);
574 574  
575 575 *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr);
... ... @@ -578,21 +578,21 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
578 578 *(target_ulong *)ptr = tswapl(env->CP0_Cause);
579 579 ptr += sizeof(target_ulong);
580 580  
581   - *(target_ulong *)ptr = tswapl(env->PC);
  581 + *(target_ulong *)ptr = tswapl(env->PC[env->current_tc]);
582 582 ptr += sizeof(target_ulong);
583 583  
584 584 if (env->CP0_Config1 & (1 << CP0C1_FP))
585 585 {
586 586 for (i = 0; i < 32; i++)
587 587 {
588   - *(target_ulong *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]);
  588 + *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].fs[FP_ENDIAN_IDX]);
589 589 ptr += sizeof(target_ulong);
590 590 }
591 591  
592   - *(target_ulong *)ptr = tswapl(env->fcr31);
  592 + *(target_ulong *)ptr = tswapl(env->fpu->fcr31);
593 593 ptr += sizeof(target_ulong);
594 594  
595   - *(target_ulong *)ptr = tswapl(env->fcr0);
  595 + *(target_ulong *)ptr = tswapl(env->fpu->fcr0);
596 596 ptr += sizeof(target_ulong);
597 597 }
598 598  
... ... @@ -611,7 +611,7 @@ static unsigned int ieee_rm[] =
611 611 float_round_down
612 612 };
613 613 #define RESTORE_ROUNDING_MODE \
614   - set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
  614 + set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)
615 615  
616 616 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
617 617 {
... ... @@ -621,17 +621,17 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
621 621 ptr = mem_buf;
622 622 for (i = 0; i < 32; i++)
623 623 {
624   - env->gpr[i] = tswapl(*(target_ulong *)ptr);
  624 + env->gpr[i][env->current_tc] = tswapl(*(target_ulong *)ptr);
625 625 ptr += sizeof(target_ulong);
626 626 }
627 627  
628 628 env->CP0_Status = tswapl(*(target_ulong *)ptr);
629 629 ptr += sizeof(target_ulong);
630 630  
631   - env->LO = tswapl(*(target_ulong *)ptr);
  631 + env->LO[0][env->current_tc] = tswapl(*(target_ulong *)ptr);
632 632 ptr += sizeof(target_ulong);
633 633  
634   - env->HI = tswapl(*(target_ulong *)ptr);
  634 + env->HI[0][env->current_tc] = tswapl(*(target_ulong *)ptr);
635 635 ptr += sizeof(target_ulong);
636 636  
637 637 env->CP0_BadVAddr = tswapl(*(target_ulong *)ptr);
... ... @@ -640,21 +640,21 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
640 640 env->CP0_Cause = tswapl(*(target_ulong *)ptr);
641 641 ptr += sizeof(target_ulong);
642 642  
643   - env->PC = tswapl(*(target_ulong *)ptr);
  643 + env->PC[env->current_tc] = tswapl(*(target_ulong *)ptr);
644 644 ptr += sizeof(target_ulong);
645 645  
646 646 if (env->CP0_Config1 & (1 << CP0C1_FP))
647 647 {
648 648 for (i = 0; i < 32; i++)
649 649 {
650   - env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
  650 + env->fpu->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
651 651 ptr += sizeof(target_ulong);
652 652 }
653 653  
654   - env->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
  654 + env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
655 655 ptr += sizeof(target_ulong);
656 656  
657   - env->fcr0 = tswapl(*(target_ulong *)ptr);
  657 + env->fpu->fcr0 = tswapl(*(target_ulong *)ptr);
658 658 ptr += sizeof(target_ulong);
659 659  
660 660 /* set rounding mode */
... ... @@ -775,7 +775,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
775 775 #elif defined (TARGET_SH4)
776 776 env->pc = addr;
777 777 #elif defined (TARGET_MIPS)
778   - env->PC = addr;
  778 + env->PC[env->current_tc] = addr;
779 779 #endif
780 780 }
781 781 #ifdef CONFIG_USER_ONLY
... ... @@ -799,7 +799,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
799 799 #elif defined (TARGET_SH4)
800 800 env->pc = addr;
801 801 #elif defined (TARGET_MIPS)
802   - env->PC = addr;
  802 + env->PC[env->current_tc] = addr;
803 803 #endif
804 804 }
805 805 cpu_single_step(env, 1);
... ...
hw/mips_r4k.c
... ... @@ -77,7 +77,7 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
77 77 if (kernel_size >= 0) {
78 78 if ((entry & ~0x7fffffffULL) == 0x80000000)
79 79 entry = (int32_t)entry;
80   - env->PC = entry;
  80 + env->PC[env->current_tc] = entry;
81 81 } else {
82 82 fprintf(stderr, "qemu: could not load kernel '%s'\n",
83 83 kernel_filename);
... ...
hw/mips_timer.c
... ... @@ -10,7 +10,7 @@ uint32_t cpu_mips_get_random (CPUState *env)
10 10 static uint32_t seed = 0;
11 11 uint32_t idx;
12 12 seed = seed * 314159 + 1;
13   - idx = (seed >> 16) % (env->nb_tlb - env->CP0_Wired) + env->CP0_Wired;
  13 + idx = (seed >> 16) % (env->tlb->nb_tlb - env->CP0_Wired) + env->CP0_Wired;
14 14 return idx;
15 15 }
16 16  
... ...
linux-user/main.c
... ... @@ -1374,8 +1374,8 @@ void cpu_loop(CPUMIPSState *env)
1374 1374 trapnr = cpu_mips_exec(env);
1375 1375 switch(trapnr) {
1376 1376 case EXCP_SYSCALL:
1377   - syscall_num = env->gpr[2] - 4000;
1378   - env->PC += 4;
  1377 + syscall_num = env->gpr[2][env->current_tc] - 4000;
  1378 + env->PC[env->current_tc] += 4;
1379 1379 if (syscall_num >= sizeof(mips_syscall_args)) {
1380 1380 ret = -ENOSYS;
1381 1381 } else {
... ... @@ -1384,7 +1384,7 @@ void cpu_loop(CPUMIPSState *env)
1384 1384 target_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
1385 1385  
1386 1386 nb_args = mips_syscall_args[syscall_num];
1387   - sp_reg = env->gpr[29];
  1387 + sp_reg = env->gpr[29][env->current_tc];
1388 1388 switch (nb_args) {
1389 1389 /* these arguments are taken from the stack */
1390 1390 case 8: arg8 = tgetl(sp_reg + 28);
... ... @@ -1394,18 +1394,20 @@ void cpu_loop(CPUMIPSState *env)
1394 1394 default:
1395 1395 break;
1396 1396 }
1397   - ret = do_syscall(env, env->gpr[2],
1398   - env->gpr[4], env->gpr[5],
1399   - env->gpr[6], env->gpr[7],
  1397 + ret = do_syscall(env, env->gpr[2][env->current_tc],
  1398 + env->gpr[4][env->current_tc],
  1399 + env->gpr[5][env->current_tc],
  1400 + env->gpr[6][env->current_tc],
  1401 + env->gpr[7][env->current_tc],
1400 1402 arg5, arg6/*, arg7, arg8*/);
1401 1403 }
1402 1404 if ((unsigned int)ret >= (unsigned int)(-1133)) {
1403   - env->gpr[7] = 1; /* error flag */
  1405 + env->gpr[7][env->current_tc] = 1; /* error flag */
1404 1406 ret = -ret;
1405 1407 } else {
1406   - env->gpr[7] = 0; /* error flag */
  1408 + env->gpr[7][env->current_tc] = 0; /* error flag */
1407 1409 }
1408   - env->gpr[2] = ret;
  1410 + env->gpr[2][env->current_tc] = ret;
1409 1411 break;
1410 1412 case EXCP_TLBL:
1411 1413 case EXCP_TLBS:
... ... @@ -2053,9 +2055,9 @@ int main(int argc, char **argv)
2053 2055 cpu_mips_register(env, def);
2054 2056  
2055 2057 for(i = 0; i < 32; i++) {
2056   - env->gpr[i] = regs->regs[i];
  2058 + env->gpr[i][env->current_tc] = regs->regs[i];
2057 2059 }
2058   - env->PC = regs->cp0_epc;
  2060 + env->PC[env->current_tc] = regs->cp0_epc;
2059 2061 }
2060 2062 #elif defined(TARGET_SH4)
2061 2063 {
... ...
linux-user/signal.c
... ... @@ -1686,10 +1686,10 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1686 1686 {
1687 1687 int err = 0;
1688 1688  
1689   - err |= __put_user(regs->PC, &sc->sc_pc);
  1689 + err |= __put_user(regs->PC[regs->current_tc], &sc->sc_pc);
1690 1690  
1691   -#define save_gp_reg(i) do { \
1692   - err |= __put_user(regs->gpr[i], &sc->sc_regs[i]); \
  1691 +#define save_gp_reg(i) do { \
  1692 + err |= __put_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]); \
1693 1693 } while(0)
1694 1694 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
1695 1695 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
... ... @@ -1702,8 +1702,8 @@ setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1702 1702 save_gp_reg(31);
1703 1703 #undef save_gp_reg
1704 1704  
1705   - err |= __put_user(regs->HI, &sc->sc_mdhi);
1706   - err |= __put_user(regs->LO, &sc->sc_mdlo);
  1705 + err |= __put_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi);
  1706 + err |= __put_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);
1707 1707  
1708 1708 /* Not used yet, but might be useful if we ever have DSP suppport */
1709 1709 #if 0
... ... @@ -1763,11 +1763,11 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
1763 1763  
1764 1764 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
1765 1765  
1766   - err |= __get_user(regs->HI, &sc->sc_mdhi);
1767   - err |= __get_user(regs->LO, &sc->sc_mdlo);
  1766 + err |= __get_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi);
  1767 + err |= __get_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);
1768 1768  
1769   -#define restore_gp_reg(i) do { \
1770   - err |= __get_user(regs->gpr[i], &sc->sc_regs[i]); \
  1769 +#define restore_gp_reg(i) do { \
  1770 + err |= __get_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]); \
1771 1771 } while(0)
1772 1772 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
1773 1773 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
... ... @@ -1833,7 +1833,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
1833 1833 unsigned long sp;
1834 1834  
1835 1835 /* Default to using normal stack */
1836   - sp = regs->gpr[29];
  1836 + sp = regs->gpr[29][regs->current_tc];
1837 1837  
1838 1838 /*
1839 1839 * FPU emulator may have it's own trampoline active just
... ... @@ -1881,15 +1881,15 @@ static void setup_frame(int sig, struct emulated_sigaction * ka,
1881 1881 * $25 and PC point to the signal handler, $29 points to the
1882 1882 * struct sigframe.
1883 1883 */
1884   - regs->gpr[ 4] = sig;
1885   - regs->gpr[ 5] = 0;
1886   - regs->gpr[ 6] = h2g(&frame->sf_sc);
1887   - regs->gpr[29] = h2g(frame);
1888   - regs->gpr[31] = h2g(frame->sf_code);
  1884 + regs->gpr[ 4][regs->current_tc] = sig;
  1885 + regs->gpr[ 5][regs->current_tc] = 0;
  1886 + regs->gpr[ 6][regs->current_tc] = h2g(&frame->sf_sc);
  1887 + regs->gpr[29][regs->current_tc] = h2g(frame);
  1888 + regs->gpr[31][regs->current_tc] = h2g(frame->sf_code);
1889 1889 /* The original kernel code sets CP0_EPC to the handler
1890 1890 * since it returns to userland using eret
1891 1891 * we cannot do this here, and we must set PC directly */
1892   - regs->PC = regs->gpr[25] = ka->sa._sa_handler;
  1892 + regs->PC[regs->current_tc] = regs->gpr[25][regs->current_tc] = ka->sa._sa_handler;
1893 1893 return;
1894 1894  
1895 1895 give_sigsegv:
... ... @@ -1907,7 +1907,7 @@ long do_sigreturn(CPUState *regs)
1907 1907 #if defined(DEBUG_SIGNAL)
1908 1908 fprintf(stderr, "do_sigreturn\n");
1909 1909 #endif
1910   - frame = (struct sigframe *) regs->gpr[29];
  1910 + frame = (struct sigframe *) regs->gpr[29][regs->current_tc];
1911 1911 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
1912 1912 goto badframe;
1913 1913  
... ... @@ -1934,7 +1934,7 @@ long do_sigreturn(CPUState *regs)
1934 1934 /* Unreached */
1935 1935 #endif
1936 1936  
1937   - regs->PC = regs->CP0_EPC;
  1937 + regs->PC[regs->current_tc] = regs->CP0_EPC;
1938 1938 /* I am not sure this is right, but it seems to work
1939 1939 * maybe a problem with nested signals ? */
1940 1940 regs->CP0_EPC = 0;
... ...
linux-user/syscall.c
... ... @@ -2189,8 +2189,8 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
2189 2189 /* ??? is this sufficient? */
2190 2190 #elif defined(TARGET_MIPS)
2191 2191 if (!newsp)
2192   - newsp = env->gpr[29];
2193   - new_env->gpr[29] = newsp;
  2192 + newsp = env->gpr[29][env->current_tc];
  2193 + new_env->gpr[29][env->current_tc] = newsp;
2194 2194 #elif defined(TARGET_PPC)
2195 2195 if (!newsp)
2196 2196 newsp = env->gpr[1];
... ... @@ -2777,7 +2777,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2777 2777 ret = get_errno(pipe(host_pipe));
2778 2778 if (!is_error(ret)) {
2779 2779 #if defined(TARGET_MIPS)
2780   - ((CPUMIPSState*)cpu_env)->gpr[3] = host_pipe[1];
  2780 + CPUMIPSState *env = (CPUMIPSState*)cpu_env;
  2781 + env->gpr[3][env->current_tc] = host_pipe[1];
2781 2782 ret = host_pipe[0];
2782 2783 #else
2783 2784 tput32(arg1, host_pipe[0]);
... ...
monitor.c
... ... @@ -309,6 +309,10 @@ static void do_info_cpus(void)
309 309 term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
310 310 if (env->halted)
311 311 term_printf(" (halted)");
  312 +#elif defined(TARGET_MIPS)
  313 + term_printf(" PC=0x" TARGET_FMT_lx, env->PC[env->current_tc]);
  314 + if (env->halted)
  315 + term_printf(" (halted)");
312 316 #endif
313 317 term_printf("\n");
314 318 }
... ...
target-mips/cpu.h
... ... @@ -17,21 +17,7 @@ typedef unsigned char uint_fast8_t;
17 17 typedef unsigned int uint_fast16_t;
18 18 #endif
19 19  
20   -typedef union fpr_t fpr_t;
21   -union fpr_t {
22   - float64 fd; /* ieee double precision */
23   - float32 fs[2];/* ieee single precision */
24   - uint64_t d; /* binary double fixed-point */
25   - uint32_t w[2]; /* binary single fixed-point */
26   -};
27   -/* define FP_ENDIAN_IDX to access the same location
28   - * in the fpr_t union regardless of the host endianess
29   - */
30   -#if defined(WORDS_BIGENDIAN)
31   -# define FP_ENDIAN_IDX 1
32   -#else
33   -# define FP_ENDIAN_IDX 0
34   -#endif
  20 +struct CPUMIPSState;
35 21  
36 22 typedef struct r4k_tlb_t r4k_tlb_t;
37 23 struct r4k_tlb_t {
... ... @@ -48,20 +34,40 @@ struct r4k_tlb_t {
48 34 target_ulong PFN[2];
49 35 };
50 36  
51   -typedef struct mips_def_t mips_def_t;
  37 +typedef struct CPUMIPSTLBContext CPUMIPSTLBContext;
  38 +struct CPUMIPSTLBContext {
  39 + uint32_t nb_tlb;
  40 + uint32_t tlb_in_use;
  41 + int (*map_address) (struct CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
  42 + void (*do_tlbwi) (void);
  43 + void (*do_tlbwr) (void);
  44 + void (*do_tlbp) (void);
  45 + void (*do_tlbr) (void);
  46 + union {
  47 + struct {
  48 + r4k_tlb_t tlb[MIPS_TLB_MAX];
  49 + } r4k;
  50 + } mmu;
  51 +};
52 52  
53   -typedef struct CPUMIPSState CPUMIPSState;
54   -struct CPUMIPSState {
55   - /* General integer registers */
56   - target_ulong gpr[32];
57   - /* Special registers */
58   - target_ulong PC;
59   -#if TARGET_LONG_BITS > HOST_LONG_BITS
60   - target_ulong t0;
61   - target_ulong t1;
62   - target_ulong t2;
  53 +typedef union fpr_t fpr_t;
  54 +union fpr_t {
  55 + float64 fd; /* ieee double precision */
  56 + float32 fs[2];/* ieee single precision */
  57 + uint64_t d; /* binary double fixed-point */
  58 + uint32_t w[2]; /* binary single fixed-point */
  59 +};
  60 +/* define FP_ENDIAN_IDX to access the same location
  61 + * in the fpr_t union regardless of the host endianess
  62 + */
  63 +#if defined(WORDS_BIGENDIAN)
  64 +# define FP_ENDIAN_IDX 1
  65 +#else
  66 +# define FP_ENDIAN_IDX 0
63 67 #endif
64   - target_ulong HI, LO;
  68 +
  69 +typedef struct CPUMIPSFPUContext CPUMIPSFPUContext;
  70 +struct CPUMIPSFPUContext {
65 71 /* Floating point registers */
66 72 fpr_t fpr[32];
67 73 #ifndef USE_HOST_FLOAT_REGS
... ... @@ -99,30 +105,161 @@ struct CPUMIPSState {
99 105 #define FP_DIV0 8
100 106 #define FP_INVALID 16
101 107 #define FP_UNIMPLEMENTED 32
  108 +};
  109 +
  110 +typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
  111 +struct CPUMIPSMVPContext {
  112 + int32_t CP0_MVPControl;
  113 +#define CP0MVPCo_CPA 3
  114 +#define CP0MVPCo_STLB 2
  115 +#define CP0MVPCo_VPC 1
  116 +#define CP0MVPCo_EVP 0
  117 + int32_t CP0_MVPConf0;
  118 +#define CP0MVPC0_M 31
  119 +#define CP0MVPC0_TLBS 29
  120 +#define CP0MVPC0_GS 28
  121 +#define CP0MVPC0_PCP 27
  122 +#define CP0MVPC0_PTLBE 16
  123 +#define CP0MVPC0_TCA 15
  124 +#define CP0MVPC0_PVPE 10
  125 +#define CP0MVPC0_PTC 0
  126 + int32_t CP0_MVPConf1;
  127 +#define CP0MVPC1_CIM 31
  128 +#define CP0MVPC1_CIF 30
  129 +#define CP0MVPC1_PCX 20
  130 +#define CP0MVPC1_PCP2 10
  131 +#define CP0MVPC1_PCP1 0
  132 +};
  133 +
  134 +typedef struct mips_def_t mips_def_t;
  135 +
  136 +#define MIPS_SHADOW_SET_MAX 16
  137 +#define MIPS_TC_MAX 5
  138 +#define MIPS_DSP_ACC 4
  139 +
  140 +typedef struct CPUMIPSState CPUMIPSState;
  141 +struct CPUMIPSState {
  142 + /* General integer registers */
  143 + target_ulong gpr[32][MIPS_SHADOW_SET_MAX];
  144 + /* Special registers */
  145 + target_ulong PC[MIPS_TC_MAX];
  146 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  147 + target_ulong t0;
  148 + target_ulong t1;
  149 + target_ulong t2;
  150 +#endif
  151 + target_ulong HI[MIPS_DSP_ACC][MIPS_TC_MAX];
  152 + target_ulong LO[MIPS_DSP_ACC][MIPS_TC_MAX];
  153 + target_ulong ACX[MIPS_DSP_ACC][MIPS_TC_MAX];
  154 + target_ulong DSPControl[MIPS_TC_MAX];
  155 +
  156 + CPUMIPSMVPContext *mvp;
  157 + CPUMIPSTLBContext *tlb;
  158 + CPUMIPSFPUContext *fpu;
  159 + uint32_t current_tc;
102 160  
103   - uint32_t nb_tlb;
104   - uint32_t tlb_in_use;
105 161 uint32_t SEGBITS;
106 162 target_ulong SEGMask;
107   - int (*map_address) (CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
108   - void (*do_tlbwi) (void);
109   - void (*do_tlbwr) (void);
110   - void (*do_tlbp) (void);
111   - void (*do_tlbr) (void);
112   - union {
113   - struct {
114   - r4k_tlb_t tlb[MIPS_TLB_MAX];
115   - } r4k;
116   - } mmu;
117 163  
118 164 int32_t CP0_Index;
  165 + /* CP0_MVP* are per MVP registers. */
119 166 int32_t CP0_Random;
  167 + int32_t CP0_VPEControl;
  168 +#define CP0VPECo_YSI 21
  169 +#define CP0VPECo_GSI 20
  170 +#define CP0VPECo_EXCPT 16
  171 +#define CP0VPECo_TE 15
  172 +#define CP0VPECo_TargTC 0
  173 + int32_t CP0_VPEConf0;
  174 +#define CP0VPEC0_M 31
  175 +#define CP0VPEC0_XTC 21
  176 +#define CP0VPEC0_TCS 19
  177 +#define CP0VPEC0_SCS 18
  178 +#define CP0VPEC0_DSC 17
  179 +#define CP0VPEC0_ICS 16
  180 +#define CP0VPEC0_MVP 1
  181 +#define CP0VPEC0_VPA 0
  182 + int32_t CP0_VPEConf1;
  183 +#define CP0VPEC1_NCX 20
  184 +#define CP0VPEC1_NCP2 10
  185 +#define CP0VPEC1_NCP1 0
  186 + target_ulong CP0_YQMask;
  187 + target_ulong CP0_VPESchedule;
  188 + target_ulong CP0_VPEScheFBack;
  189 + int32_t CP0_VPEOpt;
  190 +#define CP0VPEOpt_IWX7 15
  191 +#define CP0VPEOpt_IWX6 14
  192 +#define CP0VPEOpt_IWX5 13
  193 +#define CP0VPEOpt_IWX4 12
  194 +#define CP0VPEOpt_IWX3 11
  195 +#define CP0VPEOpt_IWX2 10
  196 +#define CP0VPEOpt_IWX1 9
  197 +#define CP0VPEOpt_IWX0 8
  198 +#define CP0VPEOpt_DWX7 7
  199 +#define CP0VPEOpt_DWX6 6
  200 +#define CP0VPEOpt_DWX5 5
  201 +#define CP0VPEOpt_DWX4 4
  202 +#define CP0VPEOpt_DWX3 3
  203 +#define CP0VPEOpt_DWX2 2
  204 +#define CP0VPEOpt_DWX1 1
  205 +#define CP0VPEOpt_DWX0 0
120 206 target_ulong CP0_EntryLo0;
  207 + int32_t CP0_TCStatus[MIPS_TC_MAX];
  208 +#define CP0TCSt_TCU3 31
  209 +#define CP0TCSt_TCU2 30
  210 +#define CP0TCSt_TCU1 29
  211 +#define CP0TCSt_TCU0 28
  212 +#define CP0TCSt_TMX 27
  213 +#define CP0TCSt_RNST 23
  214 +#define CP0TCSt_TDS 21
  215 +#define CP0TCSt_DT 20
  216 +#define CP0TCSt_DA 15
  217 +#define CP0TCSt_A 13
  218 +#define CP0TCSt_TKSU 11
  219 +#define CP0TCSt_IXMT 10
  220 +#define CP0TCSt_TASID 0
  221 + int32_t CP0_TCBind[MIPS_TC_MAX];
  222 +#define CP0TCBd_CurTC 21
  223 +#define CP0TCBd_TBE 17
  224 +#define CP0TCBd_CurVPE 0
  225 + target_ulong CP0_TCHalt[MIPS_TC_MAX];
  226 + target_ulong CP0_TCContext[MIPS_TC_MAX];
  227 + target_ulong CP0_TCSchedule[MIPS_TC_MAX];
  228 + target_ulong CP0_TCScheFBack[MIPS_TC_MAX];
121 229 target_ulong CP0_EntryLo1;
122 230 target_ulong CP0_Context;
123 231 int32_t CP0_PageMask;
124 232 int32_t CP0_PageGrain;
125 233 int32_t CP0_Wired;
  234 + int32_t CP0_SRSConf0_rw_bitmask;
  235 + int32_t CP0_SRSConf0;
  236 +#define CP0SRSC0_M 31
  237 +#define CP0SRSC0_SRS3 20
  238 +#define CP0SRSC0_SRS2 10
  239 +#define CP0SRSC0_SRS1 0
  240 + int32_t CP0_SRSConf1_rw_bitmask;
  241 + int32_t CP0_SRSConf1;
  242 +#define CP0SRSC1_M 31
  243 +#define CP0SRSC1_SRS6 20
  244 +#define CP0SRSC1_SRS5 10
  245 +#define CP0SRSC1_SRS4 0
  246 + int32_t CP0_SRSConf2_rw_bitmask;
  247 + int32_t CP0_SRSConf2;
  248 +#define CP0SRSC2_M 31
  249 +#define CP0SRSC2_SRS9 20
  250 +#define CP0SRSC2_SRS8 10
  251 +#define CP0SRSC2_SRS7 0
  252 + int32_t CP0_SRSConf3_rw_bitmask;
  253 + int32_t CP0_SRSConf3;
  254 +#define CP0SRSC3_M 31
  255 +#define CP0SRSC3_SRS12 20
  256 +#define CP0SRSC3_SRS11 10
  257 +#define CP0SRSC3_SRS10 0
  258 + int32_t CP0_SRSConf4_rw_bitmask;
  259 + int32_t CP0_SRSConf4;
  260 +#define CP0SRSC4_SRS15 20
  261 +#define CP0SRSC4_SRS14 10
  262 +#define CP0SRSC4_SRS13 0
126 263 int32_t CP0_HWREna;
127 264 target_ulong CP0_BadVAddr;
128 265 int32_t CP0_Count;
... ... @@ -152,8 +289,24 @@ struct CPUMIPSState {
152 289 #define CP0St_EXL 1
153 290 #define CP0St_IE 0
154 291 int32_t CP0_IntCtl;
  292 +#define CP0IntCtl_IPTI 29
  293 +#define CP0IntCtl_IPPC1 26
  294 +#define CP0IntCtl_VS 5
155 295 int32_t CP0_SRSCtl;
  296 +#define CP0SRSCtl_HSS 26
  297 +#define CP0SRSCtl_EICSS 18
  298 +#define CP0SRSCtl_ESS 12
  299 +#define CP0SRSCtl_PSS 6
  300 +#define CP0SRSCtl_CSS 0
156 301 int32_t CP0_SRSMap;
  302 +#define CP0SRSMap_SSV7 28
  303 +#define CP0SRSMap_SSV6 24
  304 +#define CP0SRSMap_SSV5 20
  305 +#define CP0SRSMap_SSV4 16
  306 +#define CP0SRSMap_SSV3 12
  307 +#define CP0SRSMap_SSV2 8
  308 +#define CP0SRSMap_SSV1 4
  309 +#define CP0SRSMap_SSV0 0
157 310 int32_t CP0_Cause;
158 311 #define CP0Ca_BD 31
159 312 #define CP0Ca_TI 30
... ... @@ -219,13 +372,14 @@ struct CPUMIPSState {
219 372 #define CP0C3_TL 0
220 373 int32_t CP0_Config6;
221 374 int32_t CP0_Config7;
  375 + /* XXX: Maybe make LLAddr per-TC? */
222 376 target_ulong CP0_LLAddr;
223 377 target_ulong CP0_WatchLo[8];
224 378 int32_t CP0_WatchHi[8];
225 379 target_ulong CP0_XContext;
226 380 int32_t CP0_Framemask;
227 381 int32_t CP0_Debug;
228   -#define CPDB_DBD 31
  382 +#define CP0DB_DBD 31
229 383 #define CP0DB_DM 30
230 384 #define CP0DB_LSNM 28
231 385 #define CP0DB_Doze 27
... ... @@ -243,6 +397,7 @@ struct CPUMIPSState {
243 397 #define CP0DB_DDBL 2
244 398 #define CP0DB_DBp 1
245 399 #define CP0DB_DSS 0
  400 + int32_t CP0_Debug_tcstatus[MIPS_TC_MAX];
246 401 target_ulong CP0_DEPC;
247 402 int32_t CP0_Performance0;
248 403 int32_t CP0_TagLo;
... ... @@ -284,7 +439,8 @@ struct CPUMIPSState {
284 439  
285 440 int SYNCI_Step; /* Address step size for SYNCI */
286 441 int CCRes; /* Cycle count resolution/divisor */
287   - int Status_rw_bitmask; /* Read/write bits in CP0_Status */
  442 + uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */
  443 + uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
288 444  
289 445 #ifdef CONFIG_USER_ONLY
290 446 target_ulong tls_value;
... ... @@ -376,6 +532,7 @@ enum {
376 532 EXCP_TLBS,
377 533 EXCP_DBE,
378 534 EXCP_DDBL,
  535 + EXCP_THREAD,
379 536 EXCP_MTCP0 = 0x104, /* mtmsr instruction: */
380 537 /* may change privilege level */
381 538 EXCP_BRANCH = 0x108, /* branch instruction */
... ...
target-mips/exec.h
... ... @@ -23,24 +23,24 @@ register target_ulong T2 asm(AREG3);
23 23 #if defined (USE_HOST_FLOAT_REGS)
24 24 #error "implement me."
25 25 #else
26   -#define FDT0 (env->ft0.fd)
27   -#define FDT1 (env->ft1.fd)
28   -#define FDT2 (env->ft2.fd)
29   -#define FST0 (env->ft0.fs[FP_ENDIAN_IDX])
30   -#define FST1 (env->ft1.fs[FP_ENDIAN_IDX])
31   -#define FST2 (env->ft2.fs[FP_ENDIAN_IDX])
32   -#define FSTH0 (env->ft0.fs[!FP_ENDIAN_IDX])
33   -#define FSTH1 (env->ft1.fs[!FP_ENDIAN_IDX])
34   -#define FSTH2 (env->ft2.fs[!FP_ENDIAN_IDX])
35   -#define DT0 (env->ft0.d)
36   -#define DT1 (env->ft1.d)
37   -#define DT2 (env->ft2.d)
38   -#define WT0 (env->ft0.w[FP_ENDIAN_IDX])
39   -#define WT1 (env->ft1.w[FP_ENDIAN_IDX])
40   -#define WT2 (env->ft2.w[FP_ENDIAN_IDX])
41   -#define WTH0 (env->ft0.w[!FP_ENDIAN_IDX])
42   -#define WTH1 (env->ft1.w[!FP_ENDIAN_IDX])
43   -#define WTH2 (env->ft2.w[!FP_ENDIAN_IDX])
  26 +#define FDT0 (env->fpu->ft0.fd)
  27 +#define FDT1 (env->fpu->ft1.fd)
  28 +#define FDT2 (env->fpu->ft2.fd)
  29 +#define FST0 (env->fpu->ft0.fs[FP_ENDIAN_IDX])
  30 +#define FST1 (env->fpu->ft1.fs[FP_ENDIAN_IDX])
  31 +#define FST2 (env->fpu->ft2.fs[FP_ENDIAN_IDX])
  32 +#define FSTH0 (env->fpu->ft0.fs[!FP_ENDIAN_IDX])
  33 +#define FSTH1 (env->fpu->ft1.fs[!FP_ENDIAN_IDX])
  34 +#define FSTH2 (env->fpu->ft2.fs[!FP_ENDIAN_IDX])
  35 +#define DT0 (env->fpu->ft0.d)
  36 +#define DT1 (env->fpu->ft1.d)
  37 +#define DT2 (env->fpu->ft2.d)
  38 +#define WT0 (env->fpu->ft0.w[FP_ENDIAN_IDX])
  39 +#define WT1 (env->fpu->ft1.w[FP_ENDIAN_IDX])
  40 +#define WT2 (env->fpu->ft2.w[FP_ENDIAN_IDX])
  41 +#define WTH0 (env->fpu->ft0.w[!FP_ENDIAN_IDX])
  42 +#define WTH1 (env->fpu->ft1.w[!FP_ENDIAN_IDX])
  43 +#define WTH2 (env->fpu->ft2.w[!FP_ENDIAN_IDX])
44 44 #endif
45 45  
46 46 #if defined (DEBUG_OP)
... ... @@ -157,7 +157,8 @@ void cpu_mips_update_irq (CPUState *env);
157 157 void cpu_mips_clock_init (CPUState *env);
158 158 void cpu_mips_tlb_flush (CPUState *env, int flush_global);
159 159  
160   -void do_ctc1 (void);
  160 +void do_cfc1 (int reg);
  161 +void do_ctc1 (int reg);
161 162  
162 163 #define FOP_PROTO(op) \
163 164 void do_float_ ## op ## _s(void); \
... ...
target-mips/fop_template.c
... ... @@ -24,14 +24,14 @@
24 24 #define OP_WLOAD_FREG(treg, tregname, FREG) \
25 25 void glue(glue(op_load_fpr_,tregname), FREG) (void) \
26 26 { \
27   - treg = env->fpr[FREG].fs[FP_ENDIAN_IDX]; \
  27 + treg = env->fpu->fpr[FREG].fs[FP_ENDIAN_IDX]; \
28 28 RETURN(); \
29 29 }
30 30  
31 31 #define OP_WSTORE_FREG(treg, tregname, FREG) \
32 32 void glue(glue(op_store_fpr_,tregname), FREG) (void) \
33 33 { \
34   - env->fpr[FREG].fs[FP_ENDIAN_IDX] = treg; \
  34 + env->fpu->fpr[FREG].fs[FP_ENDIAN_IDX] = treg; \
35 35 RETURN(); \
36 36 }
37 37  
... ... @@ -50,10 +50,10 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
50 50 void glue(glue(op_load_fpr_,tregname), FREG) (void) \
51 51 { \
52 52 if (env->hflags & MIPS_HFLAG_F64) \
53   - treg = env->fpr[FREG].fd; \
  53 + treg = env->fpu->fpr[FREG].fd; \
54 54 else \
55   - treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
56   - env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
  55 + treg = (uint64_t)(env->fpu->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
  56 + env->fpu->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
57 57 RETURN(); \
58 58 }
59 59  
... ... @@ -61,10 +61,10 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
61 61 void glue(glue(op_store_fpr_,tregname), FREG) (void) \
62 62 { \
63 63 if (env->hflags & MIPS_HFLAG_F64) \
64   - env->fpr[FREG].fd = treg; \
  64 + env->fpu->fpr[FREG].fd = treg; \
65 65 else { \
66   - env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
67   - env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg; \
  66 + env->fpu->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
  67 + env->fpu->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg; \
68 68 } \
69 69 RETURN(); \
70 70 }
... ... @@ -81,14 +81,14 @@ OP_DSTORE_FREG(DT2, DT2_fpr, FREG)
81 81 #define OP_PSLOAD_FREG(treg, tregname, FREG) \
82 82 void glue(glue(op_load_fpr_,tregname), FREG) (void) \
83 83 { \
84   - treg = env->fpr[FREG].fs[!FP_ENDIAN_IDX]; \
  84 + treg = env->fpu->fpr[FREG].fs[!FP_ENDIAN_IDX]; \
85 85 RETURN(); \
86 86 }
87 87  
88 88 #define OP_PSSTORE_FREG(treg, tregname, FREG) \
89 89 void glue(glue(op_store_fpr_,tregname), FREG) (void) \
90 90 { \
91   - env->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg; \
  91 + env->fpu->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg; \
92 92 RETURN(); \
93 93 }
94 94  
... ...
target-mips/helper.c
... ... @@ -70,8 +70,8 @@ int r4k_map_address (CPUState *env, target_ulong *physical, int *prot,
70 70 uint8_t ASID = env->CP0_EntryHi & 0xFF;
71 71 int i;
72 72  
73   - for (i = 0; i < env->tlb_in_use; i++) {
74   - r4k_tlb_t *tlb = &env->mmu.r4k.tlb[i];
  73 + for (i = 0; i < env->tlb->tlb_in_use; i++) {
  74 + r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i];
75 75 /* 1k pages are not supported. */
76 76 target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
77 77 target_ulong tag = address & ~mask;
... ... @@ -134,7 +134,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
134 134 *physical = address & 0xFFFFFFFF;
135 135 *prot = PAGE_READ | PAGE_WRITE;
136 136 } else {
137   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  137 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
138 138 }
139 139 #ifdef TARGET_MIPS64
140 140 /*
... ... @@ -144,14 +144,14 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
144 144 } else if (address < 0x3FFFFFFFFFFFFFFFULL) {
145 145 /* xuseg */
146 146 if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
147   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  147 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
148 148 } else {
149 149 ret = TLBRET_BADADDR;
150 150 }
151 151 } else if (address < 0x7FFFFFFFFFFFFFFFULL) {
152 152 /* xsseg */
153 153 if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
154   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  154 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
155 155 } else {
156 156 ret = TLBRET_BADADDR;
157 157 }
... ... @@ -169,7 +169,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
169 169 /* xkseg */
170 170 /* XXX: check supervisor mode */
171 171 if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
172   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  172 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
173 173 } else {
174 174 ret = TLBRET_BADADDR;
175 175 }
... ... @@ -186,12 +186,12 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
186 186 *prot = PAGE_READ | PAGE_WRITE;
187 187 } else if (address < (int32_t)0xE0000000UL) {
188 188 /* kseg2 */
189   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  189 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
190 190 } else {
191 191 /* kseg3 */
192 192 /* XXX: check supervisor mode */
193 193 /* XXX: debug segment is not emulated */
194   - ret = env->map_address(env, physical, prot, address, rw, access_type);
  194 + ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
195 195 }
196 196 #if 0
197 197 if (logfile) {
... ... @@ -238,7 +238,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
238 238 cpu_dump_state(env, logfile, fprintf, 0);
239 239 #endif
240 240 fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d is_user %d smmu %d\n",
241   - __func__, env->PC, address, rw, is_user, is_softmmu);
  241 + __func__, env->PC[env->current_tc], address, rw, is_user, is_softmmu);
242 242 }
243 243  
244 244 rw &= 1;
... ... @@ -328,7 +328,7 @@ void do_interrupt (CPUState *env)
328 328  
329 329 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
330 330 fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n",
331   - __func__, env->PC, env->CP0_EPC, cause, env->exception_index);
  331 + __func__, env->PC[env->current_tc], env->CP0_EPC, cause, env->exception_index);
332 332 }
333 333 if (env->exception_index == EXCP_EXT_INTERRUPT &&
334 334 (env->hflags & MIPS_HFLAG_DM))
... ... @@ -342,7 +342,7 @@ void do_interrupt (CPUState *env)
342 342 * (but we assume the pc has always been updated during
343 343 * code translation).
344 344 */
345   - env->CP0_DEPC = env->PC;
  345 + env->CP0_DEPC = env->PC[env->current_tc];
346 346 goto enter_debug_mode;
347 347 case EXCP_DINT:
348 348 env->CP0_Debug |= 1 << CP0DB_DINT;
... ... @@ -362,10 +362,10 @@ void do_interrupt (CPUState *env)
362 362 if (env->hflags & MIPS_HFLAG_BMASK) {
363 363 /* If the exception was raised from a delay slot,
364 364 come back to the jump. */
365   - env->CP0_DEPC = env->PC - 4;
  365 + env->CP0_DEPC = env->PC[env->current_tc] - 4;
366 366 env->hflags &= ~MIPS_HFLAG_BMASK;
367 367 } else {
368   - env->CP0_DEPC = env->PC;
  368 + env->CP0_DEPC = env->PC[env->current_tc];
369 369 }
370 370 enter_debug_mode:
371 371 env->hflags |= MIPS_HFLAG_DM;
... ... @@ -375,7 +375,7 @@ void do_interrupt (CPUState *env)
375 375 /* EJTAG probe trap enable is not implemented... */
376 376 if (!(env->CP0_Status & (1 << CP0St_EXL)))
377 377 env->CP0_Cause &= ~(1 << CP0Ca_BD);
378   - env->PC = (int32_t)0xBFC00480;
  378 + env->PC[env->current_tc] = (int32_t)0xBFC00480;
379 379 break;
380 380 case EXCP_RESET:
381 381 cpu_reset(env);
... ... @@ -390,10 +390,10 @@ void do_interrupt (CPUState *env)
390 390 if (env->hflags & MIPS_HFLAG_BMASK) {
391 391 /* If the exception was raised from a delay slot,
392 392 come back to the jump. */
393   - env->CP0_ErrorEPC = env->PC - 4;
  393 + env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
394 394 env->hflags &= ~MIPS_HFLAG_BMASK;
395 395 } else {
396   - env->CP0_ErrorEPC = env->PC;
  396 + env->CP0_ErrorEPC = env->PC[env->current_tc];
397 397 }
398 398 env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
399 399 if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
... ... @@ -401,7 +401,7 @@ void do_interrupt (CPUState *env)
401 401 env->hflags &= ~MIPS_HFLAG_UM;
402 402 if (!(env->CP0_Status & (1 << CP0St_EXL)))
403 403 env->CP0_Cause &= ~(1 << CP0Ca_BD);
404   - env->PC = (int32_t)0xBFC00000;
  404 + env->PC[env->current_tc] = (int32_t)0xBFC00000;
405 405 break;
406 406 case EXCP_MCHECK:
407 407 cause = 24;
... ... @@ -471,6 +471,9 @@ void do_interrupt (CPUState *env)
471 471 goto set_EPC;
472 472 case EXCP_TLBS:
473 473 cause = 3;
  474 + goto set_EPC;
  475 + case EXCP_THREAD:
  476 + cause = 25;
474 477 if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
475 478 #ifdef TARGET_MIPS64
476 479 int R = env->CP0_BadVAddr >> 62;
... ... @@ -489,10 +492,10 @@ void do_interrupt (CPUState *env)
489 492 if (env->hflags & MIPS_HFLAG_BMASK) {
490 493 /* If the exception was raised from a delay slot,
491 494 come back to the jump. */
492   - env->CP0_EPC = env->PC - 4;
  495 + env->CP0_EPC = env->PC[env->current_tc] - 4;
493 496 env->CP0_Cause |= (1 << CP0Ca_BD);
494 497 } else {
495   - env->CP0_EPC = env->PC;
  498 + env->CP0_EPC = env->PC[env->current_tc];
496 499 env->CP0_Cause &= ~(1 << CP0Ca_BD);
497 500 }
498 501 env->CP0_Status |= (1 << CP0St_EXL);
... ... @@ -502,11 +505,11 @@ void do_interrupt (CPUState *env)
502 505 }
503 506 env->hflags &= ~MIPS_HFLAG_BMASK;
504 507 if (env->CP0_Status & (1 << CP0St_BEV)) {
505   - env->PC = (int32_t)0xBFC00200;
  508 + env->PC[env->current_tc] = (int32_t)0xBFC00200;
506 509 } else {
507   - env->PC = (int32_t)(env->CP0_EBase & ~0x3ff);
  510 + env->PC[env->current_tc] = (int32_t)(env->CP0_EBase & ~0x3ff);
508 511 }
509   - env->PC += offset;
  512 + env->PC[env->current_tc] += offset;
510 513 env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
511 514 break;
512 515 default:
... ... @@ -520,7 +523,7 @@ void do_interrupt (CPUState *env)
520 523 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
521 524 fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n"
522 525 " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n",
523   - __func__, env->PC, env->CP0_EPC, cause, env->exception_index,
  526 + __func__, env->PC[env->current_tc], env->CP0_EPC, cause, env->exception_index,
524 527 env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
525 528 env->CP0_DEPC);
526 529 }
... ... @@ -536,19 +539,19 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra)
536 539 uint8_t ASID = env->CP0_EntryHi & 0xFF;
537 540 target_ulong mask;
538 541  
539   - tlb = &env->mmu.r4k.tlb[idx];
  542 + tlb = &env->tlb->mmu.r4k.tlb[idx];
540 543 /* The qemu TLB is flushed when the ASID changes, so no need to
541 544 flush these entries again. */
542 545 if (tlb->G == 0 && tlb->ASID != ASID) {
543 546 return;
544 547 }
545 548  
546   - if (use_extra && env->tlb_in_use < MIPS_TLB_MAX) {
  549 + if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) {
547 550 /* For tlbwr, we can shadow the discarded entry into
548 551 a new (fake) TLB entry, as long as the guest can not
549 552 tell that it's there. */
550   - env->mmu.r4k.tlb[env->tlb_in_use] = *tlb;
551   - env->tlb_in_use++;
  553 + env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb;
  554 + env->tlb->tlb_in_use++;
552 555 return;
553 556 }
554 557  
... ...
target-mips/op.c
... ... @@ -254,25 +254,25 @@ void op_dup_T0 (void)
254 254  
255 255 void op_load_HI (void)
256 256 {
257   - T0 = env->HI;
  257 + T0 = env->HI[PARAM1][env->current_tc];
258 258 RETURN();
259 259 }
260 260  
261 261 void op_store_HI (void)
262 262 {
263   - env->HI = T0;
  263 + env->HI[PARAM1][env->current_tc] = T0;
264 264 RETURN();
265 265 }
266 266  
267 267 void op_load_LO (void)
268 268 {
269   - T0 = env->LO;
  269 + T0 = env->LO[PARAM1][env->current_tc];
270 270 RETURN();
271 271 }
272 272  
273 273 void op_store_LO (void)
274 274 {
275   - env->LO = T0;
  275 + env->LO[PARAM1][env->current_tc] = T0;
276 276 RETURN();
277 277 }
278 278  
... ... @@ -363,8 +363,8 @@ void op_div (void)
363 363 void op_div (void)
364 364 {
365 365 if (T1 != 0) {
366   - env->LO = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
367   - env->HI = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
  366 + env->LO[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
  367 + env->HI[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
368 368 }
369 369 RETURN();
370 370 }
... ... @@ -373,8 +373,8 @@ void op_div (void)
373 373 void op_divu (void)
374 374 {
375 375 if (T1 != 0) {
376   - env->LO = (int32_t)((uint32_t)T0 / (uint32_t)T1);
377   - env->HI = (int32_t)((uint32_t)T0 % (uint32_t)T1);
  376 + env->LO[0][env->current_tc] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
  377 + env->HI[0][env->current_tc] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
378 378 }
379 379 RETURN();
380 380 }
... ... @@ -442,8 +442,8 @@ void op_ddivu (void)
442 442 void op_ddivu (void)
443 443 {
444 444 if (T1 != 0) {
445   - env->LO = T0 / T1;
446   - env->HI = T0 % T1;
  445 + env->LO[0][env->current_tc] = T0 / T1;
  446 + env->HI[0][env->current_tc] = T0 % T1;
447 447 }
448 448 RETURN();
449 449 }
... ... @@ -814,13 +814,14 @@ void op_msubu (void)
814 814  
815 815 static inline uint64_t get_HILO (void)
816 816 {
817   - return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO);
  817 + return ((uint64_t)env->HI[0][env->current_tc] << 32) |
  818 + ((uint64_t)(uint32_t)env->LO[0][env->current_tc]);
818 819 }
819 820  
820 821 static inline void set_HILO (uint64_t HILO)
821 822 {
822   - env->LO = (int32_t)(HILO & 0xFFFFFFFF);
823   - env->HI = (int32_t)(HILO >> 32);
  823 + env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
  824 + env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
824 825 }
825 826  
826 827 void op_mult (void)
... ... @@ -875,13 +876,13 @@ void op_msubu (void)
875 876 #ifdef TARGET_MIPS64
876 877 void op_dmult (void)
877 878 {
878   - CALL_FROM_TB4(muls64, &(env->HI), &(env->LO), T0, T1);
  879 + CALL_FROM_TB4(muls64, &(env->HI[0][env->current_tc]), &(env->LO[0][env->current_tc]), T0, T1);
879 880 RETURN();
880 881 }
881 882  
882 883 void op_dmultu (void)
883 884 {
884   - CALL_FROM_TB4(mulu64, &(env->HI), &(env->LO), T0, T1);
  885 + CALL_FROM_TB4(mulu64, &(env->HI[0][env->current_tc]), &(env->LO[0][env->current_tc]), T0, T1);
885 886 RETURN();
886 887 }
887 888 #endif
... ... @@ -890,27 +891,27 @@ void op_dmultu (void)
890 891 void op_movn (void)
891 892 {
892 893 if (T1 != 0)
893   - env->gpr[PARAM1] = T0;
  894 + env->gpr[PARAM1][env->current_tc] = T0;
894 895 RETURN();
895 896 }
896 897  
897 898 void op_movz (void)
898 899 {
899 900 if (T1 == 0)
900   - env->gpr[PARAM1] = T0;
  901 + env->gpr[PARAM1][env->current_tc] = T0;
901 902 RETURN();
902 903 }
903 904  
904 905 void op_movf (void)
905 906 {
906   - if (!(env->fcr31 & PARAM1))
  907 + if (!(env->fpu->fcr31 & PARAM1))
907 908 T0 = T1;
908 909 RETURN();
909 910 }
910 911  
911 912 void op_movt (void)
912 913 {
913   - if (env->fcr31 & PARAM1)
  914 + if (env->fpu->fcr31 & PARAM1)
914 915 T0 = T1;
915 916 RETURN();
916 917 }
... ... @@ -966,7 +967,7 @@ void op_restore_breg_target (void)
966 967  
967 968 void op_breg (void)
968 969 {
969   - env->PC = T2;
  970 + env->PC[env->current_tc] = T2;
970 971 RETURN();
971 972 }
972 973  
... ... @@ -1017,18 +1018,176 @@ void op_mfc0_index (void)
1017 1018 RETURN();
1018 1019 }
1019 1020  
  1021 +void op_mfc0_mvpcontrol (void)
  1022 +{
  1023 + T0 = env->mvp->CP0_MVPControl;
  1024 + RETURN();
  1025 +}
  1026 +
  1027 +void op_mfc0_mvpconf0 (void)
  1028 +{
  1029 + T0 = env->mvp->CP0_MVPConf0;
  1030 + RETURN();
  1031 +}
  1032 +
  1033 +void op_mfc0_mvpconf1 (void)
  1034 +{
  1035 + T0 = env->mvp->CP0_MVPConf1;
  1036 + RETURN();
  1037 +}
  1038 +
1020 1039 void op_mfc0_random (void)
1021 1040 {
1022 1041 CALL_FROM_TB0(do_mfc0_random);
1023 1042 RETURN();
1024 1043 }
1025 1044  
  1045 +void op_mfc0_vpecontrol (void)
  1046 +{
  1047 + T0 = env->CP0_VPEControl;
  1048 + RETURN();
  1049 +}
  1050 +
  1051 +void op_mfc0_vpeconf0 (void)
  1052 +{
  1053 + T0 = env->CP0_VPEConf0;
  1054 + RETURN();
  1055 +}
  1056 +
  1057 +void op_mfc0_vpeconf1 (void)
  1058 +{
  1059 + T0 = env->CP0_VPEConf1;
  1060 + RETURN();
  1061 +}
  1062 +
  1063 +void op_mfc0_yqmask (void)
  1064 +{
  1065 + T0 = env->CP0_YQMask;
  1066 + RETURN();
  1067 +}
  1068 +
  1069 +void op_mfc0_vpeschedule (void)
  1070 +{
  1071 + T0 = env->CP0_VPESchedule;
  1072 + RETURN();
  1073 +}
  1074 +
  1075 +void op_mfc0_vpeschefback (void)
  1076 +{
  1077 + T0 = env->CP0_VPEScheFBack;
  1078 + RETURN();
  1079 +}
  1080 +
  1081 +void op_mfc0_vpeopt (void)
  1082 +{
  1083 + T0 = env->CP0_VPEOpt;
  1084 + RETURN();
  1085 +}
  1086 +
1026 1087 void op_mfc0_entrylo0 (void)
1027 1088 {
1028 1089 T0 = (int32_t)env->CP0_EntryLo0;
1029 1090 RETURN();
1030 1091 }
1031 1092  
  1093 +void op_mfc0_tcstatus (void)
  1094 +{
  1095 + T0 = env->CP0_TCStatus[env->current_tc];
  1096 + RETURN();
  1097 +}
  1098 +
  1099 +void op_mftc0_tcstatus(void)
  1100 +{
  1101 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1102 +
  1103 + T0 = env->CP0_TCStatus[other_tc];
  1104 + RETURN();
  1105 +}
  1106 +
  1107 +void op_mfc0_tcbind (void)
  1108 +{
  1109 + T0 = env->CP0_TCBind[env->current_tc];
  1110 + RETURN();
  1111 +}
  1112 +
  1113 +void op_mftc0_tcbind(void)
  1114 +{
  1115 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1116 +
  1117 + T0 = env->CP0_TCBind[other_tc];
  1118 + RETURN();
  1119 +}
  1120 +
  1121 +void op_mfc0_tcrestart (void)
  1122 +{
  1123 + T0 = env->PC[env->current_tc];
  1124 + RETURN();
  1125 +}
  1126 +
  1127 +void op_mftc0_tcrestart(void)
  1128 +{
  1129 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1130 +
  1131 + T0 = env->PC[other_tc];
  1132 + RETURN();
  1133 +}
  1134 +
  1135 +void op_mfc0_tchalt (void)
  1136 +{
  1137 + T0 = env->CP0_TCHalt[env->current_tc];
  1138 + RETURN();
  1139 +}
  1140 +
  1141 +void op_mftc0_tchalt(void)
  1142 +{
  1143 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1144 +
  1145 + T0 = env->CP0_TCHalt[other_tc];
  1146 + RETURN();
  1147 +}
  1148 +
  1149 +void op_mfc0_tccontext (void)
  1150 +{
  1151 + T0 = env->CP0_TCContext[env->current_tc];
  1152 + RETURN();
  1153 +}
  1154 +
  1155 +void op_mftc0_tccontext(void)
  1156 +{
  1157 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1158 +
  1159 + T0 = env->CP0_TCContext[other_tc];
  1160 + RETURN();
  1161 +}
  1162 +
  1163 +void op_mfc0_tcschedule (void)
  1164 +{
  1165 + T0 = env->CP0_TCSchedule[env->current_tc];
  1166 + RETURN();
  1167 +}
  1168 +
  1169 +void op_mftc0_tcschedule(void)
  1170 +{
  1171 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1172 +
  1173 + T0 = env->CP0_TCSchedule[other_tc];
  1174 + RETURN();
  1175 +}
  1176 +
  1177 +void op_mfc0_tcschefback (void)
  1178 +{
  1179 + T0 = env->CP0_TCScheFBack[env->current_tc];
  1180 + RETURN();
  1181 +}
  1182 +
  1183 +void op_mftc0_tcschefback(void)
  1184 +{
  1185 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1186 +
  1187 + T0 = env->CP0_TCScheFBack[other_tc];
  1188 + RETURN();
  1189 +}
  1190 +
1032 1191 void op_mfc0_entrylo1 (void)
1033 1192 {
1034 1193 T0 = (int32_t)env->CP0_EntryLo1;
... ... @@ -1059,6 +1218,36 @@ void op_mfc0_wired (void)
1059 1218 RETURN();
1060 1219 }
1061 1220  
  1221 +void op_mfc0_srsconf0 (void)
  1222 +{
  1223 + T0 = env->CP0_SRSConf0;
  1224 + RETURN();
  1225 +}
  1226 +
  1227 +void op_mfc0_srsconf1 (void)
  1228 +{
  1229 + T0 = env->CP0_SRSConf1;
  1230 + RETURN();
  1231 +}
  1232 +
  1233 +void op_mfc0_srsconf2 (void)
  1234 +{
  1235 + T0 = env->CP0_SRSConf2;
  1236 + RETURN();
  1237 +}
  1238 +
  1239 +void op_mfc0_srsconf3 (void)
  1240 +{
  1241 + T0 = env->CP0_SRSConf3;
  1242 + RETURN();
  1243 +}
  1244 +
  1245 +void op_mfc0_srsconf4 (void)
  1246 +{
  1247 + T0 = env->CP0_SRSConf4;
  1248 + RETURN();
  1249 +}
  1250 +
1062 1251 void op_mfc0_hwrena (void)
1063 1252 {
1064 1253 T0 = env->CP0_HWREna;
... ... @@ -1083,6 +1272,14 @@ void op_mfc0_entryhi (void)
1083 1272 RETURN();
1084 1273 }
1085 1274  
  1275 +void op_mftc0_entryhi(void)
  1276 +{
  1277 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1278 +
  1279 + T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
  1280 + RETURN();
  1281 +}
  1282 +
1086 1283 void op_mfc0_compare (void)
1087 1284 {
1088 1285 T0 = env->CP0_Compare;
... ... @@ -1095,6 +1292,18 @@ void op_mfc0_status (void)
1095 1292 RETURN();
1096 1293 }
1097 1294  
  1295 +void op_mftc0_status(void)
  1296 +{
  1297 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1298 + uint32_t tcstatus = env->CP0_TCStatus[other_tc];
  1299 +
  1300 + T0 = env->CP0_Status & ~0xf1000018;
  1301 + T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
  1302 + T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
  1303 + T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_R0);
  1304 + RETURN();
  1305 +}
  1306 +
1098 1307 void op_mfc0_intctl (void)
1099 1308 {
1100 1309 T0 = env->CP0_IntCtl;
... ... @@ -1211,6 +1420,17 @@ void op_mfc0_debug (void)
1211 1420 RETURN();
1212 1421 }
1213 1422  
  1423 +void op_mftc0_debug(void)
  1424 +{
  1425 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1426 +
  1427 + /* XXX: Might be wrong, check with EJTAG spec. */
  1428 + T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
  1429 + (env->CP0_Debug_tcstatus[other_tc] &
  1430 + ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
  1431 + RETURN();
  1432 +}
  1433 +
1214 1434 void op_mfc0_depc (void)
1215 1435 {
1216 1436 T0 = (int32_t)env->CP0_DEPC;
... ... @@ -1261,7 +1481,105 @@ void op_mfc0_desave (void)
1261 1481  
1262 1482 void op_mtc0_index (void)
1263 1483 {
1264   - env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 % env->nb_tlb);
  1484 + env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 % env->tlb->nb_tlb);
  1485 + RETURN();
  1486 +}
  1487 +
  1488 +void op_mtc0_mvpcontrol (void)
  1489 +{
  1490 + uint32_t mask = 0;
  1491 + uint32_t newval;
  1492 +
  1493 + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
  1494 + mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
  1495 + (1 << CP0MVPCo_EVP);
  1496 + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
  1497 + mask |= (1 << CP0MVPCo_STLB);
  1498 + newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
  1499 +
  1500 + // TODO: Enable/disable shared TLB, enable/disable VPEs.
  1501 +
  1502 + env->mvp->CP0_MVPControl = newval;
  1503 + RETURN();
  1504 +}
  1505 +
  1506 +void op_mtc0_vpecontrol (void)
  1507 +{
  1508 + uint32_t mask;
  1509 + uint32_t newval;
  1510 +
  1511 + mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
  1512 + (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
  1513 + newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
  1514 +
  1515 + /* Yield scheduler intercept not implemented. */
  1516 + /* Gating storage scheduler intercept not implemented. */
  1517 +
  1518 + // TODO: Enable/disable TCs.
  1519 +
  1520 + env->CP0_VPEControl = newval;
  1521 + RETURN();
  1522 +}
  1523 +
  1524 +void op_mtc0_vpeconf0 (void)
  1525 +{
  1526 + uint32_t mask = 0;
  1527 + uint32_t newval;
  1528 +
  1529 + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
  1530 + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
  1531 + mask |= (0xff << CP0VPEC0_XTC);
  1532 + mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
  1533 + }
  1534 + newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
  1535 +
  1536 + // TODO: TC exclusive handling due to ERL/EXL.
  1537 +
  1538 + env->CP0_VPEConf0 = newval;
  1539 + RETURN();
  1540 +}
  1541 +
  1542 +void op_mtc0_vpeconf1 (void)
  1543 +{
  1544 + uint32_t mask = 0;
  1545 + uint32_t newval;
  1546 +
  1547 + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
  1548 + mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
  1549 + (0xff << CP0VPEC1_NCP1);
  1550 + newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
  1551 +
  1552 + /* UDI not implemented. */
  1553 + /* CP2 not implemented. */
  1554 +
  1555 + // TODO: Handle FPU (CP1) binding.
  1556 +
  1557 + env->CP0_VPEConf1 = newval;
  1558 + RETURN();
  1559 +}
  1560 +
  1561 +void op_mtc0_yqmask (void)
  1562 +{
  1563 + /* Yield qualifier inputs not implemented. */
  1564 + env->CP0_YQMask = 0x00000000;
  1565 + RETURN();
  1566 +}
  1567 +
  1568 +void op_mtc0_vpeschedule (void)
  1569 +{
  1570 + env->CP0_VPESchedule = T0;
  1571 + RETURN();
  1572 +}
  1573 +
  1574 +void op_mtc0_vpeschefback (void)
  1575 +{
  1576 + env->CP0_VPEScheFBack = T0;
  1577 + RETURN();
  1578 +}
  1579 +
  1580 +void op_mtc0_vpeopt (void)
  1581 +{
  1582 + env->CP0_VPEOpt = T0 & 0x0000ffff;
1265 1583 RETURN();
1266 1584 }
1267 1585  
... ... @@ -1273,6 +1591,135 @@ void op_mtc0_entrylo0 (void)
1273 1591 RETURN();
1274 1592 }
1275 1593  
  1594 +void op_mtc0_tcstatus (void)
  1595 +{
  1596 + uint32_t mask = env->CP0_TCStatus_rw_bitmask;
  1597 + uint32_t newval;
  1598 +
  1599 + newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
  1600 +
  1601 + // TODO: Sync with CP0_Status.
  1602 +
  1603 + env->CP0_TCStatus[env->current_tc] = newval;
  1604 + RETURN();
  1605 +}
  1606 +
  1607 +void op_mttc0_tcstatus (void)
  1608 +{
  1609 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1610 +
  1611 + // TODO: Sync with CP0_Status.
  1612 +
  1613 + env->CP0_TCStatus[other_tc] = T0;
  1614 + RETURN();
  1615 +}
  1616 +
  1617 +void op_mtc0_tcbind (void)
  1618 +{
  1619 + uint32_t mask = (1 << CP0TCBd_TBE);
  1620 + uint32_t newval;
  1621 +
  1622 + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
  1623 + mask |= (1 << CP0TCBd_CurVPE);
  1624 + newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
  1625 + env->CP0_TCBind[env->current_tc] = newval;
  1626 + RETURN();
  1627 +}
  1628 +
  1629 +void op_mttc0_tcbind (void)
  1630 +{
  1631 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1632 + uint32_t mask = (1 << CP0TCBd_TBE);
  1633 + uint32_t newval;
  1634 +
  1635 + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
  1636 + mask |= (1 << CP0TCBd_CurVPE);
  1637 + newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
  1638 + env->CP0_TCBind[other_tc] = newval;
  1639 + RETURN();
  1640 +}
  1641 +
  1642 +void op_mtc0_tcrestart (void)
  1643 +{
  1644 + env->PC[env->current_tc] = T0;
  1645 + env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
  1646 + env->CP0_LLAddr = 0ULL;
  1647 + /* MIPS16 not implemented. */
  1648 + RETURN();
  1649 +}
  1650 +
  1651 +void op_mttc0_tcrestart (void)
  1652 +{
  1653 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1654 +
  1655 + env->PC[other_tc] = T0;
  1656 + env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
  1657 + env->CP0_LLAddr = 0ULL;
  1658 + /* MIPS16 not implemented. */
  1659 + RETURN();
  1660 +}
  1661 +
  1662 +void op_mtc0_tchalt (void)
  1663 +{
  1664 + env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
  1665 +
  1666 + // TODO: Halt TC / Restart (if allocated+active) TC.
  1667 +
  1668 + RETURN();
  1669 +}
  1670 +
  1671 +void op_mttc0_tchalt (void)
  1672 +{
  1673 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1674 +
  1675 + // TODO: Halt TC / Restart (if allocated+active) TC.
  1676 +
  1677 + env->CP0_TCHalt[other_tc] = T0;
  1678 + RETURN();
  1679 +}
  1680 +
  1681 +void op_mtc0_tccontext (void)
  1682 +{
  1683 + env->CP0_TCContext[env->current_tc] = T0;
  1684 + RETURN();
  1685 +}
  1686 +
  1687 +void op_mttc0_tccontext (void)
  1688 +{
  1689 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1690 +
  1691 + env->CP0_TCContext[other_tc] = T0;
  1692 + RETURN();
  1693 +}
  1694 +
  1695 +void op_mtc0_tcschedule (void)
  1696 +{
  1697 + env->CP0_TCSchedule[env->current_tc] = T0;
  1698 + RETURN();
  1699 +}
  1700 +
  1701 +void op_mttc0_tcschedule (void)
  1702 +{
  1703 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1704 +
  1705 + env->CP0_TCSchedule[other_tc] = T0;
  1706 + RETURN();
  1707 +}
  1708 +
  1709 +void op_mtc0_tcschefback (void)
  1710 +{
  1711 + env->CP0_TCScheFBack[env->current_tc] = T0;
  1712 + RETURN();
  1713 +}
  1714 +
  1715 +void op_mttc0_tcschefback (void)
  1716 +{
  1717 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1718 +
  1719 + env->CP0_TCScheFBack[other_tc] = T0;
  1720 + RETURN();
  1721 +}
  1722 +
1276 1723 void op_mtc0_entrylo1 (void)
1277 1724 {
1278 1725 /* Large physaddr not implemented */
... ... @@ -1305,7 +1752,37 @@ void op_mtc0_pagegrain (void)
1305 1752  
1306 1753 void op_mtc0_wired (void)
1307 1754 {
1308   - env->CP0_Wired = T0 % env->nb_tlb;
  1755 + env->CP0_Wired = T0 % env->tlb->nb_tlb;
  1756 + RETURN();
  1757 +}
  1758 +
  1759 +void op_mtc0_srsconf0 (void)
  1760 +{
  1761 + env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
  1762 + RETURN();
  1763 +}
  1764 +
  1765 +void op_mtc0_srsconf1 (void)
  1766 +{
  1767 + env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
  1768 + RETURN();
  1769 +}
  1770 +
  1771 +void op_mtc0_srsconf2 (void)
  1772 +{
  1773 + env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
  1774 + RETURN();
  1775 +}
  1776 +
  1777 +void op_mtc0_srsconf3 (void)
  1778 +{
  1779 + env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
  1780 + RETURN();
  1781 +}
  1782 +
  1783 +void op_mtc0_srsconf4 (void)
  1784 +{
  1785 + env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1309 1786 RETURN();
1310 1787 }
1311 1788  
... ... @@ -1332,12 +1809,25 @@ void op_mtc0_entryhi (void)
1332 1809 #endif
1333 1810 old = env->CP0_EntryHi;
1334 1811 env->CP0_EntryHi = val;
  1812 + if (env->CP0_Config3 & (1 << CP0C3_MT)) {
  1813 + uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
  1814 + env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
  1815 + }
1335 1816 /* If the ASID changes, flush qemu's TLB. */
1336 1817 if ((old & 0xFF) != (val & 0xFF))
1337 1818 CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1338 1819 RETURN();
1339 1820 }
1340 1821  
  1822 +void op_mttc0_entryhi(void)
  1823 +{
  1824 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1825 +
  1826 + env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
  1827 + env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
  1828 + RETURN();
  1829 +}
  1830 +
1341 1831 void op_mtc0_compare (void)
1342 1832 {
1343 1833 CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
... ... @@ -1347,9 +1837,8 @@ void op_mtc0_compare (void)
1347 1837 void op_mtc0_status (void)
1348 1838 {
1349 1839 uint32_t val, old;
1350   - uint32_t mask = env->Status_rw_bitmask;
  1840 + uint32_t mask = env->CP0_Status_rw_bitmask;
1351 1841  
1352   - /* No reverse endianness, no MDMX/DSP implemented. */
1353 1842 val = T0 & mask;
1354 1843 old = env->CP0_Status;
1355 1844 if (!(val & (1 << CP0St_EXL)) &&
... ... @@ -1379,6 +1868,19 @@ void op_mtc0_status (void)
1379 1868 RETURN();
1380 1869 }
1381 1870  
  1871 +void op_mttc0_status(void)
  1872 +{
  1873 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1874 + uint32_t tcstatus = env->CP0_TCStatus[other_tc];
  1875 +
  1876 + env->CP0_Status = T0 & ~0xf1000018;
  1877 + tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
  1878 + tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
  1879 + tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_R0)) << (CP0TCSt_TKSU - CP0St_R0));
  1880 + env->CP0_TCStatus[other_tc] = tcstatus;
  1881 + RETURN();
  1882 +}
  1883 +
1382 1884 void op_mtc0_intctl (void)
1383 1885 {
1384 1886 /* vectored interrupts not implemented, timer on int 7,
... ... @@ -1389,15 +1891,14 @@ void op_mtc0_intctl (void)
1389 1891  
1390 1892 void op_mtc0_srsctl (void)
1391 1893 {
1392   - /* shadow registers not implemented */
1393   - env->CP0_SRSCtl = 0;
  1894 + uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
  1895 + env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1394 1896 RETURN();
1395 1897 }
1396 1898  
1397 1899 void op_mtc0_srsmap (void)
1398 1900 {
1399   - /* shadow registers not implemented */
1400   - env->CP0_SRSMap = 0;
  1901 + env->CP0_SRSMap = T0;
1401 1902 RETURN();
1402 1903 }
1403 1904  
... ... @@ -1460,6 +1961,13 @@ void op_mtc0_watchhi (void)
1460 1961 RETURN();
1461 1962 }
1462 1963  
  1964 +void op_mtc0_xcontext (void)
  1965 +{
  1966 + target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
  1967 + env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
  1968 + RETURN();
  1969 +}
  1970 +
1463 1971 void op_mtc0_framemask (void)
1464 1972 {
1465 1973 env->CP0_Framemask = T0; /* XXX */
... ... @@ -1476,6 +1984,17 @@ void op_mtc0_debug (void)
1476 1984 RETURN();
1477 1985 }
1478 1986  
  1987 +void op_mttc0_debug(void)
  1988 +{
  1989 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  1990 +
  1991 + /* XXX: Might be wrong, check with EJTAG spec. */
  1992 + env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
  1993 + env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
  1994 + (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
  1995 + RETURN();
  1996 +}
  1997 +
1479 1998 void op_mtc0_depc (void)
1480 1999 {
1481 2000 env->CP0_DEPC = T0;
... ... @@ -1525,10 +2044,21 @@ void op_mtc0_desave (void)
1525 2044 }
1526 2045  
1527 2046 #ifdef TARGET_MIPS64
1528   -void op_mtc0_xcontext (void)
  2047 +void op_dmfc0_yqmask (void)
1529 2048 {
1530   - target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1531   - env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
  2049 + T0 = env->CP0_YQMask;
  2050 + RETURN();
  2051 +}
  2052 +
  2053 +void op_dmfc0_vpeschedule (void)
  2054 +{
  2055 + T0 = env->CP0_VPESchedule;
  2056 + RETURN();
  2057 +}
  2058 +
  2059 +void op_dmfc0_vpeschefback (void)
  2060 +{
  2061 + T0 = env->CP0_VPEScheFBack;
1532 2062 RETURN();
1533 2063 }
1534 2064  
... ... @@ -1538,6 +2068,36 @@ void op_dmfc0_entrylo0 (void)
1538 2068 RETURN();
1539 2069 }
1540 2070  
  2071 +void op_dmfc0_tcrestart (void)
  2072 +{
  2073 + T0 = env->PC[env->current_tc];
  2074 + RETURN();
  2075 +}
  2076 +
  2077 +void op_dmfc0_tchalt (void)
  2078 +{
  2079 + T0 = env->CP0_TCHalt[env->current_tc];
  2080 + RETURN();
  2081 +}
  2082 +
  2083 +void op_dmfc0_tccontext (void)
  2084 +{
  2085 + T0 = env->CP0_TCContext[env->current_tc];
  2086 + RETURN();
  2087 +}
  2088 +
  2089 +void op_dmfc0_tcschedule (void)
  2090 +{
  2091 + T0 = env->CP0_TCSchedule[env->current_tc];
  2092 + RETURN();
  2093 +}
  2094 +
  2095 +void op_dmfc0_tcschefback (void)
  2096 +{
  2097 + T0 = env->CP0_TCScheFBack[env->current_tc];
  2098 + RETURN();
  2099 +}
  2100 +
1541 2101 void op_dmfc0_entrylo1 (void)
1542 2102 {
1543 2103 T0 = env->CP0_EntryLo1;
... ... @@ -1599,6 +2159,157 @@ void op_dmfc0_errorepc (void)
1599 2159 }
1600 2160 #endif /* TARGET_MIPS64 */
1601 2161  
  2162 +/* MIPS MT functions */
  2163 +void op_mftgpr(void)
  2164 +{
  2165 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2166 +
  2167 + T0 = env->gpr[PARAM1][other_tc];
  2168 + RETURN();
  2169 +}
  2170 +
  2171 +void op_mftlo(void)
  2172 +{
  2173 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2174 +
  2175 + T0 = env->LO[PARAM1][other_tc];
  2176 + RETURN();
  2177 +}
  2178 +
  2179 +void op_mfthi(void)
  2180 +{
  2181 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2182 +
  2183 + T0 = env->HI[PARAM1][other_tc];
  2184 + RETURN();
  2185 +}
  2186 +
  2187 +void op_mftacx(void)
  2188 +{
  2189 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2190 +
  2191 + T0 = env->ACX[PARAM1][other_tc];
  2192 + RETURN();
  2193 +}
  2194 +
  2195 +void op_mftdsp(void)
  2196 +{
  2197 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2198 +
  2199 + T0 = env->DSPControl[other_tc];
  2200 + RETURN();
  2201 +}
  2202 +
  2203 +void op_mttgpr(void)
  2204 +{
  2205 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2206 +
  2207 + T0 = env->gpr[PARAM1][other_tc];
  2208 + RETURN();
  2209 +}
  2210 +
  2211 +void op_mttlo(void)
  2212 +{
  2213 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2214 +
  2215 + T0 = env->LO[PARAM1][other_tc];
  2216 + RETURN();
  2217 +}
  2218 +
  2219 +void op_mtthi(void)
  2220 +{
  2221 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2222 +
  2223 + T0 = env->HI[PARAM1][other_tc];
  2224 + RETURN();
  2225 +}
  2226 +
  2227 +void op_mttacx(void)
  2228 +{
  2229 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2230 +
  2231 + T0 = env->ACX[PARAM1][other_tc];
  2232 + RETURN();
  2233 +}
  2234 +
  2235 +void op_mttdsp(void)
  2236 +{
  2237 + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
  2238 +
  2239 + T0 = env->DSPControl[other_tc];
  2240 + RETURN();
  2241 +}
  2242 +
  2243 +
  2244 +void op_dmt(void)
  2245 +{
  2246 + // TODO
  2247 + T0 = 0;
  2248 + // rt = T0
  2249 + RETURN();
  2250 +}
  2251 +
  2252 +void op_emt(void)
  2253 +{
  2254 + // TODO
  2255 + T0 = 0;
  2256 + // rt = T0
  2257 + RETURN();
  2258 +}
  2259 +
  2260 +void op_dvpe(void)
  2261 +{
  2262 + // TODO
  2263 + T0 = 0;
  2264 + // rt = T0
  2265 + RETURN();
  2266 +}
  2267 +
  2268 +void op_evpe(void)
  2269 +{
  2270 + // TODO
  2271 + T0 = 0;
  2272 + // rt = T0
  2273 + RETURN();
  2274 +}
  2275 +
  2276 +void op_fork(void)
  2277 +{
  2278 + // T0 = rt, T1 = rs
  2279 + T0 = 0;
  2280 + // TODO: store to TC register
  2281 + RETURN();
  2282 +}
  2283 +
  2284 +void op_yield(void)
  2285 +{
  2286 + if (T0 < 0) {
  2287 + /* No scheduling policy implemented. */
  2288 + if (T0 != -2) {
  2289 + if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
  2290 + env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
  2291 + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
  2292 + env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
  2293 + CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
  2294 + }
  2295 + }
  2296 + } else if (T0 == 0) {
  2297 + if (0 /* TODO: TC underflow */) {
  2298 + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
  2299 + CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
  2300 + } else {
  2301 + // TODO: Deallocate TC
  2302 + }
  2303 + } else if (T0 > 0) {
  2304 + /* Yield qualifier inputs not implemented. */
  2305 + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
  2306 + env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
  2307 + CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
  2308 + }
  2309 + T0 = env->CP0_YQMask;
  2310 + RETURN();
  2311 +}
  2312 +
1602 2313 /* CP1 functions */
1603 2314 #if 0
1604 2315 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
... ... @@ -1617,30 +2328,14 @@ void op_cp0_enabled(void)
1617 2328  
1618 2329 void op_cfc1 (void)
1619 2330 {
1620   - switch (T1) {
1621   - case 0:
1622   - T0 = (int32_t)env->fcr0;
1623   - break;
1624   - case 25:
1625   - T0 = ((env->fcr31 >> 24) & 0xfe) | ((env->fcr31 >> 23) & 0x1);
1626   - break;
1627   - case 26:
1628   - T0 = env->fcr31 & 0x0003f07c;
1629   - break;
1630   - case 28:
1631   - T0 = (env->fcr31 & 0x00000f83) | ((env->fcr31 >> 22) & 0x4);
1632   - break;
1633   - default:
1634   - T0 = (int32_t)env->fcr31;
1635   - break;
1636   - }
  2331 + CALL_FROM_TB1(do_cfc1, PARAM1);
1637 2332 DEBUG_FPU_STATE();
1638 2333 RETURN();
1639 2334 }
1640 2335  
1641 2336 void op_ctc1 (void)
1642 2337 {
1643   - CALL_FROM_TB0(do_ctc1);
  2338 + CALL_FROM_TB1(do_ctc1, PARAM1);
1644 2339 DEBUG_FPU_STATE();
1645 2340 RETURN();
1646 2341 }
... ... @@ -1842,21 +2537,21 @@ FLOAT_ROUNDOP(floor, w, s)
1842 2537  
1843 2538 FLOAT_OP(movf, d)
1844 2539 {
1845   - if (!(env->fcr31 & PARAM1))
  2540 + if (!(env->fpu->fcr31 & PARAM1))
1846 2541 DT2 = DT0;
1847 2542 DEBUG_FPU_STATE();
1848 2543 RETURN();
1849 2544 }
1850 2545 FLOAT_OP(movf, s)
1851 2546 {
1852   - if (!(env->fcr31 & PARAM1))
  2547 + if (!(env->fpu->fcr31 & PARAM1))
1853 2548 WT2 = WT0;
1854 2549 DEBUG_FPU_STATE();
1855 2550 RETURN();
1856 2551 }
1857 2552 FLOAT_OP(movf, ps)
1858 2553 {
1859   - if (!(env->fcr31 & PARAM1)) {
  2554 + if (!(env->fpu->fcr31 & PARAM1)) {
1860 2555 WT2 = WT0;
1861 2556 WTH2 = WTH0;
1862 2557 }
... ... @@ -1865,21 +2560,21 @@ FLOAT_OP(movf, ps)
1865 2560 }
1866 2561 FLOAT_OP(movt, d)
1867 2562 {
1868   - if (env->fcr31 & PARAM1)
  2563 + if (env->fpu->fcr31 & PARAM1)
1869 2564 DT2 = DT0;
1870 2565 DEBUG_FPU_STATE();
1871 2566 RETURN();
1872 2567 }
1873 2568 FLOAT_OP(movt, s)
1874 2569 {
1875   - if (env->fcr31 & PARAM1)
  2570 + if (env->fpu->fcr31 & PARAM1)
1876 2571 WT2 = WT0;
1877 2572 DEBUG_FPU_STATE();
1878 2573 RETURN();
1879 2574 }
1880 2575 FLOAT_OP(movt, ps)
1881 2576 {
1882   - if (env->fcr31 & PARAM1) {
  2577 + if (env->fpu->fcr31 & PARAM1) {
1883 2578 WT2 = WT0;
1884 2579 WTH2 = WTH0;
1885 2580 }
... ... @@ -1997,24 +2692,24 @@ FLOAT_HOP(mulr)
1997 2692 #define FLOAT_TERNOP(name1, name2) \
1998 2693 FLOAT_OP(name1 ## name2, d) \
1999 2694 { \
2000   - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status); \
2001   - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status); \
  2695 + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
  2696 + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2002 2697 DEBUG_FPU_STATE(); \
2003 2698 RETURN(); \
2004 2699 } \
2005 2700 FLOAT_OP(name1 ## name2, s) \
2006 2701 { \
2007   - FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2008   - FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
  2702 + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
  2703 + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2009 2704 DEBUG_FPU_STATE(); \
2010 2705 RETURN(); \
2011 2706 } \
2012 2707 FLOAT_OP(name1 ## name2, ps) \
2013 2708 { \
2014   - FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2015   - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
2016   - FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
2017   - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
  2709 + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
  2710 + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
  2711 + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
  2712 + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2018 2713 DEBUG_FPU_STATE(); \
2019 2714 RETURN(); \
2020 2715 }
... ... @@ -2026,26 +2721,26 @@ FLOAT_TERNOP(mul, sub)
2026 2721 #define FLOAT_NTERNOP(name1, name2) \
2027 2722 FLOAT_OP(n ## name1 ## name2, d) \
2028 2723 { \
2029   - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status); \
2030   - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status); \
  2724 + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
  2725 + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2031 2726 FDT2 ^= 1ULL << 63; \
2032 2727 DEBUG_FPU_STATE(); \
2033 2728 RETURN(); \
2034 2729 } \
2035 2730 FLOAT_OP(n ## name1 ## name2, s) \
2036 2731 { \
2037   - FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2038   - FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
  2732 + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
  2733 + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2039 2734 FST2 ^= 1 << 31; \
2040 2735 DEBUG_FPU_STATE(); \
2041 2736 RETURN(); \
2042 2737 } \
2043 2738 FLOAT_OP(n ## name1 ## name2, ps) \
2044 2739 { \
2045   - FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2046   - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
2047   - FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
2048   - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
  2740 + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
  2741 + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
  2742 + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
  2743 + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2049 2744 FST2 ^= 1 << 31; \
2050 2745 FSTH2 ^= 1 << 31; \
2051 2746 DEBUG_FPU_STATE(); \
... ... @@ -2059,13 +2754,13 @@ FLOAT_NTERNOP(mul, sub)
2059 2754 #define FLOAT_UNOP(name) \
2060 2755 FLOAT_OP(name, d) \
2061 2756 { \
2062   - FDT2 = float64_ ## name(FDT0, &env->fp_status); \
  2757 + FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2063 2758 DEBUG_FPU_STATE(); \
2064 2759 RETURN(); \
2065 2760 } \
2066 2761 FLOAT_OP(name, s) \
2067 2762 { \
2068   - FST2 = float32_ ## name(FST0, &env->fp_status); \
  2763 + FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2069 2764 DEBUG_FPU_STATE(); \
2070 2765 RETURN(); \
2071 2766 }
... ... @@ -2141,9 +2836,9 @@ FLOAT_OP(alnv, ps)
2141 2836  
2142 2837 #ifdef CONFIG_SOFTFLOAT
2143 2838 #define clear_invalid() do { \
2144   - int flags = get_float_exception_flags(&env->fp_status); \
  2839 + int flags = get_float_exception_flags(&env->fpu->fp_status); \
2145 2840 flags &= ~float_flag_invalid; \
2146   - set_float_exception_flags(flags, &env->fp_status); \
  2841 + set_float_exception_flags(flags, &env->fpu->fp_status); \
2147 2842 } while(0)
2148 2843 #else
2149 2844 #define clear_invalid() do { } while(0)
... ... @@ -2190,63 +2885,63 @@ CMP_OPS(ngt)
2190 2885  
2191 2886 void op_bc1f (void)
2192 2887 {
2193   - T0 = !!(~GET_FP_COND(env) & (0x1 << PARAM1));
  2888 + T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2194 2889 DEBUG_FPU_STATE();
2195 2890 RETURN();
2196 2891 }
2197 2892 void op_bc1any2f (void)
2198 2893 {
2199   - T0 = !!(~GET_FP_COND(env) & (0x3 << PARAM1));
  2894 + T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2200 2895 DEBUG_FPU_STATE();
2201 2896 RETURN();
2202 2897 }
2203 2898 void op_bc1any4f (void)
2204 2899 {
2205   - T0 = !!(~GET_FP_COND(env) & (0xf << PARAM1));
  2900 + T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
2206 2901 DEBUG_FPU_STATE();
2207 2902 RETURN();
2208 2903 }
2209 2904  
2210 2905 void op_bc1t (void)
2211 2906 {
2212   - T0 = !!(GET_FP_COND(env) & (0x1 << PARAM1));
  2907 + T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2213 2908 DEBUG_FPU_STATE();
2214 2909 RETURN();
2215 2910 }
2216 2911 void op_bc1any2t (void)
2217 2912 {
2218   - T0 = !!(GET_FP_COND(env) & (0x3 << PARAM1));
  2913 + T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2219 2914 DEBUG_FPU_STATE();
2220 2915 RETURN();
2221 2916 }
2222 2917 void op_bc1any4t (void)
2223 2918 {
2224   - T0 = !!(GET_FP_COND(env) & (0xf << PARAM1));
  2919 + T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2225 2920 DEBUG_FPU_STATE();
2226 2921 RETURN();
2227 2922 }
2228 2923  
2229 2924 void op_tlbwi (void)
2230 2925 {
2231   - CALL_FROM_TB0(env->do_tlbwi);
  2926 + CALL_FROM_TB0(env->tlb->do_tlbwi);
2232 2927 RETURN();
2233 2928 }
2234 2929  
2235 2930 void op_tlbwr (void)
2236 2931 {
2237   - CALL_FROM_TB0(env->do_tlbwr);
  2932 + CALL_FROM_TB0(env->tlb->do_tlbwr);
2238 2933 RETURN();
2239 2934 }
2240 2935  
2241 2936 void op_tlbp (void)
2242 2937 {
2243   - CALL_FROM_TB0(env->do_tlbp);
  2938 + CALL_FROM_TB0(env->tlb->do_tlbp);
2244 2939 RETURN();
2245 2940 }
2246 2941  
2247 2942 void op_tlbr (void)
2248 2943 {
2249   - CALL_FROM_TB0(env->do_tlbr);
  2944 + CALL_FROM_TB0(env->tlb->do_tlbr);
2250 2945 RETURN();
2251 2946 }
2252 2947  
... ... @@ -2307,10 +3002,10 @@ void op_eret (void)
2307 3002 if (loglevel & CPU_LOG_EXEC)
2308 3003 CALL_FROM_TB0(debug_pre_eret);
2309 3004 if (env->CP0_Status & (1 << CP0St_ERL)) {
2310   - env->PC = env->CP0_ErrorEPC;
  3005 + env->PC[env->current_tc] = env->CP0_ErrorEPC;
2311 3006 env->CP0_Status &= ~(1 << CP0St_ERL);
2312 3007 } else {
2313   - env->PC = env->CP0_EPC;
  3008 + env->PC[env->current_tc] = env->CP0_EPC;
2314 3009 env->CP0_Status &= ~(1 << CP0St_EXL);
2315 3010 }
2316 3011 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
... ... @@ -2335,7 +3030,7 @@ void op_deret (void)
2335 3030 {
2336 3031 if (loglevel & CPU_LOG_EXEC)
2337 3032 CALL_FROM_TB0(debug_pre_eret);
2338   - env->PC = env->CP0_DEPC;
  3033 + env->PC[env->current_tc] = env->CP0_DEPC;
2339 3034 env->hflags |= MIPS_HFLAG_DM;
2340 3035 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
2341 3036 !(env->CP0_Status & (1 << CP0St_ERL)) &&
... ... @@ -2407,14 +3102,14 @@ void op_save_state (void)
2407 3102  
2408 3103 void op_save_pc (void)
2409 3104 {
2410   - env->PC = PARAM1;
  3105 + env->PC[env->current_tc] = PARAM1;
2411 3106 RETURN();
2412 3107 }
2413 3108  
2414 3109 #ifdef TARGET_MIPS64
2415 3110 void op_save_pc64 (void)
2416 3111 {
2417   - env->PC = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
  3112 + env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
2418 3113 RETURN();
2419 3114 }
2420 3115 #endif
... ...
target-mips/op_helper.c
... ... @@ -160,13 +160,13 @@ void do_drotrv (void)
160 160 #if TARGET_LONG_BITS > HOST_LONG_BITS
161 161 static inline uint64_t get_HILO (void)
162 162 {
163   - return (env->HI << 32) | (uint32_t)env->LO;
  163 + return (env->HI[0][env->current_tc] << 32) | (uint32_t)env->LO[0][env->current_tc];
164 164 }
165 165  
166 166 static inline void set_HILO (uint64_t HILO)
167 167 {
168   - env->LO = (int32_t)HILO;
169   - env->HI = (int32_t)(HILO >> 32);
  168 + env->LO[0][env->current_tc] = (int32_t)HILO;
  169 + env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
170 170 }
171 171  
172 172 void do_mult (void)
... ... @@ -217,8 +217,8 @@ void do_div (void)
217 217 {
218 218 /* 64bit datatypes because we may see overflow/underflow. */
219 219 if (T1 != 0) {
220   - env->LO = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
221   - env->HI = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
  220 + env->LO[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
  221 + env->HI[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
222 222 }
223 223 }
224 224 #endif
... ... @@ -228,8 +228,8 @@ void do_ddiv (void)
228 228 {
229 229 if (T1 != 0) {
230 230 lldiv_t res = lldiv((int64_t)T0, (int64_t)T1);
231   - env->LO = res.quot;
232   - env->HI = res.rem;
  231 + env->LO[0][env->current_tc] = res.quot;
  232 + env->HI[0][env->current_tc] = res.rem;
233 233 }
234 234 }
235 235  
... ... @@ -237,8 +237,8 @@ void do_ddiv (void)
237 237 void do_ddivu (void)
238 238 {
239 239 if (T1 != 0) {
240   - env->LO = T0 / T1;
241   - env->HI = T0 % T1;
  240 + env->LO[0][env->current_tc] = T0 / T1;
  241 + env->HI[0][env->current_tc] = T0 % T1;
242 242 }
243 243 }
244 244 #endif
... ... @@ -316,10 +316,10 @@ void do_mtc0_status_irqraise_debug(void)
316 316 void fpu_handle_exception(void)
317 317 {
318 318 #ifdef CONFIG_SOFTFLOAT
319   - int flags = get_float_exception_flags(&env->fp_status);
  319 + int flags = get_float_exception_flags(&env->fpu->fp_status);
320 320 unsigned int cpuflags = 0, enable, cause = 0;
321 321  
322   - enable = GET_FP_ENABLE(env->fcr31);
  322 + enable = GET_FP_ENABLE(env->fpu->fcr31);
323 323  
324 324 /* determine current flags */
325 325 if (flags & float_flag_invalid) {
... ... @@ -342,11 +342,11 @@ void fpu_handle_exception(void)
342 342 cpuflags |= FP_INEXACT;
343 343 cause |= FP_INEXACT & enable;
344 344 }
345   - SET_FP_FLAGS(env->fcr31, cpuflags);
346   - SET_FP_CAUSE(env->fcr31, cause);
  345 + SET_FP_FLAGS(env->fpu->fcr31, cpuflags);
  346 + SET_FP_CAUSE(env->fpu->fcr31, cause);
347 347 #else
348   - SET_FP_FLAGS(env->fcr31, 0);
349   - SET_FP_CAUSE(env->fcr31, 0);
  348 + SET_FP_FLAGS(env->fpu->fcr31, 0);
  349 + SET_FP_CAUSE(env->fpu->fcr31, 0);
350 350 #endif
351 351 }
352 352  
... ... @@ -355,14 +355,14 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global)
355 355 {
356 356 /* Flush qemu's TLB and discard all shadowed entries. */
357 357 tlb_flush (env, flush_global);
358   - env->tlb_in_use = env->nb_tlb;
  358 + env->tlb->tlb_in_use = env->tlb->nb_tlb;
359 359 }
360 360  
361 361 static void r4k_mips_tlb_flush_extra (CPUState *env, int first)
362 362 {
363 363 /* Discard entries from env->tlb[first] onwards. */
364   - while (env->tlb_in_use > first) {
365   - r4k_invalidate_tlb(env, --env->tlb_in_use, 0);
  364 + while (env->tlb->tlb_in_use > first) {
  365 + r4k_invalidate_tlb(env, --env->tlb->tlb_in_use, 0);
366 366 }
367 367 }
368 368  
... ... @@ -371,7 +371,7 @@ static void r4k_fill_tlb (int idx)
371 371 r4k_tlb_t *tlb;
372 372  
373 373 /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
374   - tlb = &env->mmu.r4k.tlb[idx];
  374 + tlb = &env->tlb->mmu.r4k.tlb[idx];
375 375 tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
376 376 #ifdef TARGET_MIPS64
377 377 tlb->VPN &= env->SEGMask;
... ... @@ -394,10 +394,10 @@ void r4k_do_tlbwi (void)
394 394 /* Discard cached TLB entries. We could avoid doing this if the
395 395 tlbwi is just upgrading access permissions on the current entry;
396 396 that might be a further win. */
397   - r4k_mips_tlb_flush_extra (env, env->nb_tlb);
  397 + r4k_mips_tlb_flush_extra (env, env->tlb->nb_tlb);
398 398  
399   - r4k_invalidate_tlb(env, env->CP0_Index % env->nb_tlb, 0);
400   - r4k_fill_tlb(env->CP0_Index % env->nb_tlb);
  399 + r4k_invalidate_tlb(env, env->CP0_Index % env->tlb->nb_tlb, 0);
  400 + r4k_fill_tlb(env->CP0_Index % env->tlb->nb_tlb);
401 401 }
402 402  
403 403 void r4k_do_tlbwr (void)
... ... @@ -418,8 +418,8 @@ void r4k_do_tlbp (void)
418 418 int i;
419 419  
420 420 ASID = env->CP0_EntryHi & 0xFF;
421   - for (i = 0; i < env->nb_tlb; i++) {
422   - tlb = &env->mmu.r4k.tlb[i];
  421 + for (i = 0; i < env->tlb->nb_tlb; i++) {
  422 + tlb = &env->tlb->mmu.r4k.tlb[i];
423 423 /* 1k pages are not supported. */
424 424 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
425 425 tag = env->CP0_EntryHi & ~mask;
... ... @@ -431,10 +431,10 @@ void r4k_do_tlbp (void)
431 431 break;
432 432 }
433 433 }
434   - if (i == env->nb_tlb) {
  434 + if (i == env->tlb->nb_tlb) {
435 435 /* No match. Discard any shadow entries, if any of them match. */
436   - for (i = env->nb_tlb; i < env->tlb_in_use; i++) {
437   - tlb = &env->mmu.r4k.tlb[i];
  436 + for (i = env->tlb->nb_tlb; i < env->tlb->tlb_in_use; i++) {
  437 + tlb = &env->tlb->mmu.r4k.tlb[i];
438 438 /* 1k pages are not supported. */
439 439 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
440 440 tag = env->CP0_EntryHi & ~mask;
... ... @@ -456,13 +456,13 @@ void r4k_do_tlbr (void)
456 456 uint8_t ASID;
457 457  
458 458 ASID = env->CP0_EntryHi & 0xFF;
459   - tlb = &env->mmu.r4k.tlb[env->CP0_Index % env->nb_tlb];
  459 + tlb = &env->tlb->mmu.r4k.tlb[env->CP0_Index % env->tlb->nb_tlb];
460 460  
461 461 /* If this will change the current ASID, flush qemu's TLB. */
462 462 if (ASID != tlb->ASID)
463 463 cpu_mips_tlb_flush (env, 1);
464 464  
465   - r4k_mips_tlb_flush_extra(env, env->nb_tlb);
  465 + r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
466 466  
467 467 env->CP0_EntryHi = tlb->VPN | tlb->ASID;
468 468 env->CP0_PageMask = tlb->PageMask;
... ... @@ -491,7 +491,7 @@ void dump_sc (void)
491 491 void debug_pre_eret (void)
492 492 {
493 493 fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
494   - env->PC, env->CP0_EPC);
  494 + env->PC[env->current_tc], env->CP0_EPC);
495 495 if (env->CP0_Status & (1 << CP0St_ERL))
496 496 fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
497 497 if (env->hflags & MIPS_HFLAG_DM)
... ... @@ -502,7 +502,7 @@ void debug_pre_eret (void)
502 502 void debug_post_eret (void)
503 503 {
504 504 fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
505   - env->PC, env->CP0_EPC);
  505 + env->PC[env->current_tc], env->CP0_EPC);
506 506 if (env->CP0_Status & (1 << CP0St_ERL))
507 507 fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
508 508 if (env->hflags & MIPS_HFLAG_DM)
... ... @@ -518,21 +518,21 @@ void do_pmon (int function)
518 518 function /= 2;
519 519 switch (function) {
520 520 case 2: /* TODO: char inbyte(int waitflag); */
521   - if (env->gpr[4] == 0)
522   - env->gpr[2] = -1;
  521 + if (env->gpr[4][env->current_tc] == 0)
  522 + env->gpr[2][env->current_tc] = -1;
523 523 /* Fall through */
524 524 case 11: /* TODO: char inbyte (void); */
525   - env->gpr[2] = -1;
  525 + env->gpr[2][env->current_tc] = -1;
526 526 break;
527 527 case 3:
528 528 case 12:
529   - printf("%c", (char)(env->gpr[4] & 0xFF));
  529 + printf("%c", (char)(env->gpr[4][env->current_tc] & 0xFF));
530 530 break;
531 531 case 17:
532 532 break;
533 533 case 158:
534 534 {
535   - unsigned char *fmt = (void *)(unsigned long)env->gpr[4];
  535 + unsigned char *fmt = (void *)(unsigned long)env->gpr[4][env->current_tc];
536 536 printf("%s", fmt);
537 537 }
538 538 break;
... ... @@ -613,40 +613,61 @@ unsigned int ieee_rm[] = {
613 613 };
614 614  
615 615 #define RESTORE_ROUNDING_MODE \
616   - set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
  616 + set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)
617 617  
618   -void do_ctc1 (void)
  618 +void do_cfc1 (int reg)
619 619 {
620   - switch(T1) {
  620 + switch (reg) {
  621 + case 0:
  622 + T0 = (int32_t)env->fpu->fcr0;
  623 + break;
  624 + case 25:
  625 + T0 = ((env->fpu->fcr31 >> 24) & 0xfe) | ((env->fpu->fcr31 >> 23) & 0x1);
  626 + break;
  627 + case 26:
  628 + T0 = env->fpu->fcr31 & 0x0003f07c;
  629 + break;
  630 + case 28:
  631 + T0 = (env->fpu->fcr31 & 0x00000f83) | ((env->fpu->fcr31 >> 22) & 0x4);
  632 + break;
  633 + default:
  634 + T0 = (int32_t)env->fpu->fcr31;
  635 + break;
  636 + }
  637 +}
  638 +
  639 +void do_ctc1 (int reg)
  640 +{
  641 + switch(reg) {
621 642 case 25:
622 643 if (T0 & 0xffffff00)
623 644 return;
624   - env->fcr31 = (env->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |
  645 + env->fpu->fcr31 = (env->fpu->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |
625 646 ((T0 & 0x1) << 23);
626 647 break;
627 648 case 26:
628 649 if (T0 & 0x007c0000)
629 650 return;
630   - env->fcr31 = (env->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);
  651 + env->fpu->fcr31 = (env->fpu->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);
631 652 break;
632 653 case 28:
633 654 if (T0 & 0x007c0000)
634 655 return;
635   - env->fcr31 = (env->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |
  656 + env->fpu->fcr31 = (env->fpu->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |
636 657 ((T0 & 0x4) << 22);
637 658 break;
638 659 case 31:
639 660 if (T0 & 0x007c0000)
640 661 return;
641   - env->fcr31 = T0;
  662 + env->fpu->fcr31 = T0;
642 663 break;
643 664 default:
644 665 return;
645 666 }
646 667 /* set rounding mode */
647 668 RESTORE_ROUNDING_MODE;
648   - set_float_exception_flags(0, &env->fp_status);
649   - if ((GET_FP_ENABLE(env->fcr31) | 0x20) & GET_FP_CAUSE(env->fcr31))
  669 + set_float_exception_flags(0, &env->fpu->fp_status);
  670 + if ((GET_FP_ENABLE(env->fpu->fcr31) | 0x20) & GET_FP_CAUSE(env->fpu->fcr31))
650 671 do_raise_exception(EXCP_FPE);
651 672 }
652 673  
... ... @@ -670,325 +691,325 @@ inline char mips_ex_to_ieee(char xcpt)
670 691  
671 692 inline void update_fcr31(void)
672 693 {
673   - int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fp_status));
  694 + int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fpu->fp_status));
674 695  
675   - SET_FP_CAUSE(env->fcr31, tmp);
676   - if (GET_FP_ENABLE(env->fcr31) & tmp)
  696 + SET_FP_CAUSE(env->fpu->fcr31, tmp);
  697 + if (GET_FP_ENABLE(env->fpu->fcr31) & tmp)
677 698 do_raise_exception(EXCP_FPE);
678 699 else
679   - UPDATE_FP_FLAGS(env->fcr31, tmp);
  700 + UPDATE_FP_FLAGS(env->fpu->fcr31, tmp);
680 701 }
681 702  
682 703 #define FLOAT_OP(name, p) void do_float_##name##_##p(void)
683 704  
684 705 FLOAT_OP(cvtd, s)
685 706 {
686   - set_float_exception_flags(0, &env->fp_status);
687   - FDT2 = float32_to_float64(FST0, &env->fp_status);
  707 + set_float_exception_flags(0, &env->fpu->fp_status);
  708 + FDT2 = float32_to_float64(FST0, &env->fpu->fp_status);
688 709 update_fcr31();
689 710 }
690 711 FLOAT_OP(cvtd, w)
691 712 {
692   - set_float_exception_flags(0, &env->fp_status);
693   - FDT2 = int32_to_float64(WT0, &env->fp_status);
  713 + set_float_exception_flags(0, &env->fpu->fp_status);
  714 + FDT2 = int32_to_float64(WT0, &env->fpu->fp_status);
694 715 update_fcr31();
695 716 }
696 717 FLOAT_OP(cvtd, l)
697 718 {
698   - set_float_exception_flags(0, &env->fp_status);
699   - FDT2 = int64_to_float64(DT0, &env->fp_status);
  719 + set_float_exception_flags(0, &env->fpu->fp_status);
  720 + FDT2 = int64_to_float64(DT0, &env->fpu->fp_status);
700 721 update_fcr31();
701 722 }
702 723 FLOAT_OP(cvtl, d)
703 724 {
704   - set_float_exception_flags(0, &env->fp_status);
705   - DT2 = float64_to_int64(FDT0, &env->fp_status);
  725 + set_float_exception_flags(0, &env->fpu->fp_status);
  726 + DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);
706 727 update_fcr31();
707   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  728 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
708 729 DT2 = 0x7fffffffffffffffULL;
709 730 }
710 731 FLOAT_OP(cvtl, s)
711 732 {
712   - set_float_exception_flags(0, &env->fp_status);
713   - DT2 = float32_to_int64(FST0, &env->fp_status);
  733 + set_float_exception_flags(0, &env->fpu->fp_status);
  734 + DT2 = float32_to_int64(FST0, &env->fpu->fp_status);
714 735 update_fcr31();
715   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  736 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
716 737 DT2 = 0x7fffffffffffffffULL;
717 738 }
718 739  
719 740 FLOAT_OP(cvtps, pw)
720 741 {
721   - set_float_exception_flags(0, &env->fp_status);
722   - FST2 = int32_to_float32(WT0, &env->fp_status);
723   - FSTH2 = int32_to_float32(WTH0, &env->fp_status);
  742 + set_float_exception_flags(0, &env->fpu->fp_status);
  743 + FST2 = int32_to_float32(WT0, &env->fpu->fp_status);
  744 + FSTH2 = int32_to_float32(WTH0, &env->fpu->fp_status);
724 745 update_fcr31();
725 746 }
726 747 FLOAT_OP(cvtpw, ps)
727 748 {
728   - set_float_exception_flags(0, &env->fp_status);
729   - WT2 = float32_to_int32(FST0, &env->fp_status);
730   - WTH2 = float32_to_int32(FSTH0, &env->fp_status);
  749 + set_float_exception_flags(0, &env->fpu->fp_status);
  750 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
  751 + WTH2 = float32_to_int32(FSTH0, &env->fpu->fp_status);
731 752 update_fcr31();
732   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  753 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
733 754 WT2 = 0x7fffffff;
734 755 }
735 756 FLOAT_OP(cvts, d)
736 757 {
737   - set_float_exception_flags(0, &env->fp_status);
738   - FST2 = float64_to_float32(FDT0, &env->fp_status);
  758 + set_float_exception_flags(0, &env->fpu->fp_status);
  759 + FST2 = float64_to_float32(FDT0, &env->fpu->fp_status);
739 760 update_fcr31();
740 761 }
741 762 FLOAT_OP(cvts, w)
742 763 {
743   - set_float_exception_flags(0, &env->fp_status);
744   - FST2 = int32_to_float32(WT0, &env->fp_status);
  764 + set_float_exception_flags(0, &env->fpu->fp_status);
  765 + FST2 = int32_to_float32(WT0, &env->fpu->fp_status);
745 766 update_fcr31();
746 767 }
747 768 FLOAT_OP(cvts, l)
748 769 {
749   - set_float_exception_flags(0, &env->fp_status);
750   - FST2 = int64_to_float32(DT0, &env->fp_status);
  770 + set_float_exception_flags(0, &env->fpu->fp_status);
  771 + FST2 = int64_to_float32(DT0, &env->fpu->fp_status);
751 772 update_fcr31();
752 773 }
753 774 FLOAT_OP(cvts, pl)
754 775 {
755   - set_float_exception_flags(0, &env->fp_status);
  776 + set_float_exception_flags(0, &env->fpu->fp_status);
756 777 WT2 = WT0;
757 778 update_fcr31();
758 779 }
759 780 FLOAT_OP(cvts, pu)
760 781 {
761   - set_float_exception_flags(0, &env->fp_status);
  782 + set_float_exception_flags(0, &env->fpu->fp_status);
762 783 WT2 = WTH0;
763 784 update_fcr31();
764 785 }
765 786 FLOAT_OP(cvtw, s)
766 787 {
767   - set_float_exception_flags(0, &env->fp_status);
768   - WT2 = float32_to_int32(FST0, &env->fp_status);
  788 + set_float_exception_flags(0, &env->fpu->fp_status);
  789 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
769 790 update_fcr31();
770   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  791 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
771 792 WT2 = 0x7fffffff;
772 793 }
773 794 FLOAT_OP(cvtw, d)
774 795 {
775   - set_float_exception_flags(0, &env->fp_status);
776   - WT2 = float64_to_int32(FDT0, &env->fp_status);
  796 + set_float_exception_flags(0, &env->fpu->fp_status);
  797 + WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);
777 798 update_fcr31();
778   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  799 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
779 800 WT2 = 0x7fffffff;
780 801 }
781 802  
782 803 FLOAT_OP(roundl, d)
783 804 {
784   - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
785   - DT2 = float64_to_int64(FDT0, &env->fp_status);
  805 + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
  806 + DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);
786 807 RESTORE_ROUNDING_MODE;
787 808 update_fcr31();
788   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  809 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
789 810 DT2 = 0x7fffffffffffffffULL;
790 811 }
791 812 FLOAT_OP(roundl, s)
792 813 {
793   - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
794   - DT2 = float32_to_int64(FST0, &env->fp_status);
  814 + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
  815 + DT2 = float32_to_int64(FST0, &env->fpu->fp_status);
795 816 RESTORE_ROUNDING_MODE;
796 817 update_fcr31();
797   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  818 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
798 819 DT2 = 0x7fffffffffffffffULL;
799 820 }
800 821 FLOAT_OP(roundw, d)
801 822 {
802   - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
803   - WT2 = float64_to_int32(FDT0, &env->fp_status);
  823 + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
  824 + WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);
804 825 RESTORE_ROUNDING_MODE;
805 826 update_fcr31();
806   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  827 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
807 828 WT2 = 0x7fffffff;
808 829 }
809 830 FLOAT_OP(roundw, s)
810 831 {
811   - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
812   - WT2 = float32_to_int32(FST0, &env->fp_status);
  832 + set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
  833 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
813 834 RESTORE_ROUNDING_MODE;
814 835 update_fcr31();
815   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  836 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
816 837 WT2 = 0x7fffffff;
817 838 }
818 839  
819 840 FLOAT_OP(truncl, d)
820 841 {
821   - DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
  842 + DT2 = float64_to_int64_round_to_zero(FDT0, &env->fpu->fp_status);
822 843 update_fcr31();
823   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  844 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
824 845 DT2 = 0x7fffffffffffffffULL;
825 846 }
826 847 FLOAT_OP(truncl, s)
827 848 {
828   - DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
  849 + DT2 = float32_to_int64_round_to_zero(FST0, &env->fpu->fp_status);
829 850 update_fcr31();
830   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  851 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
831 852 DT2 = 0x7fffffffffffffffULL;
832 853 }
833 854 FLOAT_OP(truncw, d)
834 855 {
835   - WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
  856 + WT2 = float64_to_int32_round_to_zero(FDT0, &env->fpu->fp_status);
836 857 update_fcr31();
837   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  858 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
838 859 WT2 = 0x7fffffff;
839 860 }
840 861 FLOAT_OP(truncw, s)
841 862 {
842   - WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
  863 + WT2 = float32_to_int32_round_to_zero(FST0, &env->fpu->fp_status);
843 864 update_fcr31();
844   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  865 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
845 866 WT2 = 0x7fffffff;
846 867 }
847 868  
848 869 FLOAT_OP(ceill, d)
849 870 {
850   - set_float_rounding_mode(float_round_up, &env->fp_status);
851   - DT2 = float64_to_int64(FDT0, &env->fp_status);
  871 + set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
  872 + DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);
852 873 RESTORE_ROUNDING_MODE;
853 874 update_fcr31();
854   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  875 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
855 876 DT2 = 0x7fffffffffffffffULL;
856 877 }
857 878 FLOAT_OP(ceill, s)
858 879 {
859   - set_float_rounding_mode(float_round_up, &env->fp_status);
860   - DT2 = float32_to_int64(FST0, &env->fp_status);
  880 + set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
  881 + DT2 = float32_to_int64(FST0, &env->fpu->fp_status);
861 882 RESTORE_ROUNDING_MODE;
862 883 update_fcr31();
863   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  884 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
864 885 DT2 = 0x7fffffffffffffffULL;
865 886 }
866 887 FLOAT_OP(ceilw, d)
867 888 {
868   - set_float_rounding_mode(float_round_up, &env->fp_status);
869   - WT2 = float64_to_int32(FDT0, &env->fp_status);
  889 + set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
  890 + WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);
870 891 RESTORE_ROUNDING_MODE;
871 892 update_fcr31();
872   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  893 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
873 894 WT2 = 0x7fffffff;
874 895 }
875 896 FLOAT_OP(ceilw, s)
876 897 {
877   - set_float_rounding_mode(float_round_up, &env->fp_status);
878   - WT2 = float32_to_int32(FST0, &env->fp_status);
  898 + set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
  899 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
879 900 RESTORE_ROUNDING_MODE;
880 901 update_fcr31();
881   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  902 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
882 903 WT2 = 0x7fffffff;
883 904 }
884 905  
885 906 FLOAT_OP(floorl, d)
886 907 {
887   - set_float_rounding_mode(float_round_down, &env->fp_status);
888   - DT2 = float64_to_int64(FDT0, &env->fp_status);
  908 + set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
  909 + DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);
889 910 RESTORE_ROUNDING_MODE;
890 911 update_fcr31();
891   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  912 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
892 913 DT2 = 0x7fffffffffffffffULL;
893 914 }
894 915 FLOAT_OP(floorl, s)
895 916 {
896   - set_float_rounding_mode(float_round_down, &env->fp_status);
897   - DT2 = float32_to_int64(FST0, &env->fp_status);
  917 + set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
  918 + DT2 = float32_to_int64(FST0, &env->fpu->fp_status);
898 919 RESTORE_ROUNDING_MODE;
899 920 update_fcr31();
900   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  921 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
901 922 DT2 = 0x7fffffffffffffffULL;
902 923 }
903 924 FLOAT_OP(floorw, d)
904 925 {
905   - set_float_rounding_mode(float_round_down, &env->fp_status);
906   - WT2 = float64_to_int32(FDT0, &env->fp_status);
  926 + set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
  927 + WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);
907 928 RESTORE_ROUNDING_MODE;
908 929 update_fcr31();
909   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  930 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
910 931 WT2 = 0x7fffffff;
911 932 }
912 933 FLOAT_OP(floorw, s)
913 934 {
914   - set_float_rounding_mode(float_round_down, &env->fp_status);
915   - WT2 = float32_to_int32(FST0, &env->fp_status);
  935 + set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
  936 + WT2 = float32_to_int32(FST0, &env->fpu->fp_status);
916 937 RESTORE_ROUNDING_MODE;
917 938 update_fcr31();
918   - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  939 + if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
919 940 WT2 = 0x7fffffff;
920 941 }
921 942  
922 943 /* MIPS specific unary operations */
923 944 FLOAT_OP(recip, d)
924 945 {
925   - set_float_exception_flags(0, &env->fp_status);
926   - FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
  946 + set_float_exception_flags(0, &env->fpu->fp_status);
  947 + FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fpu->fp_status);
927 948 update_fcr31();
928 949 }
929 950 FLOAT_OP(recip, s)
930 951 {
931   - set_float_exception_flags(0, &env->fp_status);
932   - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
  952 + set_float_exception_flags(0, &env->fpu->fp_status);
  953 + FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status);
933 954 update_fcr31();
934 955 }
935 956  
936 957 FLOAT_OP(rsqrt, d)
937 958 {
938   - set_float_exception_flags(0, &env->fp_status);
939   - FDT2 = float64_sqrt(FDT0, &env->fp_status);
940   - FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
  959 + set_float_exception_flags(0, &env->fpu->fp_status);
  960 + FDT2 = float64_sqrt(FDT0, &env->fpu->fp_status);
  961 + FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fpu->fp_status);
941 962 update_fcr31();
942 963 }
943 964 FLOAT_OP(rsqrt, s)
944 965 {
945   - set_float_exception_flags(0, &env->fp_status);
946   - FST2 = float32_sqrt(FST0, &env->fp_status);
947   - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
  966 + set_float_exception_flags(0, &env->fpu->fp_status);
  967 + FST2 = float32_sqrt(FST0, &env->fpu->fp_status);
  968 + FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status);
948 969 update_fcr31();
949 970 }
950 971  
951 972 FLOAT_OP(recip1, d)
952 973 {
953   - set_float_exception_flags(0, &env->fp_status);
954   - FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
  974 + set_float_exception_flags(0, &env->fpu->fp_status);
  975 + FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fpu->fp_status);
955 976 update_fcr31();
956 977 }
957 978 FLOAT_OP(recip1, s)
958 979 {
959   - set_float_exception_flags(0, &env->fp_status);
960   - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
  980 + set_float_exception_flags(0, &env->fpu->fp_status);
  981 + FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status);
961 982 update_fcr31();
962 983 }
963 984 FLOAT_OP(recip1, ps)
964 985 {
965   - set_float_exception_flags(0, &env->fp_status);
966   - FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
967   - FSTH2 = float32_div(FLOAT_ONE32, FSTH0, &env->fp_status);
  986 + set_float_exception_flags(0, &env->fpu->fp_status);
  987 + FST2 = float32_div(FLOAT_ONE32, FST0, &env->fpu->fp_status);
  988 + FSTH2 = float32_div(FLOAT_ONE32, FSTH0, &env->fpu->fp_status);
968 989 update_fcr31();
969 990 }
970 991  
971 992 FLOAT_OP(rsqrt1, d)
972 993 {
973   - set_float_exception_flags(0, &env->fp_status);
974   - FDT2 = float64_sqrt(FDT0, &env->fp_status);
975   - FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
  994 + set_float_exception_flags(0, &env->fpu->fp_status);
  995 + FDT2 = float64_sqrt(FDT0, &env->fpu->fp_status);
  996 + FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fpu->fp_status);
976 997 update_fcr31();
977 998 }
978 999 FLOAT_OP(rsqrt1, s)
979 1000 {
980   - set_float_exception_flags(0, &env->fp_status);
981   - FST2 = float32_sqrt(FST0, &env->fp_status);
982   - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
  1001 + set_float_exception_flags(0, &env->fpu->fp_status);
  1002 + FST2 = float32_sqrt(FST0, &env->fpu->fp_status);
  1003 + FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status);
983 1004 update_fcr31();
984 1005 }
985 1006 FLOAT_OP(rsqrt1, ps)
986 1007 {
987   - set_float_exception_flags(0, &env->fp_status);
988   - FST2 = float32_sqrt(FST0, &env->fp_status);
989   - FSTH2 = float32_sqrt(FSTH0, &env->fp_status);
990   - FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
991   - FSTH2 = float32_div(FLOAT_ONE32, FSTH2, &env->fp_status);
  1008 + set_float_exception_flags(0, &env->fpu->fp_status);
  1009 + FST2 = float32_sqrt(FST0, &env->fpu->fp_status);
  1010 + FSTH2 = float32_sqrt(FSTH0, &env->fpu->fp_status);
  1011 + FST2 = float32_div(FLOAT_ONE32, FST2, &env->fpu->fp_status);
  1012 + FSTH2 = float32_div(FLOAT_ONE32, FSTH2, &env->fpu->fp_status);
992 1013 update_fcr31();
993 1014 }
994 1015  
... ... @@ -996,41 +1017,41 @@ FLOAT_OP(rsqrt1, ps)
996 1017 #define FLOAT_BINOP(name) \
997 1018 FLOAT_OP(name, d) \
998 1019 { \
999   - set_float_exception_flags(0, &env->fp_status); \
1000   - FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status); \
1001   - update_fcr31(); \
1002   - if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) \
1003   - FDT2 = 0x7ff7ffffffffffffULL; \
1004   - else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
1005   - if ((env->fcr31 & 0x3) == 0) \
1006   - FDT2 &= FLOAT_SIGN64; \
  1020 + set_float_exception_flags(0, &env->fpu->fp_status); \
  1021 + FDT2 = float64_ ## name (FDT0, FDT1, &env->fpu->fp_status); \
  1022 + update_fcr31(); \
  1023 + if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) \
  1024 + FDT2 = 0x7ff7ffffffffffffULL; \
  1025 + else if (GET_FP_CAUSE(env->fpu->fcr31) & FP_UNDERFLOW) { \
  1026 + if ((env->fpu->fcr31 & 0x3) == 0) \
  1027 + FDT2 &= FLOAT_SIGN64; \
1007 1028 } \
1008 1029 } \
1009 1030 FLOAT_OP(name, s) \
1010 1031 { \
1011   - set_float_exception_flags(0, &env->fp_status); \
1012   - FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
1013   - update_fcr31(); \
1014   - if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) \
1015   - FST2 = 0x7fbfffff; \
1016   - else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
1017   - if ((env->fcr31 & 0x3) == 0) \
1018   - FST2 &= FLOAT_SIGN32; \
  1032 + set_float_exception_flags(0, &env->fpu->fp_status); \
  1033 + FST2 = float32_ ## name (FST0, FST1, &env->fpu->fp_status); \
  1034 + update_fcr31(); \
  1035 + if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) \
  1036 + FST2 = 0x7fbfffff; \
  1037 + else if (GET_FP_CAUSE(env->fpu->fcr31) & FP_UNDERFLOW) { \
  1038 + if ((env->fpu->fcr31 & 0x3) == 0) \
  1039 + FST2 &= FLOAT_SIGN32; \
1019 1040 } \
1020 1041 } \
1021 1042 FLOAT_OP(name, ps) \
1022 1043 { \
1023   - set_float_exception_flags(0, &env->fp_status); \
1024   - FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
1025   - FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \
  1044 + set_float_exception_flags(0, &env->fpu->fp_status); \
  1045 + FST2 = float32_ ## name (FST0, FST1, &env->fpu->fp_status); \
  1046 + FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fpu->fp_status); \
1026 1047 update_fcr31(); \
1027   - if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) { \
1028   - FST2 = 0x7fbfffff; \
1029   - FSTH2 = 0x7fbfffff; \
1030   - } else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
1031   - if ((env->fcr31 & 0x3) == 0) { \
1032   - FST2 &= FLOAT_SIGN32; \
1033   - FSTH2 &= FLOAT_SIGN32; \
  1048 + if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) { \
  1049 + FST2 = 0x7fbfffff; \
  1050 + FSTH2 = 0x7fbfffff; \
  1051 + } else if (GET_FP_CAUSE(env->fpu->fcr31) & FP_UNDERFLOW) { \
  1052 + if ((env->fpu->fcr31 & 0x3) == 0) { \
  1053 + FST2 &= FLOAT_SIGN32; \
  1054 + FSTH2 &= FLOAT_SIGN32; \
1034 1055 } \
1035 1056 } \
1036 1057 }
... ... @@ -1043,69 +1064,69 @@ FLOAT_BINOP(div)
1043 1064 /* MIPS specific binary operations */
1044 1065 FLOAT_OP(recip2, d)
1045 1066 {
1046   - set_float_exception_flags(0, &env->fp_status);
1047   - FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
1048   - FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status) ^ FLOAT_SIGN64;
  1067 + set_float_exception_flags(0, &env->fpu->fp_status);
  1068 + FDT2 = float64_mul(FDT0, FDT2, &env->fpu->fp_status);
  1069 + FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fpu->fp_status) ^ FLOAT_SIGN64;
1049 1070 update_fcr31();
1050 1071 }
1051 1072 FLOAT_OP(recip2, s)
1052 1073 {
1053   - set_float_exception_flags(0, &env->fp_status);
1054   - FST2 = float32_mul(FST0, FST2, &env->fp_status);
1055   - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
  1074 + set_float_exception_flags(0, &env->fpu->fp_status);
  1075 + FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status);
  1076 + FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
1056 1077 update_fcr31();
1057 1078 }
1058 1079 FLOAT_OP(recip2, ps)
1059 1080 {
1060   - set_float_exception_flags(0, &env->fp_status);
1061   - FST2 = float32_mul(FST0, FST2, &env->fp_status);
1062   - FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
1063   - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
1064   - FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
  1081 + set_float_exception_flags(0, &env->fpu->fp_status);
  1082 + FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status);
  1083 + FSTH2 = float32_mul(FSTH0, FSTH2, &env->fpu->fp_status);
  1084 + FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
  1085 + FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
1065 1086 update_fcr31();
1066 1087 }
1067 1088  
1068 1089 FLOAT_OP(rsqrt2, d)
1069 1090 {
1070   - set_float_exception_flags(0, &env->fp_status);
1071   - FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
1072   - FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status);
1073   - FDT2 = float64_div(FDT2, FLOAT_TWO64, &env->fp_status) ^ FLOAT_SIGN64;
  1091 + set_float_exception_flags(0, &env->fpu->fp_status);
  1092 + FDT2 = float64_mul(FDT0, FDT2, &env->fpu->fp_status);
  1093 + FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fpu->fp_status);
  1094 + FDT2 = float64_div(FDT2, FLOAT_TWO64, &env->fpu->fp_status) ^ FLOAT_SIGN64;
1074 1095 update_fcr31();
1075 1096 }
1076 1097 FLOAT_OP(rsqrt2, s)
1077 1098 {
1078   - set_float_exception_flags(0, &env->fp_status);
1079   - FST2 = float32_mul(FST0, FST2, &env->fp_status);
1080   - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
1081   - FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
  1099 + set_float_exception_flags(0, &env->fpu->fp_status);
  1100 + FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status);
  1101 + FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status);
  1102 + FST2 = float32_div(FST2, FLOAT_TWO32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
1082 1103 update_fcr31();
1083 1104 }
1084 1105 FLOAT_OP(rsqrt2, ps)
1085 1106 {
1086   - set_float_exception_flags(0, &env->fp_status);
1087   - FST2 = float32_mul(FST0, FST2, &env->fp_status);
1088   - FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
1089   - FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
1090   - FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status);
1091   - FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
1092   - FSTH2 = float32_div(FSTH2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
  1107 + set_float_exception_flags(0, &env->fpu->fp_status);
  1108 + FST2 = float32_mul(FST0, FST2, &env->fpu->fp_status);
  1109 + FSTH2 = float32_mul(FSTH0, FSTH2, &env->fpu->fp_status);
  1110 + FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fpu->fp_status);
  1111 + FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fpu->fp_status);
  1112 + FST2 = float32_div(FST2, FLOAT_TWO32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
  1113 + FSTH2 = float32_div(FSTH2, FLOAT_TWO32, &env->fpu->fp_status) ^ FLOAT_SIGN32;
1093 1114 update_fcr31();
1094 1115 }
1095 1116  
1096 1117 FLOAT_OP(addr, ps)
1097 1118 {
1098   - set_float_exception_flags(0, &env->fp_status);
1099   - FST2 = float32_add (FST0, FSTH0, &env->fp_status);
1100   - FSTH2 = float32_add (FST1, FSTH1, &env->fp_status);
  1119 + set_float_exception_flags(0, &env->fpu->fp_status);
  1120 + FST2 = float32_add (FST0, FSTH0, &env->fpu->fp_status);
  1121 + FSTH2 = float32_add (FST1, FSTH1, &env->fpu->fp_status);
1101 1122 update_fcr31();
1102 1123 }
1103 1124  
1104 1125 FLOAT_OP(mulr, ps)
1105 1126 {
1106   - set_float_exception_flags(0, &env->fp_status);
1107   - FST2 = float32_mul (FST0, FSTH0, &env->fp_status);
1108   - FSTH2 = float32_mul (FST1, FSTH1, &env->fp_status);
  1127 + set_float_exception_flags(0, &env->fpu->fp_status);
  1128 + FST2 = float32_mul (FST0, FSTH0, &env->fpu->fp_status);
  1129 + FSTH2 = float32_mul (FST1, FSTH1, &env->fpu->fp_status);
1109 1130 update_fcr31();
1110 1131 }
1111 1132  
... ... @@ -1116,9 +1137,9 @@ void do_cmp_d_ ## op (long cc) \
1116 1137 int c = cond; \
1117 1138 update_fcr31(); \
1118 1139 if (c) \
1119   - SET_FP_COND(cc, env); \
  1140 + SET_FP_COND(cc, env->fpu); \
1120 1141 else \
1121   - CLEAR_FP_COND(cc, env); \
  1142 + CLEAR_FP_COND(cc, env->fpu); \
1122 1143 } \
1123 1144 void do_cmpabs_d_ ## op (long cc) \
1124 1145 { \
... ... @@ -1128,9 +1149,9 @@ void do_cmpabs_d_ ## op (long cc) \
1128 1149 c = cond; \
1129 1150 update_fcr31(); \
1130 1151 if (c) \
1131   - SET_FP_COND(cc, env); \
  1152 + SET_FP_COND(cc, env->fpu); \
1132 1153 else \
1133   - CLEAR_FP_COND(cc, env); \
  1154 + CLEAR_FP_COND(cc, env->fpu); \
1134 1155 }
1135 1156  
1136 1157 int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
... ... @@ -1149,24 +1170,24 @@ int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
1149 1170  
1150 1171 /* NOTE: the comma operator will make "cond" to eval to false,
1151 1172 * but float*_is_unordered() is still called. */
1152   -FOP_COND_D(f, (float64_is_unordered(0, FDT1, FDT0, &env->fp_status), 0))
1153   -FOP_COND_D(un, float64_is_unordered(0, FDT1, FDT0, &env->fp_status))
1154   -FOP_COND_D(eq, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
1155   -FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1156   -FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
1157   -FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1158   -FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
1159   -FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
  1173 +FOP_COND_D(f, (float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status), 0))
  1174 +FOP_COND_D(un, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status))
  1175 +FOP_COND_D(eq, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_eq(FDT0, FDT1, &env->fpu->fp_status))
  1176 +FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_eq(FDT0, FDT1, &env->fpu->fp_status))
  1177 +FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_lt(FDT0, FDT1, &env->fpu->fp_status))
  1178 +FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_lt(FDT0, FDT1, &env->fpu->fp_status))
  1179 +FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) && float64_le(FDT0, FDT1, &env->fpu->fp_status))
  1180 +FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fpu->fp_status) || float64_le(FDT0, FDT1, &env->fpu->fp_status))
1160 1181 /* NOTE: the comma operator will make "cond" to eval to false,
1161 1182 * but float*_is_unordered() is still called. */
1162   -FOP_COND_D(sf, (float64_is_unordered(1, FDT1, FDT0, &env->fp_status), 0))
1163   -FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fp_status))
1164   -FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
1165   -FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1166   -FOP_COND_D(lt, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
1167   -FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1168   -FOP_COND_D(le, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
1169   -FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
  1183 +FOP_COND_D(sf, (float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status), 0))
  1184 +FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status))
  1185 +FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_eq(FDT0, FDT1, &env->fpu->fp_status))
  1186 +FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_eq(FDT0, FDT1, &env->fpu->fp_status))
  1187 +FOP_COND_D(lt, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_lt(FDT0, FDT1, &env->fpu->fp_status))
  1188 +FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_lt(FDT0, FDT1, &env->fpu->fp_status))
  1189 +FOP_COND_D(le, !float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) && float64_le(FDT0, FDT1, &env->fpu->fp_status))
  1190 +FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fpu->fp_status) || float64_le(FDT0, FDT1, &env->fpu->fp_status))
1170 1191  
1171 1192 #define FOP_COND_S(op, cond) \
1172 1193 void do_cmp_s_ ## op (long cc) \
... ... @@ -1174,9 +1195,9 @@ void do_cmp_s_ ## op (long cc) \
1174 1195 int c = cond; \
1175 1196 update_fcr31(); \
1176 1197 if (c) \
1177   - SET_FP_COND(cc, env); \
  1198 + SET_FP_COND(cc, env->fpu); \
1178 1199 else \
1179   - CLEAR_FP_COND(cc, env); \
  1200 + CLEAR_FP_COND(cc, env->fpu); \
1180 1201 } \
1181 1202 void do_cmpabs_s_ ## op (long cc) \
1182 1203 { \
... ... @@ -1186,9 +1207,9 @@ void do_cmpabs_s_ ## op (long cc) \
1186 1207 c = cond; \
1187 1208 update_fcr31(); \
1188 1209 if (c) \
1189   - SET_FP_COND(cc, env); \
  1210 + SET_FP_COND(cc, env->fpu); \
1190 1211 else \
1191   - CLEAR_FP_COND(cc, env); \
  1212 + CLEAR_FP_COND(cc, env->fpu); \
1192 1213 }
1193 1214  
1194 1215 flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
... ... @@ -1207,24 +1228,24 @@ flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
1207 1228  
1208 1229 /* NOTE: the comma operator will make "cond" to eval to false,
1209 1230 * but float*_is_unordered() is still called. */
1210   -FOP_COND_S(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0))
1211   -FOP_COND_S(un, float32_is_unordered(0, FST1, FST0, &env->fp_status))
1212   -FOP_COND_S(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
1213   -FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1214   -FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
1215   -FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1216   -FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
1217   -FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
  1231 +FOP_COND_S(f, (float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status), 0))
  1232 +FOP_COND_S(un, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status))
  1233 +FOP_COND_S(eq, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status))
  1234 +FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status))
  1235 +FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status))
  1236 +FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status))
  1237 +FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status))
  1238 +FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status))
1218 1239 /* NOTE: the comma operator will make "cond" to eval to false,
1219 1240 * but float*_is_unordered() is still called. */
1220   -FOP_COND_S(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0))
1221   -FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status))
1222   -FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
1223   -FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1224   -FOP_COND_S(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
1225   -FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1226   -FOP_COND_S(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
1227   -FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
  1241 +FOP_COND_S(sf, (float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status), 0))
  1242 +FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status))
  1243 +FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status))
  1244 +FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status))
  1245 +FOP_COND_S(lt, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status))
  1246 +FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status))
  1247 +FOP_COND_S(le, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status))
  1248 +FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status))
1228 1249  
1229 1250 #define FOP_COND_PS(op, condl, condh) \
1230 1251 void do_cmp_ps_ ## op (long cc) \
... ... @@ -1233,13 +1254,13 @@ void do_cmp_ps_ ## op (long cc) \
1233 1254 int ch = condh; \
1234 1255 update_fcr31(); \
1235 1256 if (cl) \
1236   - SET_FP_COND(cc, env); \
  1257 + SET_FP_COND(cc, env->fpu); \
1237 1258 else \
1238   - CLEAR_FP_COND(cc, env); \
  1259 + CLEAR_FP_COND(cc, env->fpu); \
1239 1260 if (ch) \
1240   - SET_FP_COND(cc + 1, env); \
  1261 + SET_FP_COND(cc + 1, env->fpu); \
1241 1262 else \
1242   - CLEAR_FP_COND(cc + 1, env); \
  1263 + CLEAR_FP_COND(cc + 1, env->fpu); \
1243 1264 } \
1244 1265 void do_cmpabs_ps_ ## op (long cc) \
1245 1266 { \
... ... @@ -1252,48 +1273,48 @@ void do_cmpabs_ps_ ## op (long cc) \
1252 1273 ch = condh; \
1253 1274 update_fcr31(); \
1254 1275 if (cl) \
1255   - SET_FP_COND(cc, env); \
  1276 + SET_FP_COND(cc, env->fpu); \
1256 1277 else \
1257   - CLEAR_FP_COND(cc, env); \
  1278 + CLEAR_FP_COND(cc, env->fpu); \
1258 1279 if (ch) \
1259   - SET_FP_COND(cc + 1, env); \
  1280 + SET_FP_COND(cc + 1, env->fpu); \
1260 1281 else \
1261   - CLEAR_FP_COND(cc + 1, env); \
  1282 + CLEAR_FP_COND(cc + 1, env->fpu); \
1262 1283 }
1263 1284  
1264 1285 /* NOTE: the comma operator will make "cond" to eval to false,
1265 1286 * but float*_is_unordered() is still called. */
1266   -FOP_COND_PS(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0),
1267   - (float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status), 0))
1268   -FOP_COND_PS(un, float32_is_unordered(0, FST1, FST0, &env->fp_status),
1269   - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status))
1270   -FOP_COND_PS(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),
1271   - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
1272   -FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),
1273   - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))
1274   -FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),
1275   - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
1276   -FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),
1277   - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))
1278   -FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),
1279   - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
1280   -FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),
1281   - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))
  1287 +FOP_COND_PS(f, (float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status), 0),
  1288 + (float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status), 0))
  1289 +FOP_COND_PS(un, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status),
  1290 + float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status))
  1291 +FOP_COND_PS(eq, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status),
  1292 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_eq(FSTH0, FSTH1, &env->fpu->fp_status))
  1293 +FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status),
  1294 + float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_eq(FSTH0, FSTH1, &env->fpu->fp_status))
  1295 +FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status),
  1296 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_lt(FSTH0, FSTH1, &env->fpu->fp_status))
  1297 +FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status),
  1298 + float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_lt(FSTH0, FSTH1, &env->fpu->fp_status))
  1299 +FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status),
  1300 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) && float32_le(FSTH0, FSTH1, &env->fpu->fp_status))
  1301 +FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status),
  1302 + float32_is_unordered(0, FSTH1, FSTH0, &env->fpu->fp_status) || float32_le(FSTH0, FSTH1, &env->fpu->fp_status))
1282 1303 /* NOTE: the comma operator will make "cond" to eval to false,
1283 1304 * but float*_is_unordered() is still called. */
1284   -FOP_COND_PS(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0),
1285   - (float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status), 0))
1286   -FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status),
1287   - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status))
1288   -FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),
1289   - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
1290   -FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),
1291   - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))
1292   -FOP_COND_PS(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),
1293   - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
1294   -FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),
1295   - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))
1296   -FOP_COND_PS(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),
1297   - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
1298   -FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),
1299   - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))
  1305 +FOP_COND_PS(sf, (float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status), 0),
  1306 + (float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status), 0))
  1307 +FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status),
  1308 + float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status))
  1309 +FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_eq(FST0, FST1, &env->fpu->fp_status),
  1310 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_eq(FSTH0, FSTH1, &env->fpu->fp_status))
  1311 +FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_eq(FST0, FST1, &env->fpu->fp_status),
  1312 + float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_eq(FSTH0, FSTH1, &env->fpu->fp_status))
  1313 +FOP_COND_PS(lt, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_lt(FST0, FST1, &env->fpu->fp_status),
  1314 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_lt(FSTH0, FSTH1, &env->fpu->fp_status))
  1315 +FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_lt(FST0, FST1, &env->fpu->fp_status),
  1316 + float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_lt(FSTH0, FSTH1, &env->fpu->fp_status))
  1317 +FOP_COND_PS(le, !float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) && float32_le(FST0, FST1, &env->fpu->fp_status),
  1318 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) && float32_le(FSTH0, FSTH1, &env->fpu->fp_status))
  1319 +FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fpu->fp_status) || float32_le(FST0, FST1, &env->fpu->fp_status),
  1320 + float32_is_unordered(1, FSTH1, FSTH0, &env->fpu->fp_status) || float32_le(FSTH0, FSTH1, &env->fpu->fp_status))
... ...
target-mips/op_template.c
... ... @@ -21,31 +21,44 @@
21 21 #if defined(REG)
22 22 void glue(op_load_gpr_T0_gpr, REG) (void)
23 23 {
24   - T0 = env->gpr[REG];
  24 + T0 = env->gpr[REG][env->current_tc];
25 25 RETURN();
26 26 }
27 27  
28 28 void glue(op_store_T0_gpr_gpr, REG) (void)
29 29 {
30   - env->gpr[REG] = T0;
  30 + env->gpr[REG][env->current_tc] = T0;
31 31 RETURN();
32 32 }
33 33  
34 34 void glue(op_load_gpr_T1_gpr, REG) (void)
35 35 {
36   - T1 = env->gpr[REG];
  36 + T1 = env->gpr[REG][env->current_tc];
37 37 RETURN();
38 38 }
39 39  
40 40 void glue(op_store_T1_gpr_gpr, REG) (void)
41 41 {
42   - env->gpr[REG] = T1;
  42 + env->gpr[REG][env->current_tc] = T1;
43 43 RETURN();
44 44 }
45 45  
46 46 void glue(op_load_gpr_T2_gpr, REG) (void)
47 47 {
48   - T2 = env->gpr[REG];
  48 + T2 = env->gpr[REG][env->current_tc];
  49 + RETURN();
  50 +}
  51 +
  52 +
  53 +void glue(op_load_srsgpr_T0_gpr, REG) (void)
  54 +{
  55 + T0 = env->gpr[REG][(env->CP0_SRSCtl >> CP0SRSCtl_PSS) & 0xf];
  56 + RETURN();
  57 +}
  58 +
  59 +void glue(op_store_T0_srsgpr_gpr, REG) (void)
  60 +{
  61 + env->gpr[REG][(env->CP0_SRSCtl >> CP0SRSCtl_PSS) & 0xf] = T0;
49 62 RETURN();
50 63 }
51 64 #endif
... ...