32x: drc: handlers wip
[picodrive.git] / cpu / sh2 / compiler.c
1 /*
2  * vim:shiftwidth=2:expandtab
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <assert.h>
7
8 #include "../../pico/pico_int.h"
9 #include "sh2.h"
10 #include "compiler.h"
11 #include "../drc/cmn.h"
12
13 #ifndef DRC_DEBUG
14 #define DRC_DEBUG 0
15 #endif
16
17 #if DRC_DEBUG
18 #define dbg(l,...) { \
19   if ((l) & DRC_DEBUG) \
20     elprintf(EL_STATUS, ##__VA_ARGS__); \
21 }
22
23 #include "mame/sh2dasm.h"
24 #include <platform/linux/host_dasm.h>
25 static int insns_compiled, hash_collisions, host_insn_count;
26 #define COUNT_OP \
27         host_insn_count++
28 #else // !DRC_DEBUG
29 #define COUNT_OP
30 #define dbg(...)
31 #endif
32
33 #if (DRC_DEBUG & 2)
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
39 #else
40 #define do_host_disasm(x)
41 #endif
42
43 #define BLOCK_CYCLE_LIMIT 100
44 #define MAX_BLOCK_SIZE (BLOCK_CYCLE_LIMIT * 6 * 6)
45
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
53 };
54
55 static u8 *tcache_bases[3];
56 static u8 *tcache_ptrs[3];
57
58 // ptr for code emiters
59 static u8 *tcache_ptr;
60
61 // host register tracking
62 enum {
63   HR_FREE,
64   HR_CACHED, // 'val' has sh2_reg_e
65   HR_CACHED_DIRTY,
66   HR_CONST,  // 'val' has constant
67   HR_TEMP,   // reg used for temp storage
68 };
69
70 typedef struct {
71   u8 reg;
72   u8 type;
73   u16 stamp; // kind of a timestamp
74   u32 val;
75 } temp_reg_t;
76
77 // note: reg_temp[] must have at least the amount of
78 // registers used by handlers in worst case (currently 3?)
79 #ifdef ARM
80 #include "../drc/emit_arm.c"
81
82 static const int reg_map_g2h[] = {
83   -1, -1, -1, -1,
84   -1, -1, -1, -1,
85   -1, -1, -1, -1,
86   -1, -1, -1, -1,
87   -1, -1, -1, -1,
88   -1, -1, -1, -1,
89 };
90
91 static temp_reg_t reg_temp[] = {
92   {  0, },
93   {  1, },
94   { 12, },
95   { 14, },
96   {  2, },
97   {  3, },
98 };
99
100 #else
101 #include "../drc/emit_x86.c"
102
103 static const int reg_map_g2h[] = {
104   -1, -1, -1, -1,
105   -1, -1, -1, -1,
106   -1, -1, -1, -1,
107   -1, -1, -1, -1,
108   -1, -1, -1, -1,
109   -1, -1, -1, -1,
110 };
111
112 // ax, cx, dx are usually temporaries
113 static temp_reg_t reg_temp[] = {
114   { xAX, },
115   { xCX, },
116   { xDX, },
117 };
118
119 #endif
120
121 #define T       0x00000001
122 #define S       0x00000002
123 #define I       0x000000f0
124 #define Q       0x00000100
125 #define M       0x00000200
126
127 typedef enum {
128   SHR_R0 = 0, SHR_R15 = 15,
129   SHR_PC,  SHR_PPC, SHR_PR,   SHR_SR,
130   SHR_GBR, SHR_VBR, SHR_MACH, SHR_MACL,
131 } sh2_reg_e;
132
133 typedef struct block_desc_ {
134   u32 addr;                     // SH2 PC address
135   u32 end_addr;                 // TODO rm?
136   void *tcache_ptr;             // translated block for above PC
137   struct block_desc_ *next;     // next block with the same PC hash
138 #if (DRC_DEBUG & 1)
139   int refcount;
140 #endif
141 } block_desc;
142
143 static const int block_max_counts[3] = {
144   4*1024,
145   256,
146   256,
147 };
148 static block_desc *block_tables[3];
149 static int block_counts[3];
150
151 // ROM hash table
152 #define MAX_HASH_ENTRIES 1024
153 #define HASH_MASK (MAX_HASH_ENTRIES - 1)
154 static void **hash_table;
155
156 extern void sh2_drc_entry(SH2 *sh2, void *block);
157 extern void sh2_drc_exit(void);
158
159 // tmp
160 extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
161 static void REGPARM(1) sh2_test_irq(SH2 *sh2);
162
163 static void flush_tcache(int tcid)
164 {
165   dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
166     tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
167     block_counts[tcid], block_max_counts[tcid]);
168
169   block_counts[tcid] = 0;
170   tcache_ptrs[tcid] = tcache_bases[tcid];
171   if (tcid == 0) { // ROM, RAM
172     memset(hash_table, 0, sizeof(hash_table[0]) * MAX_HASH_ENTRIES);
173     memset(Pico32xMem->drcblk_ram, 0, sizeof(Pico32xMem->drcblk_ram));
174   }
175   else
176     memset(Pico32xMem->drcblk_da[tcid - 1], 0, sizeof(Pico32xMem->drcblk_da[0]));
177 #if (DRC_DEBUG & 2)
178   tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
179 #endif
180 }
181
182 static void *dr_find_block(block_desc *tab, u32 addr)
183 {
184   for (tab = tab->next; tab != NULL; tab = tab->next)
185     if (tab->addr == addr)
186       break;
187
188   if (tab != NULL)
189     return tab->tcache_ptr;
190
191   printf("block miss for %08x\n", addr);
192   return NULL;
193 }
194
195 static block_desc *dr_add_block(u32 addr, int tcache_id, int *blk_id)
196 {
197   int *bcount = &block_counts[tcache_id];
198   block_desc *bd;
199
200   if (*bcount >= block_max_counts[tcache_id])
201     return NULL;
202
203   bd = &block_tables[tcache_id][*bcount];
204   bd->addr = addr;
205   bd->tcache_ptr = tcache_ptr;
206   *blk_id = *bcount;
207   (*bcount)++;
208
209   return bd;
210 }
211
212 #define HASH_FUNC(hash_tab, addr) \
213   ((block_desc **)(hash_tab))[(addr) & HASH_MASK]
214
215 // ---------------------------------------------------------------
216
217 // register chache
218 static u16 rcache_counter;
219
220 static temp_reg_t *rcache_evict(void)
221 {
222   // evict reg with oldest stamp
223   int i, oldest = -1;
224   u16 min_stamp = (u16)-1;
225
226   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
227     if (reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY)
228       if (reg_temp[i].stamp <= min_stamp) {
229         min_stamp = reg_temp[i].stamp;
230         oldest = i;
231       }
232   }
233
234   if (oldest == -1) {
235     printf("no registers to evict, aborting\n");
236     exit(1);
237   }
238
239   i = oldest;
240   if (reg_temp[i].type == HR_CACHED_DIRTY) {
241     // writeback
242     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
243   }
244
245   return &reg_temp[i];
246 }
247
248 typedef enum {
249   RC_GR_READ,
250   RC_GR_WRITE,
251   RC_GR_RMW,
252 } rc_gr_mode;
253
254 // note: must not be called when doing conditional code
255 static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
256 {
257   temp_reg_t *tr;
258   int i;
259
260   // maybe already statically mapped?
261   i = reg_map_g2h[r];
262   if (i != -1)
263     return i;
264
265   rcache_counter++;
266
267   // maybe already cached?
268   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
269     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
270          reg_temp[i].val == r)
271     {
272       reg_temp[i].stamp = rcache_counter;
273       if (mode != RC_GR_READ)
274         reg_temp[i].type = HR_CACHED_DIRTY;
275       return reg_temp[i].reg;
276     }
277   }
278
279   // use any free reg
280   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
281     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
282       tr = &reg_temp[i];
283       goto do_alloc;
284     }
285   }
286
287   tr = rcache_evict();
288
289 do_alloc:
290   if (mode != RC_GR_WRITE)
291     emith_ctx_read(tr->reg, r * 4);
292
293   tr->type = mode != RC_GR_READ ? HR_CACHED_DIRTY : HR_CACHED;
294   tr->val = r;
295   tr->stamp = rcache_counter;
296   return tr->reg;
297 }
298
299 static int rcache_get_tmp(void)
300 {
301   temp_reg_t *tr;
302   int i;
303
304   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
305     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
306       tr = &reg_temp[i];
307       goto do_alloc;
308     }
309
310   tr = rcache_evict();
311
312 do_alloc:
313   tr->type = HR_TEMP;
314   return tr->reg;
315 }
316
317 static int rcache_get_arg_id(int arg)
318 {
319   int i, r = 0;
320   host_arg2reg(r, arg);
321
322   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
323     if (reg_temp[i].reg == r)
324       break;
325
326   if (i == ARRAY_SIZE(reg_temp))
327     // let's just say it's untracked arg reg
328     return r;
329
330   if (reg_temp[i].type == HR_CACHED_DIRTY) {
331     // writeback
332     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
333   }
334   else if (reg_temp[i].type == HR_TEMP) {
335     printf("arg %d reg %d already used, aborting\n", arg, r);
336     exit(1);
337   }
338
339   return i;
340 }
341
342 // get a reg to be used as function arg
343 // it's assumed that regs are cleaned before call
344 static int rcache_get_tmp_arg(int arg)
345 {
346   int id = rcache_get_arg_id(arg);
347   reg_temp[id].type = HR_TEMP;
348
349   return reg_temp[id].reg;
350 }
351
352 // same but caches reg. RC_GR_READ only.
353 static int rcache_get_reg_arg(int arg, sh2_reg_e r)
354 {
355   int i, srcr, dstr, dstid;
356
357   dstid = rcache_get_arg_id(arg);
358   dstr = reg_temp[dstid].reg;
359
360   // maybe already statically mapped?
361   srcr = reg_map_g2h[r];
362   if (srcr != -1)
363     goto do_cache;
364
365   // maybe already cached?
366   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
367     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
368          reg_temp[i].val == r)
369     {
370       srcr = reg_temp[i].reg;
371       goto do_cache;
372     }
373   }
374
375   // must read
376   srcr = dstr;
377   emith_ctx_read(srcr, r * 4);
378
379 do_cache:
380   if (srcr != dstr)
381     emith_move_r_r(dstr, srcr);
382
383   reg_temp[dstid].stamp = ++rcache_counter;
384   reg_temp[dstid].type = HR_CACHED;
385   reg_temp[dstid].val = r;
386   return dstr;
387 }
388
389 static void rcache_free_tmp(int hr)
390 {
391   int i;
392   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
393     if (reg_temp[i].reg == hr)
394       break;
395
396   if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
397     printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
398     return;
399   }
400
401   reg_temp[i].type = HR_FREE;
402 }
403
404 static void rcache_clean(void)
405 {
406   int i;
407   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
408     if (reg_temp[i].type == HR_CACHED_DIRTY) {
409       // writeback
410       emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
411       reg_temp[i].type = HR_CACHED;
412     }
413 }
414
415 static void rcache_invalidate(void)
416 {
417   int i;
418   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
419     reg_temp[i].type = HR_FREE;
420   rcache_counter = 0;
421 }
422
423 static void rcache_flush(void)
424 {
425   rcache_clean();
426   rcache_invalidate();
427 }
428
429 // ---------------------------------------------------------------
430
431 static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
432 {
433   int hr = rcache_get_reg(dst, RC_GR_WRITE);
434   emith_move_r_imm(hr, imm);
435 }
436
437 static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
438 {
439   int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
440   int hr_s = rcache_get_reg(src, RC_GR_READ);
441
442   emith_move_r_r(hr_d, hr_s);
443 }
444
445 // arguments must be ready
446 // reg cache must be clean before call
447 static int emit_memhandler_read(int size)
448 {
449   int ctxr;
450   host_arg2reg(ctxr, 1);
451   emith_move_r_r(ctxr, CONTEXT_REG);
452   switch (size) {
453   case 0: // 8
454     emith_call(p32x_sh2_read8);
455     break;
456   case 1: // 16
457     emith_call(p32x_sh2_read16);
458     break;
459   case 2: // 32
460     emith_call(p32x_sh2_read32);
461     break;
462   }
463   rcache_invalidate();
464   // assuming arg0 and retval reg matches
465   return rcache_get_tmp_arg(0);
466 }
467
468 static void emit_memhandler_write(int size)
469 {
470   int ctxr;
471   host_arg2reg(ctxr, 2);
472   emith_move_r_r(ctxr, CONTEXT_REG);
473   switch (size) {
474   case 0: // 8
475     emith_call(p32x_sh2_write8);
476     break;
477   case 1: // 16
478     emith_call(p32x_sh2_write16);
479     break;
480   case 2: // 32
481     emith_call(p32x_sh2_write32);
482     break;
483   }
484   rcache_invalidate();
485 }
486
487 /*
488 MOV   #imm,Rn       1110nnnniiiiiiii
489 MOV.W @(disp,PC),Rn 1001nnnndddddddd
490 MOV.L @(disp,PC),Rn 1101nnnndddddddd
491 MOV   Rm,Rn         0110nnnnmmmm0011
492 MOV.B @Rm,Rn        0110nnnnmmmm0000
493 MOV.W @Rm,Rn        0110nnnnmmmm0001
494 MOV.L @Rm,Rn        0110nnnnmmmm0010
495 MOV.B @Rm+,Rn       0110nnnnmmmm0100
496 MOV.W @Rm+,Rn       0110nnnnmmmm0101
497 MOV.L @Rm+,Rn       0110nnnnmmmm0110
498 MOV.B R0,@(disp,Rn) 10000000nnnndddd
499 MOV.W R0,@(disp,Rn) 10000001nnnndddd
500 MOV.B @(disp,Rm),R0 10000100mmmmdddd
501 MOV.W @(disp,Rm),R0 10000101mmmmdddd
502 MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
503 MOV.B    R0,@(disp,GBR)   11000000dddddddd
504 MOV.W    R0,@(disp,GBR)   11000001dddddddd
505 MOV.L    R0,@(disp,GBR)   11000010dddddddd
506 MOV.B    @(disp,GBR),R0   11000100dddddddd
507 MOV.W    @(disp,GBR),R0   11000101dddddddd
508 MOV.L    @(disp,GBR),R0   11000110dddddddd
509 MOVA     @(disp,PC),R0    11000111dddddddd
510 SWAP.B Rm,Rn              0110nnnnmmmm1000
511 SWAP.W Rm,Rn              0110nnnnmmmm1001
512 XTRCT    Rm,Rn            0010nnnnmmmm1101
513 ADD         Rm,Rn    0011nnnnmmmm1100
514 ADD         #imm,Rn  0111nnnniiiiiiii
515 ADDC        Rm,Rn    0011nnnnmmmm1110
516 ADDV        Rm,Rn    0011nnnnmmmm1111
517 CMP/EQ      #imm,R0  10001000iiiiiiii
518 CMP/EQ      Rm,Rn    0011nnnnmmmm0000
519 CMP/HS      Rm,Rn    0011nnnnmmmm0010
520 CMP/GE      Rm,Rn    0011nnnnmmmm0011
521 CMP/HI      Rm,Rn    0011nnnnmmmm0110
522 CMP/GT      Rm,Rn    0011nnnnmmmm0111
523 CMP/PZ      Rn       0100nnnn00010001
524 CMP/PL      Rn       0100nnnn00010101
525 CMP/ST      Rm,Rn    0010nnnnmmmm1100
526 DIV1        Rm,Rn    0011nnnnmmmm0100
527 DMULS.      Rm,Rn    0011nnnnmmmm1101
528 DMULU.L Rm,Rn        0011nnnnmmmm0101
529 EXTS.B Rm,Rn         0110nnnnmmmm1110
530 EXTS.W Rm,Rn         0110nnnnmmmm1111
531 EXTU.B Rm,Rn         0110nnnnmmmm1100
532 EXTU.W Rm,Rn         0110nnnnmmmm1101
533 MAC       @Rm+,@Rn+  0100nnnnmmmm1111
534 MULS.W Rm,Rn         0010nnnnmmmm1111
535 MULU.W Rm,Rn         0010nnnnmmmm1110
536 NEG       Rm,Rn      0110nnnnmmmm1011
537 NEGC      Rm,Rn      0110nnnnmmmm1010
538 SUB      Rm,Rn          0011nnnnmmmm1000
539 SUBC     Rm,Rn          0011nnnnmmmm1010
540 SUBV     Rm,Rn          0011nnnnmmmm1011
541 AND      Rm,Rn               0010nnnnmmmm1001
542 AND      #imm,R0             11001001iiiiiiii
543 AND.B    #imm,@(R0,GBR)      11001101iiiiiiii
544 NOT      Rm,Rn               0110nnnnmmmm0111
545 OR       Rm,Rn               0010nnnnmmmm1011
546 OR       #imm,R0             11001011iiiiiiii
547 OR.B     #imm,@(R0,GBR)      11001111iiiiiiii
548 TAS.B    @Rn                 0100nnnn00011011
549 TST      Rm,Rn               0010nnnnmmmm1000
550 TST      #imm,R0             11001000iiiiiiii
551 TST.B    #imm,@(R0,GBR)      11001100iiiiiiii
552 XOR      Rm,Rn               0010nnnnmmmm1010
553 XOR      #imm,R0             11001010iiiiiiii
554 XOR.B    #imm,@(R0,GBR)      11001110iiiiiiii
555 ROTL     Rn        0100nnnn00000100
556 ROTR     Rn        0100nnnn00000101
557 ROTCL    Rn        0100nnnn00100100
558 ROTCR    Rn        0100nnnn00100101
559 SHAL     Rn        0100nnnn00100000
560 SHAR     Rn        0100nnnn00100001
561 SHLL     Rn        0100nnnn00000000
562 SHLR     Rn        0100nnnn00000001
563 SHLL2    Rn        0100nnnn00001000
564 SHLR2    Rn        0100nnnn00001001
565 SHLL8    Rn        0100nnnn00011000
566 SHLR8    Rn        0100nnnn00011001
567 SHLL16 Rn          0100nnnn00101000
568 SHLR16 Rn          0100nnnn00101001
569 LDC      Rm,GBR    0100mmmm00011110
570 LDC      Rm,VBR    0100mmmm00101110
571 LDC.L    @Rm+,GBR  0100mmmm00010111
572 LDC.L    @Rm+,VBR  0100mmmm00100111
573 LDS      Rm,MACH   0100mmmm00001010
574 LDS      Rm,MACL   0100mmmm00011010
575 LDS      Rm,PR     0100mmmm00101010
576 LDS.L    @Rm+,MACH 0100mmmm00000110
577 LDS.L    @Rm+,MACL 0100mmmm00010110
578 LDS.L    @Rm+,PR   0100mmmm00100110
579 STC.L    SR,@–Rn   0100nnnn00000011
580 STC.L    GBR,@–Rn  0100nnnn00010011
581 STC.L    VBR,@–Rn  0100nnnn00100011
582 STS.L    MACH,@–Rn 0100nnnn00000010
583 STS.L    MACL,@–Rn 0100nnnn00010010
584 STS.L    PR,@–Rn   0100nnnn00100010
585 TRAPA    #imm      11000011iiiiiiii
586 */
587
588 #define DELAYED_OP \
589   delayed_op = 2
590
591 #define CHECK_UNHANDLED_BITS(mask) { \
592   if ((op & (mask)) != 0) \
593     goto default_; \
594 }
595
596 #define GET_Fx() \
597   ((op >> 4) & 0x0f)
598
599 #define GET_Rm GET_Fx
600
601 #define GET_Rn() \
602   ((op >> 8) & 0x0f)
603
604 #define CHECK_FX_GT_3() \
605   if (GET_Fx() > 3) \
606     goto default_
607
608 static void *sh2_translate(SH2 *sh2, block_desc *other_block)
609 {
610   void *block_entry;
611   block_desc *this_block;
612   unsigned int pc = sh2->pc;
613   int op, delayed_op = 0, test_irq = 0;
614   int tcache_id = 0, blkid = 0;
615   int cycles = 0;
616   u32 tmp, tmp2, tmp3;
617
618   // validate PC
619   tmp = sh2->pc >> 29;
620   if ((tmp != 0 && tmp != 1 && tmp != 6) || sh2->pc == 0) {
621     printf("invalid PC, aborting: %08x\n", sh2->pc);
622     // FIXME: be less destructive
623     exit(1);
624   }
625
626   if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
627     // data_array, BIOS have separate tcache (shared)
628     tcache_id = 1 + sh2->is_slave;
629   }
630
631   tcache_ptr = tcache_ptrs[tcache_id];
632   this_block = dr_add_block(pc, tcache_id, &blkid);
633
634   tmp = tcache_ptr - tcache_bases[tcache_id];
635   if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE || this_block == NULL) {
636     flush_tcache(tcache_id);
637     tcache_ptr = tcache_ptrs[tcache_id];
638     other_block = NULL; // also gone too due to flush
639     this_block = dr_add_block(pc, tcache_id, &blkid);
640   }
641
642   this_block->next = other_block;
643   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
644     HASH_FUNC(hash_table, pc) = this_block;
645
646   block_entry = tcache_ptr;
647 #if (DRC_DEBUG & 1)
648   printf("== %csh2 block #%d,%d %08x -> %p\n", sh2->is_slave ? 's' : 'm',
649     tcache_id, block_counts[tcache_id], pc, block_entry);
650   if (other_block != NULL) {
651     printf(" hash collision with %08x\n", other_block->addr);
652     hash_collisions++;
653   }
654 #endif
655
656   while (cycles < BLOCK_CYCLE_LIMIT || delayed_op)
657   {
658     if (delayed_op > 0)
659       delayed_op--;
660
661     op = p32x_sh2_read16(pc, sh2);
662
663 #if (DRC_DEBUG & 3)
664     insns_compiled++;
665 #if (DRC_DEBUG & 2)
666     DasmSH2(sh2dasm_buff, pc, op);
667     printf("%08x %04x %s\n", pc, op, sh2dasm_buff);
668 #endif
669 #endif
670
671     pc += 2;
672     cycles++;
673
674     switch ((op >> 12) & 0x0f)
675     {
676     case 0x00:
677       switch (op & 0x0f)
678       {
679       case 0x02:
680         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
681         switch (GET_Fx())
682         {
683         case 0: // STC SR,Rn  0000nnnn00000010
684           tmp2 = SHR_SR;
685           break;
686         case 1: // STC GBR,Rn 0000nnnn00010010
687           tmp2 = SHR_GBR;
688           break;
689         case 2: // STC VBR,Rn 0000nnnn00100010
690           tmp2 = SHR_VBR;
691           break;
692         default:
693           goto default_;
694         }
695         tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
696         emith_move_r_r(tmp, tmp2);
697         goto end_op;
698       case 0x03:
699         CHECK_UNHANDLED_BITS(0xd0);
700         // BRAF Rm    0000mmmm00100011
701         // BSRF Rm    0000mmmm00000011
702         DELAYED_OP;
703         if (!(op & 0x20))
704           emit_move_r_imm32(SHR_PR, pc + 2);
705         tmp = rcache_get_reg(SHR_PPC, RC_GR_WRITE);
706         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
707         emith_move_r_r(tmp, tmp2);
708         emith_add_r_imm(tmp, pc + 2);
709         cycles++;
710         goto end_op;
711       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
712       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
713       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
714         rcache_clean();
715         tmp  = rcache_get_reg_arg(0, SHR_R0);
716         tmp2 = rcache_get_reg_arg(1, GET_Rm());
717         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_READ);
718         emith_add_r_r(tmp, tmp3);
719         emit_memhandler_write(op & 3);
720         goto end_op;
721       case 0x07:
722         // MUL.L     Rm,Rn      0000nnnnmmmm0111
723         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
724         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
725         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
726         emith_mul(tmp3, tmp2, tmp);
727         cycles++;
728         goto end_op;
729       case 0x08:
730         CHECK_UNHANDLED_BITS(0xf00);
731         switch (GET_Fx())
732         {
733         case 0: // CLRT               0000000000001000
734           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
735           emith_bic_r_imm(tmp, T);
736           break;
737         case 1: // SETT               0000000000011000
738           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
739           emith_or_r_imm(tmp, T);
740           break;
741         case 2: // CLRMAC             0000000000101000
742           tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
743           emith_move_r_imm(tmp, 0);
744           tmp = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
745           emith_move_r_imm(tmp, 0);
746           break;
747         default:
748           goto default_;
749         }
750         goto end_op;
751       case 0x09:
752         switch (GET_Fx())
753         {
754         case 0: // NOP        0000000000001001
755           CHECK_UNHANDLED_BITS(0xf00);
756           break;
757         case 1: // DIV0U      0000000000011001
758           CHECK_UNHANDLED_BITS(0xf00);
759           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
760           emith_bic_r_imm(tmp, M|Q|T);
761           break;
762         case 2: // MOVT Rn    0000nnnn00101001
763           tmp  = rcache_get_reg(SHR_SR, RC_GR_READ);
764           tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
765           emith_clear_msb(tmp2, tmp, 31);
766           break;
767         default:
768           goto default_;
769         }
770         goto end_op;
771       case 0x0a:
772         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
773         switch (GET_Fx())
774         {
775         case 0: // STS      MACH,Rn   0000nnnn00001010
776           tmp2 = rcache_get_reg(SHR_MACH, RC_GR_READ);
777           break;
778         case 1: // STS      MACL,Rn   0000nnnn00011010
779           tmp2 = rcache_get_reg(SHR_MACL, RC_GR_READ);
780           break;
781         case 2: // STS      PR,Rn     0000nnnn00101010
782           tmp2 = rcache_get_reg(SHR_PR, RC_GR_READ);
783           break;
784         default:
785           goto default_;
786         }
787         emith_move_r_r(tmp, tmp2);
788         goto end_op;
789       case 0x0b:
790         CHECK_UNHANDLED_BITS(0xf00);
791         switch (GET_Fx())
792         {
793         case 0: // RTS        0000000000001011
794           DELAYED_OP;
795           emit_move_r_r(SHR_PPC, SHR_PR);
796           cycles++;
797           break;
798         case 1: // SLEEP      0000000000011011
799           emit_move_r_imm32(SHR_PC, pc - 2);
800           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
801           emith_clear_msb(tmp, tmp, 20); // clear cycles
802           test_irq = 1;
803           cycles = 1;
804           break;
805         case 2: // RTE        0000000000101011
806           //emit_move_r_r(SHR_PC, SHR_PR);
807           emit_move_r_imm32(SHR_PC, pc - 2);
808           rcache_flush();
809           emith_pass_arg_r(0, CONTEXT_REG);
810           emith_pass_arg_imm(1, op);
811           emith_call(sh2_do_op);
812           emit_move_r_r(SHR_PPC, SHR_PC);
813           test_irq = 1;
814           cycles += 3;
815           break;
816         default:
817           goto default_;
818         }
819         goto end_op;
820       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
821       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
822       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
823         rcache_clean();
824         tmp  = rcache_get_reg_arg(0, SHR_R0);
825         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
826         emith_add_r_r(tmp, tmp2);
827         tmp  = emit_memhandler_read(op & 3);
828         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
829         rcache_free_tmp(tmp);
830         if ((op & 3) != 2) {
831           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
832         } else
833           emith_move_r_r(tmp2, tmp);
834         goto end_op;
835       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
836         // TODO
837         break;
838       }
839       goto default_;
840
841     case 0x01:
842       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
843       rcache_clean();
844       tmp  = rcache_get_reg_arg(0, GET_Rn());
845       tmp2 = rcache_get_reg_arg(1, GET_Rm());
846       emith_add_r_imm(tmp, (op & 0x0f) * 4);
847       emit_memhandler_write(2);
848       goto end_op;
849
850     case 0x02:
851       switch (op & 0x0f)
852       {
853       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
854       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
855       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
856         rcache_clean();
857         rcache_get_reg_arg(0, GET_Rn());
858         rcache_get_reg_arg(1, GET_Rm());
859         emit_memhandler_write(op & 3);
860         goto end_op;
861       case 0x04: // MOV.B Rm,@–Rn       0010nnnnmmmm0100
862       case 0x05: // MOV.W Rm,@–Rn       0010nnnnmmmm0101
863       case 0x06: // MOV.L Rm,@–Rn       0010nnnnmmmm0110
864         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
865         emith_sub_r_imm(tmp, (1 << (op & 3)));
866         rcache_clean();
867         rcache_get_reg_arg(0, GET_Rn());
868         rcache_get_reg_arg(1, GET_Rm());
869         emit_memhandler_write(op & 3);
870         goto end_op;
871       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
872         tmp  = rcache_get_reg(SHR_SR, RC_GR_RMW);
873         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
874         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
875         emith_bic_r_imm(tmp, M|Q|T);
876         emith_tst_r_imm(tmp2, (1<<31));
877         EMITH_SJMP_START(DCOND_EQ);
878         emith_or_r_imm_c(DCOND_NE, tmp, Q);
879         EMITH_SJMP_END(DCOND_EQ);
880         emith_tst_r_imm(tmp3, (1<<31));
881         EMITH_SJMP_START(DCOND_EQ);
882         emith_or_r_imm_c(DCOND_NE, tmp, M);
883         EMITH_SJMP_END(DCOND_EQ);
884         emith_teq_r_r(tmp2, tmp3);
885         EMITH_SJMP_START(DCOND_PL);
886         emith_or_r_imm_c(DCOND_MI, tmp, T);
887         EMITH_SJMP_END(DCOND_PL);
888         goto end_op;
889       }
890       goto default_;
891
892     case 0x04:
893       switch (op & 0x0f) {
894       case 0x00:
895         if ((op & 0xf0) != 0x10)
896           goto default_;
897         // DT Rn      0100nnnn00010000
898         if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2
899           emith_sh2_dtbf_loop();
900           goto end_op;
901         }
902         tmp = rcache_get_reg((op >> 8) & 0x0f, RC_GR_RMW);
903         tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
904         emith_bic_r_imm(tmp2, T);
905         emith_subf_r_imm(tmp, 1);
906         EMITH_SJMP_START(DCOND_NE);
907         emith_or_r_imm_c(DCOND_EQ, tmp2, T);
908         EMITH_SJMP_END(DCOND_NE);
909         goto end_op;
910       case 0x07:
911         if ((op & 0xf0) != 0)
912           goto default_;
913         // LDC.L @Rm+,SR  0100mmmm00000111
914         test_irq = 1;
915         goto default_;
916       case 0x0b:
917         if ((op & 0xd0) != 0)
918           goto default_;
919         // JMP  @Rm   0100mmmm00101011
920         // JSR  @Rm   0100mmmm00001011
921         DELAYED_OP;
922         if (!(op & 0x20))
923           emit_move_r_imm32(SHR_PR, pc + 2);
924         emit_move_r_r(SHR_PPC, (op >> 8) & 0x0f);
925         cycles++;
926         goto end_op;
927       case 0x0e:
928         if ((op & 0xf0) != 0)
929           goto default_;
930         // LDC Rm,SR  0100mmmm00001110
931         test_irq = 1;
932         goto default_;
933       }
934       goto default_;
935
936     case 0x08:
937       switch (op & 0x0f00) {
938       // BT/S label 10001101dddddddd
939       case 0x0d00:
940       // BF/S label 10001111dddddddd
941       case 0x0f00:
942         DELAYED_OP;
943         cycles--;
944         // fallthrough
945       // BT   label 10001001dddddddd
946       case 0x0900:
947       // BF   label 10001011dddddddd
948       case 0x0b00: {
949         // jmp_cond ~ cond when guest doesn't jump
950         int jmp_cond  = (op & 0x0200) ? DCOND_NE : DCOND_EQ;
951         int insn_cond = (op & 0x0200) ? DCOND_EQ : DCOND_NE;
952         signed int offs = ((signed int)(op << 24) >> 23);
953         tmp = rcache_get_reg(delayed_op ? SHR_PPC : SHR_PC, RC_GR_WRITE);
954         emith_move_r_imm(tmp, pc + (delayed_op ? 2 : 0));
955         emith_sh2_test_t();
956         EMITH_SJMP_START(jmp_cond);
957         if (!delayed_op)
958           offs += 2;
959         if (offs < 0) {
960           emith_sub_r_imm_c(insn_cond, tmp, -offs);
961         } else
962           emith_add_r_imm_c(insn_cond, tmp, offs);
963         EMITH_SJMP_END(jmp_cond);
964         cycles += 2;
965         if (!delayed_op)
966           goto end_block;
967         goto end_op;
968       }}
969       goto default_;
970
971     case 0x0a:
972       // BRA  label 1010dddddddddddd
973       DELAYED_OP;
974     do_bra:
975       tmp = ((signed int)(op << 20) >> 19);
976       emit_move_r_imm32(SHR_PPC, pc + tmp + 2);
977       cycles++;
978       break;
979
980     case 0x0b:
981       // BSR  label 1011dddddddddddd
982       DELAYED_OP;
983       emit_move_r_imm32(SHR_PR, pc + 2);
984       goto do_bra;
985
986     default:
987     default_:
988       emit_move_r_imm32(SHR_PC, pc - 2);
989       rcache_flush();
990       emith_pass_arg_r(0, CONTEXT_REG);
991       emith_pass_arg_imm(1, op);
992       emith_call(sh2_do_op);
993       break;
994     }
995
996 end_op:
997     if (delayed_op == 1)
998       emit_move_r_r(SHR_PC, SHR_PPC);
999
1000     if (test_irq && delayed_op != 2) {
1001       rcache_flush();
1002       emith_pass_arg_r(0, CONTEXT_REG);
1003       emith_call(sh2_test_irq);
1004       break;
1005     }
1006     if (delayed_op == 1)
1007       break;
1008
1009     do_host_disasm(tcache_id);
1010   }
1011
1012 end_block:
1013   this_block->end_addr = pc;
1014
1015   // mark memory blocks as containing compiled code
1016   if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1017     // data array, BIOS
1018     u16 *drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
1019     tmp =  (this_block->addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1020     tmp2 = (this_block->end_addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1021     Pico32xMem->drcblk_da[sh2->is_slave][tmp] = (blkid << 1) | 1;
1022     for (++tmp; tmp < tmp2; tmp++) {
1023       if (drcblk[tmp])
1024         break; // dont overwrite overlay block
1025       drcblk[tmp] = blkid << 1;
1026     }
1027   }
1028   else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
1029     tmp =  (this_block->addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1030     tmp2 = (this_block->end_addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1031     Pico32xMem->drcblk_ram[tmp] = (blkid << 1) | 1;
1032     for (++tmp; tmp < tmp2; tmp++) {
1033       if (Pico32xMem->drcblk_ram[tmp])
1034         break;
1035       Pico32xMem->drcblk_ram[tmp] = blkid << 1;
1036     }
1037   }
1038
1039   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
1040   emith_sub_r_imm(tmp, cycles << 12);
1041   rcache_flush();
1042   emith_jump(sh2_drc_exit);
1043   tcache_ptrs[tcache_id] = tcache_ptr;
1044
1045 #ifdef ARM
1046   cache_flush_d_inval_i(block_entry, tcache_ptr);
1047 #endif
1048
1049   do_host_disasm(tcache_id);
1050   dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
1051     tcache_id, block_counts[tcache_id],
1052     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
1053     insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
1054   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
1055     dbg(1, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
1056 #if (DRC_DEBUG & 2)
1057   fflush(stdout);
1058 #endif
1059
1060   return block_entry;
1061 /*
1062 unimplemented:
1063   // last op
1064   do_host_disasm(tcache_id);
1065   exit(1);
1066 */
1067 }
1068
1069 void __attribute__((noinline)) sh2_drc_dispatcher(SH2 *sh2)
1070 {
1071   while (((signed int)sh2->sr >> 12) > 0)
1072   {
1073     void *block = NULL;
1074     block_desc *bd = NULL;
1075
1076     // FIXME: must avoid doing it so often..
1077     sh2_test_irq(sh2);
1078
1079     // we have full block id tables for data_array and RAM
1080     // BIOS goes to data_array table too
1081     if ((sh2->pc & 0xff000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1082       int blkid = Pico32xMem->drcblk_da[sh2->is_slave][(sh2->pc & 0xfff) >> SH2_DRCBLK_DA_SHIFT];
1083       if (blkid & 1) {
1084         bd = &block_tables[1 + sh2->is_slave][blkid >> 1];
1085         block = bd->tcache_ptr;
1086       }
1087     }
1088     // RAM
1089     else if ((sh2->pc & 0xc6000000) == 0x06000000) {
1090       int blkid = Pico32xMem->drcblk_ram[(sh2->pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT];
1091       if (blkid & 1) {
1092         bd = &block_tables[0][blkid >> 1];
1093         block = bd->tcache_ptr;
1094       }
1095     }
1096     // ROM
1097     else if ((sh2->pc & 0xc6000000) == 0x02000000) {
1098       bd = HASH_FUNC(hash_table, sh2->pc);
1099
1100       if (bd != NULL) {
1101         if (bd->addr == sh2->pc)
1102           block = bd->tcache_ptr;
1103         else
1104           block = dr_find_block(bd, sh2->pc);
1105       }
1106     }
1107
1108     if (block == NULL)
1109       block = sh2_translate(sh2, bd);
1110
1111     dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
1112       sh2->pc, block, (signed int)sh2->sr >> 12);
1113 #if (DRC_DEBUG & 1)
1114     if (bd != NULL)
1115       bd->refcount++;
1116 #endif
1117     sh2_drc_entry(sh2, block);
1118   }
1119 }
1120
1121 static void sh2_smc_rm_block(u16 *drcblk, u16 *p, block_desc *btab, u32 a)
1122 {
1123   u16 id = *p >> 1;
1124   block_desc *bd = btab + id;
1125
1126   dbg(1, "  killing block %08x", bd->addr);
1127   bd->addr = bd->end_addr = 0;
1128
1129   while (p > drcblk && (p[-1] >> 1) == id)
1130     p--;
1131
1132   // check for possible overlay block
1133   if (p > 0 && p[-1] != 0) {
1134     bd = btab + (p[-1] >> 1);
1135     if (bd->addr <= a && a < bd->end_addr)
1136       sh2_smc_rm_block(drcblk, p - 1, btab, a);
1137   }
1138
1139   do {
1140     *p++ = 0;
1141   }
1142   while ((*p >> 1) == id);
1143 }
1144
1145 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
1146 {
1147   u16 *drcblk = Pico32xMem->drcblk_ram;
1148   u16 *p = drcblk + ((a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT);
1149
1150   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1151   sh2_smc_rm_block(drcblk, p, block_tables[0], a);
1152 }
1153
1154 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
1155 {
1156   u16 *drcblk = Pico32xMem->drcblk_da[cpuid];
1157   u16 *p = drcblk + ((a & 0xfff) >> SH2_DRCBLK_DA_SHIFT);
1158
1159   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1160   sh2_smc_rm_block(drcblk, p, block_tables[1 + cpuid], a);
1161 }
1162
1163 void sh2_execute(SH2 *sh2, int cycles)
1164 {
1165   sh2->cycles_aim += cycles;
1166   cycles = sh2->cycles_aim - sh2->cycles_done;
1167
1168   // cycles are kept in SHR_SR unused bits (upper 20)
1169   sh2->sr &= 0x3f3;
1170   sh2->sr |= cycles << 12;
1171   sh2_drc_dispatcher(sh2);
1172
1173   sh2->cycles_done += cycles - ((signed int)sh2->sr >> 12);
1174 }
1175
1176 static void REGPARM(1) sh2_test_irq(SH2 *sh2)
1177 {
1178   if (sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
1179   {
1180     if (sh2->pending_irl > sh2->pending_int_irq)
1181       sh2_do_irq(sh2, sh2->pending_irl, 64 + sh2->pending_irl/2);
1182     else {
1183       sh2_do_irq(sh2, sh2->pending_int_irq, sh2->pending_int_vector);
1184       sh2->pending_int_irq = 0; // auto-clear
1185       sh2->pending_level = sh2->pending_irl;
1186     }
1187   }
1188 }
1189
1190 #if (DRC_DEBUG & 1)
1191 static void block_stats(void)
1192 {
1193   int c, b, i, total = 0;
1194
1195   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1196     for (i = 0; i < block_counts[b]; i++)
1197       if (block_tables[b][i].addr != 0)
1198         total += block_tables[b][i].refcount;
1199
1200   for (c = 0; c < 10; c++) {
1201     block_desc *blk, *maxb = NULL;
1202     int max = 0;
1203     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
1204       for (i = 0; i < block_counts[b]; i++) {
1205         blk = &block_tables[b][i];
1206         if (blk->addr != 0 && blk->refcount > max) {
1207           max = blk->refcount;
1208           maxb = blk;
1209         }
1210       }
1211     }
1212     if (maxb == NULL)
1213       break;
1214     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
1215       (double)maxb->refcount / total * 100.0);
1216     maxb->refcount = 0;
1217   }
1218
1219   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1220     for (i = 0; i < block_counts[b]; i++)
1221       block_tables[b][i].refcount = 0;
1222 }
1223 #else
1224 #define block_stats()
1225 #endif
1226
1227 void sh2_drc_flush_all(void)
1228 {
1229   block_stats();
1230   flush_tcache(0);
1231   flush_tcache(1);
1232   flush_tcache(2);
1233 }
1234
1235 int sh2_drc_init(SH2 *sh2)
1236 {
1237   if (block_tables[0] == NULL) {
1238     int i, cnt;
1239
1240     drc_cmn_init();
1241
1242     cnt = block_max_counts[0] + block_max_counts[1] + block_max_counts[2];
1243     block_tables[0] = calloc(cnt, sizeof(*block_tables[0]));
1244     if (block_tables[0] == NULL)
1245       return -1;
1246
1247     memset(block_counts, 0, sizeof(block_counts));
1248     tcache_bases[0] = tcache_ptrs[0] = tcache;
1249
1250     for (i = 1; i < ARRAY_SIZE(block_tables); i++) {
1251       block_tables[i] = block_tables[i - 1] + block_max_counts[i - 1];
1252       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
1253     }
1254
1255     // tmp
1256     PicoOpt |= POPT_DIS_VDP_FIFO;
1257
1258 #if (DRC_DEBUG & 2)
1259     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
1260       tcache_dsm_ptrs[i] = tcache_bases[i];
1261 #endif
1262 #if (DRC_DEBUG & 1)
1263     hash_collisions = 0;
1264 #endif
1265   }
1266
1267   if (hash_table == NULL) {
1268     hash_table = calloc(sizeof(hash_table[0]), MAX_HASH_ENTRIES);
1269     if (hash_table == NULL)
1270       return -1;
1271   }
1272
1273   return 0;
1274 }
1275
1276 void sh2_drc_finish(SH2 *sh2)
1277 {
1278   if (block_tables[0] != NULL) {
1279     block_stats();
1280     free(block_tables[0]);
1281     memset(block_tables, 0, sizeof(block_tables));
1282
1283     drc_cmn_cleanup();
1284   }
1285
1286   if (hash_table != NULL) {
1287     free(hash_table);
1288     hash_table = NULL;
1289   }
1290 }