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