Commit ead9360e2fbcaae10a8ca3d8bfed885422205dca
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
Showing
15 changed files
with
1433 additions
and
536 deletions
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 | ... | ... |