2 * vim:shiftwidth=2:expandtab
8 #include "../../pico/pico_int.h"
11 #include "../drc/cmn.h"
18 #define dbg(l,...) { \
19 if ((l) & DRC_DEBUG) \
20 elprintf(EL_STATUS, ##__VA_ARGS__); \
23 #include "mame/sh2dasm.h"
24 #include <platform/linux/host_dasm.h>
25 static int insns_compiled, hash_collisions, host_insn_count;
34 static u8 *tcache_dsm_ptrs[3];
35 static char sh2dasm_buff[64];
36 #define do_host_disasm(tcid) \
37 host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
38 tcache_dsm_ptrs[tcid] = tcache_ptr
40 #define do_host_disasm(x)
43 #define BLOCK_CYCLE_LIMIT 100
44 #define MAX_BLOCK_SIZE (BLOCK_CYCLE_LIMIT * 6 * 6)
46 // we have 3 translation cache buffers, split from one drc/cmn buffer.
47 // BIOS shares tcache with data array because it's only used for init
48 // and can be discarded early
49 static const int tcache_sizes[3] = {
50 DRC_TCACHE_SIZE * 6 / 8, // ROM, DRAM
51 DRC_TCACHE_SIZE / 8, // BIOS, data array in master sh2
52 DRC_TCACHE_SIZE / 8, // ... slave
55 static u8 *tcache_bases[3];
56 static u8 *tcache_ptrs[3];
58 // ptr for code emiters
59 static u8 *tcache_ptr;
61 // host register tracking
64 HR_CACHED, // 'val' has sh2_reg_e
66 HR_CONST, // 'val' has constant
67 HR_TEMP, // reg used for temp storage
73 u16 stamp; // kind of a timestamp
77 // note: reg_temp[] must have at least the amount of
78 // registers used by handlers in worst case (currently 4)
80 #include "../drc/emit_arm.c"
82 static const int reg_map_g2h[] = {
91 static temp_reg_t reg_temp[] = {
101 #include "../drc/emit_x86.c"
103 static const int reg_map_g2h[] = {
112 // ax, cx, dx are usually temporaries by convention
113 static temp_reg_t reg_temp[] = {
129 SHR_R0 = 0, SHR_R15 = 15,
130 SHR_PC, SHR_PPC, SHR_PR, SHR_SR,
131 SHR_GBR, SHR_VBR, SHR_MACH, SHR_MACL,
134 typedef struct block_desc_ {
135 u32 addr; // SH2 PC address
136 u32 end_addr; // TODO rm?
137 void *tcache_ptr; // translated block for above PC
138 struct block_desc_ *next; // next block with the same PC hash
144 static const int block_max_counts[3] = {
149 static block_desc *block_tables[3];
150 static int block_counts[3];
153 #define MAX_HASH_ENTRIES 1024
154 #define HASH_MASK (MAX_HASH_ENTRIES - 1)
155 static void **hash_table;
157 extern void sh2_drc_entry(SH2 *sh2, void *block);
158 extern void sh2_drc_exit(void);
161 extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
162 static void REGPARM(1) sh2_test_irq(SH2 *sh2);
164 static void flush_tcache(int tcid)
166 dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
167 tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
168 block_counts[tcid], block_max_counts[tcid]);
170 block_counts[tcid] = 0;
171 tcache_ptrs[tcid] = tcache_bases[tcid];
172 if (tcid == 0) { // ROM, RAM
173 memset(hash_table, 0, sizeof(hash_table[0]) * MAX_HASH_ENTRIES);
174 memset(Pico32xMem->drcblk_ram, 0, sizeof(Pico32xMem->drcblk_ram));
177 memset(Pico32xMem->drcblk_da[tcid - 1], 0, sizeof(Pico32xMem->drcblk_da[0]));
179 tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
183 static void *dr_find_block(block_desc *tab, u32 addr)
185 for (tab = tab->next; tab != NULL; tab = tab->next)
186 if (tab->addr == addr)
190 return tab->tcache_ptr;
192 printf("block miss for %08x\n", addr);
196 static block_desc *dr_add_block(u32 addr, int tcache_id, int *blk_id)
198 int *bcount = &block_counts[tcache_id];
201 if (*bcount >= block_max_counts[tcache_id])
204 bd = &block_tables[tcache_id][*bcount];
206 bd->tcache_ptr = tcache_ptr;
213 #define HASH_FUNC(hash_tab, addr) \
214 ((block_desc **)(hash_tab))[(addr) & HASH_MASK]
216 // ---------------------------------------------------------------
219 static u16 rcache_counter;
221 static temp_reg_t *rcache_evict(void)
223 // evict reg with oldest stamp
225 u16 min_stamp = (u16)-1;
227 for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
228 if (reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY)
229 if (reg_temp[i].stamp <= min_stamp) {
230 min_stamp = reg_temp[i].stamp;
236 printf("no registers to evict, aborting\n");
241 if (reg_temp[i].type == HR_CACHED_DIRTY) {
243 emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
255 // note: must not be called when doing conditional code
256 static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
261 // maybe already statically mapped?
268 // maybe already cached?
269 for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
270 if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
271 reg_temp[i].val == r)
273 reg_temp[i].stamp = rcache_counter;
274 if (mode != RC_GR_READ)
275 reg_temp[i].type = HR_CACHED_DIRTY;
276 return reg_temp[i].reg;
281 for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
282 if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
291 if (mode != RC_GR_WRITE)
292 emith_ctx_read(tr->reg, r * 4);
294 tr->type = mode != RC_GR_READ ? HR_CACHED_DIRTY : HR_CACHED;
296 tr->stamp = rcache_counter;
300 static int rcache_get_tmp(void)
305 for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
306 if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
318 static int rcache_get_arg_id(int arg)
321 host_arg2reg(r, arg);
323 for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
324 if (reg_temp[i].reg == r)
327 if (i == ARRAY_SIZE(reg_temp))
328 // let's just say it's untracked arg reg
331 if (reg_temp[i].type == HR_CACHED_DIRTY) {
333 emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
335 else if (reg_temp[i].type == HR_TEMP) {
336 printf("arg %d reg %d already used, aborting\n", arg, r);
343 // get a reg to be used as function arg
344 // it's assumed that regs are cleaned before call
345 static int rcache_get_tmp_arg(int arg)
347 int id = rcache_get_arg_id(arg);
348 reg_temp[id].type = HR_TEMP;
350 return reg_temp[id].reg;
353 // same but caches reg. RC_GR_READ only.
354 static int rcache_get_reg_arg(int arg, sh2_reg_e r)
356 int i, srcr, dstr, dstid;
358 dstid = rcache_get_arg_id(arg);
359 dstr = reg_temp[dstid].reg;
361 // maybe already statically mapped?
362 srcr = reg_map_g2h[r];
366 // maybe already cached?
367 for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
368 if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
369 reg_temp[i].val == r)
371 srcr = reg_temp[i].reg;
378 emith_ctx_read(srcr, r * 4);
382 emith_move_r_r(dstr, srcr);
384 reg_temp[dstid].stamp = ++rcache_counter;
385 reg_temp[dstid].type = HR_CACHED;
386 reg_temp[dstid].val = r;
390 static void rcache_free_tmp(int hr)
393 for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
394 if (reg_temp[i].reg == hr)
397 if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
398 printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
402 reg_temp[i].type = HR_FREE;
405 static void rcache_clean(void)
408 for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
409 if (reg_temp[i].type == HR_CACHED_DIRTY) {
411 emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
412 reg_temp[i].type = HR_CACHED;
416 static void rcache_invalidate(void)
419 for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
420 reg_temp[i].type = HR_FREE;
424 static void rcache_flush(void)
430 // ---------------------------------------------------------------
432 static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
434 int hr = rcache_get_reg(dst, RC_GR_WRITE);
435 emith_move_r_imm(hr, imm);
438 static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
440 int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
441 int hr_s = rcache_get_reg(src, RC_GR_READ);
443 emith_move_r_r(hr_d, hr_s);
446 // arguments must be ready
447 // reg cache must be clean before call
448 static int emit_memhandler_read(int size)
451 host_arg2reg(ctxr, 1);
452 emith_move_r_r(ctxr, CONTEXT_REG);
455 emith_call(p32x_sh2_read8);
458 emith_call(p32x_sh2_read16);
461 emith_call(p32x_sh2_read32);
465 // assuming arg0 and retval reg matches
466 return rcache_get_tmp_arg(0);
469 static void emit_memhandler_write(int size)
472 host_arg2reg(ctxr, 2);
473 emith_move_r_r(ctxr, CONTEXT_REG);
476 emith_call(p32x_sh2_write8);
479 emith_call(p32x_sh2_write16);
482 emith_call(p32x_sh2_write32);
489 MOV #imm,Rn 1110nnnniiiiiiii
490 MOV.W @(disp,PC),Rn 1001nnnndddddddd
491 MOV.L @(disp,PC),Rn 1101nnnndddddddd
492 MOV Rm,Rn 0110nnnnmmmm0011
493 MOV.B @Rm,Rn 0110nnnnmmmm0000
494 MOV.W @Rm,Rn 0110nnnnmmmm0001
495 MOV.L @Rm,Rn 0110nnnnmmmm0010
496 MOV.B @Rm+,Rn 0110nnnnmmmm0100
497 MOV.W @Rm+,Rn 0110nnnnmmmm0101
498 MOV.L @Rm+,Rn 0110nnnnmmmm0110
499 MOV.B R0,@(disp,Rn) 10000000nnnndddd
500 MOV.W R0,@(disp,Rn) 10000001nnnndddd
501 MOV.B @(disp,Rm),R0 10000100mmmmdddd
502 MOV.W @(disp,Rm),R0 10000101mmmmdddd
503 MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
504 MOV.B R0,@(disp,GBR) 11000000dddddddd
505 MOV.W R0,@(disp,GBR) 11000001dddddddd
506 MOV.L R0,@(disp,GBR) 11000010dddddddd
507 MOV.B @(disp,GBR),R0 11000100dddddddd
508 MOV.W @(disp,GBR),R0 11000101dddddddd
509 MOV.L @(disp,GBR),R0 11000110dddddddd
510 MOVA @(disp,PC),R0 11000111dddddddd
511 SWAP.B Rm,Rn 0110nnnnmmmm1000
512 SWAP.W Rm,Rn 0110nnnnmmmm1001
513 ADD #imm,Rn 0111nnnniiiiiiii
514 CMP/EQ #imm,R0 10001000iiiiiiii
515 EXTS.B Rm,Rn 0110nnnnmmmm1110
516 EXTS.W Rm,Rn 0110nnnnmmmm1111
517 EXTU.B Rm,Rn 0110nnnnmmmm1100
518 EXTU.W Rm,Rn 0110nnnnmmmm1101
519 MAC @Rm+,@Rn+ 0100nnnnmmmm1111
520 NEG Rm,Rn 0110nnnnmmmm1011
521 NEGC Rm,Rn 0110nnnnmmmm1010
522 AND #imm,R0 11001001iiiiiiii
523 AND.B #imm,@(R0,GBR) 11001101iiiiiiii
524 NOT Rm,Rn 0110nnnnmmmm0111
525 OR #imm,R0 11001011iiiiiiii
526 OR.B #imm,@(R0,GBR) 11001111iiiiiiii
527 TAS.B @Rn 0100nnnn00011011
528 TST #imm,R0 11001000iiiiiiii
529 TST.B #imm,@(R0,GBR) 11001100iiiiiiii
530 XOR #imm,R0 11001010iiiiiiii
531 XOR.B #imm,@(R0,GBR) 11001110iiiiiiii
532 SHLL2 Rn 0100nnnn00001000
533 SHLR2 Rn 0100nnnn00001001
534 SHLL8 Rn 0100nnnn00011000
535 SHLR8 Rn 0100nnnn00011001
536 SHLL16 Rn 0100nnnn00101000
537 SHLR16 Rn 0100nnnn00101001
538 LDC Rm,GBR 0100mmmm00011110
539 LDC Rm,VBR 0100mmmm00101110
540 LDS Rm,MACH 0100mmmm00001010
541 LDS Rm,MACL 0100mmmm00011010
542 LDS Rm,PR 0100mmmm00101010
543 TRAPA #imm 11000011iiiiiiii
549 #define CHECK_UNHANDLED_BITS(mask) { \
550 if ((op & (mask)) != 0) \
557 #define GET_Rm GET_Fx
562 #define CHECK_FX_LT(n) \
566 static void *sh2_translate(SH2 *sh2, block_desc *other_block)
569 block_desc *this_block;
570 unsigned int pc = sh2->pc;
571 int op, delayed_op = 0, test_irq = 0;
572 int tcache_id = 0, blkid = 0;
574 u32 tmp, tmp2, tmp3, tmp4;
578 if ((tmp != 0 && tmp != 1 && tmp != 6) || sh2->pc == 0) {
579 printf("invalid PC, aborting: %08x\n", sh2->pc);
580 // FIXME: be less destructive
584 if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
585 // data_array, BIOS have separate tcache (shared)
586 tcache_id = 1 + sh2->is_slave;
589 tcache_ptr = tcache_ptrs[tcache_id];
590 this_block = dr_add_block(pc, tcache_id, &blkid);
592 tmp = tcache_ptr - tcache_bases[tcache_id];
593 if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE || this_block == NULL) {
594 flush_tcache(tcache_id);
595 tcache_ptr = tcache_ptrs[tcache_id];
596 other_block = NULL; // also gone too due to flush
597 this_block = dr_add_block(pc, tcache_id, &blkid);
600 this_block->next = other_block;
601 if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
602 HASH_FUNC(hash_table, pc) = this_block;
604 block_entry = tcache_ptr;
606 printf("== %csh2 block #%d,%d %08x -> %p\n", sh2->is_slave ? 's' : 'm',
607 tcache_id, block_counts[tcache_id], pc, block_entry);
608 if (other_block != NULL) {
609 printf(" hash collision with %08x\n", other_block->addr);
614 while (cycles < BLOCK_CYCLE_LIMIT || delayed_op)
619 op = p32x_sh2_read16(pc, sh2);
624 DasmSH2(sh2dasm_buff, pc, op);
625 printf("%08x %04x %s\n", pc, op, sh2dasm_buff);
632 switch ((op >> 12) & 0x0f)
634 /////////////////////////////////////////////
639 tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
642 case 0: // STC SR,Rn 0000nnnn00000010
645 case 1: // STC GBR,Rn 0000nnnn00010010
648 case 2: // STC VBR,Rn 0000nnnn00100010
654 tmp3 = rcache_get_reg(tmp2, RC_GR_READ);
655 emith_move_r_r(tmp, tmp3);
657 emith_clear_msb(tmp, tmp, 20); // reserved bits defined by ISA as 0
660 CHECK_UNHANDLED_BITS(0xd0);
661 // BRAF Rm 0000mmmm00100011
662 // BSRF Rm 0000mmmm00000011
665 emit_move_r_imm32(SHR_PR, pc + 2);
666 tmp = rcache_get_reg(SHR_PPC, RC_GR_WRITE);
667 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
668 emith_move_r_r(tmp, tmp2);
669 emith_add_r_imm(tmp, pc + 2);
672 case 0x04: // MOV.B Rm,@(R0,Rn) 0000nnnnmmmm0100
673 case 0x05: // MOV.W Rm,@(R0,Rn) 0000nnnnmmmm0101
674 case 0x06: // MOV.L Rm,@(R0,Rn) 0000nnnnmmmm0110
676 tmp = rcache_get_reg_arg(0, SHR_R0);
677 tmp2 = rcache_get_reg_arg(1, GET_Rm());
678 tmp3 = rcache_get_reg(GET_Rn(), RC_GR_READ);
679 emith_add_r_r(tmp, tmp3);
680 emit_memhandler_write(op & 3);
683 // MUL.L Rm,Rn 0000nnnnmmmm0111
684 tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
685 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
686 tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
687 emith_mul(tmp3, tmp2, tmp);
691 CHECK_UNHANDLED_BITS(0xf00);
694 case 0: // CLRT 0000000000001000
695 tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
696 emith_bic_r_imm(tmp, T);
698 case 1: // SETT 0000000000011000
699 tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
700 emith_or_r_imm(tmp, T);
702 case 2: // CLRMAC 0000000000101000
703 tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
704 emith_move_r_imm(tmp, 0);
705 tmp = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
706 emith_move_r_imm(tmp, 0);
715 case 0: // NOP 0000000000001001
716 CHECK_UNHANDLED_BITS(0xf00);
718 case 1: // DIV0U 0000000000011001
719 CHECK_UNHANDLED_BITS(0xf00);
720 tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
721 emith_bic_r_imm(tmp, M|Q|T);
723 case 2: // MOVT Rn 0000nnnn00101001
724 tmp = rcache_get_reg(SHR_SR, RC_GR_READ);
725 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
726 emith_clear_msb(tmp2, tmp, 31);
733 tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
736 case 0: // STS MACH,Rn 0000nnnn00001010
739 case 1: // STS MACL,Rn 0000nnnn00011010
742 case 2: // STS PR,Rn 0000nnnn00101010
748 tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
749 emith_move_r_r(tmp, tmp2);
752 CHECK_UNHANDLED_BITS(0xf00);
755 case 0: // RTS 0000000000001011
757 emit_move_r_r(SHR_PPC, SHR_PR);
760 case 1: // SLEEP 0000000000011011
761 emit_move_r_imm32(SHR_PC, pc - 2);
762 tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
763 emith_clear_msb(tmp, tmp, 20); // clear cycles
767 case 2: // RTE 0000000000101011
768 //emit_move_r_r(SHR_PC, SHR_PR);
769 emit_move_r_imm32(SHR_PC, pc - 2);
771 emith_pass_arg_r(0, CONTEXT_REG);
772 emith_pass_arg_imm(1, op);
773 emith_call(sh2_do_op);
774 emit_move_r_r(SHR_PPC, SHR_PC);
782 case 0x0c: // MOV.B @(R0,Rm),Rn 0000nnnnmmmm1100
783 case 0x0d: // MOV.W @(R0,Rm),Rn 0000nnnnmmmm1101
784 case 0x0e: // MOV.L @(R0,Rm),Rn 0000nnnnmmmm1110
786 tmp = rcache_get_reg_arg(0, SHR_R0);
787 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
788 emith_add_r_r(tmp, tmp2);
789 tmp = emit_memhandler_read(op & 3);
790 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
791 rcache_free_tmp(tmp);
793 emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
795 emith_move_r_r(tmp2, tmp);
797 case 0x0f: // MAC.L @Rm+,@Rn+ 0000nnnnmmmm1111
803 /////////////////////////////////////////////
805 // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
807 tmp = rcache_get_reg_arg(0, GET_Rn());
808 tmp2 = rcache_get_reg_arg(1, GET_Rm());
809 emith_add_r_imm(tmp, (op & 0x0f) * 4);
810 emit_memhandler_write(2);
816 case 0x00: // MOV.B Rm,@Rn 0010nnnnmmmm0000
817 case 0x01: // MOV.W Rm,@Rn 0010nnnnmmmm0001
818 case 0x02: // MOV.L Rm,@Rn 0010nnnnmmmm0010
820 rcache_get_reg_arg(0, GET_Rn());
821 rcache_get_reg_arg(1, GET_Rm());
822 emit_memhandler_write(op & 3);
824 case 0x04: // MOV.B Rm,@–Rn 0010nnnnmmmm0100
825 case 0x05: // MOV.W Rm,@–Rn 0010nnnnmmmm0101
826 case 0x06: // MOV.L Rm,@–Rn 0010nnnnmmmm0110
827 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
828 emith_sub_r_imm(tmp, (1 << (op & 3)));
830 rcache_get_reg_arg(0, GET_Rn());
831 rcache_get_reg_arg(1, GET_Rm());
832 emit_memhandler_write(op & 3);
834 case 0x07: // DIV0S Rm,Rn 0010nnnnmmmm0111
835 tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
836 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
837 tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
838 emith_bic_r_imm(tmp, M|Q|T);
839 emith_tst_r_imm(tmp2, (1<<31));
840 EMITH_SJMP_START(DCOND_EQ);
841 emith_or_r_imm_c(DCOND_NE, tmp, Q);
842 EMITH_SJMP_END(DCOND_EQ);
843 emith_tst_r_imm(tmp3, (1<<31));
844 EMITH_SJMP_START(DCOND_EQ);
845 emith_or_r_imm_c(DCOND_NE, tmp, M);
846 EMITH_SJMP_END(DCOND_EQ);
847 emith_teq_r_r(tmp2, tmp3);
848 EMITH_SJMP_START(DCOND_PL);
849 emith_or_r_imm_c(DCOND_MI, tmp, T);
850 EMITH_SJMP_END(DCOND_PL);
852 case 0x08: // TST Rm,Rn 0010nnnnmmmm1000
853 tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
854 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
855 tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
856 emith_bic_r_imm(tmp, T);
857 emith_tst_r_r(tmp2, tmp3);
858 EMITH_SJMP_START(DCOND_NE);
859 emith_or_r_imm_c(DCOND_EQ, tmp, T);
860 EMITH_SJMP_END(DCOND_NE);
862 case 0x09: // AND Rm,Rn 0010nnnnmmmm1001
863 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
864 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
865 emith_and_r_r(tmp, tmp2);
867 case 0x0a: // XOR Rm,Rn 0010nnnnmmmm1010
868 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
869 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
870 emith_eor_r_r(tmp, tmp2);
872 case 0x0b: // OR Rm,Rn 0010nnnnmmmm1011
873 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
874 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
875 emith_or_r_r(tmp, tmp2);
877 case 0x0c: // CMP/STR Rm,Rn 0010nnnnmmmm1100
878 tmp = rcache_get_tmp();
879 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
880 tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
881 emith_eor_r_r_r(tmp, tmp2, tmp3);
882 tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
883 emith_bic_r_imm(tmp2, T);
884 emith_tst_r_imm(tmp, 0x000000ff);
885 EMITH_SJMP_START(DCOND_NE);
886 emith_or_r_imm_c(DCOND_EQ, tmp2, T);
887 EMITH_SJMP_END(DCOND_NE);
888 emith_tst_r_imm(tmp, 0x0000ff00);
889 EMITH_SJMP_START(DCOND_NE);
890 emith_or_r_imm_c(DCOND_EQ, tmp2, T);
891 EMITH_SJMP_END(DCOND_NE);
892 emith_tst_r_imm(tmp, 0x00ff0000);
893 EMITH_SJMP_START(DCOND_NE);
894 emith_or_r_imm_c(DCOND_EQ, tmp2, T);
895 EMITH_SJMP_END(DCOND_NE);
896 emith_tst_r_imm(tmp, 0xff000000);
897 EMITH_SJMP_START(DCOND_NE);
898 emith_or_r_imm_c(DCOND_EQ, tmp2, T);
899 EMITH_SJMP_END(DCOND_NE);
900 rcache_free_tmp(tmp);
902 case 0x0d: // XTRCT Rm,Rn 0010nnnnmmmm1101
903 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
904 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
905 emith_lsr(tmp, tmp, 16);
906 emith_or_r_r_r_lsl(tmp, tmp, tmp2, 16);
908 case 0x0e: // MULU.W Rm,Rn 0010nnnnmmmm1110
909 case 0x0f: // MULS.W Rm,Rn 0010nnnnmmmm1111
910 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
911 tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
913 emith_sext(tmp, tmp2, 16);
915 emith_clear_msb(tmp, tmp2, 16);
916 tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
917 tmp2 = rcache_get_tmp();
919 emith_sext(tmp2, tmp3, 16);
921 emith_clear_msb(tmp2, tmp3, 16);
922 emith_mul(tmp, tmp, tmp2);
923 rcache_free_tmp(tmp2);
924 // FIXME: causes timing issues in Doom?
930 /////////////////////////////////////////////
934 case 0x00: // CMP/EQ Rm,Rn 0011nnnnmmmm0000
935 case 0x02: // CMP/HS Rm,Rn 0011nnnnmmmm0010
936 case 0x03: // CMP/GE Rm,Rn 0011nnnnmmmm0011
937 case 0x06: // CMP/HI Rm,Rn 0011nnnnmmmm0110
938 case 0x07: // CMP/GT Rm,Rn 0011nnnnmmmm0111
939 tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
940 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
941 tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
942 emith_bic_r_imm(tmp, T);
943 emith_cmp_r_r(tmp2, tmp3);
947 EMITH_SJMP_START(DCOND_NE);
948 emith_or_r_imm_c(DCOND_EQ, tmp, T);
949 EMITH_SJMP_END(DCOND_NE);
952 EMITH_SJMP_START(DCOND_LO);
953 emith_or_r_imm_c(DCOND_HS, tmp, T);
954 EMITH_SJMP_END(DCOND_LO);
957 EMITH_SJMP_START(DCOND_LT);
958 emith_or_r_imm_c(DCOND_GE, tmp, T);
959 EMITH_SJMP_END(DCOND_LT);
962 EMITH_SJMP_START(DCOND_LS);
963 emith_or_r_imm_c(DCOND_HI, tmp, T);
964 EMITH_SJMP_END(DCOND_LS);
967 EMITH_SJMP_START(DCOND_LE);
968 emith_or_r_imm_c(DCOND_GT, tmp, T);
969 EMITH_SJMP_END(DCOND_LE);
973 case 0x04: // DIV1 Rm,Rn 0011nnnnmmmm0100
976 case 0x05: // DMULU.L Rm,Rn 0011nnnnmmmm0101
977 tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
978 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
979 tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
980 tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
981 emith_mul_u64(tmp3, tmp4, tmp, tmp2);
983 case 0x08: // SUB Rm,Rn 0011nnnnmmmm1000
984 case 0x0c: // ADD Rm,Rn 0011nnnnmmmm1100
985 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
986 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
988 emith_add_r_r(tmp, tmp2);
990 emith_sub_r_r(tmp, tmp2);
992 case 0x0a: // SUBC Rm,Rn 0011nnnnmmmm1010
993 case 0x0e: // ADDC Rm,Rn 0011nnnnmmmm1110
994 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
995 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
996 tmp3 = rcache_get_reg(SHR_SR, RC_GR_RMW);
998 emith_set_carry(tmp3);
999 emith_adcf_r_r(tmp, tmp2);
1000 emith_carry_to_t(tmp3, 0);
1002 emith_set_carry_sub(tmp3);
1003 emith_sbcf_r_r(tmp, tmp2);
1004 emith_carry_to_t(tmp3, 1);
1007 case 0x0b: // SUBV Rm,Rn 0011nnnnmmmm1011
1008 case 0x0f: // ADDV Rm,Rn 0011nnnnmmmm1111
1009 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1010 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1011 tmp3 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1012 emith_bic_r_imm(tmp3, T);
1014 emith_addf_r_r(tmp, tmp2);
1016 emith_subf_r_r(tmp, tmp2);
1017 EMITH_SJMP_START(DCOND_VC);
1018 emith_or_r_imm_c(DCOND_VS, tmp3, T);
1019 EMITH_SJMP_END(DCOND_VC);
1021 case 0x0d: // DMULS.L Rm,Rn 0011nnnnmmmm1101
1022 tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
1023 tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1024 tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1025 tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1026 emith_mul_s64(tmp3, tmp4, tmp, tmp2);
1031 /////////////////////////////////////////////
1038 case 0: // SHLL Rn 0100nnnn00000000
1039 case 2: // SHAL Rn 0100nnnn00100000
1040 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1041 tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1042 emith_lslf(tmp, tmp, 1);
1043 emith_carry_to_t(tmp2, 0);
1045 case 1: // DT Rn 0100nnnn00010000
1046 if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2
1047 emith_sh2_dtbf_loop();
1050 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1051 tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1052 emith_bic_r_imm(tmp2, T);
1053 emith_subf_r_imm(tmp, 1);
1054 EMITH_SJMP_START(DCOND_NE);
1055 emith_or_r_imm_c(DCOND_EQ, tmp2, T);
1056 EMITH_SJMP_END(DCOND_NE);
1063 case 0: // SHLR Rn 0100nnnn00000001
1064 case 2: // SHAR Rn 0100nnnn00100001
1065 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1066 tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1068 emith_asrf(tmp, tmp, 1);
1070 emith_lsrf(tmp, tmp, 1);
1071 emith_carry_to_t(tmp2, 0);
1073 case 1: // CMP/PZ Rn 0100nnnn00010001
1074 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1075 tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1076 emith_bic_r_imm(tmp2, T);
1077 emith_cmp_r_imm(tmp, 0);
1078 EMITH_SJMP_START(DCOND_LT);
1079 emith_or_r_imm_c(DCOND_GE, tmp2, T);
1080 EMITH_SJMP_END(DCOND_LT);
1088 case 0x02: // STS.L MACH,@–Rn 0100nnnn00000010
1091 case 0x12: // STS.L MACL,@–Rn 0100nnnn00010010
1094 case 0x22: // STS.L PR,@–Rn 0100nnnn00100010
1097 case 0x03: // STC.L SR,@–Rn 0100nnnn00000011
1100 case 0x13: // STC.L GBR,@–Rn 0100nnnn00010011
1103 case 0x23: // STC.L VBR,@–Rn 0100nnnn00100011
1109 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1110 emith_sub_r_imm(tmp2, 4);
1112 rcache_get_reg_arg(0, GET_Rn());
1113 tmp3 = rcache_get_reg_arg(1, tmp);
1115 emith_clear_msb(tmp3, tmp3, 20); // reserved bits defined by ISA as 0
1116 emit_memhandler_write(2);
1122 case 0x04: // ROTL Rn 0100nnnn00000100
1123 case 0x05: // ROTR Rn 0100nnnn00000101
1124 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1125 tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1127 emith_rorf(tmp, tmp, 1);
1129 emith_rolf(tmp, tmp, 1);
1130 emith_carry_to_t(tmp2, 0);
1132 case 0x24: // ROTCL Rn 0100nnnn00100100
1133 case 0x25: // ROTCR Rn 0100nnnn00100101
1134 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1135 tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1136 emith_set_carry(tmp2);
1141 emith_carry_to_t(tmp2, 0);
1143 case 0x15: // CMP/PL Rn 0100nnnn00010101
1144 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1145 tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1146 emith_bic_r_imm(tmp2, T);
1147 emith_cmp_r_imm(tmp, 0);
1148 EMITH_SJMP_START(DCOND_LE);
1149 emith_or_r_imm_c(DCOND_GT, tmp2, T);
1150 EMITH_SJMP_END(DCOND_LE);
1158 case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
1161 case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
1164 case 0x26: // LDS.L @Rm+,PR 0100mmmm00100110
1167 case 0x07: // LDC.L @Rm+,SR 0100mmmm00000111
1170 case 0x17: // LDC.L @Rm+,GBR 0100mmmm00010111
1173 case 0x27: // LDC.L @Rm+,VBR 0100mmmm00100111
1180 rcache_get_reg_arg(0, GET_Rn());
1181 tmp2 = emit_memhandler_read(2);
1182 if (tmp == SHR_SR) {
1183 emith_write_sr(tmp2);
1186 tmp = rcache_get_reg(tmp, RC_GR_WRITE);
1187 emith_move_r_r(tmp, tmp2);
1189 rcache_free_tmp(tmp2);
1190 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1191 emith_add_r_imm(tmp, 4);
1194 if ((op & 0xd0) != 0)
1196 // JMP @Rm 0100mmmm00101011
1197 // JSR @Rm 0100mmmm00001011
1200 emit_move_r_imm32(SHR_PR, pc + 2);
1201 emit_move_r_r(SHR_PPC, (op >> 8) & 0x0f);
1205 if ((op & 0xf0) != 0)
1207 // LDC Rm,SR 0100mmmm00001110
1213 /////////////////////////////////////////////
1215 switch (op & 0x0f00) {
1216 // BT/S label 10001101dddddddd
1218 // BF/S label 10001111dddddddd
1223 // BT label 10001001dddddddd
1225 // BF label 10001011dddddddd
1227 // jmp_cond ~ cond when guest doesn't jump
1228 int jmp_cond = (op & 0x0200) ? DCOND_NE : DCOND_EQ;
1229 int insn_cond = (op & 0x0200) ? DCOND_EQ : DCOND_NE;
1230 signed int offs = ((signed int)(op << 24) >> 23);
1231 tmp = rcache_get_reg(delayed_op ? SHR_PPC : SHR_PC, RC_GR_WRITE);
1232 emith_move_r_imm(tmp, pc + (delayed_op ? 2 : 0));
1234 EMITH_SJMP_START(jmp_cond);
1238 emith_sub_r_imm_c(insn_cond, tmp, -offs);
1240 emith_add_r_imm_c(insn_cond, tmp, offs);
1241 EMITH_SJMP_END(jmp_cond);
1249 /////////////////////////////////////////////
1251 // BRA label 1010dddddddddddd
1254 tmp = ((signed int)(op << 20) >> 19);
1255 emit_move_r_imm32(SHR_PPC, pc + tmp + 2);
1259 /////////////////////////////////////////////
1261 // BSR label 1011dddddddddddd
1263 emit_move_r_imm32(SHR_PR, pc + 2);
1268 emit_move_r_imm32(SHR_PC, pc - 2);
1270 emith_pass_arg_r(0, CONTEXT_REG);
1271 emith_pass_arg_imm(1, op);
1272 emith_call(sh2_do_op);
1277 if (delayed_op == 1)
1278 emit_move_r_r(SHR_PC, SHR_PPC);
1280 if (test_irq && delayed_op != 2) {
1282 emith_pass_arg_r(0, CONTEXT_REG);
1283 emith_call(sh2_test_irq);
1286 if (delayed_op == 1)
1289 do_host_disasm(tcache_id);
1293 this_block->end_addr = pc;
1295 // mark memory blocks as containing compiled code
1296 if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1298 u16 *drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
1299 tmp = (this_block->addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1300 tmp2 = (this_block->end_addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1301 Pico32xMem->drcblk_da[sh2->is_slave][tmp] = (blkid << 1) | 1;
1302 for (++tmp; tmp < tmp2; tmp++) {
1304 break; // dont overwrite overlay block
1305 drcblk[tmp] = blkid << 1;
1308 else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
1309 tmp = (this_block->addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1310 tmp2 = (this_block->end_addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1311 Pico32xMem->drcblk_ram[tmp] = (blkid << 1) | 1;
1312 for (++tmp; tmp < tmp2; tmp++) {
1313 if (Pico32xMem->drcblk_ram[tmp])
1315 Pico32xMem->drcblk_ram[tmp] = blkid << 1;
1319 tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
1320 emith_sub_r_imm(tmp, cycles << 12);
1322 emith_jump(sh2_drc_exit);
1323 tcache_ptrs[tcache_id] = tcache_ptr;
1326 cache_flush_d_inval_i(block_entry, tcache_ptr);
1329 do_host_disasm(tcache_id);
1330 dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
1331 tcache_id, block_counts[tcache_id],
1332 tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
1333 insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
1334 if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
1335 dbg(1, " hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
1344 do_host_disasm(tcache_id);
1349 void __attribute__((noinline)) sh2_drc_dispatcher(SH2 *sh2)
1351 while (((signed int)sh2->sr >> 12) > 0)
1354 block_desc *bd = NULL;
1356 // FIXME: must avoid doing it so often..
1359 // we have full block id tables for data_array and RAM
1360 // BIOS goes to data_array table too
1361 if ((sh2->pc & 0xff000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1362 int blkid = Pico32xMem->drcblk_da[sh2->is_slave][(sh2->pc & 0xfff) >> SH2_DRCBLK_DA_SHIFT];
1364 bd = &block_tables[1 + sh2->is_slave][blkid >> 1];
1365 block = bd->tcache_ptr;
1369 else if ((sh2->pc & 0xc6000000) == 0x06000000) {
1370 int blkid = Pico32xMem->drcblk_ram[(sh2->pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT];
1372 bd = &block_tables[0][blkid >> 1];
1373 block = bd->tcache_ptr;
1377 else if ((sh2->pc & 0xc6000000) == 0x02000000) {
1378 bd = HASH_FUNC(hash_table, sh2->pc);
1381 if (bd->addr == sh2->pc)
1382 block = bd->tcache_ptr;
1384 block = dr_find_block(bd, sh2->pc);
1389 block = sh2_translate(sh2, bd);
1391 dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
1392 sh2->pc, block, (signed int)sh2->sr >> 12);
1397 sh2_drc_entry(sh2, block);
1401 static void sh2_smc_rm_block(u16 *drcblk, u16 *p, block_desc *btab, u32 a)
1404 block_desc *bd = btab + id;
1406 dbg(1, " killing block %08x", bd->addr);
1407 bd->addr = bd->end_addr = 0;
1409 while (p > drcblk && (p[-1] >> 1) == id)
1412 // check for possible overlay block
1413 if (p > 0 && p[-1] != 0) {
1414 bd = btab + (p[-1] >> 1);
1415 if (bd->addr <= a && a < bd->end_addr)
1416 sh2_smc_rm_block(drcblk, p - 1, btab, a);
1422 while ((*p >> 1) == id);
1425 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
1427 u16 *drcblk = Pico32xMem->drcblk_ram;
1428 u16 *p = drcblk + ((a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT);
1430 dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1431 sh2_smc_rm_block(drcblk, p, block_tables[0], a);
1434 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
1436 u16 *drcblk = Pico32xMem->drcblk_da[cpuid];
1437 u16 *p = drcblk + ((a & 0xfff) >> SH2_DRCBLK_DA_SHIFT);
1439 dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1440 sh2_smc_rm_block(drcblk, p, block_tables[1 + cpuid], a);
1443 void sh2_execute(SH2 *sh2, int cycles)
1445 sh2->cycles_aim += cycles;
1446 cycles = sh2->cycles_aim - sh2->cycles_done;
1448 // cycles are kept in SHR_SR unused bits (upper 20)
1450 sh2->sr |= cycles << 12;
1451 sh2_drc_dispatcher(sh2);
1453 sh2->cycles_done += cycles - ((signed int)sh2->sr >> 12);
1456 static void REGPARM(1) sh2_test_irq(SH2 *sh2)
1458 if (sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
1460 if (sh2->pending_irl > sh2->pending_int_irq)
1461 sh2_do_irq(sh2, sh2->pending_irl, 64 + sh2->pending_irl/2);
1463 sh2_do_irq(sh2, sh2->pending_int_irq, sh2->pending_int_vector);
1464 sh2->pending_int_irq = 0; // auto-clear
1465 sh2->pending_level = sh2->pending_irl;
1471 static void block_stats(void)
1473 int c, b, i, total = 0;
1475 for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1476 for (i = 0; i < block_counts[b]; i++)
1477 if (block_tables[b][i].addr != 0)
1478 total += block_tables[b][i].refcount;
1480 for (c = 0; c < 10; c++) {
1481 block_desc *blk, *maxb = NULL;
1483 for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
1484 for (i = 0; i < block_counts[b]; i++) {
1485 blk = &block_tables[b][i];
1486 if (blk->addr != 0 && blk->refcount > max) {
1487 max = blk->refcount;
1494 printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
1495 (double)maxb->refcount / total * 100.0);
1499 for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1500 for (i = 0; i < block_counts[b]; i++)
1501 block_tables[b][i].refcount = 0;
1504 #define block_stats()
1507 void sh2_drc_flush_all(void)
1515 int sh2_drc_init(SH2 *sh2)
1517 if (block_tables[0] == NULL) {
1522 cnt = block_max_counts[0] + block_max_counts[1] + block_max_counts[2];
1523 block_tables[0] = calloc(cnt, sizeof(*block_tables[0]));
1524 if (block_tables[0] == NULL)
1527 memset(block_counts, 0, sizeof(block_counts));
1528 tcache_bases[0] = tcache_ptrs[0] = tcache;
1530 for (i = 1; i < ARRAY_SIZE(block_tables); i++) {
1531 block_tables[i] = block_tables[i - 1] + block_max_counts[i - 1];
1532 tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
1536 PicoOpt |= POPT_DIS_VDP_FIFO;
1539 for (i = 0; i < ARRAY_SIZE(block_tables); i++)
1540 tcache_dsm_ptrs[i] = tcache_bases[i];
1543 hash_collisions = 0;
1547 if (hash_table == NULL) {
1548 hash_table = calloc(sizeof(hash_table[0]), MAX_HASH_ENTRIES);
1549 if (hash_table == NULL)
1556 void sh2_drc_finish(SH2 *sh2)
1558 if (block_tables[0] != NULL) {
1560 free(block_tables[0]);
1561 memset(block_tables, 0, sizeof(block_tables));
1566 if (hash_table != NULL) {