ALL: Huge upstream synch + PerRom DelaySI & CountPerOp parameters
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / r4300.c
CommitLineData
451ab91e 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - r4300.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
5 * *
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. *
10 * *
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. *
15 * *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22#include <stdlib.h>
23#include <string.h>
24
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"
30#include "main/rom.h"
31
32#include "r4300.h"
33#include "ops.h"
34#include "exception.h"
35#include "interupt.h"
36#include "macros.h"
37#include "recomp.h"
38#include "recomph.h"
39#include "new_dynarec/new_dynarec.h"
40
41#ifdef DBG
42#include "debugger/dbg_types.h"
43#include "debugger/debugger.h"
44#endif
45
46unsigned int r4300emu = 0;
47int no_compiled_jump = 0;
2d262872 48unsigned int count_per_op = 2;
451ab91e 49int llbit, rompause;
50#if NEW_DYNAREC != NEW_DYNAREC_ARM
51int stop;
52long long int reg[32], hi, lo;
53unsigned int reg_cop0[32];
54float *reg_cop1_simple[32];
55double *reg_cop1_double[32];
56int FCR0, FCR31;
57unsigned int next_interupt;
58precomp_instr *PC;
59#endif
60long long int local_rs;
61long long int reg_cop1_fgr_64[32];
62tlb tlb_e[32];
63unsigned int delay_slot, skip_jump = 0, dyna_interp = 0, last_addr;
451ab91e 64unsigned int CIC_Chip;
65char invalid_code[0x100000];
66
67precomp_block *blocks[0x100000], *actual;
68int rounding_mode = 0x33F, trunc_mode = 0xF3F, round_mode = 0x33F,
69 ceil_mode = 0xB3F, floor_mode = 0x73F;
70
71// -----------------------------------------------------------
72// Cached interpreter functions (and fallback for dynarec).
73// -----------------------------------------------------------
74#ifdef DBG
75#define UPDATE_DEBUGGER() if (g_DebuggerActive) update_debugger(PC->addr)
76#else
77#define UPDATE_DEBUGGER() do { } while(0)
78#endif
79
80#define PCADDR PC->addr
81#define ADD_TO_PC(x) PC += x;
82#define DECLARE_INSTRUCTION(name) static void name(void)
83
84#define DECLARE_JUMP(name, destination, condition, link, likely, cop1) \
85 static void name(void) \
86 { \
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) \
92 { \
93 PC++; \
94 delay_slot=1; \
95 UPDATE_DEBUGGER(); \
96 PC->ops(); \
97 update_count(); \
98 delay_slot=0; \
99 if (take_jump && !skip_jump) \
100 { \
101 if (link_register != &reg[0]) \
102 { \
103 *link_register=PC->addr; \
104 sign_extended(*link_register); \
105 } \
106 PC=actual->block+((jump_target-actual->start)>>2); \
107 } \
108 } \
109 else \
110 { \
111 PC += 2; \
112 update_count(); \
113 } \
114 last_addr = PC->addr; \
115 if (next_interupt <= Count) gen_interupt(); \
116 } \
117 static void name##_OUT(void) \
118 { \
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) \
124 { \
125 PC++; \
126 delay_slot=1; \
127 UPDATE_DEBUGGER(); \
128 PC->ops(); \
129 update_count(); \
130 delay_slot=0; \
131 if (take_jump && !skip_jump) \
132 { \
133 if (link_register != &reg[0]) \
134 { \
135 *link_register=PC->addr; \
136 sign_extended(*link_register); \
137 } \
138 jump_to(jump_target); \
139 } \
140 } \
141 else \
142 { \
143 PC += 2; \
144 update_count(); \
145 } \
146 last_addr = PC->addr; \
147 if (next_interupt <= Count) gen_interupt(); \
148 } \
149 static void name##_IDLE(void) \
150 { \
151 const int take_jump = (condition); \
152 int skip; \
153 if (cop1 && check_cop1_unusable()) return; \
154 if (take_jump) \
155 { \
156 update_count(); \
157 skip = next_interupt - Count; \
158 if (skip > 3) Count += (skip & 0xFFFFFFFC); \
159 else name(); \
160 } \
161 else name(); \
162 }
163
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;
169
170#include "interpreter.def"
171
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));
177#endif
178
179// -----------------------------------------------------------
180// Flow control 'fake' instructions
181// -----------------------------------------------------------
182static void FIN_BLOCK(void)
183{
184 if (!delay_slot)
185 {
186 jump_to((PC-1)->addr+4);
187/*#ifdef DBG
188 if (g_DebuggerActive) update_debugger(PC->addr);
189#endif
190Used by dynarec only, check should be unnecessary
191*/
192 PC->ops();
193 if (r4300emu == CORE_DYNAREC) dyna_jump();
194 }
195 else
196 {
197 precomp_block *blk = actual;
198 precomp_instr *inst = PC;
199 jump_to((PC-1)->addr+4);
200
201/*#ifdef DBG
202 if (g_DebuggerActive) update_debugger(PC->addr);
203#endif
204Used by dynarec only, check should be unnecessary
205*/
206 if (!skip_jump)
207 {
208 PC->ops();
209 actual = blk;
210 PC = inst+1;
211 }
212 else
213 PC->ops();
214
215 if (r4300emu == CORE_DYNAREC) dyna_jump();
216 }
217}
218
219static void NOTCOMPILED(void)
220{
221 unsigned int *mem = fast_mem_access(blocks[PC->addr>>12]->start);
222#ifdef CORE_DBG
223 DebugMessage(M64MSG_INFO, "NOTCOMPILED: addr = %x ops = %lx", PC->addr, (long) PC->ops);
224#endif
225
226 if (mem != NULL)
227 recompile_block((int *)mem, blocks[PC->addr >> 12], PC->addr);
228 else
229 DebugMessage(M64MSG_ERROR, "not compiled exception");
230
231/*#ifdef DBG
232 if (g_DebuggerActive) update_debugger(PC->addr);
233#endif
234The preceeding update_debugger SHOULD be unnecessary since it should have been
235called before NOTCOMPILED would have been executed
236*/
237 PC->ops();
238 if (r4300emu == CORE_DYNAREC)
239 dyna_jump();
240}
241
242static void NOTCOMPILED2(void)
243{
244 NOTCOMPILED();
245}
246
247// -----------------------------------------------------------
248// Cached interpreter instruction table
249// -----------------------------------------------------------
250const cpu_instruction_table cached_interpreter_table = {
251 LB,
252 LBU,
253 LH,
254 LHU,
255 LW,
256 LWL,
257 LWR,
258 SB,
259 SH,
260 SW,
261 SWL,
262 SWR,
263
264 LD,
265 LDL,
266 LDR,
267 LL,
268 LWU,
269 SC,
270 SD,
271 SDL,
272 SDR,
273 SYNC,
274
275 ADDI,
276 ADDIU,
277 SLTI,
278 SLTIU,
279 ANDI,
280 ORI,
281 XORI,
282 LUI,
283
284 DADDI,
285 DADDIU,
286
287 ADD,
288 ADDU,
289 SUB,
290 SUBU,
291 SLT,
292 SLTU,
293 AND,
294 OR,
295 XOR,
296 NOR,
297
298 DADD,
299 DADDU,
300 DSUB,
301 DSUBU,
302
303 MULT,
304 MULTU,
305 DIV,
306 DIVU,
307 MFHI,
308 MTHI,
309 MFLO,
310 MTLO,
311
312 DMULT,
313 DMULTU,
314 DDIV,
315 DDIVU,
316
317 J,
318 J_OUT,
319 J_IDLE,
320 JAL,
321 JAL_OUT,
322 JAL_IDLE,
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
325 JR_OUT,
326 JALR_OUT,
327 BEQ,
328 BEQ_OUT,
329 BEQ_IDLE,
330 BNE,
331 BNE_OUT,
332 BNE_IDLE,
333 BLEZ,
334 BLEZ_OUT,
335 BLEZ_IDLE,
336 BGTZ,
337 BGTZ_OUT,
338 BGTZ_IDLE,
339 BLTZ,
340 BLTZ_OUT,
341 BLTZ_IDLE,
342 BGEZ,
343 BGEZ_OUT,
344 BGEZ_IDLE,
345 BLTZAL,
346 BLTZAL_OUT,
347 BLTZAL_IDLE,
348 BGEZAL,
349 BGEZAL_OUT,
350 BGEZAL_IDLE,
351
352 BEQL,
353 BEQL_OUT,
354 BEQL_IDLE,
355 BNEL,
356 BNEL_OUT,
357 BNEL_IDLE,
358 BLEZL,
359 BLEZL_OUT,
360 BLEZL_IDLE,
361 BGTZL,
362 BGTZL_OUT,
363 BGTZL_IDLE,
364 BLTZL,
365 BLTZL_OUT,
366 BLTZL_IDLE,
367 BGEZL,
368 BGEZL_OUT,
369 BGEZL_IDLE,
370 BLTZALL,
371 BLTZALL_OUT,
372 BLTZALL_IDLE,
373 BGEZALL,
374 BGEZALL_OUT,
375 BGEZALL_IDLE,
376 BC1TL,
377 BC1TL_OUT,
378 BC1TL_IDLE,
379 BC1FL,
380 BC1FL_OUT,
381 BC1FL_IDLE,
382
383 SLL,
384 SRL,
385 SRA,
386 SLLV,
387 SRLV,
388 SRAV,
389
390 DSLL,
391 DSRL,
392 DSRA,
393 DSLLV,
394 DSRLV,
395 DSRAV,
396 DSLL32,
397 DSRL32,
398 DSRA32,
399
400 MTC0,
401 MFC0,
402
403 TLBR,
404 TLBWI,
405 TLBWR,
406 TLBP,
407 CACHE,
408 ERET,
409
410 LWC1,
411 SWC1,
412 MTC1,
413 MFC1,
414 CTC1,
415 CFC1,
416 BC1T,
417 BC1T_OUT,
418 BC1T_IDLE,
419 BC1F,
420 BC1F_OUT,
421 BC1F_IDLE,
422
423 DMFC1,
424 DMTC1,
425 LDC1,
426 SDC1,
427
428 CVT_S_D,
429 CVT_S_W,
430 CVT_S_L,
431 CVT_D_S,
432 CVT_D_W,
433 CVT_D_L,
434 CVT_W_S,
435 CVT_W_D,
436 CVT_L_S,
437 CVT_L_D,
438
439 ROUND_W_S,
440 ROUND_W_D,
441 ROUND_L_S,
442 ROUND_L_D,
443
444 TRUNC_W_S,
445 TRUNC_W_D,
446 TRUNC_L_S,
447 TRUNC_L_D,
448
449 CEIL_W_S,
450 CEIL_W_D,
451 CEIL_L_S,
452 CEIL_L_D,
453
454 FLOOR_W_S,
455 FLOOR_W_D,
456 FLOOR_L_S,
457 FLOOR_L_D,
458
459 ADD_S,
460 ADD_D,
461
462 SUB_S,
463 SUB_D,
464
465 MUL_S,
466 MUL_D,
467
468 DIV_S,
469 DIV_D,
470
471 ABS_S,
472 ABS_D,
473
474 MOV_S,
475 MOV_D,
476
477 NEG_S,
478 NEG_D,
479
480 SQRT_S,
481 SQRT_D,
482
483 C_F_S,
484 C_F_D,
485 C_UN_S,
486 C_UN_D,
487 C_EQ_S,
488 C_EQ_D,
489 C_UEQ_S,
490 C_UEQ_D,
491 C_OLT_S,
492 C_OLT_D,
493 C_ULT_S,
494 C_ULT_D,
495 C_OLE_S,
496 C_OLE_D,
497 C_ULE_S,
498 C_ULE_D,
499 C_SF_S,
500 C_SF_D,
501 C_NGLE_S,
502 C_NGLE_D,
503 C_SEQ_S,
504 C_SEQ_D,
505 C_NGL_S,
506 C_NGL_D,
507 C_LT_S,
508 C_LT_D,
509 C_NGE_S,
510 C_NGE_D,
511 C_LE_S,
512 C_LE_D,
513 C_NGT_S,
514 C_NGT_D,
515
516 SYSCALL,
517
518 TEQ,
519
520 NOP,
521 RESERVED,
522 NI,
523
524 FIN_BLOCK,
525 NOTCOMPILED,
526 NOTCOMPILED2
527};
528
529cpu_instruction_table current_instruction_table;
530
531static unsigned int update_invalid_addr(unsigned int addr)
532{
533 if (addr >= 0x80000000 && addr < 0xa0000000)
534 {
535 if (invalid_code[addr>>12]) invalid_code[(addr+0x20000000)>>12] = 1;
536 if (invalid_code[(addr+0x20000000)>>12]) invalid_code[addr>>12] = 1;
537 return addr;
538 }
539 else if (addr >= 0xa0000000 && addr < 0xc0000000)
540 {
541 if (invalid_code[addr>>12]) invalid_code[(addr-0x20000000)>>12] = 1;
542 if (invalid_code[(addr-0x20000000)>>12]) invalid_code[addr>>12] = 1;
543 return addr;
544 }
545 else
546 {
547 unsigned int paddr = virtual_to_physical_address(addr, 2);
548 if (paddr)
549 {
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;
556 }
557 return paddr;
558 }
559}
560
561#define addr jump_to_address
562unsigned int jump_to_address;
563void jump_to_func(void)
564{
565 unsigned int paddr;
566 if (skip_jump) return;
567 paddr = update_invalid_addr(addr);
568 if (!paddr) return;
569 actual = blocks[addr>>12];
570 if (invalid_code[addr>>12])
571 {
572 if (!blocks[addr>>12])
573 {
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;
580 }
581 blocks[addr>>12]->start = addr & ~0xFFF;
582 blocks[addr>>12]->end = (addr & ~0xFFF) + 0x1000;
583 init_block(blocks[addr>>12]);
584 }
585 PC=actual->block+((addr-actual->start)>>2);
586
587 if (r4300emu == CORE_DYNAREC) dyna_jump();
588}
589#undef addr
590
591void generic_jump_to(unsigned int address)
592{
593 if (r4300emu == CORE_PURE_INTERPRETER)
594 PC->addr = address;
595 else {
596#ifdef NEW_DYNAREC
597 if (r4300emu == CORE_DYNAREC)
598 last_addr = pcaddr;
599 else
600 jump_to(address);
601#else
602 jump_to(address);
603#endif
604 }
605}
606
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)
609 by Joe Heinrich.
610*/
611void shuffle_fpr_data(int oldStatus, int newStatus)
612{
613#if defined(M64P_BIG_ENDIAN)
614 const int isBigEndian = 1;
615#else
616 const int isBigEndian = 0;
617#endif
618
619 if ((newStatus & 0x04000000) != (oldStatus & 0x04000000))
620 {
621 int i;
622 int temp_fgr_32[32];
623
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++)
629 {
630 temp_fgr_32[i] = *((int *) &reg_cop1_fgr_64[i>>1] + ((i & 1) ^ isBigEndian));
631 }
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++)
634 {
635 int high32 = *((int *) &reg_cop1_fgr_64[(i>>1)+16] + (i & 1));
636 *((int *) &reg_cop1_fgr_64[i] + isBigEndian) = temp_fgr_32[i];
637 *((int *) &reg_cop1_fgr_64[i] + (isBigEndian^1)) = high32;
638 }
639 }
640 else
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++)
644 {
645 temp_fgr_32[i] = *((int *) &reg_cop1_fgr_64[i] + (isBigEndian^1));
646 }
647 // take the low 32 bits from each register and pack them together into 64-bit pairs
648 for (i = 0; i < 16; i++)
649 {
650 unsigned int least32 = *((unsigned int *) &reg_cop1_fgr_64[i*2] + isBigEndian);
651 unsigned int most32 = *((unsigned int *) &reg_cop1_fgr_64[i*2+1] + isBigEndian);
652 reg_cop1_fgr_64[i] = ((unsigned long long) most32 << 32) | (unsigned long long) least32;
653 }
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++)
656 {
657 *((int *) &reg_cop1_fgr_64[(i>>1)+16] + (i & 1)) = temp_fgr_32[i];
658 }
659 }
660 }
661}
662
663void set_fpr_pointers(int newStatus)
664{
665 int i;
666#if defined(M64P_BIG_ENDIAN)
667 const int isBigEndian = 1;
668#else
669 const int isBigEndian = 0;
670#endif
671
672 // update the FPR register pointers
673 if (newStatus & 0x04000000)
674 {
675 for (i = 0; i < 32; i++)
676 {
677 reg_cop1_double[i] = (double*) &reg_cop1_fgr_64[i];
678 reg_cop1_simple[i] = ((float*) &reg_cop1_fgr_64[i]) + isBigEndian;
679 }
680 }
681 else
682 {
683 for (i = 0; i < 32; i++)
684 {
685 reg_cop1_double[i] = (double*) &reg_cop1_fgr_64[i>>1];
686 reg_cop1_simple[i] = ((float*) &reg_cop1_fgr_64[i>>1]) + ((i & 1) ^ isBigEndian);
687 }
688 }
689}
690
691int check_cop1_unusable(void)
692{
693 if (!(Status & 0x20000000))
694 {
695 Cause = (11 << 2) | 0x10000000;
696 exception_general();
697 return 1;
698 }
699 return 0;
700}
701
702void update_count(void)
703{
704#ifdef NEW_DYNAREC
705 if (r4300emu != CORE_DYNAREC)
706 {
707#endif
2d262872 708 Count += ((PC->addr - last_addr) >> 2) * count_per_op;
451ab91e 709 last_addr = PC->addr;
710#ifdef NEW_DYNAREC
711 }
712#endif
713
714#ifdef COMPARE_CORE
715 if (delay_slot)
716 CoreCompareCallback();
717#endif
718/*#ifdef DBG
719 if (g_DebuggerActive && !delay_slot) update_debugger(PC->addr);
720#endif
721*/
722}
723
724void init_blocks(void)
725{
726 int i;
727 for (i=0; i<0x100000; i++)
728 {
729 invalid_code[i] = 1;
730 blocks[i] = NULL;
731 }
732}
733
734void free_blocks(void)
735{
736 int i;
737 for (i=0; i<0x100000; i++)
738 {
739 if (blocks[i])
740 {
741 free_block(blocks[i]);
742 free(blocks[i]);
743 blocks[i] = NULL;
744 }
745 }
746}
747
748/* this hard reset function simulates the boot-up state of the R4300 CPU */
749void r4300_reset_hard(void)
750{
751 unsigned int i;
752
753 // clear r4300 registers and TLB entries
754 for (i = 0; i < 32; i++)
755 {
756 reg[i]=0;
757 reg_cop0[i]=0;
758 reg_cop1_fgr_64[i]=0;
759
760 // --------------tlb------------------------
761 tlb_e[i].mask=0;
762 tlb_e[i].vpn2=0;
763 tlb_e[i].g=0;
764 tlb_e[i].asid=0;
765 tlb_e[i].pfn_even=0;
766 tlb_e[i].c_even=0;
767 tlb_e[i].d_even=0;
768 tlb_e[i].v_even=0;
769 tlb_e[i].pfn_odd=0;
770 tlb_e[i].c_odd=0;
771 tlb_e[i].d_odd=0;
772 tlb_e[i].v_odd=0;
773 tlb_e[i].r=0;
774 //tlb_e[i].check_parity_mask=0x1000;
775
776 tlb_e[i].start_even=0;
777 tlb_e[i].end_even=0;
778 tlb_e[i].phys_even=0;
779 tlb_e[i].start_odd=0;
780 tlb_e[i].end_odd=0;
781 tlb_e[i].phys_odd=0;
782 }
783 for (i=0; i<0x100000; i++)
784 {
785 tlb_LUT_r[i] = 0;
786 tlb_LUT_w[i] = 0;
787 }
788 llbit=0;
789 hi=0;
790 lo=0;
791 FCR0=0x511;
792 FCR31=0;
793
794 // set COP0 registers
795 Random = 31;
796 Status= 0x34000000;
797 set_fpr_pointers(Status);
798 Config= 0x6e463;
799 PRevID = 0xb00;
800 Count = 0x5000;
801 Cause = 0x5C;
802 Context = 0x7FFFF0;
803 EPC = 0xFFFFFFFF;
804 BadVAddr = 0xFFFFFFFF;
805 ErrorEPC = 0xFFFFFFFF;
806
807 rounding_mode = 0x33F;
808}
809
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) */
813void r4300_reset_soft(void)
814{
815 long long CRC = 0;
816 unsigned int i;
817
818 // copy boot code from ROM to SP_DMEM
819 memcpy((char *)SP_DMEM+0x40, rom+0x40, 0xFC0);
820
821 // the following values are extracted from the pj64 source code
822 // thanks to Zilmar and Jabo
823
824 reg[6] = 0xFFFFFFFFA4001F0CLL;
825 reg[7] = 0xFFFFFFFFA4001F08LL;
826 reg[8] = 0x00000000000000C0LL;
827 reg[10]= 0x0000000000000040LL;
828 reg[11]= 0xFFFFFFFFA4000040LL;
829 reg[29]= 0xFFFFFFFFA4001FF0LL;
830
831 // figure out which ROM type is loaded
832 for (i = 0x40/4; i < (0x1000/4); i++)
833 CRC += SP_DMEM[i];
834 switch(CRC) {
835 case 0x000000D0027FDF31LL:
836 case 0x000000CFFB631223LL:
837 CIC_Chip = 1;
838 break;
839 case 0x000000D057C85244LL:
840 CIC_Chip = 2;
841 break;
842 case 0x000000D6497E414BLL:
843 CIC_Chip = 3;
844 break;
845 case 0x0000011A49F60E96LL:
846 CIC_Chip = 5;
847 break;
848 case 0x000000D6D5BE5580LL:
849 CIC_Chip = 6;
850 break;
851 default:
852 CIC_Chip = 2;
853 }
854
855 switch(ROM_PARAMS.systemtype)
856 {
857 case SYSTEM_PAL:
858 switch (CIC_Chip) {
859 case 2:
860 reg[5] = 0xFFFFFFFFC0F1D859LL;
861 reg[14]= 0x000000002DE108EALL;
862 break;
863 case 3:
864 reg[5] = 0xFFFFFFFFD4646273LL;
865 reg[14]= 0x000000001AF99984LL;
866 break;
867 case 5:
868 SP_IMEM[1] = 0xBDA807FC;
869 reg[5] = 0xFFFFFFFFDECAAAD1LL;
870 reg[14]= 0x000000000CF85C13LL;
871 reg[24]= 0x0000000000000002LL;
872 break;
873 case 6:
874 reg[5] = 0xFFFFFFFFB04DC903LL;
875 reg[14]= 0x000000001AF99984LL;
876 reg[24]= 0x0000000000000002LL;
877 break;
878 }
879 reg[23]= 0x0000000000000006LL;
880 reg[31]= 0xFFFFFFFFA4001554LL;
881 break;
882 case SYSTEM_NTSC:
883 default:
884 switch (CIC_Chip) {
885 case 2:
886 reg[5] = 0xFFFFFFFFC95973D5LL;
887 reg[14]= 0x000000002449A366LL;
888 break;
889 case 3:
890 reg[5] = 0xFFFFFFFF95315A28LL;
891 reg[14]= 0x000000005BACA1DFLL;
892 break;
893 case 5:
894 SP_IMEM[1] = 0x8DA807FC;
895 reg[5] = 0x000000005493FB9ALL;
896 reg[14]= 0xFFFFFFFFC2C20384LL;
897 break;
898 case 6:
899 reg[5] = 0xFFFFFFFFE067221FLL;
900 reg[14]= 0x000000005CD2B70FLL;
901 break;
902 }
903 reg[20]= 0x0000000000000001LL;
904 reg[24]= 0x0000000000000003LL;
905 reg[31]= 0xFFFFFFFFA4001550LL;
906 }
907 switch (CIC_Chip) {
908 case 1:
909 reg[22]= 0x000000000000003FLL;
910 break;
911 case 2:
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;
921 break;
922 case 3:
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;
932 break;
933 case 5:
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;
949 break;
950 case 6:
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;
959 break;
960 }
961
962}
963
964#if !defined(NO_ASM)
965static void dynarec_setup_code(void)
966{
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
969 jump_to(0xa4000040);
970
971 // Prevent segfault on failed jump_to
972 if (!actual->block || !actual->code)
973 dyna_stop();
974}
975#endif
976
977void r4300_execute(void)
978{
979#if defined(COUNT_INSTR) || (defined(DYNAREC) && defined(PROFILE_R4300))
980 unsigned int i;
981#endif
982
983 current_instruction_table = cached_interpreter_table;
984
451ab91e 985 delay_slot=0;
986 stop = 0;
987 rompause = 0;
988
989 /* clear instruction counters */
990#if defined(COUNT_INSTR)
991 for (i = 0; i < 131; i++)
992 instr_count[i] = 0;
993#endif
994
995 last_addr = 0xa4000040;
996 next_interupt = 624999;
997 init_interupt();
998
999 if (r4300emu == CORE_PURE_INTERPRETER)
1000 {
1001 DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Pure Interpreter");
1002 r4300emu = CORE_PURE_INTERPRETER;
1003 pure_interpreter();
1004 }
1005#if defined(DYNAREC)
1006 else if (r4300emu >= 2)
1007 {
1008 DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Dynamic Recompiler");
1009 r4300emu = CORE_DYNAREC;
1010 init_blocks();
1011
1012#ifdef NEW_DYNAREC
1013 new_dynarec_init();
1014 new_dyna_start();
1015 new_dynarec_cleanup();
1016#else
1017 dyna_start(dynarec_setup_code);
1018 PC++;
1019#endif
1020#if defined(PROFILE_R4300)
1021 pfProfile = fopen("instructionaddrs.dat", "ab");
1022 for (i=0; i<0x100000; i++)
1023 if (invalid_code[i] == 0 && blocks[i] != NULL && blocks[i]->code != NULL && blocks[i]->block != NULL)
1024 {
1025 unsigned char *x86addr;
1026 int mipsop;
1027 // store final code length for this block
1028 mipsop = -1; /* -1 == end of x86 code block */
1029 x86addr = blocks[i]->code + blocks[i]->code_length;
1030 if (fwrite(&mipsop, 1, 4, pfProfile) != 4 ||
1031 fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *))
1032 DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
1033 }
1034 fclose(pfProfile);
1035 pfProfile = NULL;
1036#endif
1037 free_blocks();
1038 }
1039#endif
1040 else /* if (r4300emu == CORE_INTERPRETER) */
1041 {
1042 DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Cached Interpreter");
1043 r4300emu = CORE_INTERPRETER;
1044 init_blocks();
1045 jump_to(0xa4000040);
1046
1047 /* Prevent segfault on failed jump_to */
1048 if (!actual->block)
1049 return;
1050
1051 last_addr = PC->addr;
1052 while (!stop)
1053 {
1054#ifdef COMPARE_CORE
1055 if (PC->ops == FIN_BLOCK && (PC->addr < 0x80000000 || PC->addr >= 0xc0000000))
1056 virtual_to_physical_address(PC->addr, 2);
1057 CoreCompareCallback();
1058#endif
1059#ifdef DBG
1060 if (g_DebuggerActive) update_debugger(PC->addr);
1061#endif
1062 PC->ops();
1063 }
1064
1065 free_blocks();
1066 }
1067
451ab91e 1068 DebugMessage(M64MSG_INFO, "R4300 emulator finished.");
1069
1070 /* print instruction counts */
1071#if defined(COUNT_INSTR)
1072 if (r4300emu == CORE_DYNAREC)
1073 {
1074 unsigned int iTypeCount[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1075 unsigned int iTotal = 0;
1076 char line[128], param[24];
1077 DebugMessage(M64MSG_INFO, "Instruction counters:");
1078 line[0] = 0;
1079 for (i = 0; i < 131; i++)
1080 {
1081 sprintf(param, "%8s: %08i ", instr_name[i], instr_count[i]);
1082 strcat(line, param);
1083 if (i % 5 == 4)
1084 {
1085 DebugMessage(M64MSG_INFO, "%s", line);
1086 line[0] = 0;
1087 }
1088 iTypeCount[instr_type[i]] += instr_count[i];
1089 iTotal += instr_count[i];
1090 }
1091 DebugMessage(M64MSG_INFO, "Instruction type summary (total instructions = %i)", iTotal);
1092 for (i = 0; i < 11; i++)
1093 {
1094 DebugMessage(M64MSG_INFO, "%20s: %04.1f%% (%i)", instr_typename[i], (float) iTypeCount[i] * 100.0 / iTotal, iTypeCount[i]);
1095 }
1096 }
1097#endif
1098}