1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - r4300.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25 #include "api/m64p_types.h"
26 #include "api/callbacks.h"
27 #include "api/debugger.h"
28 #include "memory/memory.h"
29 #include "main/main.h"
34 #include "exception.h"
39 #include "new_dynarec/new_dynarec.h"
42 #include "debugger/dbg_types.h"
43 #include "debugger/debugger.h"
46 unsigned int r4300emu = 0;
47 int no_compiled_jump = 0;
49 #if NEW_DYNAREC != NEW_DYNAREC_ARM
51 long long int reg[32], hi, lo;
52 unsigned int reg_cop0[32];
53 float *reg_cop1_simple[32];
54 double *reg_cop1_double[32];
56 unsigned int next_interupt;
59 long long int local_rs;
60 long long int reg_cop1_fgr_64[32];
62 unsigned int delay_slot, skip_jump = 0, dyna_interp = 0, last_addr;
63 unsigned long long int debug_count = 0;
64 unsigned int CIC_Chip;
65 char invalid_code[0x100000];
67 precomp_block *blocks[0x100000], *actual;
68 int rounding_mode = 0x33F, trunc_mode = 0xF3F, round_mode = 0x33F,
69 ceil_mode = 0xB3F, floor_mode = 0x73F;
71 // -----------------------------------------------------------
72 // Cached interpreter functions (and fallback for dynarec).
73 // -----------------------------------------------------------
75 #define UPDATE_DEBUGGER() if (g_DebuggerActive) update_debugger(PC->addr)
77 #define UPDATE_DEBUGGER() do { } while(0)
80 #define PCADDR PC->addr
81 #define ADD_TO_PC(x) PC += x;
82 #define DECLARE_INSTRUCTION(name) static void name(void)
84 #define DECLARE_JUMP(name, destination, condition, link, likely, cop1) \
85 static void name(void) \
87 const int take_jump = (condition); \
88 const unsigned int jump_target = (destination); \
89 long long int *link_register = (link); \
90 if (cop1 && check_cop1_unusable()) return; \
91 if (!likely || take_jump) \
99 if (take_jump && !skip_jump) \
101 if (link_register != ®[0]) \
103 *link_register=PC->addr; \
104 sign_extended(*link_register); \
106 PC=actual->block+((jump_target-actual->start)>>2); \
114 last_addr = PC->addr; \
115 if (next_interupt <= Count) gen_interupt(); \
117 static void name##_OUT(void) \
119 const int take_jump = (condition); \
120 const unsigned int jump_target = (destination); \
121 long long int *link_register = (link); \
122 if (cop1 && check_cop1_unusable()) return; \
123 if (!likely || take_jump) \
131 if (take_jump && !skip_jump) \
133 if (link_register != ®[0]) \
135 *link_register=PC->addr; \
136 sign_extended(*link_register); \
138 jump_to(jump_target); \
146 last_addr = PC->addr; \
147 if (next_interupt <= Count) gen_interupt(); \
149 static void name##_IDLE(void) \
151 const int take_jump = (condition); \
153 if (cop1 && check_cop1_unusable()) return; \
157 skip = next_interupt - Count; \
158 if (skip > 3) Count += (skip & 0xFFFFFFFC); \
164 #define CHECK_MEMORY() \
165 if (!invalid_code[address>>12]) \
166 if (blocks[address>>12]->block[(address&0xFFF)/4].ops != \
167 current_instruction_table.NOTCOMPILED) \
168 invalid_code[address>>12] = 1;
170 #include "interpreter.def"
172 // two functions are defined from the macros above but never used
173 // these prototype declarations will prevent a warning
174 #if defined(__GNUC__)
175 void JR_IDLE(void) __attribute__((used));
176 void JALR_IDLE(void) __attribute__((used));
179 // -----------------------------------------------------------
180 // Flow control 'fake' instructions
181 // -----------------------------------------------------------
182 static void FIN_BLOCK(void)
186 jump_to((PC-1)->addr+4);
188 if (g_DebuggerActive) update_debugger(PC->addr);
190 Used by dynarec only, check should be unnecessary
193 if (r4300emu == CORE_DYNAREC) dyna_jump();
197 precomp_block *blk = actual;
198 precomp_instr *inst = PC;
199 jump_to((PC-1)->addr+4);
202 if (g_DebuggerActive) update_debugger(PC->addr);
204 Used by dynarec only, check should be unnecessary
215 if (r4300emu == CORE_DYNAREC) dyna_jump();
219 static void NOTCOMPILED(void)
221 unsigned int *mem = fast_mem_access(blocks[PC->addr>>12]->start);
223 DebugMessage(M64MSG_INFO, "NOTCOMPILED: addr = %x ops = %lx", PC->addr, (long) PC->ops);
227 recompile_block((int *)mem, blocks[PC->addr >> 12], PC->addr);
229 DebugMessage(M64MSG_ERROR, "not compiled exception");
232 if (g_DebuggerActive) update_debugger(PC->addr);
234 The preceeding update_debugger SHOULD be unnecessary since it should have been
235 called before NOTCOMPILED would have been executed
238 if (r4300emu == CORE_DYNAREC)
242 static void NOTCOMPILED2(void)
247 // -----------------------------------------------------------
248 // Cached interpreter instruction table
249 // -----------------------------------------------------------
250 const cpu_instruction_table cached_interpreter_table = {
323 // Use the _OUT versions of JR and JALR, since we don't know
324 // until runtime if they're going to jump inside or outside the block
529 cpu_instruction_table current_instruction_table;
531 static unsigned int update_invalid_addr(unsigned int addr)
533 if (addr >= 0x80000000 && addr < 0xa0000000)
535 if (invalid_code[addr>>12]) invalid_code[(addr+0x20000000)>>12] = 1;
536 if (invalid_code[(addr+0x20000000)>>12]) invalid_code[addr>>12] = 1;
539 else if (addr >= 0xa0000000 && addr < 0xc0000000)
541 if (invalid_code[addr>>12]) invalid_code[(addr-0x20000000)>>12] = 1;
542 if (invalid_code[(addr-0x20000000)>>12]) invalid_code[addr>>12] = 1;
547 unsigned int paddr = virtual_to_physical_address(addr, 2);
550 unsigned int beg_paddr = paddr - (addr - (addr&~0xFFF));
551 update_invalid_addr(paddr);
552 if (invalid_code[(beg_paddr+0x000)>>12]) invalid_code[addr>>12] = 1;
553 if (invalid_code[(beg_paddr+0xFFC)>>12]) invalid_code[addr>>12] = 1;
554 if (invalid_code[addr>>12]) invalid_code[(beg_paddr+0x000)>>12] = 1;
555 if (invalid_code[addr>>12]) invalid_code[(beg_paddr+0xFFC)>>12] = 1;
561 #define addr jump_to_address
562 unsigned int jump_to_address;
563 void jump_to_func(void)
566 if (skip_jump) return;
567 paddr = update_invalid_addr(addr);
569 actual = blocks[addr>>12];
570 if (invalid_code[addr>>12])
572 if (!blocks[addr>>12])
574 blocks[addr>>12] = (precomp_block *) malloc(sizeof(precomp_block));
575 actual = blocks[addr>>12];
576 blocks[addr>>12]->code = NULL;
577 blocks[addr>>12]->block = NULL;
578 blocks[addr>>12]->jumps_table = NULL;
579 blocks[addr>>12]->riprel_table = NULL;
581 blocks[addr>>12]->start = addr & ~0xFFF;
582 blocks[addr>>12]->end = (addr & ~0xFFF) + 0x1000;
583 init_block(blocks[addr>>12]);
585 PC=actual->block+((addr-actual->start)>>2);
587 if (r4300emu == CORE_DYNAREC) dyna_jump();
591 void generic_jump_to(unsigned int address)
593 if (r4300emu == CORE_PURE_INTERPRETER)
597 if (r4300emu == CORE_DYNAREC)
607 /* Refer to Figure 6-2 on page 155 and explanation on page B-11
608 of MIPS R4000 Microprocessor User's Manual (Second Edition)
611 void shuffle_fpr_data(int oldStatus, int newStatus)
613 #if defined(M64P_BIG_ENDIAN)
614 const int isBigEndian = 1;
616 const int isBigEndian = 0;
619 if ((newStatus & 0x04000000) != (oldStatus & 0x04000000))
624 // pack or unpack the FGR register data
625 if (newStatus & 0x04000000)
626 { // switching into 64-bit mode
627 // retrieve 32 FPR values from packed 32-bit FGR registers
628 for (i = 0; i < 32; i++)
630 temp_fgr_32[i] = *((int *) ®_cop1_fgr_64[i>>1] + ((i & 1) ^ isBigEndian));
632 // unpack them into 32 64-bit registers, taking the high 32-bits from their temporary place in the upper 16 FGRs
633 for (i = 0; i < 32; i++)
635 int high32 = *((int *) ®_cop1_fgr_64[(i>>1)+16] + (i & 1));
636 *((int *) ®_cop1_fgr_64[i] + isBigEndian) = temp_fgr_32[i];
637 *((int *) ®_cop1_fgr_64[i] + (isBigEndian^1)) = high32;
641 { // switching into 32-bit mode
642 // retrieve the high 32 bits from each 64-bit FGR register and store in temp array
643 for (i = 0; i < 32; i++)
645 temp_fgr_32[i] = *((int *) ®_cop1_fgr_64[i] + (isBigEndian^1));
647 // take the low 32 bits from each register and pack them together into 64-bit pairs
648 for (i = 0; i < 16; i++)
650 unsigned int least32 = *((unsigned int *) ®_cop1_fgr_64[i*2] + isBigEndian);
651 unsigned int most32 = *((unsigned int *) ®_cop1_fgr_64[i*2+1] + isBigEndian);
652 reg_cop1_fgr_64[i] = ((unsigned long long) most32 << 32) | (unsigned long long) least32;
654 // store the high bits in the upper 16 FGRs, which wont be accessible in 32-bit mode
655 for (i = 0; i < 32; i++)
657 *((int *) ®_cop1_fgr_64[(i>>1)+16] + (i & 1)) = temp_fgr_32[i];
663 void set_fpr_pointers(int newStatus)
666 #if defined(M64P_BIG_ENDIAN)
667 const int isBigEndian = 1;
669 const int isBigEndian = 0;
672 // update the FPR register pointers
673 if (newStatus & 0x04000000)
675 for (i = 0; i < 32; i++)
677 reg_cop1_double[i] = (double*) ®_cop1_fgr_64[i];
678 reg_cop1_simple[i] = ((float*) ®_cop1_fgr_64[i]) + isBigEndian;
683 for (i = 0; i < 32; i++)
685 reg_cop1_double[i] = (double*) ®_cop1_fgr_64[i>>1];
686 reg_cop1_simple[i] = ((float*) ®_cop1_fgr_64[i>>1]) + ((i & 1) ^ isBigEndian);
691 int check_cop1_unusable(void)
693 if (!(Status & 0x20000000))
695 Cause = (11 << 2) | 0x10000000;
702 void update_count(void)
705 if (r4300emu != CORE_DYNAREC)
708 Count = Count + (PC->addr - last_addr)/2;
709 last_addr = PC->addr;
716 CoreCompareCallback();
719 if (g_DebuggerActive && !delay_slot) update_debugger(PC->addr);
724 void init_blocks(void)
727 for (i=0; i<0x100000; i++)
734 void free_blocks(void)
737 for (i=0; i<0x100000; i++)
741 free_block(blocks[i]);
748 /* this hard reset function simulates the boot-up state of the R4300 CPU */
749 void r4300_reset_hard(void)
753 // clear r4300 registers and TLB entries
754 for (i = 0; i < 32; i++)
758 reg_cop1_fgr_64[i]=0;
760 // --------------tlb------------------------
774 //tlb_e[i].check_parity_mask=0x1000;
776 tlb_e[i].start_even=0;
778 tlb_e[i].phys_even=0;
779 tlb_e[i].start_odd=0;
783 for (i=0; i<0x100000; i++)
794 // set COP0 registers
797 set_fpr_pointers(Status);
804 BadVAddr = 0xFFFFFFFF;
805 ErrorEPC = 0xFFFFFFFF;
807 rounding_mode = 0x33F;
810 /* this soft reset function simulates the actions of the PIF ROM, which may vary by region
811 * TODO: accurately simulate the effects of the PIF ROM in the case of a soft reset
812 * (e.g. Goldeneye crashes) */
813 void r4300_reset_soft(void)
818 // copy boot code from ROM to SP_DMEM
819 memcpy((char *)SP_DMEM+0x40, rom+0x40, 0xFC0);
821 // the following values are extracted from the pj64 source code
822 // thanks to Zilmar and Jabo
824 reg[6] = 0xFFFFFFFFA4001F0CLL;
825 reg[7] = 0xFFFFFFFFA4001F08LL;
826 reg[8] = 0x00000000000000C0LL;
827 reg[10]= 0x0000000000000040LL;
828 reg[11]= 0xFFFFFFFFA4000040LL;
829 reg[29]= 0xFFFFFFFFA4001FF0LL;
831 // figure out which ROM type is loaded
832 for (i = 0x40/4; i < (0x1000/4); i++)
835 case 0x000000D0027FDF31LL:
836 case 0x000000CFFB631223LL:
839 case 0x000000D057C85244LL:
842 case 0x000000D6497E414BLL:
845 case 0x0000011A49F60E96LL:
848 case 0x000000D6D5BE5580LL:
855 switch(ROM_PARAMS.systemtype)
860 reg[5] = 0xFFFFFFFFC0F1D859LL;
861 reg[14]= 0x000000002DE108EALL;
864 reg[5] = 0xFFFFFFFFD4646273LL;
865 reg[14]= 0x000000001AF99984LL;
868 SP_IMEM[1] = 0xBDA807FC;
869 reg[5] = 0xFFFFFFFFDECAAAD1LL;
870 reg[14]= 0x000000000CF85C13LL;
871 reg[24]= 0x0000000000000002LL;
874 reg[5] = 0xFFFFFFFFB04DC903LL;
875 reg[14]= 0x000000001AF99984LL;
876 reg[24]= 0x0000000000000002LL;
879 reg[23]= 0x0000000000000006LL;
880 reg[31]= 0xFFFFFFFFA4001554LL;
886 reg[5] = 0xFFFFFFFFC95973D5LL;
887 reg[14]= 0x000000002449A366LL;
890 reg[5] = 0xFFFFFFFF95315A28LL;
891 reg[14]= 0x000000005BACA1DFLL;
894 SP_IMEM[1] = 0x8DA807FC;
895 reg[5] = 0x000000005493FB9ALL;
896 reg[14]= 0xFFFFFFFFC2C20384LL;
899 reg[5] = 0xFFFFFFFFE067221FLL;
900 reg[14]= 0x000000005CD2B70FLL;
903 reg[20]= 0x0000000000000001LL;
904 reg[24]= 0x0000000000000003LL;
905 reg[31]= 0xFFFFFFFFA4001550LL;
909 reg[22]= 0x000000000000003FLL;
912 reg[1] = 0x0000000000000001LL;
913 reg[2] = 0x000000000EBDA536LL;
914 reg[3] = 0x000000000EBDA536LL;
915 reg[4] = 0x000000000000A536LL;
916 reg[12]= 0xFFFFFFFFED10D0B3LL;
917 reg[13]= 0x000000001402A4CCLL;
918 reg[15]= 0x000000003103E121LL;
919 reg[22]= 0x000000000000003FLL;
920 reg[25]= 0xFFFFFFFF9DEBB54FLL;
923 reg[1] = 0x0000000000000001LL;
924 reg[2] = 0x0000000049A5EE96LL;
925 reg[3] = 0x0000000049A5EE96LL;
926 reg[4] = 0x000000000000EE96LL;
927 reg[12]= 0xFFFFFFFFCE9DFBF7LL;
928 reg[13]= 0xFFFFFFFFCE9DFBF7LL;
929 reg[15]= 0x0000000018B63D28LL;
930 reg[22]= 0x0000000000000078LL;
931 reg[25]= 0xFFFFFFFF825B21C9LL;
934 SP_IMEM[0] = 0x3C0DBFC0;
935 SP_IMEM[2] = 0x25AD07C0;
936 SP_IMEM[3] = 0x31080080;
937 SP_IMEM[4] = 0x5500FFFC;
938 SP_IMEM[5] = 0x3C0DBFC0;
939 SP_IMEM[6] = 0x8DA80024;
940 SP_IMEM[7] = 0x3C0BB000;
941 reg[2] = 0xFFFFFFFFF58B0FBFLL;
942 reg[3] = 0xFFFFFFFFF58B0FBFLL;
943 reg[4] = 0x0000000000000FBFLL;
944 reg[12]= 0xFFFFFFFF9651F81ELL;
945 reg[13]= 0x000000002D42AAC5LL;
946 reg[15]= 0x0000000056584D60LL;
947 reg[22]= 0x0000000000000091LL;
948 reg[25]= 0xFFFFFFFFCDCE565FLL;
951 reg[2] = 0xFFFFFFFFA95930A4LL;
952 reg[3] = 0xFFFFFFFFA95930A4LL;
953 reg[4] = 0x00000000000030A4LL;
954 reg[12]= 0xFFFFFFFFBCB59510LL;
955 reg[13]= 0xFFFFFFFFBCB59510LL;
956 reg[15]= 0x000000007A3C07F4LL;
957 reg[22]= 0x0000000000000085LL;
958 reg[25]= 0x00000000465E3F72LL;
965 static void dynarec_setup_code(void)
967 // The dynarec jumps here after we call dyna_start and it prepares
968 // Here we need to prepare the initial code block and jump to it
971 // Prevent segfault on failed jump_to
972 if (!actual->block || !actual->code)
977 void r4300_execute(void)
979 #if defined(COUNT_INSTR) || (defined(DYNAREC) && defined(PROFILE_R4300))
983 current_instruction_table = cached_interpreter_table;
990 /* clear instruction counters */
991 #if defined(COUNT_INSTR)
992 for (i = 0; i < 131; i++)
996 last_addr = 0xa4000040;
997 next_interupt = 624999;
1000 if (r4300emu == CORE_PURE_INTERPRETER)
1002 DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Pure Interpreter");
1003 r4300emu = CORE_PURE_INTERPRETER;
1006 #if defined(DYNAREC)
1007 else if (r4300emu >= 2)
1009 DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Dynamic Recompiler");
1010 r4300emu = CORE_DYNAREC;
1016 new_dynarec_cleanup();
1018 dyna_start(dynarec_setup_code);
1021 #if defined(PROFILE_R4300)
1022 pfProfile = fopen("instructionaddrs.dat", "ab");
1023 for (i=0; i<0x100000; i++)
1024 if (invalid_code[i] == 0 && blocks[i] != NULL && blocks[i]->code != NULL && blocks[i]->block != NULL)
1026 unsigned char *x86addr;
1028 // store final code length for this block
1029 mipsop = -1; /* -1 == end of x86 code block */
1030 x86addr = blocks[i]->code + blocks[i]->code_length;
1031 if (fwrite(&mipsop, 1, 4, pfProfile) != 4 ||
1032 fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *))
1033 DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
1041 else /* if (r4300emu == CORE_INTERPRETER) */
1043 DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Cached Interpreter");
1044 r4300emu = CORE_INTERPRETER;
1046 jump_to(0xa4000040);
1048 /* Prevent segfault on failed jump_to */
1052 last_addr = PC->addr;
1056 if (PC->ops == FIN_BLOCK && (PC->addr < 0x80000000 || PC->addr >= 0xc0000000))
1057 virtual_to_physical_address(PC->addr, 2);
1058 CoreCompareCallback();
1061 if (g_DebuggerActive) update_debugger(PC->addr);
1069 debug_count+= Count;
1070 DebugMessage(M64MSG_INFO, "R4300 emulator finished.");
1072 /* print instruction counts */
1073 #if defined(COUNT_INSTR)
1074 if (r4300emu == CORE_DYNAREC)
1076 unsigned int iTypeCount[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1077 unsigned int iTotal = 0;
1078 char line[128], param[24];
1079 DebugMessage(M64MSG_INFO, "Instruction counters:");
1081 for (i = 0; i < 131; i++)
1083 sprintf(param, "%8s: %08i ", instr_name[i], instr_count[i]);
1084 strcat(line, param);
1087 DebugMessage(M64MSG_INFO, "%s", line);
1090 iTypeCount[instr_type[i]] += instr_count[i];
1091 iTotal += instr_count[i];
1093 DebugMessage(M64MSG_INFO, "Instruction type summary (total instructions = %i)", iTotal);
1094 for (i = 0; i < 11; i++)
1096 DebugMessage(M64MSG_INFO, "%20s: %04.1f%% (%i)", instr_typename[i], (float) iTypeCount[i] * 100.0 / iTotal, iTypeCount[i]);