trunk/src/emu/cpu/mips/mips3.h
| r31796 | r31797 | |
| 544 | 544 | void static_generate_tlb_mismatch(); |
| 545 | 545 | void static_generate_exception(UINT8 exception, int recover, const char *name); |
| 546 | 546 | void static_generate_memory_accessor(int mode, int size, int iswrite, int ismasked, const char *name, uml::code_handle **handleptr); |
| 547 | |
| 547 | 548 | void generate_update_mode(drcuml_block *block); |
| 548 | 549 | void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, int allow_exception); |
| 549 | 550 | void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); |
| 550 | 551 | void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); |
| 551 | 552 | void generate_delay_slot_and_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 linkreg); |
| 553 | |
| 552 | 554 | int generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); |
| 553 | 555 | int generate_special(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); |
| 554 | 556 | int generate_regimm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); |
| 555 | 557 | int generate_idt(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); |
| 558 | |
| 556 | 559 | int generate_set_cop0_reg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 reg); |
| 557 | 560 | int generate_get_cop0_reg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 reg); |
| 558 | 561 | int generate_cop0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); |
| 559 | 562 | int generate_cop1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); |
| 560 | 563 | int generate_cop1x(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); |
| 564 | |
| 565 | void check_cop0_access(drcuml_block *block); |
| 566 | void check_cop1_access(drcuml_block *block); |
| 567 | void generate_badcop(drcuml_block *block, const int cop); |
| 568 | |
| 561 | 569 | void log_add_disasm_comment(drcuml_block *block, UINT32 pc, UINT32 op); |
| 562 | 570 | const char *log_desc_flags_to_string(UINT32 flags); |
| 563 | 571 | void log_register_list(drcuml_state *drcuml, const char *string, const UINT32 *reglist, const UINT32 *regnostarlist); |
| r31796 | r31797 | |
| 743 | 751 | |
| 744 | 752 | /* fix me -- how do we make this work?? */ |
| 745 | 753 | #define MIPS3DRC_STRICT_VERIFY 0x0001 /* verify all instructions */ |
| 746 | | #define MIPS3DRC_STRICT_COP1 0x0002 /* validate all COP1 instructions */ |
| 747 | | #define MIPS3DRC_STRICT_COP2 0x0004 /* validate all COP2 instructions */ |
| 748 | | #define MIPS3DRC_FLUSH_PC 0x0008 /* flush the PC value before each memory access */ |
| 749 | | #define MIPS3DRC_CHECK_OVERFLOWS 0x0010 /* actually check overflows on add/sub instructions */ |
| 754 | #define MIPS3DRC_STRICT_COP0 0x0002 /* validate all COP0 instructions */ |
| 755 | #define MIPS3DRC_STRICT_COP1 0x0004 /* validate all COP1 instructions */ |
| 756 | #define MIPS3DRC_STRICT_COP2 0x0008 /* validate all COP2 instructions */ |
| 757 | #define MIPS3DRC_FLUSH_PC 0x0010 /* flush the PC value before each memory access */ |
| 758 | #define MIPS3DRC_CHECK_OVERFLOWS 0x0020 /* actually check overflows on add/sub instructions */ |
| 750 | 759 | |
| 751 | | #define MIPS3DRC_COMPATIBLE_OPTIONS (MIPS3DRC_STRICT_VERIFY | MIPS3DRC_STRICT_COP1 | MIPS3DRC_STRICT_COP2 | MIPS3DRC_FLUSH_PC) |
| 760 | #define MIPS3DRC_COMPATIBLE_OPTIONS (MIPS3DRC_STRICT_VERIFY | MIPS3DRC_STRICT_COP1 | MIPS3DRC_STRICT_COP0 | MIPS3DRC_STRICT_COP2 | MIPS3DRC_FLUSH_PC) |
| 752 | 761 | #define MIPS3DRC_FASTEST_OPTIONS (0) |
| 753 | 762 | |
| 754 | 763 | |
trunk/src/emu/cpu/mips/mips3drc.c
| r31796 | r31797 | |
| 1617 | 1617 | return TRUE; |
| 1618 | 1618 | |
| 1619 | 1619 | case 0x31: /* LWC1 - MIPS I */ |
| 1620 | | UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1 |
| 1621 | | UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1); // exh cop,1,Z |
| 1620 | check_cop1_access(block); |
| 1622 | 1621 | UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,<rsreg>,SIMMVAL |
| 1623 | 1622 | UML_CALLH(block, *m_read32[m_core->mode >> 1]); // callh read32 |
| 1624 | 1623 | UML_MOV(block, FPR32(RTREG), I0); // mov <cpr1_rt>,i0 |
| r31796 | r31797 | |
| 1627 | 1626 | return TRUE; |
| 1628 | 1627 | |
| 1629 | 1628 | case 0x35: /* LDC1 - MIPS III */ |
| 1630 | | UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1 |
| 1631 | | UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1); // exh cop,1,Z |
| 1629 | check_cop1_access(block); |
| 1632 | 1630 | UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,<rsreg>,SIMMVAL |
| 1633 | 1631 | UML_CALLH(block, *m_read64[m_core->mode >> 1]); // callh read64 |
| 1634 | 1632 | UML_DMOV(block, FPR64(RTREG), I0); // dmov <cpr1_rt>,i0 |
| r31796 | r31797 | |
| 1772 | 1770 | return TRUE; |
| 1773 | 1771 | |
| 1774 | 1772 | case 0x39: /* SWC1 - MIPS I */ |
| 1775 | | UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1 |
| 1776 | | UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1); // exh cop,1,Z |
| 1773 | check_cop1_access(block); |
| 1777 | 1774 | UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,<rsreg>,SIMMVAL |
| 1778 | 1775 | UML_MOV(block, I1, FPR32(RTREG)); // mov i1,<cpr1_rt> |
| 1779 | 1776 | UML_CALLH(block, *m_write32[m_core->mode >> 1]); // callh write32 |
| r31796 | r31797 | |
| 1782 | 1779 | return TRUE; |
| 1783 | 1780 | |
| 1784 | 1781 | case 0x3d: /* SDC1 - MIPS III */ |
| 1785 | | UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1 |
| 1786 | | UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1); // exh cop,1,Z |
| 1782 | check_cop1_access(block); |
| 1787 | 1783 | UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,<rsreg>,SIMMVAL |
| 1788 | 1784 | UML_DMOV(block, I1, FPR64(RTREG)); // dmov i1,<cpr1_rt> |
| 1789 | 1785 | UML_CALLH(block, *m_write64[m_core->mode >> 1]); // callh write64 |
| r31796 | r31797 | |
| 2480 | 2476 | } |
| 2481 | 2477 | |
| 2482 | 2478 | |
| 2479 | /*------------------------------------------------------------------------- |
| 2480 | generate_badcop - raise a BADCOP exception |
| 2481 | -------------------------------------------------------------------------*/ |
| 2482 | |
| 2483 | void mips3_device::generate_badcop(drcuml_block *block, const int cop) |
| 2484 | { |
| 2485 | UML_TEST(block, CPR032(COP0_Status), SR_COP0 << cop); // test [Status], SR_COP0 << cop |
| 2486 | UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], cop); // exh badcop,cop,Z |
| 2487 | } |
| 2488 | |
| 2489 | /*------------------------------------------------------------------------- |
| 2490 | check_cop0_access - raise a BADCOP exception if we're not in kernel mode |
| 2491 | -------------------------------------------------------------------------*/ |
| 2492 | |
| 2493 | void mips3_device::check_cop0_access(drcuml_block *block) |
| 2494 | { |
| 2495 | if ((m_core->mode >> 1) != MODE_KERNEL) |
| 2496 | { |
| 2497 | generate_badcop(block, 0); |
| 2498 | } |
| 2499 | } |
| 2500 | |
| 2483 | 2501 | /*------------------------------------------------- |
| 2484 | 2502 | generate_cop0 - compile COP0 opcodes |
| 2485 | 2503 | -------------------------------------------------*/ |
| r31796 | r31797 | |
| 2606 | 2624 | COP1 RECOMPILATION |
| 2607 | 2625 | ***************************************************************************/ |
| 2608 | 2626 | |
| 2627 | /*------------------------------------------------------------------------- |
| 2628 | check_cop1_access - raise a BADCOP exception if COP1 is not enabled |
| 2629 | -------------------------------------------------------------------------*/ |
| 2630 | |
| 2631 | void mips3_device::check_cop1_access(drcuml_block *block) |
| 2632 | { |
| 2633 | if (m_drcoptions & MIPS3DRC_STRICT_COP1) |
| 2634 | { |
| 2635 | generate_badcop(block, 1); |
| 2636 | } |
| 2637 | } |
| 2638 | |
| 2609 | 2639 | /*------------------------------------------------- |
| 2610 | 2640 | generate_cop1 - compile COP1 opcodes |
| 2611 | 2641 | -------------------------------------------------*/ |
| r31796 | r31797 | |
| 2616 | 2646 | code_label skip; |
| 2617 | 2647 | condition_t condition; |
| 2618 | 2648 | |
| 2619 | | /* generate an exception if COP1 is disabled */ |
| 2620 | | if (m_drcoptions & MIPS3DRC_STRICT_COP1) |
| 2621 | | { |
| 2622 | | UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1 |
| 2623 | | UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1);// exh cop,1,Z |
| 2624 | | } |
| 2649 | check_cop1_access(block); |
| 2625 | 2650 | |
| 2626 | 2651 | switch (RSREG) |
| 2627 | 2652 | { |
| 2628 | | case 0x00: /* MFCz - MIPS I */ |
| 2653 | case 0x00: /* MFC1 - MIPS I */ |
| 2629 | 2654 | if (RTREG != 0) |
| 2630 | 2655 | UML_DSEXT(block, R64(RTREG), FPR32(RDREG), SIZE_DWORD); // dsext <rtreg>,fpr[rdreg],dword |
| 2631 | 2656 | return TRUE; |
| 2632 | 2657 | |
| 2633 | | case 0x01: /* DMFCz - MIPS III */ |
| 2658 | case 0x01: /* DMFC1 - MIPS III */ |
| 2634 | 2659 | if (RTREG != 0) |
| 2635 | 2660 | UML_DMOV(block, R64(RTREG), FPR64(RDREG)); // dmov <rtreg>,fpr[rdreg] |
| 2636 | 2661 | return TRUE; |
| 2637 | 2662 | |
| 2638 | | case 0x02: /* CFCz - MIPS I */ |
| 2663 | case 0x02: /* CFC1 - MIPS I */ |
| 2639 | 2664 | if (RTREG != 0) |
| 2640 | 2665 | UML_DSEXT(block, R64(RTREG), CCR132(RDREG), SIZE_DWORD); // dsext <rtreg>,ccr132[rdreg],dword |
| 2641 | 2666 | return TRUE; |
| 2642 | 2667 | |
| 2643 | | case 0x04: /* MTCz - MIPS I */ |
| 2668 | case 0x04: /* MTC1 - MIPS I */ |
| 2644 | 2669 | UML_MOV(block, FPR32(RDREG), R32(RTREG)); // mov fpr[rdreg],<rtreg> |
| 2645 | 2670 | return TRUE; |
| 2646 | 2671 | |
| 2647 | | case 0x05: /* DMTCz - MIPS III */ |
| 2672 | case 0x05: /* DMTC1 - MIPS III */ |
| 2648 | 2673 | UML_DMOV(block, FPR64(RDREG), R64(RTREG)); // dmov fpr[rdreg],<rtreg> |
| 2649 | 2674 | return TRUE; |
| 2650 | 2675 | |
| 2651 | | case 0x06: /* CTCz - MIPS I */ |
| 2676 | case 0x06: /* CTC1 - MIPS I */ |
| 2652 | 2677 | if (RDREG != 31) |
| 2653 | 2678 | UML_DSEXT(block, CCR164(RDREG), R32(RTREG), SIZE_DWORD); // dsext ccr1[rdreg],<rtreg>,dword |
| 2654 | 2679 | else |
| r31796 | r31797 | |
| 2991 | 3016 | int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); |
| 2992 | 3017 | UINT32 op = desc->opptr.l[0]; |
| 2993 | 3018 | |
| 2994 | | if (m_drcoptions & MIPS3DRC_STRICT_COP1) |
| 2995 | | { |
| 2996 | | UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1 |
| 2997 | | UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1);// exh cop,1,Z |
| 2998 | | } |
| 3019 | check_cop1_access(block); |
| 2999 | 3020 | |
| 3000 | 3021 | switch (op & 0x3f) |
| 3001 | 3022 | { |