32x: drc: self-reentrant blocks
[picodrive.git] / cpu / sh2 / compiler.c
1 /*
2  * vim:shiftwidth=2:expandtab
3  */
4 #include <stddef.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <assert.h>
8
9 #include "../../pico/pico_int.h"
10 #include "sh2.h"
11 #include "compiler.h"
12 #include "../drc/cmn.h"
13
14 // debug stuff {
15 #ifndef DRC_DEBUG
16 #define DRC_DEBUG 0
17 #endif
18
19 #if DRC_DEBUG
20 #define dbg(l,...) { \
21   if ((l) & DRC_DEBUG) \
22     elprintf(EL_STATUS, ##__VA_ARGS__); \
23 }
24
25 #include "mame/sh2dasm.h"
26 #include <platform/linux/host_dasm.h>
27 static int insns_compiled, hash_collisions, host_insn_count;
28 #define COUNT_OP \
29         host_insn_count++
30 #else // !DRC_DEBUG
31 #define COUNT_OP
32 #define dbg(...)
33 #endif
34
35 #if (DRC_DEBUG & 2)
36 static u8 *tcache_dsm_ptrs[3];
37 static char sh2dasm_buff[64];
38 #define do_host_disasm(tcid) \
39   host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
40   tcache_dsm_ptrs[tcid] = tcache_ptr
41 #else
42 #define do_host_disasm(x)
43 #endif
44 // } debug
45
46 #define BLOCK_CYCLE_LIMIT 100
47 #define MAX_BLOCK_SIZE (BLOCK_CYCLE_LIMIT * 6 * 6)
48
49 // we have 3 translation cache buffers, split from one drc/cmn buffer.
50 // BIOS shares tcache with data array because it's only used for init
51 // and can be discarded early
52 // XXX: need to tune sizes
53 static const int tcache_sizes[3] = {
54   DRC_TCACHE_SIZE * 6 / 8, // ROM, DRAM
55   DRC_TCACHE_SIZE / 8, // BIOS, data array in master sh2
56   DRC_TCACHE_SIZE / 8, // ... slave
57 };
58
59 static u8 *tcache_bases[3];
60 static u8 *tcache_ptrs[3];
61
62 // ptr for code emiters
63 static u8 *tcache_ptr;
64
65 // host register tracking
66 enum {
67   HR_FREE,
68   HR_CACHED, // 'val' has sh2_reg_e
69   HR_CACHED_DIRTY,
70   HR_CONST,  // 'val' has constant
71   HR_TEMP,   // reg used for temp storage
72 };
73
74 typedef struct {
75   u8 reg;
76   u8 type;
77   u16 stamp; // kind of a timestamp
78   u32 val;
79 } temp_reg_t;
80
81 // note: reg_temp[] must have at least the amount of
82 // registers used by handlers in worst case (currently 4)
83 #ifdef ARM
84 #include "../drc/emit_arm.c"
85
86 static const int reg_map_g2h[] = {
87    4,  5,  6,  7,
88    8, -1, -1, -1,
89   -1, -1, -1, -1,
90   -1, -1, -1,  9,
91   -1, -1, -1, 10,
92   -1, -1, -1, -1,
93 };
94
95 static temp_reg_t reg_temp[] = {
96   {  0, },
97   {  1, },
98   { 12, },
99   { 14, },
100   {  2, },
101   {  3, },
102 };
103
104 #else
105 #include "../drc/emit_x86.c"
106
107 static const int reg_map_g2h[] = {
108   xSI,-1, -1, -1,
109   -1, -1, -1, -1,
110   -1, -1, -1, -1,
111   -1, -1, -1, -1,
112   -1, -1, -1, xDI,
113   -1, -1, -1, -1,
114 };
115
116 // ax, cx, dx are usually temporaries by convention
117 static temp_reg_t reg_temp[] = {
118   { xAX, },
119   { xBX, },
120   { xCX, },
121   { xDX, },
122 };
123
124 #endif
125
126 #define T       0x00000001
127 #define S       0x00000002
128 #define I       0x000000f0
129 #define Q       0x00000100
130 #define M       0x00000200
131 #define T_save  0x00000800
132
133 #define Q_SHIFT 8
134 #define M_SHIFT 9
135
136 typedef struct block_desc_ {
137   u32 addr;                  // SH2 PC address
138   u32 end_addr;              // TODO rm?
139   void *tcache_ptr;          // translated block for above PC
140   struct block_desc_ *next;  // next block with the same PC hash
141 #if (DRC_DEBUG & 1)
142   int refcount;
143 #endif
144 } block_desc;
145
146 static const int block_max_counts[3] = {
147   4*1024,
148   256,
149   256,
150 };
151 static block_desc *block_tables[3];
152 static int block_counts[3];
153
154 // ROM hash table
155 #define MAX_HASH_ENTRIES 1024
156 #define HASH_MASK (MAX_HASH_ENTRIES - 1)
157 static void **hash_table;
158
159 #define HASH_FUNC(hash_tab, addr) \
160   ((block_desc **)(hash_tab))[(addr) & HASH_MASK]
161
162 static void REGPARM(2) (*sh2_drc_entry)(const void *block, SH2 *sh2);
163 static void (*sh2_drc_exit)(void);
164
165 // tmp
166 extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
167 static void REGPARM(1) sh2_test_irq(SH2 *sh2);
168
169 static void flush_tcache(int tcid)
170 {
171   dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
172     tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
173     block_counts[tcid], block_max_counts[tcid]);
174
175   block_counts[tcid] = 0;
176   tcache_ptrs[tcid] = tcache_bases[tcid];
177   if (tcid == 0) { // ROM, RAM
178     memset(hash_table, 0, sizeof(hash_table[0]) * MAX_HASH_ENTRIES);
179     memset(Pico32xMem->drcblk_ram, 0, sizeof(Pico32xMem->drcblk_ram));
180   }
181   else
182     memset(Pico32xMem->drcblk_da[tcid - 1], 0, sizeof(Pico32xMem->drcblk_da[0]));
183 #if (DRC_DEBUG & 2)
184   tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
185 #endif
186 }
187
188 static void *dr_find_block(block_desc *tab, u32 addr)
189 {
190   for (tab = tab->next; tab != NULL; tab = tab->next)
191     if (tab->addr == addr)
192       break;
193
194   if (tab != NULL)
195     return tab->tcache_ptr;
196
197   printf("block miss for %08x\n", addr);
198   return NULL;
199 }
200
201 static block_desc *dr_add_block(u32 addr, int tcache_id, int *blk_id)
202 {
203   int *bcount = &block_counts[tcache_id];
204   block_desc *bd;
205
206   if (*bcount >= block_max_counts[tcache_id])
207     return NULL;
208
209   bd = &block_tables[tcache_id][*bcount];
210   bd->addr = addr;
211   bd->tcache_ptr = tcache_ptr;
212   *blk_id = *bcount;
213   (*bcount)++;
214
215   if ((addr & 0xc6000000) == 0x02000000) { // ROM
216     bd->next = HASH_FUNC(hash_table, addr);
217     HASH_FUNC(hash_table, addr) = bd;
218 #if (DRC_DEBUG & 1)
219     if (bd->next != NULL) {
220       printf(" hash collision with %08x\n", bd->next->addr);
221       hash_collisions++;
222     }
223 #endif
224   }
225
226   return bd;
227 }
228
229 int find_in_array(u32 *array, size_t size, u32 what)
230 {
231   size_t i;
232   for (i = 0; i < size; i++)
233     if (what == array[i])
234       return i;
235
236   return -1;
237 }
238
239 // ---------------------------------------------------------------
240
241 // register chache
242 static u16 rcache_counter;
243
244 static temp_reg_t *rcache_evict(void)
245 {
246   // evict reg with oldest stamp
247   int i, oldest = -1;
248   u16 min_stamp = (u16)-1;
249
250   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
251     if (reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY)
252       if (reg_temp[i].stamp <= min_stamp) {
253         min_stamp = reg_temp[i].stamp;
254         oldest = i;
255       }
256   }
257
258   if (oldest == -1) {
259     printf("no registers to evict, aborting\n");
260     exit(1);
261   }
262
263   i = oldest;
264   if (reg_temp[i].type == HR_CACHED_DIRTY) {
265     // writeback
266     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
267   }
268
269   return &reg_temp[i];
270 }
271
272 typedef enum {
273   RC_GR_READ,
274   RC_GR_WRITE,
275   RC_GR_RMW,
276 } rc_gr_mode;
277
278 // note: must not be called when doing conditional code
279 static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
280 {
281   temp_reg_t *tr;
282   int i;
283
284   // maybe already statically mapped?
285   i = reg_map_g2h[r];
286   if (i != -1)
287     return i;
288
289   rcache_counter++;
290
291   // maybe already cached?
292   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
293     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
294          reg_temp[i].val == r)
295     {
296       reg_temp[i].stamp = rcache_counter;
297       if (mode != RC_GR_READ)
298         reg_temp[i].type = HR_CACHED_DIRTY;
299       return reg_temp[i].reg;
300     }
301   }
302
303   // use any free reg
304   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; 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
311   tr = rcache_evict();
312
313 do_alloc:
314   if (mode != RC_GR_WRITE)
315     emith_ctx_read(tr->reg, r * 4);
316
317   tr->type = mode != RC_GR_READ ? HR_CACHED_DIRTY : HR_CACHED;
318   tr->val = r;
319   tr->stamp = rcache_counter;
320   return tr->reg;
321 }
322
323 static int rcache_get_tmp(void)
324 {
325   temp_reg_t *tr;
326   int i;
327
328   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
329     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
330       tr = &reg_temp[i];
331       goto do_alloc;
332     }
333
334   tr = rcache_evict();
335
336 do_alloc:
337   tr->type = HR_TEMP;
338   return tr->reg;
339 }
340
341 static int rcache_get_arg_id(int arg)
342 {
343   int i, r = 0;
344   host_arg2reg(r, arg);
345
346   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
347     if (reg_temp[i].reg == r)
348       break;
349
350   if (i == ARRAY_SIZE(reg_temp))
351     // let's just say it's untracked arg reg
352     return r;
353
354   if (reg_temp[i].type == HR_CACHED_DIRTY) {
355     // writeback
356     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
357   }
358   else if (reg_temp[i].type == HR_TEMP) {
359     printf("arg %d reg %d already used, aborting\n", arg, r);
360     exit(1);
361   }
362
363   return i;
364 }
365
366 // get a reg to be used as function arg
367 // it's assumed that regs are cleaned before call
368 static int rcache_get_tmp_arg(int arg)
369 {
370   int id = rcache_get_arg_id(arg);
371   reg_temp[id].type = HR_TEMP;
372
373   return reg_temp[id].reg;
374 }
375
376 // same but caches reg. RC_GR_READ only.
377 static int rcache_get_reg_arg(int arg, sh2_reg_e r)
378 {
379   int i, srcr, dstr, dstid;
380
381   dstid = rcache_get_arg_id(arg);
382   dstr = reg_temp[dstid].reg;
383
384   // maybe already statically mapped?
385   srcr = reg_map_g2h[r];
386   if (srcr != -1)
387     goto do_cache;
388
389   // maybe already cached?
390   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
391     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
392          reg_temp[i].val == r)
393     {
394       srcr = reg_temp[i].reg;
395       goto do_cache;
396     }
397   }
398
399   // must read
400   srcr = dstr;
401   emith_ctx_read(srcr, r * 4);
402
403 do_cache:
404   if (srcr != dstr)
405     emith_move_r_r(dstr, srcr);
406
407   reg_temp[dstid].stamp = ++rcache_counter;
408   reg_temp[dstid].type = HR_CACHED;
409   reg_temp[dstid].val = r;
410   return dstr;
411 }
412
413 static void rcache_free_tmp(int hr)
414 {
415   int i;
416   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
417     if (reg_temp[i].reg == hr)
418       break;
419
420   if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
421     printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
422     return;
423   }
424
425   reg_temp[i].type = HR_FREE;
426 }
427
428 static void rcache_clean(void)
429 {
430   int i;
431   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
432     if (reg_temp[i].type == HR_CACHED_DIRTY) {
433       // writeback
434       emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
435       reg_temp[i].type = HR_CACHED;
436     }
437 }
438
439 static void rcache_invalidate(void)
440 {
441   int i;
442   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
443     reg_temp[i].type = HR_FREE;
444   rcache_counter = 0;
445 }
446
447 static void rcache_flush(void)
448 {
449   rcache_clean();
450   rcache_invalidate();
451 }
452
453 // ---------------------------------------------------------------
454
455 static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
456 {
457   // TODO: propagate this constant
458   int hr = rcache_get_reg(dst, RC_GR_WRITE);
459   emith_move_r_imm(hr, imm);
460 }
461
462 static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
463 {
464   int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
465   int hr_s = rcache_get_reg(src, RC_GR_READ);
466
467   emith_move_r_r(hr_d, hr_s);
468 }
469
470 // T must be clear, and comparison done just before this
471 static void emit_or_t_if_eq(int srr)
472 {
473   EMITH_SJMP_START(DCOND_NE);
474   emith_or_r_imm_c(DCOND_EQ, srr, T);
475   EMITH_SJMP_END(DCOND_NE);
476 }
477
478 // arguments must be ready
479 // reg cache must be clean before call
480 static int emit_memhandler_read(int size)
481 {
482   int ctxr;
483   host_arg2reg(ctxr, 1);
484   emith_move_r_r(ctxr, CONTEXT_REG);
485   switch (size) {
486   case 0: // 8
487     emith_call(p32x_sh2_read8);
488     break;
489   case 1: // 16
490     emith_call(p32x_sh2_read16);
491     break;
492   case 2: // 32
493     emith_call(p32x_sh2_read32);
494     break;
495   }
496   rcache_invalidate();
497   // assuming arg0 and retval reg matches
498   return rcache_get_tmp_arg(0);
499 }
500
501 static void emit_memhandler_write(int size)
502 {
503   int ctxr;
504   host_arg2reg(ctxr, 2);
505   emith_move_r_r(ctxr, CONTEXT_REG);
506   switch (size) {
507   case 0: // 8
508     emith_call(p32x_sh2_write8);
509     break;
510   case 1: // 16
511     emith_call(p32x_sh2_write16);
512     break;
513   case 2: // 32
514     emith_call(p32x_sh2_write32);
515     break;
516   }
517   rcache_invalidate();
518 }
519
520 // @(Rx,Ry)
521 static int emit_indirect_indexed_read(int rx, int ry, int size)
522 {
523   int a0, t;
524   rcache_clean();
525   a0 = rcache_get_reg_arg(0, rx);
526   t  = rcache_get_reg(ry, RC_GR_READ);
527   emith_add_r_r(a0, t);
528   return emit_memhandler_read(size);
529 }
530
531 // tmp_wr -> @(Rx,Ry)
532 static void emit_indirect_indexed_write(int tmp_wr, int rx, int ry, int size)
533 {
534   int a0, t;
535   rcache_clean();
536   t = rcache_get_tmp_arg(1);
537   emith_move_r_r(t, tmp_wr);
538   a0 = rcache_get_reg_arg(0, rx);
539   t  = rcache_get_reg(ry, RC_GR_READ);
540   emith_add_r_r(a0, t);
541   emit_memhandler_write(size);
542 }
543
544 // read @Rn, @rm
545 static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size)
546 {
547   int tmp;
548
549   rcache_clean();
550   rcache_get_reg_arg(0, rn);
551   tmp = emit_memhandler_read(size);
552   emith_ctx_write(tmp, offsetof(SH2, drc_tmp));
553   rcache_free_tmp(tmp);
554   tmp = rcache_get_reg(rn, RC_GR_RMW);
555   emith_add_r_imm(tmp, 1 << size);
556
557   rcache_clean();
558   rcache_get_reg_arg(0, rm);
559   *rmr = emit_memhandler_read(size);
560   *rnr = rcache_get_tmp();
561   emith_ctx_read(*rnr, offsetof(SH2, drc_tmp));
562   tmp = rcache_get_reg(rm, RC_GR_RMW);
563   emith_add_r_imm(tmp, 1 << size);
564 }
565  
566 static void emit_do_static_regs(int is_write, int tmpr)
567 {
568   int i, r, count;
569
570   for (i = 0; i < ARRAY_SIZE(reg_map_g2h); i++) {
571     r = reg_map_g2h[i];
572     if (r == -1)
573       continue;
574
575     for (count = 1; i < ARRAY_SIZE(reg_map_g2h) - 1; i++, r++) {
576       if (reg_map_g2h[i + 1] != r + 1)
577         break;
578       count++;
579     }
580
581     if (count > 1) {
582       // i, r point to last item
583       if (is_write)
584         emith_ctx_write_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
585       else
586         emith_ctx_read_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
587     } else {
588       if (is_write)
589         emith_ctx_write(r, i * 4);
590       else
591         emith_ctx_read(r, i * 4);
592     }
593   }
594 }
595
596 static void sh2_generate_utils(void)
597 {
598   int ctx, blk, tmp;
599
600   host_arg2reg(blk, 0);
601   host_arg2reg(ctx, 1);
602   host_arg2reg(tmp, 2);
603
604   // sh2_drc_entry(void *block, SH2 *sh2)
605   sh2_drc_entry = (void *)tcache_ptr;
606   emith_sh2_drc_entry();
607   emith_move_r_r(CONTEXT_REG, ctx); // move ctx, arg1
608   emit_do_static_regs(0, tmp);
609   emith_jump_reg(blk); // jump arg0
610
611   // sh2_drc_exit(void)
612   sh2_drc_exit = (void *)tcache_ptr;
613   emit_do_static_regs(1, tmp);
614   emith_sh2_drc_exit();
615
616   rcache_invalidate();
617 }
618
619 #define DELAYED_OP \
620   drcf.delayed_op = 2
621
622 #define DELAY_SAVE_T(sr) { \
623   emith_bic_r_imm(sr, T_save); \
624   emith_tst_r_imm(sr, T);      \
625   EMITH_SJMP_START(DCOND_EQ);  \
626   emith_or_r_imm_c(DCOND_NE, sr, T_save); \
627   EMITH_SJMP_END(DCOND_EQ);    \
628   drcf.use_saved_t = 1;        \
629 }
630
631 #define CHECK_UNHANDLED_BITS(mask) { \
632   if ((op & (mask)) != 0) \
633     goto default_; \
634 }
635
636 #define GET_Fx() \
637   ((op >> 4) & 0x0f)
638
639 #define GET_Rm GET_Fx
640
641 #define GET_Rn() \
642   ((op >> 8) & 0x0f)
643
644 #define CHECK_FX_LT(n) \
645   if (GET_Fx() >= n) \
646     goto default_
647
648 #define MAX_LOCAL_BRANCHES 16
649
650 // op_flags: data from 1st pass
651 #define OP_FLAGS(pc) op_flags[((pc) - base_pc) / 2]
652 #define OF_DELAY_OP (1 << 0)
653
654 static void *sh2_translate(SH2 *sh2, int tcache_id)
655 {
656   // XXX: maybe use structs instead?
657   void *branch_target_ptr[MAX_LOCAL_BRANCHES];
658   u32 branch_target_pc[MAX_LOCAL_BRANCHES];
659   int branch_target_count = 0;
660   void *branch_patch_ptr[MAX_LOCAL_BRANCHES];
661   u32 branch_patch_pc[MAX_LOCAL_BRANCHES];
662   int branch_patch_count = 0;
663   int branch_patch_cond = -1;
664   u8 op_flags[BLOCK_CYCLE_LIMIT + 1];
665   struct {
666     u32 delayed_op:2;
667     u32 test_irq:1;
668     u32 use_saved_t:1; // delayed op modifies T
669   } drcf = { 0, };
670
671   void *block_entry;
672   block_desc *this_block;
673   u32 pc, base_pc, end_pc; // PC of current, first, last insn
674   int blkid_main = 0;
675   u32 tmp, tmp2;
676   int cycles;
677   int op;
678   int i;
679
680   base_pc = sh2->pc;
681
682   // validate PC
683   tmp = base_pc >> 29;
684   if ((tmp != 0 && tmp != 1 && tmp != 6) || base_pc == 0) {
685     printf("invalid PC, aborting: %08x\n", base_pc);
686     // FIXME: be less destructive
687     exit(1);
688   }
689
690   tcache_ptr = tcache_ptrs[tcache_id];
691   this_block = dr_add_block(base_pc, tcache_id, &blkid_main);
692
693   // predict tcache overflow
694   tmp = tcache_ptr - tcache_bases[tcache_id];
695   if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE || this_block == NULL)
696     return NULL;
697
698   block_entry = tcache_ptr;
699   dbg(1, "== %csh2 block #%d,%d %08x -> %p", sh2->is_slave ? 's' : 'm',
700     tcache_id, blkid_main, base_pc, block_entry);
701
702   // 1st pass: scan forward for local branches
703   memset(op_flags, 0, sizeof(op_flags));
704   for (cycles = 0, pc = base_pc; cycles < BLOCK_CYCLE_LIMIT; cycles++, pc += 2) {
705     op = p32x_sh2_read16(pc, sh2);
706     if ((op & 0xf000) == 0xa000 || (op & 0xf000) == 0xb000) { // BRA, BSR
707       pc += 2;
708       OP_FLAGS(pc) |= OF_DELAY_OP;
709       break;
710     }
711     if ((op & 0xf000) == 0) {
712       op &= 0xff;
713       if (op == 0x23 || op == 0x03 || op == 0x0b) { // BRAF, BSRF, RTS
714         pc += 2;
715         OP_FLAGS(pc) |= OF_DELAY_OP;
716         break;
717       }
718       continue;
719     }
720     if ((op & 0xf0df) == 0x400b) { // JMP, JSR
721       pc += 2;
722       OP_FLAGS(pc) |= OF_DELAY_OP;
723       break;
724     }
725     if ((op & 0xf900) == 0x8900) { // BT(S), BF(S)
726       signed int offs = ((signed int)(op << 24) >> 23);
727       if (op & 0x0400)
728         OP_FLAGS(pc + 2) |= OF_DELAY_OP;
729       branch_target_pc[branch_target_count++] = pc + offs + 4;
730       if (branch_target_count == MAX_LOCAL_BRANCHES) {
731         printf("warning: branch target overflow\n");
732         // will only spawn additional blocks
733         break;
734       }
735     }
736   }
737
738   end_pc = pc;
739
740   // clean branch_targets that are not really local,
741   // and that land on delay slots
742   for (i = 0, tmp = 0; i < branch_target_count; i++) {
743     pc = branch_target_pc[i];
744     if (base_pc <= pc && pc <= end_pc && !(OP_FLAGS(pc) & OF_DELAY_OP))
745       branch_target_pc[tmp++] = branch_target_pc[i];
746   }
747   branch_target_count = tmp;
748   memset(branch_target_ptr, 0, sizeof(branch_target_ptr[0]) * branch_target_count);
749
750   // -------------------------------------------------
751   // 2nd pass: actual compilation
752   pc = base_pc;
753   for (cycles = 0; pc <= end_pc || drcf.delayed_op; )
754   {
755     u32 tmp3, tmp4, sr;
756
757     if (drcf.delayed_op > 0)
758       drcf.delayed_op--;
759
760     i = find_in_array(branch_target_pc, branch_target_count, pc);
761     if (i >= 0)
762     {
763       if (pc != sh2->pc)
764       {
765         /* make "subblock" - just a mid-block entry */
766         block_desc *subblock;
767         u16 *drcblk;
768         int blkid;
769
770         sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
771         emith_sub_r_imm(sr, cycles << 12);
772         cycles = 0;
773         rcache_flush();
774         do_host_disasm(tcache_id);
775
776         subblock = dr_add_block(pc, tcache_id, &blkid);
777         if (subblock == NULL)
778           return NULL;
779         subblock->end_addr = pc;
780
781         if (tcache_id != 0) { // data array, BIOS
782           drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
783           drcblk += (pc & 0x00fff) >> SH2_DRCBLK_DA_SHIFT;
784           *drcblk = (blkid << 1) | 1;
785         } else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
786           drcblk = Pico32xMem->drcblk_ram;
787           drcblk += (pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
788           *drcblk = (blkid << 1) | 1;
789         }
790
791         dbg(1, "=== %csh2 subblock #%d,%d %08x -> %p", sh2->is_slave ? 's' : 'm',
792           tcache_id, blkid, pc, tcache_ptr);
793       }
794       branch_target_ptr[i] = tcache_ptr;
795
796       // must update PC
797       emit_move_r_imm32(SHR_PC, pc);
798       rcache_clean();
799
800       // check cycles
801       sr = rcache_get_reg(SHR_SR, RC_GR_READ);
802       emith_cmp_r_imm(sr, 0);
803       emith_jump_cond(DCOND_LE, sh2_drc_exit);
804     }
805
806     op = p32x_sh2_read16(pc, sh2);
807
808 #if (DRC_DEBUG & 3)
809     insns_compiled++;
810 #if (DRC_DEBUG & 2)
811     DasmSH2(sh2dasm_buff, pc, op);
812     printf("%08x %04x %s\n", pc, op, sh2dasm_buff);
813 #endif
814 #endif
815
816     pc += 2;
817     cycles++;
818
819     switch ((op >> 12) & 0x0f)
820     {
821     /////////////////////////////////////////////
822     case 0x00:
823       switch (op & 0x0f)
824       {
825       case 0x02:
826         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
827         switch (GET_Fx())
828         {
829         case 0: // STC SR,Rn  0000nnnn00000010
830           tmp2 = SHR_SR;
831           break;
832         case 1: // STC GBR,Rn 0000nnnn00010010
833           tmp2 = SHR_GBR;
834           break;
835         case 2: // STC VBR,Rn 0000nnnn00100010
836           tmp2 = SHR_VBR;
837           break;
838         default:
839           goto default_;
840         }
841         tmp3 = rcache_get_reg(tmp2, RC_GR_READ);
842         emith_move_r_r(tmp, tmp3);
843         if (tmp2 == SHR_SR)
844           emith_clear_msb(tmp, tmp, 22); // reserved bits defined by ISA as 0
845         goto end_op;
846       case 0x03:
847         CHECK_UNHANDLED_BITS(0xd0);
848         // BRAF Rm    0000mmmm00100011
849         // BSRF Rm    0000mmmm00000011
850         DELAYED_OP;
851         tmp  = rcache_get_reg(SHR_PC, RC_GR_WRITE);
852         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
853         emith_move_r_r(tmp, tmp2);
854         if (op & 0x20)
855           emith_add_r_imm(tmp, pc + 2);
856         else { // BSRF
857           tmp3 = rcache_get_reg(SHR_PR, RC_GR_WRITE);
858           emith_move_r_imm(tmp3, pc + 2);
859           emith_add_r_r(tmp, tmp3);
860         }
861         cycles++;
862         goto end_op;
863       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
864       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
865       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
866         tmp = rcache_get_reg(GET_Rm(), RC_GR_READ);
867         emit_indirect_indexed_write(tmp, SHR_R0, GET_Rn(), op & 3);
868         goto end_op;
869       case 0x07:
870         // MUL.L     Rm,Rn      0000nnnnmmmm0111
871         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
872         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
873         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
874         emith_mul(tmp3, tmp2, tmp);
875         cycles++;
876         goto end_op;
877       case 0x08:
878         CHECK_UNHANDLED_BITS(0xf00);
879         switch (GET_Fx())
880         {
881         case 0: // CLRT               0000000000001000
882           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
883           if (drcf.delayed_op)
884             DELAY_SAVE_T(sr);
885           emith_bic_r_imm(sr, T);
886           break;
887         case 1: // SETT               0000000000011000
888           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
889           if (drcf.delayed_op)
890             DELAY_SAVE_T(sr);
891           emith_or_r_imm(sr, T);
892           break;
893         case 2: // CLRMAC             0000000000101000
894           tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
895           emith_move_r_imm(tmp, 0);
896           tmp = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
897           emith_move_r_imm(tmp, 0);
898           break;
899         default:
900           goto default_;
901         }
902         goto end_op;
903       case 0x09:
904         switch (GET_Fx())
905         {
906         case 0: // NOP        0000000000001001
907           CHECK_UNHANDLED_BITS(0xf00);
908           break;
909         case 1: // DIV0U      0000000000011001
910           CHECK_UNHANDLED_BITS(0xf00);
911           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
912           if (drcf.delayed_op)
913             DELAY_SAVE_T(sr);
914           emith_bic_r_imm(sr, M|Q|T);
915           break;
916         case 2: // MOVT Rn    0000nnnn00101001
917           sr   = rcache_get_reg(SHR_SR, RC_GR_READ);
918           tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
919           emith_clear_msb(tmp2, sr, 31);
920           break;
921         default:
922           goto default_;
923         }
924         goto end_op;
925       case 0x0a:
926         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
927         switch (GET_Fx())
928         {
929         case 0: // STS      MACH,Rn   0000nnnn00001010
930           tmp2 = SHR_MACH;
931           break;
932         case 1: // STS      MACL,Rn   0000nnnn00011010
933           tmp2 = SHR_MACL;
934           break;
935         case 2: // STS      PR,Rn     0000nnnn00101010
936           tmp2 = SHR_PR;
937           break;
938         default:
939           goto default_;
940         }
941         tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
942         emith_move_r_r(tmp, tmp2);
943         goto end_op;
944       case 0x0b:
945         CHECK_UNHANDLED_BITS(0xf00);
946         switch (GET_Fx())
947         {
948         case 0: // RTS        0000000000001011
949           DELAYED_OP;
950           emit_move_r_r(SHR_PC, SHR_PR);
951           cycles++;
952           break;
953         case 1: // SLEEP      0000000000011011
954           emit_move_r_imm32(SHR_PC, pc - 2);
955           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
956           emith_clear_msb(tmp, tmp, 20); // clear cycles
957           drcf.test_irq = 1;
958           cycles = 1;
959           break;
960         case 2: // RTE        0000000000101011
961           DELAYED_OP;
962           rcache_clean();
963           // pop PC
964           rcache_get_reg_arg(0, SHR_SP);
965           tmp = emit_memhandler_read(2);
966           tmp2 = rcache_get_reg(SHR_PC, RC_GR_WRITE);
967           emith_move_r_r(tmp2, tmp);
968           rcache_free_tmp(tmp);
969           rcache_clean();
970           // pop SR
971           tmp = rcache_get_reg_arg(0, SHR_SP);
972           emith_add_r_imm(tmp, 4);
973           tmp = emit_memhandler_read(2);
974           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
975           emith_write_sr(sr, tmp);
976           rcache_free_tmp(tmp);
977           tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
978           emith_add_r_imm(tmp, 4*2);
979           drcf.test_irq = 1;
980           cycles += 3;
981           break;
982         default:
983           goto default_;
984         }
985         goto end_op;
986       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
987       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
988       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
989         tmp = emit_indirect_indexed_read(SHR_R0, GET_Rm(), op & 3);
990         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
991         if ((op & 3) != 2) {
992           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
993         } else
994           emith_move_r_r(tmp2, tmp);
995         rcache_free_tmp(tmp);
996         goto end_op;
997       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
998         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2);
999         sr   = rcache_get_reg(SHR_SR, RC_GR_READ);
1000         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
1001         /* MS 16 MAC bits unused if saturated */
1002         emith_tst_r_imm(sr, S);
1003         EMITH_SJMP_START(DCOND_EQ);
1004         emith_clear_msb_c(DCOND_NE, tmp4, tmp4, 16);
1005         EMITH_SJMP_END(DCOND_EQ);
1006         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); // might evict SR
1007         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
1008         rcache_free_tmp(tmp2);
1009         sr = rcache_get_reg(SHR_SR, RC_GR_READ); // reget just in case
1010         emith_tst_r_imm(sr, S);
1011
1012         EMITH_JMP_START(DCOND_EQ);
1013         emith_asr(tmp, tmp4, 15);
1014         emith_cmp_r_imm(tmp, -1); // negative overflow (0x80000000..0xffff7fff)
1015         EMITH_SJMP_START(DCOND_GE);
1016         emith_move_r_imm_c(DCOND_LT, tmp4, 0x8000);
1017         emith_move_r_imm_c(DCOND_LT, tmp3, 0x0000);
1018         EMITH_SJMP_END(DCOND_GE);
1019         emith_cmp_r_imm(tmp, 0); // positive overflow (0x00008000..0x7fffffff)
1020         EMITH_SJMP_START(DCOND_LE);
1021         emith_move_r_imm_c(DCOND_GT, tmp4, 0x00007fff);
1022         emith_move_r_imm_c(DCOND_GT, tmp3, 0xffffffff);
1023         EMITH_SJMP_END(DCOND_LE);
1024         EMITH_JMP_END(DCOND_EQ);
1025
1026         rcache_free_tmp(tmp);
1027         cycles += 3;
1028         goto end_op;
1029       }
1030       goto default_;
1031
1032     /////////////////////////////////////////////
1033     case 0x01:
1034       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
1035       rcache_clean();
1036       tmp  = rcache_get_reg_arg(0, GET_Rn());
1037       tmp2 = rcache_get_reg_arg(1, GET_Rm());
1038       emith_add_r_imm(tmp, (op & 0x0f) * 4);
1039       emit_memhandler_write(2);
1040       goto end_op;
1041
1042     case 0x02:
1043       switch (op & 0x0f)
1044       {
1045       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
1046       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
1047       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
1048         rcache_clean();
1049         rcache_get_reg_arg(0, GET_Rn());
1050         rcache_get_reg_arg(1, GET_Rm());
1051         emit_memhandler_write(op & 3);
1052         goto end_op;
1053       case 0x04: // MOV.B Rm,@–Rn       0010nnnnmmmm0100
1054       case 0x05: // MOV.W Rm,@–Rn       0010nnnnmmmm0101
1055       case 0x06: // MOV.L Rm,@–Rn       0010nnnnmmmm0110
1056         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1057         emith_sub_r_imm(tmp, (1 << (op & 3)));
1058         rcache_clean();
1059         rcache_get_reg_arg(0, GET_Rn());
1060         rcache_get_reg_arg(1, GET_Rm());
1061         emit_memhandler_write(op & 3);
1062         goto end_op;
1063       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
1064         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1065         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1066         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1067         if (drcf.delayed_op)
1068           DELAY_SAVE_T(sr);
1069         emith_bic_r_imm(sr, M|Q|T);
1070         emith_tst_r_imm(tmp2, (1<<31));
1071         EMITH_SJMP_START(DCOND_EQ);
1072         emith_or_r_imm_c(DCOND_NE, sr, Q);
1073         EMITH_SJMP_END(DCOND_EQ);
1074         emith_tst_r_imm(tmp3, (1<<31));
1075         EMITH_SJMP_START(DCOND_EQ);
1076         emith_or_r_imm_c(DCOND_NE, sr, M);
1077         EMITH_SJMP_END(DCOND_EQ);
1078         emith_teq_r_r(tmp2, tmp3);
1079         EMITH_SJMP_START(DCOND_PL);
1080         emith_or_r_imm_c(DCOND_MI, sr, T);
1081         EMITH_SJMP_END(DCOND_PL);
1082         goto end_op;
1083       case 0x08: // TST Rm,Rn           0010nnnnmmmm1000
1084         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1085         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1086         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1087         if (drcf.delayed_op)
1088           DELAY_SAVE_T(sr);
1089         emith_bic_r_imm(sr, T);
1090         emith_tst_r_r(tmp2, tmp3);
1091         emit_or_t_if_eq(sr);
1092         goto end_op;
1093       case 0x09: // AND Rm,Rn           0010nnnnmmmm1001
1094         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1095         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1096         emith_and_r_r(tmp, tmp2);
1097         goto end_op;
1098       case 0x0a: // XOR Rm,Rn           0010nnnnmmmm1010
1099         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1100         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1101         emith_eor_r_r(tmp, tmp2);
1102         goto end_op;
1103       case 0x0b: // OR  Rm,Rn           0010nnnnmmmm1011
1104         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1105         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1106         emith_or_r_r(tmp, tmp2);
1107         goto end_op;
1108       case 0x0c: // CMP/STR Rm,Rn       0010nnnnmmmm1100
1109         tmp  = rcache_get_tmp();
1110         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1111         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1112         emith_eor_r_r_r(tmp, tmp2, tmp3);
1113         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1114         if (drcf.delayed_op)
1115           DELAY_SAVE_T(sr);
1116         emith_bic_r_imm(sr, T);
1117         emith_tst_r_imm(tmp, 0x000000ff);
1118         emit_or_t_if_eq(tmp);
1119         emith_tst_r_imm(tmp, 0x0000ff00);
1120         emit_or_t_if_eq(tmp);
1121         emith_tst_r_imm(tmp, 0x00ff0000);
1122         emit_or_t_if_eq(tmp);
1123         emith_tst_r_imm(tmp, 0xff000000);
1124         emit_or_t_if_eq(tmp);
1125         rcache_free_tmp(tmp);
1126         goto end_op;
1127       case 0x0d: // XTRCT  Rm,Rn        0010nnnnmmmm1101
1128         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1129         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1130         emith_lsr(tmp, tmp, 16);
1131         emith_or_r_r_lsl(tmp, tmp2, 16);
1132         goto end_op;
1133       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
1134       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
1135         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1136         tmp  = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1137         if (op & 1) {
1138           emith_sext(tmp, tmp2, 16);
1139         } else
1140           emith_clear_msb(tmp, tmp2, 16);
1141         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1142         tmp2 = rcache_get_tmp();
1143         if (op & 1) {
1144           emith_sext(tmp2, tmp3, 16);
1145         } else
1146           emith_clear_msb(tmp2, tmp3, 16);
1147         emith_mul(tmp, tmp, tmp2);
1148         rcache_free_tmp(tmp2);
1149 //      FIXME: causes timing issues in Doom?
1150 //        cycles++;
1151         goto end_op;
1152       }
1153       goto default_;
1154
1155     /////////////////////////////////////////////
1156     case 0x03:
1157       switch (op & 0x0f)
1158       {
1159       case 0x00: // CMP/EQ Rm,Rn        0011nnnnmmmm0000
1160       case 0x02: // CMP/HS Rm,Rn        0011nnnnmmmm0010
1161       case 0x03: // CMP/GE Rm,Rn        0011nnnnmmmm0011
1162       case 0x06: // CMP/HI Rm,Rn        0011nnnnmmmm0110
1163       case 0x07: // CMP/GT Rm,Rn        0011nnnnmmmm0111
1164         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1165         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1166         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1167         if (drcf.delayed_op)
1168           DELAY_SAVE_T(sr);
1169         emith_bic_r_imm(sr, T);
1170         emith_cmp_r_r(tmp2, tmp3);
1171         switch (op & 0x07)
1172         {
1173         case 0x00: // CMP/EQ
1174           emit_or_t_if_eq(sr);
1175           break;
1176         case 0x02: // CMP/HS
1177           EMITH_SJMP_START(DCOND_LO);
1178           emith_or_r_imm_c(DCOND_HS, sr, T);
1179           EMITH_SJMP_END(DCOND_LO);
1180           break;
1181         case 0x03: // CMP/GE
1182           EMITH_SJMP_START(DCOND_LT);
1183           emith_or_r_imm_c(DCOND_GE, sr, T);
1184           EMITH_SJMP_END(DCOND_LT);
1185           break;
1186         case 0x06: // CMP/HI
1187           EMITH_SJMP_START(DCOND_LS);
1188           emith_or_r_imm_c(DCOND_HI, sr, T);
1189           EMITH_SJMP_END(DCOND_LS);
1190           break;
1191         case 0x07: // CMP/GT
1192           EMITH_SJMP_START(DCOND_LE);
1193           emith_or_r_imm_c(DCOND_GT, sr, T);
1194           EMITH_SJMP_END(DCOND_LE);
1195           break;
1196         }
1197         goto end_op;
1198       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
1199         // Q1 = carry(Rn = (Rn << 1) | T)
1200         // if Q ^ M
1201         //   Q2 = carry(Rn += Rm)
1202         // else
1203         //   Q2 = carry(Rn -= Rm)
1204         // Q = M ^ Q1 ^ Q2
1205         // T = (Q == M) = !(Q ^ M) = !(Q1 ^ Q2)
1206         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1207         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1208         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1209         if (drcf.delayed_op)
1210           DELAY_SAVE_T(sr);
1211         emith_tpop_carry(sr, 0);
1212         emith_adcf_r_r(tmp2, tmp2);
1213         emith_tpush_carry(sr, 0);            // keep Q1 in T for now
1214         tmp4 = rcache_get_tmp();
1215         emith_and_r_r_imm(tmp4, sr, M);
1216         emith_eor_r_r_lsr(sr, tmp4, M_SHIFT - Q_SHIFT); // Q ^= M
1217         rcache_free_tmp(tmp4);
1218         // add or sub, invert T if carry to get Q1 ^ Q2
1219         // in: (Q ^ M) passed in Q, Q1 in T
1220         emith_sh2_div1_step(tmp2, tmp3, sr);
1221         emith_bic_r_imm(sr, Q);
1222         emith_tst_r_imm(sr, M);
1223         EMITH_SJMP_START(DCOND_EQ);
1224         emith_or_r_imm_c(DCOND_NE, sr, Q);  // Q = M
1225         EMITH_SJMP_END(DCOND_EQ);
1226         emith_tst_r_imm(sr, T);
1227         EMITH_SJMP_START(DCOND_EQ);
1228         emith_eor_r_imm_c(DCOND_NE, sr, Q); // Q = M ^ Q1 ^ Q2
1229         EMITH_SJMP_END(DCOND_EQ);
1230         emith_eor_r_imm(sr, T);             // T = !(Q1 ^ Q2)
1231         goto end_op;
1232       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
1233         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1234         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1235         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1236         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1237         emith_mul_u64(tmp3, tmp4, tmp, tmp2);
1238         goto end_op;
1239       case 0x08: // SUB     Rm,Rn       0011nnnnmmmm1000
1240       case 0x0c: // ADD     Rm,Rn       0011nnnnmmmm1100
1241         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1242         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1243         if (op & 4) {
1244           emith_add_r_r(tmp, tmp2);
1245         } else
1246           emith_sub_r_r(tmp, tmp2);
1247         goto end_op;
1248       case 0x0a: // SUBC    Rm,Rn       0011nnnnmmmm1010
1249       case 0x0e: // ADDC    Rm,Rn       0011nnnnmmmm1110
1250         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1251         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1252         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1253         if (drcf.delayed_op)
1254           DELAY_SAVE_T(sr);
1255         if (op & 4) { // adc
1256           emith_tpop_carry(sr, 0);
1257           emith_adcf_r_r(tmp, tmp2);
1258           emith_tpush_carry(sr, 0);
1259         } else {
1260           emith_tpop_carry(sr, 1);
1261           emith_sbcf_r_r(tmp, tmp2);
1262           emith_tpush_carry(sr, 1);
1263         }
1264         goto end_op;
1265       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
1266       case 0x0f: // ADDV    Rm,Rn       0011nnnnmmmm1111
1267         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1268         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1269         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1270         if (drcf.delayed_op)
1271           DELAY_SAVE_T(sr);
1272         emith_bic_r_imm(sr, T);
1273         if (op & 4) {
1274           emith_addf_r_r(tmp, tmp2);
1275         } else
1276           emith_subf_r_r(tmp, tmp2);
1277         EMITH_SJMP_START(DCOND_VC);
1278         emith_or_r_imm_c(DCOND_VS, sr, T);
1279         EMITH_SJMP_END(DCOND_VC);
1280         goto end_op;
1281       case 0x0d: // DMULS.L Rm,Rn       0011nnnnmmmm1101
1282         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1283         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1284         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1285         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1286         emith_mul_s64(tmp3, tmp4, tmp, tmp2);
1287         goto end_op;
1288       }
1289       goto default_;
1290
1291     /////////////////////////////////////////////
1292     case 0x04:
1293       switch (op & 0x0f)
1294       {
1295       case 0x00:
1296         switch (GET_Fx())
1297         {
1298         case 0: // SHLL Rn    0100nnnn00000000
1299         case 2: // SHAL Rn    0100nnnn00100000
1300           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1301           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1302           if (drcf.delayed_op)
1303             DELAY_SAVE_T(sr);
1304           emith_tpop_carry(sr, 0); // dummy
1305           emith_lslf(tmp, tmp, 1);
1306           emith_tpush_carry(sr, 0);
1307           goto end_op;
1308         case 1: // DT Rn      0100nnnn00010000
1309           if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2
1310             emith_sh2_dtbf_loop();
1311             goto end_op;
1312           }
1313           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1314           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1315           if (drcf.delayed_op)
1316             DELAY_SAVE_T(sr);
1317           emith_bic_r_imm(sr, T);
1318           emith_subf_r_imm(tmp, 1);
1319           emit_or_t_if_eq(sr);
1320           goto end_op;
1321         }
1322         goto default_;
1323       case 0x01:
1324         switch (GET_Fx())
1325         {
1326         case 0: // SHLR Rn    0100nnnn00000001
1327         case 2: // SHAR Rn    0100nnnn00100001
1328           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1329           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1330           if (drcf.delayed_op)
1331             DELAY_SAVE_T(sr);
1332           emith_tpop_carry(sr, 0); // dummy
1333           if (op & 0x20) {
1334             emith_asrf(tmp, tmp, 1);
1335           } else
1336             emith_lsrf(tmp, tmp, 1);
1337           emith_tpush_carry(sr, 0);
1338           goto end_op;
1339         case 1: // CMP/PZ Rn  0100nnnn00010001
1340           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1341           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1342           if (drcf.delayed_op)
1343             DELAY_SAVE_T(sr);
1344           emith_bic_r_imm(sr, T);
1345           emith_cmp_r_imm(tmp, 0);
1346           EMITH_SJMP_START(DCOND_LT);
1347           emith_or_r_imm_c(DCOND_GE, sr, T);
1348           EMITH_SJMP_END(DCOND_LT);
1349           goto end_op;
1350         }
1351         goto default_;
1352       case 0x02:
1353       case 0x03:
1354         switch (op & 0x3f)
1355         {
1356         case 0x02: // STS.L    MACH,@–Rn 0100nnnn00000010
1357           tmp = SHR_MACH;
1358           break;
1359         case 0x12: // STS.L    MACL,@–Rn 0100nnnn00010010
1360           tmp = SHR_MACL;
1361           break;
1362         case 0x22: // STS.L    PR,@–Rn   0100nnnn00100010
1363           tmp = SHR_PR;
1364           break;
1365         case 0x03: // STC.L    SR,@–Rn   0100nnnn00000011
1366           tmp = SHR_SR;
1367           break;
1368         case 0x13: // STC.L    GBR,@–Rn  0100nnnn00010011
1369           tmp = SHR_GBR;
1370           break;
1371         case 0x23: // STC.L    VBR,@–Rn  0100nnnn00100011
1372           tmp = SHR_VBR;
1373           break;
1374         default:
1375           goto default_;
1376         }
1377         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1378         emith_sub_r_imm(tmp2, 4);
1379         rcache_clean();
1380         rcache_get_reg_arg(0, GET_Rn());
1381         tmp3 = rcache_get_reg_arg(1, tmp);
1382         if (tmp == SHR_SR)
1383           emith_clear_msb(tmp3, tmp3, 20); // reserved bits defined by ISA as 0
1384         emit_memhandler_write(2);
1385         goto end_op;
1386       case 0x04:
1387       case 0x05:
1388         switch (op & 0x3f)
1389         {
1390         case 0x04: // ROTL   Rn          0100nnnn00000100
1391         case 0x05: // ROTR   Rn          0100nnnn00000101
1392           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1393           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1394           if (drcf.delayed_op)
1395             DELAY_SAVE_T(sr);
1396           emith_tpop_carry(sr, 0); // dummy
1397           if (op & 1) {
1398             emith_rorf(tmp, tmp, 1);
1399           } else
1400             emith_rolf(tmp, tmp, 1);
1401           emith_tpush_carry(sr, 0);
1402           goto end_op;
1403         case 0x24: // ROTCL  Rn          0100nnnn00100100
1404         case 0x25: // ROTCR  Rn          0100nnnn00100101
1405           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1406           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1407           if (drcf.delayed_op)
1408             DELAY_SAVE_T(sr);
1409           emith_tpop_carry(sr, 0);
1410           if (op & 1) {
1411             emith_rorcf(tmp);
1412           } else
1413             emith_rolcf(tmp);
1414           emith_tpush_carry(sr, 0);
1415           goto end_op;
1416         case 0x15: // CMP/PL Rn          0100nnnn00010101
1417           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1418           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1419           if (drcf.delayed_op)
1420             DELAY_SAVE_T(sr);
1421           emith_bic_r_imm(sr, T);
1422           emith_cmp_r_imm(tmp, 0);
1423           EMITH_SJMP_START(DCOND_LE);
1424           emith_or_r_imm_c(DCOND_GT, sr, T);
1425           EMITH_SJMP_END(DCOND_LE);
1426           goto end_op;
1427         }
1428         goto default_;
1429       case 0x06:
1430       case 0x07:
1431         switch (op & 0x3f)
1432         {
1433         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
1434           tmp = SHR_MACH;
1435           break;
1436         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
1437           tmp = SHR_MACL;
1438           break;
1439         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
1440           tmp = SHR_PR;
1441           break;
1442         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
1443           tmp = SHR_SR;
1444           break;
1445         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
1446           tmp = SHR_GBR;
1447           break;
1448         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
1449           tmp = SHR_VBR;
1450           break;
1451         default:
1452           goto default_;
1453         }
1454         rcache_clean();
1455         rcache_get_reg_arg(0, GET_Rn());
1456         tmp2 = emit_memhandler_read(2);
1457         if (tmp == SHR_SR) {
1458           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1459           if (drcf.delayed_op)
1460             DELAY_SAVE_T(sr);
1461           emith_write_sr(sr, tmp2);
1462           drcf.test_irq = 1;
1463         } else {
1464           tmp = rcache_get_reg(tmp, RC_GR_WRITE);
1465           emith_move_r_r(tmp, tmp2);
1466         }
1467         rcache_free_tmp(tmp2);
1468         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1469         emith_add_r_imm(tmp, 4);
1470         goto end_op;
1471       case 0x08:
1472       case 0x09:
1473         switch (GET_Fx())
1474         {
1475         case 0:
1476           // SHLL2 Rn        0100nnnn00001000
1477           // SHLR2 Rn        0100nnnn00001001
1478           tmp = 2;
1479           break;
1480         case 1:
1481           // SHLL8 Rn        0100nnnn00011000
1482           // SHLR8 Rn        0100nnnn00011001
1483           tmp = 8;
1484           break;
1485         case 2:
1486           // SHLL16 Rn       0100nnnn00101000
1487           // SHLR16 Rn       0100nnnn00101001
1488           tmp = 16;
1489           break;
1490         default:
1491           goto default_;
1492         }
1493         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1494         if (op & 1) {
1495           emith_lsr(tmp2, tmp2, tmp);
1496         } else
1497           emith_lsl(tmp2, tmp2, tmp);
1498         goto end_op;
1499       case 0x0a:
1500         switch (GET_Fx())
1501         {
1502         case 0: // LDS      Rm,MACH   0100mmmm00001010
1503           tmp2 = SHR_MACH;
1504           break;
1505         case 1: // LDS      Rm,MACL   0100mmmm00011010
1506           tmp2 = SHR_MACL;
1507           break;
1508         case 2: // LDS      Rm,PR     0100mmmm00101010
1509           tmp2 = SHR_PR;
1510           break;
1511         default:
1512           goto default_;
1513         }
1514         emit_move_r_r(tmp2, GET_Rn());
1515         goto end_op;
1516       case 0x0b:
1517         switch (GET_Fx())
1518         {
1519         case 0: // JSR  @Rm   0100mmmm00001011
1520         case 2: // JMP  @Rm   0100mmmm00101011
1521           DELAYED_OP;
1522           if (!(op & 0x20))
1523             emit_move_r_imm32(SHR_PR, pc + 2);
1524           emit_move_r_r(SHR_PC, (op >> 8) & 0x0f);
1525           cycles++;
1526           break;
1527         case 1: // TAS.B @Rn  0100nnnn00011011
1528           // XXX: is TAS working on 32X?
1529           rcache_clean();
1530           rcache_get_reg_arg(0, GET_Rn());
1531           tmp = emit_memhandler_read(0);
1532           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1533           if (drcf.delayed_op)
1534             DELAY_SAVE_T(sr);
1535           emith_bic_r_imm(sr, T);
1536           emith_cmp_r_imm(tmp, 0);
1537           emit_or_t_if_eq(sr);
1538           rcache_clean();
1539           emith_or_r_imm(tmp, 0x80);
1540           tmp2 = rcache_get_tmp_arg(1); // assuming it differs to tmp
1541           emith_move_r_r(tmp2, tmp);
1542           rcache_free_tmp(tmp);
1543           rcache_get_reg_arg(0, GET_Rn());
1544           emit_memhandler_write(0);
1545           cycles += 3;
1546           break;
1547         default:
1548           goto default_;
1549         }
1550         goto end_op;
1551       case 0x0e:
1552         tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
1553         switch (GET_Fx())
1554         {
1555         case 0: // LDC Rm,SR   0100mmmm00001110
1556           tmp2 = SHR_SR;
1557           break;
1558         case 1: // LDC Rm,GBR  0100mmmm00011110
1559           tmp2 = SHR_GBR;
1560           break;
1561         case 2: // LDC Rm,VBR  0100mmmm00101110
1562           tmp2 = SHR_VBR;
1563           break;
1564         default:
1565           goto default_;
1566         }
1567         if (tmp2 == SHR_SR) {
1568           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1569           if (drcf.delayed_op)
1570             DELAY_SAVE_T(sr);
1571           emith_write_sr(sr, tmp);
1572           drcf.test_irq = 1;
1573         } else {
1574           tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE);
1575           emith_move_r_r(tmp2, tmp);
1576         }
1577         goto end_op;
1578       case 0x0f:
1579         // MAC @Rm+,@Rn+  0100nnnnmmmm1111
1580         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1);
1581         emith_sext(tmp, tmp, 16);
1582         emith_sext(tmp2, tmp2, 16);
1583         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW);
1584         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
1585         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
1586         rcache_free_tmp(tmp2);
1587         // XXX: MACH should be untouched when S is set?
1588         sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1589         emith_tst_r_imm(sr, S);
1590         EMITH_JMP_START(DCOND_EQ);
1591
1592         emith_asr(tmp, tmp3, 31);
1593         emith_eorf_r_r(tmp, tmp4); // tmp = ((signed)macl >> 31) ^ mach
1594         EMITH_JMP_START(DCOND_EQ);
1595         emith_move_r_imm(tmp3, 0x80000000);
1596         emith_tst_r_r(tmp4, tmp4);
1597         EMITH_SJMP_START(DCOND_MI);
1598         emith_sub_r_imm_c(DCOND_PL, tmp3, 1); // positive
1599         EMITH_SJMP_END(DCOND_MI);
1600         EMITH_JMP_END(DCOND_EQ);
1601
1602         EMITH_JMP_END(DCOND_EQ);
1603         rcache_free_tmp(tmp);
1604         cycles += 2;
1605         goto end_op;
1606       }
1607       goto default_;
1608
1609     /////////////////////////////////////////////
1610     case 0x05:
1611       // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
1612       rcache_clean();
1613       tmp = rcache_get_reg_arg(0, GET_Rm());
1614       emith_add_r_imm(tmp, (op & 0x0f) * 4);
1615       tmp = emit_memhandler_read(2);
1616       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1617       emith_move_r_r(tmp2, tmp);
1618       rcache_free_tmp(tmp);
1619       goto end_op;
1620
1621     /////////////////////////////////////////////
1622     case 0x06:
1623       switch (op & 0x0f)
1624       {
1625       case 0x00: // MOV.B @Rm,Rn        0110nnnnmmmm0000
1626       case 0x01: // MOV.W @Rm,Rn        0110nnnnmmmm0001
1627       case 0x02: // MOV.L @Rm,Rn        0110nnnnmmmm0010
1628       case 0x04: // MOV.B @Rm+,Rn       0110nnnnmmmm0100
1629       case 0x05: // MOV.W @Rm+,Rn       0110nnnnmmmm0101
1630       case 0x06: // MOV.L @Rm+,Rn       0110nnnnmmmm0110
1631         rcache_clean();
1632         rcache_get_reg_arg(0, GET_Rm());
1633         tmp  = emit_memhandler_read(op & 3);
1634         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1635         if ((op & 3) != 2) {
1636           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
1637         } else
1638           emith_move_r_r(tmp2, tmp);
1639         rcache_free_tmp(tmp);
1640         if ((op & 7) >= 4 && GET_Rn() != GET_Rm()) {
1641           tmp = rcache_get_reg(GET_Rm(), RC_GR_RMW);
1642           emith_add_r_imm(tmp, (1 << (op & 3)));
1643         }
1644         goto end_op;
1645       case 0x03:
1646       case 0x07 ... 0x0f:
1647         tmp  = rcache_get_reg(GET_Rm(), RC_GR_READ);
1648         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1649         switch (op & 0x0f)
1650         {
1651         case 0x03: // MOV    Rm,Rn        0110nnnnmmmm0011
1652           emith_move_r_r(tmp2, tmp);
1653           break;
1654         case 0x07: // NOT    Rm,Rn        0110nnnnmmmm0111
1655           emith_mvn_r_r(tmp2, tmp);
1656           break;
1657         case 0x08: // SWAP.B Rm,Rn        0110nnnnmmmm1000
1658           tmp3 = tmp2;
1659           if (tmp == tmp2)
1660             tmp3 = rcache_get_tmp();
1661           tmp4 = rcache_get_tmp();
1662           emith_lsr(tmp3, tmp, 16);
1663           emith_or_r_r_lsl(tmp3, tmp, 24);
1664           emith_and_r_r_imm(tmp4, tmp, 0xff00);
1665           emith_or_r_r_lsl(tmp3, tmp4, 8);
1666           emith_rol(tmp2, tmp3, 16);
1667           rcache_free_tmp(tmp4);
1668           if (tmp == tmp2)
1669             rcache_free_tmp(tmp3);
1670           break;
1671         case 0x09: // SWAP.W Rm,Rn        0110nnnnmmmm1001
1672           emith_rol(tmp2, tmp, 16);
1673           break;
1674         case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
1675           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1676           if (drcf.delayed_op)
1677             DELAY_SAVE_T(sr);
1678           emith_tpop_carry(sr, 1);
1679           emith_negcf_r_r(tmp2, tmp);
1680           emith_tpush_carry(sr, 1);
1681           break;
1682         case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
1683           emith_neg_r_r(tmp2, tmp);
1684           break;
1685         case 0x0c: // EXTU.B Rm,Rn        0110nnnnmmmm1100
1686           emith_clear_msb(tmp2, tmp, 24);
1687           break;
1688         case 0x0d: // EXTU.W Rm,Rn        0110nnnnmmmm1101
1689           emith_clear_msb(tmp2, tmp, 16);
1690           break;
1691         case 0x0e: // EXTS.B Rm,Rn        0110nnnnmmmm1110
1692           emith_sext(tmp2, tmp, 8);
1693           break;
1694         case 0x0f: // EXTS.W Rm,Rn        0110nnnnmmmm1111
1695           emith_sext(tmp2, tmp, 16);
1696           break;
1697         }
1698         goto end_op;
1699       }
1700       goto default_;
1701
1702     /////////////////////////////////////////////
1703     case 0x07:
1704       // ADD #imm,Rn  0111nnnniiiiiiii
1705       tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1706       if (op & 0x80) { // adding negative
1707         emith_sub_r_imm(tmp, -op & 0xff);
1708       } else
1709         emith_add_r_imm(tmp, op & 0xff);
1710       goto end_op;
1711
1712     /////////////////////////////////////////////
1713     case 0x08:
1714       switch (op & 0x0f00)
1715       {
1716       case 0x0000: // MOV.B R0,@(disp,Rn)  10000000nnnndddd
1717       case 0x0100: // MOV.W R0,@(disp,Rn)  10000001nnnndddd
1718         rcache_clean();
1719         tmp  = rcache_get_reg_arg(0, GET_Rm());
1720         tmp2 = rcache_get_reg_arg(1, SHR_R0);
1721         tmp3 = (op & 0x100) >> 8;
1722         emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
1723         emit_memhandler_write(tmp3);
1724         goto end_op;
1725       case 0x0400: // MOV.B @(disp,Rm),R0  10000100mmmmdddd
1726       case 0x0500: // MOV.W @(disp,Rm),R0  10000101mmmmdddd
1727         rcache_clean();
1728         tmp  = rcache_get_reg_arg(0, GET_Rm());
1729         tmp3 = (op & 0x100) >> 8;
1730         emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
1731         tmp  = emit_memhandler_read(tmp3);
1732         tmp2 = rcache_get_reg(0, RC_GR_WRITE);
1733         emith_sext(tmp2, tmp, 8 << tmp3);
1734         rcache_free_tmp(tmp);
1735         goto end_op;
1736       case 0x0800: // CMP/EQ #imm,R0       10001000iiiiiiii
1737         // XXX: could use cmn
1738         tmp  = rcache_get_tmp();
1739         tmp2 = rcache_get_reg(0, RC_GR_READ);
1740         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1741         if (drcf.delayed_op)
1742           DELAY_SAVE_T(sr);
1743         emith_move_r_imm_s8(tmp, op & 0xff);
1744         emith_bic_r_imm(sr, T);
1745         emith_cmp_r_r(tmp2, tmp);
1746         emit_or_t_if_eq(sr);
1747         rcache_free_tmp(tmp);
1748         goto end_op;
1749       case 0x0d00: // BT/S label 10001101dddddddd
1750       case 0x0f00: // BF/S label 10001111dddddddd
1751         DELAYED_OP;
1752         cycles--;
1753         // fallthrough
1754       case 0x0900:   // BT   label 10001001dddddddd
1755       case 0x0b00: { // BF   label 10001011dddddddd
1756         // jmp_cond ~ cond when guest doesn't jump
1757         int jmp_cond  = (op & 0x0200) ? DCOND_NE : DCOND_EQ;
1758         int insn_cond = (op & 0x0200) ? DCOND_EQ : DCOND_NE;
1759         signed int offs = ((signed int)(op << 24) >> 23);
1760         sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1761         if (find_in_array(branch_target_pc, branch_target_count, pc + offs + 2) >= 0) {
1762           branch_patch_pc[branch_patch_count] = pc + offs + 2;
1763           branch_patch_cond = insn_cond;
1764           goto end_op;
1765         }
1766
1767         // can't resolve branch, cause end of block
1768         tmp = rcache_get_reg(SHR_PC, RC_GR_WRITE);
1769         emith_move_r_imm(tmp, pc + (drcf.delayed_op ? 2 : 0));
1770         emith_tst_r_imm(sr, T);
1771         EMITH_SJMP_START(jmp_cond);
1772         if (!drcf.delayed_op)
1773           offs += 2;
1774         if (offs < 0) {
1775           emith_sub_r_imm_c(insn_cond, tmp, -offs);
1776         } else
1777           emith_add_r_imm_c(insn_cond, tmp, offs);
1778         EMITH_SJMP_END(jmp_cond);
1779         cycles += 2;
1780         if (!drcf.delayed_op)
1781           goto end_block_btf;
1782         goto end_op;
1783       }}
1784       goto default_;
1785
1786     /////////////////////////////////////////////
1787     case 0x09:
1788       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
1789       rcache_clean();
1790       tmp = rcache_get_tmp_arg(0);
1791       emith_move_r_imm(tmp, pc + (op & 0xff) * 2 + 2);
1792       tmp  = emit_memhandler_read(1);
1793       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1794       emith_sext(tmp2, tmp, 16);
1795       rcache_free_tmp(tmp);
1796       goto end_op;
1797
1798     /////////////////////////////////////////////
1799     case 0x0a:
1800       // BRA  label 1010dddddddddddd
1801       DELAYED_OP;
1802     do_bra:
1803       tmp = ((signed int)(op << 20) >> 19);
1804       emit_move_r_imm32(SHR_PC, pc + tmp + 2);
1805       cycles++;
1806       break;
1807
1808     /////////////////////////////////////////////
1809     case 0x0b:
1810       // BSR  label 1011dddddddddddd
1811       DELAYED_OP;
1812       emit_move_r_imm32(SHR_PR, pc + 2);
1813       goto do_bra;
1814
1815     /////////////////////////////////////////////
1816     case 0x0c:
1817       switch (op & 0x0f00)
1818       {
1819       case 0x0000: // MOV.B R0,@(disp,GBR)   11000000dddddddd
1820       case 0x0100: // MOV.W R0,@(disp,GBR)   11000001dddddddd
1821       case 0x0200: // MOV.L R0,@(disp,GBR)   11000010dddddddd
1822         rcache_clean();
1823         tmp  = rcache_get_reg_arg(0, SHR_GBR);
1824         tmp2 = rcache_get_reg_arg(1, SHR_R0);
1825         tmp3 = (op & 0x300) >> 8;
1826         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
1827         emit_memhandler_write(tmp3);
1828         goto end_op;
1829       case 0x0400: // MOV.B @(disp,GBR),R0   11000100dddddddd
1830       case 0x0500: // MOV.W @(disp,GBR),R0   11000101dddddddd
1831       case 0x0600: // MOV.L @(disp,GBR),R0   11000110dddddddd
1832         rcache_clean();
1833         tmp  = rcache_get_reg_arg(0, SHR_GBR);
1834         tmp3 = (op & 0x300) >> 8;
1835         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
1836         tmp  = emit_memhandler_read(tmp3);
1837         tmp2 = rcache_get_reg(0, RC_GR_WRITE);
1838         if (tmp3 != 2) {
1839           emith_sext(tmp2, tmp, 8 << tmp3);
1840         } else
1841           emith_move_r_r(tmp2, tmp);
1842         rcache_free_tmp(tmp);
1843         goto end_op;
1844       case 0x0300: // TRAPA #imm      11000011iiiiiiii
1845         tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
1846         emith_sub_r_imm(tmp, 4*2);
1847         rcache_clean();
1848         // push SR
1849         tmp = rcache_get_reg_arg(0, SHR_SP);
1850         emith_add_r_imm(tmp, 4);
1851         tmp = rcache_get_reg_arg(1, SHR_SR);
1852         emith_clear_msb(tmp, tmp, 22);
1853         emit_memhandler_write(2);
1854         // push PC
1855         rcache_get_reg_arg(0, SHR_SP);
1856         tmp = rcache_get_tmp_arg(1);
1857         emith_move_r_imm(tmp, pc);
1858         emit_memhandler_write(2);
1859         // obtain new PC
1860         tmp = rcache_get_reg_arg(0, SHR_VBR);
1861         emith_add_r_imm(tmp, (op & 0xff) * 4);
1862         tmp  = emit_memhandler_read(2);
1863         tmp2 = rcache_get_reg(SHR_PC, RC_GR_WRITE);
1864         emith_move_r_r(tmp2, tmp);
1865         rcache_free_tmp(tmp);
1866         cycles += 7;
1867         goto end_block_btf;
1868       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
1869         emit_move_r_imm32(SHR_R0, (pc + (op & 0xff) * 4 + 2) & ~3);
1870         goto end_op;
1871       case 0x0800: // TST #imm,R0           11001000iiiiiiii
1872         tmp = rcache_get_reg(SHR_R0, RC_GR_READ);
1873         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1874         if (drcf.delayed_op)
1875           DELAY_SAVE_T(sr);
1876         emith_bic_r_imm(sr, T);
1877         emith_tst_r_imm(tmp, op & 0xff);
1878         emit_or_t_if_eq(sr);
1879         goto end_op;
1880       case 0x0900: // AND #imm,R0           11001001iiiiiiii
1881         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1882         emith_and_r_imm(tmp, op & 0xff);
1883         goto end_op;
1884       case 0x0a00: // XOR #imm,R0           11001010iiiiiiii
1885         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1886         emith_eor_r_imm(tmp, op & 0xff);
1887         goto end_op;
1888       case 0x0b00: // OR  #imm,R0           11001011iiiiiiii
1889         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1890         emith_or_r_imm(tmp, op & 0xff);
1891         goto end_op;
1892       case 0x0c00: // TST.B #imm,@(R0,GBR)  11001100iiiiiiii
1893         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1894         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1895         if (drcf.delayed_op)
1896           DELAY_SAVE_T(sr);
1897         emith_bic_r_imm(sr, T);
1898         emith_tst_r_imm(tmp, op & 0xff);
1899         emit_or_t_if_eq(sr);
1900         rcache_free_tmp(tmp);
1901         cycles += 2;
1902         goto end_op;
1903       case 0x0d00: // AND.B #imm,@(R0,GBR)  11001101iiiiiiii
1904         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1905         emith_and_r_imm(tmp, op & 0xff);
1906         goto end_rmw_op;
1907       case 0x0e00: // XOR.B #imm,@(R0,GBR)  11001110iiiiiiii
1908         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1909         emith_eor_r_imm(tmp, op & 0xff);
1910         goto end_rmw_op;
1911       case 0x0f00: // OR.B  #imm,@(R0,GBR)  11001111iiiiiiii
1912         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1913         emith_or_r_imm(tmp, op & 0xff);
1914       end_rmw_op:
1915         tmp2 = rcache_get_tmp_arg(1);
1916         emith_move_r_r(tmp2, tmp);
1917         rcache_free_tmp(tmp);
1918         tmp3 = rcache_get_reg_arg(0, SHR_GBR);
1919         tmp4 = rcache_get_reg(SHR_R0, RC_GR_READ);
1920         emith_add_r_r(tmp3, tmp4);
1921         emit_memhandler_write(0);
1922         cycles += 2;
1923         goto end_op;
1924       }
1925       goto default_;
1926
1927     /////////////////////////////////////////////
1928     case 0x0d:
1929       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
1930       rcache_clean();
1931       tmp = rcache_get_tmp_arg(0);
1932       emith_move_r_imm(tmp, (pc + (op & 0xff) * 4 + 2) & ~3);
1933       tmp  = emit_memhandler_read(2);
1934       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1935       emith_move_r_r(tmp2, tmp);
1936       rcache_free_tmp(tmp);
1937       goto end_op;
1938
1939     /////////////////////////////////////////////
1940     case 0x0e:
1941       // MOV #imm,Rn   1110nnnniiiiiiii
1942       tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1943       emith_move_r_imm_s8(tmp, op & 0xff);
1944       goto end_op;
1945
1946     default:
1947     default_:
1948       elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
1949         sh2->is_slave ? 's' : 'm', op, pc - 2);
1950 #ifdef DRC_DEBUG_INTERP
1951       emit_move_r_imm32(SHR_PC, pc - 2);
1952       rcache_flush();
1953       emith_pass_arg_r(0, CONTEXT_REG);
1954       emith_pass_arg_imm(1, op);
1955       emith_call(sh2_do_op);
1956 #endif
1957       break;
1958     }
1959
1960 end_op:
1961     // block-local conditional branch handling (with/without delay)
1962     if (branch_patch_cond != -1 && drcf.delayed_op != 2) {
1963       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1964       // handle cycles
1965       emith_sub_r_imm(sr, cycles << 12);
1966       cycles = 0;
1967       rcache_clean();
1968
1969       if (drcf.use_saved_t)
1970         emith_tst_r_imm(sr, T_save);
1971       else
1972         emith_tst_r_imm(sr, T);
1973       branch_patch_ptr[branch_patch_count] = tcache_ptr;
1974       emith_jump_patchable(branch_patch_cond);
1975
1976       drcf.use_saved_t = 0;
1977       branch_patch_cond = -1;
1978       branch_patch_count++;
1979       drcf.delayed_op = 0; // XXX: delayed_op ends block, so must override
1980       if (branch_patch_count == MAX_LOCAL_BRANCHES) {
1981         printf("too many local branches\n");
1982         break;
1983       }
1984     }
1985     // test irq?
1986     if (drcf.test_irq && drcf.delayed_op != 2)
1987       break;
1988     if (drcf.delayed_op == 1)
1989       break;
1990
1991     do_host_disasm(tcache_id);
1992   }
1993
1994   // delayed_op means some kind of branch - PC already handled
1995   if (!drcf.delayed_op)
1996     emit_move_r_imm32(SHR_PC, pc);
1997
1998   if (drcf.test_irq) {
1999     rcache_flush();
2000     emith_pass_arg_r(0, CONTEXT_REG);
2001     emith_call(sh2_test_irq);
2002   }
2003
2004 end_block_btf:
2005   this_block->end_addr = pc;
2006
2007   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
2008   emith_sub_r_imm(tmp, cycles << 12);
2009   rcache_flush();
2010   emith_jump(sh2_drc_exit);
2011
2012   // link local branches
2013   for (i = 0; i < branch_patch_count; i++) {
2014     void *target;
2015     int t;
2016     //printf("patch %08x %p\n", branch_patch_pc[i], branch_patch_ptr[i]);
2017     t = find_in_array(branch_target_pc, branch_target_count, branch_patch_pc[i]);
2018     if (branch_target_ptr[t] != NULL)
2019       target = branch_target_ptr[t];
2020     else {
2021       // flush pc and go back to dispatcher (for now)
2022       printf("stray branch to %08x %p\n", branch_patch_pc[i], tcache_ptr);
2023       target = tcache_ptr;
2024       emit_move_r_imm32(SHR_PC, branch_patch_pc[i]);
2025       rcache_flush();
2026       emith_jump(sh2_drc_exit);
2027     }
2028     emith_jump_patch(branch_patch_ptr[i], target);
2029   }
2030
2031   // mark memory blocks as containing compiled code
2032   if (tcache_id != 0) {
2033     // data array, BIOS
2034     u16 *drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
2035     tmp  = (this_block->addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
2036     tmp2 = (this_block->end_addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
2037     drcblk[tmp] = (blkid_main << 1) | 1;
2038     for (++tmp; tmp < tmp2; tmp++) {
2039       if (drcblk[tmp])
2040         continue; // dont overwrite overlay block(s)
2041       drcblk[tmp] = blkid_main << 1;
2042     }
2043   }
2044   else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
2045     tmp  = (this_block->addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
2046     tmp2 = (this_block->end_addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
2047     Pico32xMem->drcblk_ram[tmp] = (blkid_main << 1) | 1;
2048     for (++tmp; tmp < tmp2; tmp++) {
2049       if (Pico32xMem->drcblk_ram[tmp])
2050         continue;
2051       Pico32xMem->drcblk_ram[tmp] = blkid_main << 1;
2052     }
2053   }
2054
2055   tcache_ptrs[tcache_id] = tcache_ptr;
2056
2057 #ifdef ARM
2058   cache_flush_d_inval_i(block_entry, tcache_ptr);
2059 #endif
2060
2061   do_host_disasm(tcache_id);
2062   dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
2063     tcache_id, block_counts[tcache_id],
2064     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
2065     insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
2066   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
2067     dbg(1, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
2068 /*
2069  printf("~~~\n");
2070  tcache_dsm_ptrs[tcache_id] = block_entry;
2071  do_host_disasm(tcache_id);
2072  printf("~~~\n");
2073 */
2074
2075 #if (DRC_DEBUG & 2)
2076   fflush(stdout);
2077 #endif
2078
2079   return block_entry;
2080 /*
2081 unimplemented:
2082   // last op
2083   do_host_disasm(tcache_id);
2084   exit(1);
2085 */
2086 }
2087
2088 void __attribute__((noinline)) sh2_drc_dispatcher(SH2 *sh2)
2089 {
2090   // TODO: need to handle self-caused interrupts
2091   sh2_test_irq(sh2);
2092
2093   while (((signed int)sh2->sr >> 12) > 0)
2094   {
2095     void *block = NULL;
2096     block_desc *bd = NULL;
2097     int tcache_id = 0;
2098
2099     // FIXME: must avoid doing it so often..
2100     //sh2_test_irq(sh2);
2101
2102     // we have full block id tables for data_array and RAM
2103     // BIOS goes to data_array table too
2104     if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
2105       int blkid = Pico32xMem->drcblk_da[sh2->is_slave][(sh2->pc & 0xfff) >> SH2_DRCBLK_DA_SHIFT];
2106       tcache_id = 1 + sh2->is_slave;
2107       if (blkid & 1) {
2108         bd = &block_tables[tcache_id][blkid >> 1];
2109         block = bd->tcache_ptr;
2110       }
2111     }
2112     // RAM
2113     else if ((sh2->pc & 0xc6000000) == 0x06000000) {
2114       int blkid = Pico32xMem->drcblk_ram[(sh2->pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT];
2115       if (blkid & 1) {
2116         bd = &block_tables[tcache_id][blkid >> 1];
2117         block = bd->tcache_ptr;
2118       }
2119     }
2120     // ROM
2121     else if ((sh2->pc & 0xc6000000) == 0x02000000) {
2122       bd = HASH_FUNC(hash_table, sh2->pc);
2123
2124       if (bd != NULL) {
2125         if (bd->addr == sh2->pc)
2126           block = bd->tcache_ptr;
2127         else
2128           block = dr_find_block(bd, sh2->pc);
2129       }
2130     }
2131
2132     if (block == NULL)
2133       block = sh2_translate(sh2, tcache_id);
2134     if (block == NULL) {
2135       // sh2_translate failed, possibly tcache overflow, clean up and try again
2136       flush_tcache(tcache_id);
2137       block = sh2_translate(sh2, tcache_id);
2138     }
2139
2140     dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
2141       sh2->pc, block, (signed int)sh2->sr >> 12);
2142 #if (DRC_DEBUG & 1)
2143     if (bd != NULL)
2144       bd->refcount++;
2145 #endif
2146     sh2_drc_entry(block, sh2);
2147     dbg(4, "= leave %p", block);
2148   }
2149 }
2150
2151 static void sh2_smc_rm_block(u16 *drcblk, u16 *p, block_desc *btab, u32 a)
2152 {
2153   u16 id = *p >> 1;
2154   block_desc *bd = btab + id;
2155
2156   // FIXME: skip subblocks; do both directions
2157   dbg(1, "  killing block %08x", bd->addr);
2158   bd->addr = bd->end_addr = 0;
2159
2160   while (p > drcblk && (p[-1] >> 1) == id)
2161     p--;
2162
2163   // check for possible overlay block
2164   if (p > 0 && p[-1] != 0) {
2165     bd = btab + (p[-1] >> 1);
2166     if (bd->addr <= a && a < bd->end_addr)
2167       sh2_smc_rm_block(drcblk, p - 1, btab, a);
2168   }
2169
2170   do {
2171     *p++ = 0;
2172   }
2173   while ((*p >> 1) == id);
2174 }
2175
2176 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
2177 {
2178   u16 *drcblk = Pico32xMem->drcblk_ram;
2179   u16 *p = drcblk + ((a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT);
2180
2181   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
2182   sh2_smc_rm_block(drcblk, p, block_tables[0], a);
2183 }
2184
2185 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
2186 {
2187   u16 *drcblk = Pico32xMem->drcblk_da[cpuid];
2188   u16 *p = drcblk + ((a & 0xfff) >> SH2_DRCBLK_DA_SHIFT);
2189
2190   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
2191   sh2_smc_rm_block(drcblk, p, block_tables[1 + cpuid], a);
2192 }
2193
2194 void sh2_execute(SH2 *sh2c, int cycles)
2195 {
2196   sh2 = sh2c; // XXX
2197
2198   sh2c->cycles_aim += cycles;
2199   cycles = sh2c->cycles_aim - sh2c->cycles_done;
2200
2201   // cycles are kept in SHR_SR unused bits (upper 20)
2202   // bit19 contains T saved for delay slot
2203   // others are usual SH2 flags
2204   sh2c->sr &= 0x3f3;
2205   sh2c->sr |= cycles << 12;
2206   sh2_drc_dispatcher(sh2c);
2207
2208   sh2c->cycles_done += cycles - ((signed int)sh2c->sr >> 12);
2209 }
2210
2211 static void REGPARM(1) sh2_test_irq(SH2 *sh2)
2212 {
2213   if (sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
2214   {
2215     if (sh2->pending_irl > sh2->pending_int_irq)
2216       sh2_do_irq(sh2, sh2->pending_irl, 64 + sh2->pending_irl/2);
2217     else {
2218       sh2_do_irq(sh2, sh2->pending_int_irq, sh2->pending_int_vector);
2219       sh2->pending_int_irq = 0; // auto-clear
2220       sh2->pending_level = sh2->pending_irl;
2221     }
2222   }
2223 }
2224
2225 #if (DRC_DEBUG & 1)
2226 static void block_stats(void)
2227 {
2228   int c, b, i, total = 0;
2229
2230   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
2231     for (i = 0; i < block_counts[b]; i++)
2232       if (block_tables[b][i].addr != 0)
2233         total += block_tables[b][i].refcount;
2234
2235   for (c = 0; c < 10; c++) {
2236     block_desc *blk, *maxb = NULL;
2237     int max = 0;
2238     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
2239       for (i = 0; i < block_counts[b]; i++) {
2240         blk = &block_tables[b][i];
2241         if (blk->addr != 0 && blk->refcount > max) {
2242           max = blk->refcount;
2243           maxb = blk;
2244         }
2245       }
2246     }
2247     if (maxb == NULL)
2248       break;
2249     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
2250       (double)maxb->refcount / total * 100.0);
2251     maxb->refcount = 0;
2252   }
2253
2254   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
2255     for (i = 0; i < block_counts[b]; i++)
2256       block_tables[b][i].refcount = 0;
2257 }
2258 #else
2259 #define block_stats()
2260 #endif
2261
2262 void sh2_drc_flush_all(void)
2263 {
2264   block_stats();
2265   flush_tcache(0);
2266   flush_tcache(1);
2267   flush_tcache(2);
2268 }
2269
2270 int sh2_drc_init(SH2 *sh2)
2271 {
2272   if (block_tables[0] == NULL) {
2273     int i, cnt;
2274
2275     drc_cmn_init();
2276
2277     cnt = block_max_counts[0] + block_max_counts[1] + block_max_counts[2];
2278     block_tables[0] = calloc(cnt, sizeof(*block_tables[0]));
2279     if (block_tables[0] == NULL)
2280       return -1;
2281
2282     tcache_ptr = tcache;
2283     sh2_generate_utils();
2284 #ifdef ARM
2285     cache_flush_d_inval_i(tcache, tcache_ptr);
2286 #endif
2287
2288     memset(block_counts, 0, sizeof(block_counts));
2289     tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;
2290
2291     for (i = 1; i < ARRAY_SIZE(block_tables); i++) {
2292       block_tables[i] = block_tables[i - 1] + block_max_counts[i - 1];
2293       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
2294     }
2295
2296     // tmp
2297     PicoOpt |= POPT_DIS_VDP_FIFO;
2298
2299 #if (DRC_DEBUG & 2)
2300     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
2301       tcache_dsm_ptrs[i] = tcache_bases[i];
2302     // disasm the utils
2303     tcache_dsm_ptrs[0] = tcache;
2304     do_host_disasm(0);
2305 #endif
2306 #if (DRC_DEBUG & 1)
2307     hash_collisions = 0;
2308 #endif
2309   }
2310
2311   if (hash_table == NULL) {
2312     hash_table = calloc(sizeof(hash_table[0]), MAX_HASH_ENTRIES);
2313     if (hash_table == NULL)
2314       return -1;
2315   }
2316
2317   return 0;
2318 }
2319
2320 void sh2_drc_finish(SH2 *sh2)
2321 {
2322   if (block_tables[0] != NULL) {
2323     block_stats();
2324     free(block_tables[0]);
2325     memset(block_tables, 0, sizeof(block_tables));
2326
2327     drc_cmn_cleanup();
2328   }
2329
2330   if (hash_table != NULL) {
2331     free(hash_table);
2332     hash_table = NULL;
2333   }
2334 }