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