32x: drc: some constant propagation
[picodrive.git] / cpu / sh2 / compiler.c
1 /*
2  * vim:shiftwidth=2:expandtab
3  *
4  * notes:
5  * - tcache, block descriptor, link buffer overflows result in sh2_translate()
6  *   failure, followed by full tcache invalidation for that region
7  * - jumps between blocks are tracked for SMC handling (in block_links[]),
8  *   except jumps between different tcaches
9  *
10  * implemented:
11  * - static register allocation
12  * - remaining register caching and tracking in temporaries
13  * - block-local branch linking
14  * - block linking (except between tcaches)
15  * - some constant propagation
16  *
17  * TODO:
18  * - proper SMC handling
19  * - better constant propagation
20  * - stack caching?
21  * - bug fixing
22  */
23 #include <stddef.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <assert.h>
27
28 #include "../../pico/pico_int.h"
29 #include "sh2.h"
30 #include "compiler.h"
31 #include "../drc/cmn.h"
32
33 // features
34 #define PROPAGATE_CONSTANTS     1
35 #define LINK_BRANCHES           1
36
37 // max literal offset from the block end
38 #define MAX_LITERAL_OFFSET      32*2
39
40 // debug stuff {
41 #ifndef DRC_DEBUG
42 #define DRC_DEBUG 0
43 #endif
44
45 #if DRC_DEBUG
46 #define dbg(l,...) { \
47   if ((l) & DRC_DEBUG) \
48     elprintf(EL_STATUS, ##__VA_ARGS__); \
49 }
50
51 #include "mame/sh2dasm.h"
52 #include <platform/linux/host_dasm.h>
53 static int insns_compiled, hash_collisions, host_insn_count;
54 #define COUNT_OP \
55         host_insn_count++
56 #else // !DRC_DEBUG
57 #define COUNT_OP
58 #define dbg(...)
59 #endif
60
61 #if (DRC_DEBUG & 2)
62 static u8 *tcache_dsm_ptrs[3];
63 static char sh2dasm_buff[64];
64 #define do_host_disasm(tcid) \
65   host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
66   tcache_dsm_ptrs[tcid] = tcache_ptr
67 #else
68 #define do_host_disasm(x)
69 #endif
70
71 #if (DRC_DEBUG & 4)
72 static void REGPARM(3) *sh2_drc_announce_entry(void *block, SH2 *sh2, u32 sr)
73 {
74   if (block != NULL)
75     dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
76       sh2->pc, block, (signed int)sr >> 12);
77   return block;
78 }
79 #endif
80 // } debug
81
82 #define BLOCK_CYCLE_LIMIT 100
83 #define MAX_BLOCK_SIZE (BLOCK_CYCLE_LIMIT * 6 * 6)
84 #define TCACHE_BUFFERS 3
85
86 // we have 3 translation cache buffers, split from one drc/cmn buffer.
87 // BIOS shares tcache with data array because it's only used for init
88 // and can be discarded early
89 // XXX: need to tune sizes
90 static const int tcache_sizes[TCACHE_BUFFERS] = {
91   DRC_TCACHE_SIZE * 6 / 8, // ROM, DRAM
92   DRC_TCACHE_SIZE / 8, // BIOS, data array in master sh2
93   DRC_TCACHE_SIZE / 8, // ... slave
94 };
95
96 static u8 *tcache_bases[TCACHE_BUFFERS];
97 static u8 *tcache_ptrs[TCACHE_BUFFERS];
98
99 // ptr for code emiters
100 static u8 *tcache_ptr;
101
102 typedef struct block_desc_ {
103   u32 addr;                  // SH2 PC address
104   u32 end_addr;              // TODO rm?
105   void *tcache_ptr;          // translated block for above PC
106   struct block_desc_ *next;  // next block with the same PC hash
107 #if (DRC_DEBUG & 1)
108   int refcount;
109 #endif
110 } block_desc;
111
112 typedef struct block_link_ {
113   u32 target_pc;
114   void *jump;
115 //  struct block_link_ *next;
116 } block_link;
117
118 static const int block_max_counts[TCACHE_BUFFERS] = {
119   4*1024,
120   256,
121   256,
122 };
123 static block_desc *block_tables[TCACHE_BUFFERS];
124 static block_link *block_links[TCACHE_BUFFERS]; 
125 static int block_counts[TCACHE_BUFFERS];
126 static int block_link_counts[TCACHE_BUFFERS];
127
128 // host register tracking
129 enum {
130   HR_FREE,
131   HR_CACHED, // 'val' has sh2_reg_e
132 //  HR_CONST,  // 'val' has a constant
133   HR_TEMP,   // reg used for temp storage
134 };
135
136 enum {
137   HRF_DIRTY  = 1 << 0, // reg has "dirty" value to be written to ctx
138   HRF_LOCKED = 1 << 1, // HR_CACHED can't be evicted
139 };
140
141 typedef struct {
142   u32 hreg:5;   // "host" reg
143   u32 greg:5;   // "guest" reg
144   u32 type:3;
145   u32 flags:3;
146   u32 stamp:16; // kind of a timestamp
147 } temp_reg_t;
148
149 // note: reg_temp[] must have at least the amount of
150 // registers used by handlers in worst case (currently 4)
151 #ifdef ARM
152 #include "../drc/emit_arm.c"
153
154 static const int reg_map_g2h[] = {
155    4,  5,  6,  7,
156    8, -1, -1, -1,
157   -1, -1, -1, -1,
158   -1, -1, -1,  9,
159   -1, -1, -1, 10,
160   -1, -1, -1, -1,
161 };
162
163 static temp_reg_t reg_temp[] = {
164   {  0, },
165   {  1, },
166   { 12, },
167   { 14, },
168   {  2, },
169   {  3, },
170 };
171
172 #elif defined(__i386__)
173 #include "../drc/emit_x86.c"
174
175 static const int reg_map_g2h[] = {
176   xSI,-1, -1, -1,
177   -1, -1, -1, -1,
178   -1, -1, -1, -1,
179   -1, -1, -1, -1,
180   -1, -1, -1, xDI,
181   -1, -1, -1, -1,
182 };
183
184 // ax, cx, dx are usually temporaries by convention
185 static temp_reg_t reg_temp[] = {
186   { xAX, },
187   { xBX, },
188   { xCX, },
189   { xDX, },
190 };
191
192 #else
193 #error unsupported arch
194 #endif
195
196 #define T       0x00000001
197 #define S       0x00000002
198 #define I       0x000000f0
199 #define Q       0x00000100
200 #define M       0x00000200
201 #define T_save  0x00000800
202
203 #define I_SHIFT 4
204 #define Q_SHIFT 8
205 #define M_SHIFT 9
206
207 // ROM hash table
208 #define MAX_HASH_ENTRIES 1024
209 #define HASH_MASK (MAX_HASH_ENTRIES - 1)
210 static void **hash_table;
211
212 #define HASH_FUNC(hash_tab, addr) \
213   ((block_desc **)(hash_tab))[(addr) & HASH_MASK]
214
215 static void REGPARM(1) (*sh2_drc_entry)(SH2 *sh2);
216 static void            (*sh2_drc_dispatcher)(void);
217 static void            (*sh2_drc_exit)(void);
218 static void            (*sh2_drc_test_irq)(void);
219 static void REGPARM(2) (*sh2_drc_write8)(u32 a, u32 d);
220 static void REGPARM(2) (*sh2_drc_write8_slot)(u32 a, u32 d);
221 static void REGPARM(2) (*sh2_drc_write16)(u32 a, u32 d);
222 static void REGPARM(2) (*sh2_drc_write16_slot)(u32 a, u32 d);
223
224 extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
225
226 static void flush_tcache(int tcid)
227 {
228   dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
229     tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
230     block_counts[tcid], block_max_counts[tcid]);
231
232   block_counts[tcid] = 0;
233   tcache_ptrs[tcid] = tcache_bases[tcid];
234   if (tcid == 0) { // ROM, RAM
235     memset(hash_table, 0, sizeof(hash_table[0]) * MAX_HASH_ENTRIES);
236     memset(Pico32xMem->drcblk_ram, 0, sizeof(Pico32xMem->drcblk_ram));
237   }
238   else
239     memset(Pico32xMem->drcblk_da[tcid - 1], 0, sizeof(Pico32xMem->drcblk_da[0]));
240 #if (DRC_DEBUG & 2)
241   tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
242 #endif
243 }
244
245 // add block links (tracked branches)
246 static int dr_add_block_link(u32 target_pc, void *jump, int tcache_id)
247 {
248   block_link *bl = block_links[tcache_id];
249   int cnt = block_link_counts[tcache_id];
250
251   if (cnt >= block_max_counts[tcache_id] * 2) {
252     printf("bl overflow for tcache %d\n", tcache_id);
253     return -1;
254   }
255
256   bl[cnt].target_pc = target_pc;
257   bl[cnt].jump = jump;
258   block_link_counts[tcache_id]++;
259
260   return 0;
261 }
262
263 static void *dr_find_block(block_desc *tab, u32 addr)
264 {
265   for (tab = tab->next; tab != NULL; tab = tab->next)
266     if (tab->addr == addr)
267       break;
268
269   if (tab != NULL)
270     return tab->tcache_ptr;
271
272   printf("block miss for %08x\n", addr);
273   return NULL;
274 }
275
276 static block_desc *dr_add_block(u32 addr, int tcache_id, int *blk_id)
277 {
278   int *bcount = &block_counts[tcache_id];
279   block_desc *bd;
280
281   if (*bcount >= block_max_counts[tcache_id]) {
282     printf("bd overflow for tcache %d\n", tcache_id);
283     return NULL;
284   }
285
286   bd = &block_tables[tcache_id][*bcount];
287   bd->addr = addr;
288   bd->tcache_ptr = tcache_ptr;
289   *blk_id = *bcount;
290   (*bcount)++;
291
292   if ((addr & 0xc6000000) == 0x02000000) { // ROM
293     bd->next = HASH_FUNC(hash_table, addr);
294     HASH_FUNC(hash_table, addr) = bd;
295 #if (DRC_DEBUG & 1)
296     if (bd->next != NULL) {
297       printf(" hash collision with %08x\n", bd->next->addr);
298       hash_collisions++;
299     }
300 #endif
301   }
302
303   return bd;
304 }
305
306 #define ADD_TO_ARRAY(array, count, item, failcode) \
307   array[count++] = item; \
308   if (count >= ARRAY_SIZE(array)) { \
309     printf("warning: " #array " overflow\n"); \
310     failcode; \
311   }
312
313 int find_in_array(u32 *array, size_t size, u32 what)
314 {
315   size_t i;
316   for (i = 0; i < size; i++)
317     if (what == array[i])
318       return i;
319
320   return -1;
321 }
322
323 // ---------------------------------------------------------------
324
325 typedef enum {
326   RC_GR_READ,
327   RC_GR_WRITE,
328   RC_GR_RMW,
329 } rc_gr_mode;
330
331 static int rcache_get_reg_(sh2_reg_e r, rc_gr_mode mode, int do_locking);
332
333 // guest regs with constants
334 static u32 dr_gcregs[24];
335 // a mask of constant/dirty regs
336 static u32 dr_gcregs_mask;
337 static u32 dr_gcregs_dirty;
338
339 static void gconst_new(sh2_reg_e r, u32 val)
340 {
341 #if PROPAGATE_CONSTANTS
342   int i;
343
344   dr_gcregs_mask  |= 1 << r;
345   dr_gcregs_dirty |= 1 << r;
346   dr_gcregs[r] = val;
347
348   // throw away old r that we might have cached
349   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
350     if ((reg_temp[i].type == HR_CACHED) &&
351          reg_temp[i].greg == r) {
352       reg_temp[i].type = HR_FREE;
353       reg_temp[i].flags = 0;
354     }
355   }
356 #endif
357 }
358
359 static int gconst_get(sh2_reg_e r, u32 *val)
360 {
361   if (dr_gcregs_mask & (1 << r)) {
362     *val = dr_gcregs[r];
363     return 1;
364   }
365   return 0;
366 }
367
368 static int gconst_check(sh2_reg_e r)
369 {
370   if ((dr_gcregs_mask | dr_gcregs_dirty) & (1 << r))
371     return 1;
372   return 0;
373 }
374
375 // update hr if dirty, else do nothing
376 static int gconst_try_read(int hr, sh2_reg_e r)
377 {
378   if (dr_gcregs_dirty & (1 << r)) {
379     emith_move_r_imm(hr, dr_gcregs[r]);
380     dr_gcregs_dirty &= ~(1 << r);
381     return 1;
382   }
383   return 0;
384 }
385
386 static void gconst_check_evict(sh2_reg_e r)
387 {
388   if (dr_gcregs_mask & (1 << r))
389     // no longer cached in reg, make dirty again
390     dr_gcregs_dirty |= 1 << r;
391 }
392
393 static void gconst_kill(sh2_reg_e r)
394 {
395   dr_gcregs_mask &= ~(1 << r);
396   dr_gcregs_dirty &= ~(1 << r);
397 }
398
399 static void gconst_clean(void)
400 {
401   int i;
402
403   for (i = 0; i < ARRAY_SIZE(dr_gcregs); i++)
404     if (dr_gcregs_dirty & (1 << i)) {
405       // using RC_GR_READ here: it will call gconst_try_read,
406       // cache the reg and mark it dirty.
407       rcache_get_reg_(i, RC_GR_READ, 0);
408     }
409 }
410
411 static void gconst_invalidate(void)
412 {
413   dr_gcregs_mask = dr_gcregs_dirty = 0;
414 }
415
416 // register chache
417 static u16 rcache_counter;
418
419 static temp_reg_t *rcache_evict(void)
420 {
421   // evict reg with oldest stamp
422   int i, oldest = -1;
423   u16 min_stamp = (u16)-1;
424
425   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
426     if (reg_temp[i].type == HR_CACHED && !(reg_temp[i].flags & HRF_LOCKED) &&
427         reg_temp[i].stamp <= min_stamp) {
428       min_stamp = reg_temp[i].stamp;
429       oldest = i;
430     }
431   }
432
433   if (oldest == -1) {
434     printf("no registers to evict, aborting\n");
435     exit(1);
436   }
437
438   i = oldest;
439   if (reg_temp[i].type == HR_CACHED) {
440     if (reg_temp[i].flags & HRF_DIRTY)
441       // writeback
442       emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
443     gconst_check_evict(reg_temp[i].greg);
444   }
445
446   reg_temp[i].type = HR_FREE;
447   reg_temp[i].flags = 0;
448   return &reg_temp[i];
449 }
450
451 static int get_reg_static(sh2_reg_e r, rc_gr_mode mode)
452 {
453   int i = reg_map_g2h[r];
454   if (i != -1) {
455     if (mode != RC_GR_WRITE)
456       gconst_try_read(i, r);
457   }
458   return i;
459 }
460
461 // note: must not be called when doing conditional code
462 static int rcache_get_reg_(sh2_reg_e r, rc_gr_mode mode, int do_locking)
463 {
464   temp_reg_t *tr;
465   int i, ret;
466
467   // maybe statically mapped?
468   ret = get_reg_static(r, mode);
469   if (ret != -1)
470     goto end;
471
472   rcache_counter++;
473
474   // maybe already cached?
475   // if so, prefer against gconst (they must be in sync)
476   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
477     if (reg_temp[i].type == HR_CACHED && reg_temp[i].greg == r) {
478       reg_temp[i].stamp = rcache_counter;
479       if (mode != RC_GR_READ)
480         reg_temp[i].flags |= HRF_DIRTY;
481       ret = reg_temp[i].hreg;
482       goto end;
483     }
484   }
485
486   // use any free reg
487   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
488     if (reg_temp[i].type == HR_FREE) {
489       tr = &reg_temp[i];
490       goto do_alloc;
491     }
492   }
493
494   tr = rcache_evict();
495
496 do_alloc:
497   tr->type = HR_CACHED;
498   if (do_locking)
499     tr->flags |= HRF_LOCKED;
500   if (mode != RC_GR_READ)
501     tr->flags |= HRF_DIRTY;
502   tr->greg = r;
503   tr->stamp = rcache_counter;
504   ret = tr->hreg;
505
506   if (mode != RC_GR_WRITE) {
507     if (gconst_check(r)) {
508       if (gconst_try_read(ret, r))
509         tr->flags |= HRF_DIRTY;
510     }
511     else
512       emith_ctx_read(tr->hreg, r * 4);
513   }
514
515 end:
516   if (mode != RC_GR_READ)
517     gconst_kill(r);
518
519   return ret;
520 }
521
522 static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
523 {
524   return rcache_get_reg_(r, mode, 1);
525 }
526
527 static int rcache_get_tmp(void)
528 {
529   temp_reg_t *tr;
530   int i;
531
532   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
533     if (reg_temp[i].type == HR_FREE) {
534       tr = &reg_temp[i];
535       goto do_alloc;
536     }
537
538   tr = rcache_evict();
539
540 do_alloc:
541   tr->type = HR_TEMP;
542   return tr->hreg;
543 }
544
545 static int rcache_get_arg_id(int arg)
546 {
547   int i, r = 0;
548   host_arg2reg(r, arg);
549
550   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
551     if (reg_temp[i].hreg == r)
552       break;
553
554   if (i == ARRAY_SIZE(reg_temp))
555     // let's just say it's untracked arg reg
556     return r;
557
558   if (reg_temp[i].type == HR_CACHED) {
559     // writeback
560     if (reg_temp[i].flags & HRF_DIRTY)
561       emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
562     gconst_check_evict(reg_temp[i].greg);
563   }
564   else if (reg_temp[i].type == HR_TEMP) {
565     printf("arg %d reg %d already used, aborting\n", arg, r);
566     exit(1);
567   }
568
569   reg_temp[i].type = HR_FREE;
570   reg_temp[i].flags = 0;
571
572   return i;
573 }
574
575 // get a reg to be used as function arg
576 static int rcache_get_tmp_arg(int arg)
577 {
578   int id = rcache_get_arg_id(arg);
579   reg_temp[id].type = HR_TEMP;
580
581   return reg_temp[id].hreg;
582 }
583
584 // same but caches a reg. RC_GR_READ only.
585 static int rcache_get_reg_arg(int arg, sh2_reg_e r)
586 {
587   int i, srcr, dstr, dstid;
588   int dirty = 0;
589
590   dstid = rcache_get_arg_id(arg);
591   dstr = reg_temp[dstid].hreg;
592
593   // maybe already statically mapped?
594   srcr = get_reg_static(r, RC_GR_READ);
595   if (srcr != -1)
596     goto do_cache;
597
598   // maybe already cached?
599   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
600     if ((reg_temp[i].type == HR_CACHED) &&
601          reg_temp[i].greg == r)
602     {
603       srcr = reg_temp[i].hreg;
604       goto do_cache;
605     }
606   }
607
608   // must read
609   srcr = dstr;
610   if (gconst_check(r)) {
611     if (gconst_try_read(srcr, r))
612       dirty = 1;
613   }
614   else
615     emith_ctx_read(srcr, r * 4);
616
617 do_cache:
618   if (dstr != srcr)
619     emith_move_r_r(dstr, srcr);
620
621   reg_temp[dstid].stamp = ++rcache_counter;
622   reg_temp[dstid].type = HR_CACHED;
623   reg_temp[dstid].greg = r;
624   reg_temp[dstid].flags |= HRF_LOCKED;
625   if (dirty)
626     reg_temp[dstid].flags |= HRF_DIRTY;
627   return dstr;
628 }
629
630 static void rcache_free_tmp(int hr)
631 {
632   int i;
633   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
634     if (reg_temp[i].hreg == hr)
635       break;
636
637   if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
638     printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
639     return;
640   }
641
642   reg_temp[i].type = HR_FREE;
643   reg_temp[i].flags = 0;
644 }
645
646 static void rcache_unlock(int hr)
647 {
648   int i;
649   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
650     if (reg_temp[i].type == HR_CACHED && reg_temp[i].hreg == hr)
651       reg_temp[i].flags &= ~HRF_LOCKED;
652 }
653
654 static void rcache_unlock_all(void)
655 {
656   int i;
657   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
658     reg_temp[i].flags &= ~HRF_LOCKED;
659 }
660
661 static void rcache_clean(void)
662 {
663   int i;
664   gconst_clean();
665
666   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
667     if (reg_temp[i].type == HR_CACHED && (reg_temp[i].flags & HRF_DIRTY)) {
668       // writeback
669       emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
670       reg_temp[i].flags &= ~HRF_DIRTY;
671     }
672 }
673
674 static void rcache_invalidate(void)
675 {
676   int i;
677   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
678     reg_temp[i].type = HR_FREE;
679     reg_temp[i].flags = 0;
680   }
681   rcache_counter = 0;
682
683   gconst_invalidate();
684 }
685
686 static void rcache_flush(void)
687 {
688   rcache_clean();
689   rcache_invalidate();
690 }
691
692 // ---------------------------------------------------------------
693
694 // address space stuff
695 static void *dr_get_pc_base(u32 pc, int is_slave)
696 {
697   void *ret = NULL;
698   u32 mask = 0;
699
700   if ((pc & ~0x7ff) == 0) {
701     // BIOS
702     ret = is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m;
703     mask = 0x7ff;
704   }
705   else if ((pc & 0xfffff000) == 0xc0000000) {
706     // data array
707     ret = Pico32xMem->data_array[is_slave];
708     mask = 0xfff;
709   }
710   else if ((pc & 0xc6000000) == 0x06000000) {
711     // SDRAM
712     ret = Pico32xMem->sdram;
713     mask = 0x03ffff;
714   }
715   else if ((pc & 0xc6000000) == 0x02000000) {
716     // ROM
717     ret = Pico.rom;
718     mask = 0x3fffff;
719   }
720
721   if (ret == NULL)
722     return (void *)-1; // NULL is valid value
723
724   return (char *)ret - (pc & ~mask);
725 }
726
727 static int emit_get_rbase_and_offs(u32 a, u32 *offs)
728 {
729   int poffs = -1;
730   u32 mask = 0;
731   int hr;
732
733   if ((a & ~0x7ff) == 0) {
734     // BIOS
735     poffs = offsetof(SH2, p_bios);
736     mask = 0x7ff;
737   }
738   else if ((a & 0xfffff000) == 0xc0000000) {
739     // data array
740     poffs = offsetof(SH2, p_da);
741     mask = 0xfff;
742   }
743   else if ((a & 0xc6000000) == 0x06000000) {
744     // SDRAM
745     poffs = offsetof(SH2, p_sdram);
746     mask = 0x03ffff;
747   }
748   else if ((a & 0xc6000000) == 0x02000000) {
749     // ROM
750     poffs = offsetof(SH2, p_rom);
751     mask = 0x3fffff;
752   }
753
754   if (poffs == -1)
755     return -1;
756
757   // XXX: could use related reg
758   hr = rcache_get_tmp();
759   emith_ctx_read(hr, poffs);
760   emith_add_r_imm(hr, a & mask & ~0xff);
761   *offs = a & 0xff; // XXX: ARM oriented..
762   return hr;
763 }
764
765 static void REGPARM(3) *lookup_block(u32 pc, int is_slave, int *tcache_id)
766 {
767   block_desc *bd = NULL;
768   void *block = NULL;
769   *tcache_id = 0;
770
771   // we have full block id tables for data_array and RAM
772   // BIOS goes to data_array table too
773   if ((pc & 0xe0000000) == 0xc0000000 || (pc & ~0xfff) == 0) {
774     int blkid = Pico32xMem->drcblk_da[is_slave][(pc & 0xfff) >> SH2_DRCBLK_DA_SHIFT];
775     *tcache_id = 1 + is_slave;
776     if (blkid & 1) {
777       bd = &block_tables[*tcache_id][blkid >> 1];
778       block = bd->tcache_ptr;
779     }
780   }
781   // RAM
782   else if ((pc & 0xc6000000) == 0x06000000) {
783     int blkid = Pico32xMem->drcblk_ram[(pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT];
784     if (blkid & 1) {
785       bd = &block_tables[0][blkid >> 1];
786       block = bd->tcache_ptr;
787     }
788   }
789   // ROM
790   else if ((pc & 0xc6000000) == 0x02000000) {
791     bd = HASH_FUNC(hash_table, pc);
792
793     if (bd != NULL) {
794       if (bd->addr == pc)
795         block = bd->tcache_ptr;
796       else
797         block = dr_find_block(bd, pc);
798     }
799   }
800
801 #if (DRC_DEBUG & 1)
802   if (bd != NULL)
803     bd->refcount++;
804 #endif
805   return block;
806 }
807
808 static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
809 {
810 #if PROPAGATE_CONSTANTS
811   gconst_new(dst, imm);
812 #else
813   int hr = rcache_get_reg(dst, RC_GR_WRITE);
814   emith_move_r_imm(hr, imm);
815 #endif
816 }
817
818 static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
819 {
820   int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
821   int hr_s = rcache_get_reg(src, RC_GR_READ);
822
823   emith_move_r_r(hr_d, hr_s);
824 }
825
826 // T must be clear, and comparison done just before this
827 static void emit_or_t_if_eq(int srr)
828 {
829   EMITH_SJMP_START(DCOND_NE);
830   emith_or_r_imm_c(DCOND_EQ, srr, T);
831   EMITH_SJMP_END(DCOND_NE);
832 }
833
834 // arguments must be ready
835 // reg cache must be clean before call
836 static int emit_memhandler_read_(int size, int ram_check)
837 {
838   int arg0, arg1;
839   host_arg2reg(arg0, 0);
840
841   rcache_clean();
842
843   // must writeback cycles for poll detection stuff
844   // FIXME: rm
845   if (reg_map_g2h[SHR_SR] != -1)
846     emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
847
848   arg1 = rcache_get_tmp_arg(1);
849   emith_move_r_r(arg1, CONTEXT_REG);
850
851 #if 1
852   if (ram_check && Pico.rom == (void *)0x02000000 && Pico32xMem->sdram == (void *)0x06000000) {
853     int tmp = rcache_get_tmp();
854     emith_and_r_r_imm(tmp, arg0, 0xfb000000);
855     emith_cmp_r_imm(tmp, 0x02000000);
856     switch (size) {
857     case 0: // 8
858       EMITH_SJMP3_START(DCOND_NE);
859       emith_eor_r_imm_c(DCOND_EQ, arg0, 1);
860       emith_read8_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
861       EMITH_SJMP3_MID(DCOND_NE);
862       emith_call_cond(DCOND_NE, p32x_sh2_read8);
863       EMITH_SJMP3_END();
864       break;
865     case 1: // 16
866       EMITH_SJMP3_START(DCOND_NE);
867       emith_read16_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
868       EMITH_SJMP3_MID(DCOND_NE);
869       emith_call_cond(DCOND_NE, p32x_sh2_read16);
870       EMITH_SJMP3_END();
871       break;
872     case 2: // 32
873       EMITH_SJMP3_START(DCOND_NE);
874       emith_read_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
875       emith_ror_c(DCOND_EQ, arg0, arg0, 16);
876       EMITH_SJMP3_MID(DCOND_NE);
877       emith_call_cond(DCOND_NE, p32x_sh2_read32);
878       EMITH_SJMP3_END();
879       break;
880     }
881   }
882   else
883 #endif
884   {
885     switch (size) {
886     case 0: // 8
887       emith_call(p32x_sh2_read8);
888       break;
889     case 1: // 16
890       emith_call(p32x_sh2_read16);
891       break;
892     case 2: // 32
893       emith_call(p32x_sh2_read32);
894       break;
895     }
896   }
897   rcache_invalidate();
898   // assuming arg0 and retval reg matches
899   return rcache_get_tmp_arg(0);
900 }
901
902 static int emit_memhandler_read(int size)
903 {
904   return emit_memhandler_read_(size, 1);
905 }
906
907 static int emit_memhandler_read_rr(sh2_reg_e rd, sh2_reg_e rs, u32 offs, int size)
908 {
909   int hr, hr2, ram_check = 1;
910   u32 val, offs2;
911
912   if (gconst_get(rs, &val)) {
913     hr = emit_get_rbase_and_offs(val + offs, &offs2);
914     if (hr != -1) {
915       hr2 = rcache_get_reg(rd, RC_GR_WRITE);
916       switch (size) {
917       case 0: // 8
918         emith_read8_r_r_offs(hr2, hr, offs2 ^ 1);
919         emith_sext(hr2, hr2, 8);
920         break;
921       case 1: // 16
922         emith_read16_r_r_offs(hr2, hr, offs2);
923         emith_sext(hr2, hr2, 16);
924         break;
925       case 2: // 32
926         emith_read_r_r_offs(hr2, hr, offs2);
927         emith_ror(hr2, hr2, 16);
928         break;
929       }
930       rcache_free_tmp(hr);
931       return hr2;
932     }
933
934     ram_check = 0;
935   }
936
937   hr = rcache_get_reg_arg(0, rs);
938   if (offs != 0)
939     emith_add_r_imm(hr, offs);
940   hr  = emit_memhandler_read_(size, ram_check);
941   hr2 = rcache_get_reg(rd, RC_GR_WRITE);
942   if (size != 2) {
943     emith_sext(hr2, hr, (size == 1) ? 16 : 8);
944   } else
945     emith_move_r_r(hr2, hr);
946   rcache_free_tmp(hr);
947
948   return hr2;
949 }
950
951 static void emit_memhandler_write(int size, u32 pc, int delay)
952 {
953   int ctxr;
954   host_arg2reg(ctxr, 2);
955   switch (size) {
956   case 0: // 8
957     // XXX: consider inlining sh2_drc_write8
958     if (delay) {
959       emith_call(sh2_drc_write8_slot);
960     } else {
961       emit_move_r_imm32(SHR_PC, pc);
962       rcache_clean();
963       emith_call(sh2_drc_write8);
964     }
965     break;
966   case 1: // 16
967     if (delay) {
968       emith_call(sh2_drc_write16_slot);
969     } else {
970       emit_move_r_imm32(SHR_PC, pc);
971       rcache_clean();
972       emith_call(sh2_drc_write16);
973     }
974     break;
975   case 2: // 32
976     emith_move_r_r(ctxr, CONTEXT_REG);
977     emith_call(p32x_sh2_write32);
978     break;
979   }
980   rcache_invalidate();
981 }
982
983 // @(Rx,Ry)
984 static int emit_indirect_indexed_read(int rx, int ry, int size)
985 {
986   int a0, t;
987   a0 = rcache_get_reg_arg(0, rx);
988   t  = rcache_get_reg(ry, RC_GR_READ);
989   emith_add_r_r(a0, t);
990   return emit_memhandler_read(size);
991 }
992
993 // read @Rn, @rm
994 static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size)
995 {
996   int tmp;
997
998   rcache_get_reg_arg(0, rn);
999   tmp = emit_memhandler_read(size);
1000   emith_ctx_write(tmp, offsetof(SH2, drc_tmp));
1001   rcache_free_tmp(tmp);
1002   tmp = rcache_get_reg(rn, RC_GR_RMW);
1003   emith_add_r_imm(tmp, 1 << size);
1004   rcache_unlock(tmp);
1005
1006   rcache_get_reg_arg(0, rm);
1007   *rmr = emit_memhandler_read(size);
1008   *rnr = rcache_get_tmp();
1009   emith_ctx_read(*rnr, offsetof(SH2, drc_tmp));
1010   tmp = rcache_get_reg(rm, RC_GR_RMW);
1011   emith_add_r_imm(tmp, 1 << size);
1012   rcache_unlock(tmp);
1013 }
1014  
1015 static void emit_do_static_regs(int is_write, int tmpr)
1016 {
1017   int i, r, count;
1018
1019   for (i = 0; i < ARRAY_SIZE(reg_map_g2h); i++) {
1020     r = reg_map_g2h[i];
1021     if (r == -1)
1022       continue;
1023
1024     for (count = 1; i < ARRAY_SIZE(reg_map_g2h) - 1; i++, r++) {
1025       if (reg_map_g2h[i + 1] != r + 1)
1026         break;
1027       count++;
1028     }
1029
1030     if (count > 1) {
1031       // i, r point to last item
1032       if (is_write)
1033         emith_ctx_write_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
1034       else
1035         emith_ctx_read_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
1036     } else {
1037       if (is_write)
1038         emith_ctx_write(r, i * 4);
1039       else
1040         emith_ctx_read(r, i * 4);
1041     }
1042   }
1043 }
1044
1045 static void emit_block_entry(void)
1046 {
1047   int arg0, arg1, arg2;
1048
1049   host_arg2reg(arg0, 0);
1050   host_arg2reg(arg1, 1);
1051   host_arg2reg(arg2, 2);
1052
1053 #if (DRC_DEBUG & 4)
1054   emith_move_r_r(arg1, CONTEXT_REG);
1055   emith_move_r_r(arg2, rcache_get_reg(SHR_SR, RC_GR_READ));
1056   emith_call(sh2_drc_announce_entry);
1057   rcache_invalidate();
1058 #endif
1059   emith_tst_r_r(arg0, arg0);
1060   EMITH_SJMP_START(DCOND_EQ);
1061   emith_jump_reg_c(DCOND_NE, arg0);
1062   EMITH_SJMP_END(DCOND_EQ);
1063 }
1064
1065 void dr_link_blocks(void *target, u32 pc, int tcache_id)
1066 {
1067 #if LINK_BRANCHES
1068   block_link *bl = block_links[tcache_id];
1069   int cnt = block_link_counts[tcache_id];
1070   int i;
1071
1072   for (i = 0; i < cnt; i++) {
1073     if (bl[i].target_pc == pc) {
1074       dbg(1, "- link from %p", bl[i].jump);
1075       emith_jump_patch(bl[i].jump, target);
1076       // XXX: sync ARM caches (old jump should be fine)?
1077     }
1078   }
1079 #endif
1080 }
1081
1082 void *dr_prepare_ext_branch(u32 pc, SH2 *sh2, int tcache_id)
1083 {
1084 #if LINK_BRANCHES
1085   int target_tcache_id;
1086   void *target;
1087   int ret;
1088
1089   target = lookup_block(pc, sh2->is_slave, &target_tcache_id);
1090   if (target_tcache_id == tcache_id) {
1091     // allow linking blocks only from local cache
1092     ret = dr_add_block_link(pc, tcache_ptr, tcache_id);
1093     if (ret < 0)
1094       return NULL;
1095   }
1096   if (target == NULL || target_tcache_id != tcache_id)
1097     target = sh2_drc_dispatcher;
1098
1099   return target;
1100 #else
1101   return sh2_drc_dispatcher;
1102 #endif
1103 }
1104
1105 #define DELAYED_OP \
1106   drcf.delayed_op = 2
1107
1108 #define DELAY_SAVE_T(sr) { \
1109   emith_bic_r_imm(sr, T_save); \
1110   emith_tst_r_imm(sr, T);      \
1111   EMITH_SJMP_START(DCOND_EQ);  \
1112   emith_or_r_imm_c(DCOND_NE, sr, T_save); \
1113   EMITH_SJMP_END(DCOND_EQ);    \
1114   drcf.use_saved_t = 1;        \
1115 }
1116
1117 #define FLUSH_CYCLES(sr) \
1118   if (cycles > 0) { \
1119     emith_sub_r_imm(sr, cycles << 12); \
1120     cycles = 0; \
1121   }
1122
1123 #define CHECK_UNHANDLED_BITS(mask) { \
1124   if ((op & (mask)) != 0) \
1125     goto default_; \
1126 }
1127
1128 #define FETCH_OP(pc) \
1129   dr_pc_base[(pc) / 2]
1130
1131 #define FETCH32(a) \
1132   ((dr_pc_base[(a) / 2] << 16) | dr_pc_base[(a) / 2 + 1])
1133
1134 #define GET_Fx() \
1135   ((op >> 4) & 0x0f)
1136
1137 #define GET_Rm GET_Fx
1138
1139 #define GET_Rn() \
1140   ((op >> 8) & 0x0f)
1141
1142 #define CHECK_FX_LT(n) \
1143   if (GET_Fx() >= n) \
1144     goto default_
1145
1146 #define MAX_LOCAL_BRANCHES 32
1147
1148 // op_flags: data from 1st pass
1149 #define OP_FLAGS(pc) op_flags[((pc) - base_pc) / 2]
1150 #define OF_DELAY_OP (1 << 0)
1151
1152 static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
1153 {
1154   // XXX: maybe use structs instead?
1155   void *branch_target_ptr[MAX_LOCAL_BRANCHES];
1156   u32 branch_target_pc[MAX_LOCAL_BRANCHES];
1157   int branch_target_count = 0;
1158   void *branch_patch_ptr[MAX_LOCAL_BRANCHES];
1159   u32 branch_patch_pc[MAX_LOCAL_BRANCHES];
1160   int branch_patch_count = 0;
1161   int pending_branch_cond = -1;
1162   int pending_branch_pc = 0;
1163   u8 op_flags[BLOCK_CYCLE_LIMIT + 1];
1164   struct {
1165     u32 delayed_op:2;
1166     u32 test_irq:1;
1167     u32 use_saved_t:1; // delayed op modifies T
1168   } drcf = { 0, };
1169
1170   // PC of current, first, last, last_target_blk SH2 insn
1171   u32 pc, base_pc, end_pc, out_pc;
1172   u32 last_inlined_literal = 0;
1173   void *block_entry;
1174   block_desc *this_block;
1175   u16 *dr_pc_base;
1176   int blkid_main = 0;
1177   int skip_op = 0;
1178   u32 tmp, tmp2;
1179   int cycles;
1180   int op;
1181   int i;
1182
1183   base_pc = sh2->pc;
1184
1185   // get base/validate PC
1186   dr_pc_base = dr_get_pc_base(base_pc, sh2->is_slave);
1187   if (dr_pc_base == (void *)-1) {
1188     printf("invalid PC, aborting: %08x\n", base_pc);
1189     // FIXME: be less destructive
1190     exit(1);
1191   }
1192
1193   tcache_ptr = tcache_ptrs[tcache_id];
1194   this_block = dr_add_block(base_pc, tcache_id, &blkid_main);
1195   if (this_block == NULL)
1196     return NULL;
1197
1198   // predict tcache overflow
1199   tmp = tcache_ptr - tcache_bases[tcache_id];
1200   if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE) {
1201     printf("tcache %d overflow\n", tcache_id);
1202     return NULL;
1203   }
1204
1205   block_entry = tcache_ptr;
1206   dbg(1, "== %csh2 block #%d,%d %08x -> %p", sh2->is_slave ? 's' : 'm',
1207     tcache_id, blkid_main, base_pc, block_entry);
1208
1209   dr_link_blocks(tcache_ptr, base_pc, tcache_id);
1210
1211   // 1st pass: scan forward for local branches
1212   memset(op_flags, 0, sizeof(op_flags));
1213   for (cycles = 0, pc = base_pc; cycles < BLOCK_CYCLE_LIMIT; cycles++, pc += 2) {
1214     op = FETCH_OP(pc);
1215     if ((op & 0xf000) == 0xa000 || (op & 0xf000) == 0xb000) { // BRA, BSR
1216       signed int offs = ((signed int)(op << 20) >> 19);
1217       pc += 2;
1218       OP_FLAGS(pc) |= OF_DELAY_OP;
1219       ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc + offs + 2,);
1220       break;
1221     }
1222     if ((op & 0xf000) == 0) {
1223       op &= 0xff;
1224       if (op == 0x1b) // SLEEP
1225         break;
1226       if (op == 0x23 || op == 0x03 || op == 0x0b || op == 0x2b) { // BRAF, BSRF, RTS, RTE
1227         pc += 2;
1228         OP_FLAGS(pc) |= OF_DELAY_OP;
1229         break;
1230       }
1231       continue;
1232     }
1233     if ((op & 0xf0df) == 0x400b) { // JMP, JSR
1234       pc += 2;
1235       OP_FLAGS(pc) |= OF_DELAY_OP;
1236       break;
1237     }
1238     if ((op & 0xf900) == 0x8900) { // BT(S), BF(S)
1239       signed int offs = ((signed int)(op << 24) >> 23);
1240       if (op & 0x0400)
1241         OP_FLAGS(pc + 2) |= OF_DELAY_OP;
1242       ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc + offs + 4, break);
1243     }
1244     if ((op & 0xff00) == 0xc300) // TRAPA
1245       break;
1246   }
1247
1248   end_pc = pc;
1249
1250   // clean branch_targets that are not really local,
1251   // and that land on delay slots
1252   for (i = 0, tmp = 0; i < branch_target_count; i++) {
1253     pc = branch_target_pc[i];
1254     if (base_pc <= pc && pc <= end_pc && !(OP_FLAGS(pc) & OF_DELAY_OP))
1255       branch_target_pc[tmp++] = branch_target_pc[i];
1256   }
1257   branch_target_count = tmp;
1258   memset(branch_target_ptr, 0, sizeof(branch_target_ptr[0]) * branch_target_count);
1259 #if !LINK_BRANCHES
1260   // for debug
1261   branch_target_count = 0;
1262 #endif
1263
1264   // -------------------------------------------------
1265   // 2nd pass: actual compilation
1266   out_pc = 0;
1267   pc = base_pc;
1268   for (cycles = 0; pc <= end_pc || drcf.delayed_op; )
1269   {
1270     u32 tmp3, tmp4, sr;
1271
1272     if (drcf.delayed_op > 0)
1273       drcf.delayed_op--;
1274
1275     op = FETCH_OP(pc);
1276
1277     i = find_in_array(branch_target_pc, branch_target_count, pc);
1278     if (i >= 0)
1279     {
1280       if (pc != sh2->pc)
1281       {
1282         /* make "subblock" - just a mid-block entry */
1283         block_desc *subblock;
1284         u16 *drcblk;
1285         int blkid;
1286
1287         sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1288         FLUSH_CYCLES(sr);
1289         // decide if to flush rcache
1290         if ((op & 0xf0ff) == 0x4010 && FETCH_OP(pc + 2) == 0x8bfd) // DT; BF #-2
1291           rcache_clean();
1292         else
1293           rcache_flush();
1294         do_host_disasm(tcache_id);
1295
1296         subblock = dr_add_block(pc, tcache_id, &blkid);
1297         if (subblock == NULL)
1298           return NULL;
1299         subblock->end_addr = pc;
1300
1301         if (tcache_id != 0) { // data array, BIOS
1302           drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
1303           drcblk += (pc & 0x00fff) >> SH2_DRCBLK_DA_SHIFT;
1304           *drcblk = (blkid << 1) | 1;
1305         } else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
1306           drcblk = Pico32xMem->drcblk_ram;
1307           drcblk += (pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1308           *drcblk = (blkid << 1) | 1;
1309         }
1310
1311         dbg(1, "-- %csh2 subblock #%d,%d %08x -> %p", sh2->is_slave ? 's' : 'm',
1312           tcache_id, blkid, pc, tcache_ptr);
1313
1314         // since we made a block entry, link any other blocks that jump to current pc
1315         dr_link_blocks(tcache_ptr, pc, tcache_id);
1316       }
1317       branch_target_ptr[i] = tcache_ptr;
1318
1319       // must update PC
1320       emit_move_r_imm32(SHR_PC, pc);
1321       rcache_clean();
1322
1323       // check cycles
1324       sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1325       emith_cmp_r_imm(sr, 0);
1326       emith_jump_cond(DCOND_LE, sh2_drc_exit);
1327       do_host_disasm(tcache_id);
1328     }
1329
1330 #if (DRC_DEBUG & 3)
1331     insns_compiled++;
1332 #if (DRC_DEBUG & 2)
1333     DasmSH2(sh2dasm_buff, pc, op);
1334     printf("%08x %04x %s\n", pc, op, sh2dasm_buff);
1335 #endif
1336 #endif
1337
1338     pc += 2;
1339     cycles++;
1340
1341     if (skip_op > 0) {
1342       skip_op--;
1343       continue;
1344     }
1345
1346     switch ((op >> 12) & 0x0f)
1347     {
1348     /////////////////////////////////////////////
1349     case 0x00:
1350       switch (op & 0x0f)
1351       {
1352       case 0x02:
1353         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1354         switch (GET_Fx())
1355         {
1356         case 0: // STC SR,Rn  0000nnnn00000010
1357           tmp2 = SHR_SR;
1358           break;
1359         case 1: // STC GBR,Rn 0000nnnn00010010
1360           tmp2 = SHR_GBR;
1361           break;
1362         case 2: // STC VBR,Rn 0000nnnn00100010
1363           tmp2 = SHR_VBR;
1364           break;
1365         default:
1366           goto default_;
1367         }
1368         tmp3 = rcache_get_reg(tmp2, RC_GR_READ);
1369         emith_move_r_r(tmp, tmp3);
1370         if (tmp2 == SHR_SR)
1371           emith_clear_msb(tmp, tmp, 22); // reserved bits defined by ISA as 0
1372         goto end_op;
1373       case 0x03:
1374         CHECK_UNHANDLED_BITS(0xd0);
1375         // BRAF Rm    0000mmmm00100011
1376         // BSRF Rm    0000mmmm00000011
1377         DELAYED_OP;
1378         tmp  = rcache_get_reg(SHR_PC, RC_GR_WRITE);
1379         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1380         emith_move_r_r(tmp, tmp2);
1381         if (op & 0x20)
1382           emith_add_r_imm(tmp, pc + 2);
1383         else { // BSRF
1384           tmp3 = rcache_get_reg(SHR_PR, RC_GR_WRITE);
1385           emith_move_r_imm(tmp3, pc + 2);
1386           emith_add_r_r(tmp, tmp3);
1387         }
1388         out_pc = (u32)-1;
1389         cycles++;
1390         goto end_op;
1391       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
1392       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
1393       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
1394         rcache_clean();
1395         tmp  = rcache_get_reg_arg(1, GET_Rm());
1396         tmp2 = rcache_get_reg_arg(0, SHR_R0);
1397         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1398         emith_add_r_r(tmp2, tmp3);
1399         emit_memhandler_write(op & 3, pc, drcf.delayed_op);
1400         goto end_op;
1401       case 0x07:
1402         // MUL.L     Rm,Rn      0000nnnnmmmm0111
1403         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1404         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1405         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1406         emith_mul(tmp3, tmp2, tmp);
1407         cycles++;
1408         goto end_op;
1409       case 0x08:
1410         CHECK_UNHANDLED_BITS(0xf00);
1411         switch (GET_Fx())
1412         {
1413         case 0: // CLRT               0000000000001000
1414           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1415           if (drcf.delayed_op)
1416             DELAY_SAVE_T(sr);
1417           emith_bic_r_imm(sr, T);
1418           break;
1419         case 1: // SETT               0000000000011000
1420           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1421           if (drcf.delayed_op)
1422             DELAY_SAVE_T(sr);
1423           emith_or_r_imm(sr, T);
1424           break;
1425         case 2: // CLRMAC             0000000000101000
1426           emit_move_r_imm32(SHR_MACL, 0);
1427           emit_move_r_imm32(SHR_MACH, 0);
1428           break;
1429         default:
1430           goto default_;
1431         }
1432         goto end_op;
1433       case 0x09:
1434         switch (GET_Fx())
1435         {
1436         case 0: // NOP        0000000000001001
1437           CHECK_UNHANDLED_BITS(0xf00);
1438           break;
1439         case 1: // DIV0U      0000000000011001
1440           CHECK_UNHANDLED_BITS(0xf00);
1441           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1442           if (drcf.delayed_op)
1443             DELAY_SAVE_T(sr);
1444           emith_bic_r_imm(sr, M|Q|T);
1445           break;
1446         case 2: // MOVT Rn    0000nnnn00101001
1447           sr   = rcache_get_reg(SHR_SR, RC_GR_READ);
1448           tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1449           emith_clear_msb(tmp2, sr, 31);
1450           break;
1451         default:
1452           goto default_;
1453         }
1454         goto end_op;
1455       case 0x0a:
1456         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1457         switch (GET_Fx())
1458         {
1459         case 0: // STS      MACH,Rn   0000nnnn00001010
1460           tmp2 = SHR_MACH;
1461           break;
1462         case 1: // STS      MACL,Rn   0000nnnn00011010
1463           tmp2 = SHR_MACL;
1464           break;
1465         case 2: // STS      PR,Rn     0000nnnn00101010
1466           tmp2 = SHR_PR;
1467           break;
1468         default:
1469           goto default_;
1470         }
1471         tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
1472         emith_move_r_r(tmp, tmp2);
1473         goto end_op;
1474       case 0x0b:
1475         CHECK_UNHANDLED_BITS(0xf00);
1476         switch (GET_Fx())
1477         {
1478         case 0: // RTS        0000000000001011
1479           DELAYED_OP;
1480           emit_move_r_r(SHR_PC, SHR_PR);
1481           out_pc = (u32)-1;
1482           cycles++;
1483           break;
1484         case 1: // SLEEP      0000000000011011
1485           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
1486           emith_clear_msb(tmp, tmp, 20); // clear cycles
1487           out_pc = out_pc - 2;
1488           cycles = 1;
1489           goto end_op;
1490         case 2: // RTE        0000000000101011
1491           DELAYED_OP;
1492           // pop PC
1493           emit_memhandler_read_rr(SHR_PC, SHR_SP, 0, 2);
1494           // pop SR
1495           tmp = rcache_get_reg_arg(0, SHR_SP);
1496           emith_add_r_imm(tmp, 4);
1497           tmp = emit_memhandler_read(2);
1498           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1499           emith_write_sr(sr, tmp);
1500           rcache_free_tmp(tmp);
1501           tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
1502           emith_add_r_imm(tmp, 4*2);
1503           drcf.test_irq = 1;
1504           out_pc = (u32)-1;
1505           cycles += 3;
1506           break;
1507         default:
1508           goto default_;
1509         }
1510         goto end_op;
1511       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
1512       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
1513       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
1514         tmp = emit_indirect_indexed_read(SHR_R0, GET_Rm(), op & 3);
1515         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1516         if ((op & 3) != 2) {
1517           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
1518         } else
1519           emith_move_r_r(tmp2, tmp);
1520         rcache_free_tmp(tmp);
1521         goto end_op;
1522       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
1523         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2);
1524         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
1525         /* MS 16 MAC bits unused if saturated */
1526         sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1527         emith_tst_r_imm(sr, S);
1528         EMITH_SJMP_START(DCOND_EQ);
1529         emith_clear_msb_c(DCOND_NE, tmp4, tmp4, 16);
1530         EMITH_SJMP_END(DCOND_EQ);
1531         rcache_unlock(sr);
1532         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); // might evict SR
1533         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
1534         rcache_free_tmp(tmp2);
1535         sr = rcache_get_reg(SHR_SR, RC_GR_READ); // reget just in case
1536         emith_tst_r_imm(sr, S);
1537
1538         EMITH_JMP_START(DCOND_EQ);
1539         emith_asr(tmp, tmp4, 15);
1540         emith_cmp_r_imm(tmp, -1); // negative overflow (0x80000000..0xffff7fff)
1541         EMITH_SJMP_START(DCOND_GE);
1542         emith_move_r_imm_c(DCOND_LT, tmp4, 0x8000);
1543         emith_move_r_imm_c(DCOND_LT, tmp3, 0x0000);
1544         EMITH_SJMP_END(DCOND_GE);
1545         emith_cmp_r_imm(tmp, 0); // positive overflow (0x00008000..0x7fffffff)
1546         EMITH_SJMP_START(DCOND_LE);
1547         emith_move_r_imm_c(DCOND_GT, tmp4, 0x00007fff);
1548         emith_move_r_imm_c(DCOND_GT, tmp3, 0xffffffff);
1549         EMITH_SJMP_END(DCOND_LE);
1550         EMITH_JMP_END(DCOND_EQ);
1551
1552         rcache_free_tmp(tmp);
1553         cycles += 3;
1554         goto end_op;
1555       }
1556       goto default_;
1557
1558     /////////////////////////////////////////////
1559     case 0x01:
1560       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
1561       rcache_clean();
1562       tmp  = rcache_get_reg_arg(0, GET_Rn());
1563       tmp2 = rcache_get_reg_arg(1, GET_Rm());
1564       if (op & 0x0f)
1565         emith_add_r_imm(tmp, (op & 0x0f) * 4);
1566       emit_memhandler_write(2, pc, drcf.delayed_op);
1567       goto end_op;
1568
1569     case 0x02:
1570       switch (op & 0x0f)
1571       {
1572       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
1573       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
1574       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
1575         rcache_clean();
1576         rcache_get_reg_arg(0, GET_Rn());
1577         rcache_get_reg_arg(1, GET_Rm());
1578         emit_memhandler_write(op & 3, pc, drcf.delayed_op);
1579         goto end_op;
1580       case 0x04: // MOV.B Rm,@–Rn       0010nnnnmmmm0100
1581       case 0x05: // MOV.W Rm,@–Rn       0010nnnnmmmm0101
1582       case 0x06: // MOV.L Rm,@–Rn       0010nnnnmmmm0110
1583         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1584         emith_sub_r_imm(tmp, (1 << (op & 3)));
1585         rcache_clean();
1586         rcache_get_reg_arg(0, GET_Rn());
1587         rcache_get_reg_arg(1, GET_Rm());
1588         emit_memhandler_write(op & 3, pc, drcf.delayed_op);
1589         goto end_op;
1590       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
1591         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1592         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1593         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1594         if (drcf.delayed_op)
1595           DELAY_SAVE_T(sr);
1596         emith_bic_r_imm(sr, M|Q|T);
1597         emith_tst_r_imm(tmp2, (1<<31));
1598         EMITH_SJMP_START(DCOND_EQ);
1599         emith_or_r_imm_c(DCOND_NE, sr, Q);
1600         EMITH_SJMP_END(DCOND_EQ);
1601         emith_tst_r_imm(tmp3, (1<<31));
1602         EMITH_SJMP_START(DCOND_EQ);
1603         emith_or_r_imm_c(DCOND_NE, sr, M);
1604         EMITH_SJMP_END(DCOND_EQ);
1605         emith_teq_r_r(tmp2, tmp3);
1606         EMITH_SJMP_START(DCOND_PL);
1607         emith_or_r_imm_c(DCOND_MI, sr, T);
1608         EMITH_SJMP_END(DCOND_PL);
1609         goto end_op;
1610       case 0x08: // TST Rm,Rn           0010nnnnmmmm1000
1611         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1612         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1613         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1614         if (drcf.delayed_op)
1615           DELAY_SAVE_T(sr);
1616         emith_bic_r_imm(sr, T);
1617         emith_tst_r_r(tmp2, tmp3);
1618         emit_or_t_if_eq(sr);
1619         goto end_op;
1620       case 0x09: // AND Rm,Rn           0010nnnnmmmm1001
1621         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1622         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1623         emith_and_r_r(tmp, tmp2);
1624         goto end_op;
1625       case 0x0a: // XOR Rm,Rn           0010nnnnmmmm1010
1626         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1627         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1628         emith_eor_r_r(tmp, tmp2);
1629         goto end_op;
1630       case 0x0b: // OR  Rm,Rn           0010nnnnmmmm1011
1631         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1632         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1633         emith_or_r_r(tmp, tmp2);
1634         goto end_op;
1635       case 0x0c: // CMP/STR Rm,Rn       0010nnnnmmmm1100
1636         tmp  = rcache_get_tmp();
1637         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1638         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1639         emith_eor_r_r_r(tmp, tmp2, tmp3);
1640         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1641         if (drcf.delayed_op)
1642           DELAY_SAVE_T(sr);
1643         emith_bic_r_imm(sr, T);
1644         emith_tst_r_imm(tmp, 0x000000ff);
1645         emit_or_t_if_eq(tmp);
1646         emith_tst_r_imm(tmp, 0x0000ff00);
1647         emit_or_t_if_eq(tmp);
1648         emith_tst_r_imm(tmp, 0x00ff0000);
1649         emit_or_t_if_eq(tmp);
1650         emith_tst_r_imm(tmp, 0xff000000);
1651         emit_or_t_if_eq(tmp);
1652         rcache_free_tmp(tmp);
1653         goto end_op;
1654       case 0x0d: // XTRCT  Rm,Rn        0010nnnnmmmm1101
1655         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1656         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1657         emith_lsr(tmp, tmp, 16);
1658         emith_or_r_r_lsl(tmp, tmp2, 16);
1659         goto end_op;
1660       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
1661       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
1662         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1663         tmp  = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1664         if (op & 1) {
1665           emith_sext(tmp, tmp2, 16);
1666         } else
1667           emith_clear_msb(tmp, tmp2, 16);
1668         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1669         tmp2 = rcache_get_tmp();
1670         if (op & 1) {
1671           emith_sext(tmp2, tmp3, 16);
1672         } else
1673           emith_clear_msb(tmp2, tmp3, 16);
1674         emith_mul(tmp, tmp, tmp2);
1675         rcache_free_tmp(tmp2);
1676 //      FIXME: causes timing issues in Doom?
1677 //        cycles++;
1678         goto end_op;
1679       }
1680       goto default_;
1681
1682     /////////////////////////////////////////////
1683     case 0x03:
1684       switch (op & 0x0f)
1685       {
1686       case 0x00: // CMP/EQ Rm,Rn        0011nnnnmmmm0000
1687       case 0x02: // CMP/HS Rm,Rn        0011nnnnmmmm0010
1688       case 0x03: // CMP/GE Rm,Rn        0011nnnnmmmm0011
1689       case 0x06: // CMP/HI Rm,Rn        0011nnnnmmmm0110
1690       case 0x07: // CMP/GT Rm,Rn        0011nnnnmmmm0111
1691         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1692         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1693         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1694         if (drcf.delayed_op)
1695           DELAY_SAVE_T(sr);
1696         emith_bic_r_imm(sr, T);
1697         emith_cmp_r_r(tmp2, tmp3);
1698         switch (op & 0x07)
1699         {
1700         case 0x00: // CMP/EQ
1701           emit_or_t_if_eq(sr);
1702           break;
1703         case 0x02: // CMP/HS
1704           EMITH_SJMP_START(DCOND_LO);
1705           emith_or_r_imm_c(DCOND_HS, sr, T);
1706           EMITH_SJMP_END(DCOND_LO);
1707           break;
1708         case 0x03: // CMP/GE
1709           EMITH_SJMP_START(DCOND_LT);
1710           emith_or_r_imm_c(DCOND_GE, sr, T);
1711           EMITH_SJMP_END(DCOND_LT);
1712           break;
1713         case 0x06: // CMP/HI
1714           EMITH_SJMP_START(DCOND_LS);
1715           emith_or_r_imm_c(DCOND_HI, sr, T);
1716           EMITH_SJMP_END(DCOND_LS);
1717           break;
1718         case 0x07: // CMP/GT
1719           EMITH_SJMP_START(DCOND_LE);
1720           emith_or_r_imm_c(DCOND_GT, sr, T);
1721           EMITH_SJMP_END(DCOND_LE);
1722           break;
1723         }
1724         goto end_op;
1725       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
1726         // Q1 = carry(Rn = (Rn << 1) | T)
1727         // if Q ^ M
1728         //   Q2 = carry(Rn += Rm)
1729         // else
1730         //   Q2 = carry(Rn -= Rm)
1731         // Q = M ^ Q1 ^ Q2
1732         // T = (Q == M) = !(Q ^ M) = !(Q1 ^ Q2)
1733         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1734         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1735         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1736         if (drcf.delayed_op)
1737           DELAY_SAVE_T(sr);
1738         emith_tpop_carry(sr, 0);
1739         emith_adcf_r_r(tmp2, tmp2);
1740         emith_tpush_carry(sr, 0);            // keep Q1 in T for now
1741         tmp4 = rcache_get_tmp();
1742         emith_and_r_r_imm(tmp4, sr, M);
1743         emith_eor_r_r_lsr(sr, tmp4, M_SHIFT - Q_SHIFT); // Q ^= M
1744         rcache_free_tmp(tmp4);
1745         // add or sub, invert T if carry to get Q1 ^ Q2
1746         // in: (Q ^ M) passed in Q, Q1 in T
1747         emith_sh2_div1_step(tmp2, tmp3, sr);
1748         emith_bic_r_imm(sr, Q);
1749         emith_tst_r_imm(sr, M);
1750         EMITH_SJMP_START(DCOND_EQ);
1751         emith_or_r_imm_c(DCOND_NE, sr, Q);  // Q = M
1752         EMITH_SJMP_END(DCOND_EQ);
1753         emith_tst_r_imm(sr, T);
1754         EMITH_SJMP_START(DCOND_EQ);
1755         emith_eor_r_imm_c(DCOND_NE, sr, Q); // Q = M ^ Q1 ^ Q2
1756         EMITH_SJMP_END(DCOND_EQ);
1757         emith_eor_r_imm(sr, T);             // T = !(Q1 ^ Q2)
1758         goto end_op;
1759       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
1760         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1761         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1762         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1763         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1764         emith_mul_u64(tmp3, tmp4, tmp, tmp2);
1765         goto end_op;
1766       case 0x08: // SUB     Rm,Rn       0011nnnnmmmm1000
1767       case 0x0c: // ADD     Rm,Rn       0011nnnnmmmm1100
1768         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1769         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1770         if (op & 4) {
1771           emith_add_r_r(tmp, tmp2);
1772         } else
1773           emith_sub_r_r(tmp, tmp2);
1774         goto end_op;
1775       case 0x0a: // SUBC    Rm,Rn       0011nnnnmmmm1010
1776       case 0x0e: // ADDC    Rm,Rn       0011nnnnmmmm1110
1777         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1778         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1779         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1780         if (drcf.delayed_op)
1781           DELAY_SAVE_T(sr);
1782         if (op & 4) { // adc
1783           emith_tpop_carry(sr, 0);
1784           emith_adcf_r_r(tmp, tmp2);
1785           emith_tpush_carry(sr, 0);
1786         } else {
1787           emith_tpop_carry(sr, 1);
1788           emith_sbcf_r_r(tmp, tmp2);
1789           emith_tpush_carry(sr, 1);
1790         }
1791         goto end_op;
1792       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
1793       case 0x0f: // ADDV    Rm,Rn       0011nnnnmmmm1111
1794         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1795         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1796         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1797         if (drcf.delayed_op)
1798           DELAY_SAVE_T(sr);
1799         emith_bic_r_imm(sr, T);
1800         if (op & 4) {
1801           emith_addf_r_r(tmp, tmp2);
1802         } else
1803           emith_subf_r_r(tmp, tmp2);
1804         EMITH_SJMP_START(DCOND_VC);
1805         emith_or_r_imm_c(DCOND_VS, sr, T);
1806         EMITH_SJMP_END(DCOND_VC);
1807         goto end_op;
1808       case 0x0d: // DMULS.L Rm,Rn       0011nnnnmmmm1101
1809         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1810         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1811         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1812         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1813         emith_mul_s64(tmp3, tmp4, tmp, tmp2);
1814         goto end_op;
1815       }
1816       goto default_;
1817
1818     /////////////////////////////////////////////
1819     case 0x04:
1820       switch (op & 0x0f)
1821       {
1822       case 0x00:
1823         switch (GET_Fx())
1824         {
1825         case 0: // SHLL Rn    0100nnnn00000000
1826         case 2: // SHAL Rn    0100nnnn00100000
1827           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1828           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1829           if (drcf.delayed_op)
1830             DELAY_SAVE_T(sr);
1831           emith_tpop_carry(sr, 0); // dummy
1832           emith_lslf(tmp, tmp, 1);
1833           emith_tpush_carry(sr, 0);
1834           goto end_op;
1835         case 1: // DT Rn      0100nnnn00010000
1836           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1837           if (drcf.delayed_op)
1838             DELAY_SAVE_T(sr);
1839           if (FETCH_OP(pc) == 0x8bfd) { // BF #-2
1840             if (gconst_get(GET_Rn(), &tmp)) {
1841               // XXX: limit burned cycles
1842               emit_move_r_imm32(GET_Rn(), 0);
1843               emith_or_r_imm(sr, T);
1844               cycles += tmp * 4;
1845               skip_op = 1;
1846             }
1847             else
1848               emith_sh2_dtbf_loop();
1849             goto end_op;
1850           }
1851           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1852           emith_bic_r_imm(sr, T);
1853           emith_subf_r_imm(tmp, 1);
1854           emit_or_t_if_eq(sr);
1855           goto end_op;
1856         }
1857         goto default_;
1858       case 0x01:
1859         switch (GET_Fx())
1860         {
1861         case 0: // SHLR Rn    0100nnnn00000001
1862         case 2: // SHAR Rn    0100nnnn00100001
1863           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1864           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1865           if (drcf.delayed_op)
1866             DELAY_SAVE_T(sr);
1867           emith_tpop_carry(sr, 0); // dummy
1868           if (op & 0x20) {
1869             emith_asrf(tmp, tmp, 1);
1870           } else
1871             emith_lsrf(tmp, tmp, 1);
1872           emith_tpush_carry(sr, 0);
1873           goto end_op;
1874         case 1: // CMP/PZ Rn  0100nnnn00010001
1875           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1876           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1877           if (drcf.delayed_op)
1878             DELAY_SAVE_T(sr);
1879           emith_bic_r_imm(sr, T);
1880           emith_cmp_r_imm(tmp, 0);
1881           EMITH_SJMP_START(DCOND_LT);
1882           emith_or_r_imm_c(DCOND_GE, sr, T);
1883           EMITH_SJMP_END(DCOND_LT);
1884           goto end_op;
1885         }
1886         goto default_;
1887       case 0x02:
1888       case 0x03:
1889         switch (op & 0x3f)
1890         {
1891         case 0x02: // STS.L    MACH,@–Rn 0100nnnn00000010
1892           tmp = SHR_MACH;
1893           break;
1894         case 0x12: // STS.L    MACL,@–Rn 0100nnnn00010010
1895           tmp = SHR_MACL;
1896           break;
1897         case 0x22: // STS.L    PR,@–Rn   0100nnnn00100010
1898           tmp = SHR_PR;
1899           break;
1900         case 0x03: // STC.L    SR,@–Rn   0100nnnn00000011
1901           tmp = SHR_SR;
1902           break;
1903         case 0x13: // STC.L    GBR,@–Rn  0100nnnn00010011
1904           tmp = SHR_GBR;
1905           break;
1906         case 0x23: // STC.L    VBR,@–Rn  0100nnnn00100011
1907           tmp = SHR_VBR;
1908           break;
1909         default:
1910           goto default_;
1911         }
1912         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1913         emith_sub_r_imm(tmp2, 4);
1914         rcache_clean();
1915         rcache_get_reg_arg(0, GET_Rn());
1916         tmp3 = rcache_get_reg_arg(1, tmp);
1917         if (tmp == SHR_SR)
1918           emith_clear_msb(tmp3, tmp3, 22); // reserved bits defined by ISA as 0
1919         emit_memhandler_write(2, pc, drcf.delayed_op);
1920         goto end_op;
1921       case 0x04:
1922       case 0x05:
1923         switch (op & 0x3f)
1924         {
1925         case 0x04: // ROTL   Rn          0100nnnn00000100
1926         case 0x05: // ROTR   Rn          0100nnnn00000101
1927           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1928           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1929           if (drcf.delayed_op)
1930             DELAY_SAVE_T(sr);
1931           emith_tpop_carry(sr, 0); // dummy
1932           if (op & 1) {
1933             emith_rorf(tmp, tmp, 1);
1934           } else
1935             emith_rolf(tmp, tmp, 1);
1936           emith_tpush_carry(sr, 0);
1937           goto end_op;
1938         case 0x24: // ROTCL  Rn          0100nnnn00100100
1939         case 0x25: // ROTCR  Rn          0100nnnn00100101
1940           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1941           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1942           if (drcf.delayed_op)
1943             DELAY_SAVE_T(sr);
1944           emith_tpop_carry(sr, 0);
1945           if (op & 1) {
1946             emith_rorcf(tmp);
1947           } else
1948             emith_rolcf(tmp);
1949           emith_tpush_carry(sr, 0);
1950           goto end_op;
1951         case 0x15: // CMP/PL Rn          0100nnnn00010101
1952           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1953           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1954           if (drcf.delayed_op)
1955             DELAY_SAVE_T(sr);
1956           emith_bic_r_imm(sr, T);
1957           emith_cmp_r_imm(tmp, 0);
1958           EMITH_SJMP_START(DCOND_LE);
1959           emith_or_r_imm_c(DCOND_GT, sr, T);
1960           EMITH_SJMP_END(DCOND_LE);
1961           goto end_op;
1962         }
1963         goto default_;
1964       case 0x06:
1965       case 0x07:
1966         switch (op & 0x3f)
1967         {
1968         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
1969           tmp = SHR_MACH;
1970           break;
1971         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
1972           tmp = SHR_MACL;
1973           break;
1974         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
1975           tmp = SHR_PR;
1976           break;
1977         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
1978           tmp = SHR_SR;
1979           break;
1980         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
1981           tmp = SHR_GBR;
1982           break;
1983         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
1984           tmp = SHR_VBR;
1985           break;
1986         default:
1987           goto default_;
1988         }
1989         rcache_get_reg_arg(0, GET_Rn());
1990         tmp2 = emit_memhandler_read(2);
1991         if (tmp == SHR_SR) {
1992           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1993           if (drcf.delayed_op)
1994             DELAY_SAVE_T(sr);
1995           emith_write_sr(sr, tmp2);
1996           drcf.test_irq = 1;
1997         } else {
1998           tmp = rcache_get_reg(tmp, RC_GR_WRITE);
1999           emith_move_r_r(tmp, tmp2);
2000         }
2001         rcache_free_tmp(tmp2);
2002         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2003         emith_add_r_imm(tmp, 4);
2004         goto end_op;
2005       case 0x08:
2006       case 0x09:
2007         switch (GET_Fx())
2008         {
2009         case 0:
2010           // SHLL2 Rn        0100nnnn00001000
2011           // SHLR2 Rn        0100nnnn00001001
2012           tmp = 2;
2013           break;
2014         case 1:
2015           // SHLL8 Rn        0100nnnn00011000
2016           // SHLR8 Rn        0100nnnn00011001
2017           tmp = 8;
2018           break;
2019         case 2:
2020           // SHLL16 Rn       0100nnnn00101000
2021           // SHLR16 Rn       0100nnnn00101001
2022           tmp = 16;
2023           break;
2024         default:
2025           goto default_;
2026         }
2027         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2028         if (op & 1) {
2029           emith_lsr(tmp2, tmp2, tmp);
2030         } else
2031           emith_lsl(tmp2, tmp2, tmp);
2032         goto end_op;
2033       case 0x0a:
2034         switch (GET_Fx())
2035         {
2036         case 0: // LDS      Rm,MACH   0100mmmm00001010
2037           tmp2 = SHR_MACH;
2038           break;
2039         case 1: // LDS      Rm,MACL   0100mmmm00011010
2040           tmp2 = SHR_MACL;
2041           break;
2042         case 2: // LDS      Rm,PR     0100mmmm00101010
2043           tmp2 = SHR_PR;
2044           break;
2045         default:
2046           goto default_;
2047         }
2048         emit_move_r_r(tmp2, GET_Rn());
2049         goto end_op;
2050       case 0x0b:
2051         switch (GET_Fx())
2052         {
2053         case 0: // JSR  @Rm   0100mmmm00001011
2054         case 2: // JMP  @Rm   0100mmmm00101011
2055           DELAYED_OP;
2056           if (!(op & 0x20))
2057             emit_move_r_imm32(SHR_PR, pc + 2);
2058           emit_move_r_r(SHR_PC, (op >> 8) & 0x0f);
2059           out_pc = (u32)-1;
2060           cycles++;
2061           break;
2062         case 1: // TAS.B @Rn  0100nnnn00011011
2063           // XXX: is TAS working on 32X?
2064           rcache_get_reg_arg(0, GET_Rn());
2065           tmp = emit_memhandler_read(0);
2066           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2067           if (drcf.delayed_op)
2068             DELAY_SAVE_T(sr);
2069           emith_bic_r_imm(sr, T);
2070           emith_cmp_r_imm(tmp, 0);
2071           emit_or_t_if_eq(sr);
2072           rcache_clean();
2073           emith_or_r_imm(tmp, 0x80);
2074           tmp2 = rcache_get_tmp_arg(1); // assuming it differs to tmp
2075           emith_move_r_r(tmp2, tmp);
2076           rcache_free_tmp(tmp);
2077           rcache_get_reg_arg(0, GET_Rn());
2078           emit_memhandler_write(0, pc, drcf.delayed_op);
2079           cycles += 3;
2080           break;
2081         default:
2082           goto default_;
2083         }
2084         goto end_op;
2085       case 0x0e:
2086         tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
2087         switch (GET_Fx())
2088         {
2089         case 0: // LDC Rm,SR   0100mmmm00001110
2090           tmp2 = SHR_SR;
2091           break;
2092         case 1: // LDC Rm,GBR  0100mmmm00011110
2093           tmp2 = SHR_GBR;
2094           break;
2095         case 2: // LDC Rm,VBR  0100mmmm00101110
2096           tmp2 = SHR_VBR;
2097           break;
2098         default:
2099           goto default_;
2100         }
2101         if (tmp2 == SHR_SR) {
2102           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2103           if (drcf.delayed_op)
2104             DELAY_SAVE_T(sr);
2105           emith_write_sr(sr, tmp);
2106           drcf.test_irq = 1;
2107         } else {
2108           tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE);
2109           emith_move_r_r(tmp2, tmp);
2110         }
2111         goto end_op;
2112       case 0x0f:
2113         // MAC.W @Rm+,@Rn+  0100nnnnmmmm1111
2114         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1);
2115         emith_sext(tmp, tmp, 16);
2116         emith_sext(tmp2, tmp2, 16);
2117         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW);
2118         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
2119         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
2120         rcache_free_tmp(tmp2);
2121         // XXX: MACH should be untouched when S is set?
2122         sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2123         emith_tst_r_imm(sr, S);
2124         EMITH_JMP_START(DCOND_EQ);
2125
2126         emith_asr(tmp, tmp3, 31);
2127         emith_eorf_r_r(tmp, tmp4); // tmp = ((signed)macl >> 31) ^ mach
2128         EMITH_JMP_START(DCOND_EQ);
2129         emith_move_r_imm(tmp3, 0x80000000);
2130         emith_tst_r_r(tmp4, tmp4);
2131         EMITH_SJMP_START(DCOND_MI);
2132         emith_sub_r_imm_c(DCOND_PL, tmp3, 1); // positive
2133         EMITH_SJMP_END(DCOND_MI);
2134         EMITH_JMP_END(DCOND_EQ);
2135
2136         EMITH_JMP_END(DCOND_EQ);
2137         rcache_free_tmp(tmp);
2138         cycles += 2;
2139         goto end_op;
2140       }
2141       goto default_;
2142
2143     /////////////////////////////////////////////
2144     case 0x05:
2145       // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
2146       emit_memhandler_read_rr(GET_Rn(), GET_Rm(), (op & 0x0f) * 4, 2);
2147       goto end_op;
2148
2149     /////////////////////////////////////////////
2150     case 0x06:
2151       switch (op & 0x0f)
2152       {
2153       case 0x00: // MOV.B @Rm,Rn        0110nnnnmmmm0000
2154       case 0x01: // MOV.W @Rm,Rn        0110nnnnmmmm0001
2155       case 0x02: // MOV.L @Rm,Rn        0110nnnnmmmm0010
2156       case 0x04: // MOV.B @Rm+,Rn       0110nnnnmmmm0100
2157       case 0x05: // MOV.W @Rm+,Rn       0110nnnnmmmm0101
2158       case 0x06: // MOV.L @Rm+,Rn       0110nnnnmmmm0110
2159         emit_memhandler_read_rr(GET_Rn(), GET_Rm(), 0, op & 3);
2160         if ((op & 7) >= 4 && GET_Rn() != GET_Rm()) {
2161           tmp = rcache_get_reg(GET_Rm(), RC_GR_RMW);
2162           emith_add_r_imm(tmp, (1 << (op & 3)));
2163         }
2164         goto end_op;
2165       case 0x03:
2166       case 0x07 ... 0x0f:
2167         tmp  = rcache_get_reg(GET_Rm(), RC_GR_READ);
2168         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
2169         switch (op & 0x0f)
2170         {
2171         case 0x03: // MOV    Rm,Rn        0110nnnnmmmm0011
2172           emith_move_r_r(tmp2, tmp);
2173           break;
2174         case 0x07: // NOT    Rm,Rn        0110nnnnmmmm0111
2175           emith_mvn_r_r(tmp2, tmp);
2176           break;
2177         case 0x08: // SWAP.B Rm,Rn        0110nnnnmmmm1000
2178           tmp3 = tmp2;
2179           if (tmp == tmp2)
2180             tmp3 = rcache_get_tmp();
2181           tmp4 = rcache_get_tmp();
2182           emith_lsr(tmp3, tmp, 16);
2183           emith_or_r_r_lsl(tmp3, tmp, 24);
2184           emith_and_r_r_imm(tmp4, tmp, 0xff00);
2185           emith_or_r_r_lsl(tmp3, tmp4, 8);
2186           emith_rol(tmp2, tmp3, 16);
2187           rcache_free_tmp(tmp4);
2188           if (tmp == tmp2)
2189             rcache_free_tmp(tmp3);
2190           break;
2191         case 0x09: // SWAP.W Rm,Rn        0110nnnnmmmm1001
2192           emith_rol(tmp2, tmp, 16);
2193           break;
2194         case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
2195           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2196           if (drcf.delayed_op)
2197             DELAY_SAVE_T(sr);
2198           emith_tpop_carry(sr, 1);
2199           emith_negcf_r_r(tmp2, tmp);
2200           emith_tpush_carry(sr, 1);
2201           break;
2202         case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
2203           emith_neg_r_r(tmp2, tmp);
2204           break;
2205         case 0x0c: // EXTU.B Rm,Rn        0110nnnnmmmm1100
2206           emith_clear_msb(tmp2, tmp, 24);
2207           break;
2208         case 0x0d: // EXTU.W Rm,Rn        0110nnnnmmmm1101
2209           emith_clear_msb(tmp2, tmp, 16);
2210           break;
2211         case 0x0e: // EXTS.B Rm,Rn        0110nnnnmmmm1110
2212           emith_sext(tmp2, tmp, 8);
2213           break;
2214         case 0x0f: // EXTS.W Rm,Rn        0110nnnnmmmm1111
2215           emith_sext(tmp2, tmp, 16);
2216           break;
2217         }
2218         goto end_op;
2219       }
2220       goto default_;
2221
2222     /////////////////////////////////////////////
2223     case 0x07:
2224       // ADD #imm,Rn  0111nnnniiiiiiii
2225       tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2226       if (op & 0x80) { // adding negative
2227         emith_sub_r_imm(tmp, -op & 0xff);
2228       } else
2229         emith_add_r_imm(tmp, op & 0xff);
2230       goto end_op;
2231
2232     /////////////////////////////////////////////
2233     case 0x08:
2234       switch (op & 0x0f00)
2235       {
2236       case 0x0000: // MOV.B R0,@(disp,Rn)  10000000nnnndddd
2237       case 0x0100: // MOV.W R0,@(disp,Rn)  10000001nnnndddd
2238         rcache_clean();
2239         tmp  = rcache_get_reg_arg(0, GET_Rm());
2240         tmp2 = rcache_get_reg_arg(1, SHR_R0);
2241         tmp3 = (op & 0x100) >> 8;
2242         if (op & 0x0f)
2243           emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
2244         emit_memhandler_write(tmp3, pc, drcf.delayed_op);
2245         goto end_op;
2246       case 0x0400: // MOV.B @(disp,Rm),R0  10000100mmmmdddd
2247       case 0x0500: // MOV.W @(disp,Rm),R0  10000101mmmmdddd
2248         tmp = (op & 0x100) >> 8;
2249         emit_memhandler_read_rr(SHR_R0, GET_Rm(), (op & 0x0f) << tmp, tmp);
2250         goto end_op;
2251       case 0x0800: // CMP/EQ #imm,R0       10001000iiiiiiii
2252         // XXX: could use cmn
2253         tmp  = rcache_get_tmp();
2254         tmp2 = rcache_get_reg(0, RC_GR_READ);
2255         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
2256         if (drcf.delayed_op)
2257           DELAY_SAVE_T(sr);
2258         emith_move_r_imm_s8(tmp, op & 0xff);
2259         emith_bic_r_imm(sr, T);
2260         emith_cmp_r_r(tmp2, tmp);
2261         emit_or_t_if_eq(sr);
2262         rcache_free_tmp(tmp);
2263         goto end_op;
2264       case 0x0d00: // BT/S label 10001101dddddddd
2265       case 0x0f00: // BF/S label 10001111dddddddd
2266         DELAYED_OP;
2267         cycles--;
2268         // fallthrough
2269       case 0x0900: // BT   label 10001001dddddddd
2270       case 0x0b00: // BF   label 10001011dddddddd
2271         // will handle conditional branches later
2272         pending_branch_cond = (op & 0x0200) ? DCOND_EQ : DCOND_NE;
2273         i = ((signed int)(op << 24) >> 23);
2274         pending_branch_pc = pc + i + 2;
2275         cycles += 2;
2276         goto end_op;
2277       }
2278       goto default_;
2279
2280     /////////////////////////////////////////////
2281     case 0x09:
2282       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
2283       tmp = pc + (op & 0xff) * 2 + 2;
2284 #if PROPAGATE_CONSTANTS
2285       if (tmp < end_pc + MAX_LITERAL_OFFSET) {
2286         gconst_new(GET_Rn(), (u32)(int)(signed short)FETCH_OP(tmp));
2287         if (last_inlined_literal < tmp)
2288           last_inlined_literal = tmp;
2289       }
2290       else
2291 #endif
2292       {
2293         tmp2 = rcache_get_tmp_arg(0);
2294         emith_move_r_imm(tmp2, tmp);
2295         tmp2 = emit_memhandler_read(1);
2296         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
2297         emith_sext(tmp3, tmp2, 16);
2298         rcache_free_tmp(tmp2);
2299       }
2300       goto end_op;
2301
2302     /////////////////////////////////////////////
2303     case 0x0a:
2304       // BRA  label 1010dddddddddddd
2305       DELAYED_OP;
2306       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2307       tmp = ((signed int)(op << 20) >> 19);
2308       out_pc = pc + tmp + 2;
2309       if (tmp == (u32)-4)
2310         emith_clear_msb(sr, sr, 20); // burn cycles
2311       cycles++;
2312       break;
2313
2314     /////////////////////////////////////////////
2315     case 0x0b:
2316       // BSR  label 1011dddddddddddd
2317       DELAYED_OP;
2318       emit_move_r_imm32(SHR_PR, pc + 2);
2319       tmp = ((signed int)(op << 20) >> 19);
2320       out_pc = pc + tmp + 2;
2321       cycles++;
2322       break;
2323
2324     /////////////////////////////////////////////
2325     case 0x0c:
2326       switch (op & 0x0f00)
2327       {
2328       case 0x0000: // MOV.B R0,@(disp,GBR)   11000000dddddddd
2329       case 0x0100: // MOV.W R0,@(disp,GBR)   11000001dddddddd
2330       case 0x0200: // MOV.L R0,@(disp,GBR)   11000010dddddddd
2331         rcache_clean();
2332         tmp  = rcache_get_reg_arg(0, SHR_GBR);
2333         tmp2 = rcache_get_reg_arg(1, SHR_R0);
2334         tmp3 = (op & 0x300) >> 8;
2335         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
2336         emit_memhandler_write(tmp3, pc, drcf.delayed_op);
2337         goto end_op;
2338       case 0x0400: // MOV.B @(disp,GBR),R0   11000100dddddddd
2339       case 0x0500: // MOV.W @(disp,GBR),R0   11000101dddddddd
2340       case 0x0600: // MOV.L @(disp,GBR),R0   11000110dddddddd
2341         tmp = (op & 0x300) >> 8;
2342         emit_memhandler_read_rr(SHR_R0, SHR_GBR, (op & 0xff) << tmp, tmp);
2343         goto end_op;
2344       case 0x0300: // TRAPA #imm      11000011iiiiiiii
2345         tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
2346         emith_sub_r_imm(tmp, 4*2);
2347         // push SR
2348         tmp = rcache_get_reg_arg(0, SHR_SP);
2349         emith_add_r_imm(tmp, 4);
2350         tmp = rcache_get_reg_arg(1, SHR_SR);
2351         emith_clear_msb(tmp, tmp, 22);
2352         emit_memhandler_write(2, pc, drcf.delayed_op);
2353         // push PC
2354         rcache_get_reg_arg(0, SHR_SP);
2355         tmp = rcache_get_tmp_arg(1);
2356         emith_move_r_imm(tmp, pc);
2357         emit_memhandler_write(2, pc, drcf.delayed_op);
2358         // obtain new PC
2359         emit_memhandler_read_rr(SHR_PC, SHR_VBR, (op & 0xff) * 4, 2);
2360         out_pc = (u32)-1;
2361         cycles += 7;
2362         goto end_op;
2363       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
2364         emit_move_r_imm32(SHR_R0, (pc + (op & 0xff) * 4 + 2) & ~3);
2365         goto end_op;
2366       case 0x0800: // TST #imm,R0           11001000iiiiiiii
2367         tmp = rcache_get_reg(SHR_R0, RC_GR_READ);
2368         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2369         if (drcf.delayed_op)
2370           DELAY_SAVE_T(sr);
2371         emith_bic_r_imm(sr, T);
2372         emith_tst_r_imm(tmp, op & 0xff);
2373         emit_or_t_if_eq(sr);
2374         goto end_op;
2375       case 0x0900: // AND #imm,R0           11001001iiiiiiii
2376         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2377         emith_and_r_imm(tmp, op & 0xff);
2378         goto end_op;
2379       case 0x0a00: // XOR #imm,R0           11001010iiiiiiii
2380         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2381         emith_eor_r_imm(tmp, op & 0xff);
2382         goto end_op;
2383       case 0x0b00: // OR  #imm,R0           11001011iiiiiiii
2384         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2385         emith_or_r_imm(tmp, op & 0xff);
2386         goto end_op;
2387       case 0x0c00: // TST.B #imm,@(R0,GBR)  11001100iiiiiiii
2388         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2389         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2390         if (drcf.delayed_op)
2391           DELAY_SAVE_T(sr);
2392         emith_bic_r_imm(sr, T);
2393         emith_tst_r_imm(tmp, op & 0xff);
2394         emit_or_t_if_eq(sr);
2395         rcache_free_tmp(tmp);
2396         cycles += 2;
2397         goto end_op;
2398       case 0x0d00: // AND.B #imm,@(R0,GBR)  11001101iiiiiiii
2399         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2400         emith_and_r_imm(tmp, op & 0xff);
2401         goto end_rmw_op;
2402       case 0x0e00: // XOR.B #imm,@(R0,GBR)  11001110iiiiiiii
2403         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2404         emith_eor_r_imm(tmp, op & 0xff);
2405         goto end_rmw_op;
2406       case 0x0f00: // OR.B  #imm,@(R0,GBR)  11001111iiiiiiii
2407         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2408         emith_or_r_imm(tmp, op & 0xff);
2409       end_rmw_op:
2410         tmp2 = rcache_get_tmp_arg(1);
2411         emith_move_r_r(tmp2, tmp);
2412         rcache_free_tmp(tmp);
2413         tmp3 = rcache_get_reg_arg(0, SHR_GBR);
2414         tmp4 = rcache_get_reg(SHR_R0, RC_GR_READ);
2415         emith_add_r_r(tmp3, tmp4);
2416         emit_memhandler_write(0, pc, drcf.delayed_op);
2417         cycles += 2;
2418         goto end_op;
2419       }
2420       goto default_;
2421
2422     /////////////////////////////////////////////
2423     case 0x0d:
2424       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
2425       tmp = (pc + (op & 0xff) * 4 + 2) & ~3;
2426 #if PROPAGATE_CONSTANTS
2427       if (tmp < end_pc + MAX_LITERAL_OFFSET) {
2428         gconst_new(GET_Rn(), FETCH32(tmp));
2429         if (last_inlined_literal < tmp)
2430           last_inlined_literal = tmp;
2431       }
2432       else
2433 #endif
2434       {
2435         tmp2 = rcache_get_tmp_arg(0);
2436         emith_move_r_imm(tmp2, tmp);
2437         tmp2 = emit_memhandler_read(2);
2438         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
2439         emith_move_r_r(tmp3, tmp2);
2440         rcache_free_tmp(tmp2);
2441       }
2442       goto end_op;
2443
2444     /////////////////////////////////////////////
2445     case 0x0e:
2446       // MOV #imm,Rn   1110nnnniiiiiiii
2447       emit_move_r_imm32(GET_Rn(), (u32)(signed int)(signed char)op);
2448       goto end_op;
2449
2450     default:
2451     default_:
2452       elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
2453         sh2->is_slave ? 's' : 'm', op, pc - 2);
2454 #ifdef DRC_DEBUG_INTERP
2455       emit_move_r_imm32(SHR_PC, pc - 2);
2456       rcache_flush();
2457       emith_pass_arg_r(0, CONTEXT_REG);
2458       emith_pass_arg_imm(1, op);
2459       emith_call(sh2_do_op);
2460 #endif
2461       break;
2462     }
2463
2464 end_op:
2465     rcache_unlock_all();
2466
2467     // conditional branch handling (with/without delay)
2468     if (pending_branch_cond != -1 && drcf.delayed_op != 2)
2469     {
2470       u32 target_pc = pending_branch_pc;
2471       void *target;
2472
2473       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2474       // handle cycles
2475       FLUSH_CYCLES(sr);
2476       rcache_clean();
2477       if (drcf.use_saved_t)
2478         emith_tst_r_imm(sr, T_save);
2479       else
2480         emith_tst_r_imm(sr, T);
2481
2482       if (find_in_array(branch_target_pc, branch_target_count, target_pc) >= 0) {
2483         // local branch
2484         // XXX: jumps back can be linked already
2485         branch_patch_pc[branch_patch_count] = target_pc;
2486         branch_patch_ptr[branch_patch_count] = tcache_ptr;
2487         emith_jump_cond_patchable(pending_branch_cond, tcache_ptr);
2488
2489         branch_patch_count++;
2490         if (branch_patch_count == MAX_LOCAL_BRANCHES) {
2491           printf("warning: too many local branches\n");
2492           break;
2493         }
2494       }
2495       else {
2496         // can't resolve branch locally, make a block exit
2497         emit_move_r_imm32(SHR_PC, target_pc);
2498         rcache_clean();
2499
2500         target = dr_prepare_ext_branch(target_pc, sh2, tcache_id);
2501         if (target == NULL)
2502           return NULL;
2503         emith_jump_cond_patchable(pending_branch_cond, target);
2504       }
2505
2506       drcf.use_saved_t = 0;
2507       pending_branch_cond = -1;
2508     }
2509
2510     // test irq?
2511     // XXX: delay slots..
2512     if (drcf.test_irq && drcf.delayed_op != 2) {
2513       if (!drcf.delayed_op)
2514         emit_move_r_imm32(SHR_PC, pc);
2515       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2516       FLUSH_CYCLES(sr);
2517       rcache_flush();
2518       emith_call(sh2_drc_test_irq);
2519       drcf.test_irq = 0;
2520     }
2521
2522     do_host_disasm(tcache_id);
2523
2524     if (out_pc != 0 && drcf.delayed_op != 2)
2525       break;
2526   }
2527
2528   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
2529   FLUSH_CYCLES(tmp);
2530   rcache_flush();
2531
2532   if (out_pc == (u32)-1) {
2533     // indirect jump -> back to dispatcher
2534     emith_jump(sh2_drc_dispatcher);
2535   } else {
2536     void *target;
2537     if (out_pc == 0)
2538       out_pc = pc;
2539     emit_move_r_imm32(SHR_PC, out_pc);
2540     rcache_flush();
2541
2542     target = dr_prepare_ext_branch(out_pc, sh2, tcache_id);
2543     if (target == NULL)
2544       return NULL;
2545     emith_jump_patchable(target);
2546   }
2547
2548   // link local branches
2549   for (i = 0; i < branch_patch_count; i++) {
2550     void *target;
2551     int t;
2552     t = find_in_array(branch_target_pc, branch_target_count, branch_patch_pc[i]);
2553     target = branch_target_ptr[t];
2554     if (target == NULL) {
2555       // flush pc and go back to dispatcher (should no longer happen)
2556       printf("stray branch to %08x %p\n", branch_patch_pc[i], tcache_ptr);
2557       target = tcache_ptr;
2558       emit_move_r_imm32(SHR_PC, branch_patch_pc[i]);
2559       rcache_flush();
2560       emith_jump(sh2_drc_dispatcher);
2561     }
2562     emith_jump_patch(branch_patch_ptr[i], target);
2563   }
2564
2565   this_block->end_addr = pc;
2566   if (last_inlined_literal > pc)
2567     this_block->end_addr = last_inlined_literal + 4;
2568
2569   // mark memory blocks as containing compiled code
2570   if (tcache_id != 0) {
2571     // data array, BIOS
2572     u16 *drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
2573     tmp  = (this_block->addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
2574     tmp2 = (this_block->end_addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
2575     drcblk[tmp] = (blkid_main << 1) | 1;
2576     for (++tmp; tmp < tmp2; tmp++) {
2577       if (drcblk[tmp])
2578         continue; // dont overwrite overlay block(s)
2579       drcblk[tmp] = blkid_main << 1;
2580     }
2581   }
2582   else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
2583     tmp  = (this_block->addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
2584     tmp2 = (this_block->end_addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
2585     Pico32xMem->drcblk_ram[tmp] = (blkid_main << 1) | 1;
2586     for (++tmp; tmp < tmp2; tmp++) {
2587       if (Pico32xMem->drcblk_ram[tmp])
2588         continue;
2589       Pico32xMem->drcblk_ram[tmp] = blkid_main << 1;
2590     }
2591   }
2592
2593   tcache_ptrs[tcache_id] = tcache_ptr;
2594
2595 #ifdef ARM
2596   cache_flush_d_inval_i(block_entry, tcache_ptr);
2597 #endif
2598
2599   do_host_disasm(tcache_id);
2600   dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
2601     tcache_id, block_counts[tcache_id],
2602     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
2603     insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
2604   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
2605     dbg(1, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
2606 /*
2607  printf("~~~\n");
2608  tcache_dsm_ptrs[tcache_id] = block_entry;
2609  do_host_disasm(tcache_id);
2610  printf("~~~\n");
2611 */
2612
2613 #if (DRC_DEBUG & 2)
2614   fflush(stdout);
2615 #endif
2616
2617   return block_entry;
2618 }
2619
2620 static void sh2_generate_utils(void)
2621 {
2622   int arg0, arg1, arg2, sr, tmp;
2623   void *sh2_drc_write_end, *sh2_drc_write_slot_end;
2624
2625   host_arg2reg(arg0, 0);
2626   host_arg2reg(arg1, 1);
2627   host_arg2reg(arg2, 2);
2628   emith_move_r_r(arg0, arg0); // nop
2629
2630   // sh2_drc_exit(void)
2631   sh2_drc_exit = (void *)tcache_ptr;
2632   emit_do_static_regs(1, arg2);
2633   emith_sh2_drc_exit();
2634
2635   // sh2_drc_dispatcher(void)
2636   sh2_drc_dispatcher = (void *)tcache_ptr;
2637   sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2638   emith_cmp_r_imm(sr, 0);
2639   emith_jump_cond(DCOND_LT, sh2_drc_exit);
2640   rcache_invalidate();
2641   emith_ctx_read(arg0, SHR_PC * 4);
2642   emith_ctx_read(arg1, offsetof(SH2, is_slave));
2643   emith_add_r_r_imm(arg2, CONTEXT_REG, offsetof(SH2, drc_tmp));
2644   emith_call(lookup_block);
2645   emit_block_entry();
2646   // lookup failed, call sh2_translate()
2647   emith_move_r_r(arg0, CONTEXT_REG);
2648   emith_ctx_read(arg1, offsetof(SH2, drc_tmp)); // tcache_id
2649   emith_call(sh2_translate);
2650   emit_block_entry();
2651   // sh2_translate() failed, flush cache and retry
2652   emith_ctx_read(arg0, offsetof(SH2, drc_tmp));
2653   emith_call(flush_tcache);
2654   emith_move_r_r(arg0, CONTEXT_REG);
2655   emith_ctx_read(arg1, offsetof(SH2, drc_tmp));
2656   emith_call(sh2_translate);
2657   emit_block_entry();
2658   // XXX: can't translate, fail
2659   emith_call(exit);
2660
2661   // sh2_drc_test_irq(void)
2662   // assumes it's called from main function (may jump to dispatcher)
2663   sh2_drc_test_irq = (void *)tcache_ptr;
2664   emith_ctx_read(arg1, offsetof(SH2, pending_level));
2665   sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2666   emith_lsr(arg0, sr, I_SHIFT);
2667   emith_and_r_imm(arg0, 0x0f);
2668   emith_cmp_r_r(arg1, arg0); // pending_level > ((sr >> 4) & 0x0f)?
2669   EMITH_SJMP_START(DCOND_GT);
2670   emith_ret_c(DCOND_LE);     // nope, return
2671   EMITH_SJMP_END(DCOND_GT);
2672   // adjust SP
2673   tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
2674   emith_sub_r_imm(tmp, 4*2);
2675   rcache_clean();
2676   // push SR
2677   tmp = rcache_get_reg_arg(0, SHR_SP);
2678   emith_add_r_imm(tmp, 4);
2679   tmp = rcache_get_reg_arg(1, SHR_SR);
2680   emith_clear_msb(tmp, tmp, 22);
2681   emith_move_r_r(arg2, CONTEXT_REG);
2682   emith_call(p32x_sh2_write32);
2683   rcache_invalidate();
2684   // push PC
2685   rcache_get_reg_arg(0, SHR_SP);
2686   emith_ctx_read(arg1, SHR_PC * 4);
2687   emith_move_r_r(arg2, CONTEXT_REG);
2688   emith_call(p32x_sh2_write32);
2689   rcache_invalidate();
2690   // update I, cycles, do callback
2691   emith_ctx_read(arg1, offsetof(SH2, pending_level));
2692   sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2693   emith_bic_r_imm(sr, I);
2694   emith_or_r_r_lsl(sr, arg1, I_SHIFT);
2695   emith_sub_r_imm(sr, 13 << 12); // at least 13 cycles
2696   rcache_flush();
2697   emith_move_r_r(arg0, CONTEXT_REG);
2698   emith_call_ctx(offsetof(SH2, irq_callback)); // vector = sh2->irq_callback(sh2, level);
2699   // obtain new PC
2700   emith_lsl(arg0, arg0, 2);
2701   emith_ctx_read(arg1, SHR_VBR * 4);
2702   emith_add_r_r(arg0, arg1);
2703   emit_memhandler_read(2);
2704   emith_ctx_write(arg0, SHR_PC * 4);
2705 #ifdef __i386__
2706   emith_add_r_imm(xSP, 4); // fix stack
2707 #endif
2708   emith_jump(sh2_drc_dispatcher);
2709   rcache_invalidate();
2710
2711   // sh2_drc_entry(SH2 *sh2)
2712   sh2_drc_entry = (void *)tcache_ptr;
2713   emith_sh2_drc_entry();
2714   emith_move_r_r(CONTEXT_REG, arg0); // move ctx, arg0
2715   emit_do_static_regs(0, arg2);
2716   emith_call(sh2_drc_test_irq);
2717   emith_jump(sh2_drc_dispatcher);
2718
2719   // write-caused irq detection
2720   sh2_drc_write_end = tcache_ptr;
2721   emith_tst_r_r(arg0, arg0);
2722   EMITH_SJMP_START(DCOND_NE);
2723   emith_jump_ctx_c(DCOND_EQ, offsetof(SH2, drc_tmp)); // return
2724   EMITH_SJMP_END(DCOND_NE);
2725   // since PC is up to date, jump to it's block instead of returning
2726   emith_call(sh2_drc_test_irq);
2727   emith_jump_ctx(offsetof(SH2, drc_tmp));
2728
2729   // write-caused irq detection for writes in delay slot
2730   sh2_drc_write_slot_end = tcache_ptr;
2731   emith_tst_r_r(arg0, arg0);
2732   EMITH_SJMP_START(DCOND_NE);
2733   emith_jump_ctx_c(DCOND_EQ, offsetof(SH2, drc_tmp));
2734   EMITH_SJMP_END(DCOND_NE);
2735   // just burn cycles to get back to dispatcher after branch is handled
2736   sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2737   emith_ctx_write(sr, offsetof(SH2, irq_cycles));
2738   emith_clear_msb(sr, sr, 20); // clear cycles
2739   rcache_flush();
2740   emith_jump_ctx(offsetof(SH2, drc_tmp));
2741
2742   // sh2_drc_write8(u32 a, u32 d)
2743   sh2_drc_write8 = (void *)tcache_ptr;
2744   emith_ret_to_ctx(offsetof(SH2, drc_tmp));
2745   emith_ctx_read(arg2, offsetof(SH2, write8_tab));
2746   emith_sh2_wcall(arg0, arg2, sh2_drc_write_end);
2747
2748   // sh2_drc_write16(u32 a, u32 d)
2749   sh2_drc_write16 = (void *)tcache_ptr;
2750   emith_ret_to_ctx(offsetof(SH2, drc_tmp));
2751   emith_ctx_read(arg2, offsetof(SH2, write16_tab));
2752   emith_sh2_wcall(arg0, arg2, sh2_drc_write_end);
2753
2754   // sh2_drc_write8_slot(u32 a, u32 d)
2755   sh2_drc_write8_slot = (void *)tcache_ptr;
2756   emith_ret_to_ctx(offsetof(SH2, drc_tmp));
2757   emith_ctx_read(arg2, offsetof(SH2, write8_tab));
2758   emith_sh2_wcall(arg0, arg2, sh2_drc_write_slot_end);
2759
2760   // sh2_drc_write16_slot(u32 a, u32 d)
2761   sh2_drc_write16_slot = (void *)tcache_ptr;
2762   emith_ret_to_ctx(offsetof(SH2, drc_tmp));
2763   emith_ctx_read(arg2, offsetof(SH2, write16_tab));
2764   emith_sh2_wcall(arg0, arg2, sh2_drc_write_slot_end);
2765
2766   rcache_invalidate();
2767 #if (DRC_DEBUG & 2)
2768   host_dasm_new_symbol(sh2_drc_entry);
2769   host_dasm_new_symbol(sh2_drc_dispatcher);
2770   host_dasm_new_symbol(sh2_drc_exit);
2771   host_dasm_new_symbol(sh2_drc_test_irq);
2772   host_dasm_new_symbol(sh2_drc_write_end);
2773   host_dasm_new_symbol(sh2_drc_write_slot_end);
2774   host_dasm_new_symbol(sh2_drc_write8);
2775   host_dasm_new_symbol(sh2_drc_write8_slot);
2776   host_dasm_new_symbol(sh2_drc_write16);
2777   host_dasm_new_symbol(sh2_drc_write16_slot);
2778 #endif
2779 }
2780
2781 static void sh2_smc_rm_block(u16 *drcblk, u16 *p, block_desc *btab, u32 a)
2782 {
2783   u16 id = *p >> 1;
2784   block_desc *bd = btab + id;
2785
2786   // FIXME: skip subblocks; do both directions
2787   // FIXME: collect all branches
2788   dbg(1, "  killing block %08x", bd->addr);
2789   bd->addr = bd->end_addr = 0;
2790
2791   while (p > drcblk && (p[-1] >> 1) == id)
2792     p--;
2793
2794   // check for possible overlay block
2795   if (p > 0 && p[-1] != 0) {
2796     bd = btab + (p[-1] >> 1);
2797     if (bd->addr <= a && a < bd->end_addr)
2798       sh2_smc_rm_block(drcblk, p - 1, btab, a);
2799   }
2800
2801   do {
2802     *p++ = 0;
2803   }
2804   while ((*p >> 1) == id);
2805 }
2806
2807 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
2808 {
2809   u16 *drcblk = Pico32xMem->drcblk_ram;
2810   u16 *p = drcblk + ((a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT);
2811
2812   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
2813   sh2_smc_rm_block(drcblk, p, block_tables[0], a);
2814 }
2815
2816 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
2817 {
2818   u16 *drcblk = Pico32xMem->drcblk_da[cpuid];
2819   u16 *p = drcblk + ((a & 0xfff) >> SH2_DRCBLK_DA_SHIFT);
2820
2821   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
2822   sh2_smc_rm_block(drcblk, p, block_tables[1 + cpuid], a);
2823 }
2824
2825 void sh2_execute(SH2 *sh2c, int cycles)
2826 {
2827   int ret_cycles;
2828   sh2 = sh2c; // XXX
2829
2830   sh2c->cycles_aim += cycles;
2831   cycles = sh2c->cycles_aim - sh2c->cycles_done;
2832
2833   // cycles are kept in SHR_SR unused bits (upper 20)
2834   // bit19 contains T saved for delay slot
2835   // others are usual SH2 flags
2836   sh2c->sr &= 0x3f3;
2837   sh2c->sr |= cycles << 12;
2838   sh2_drc_entry(sh2c);
2839
2840   // TODO: irq cycles
2841   ret_cycles = (signed int)sh2c->sr >> 12;
2842   if (ret_cycles > 0)
2843     printf("warning: drc returned with cycles: %d\n", ret_cycles);
2844
2845   sh2c->cycles_done += cycles - ret_cycles;
2846 }
2847
2848 #if (DRC_DEBUG & 1)
2849 void block_stats(void)
2850 {
2851   int c, b, i, total = 0;
2852
2853   printf("block stats:\n");
2854   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
2855     for (i = 0; i < block_counts[b]; i++)
2856       if (block_tables[b][i].addr != 0)
2857         total += block_tables[b][i].refcount;
2858
2859   for (c = 0; c < 10; c++) {
2860     block_desc *blk, *maxb = NULL;
2861     int max = 0;
2862     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
2863       for (i = 0; i < block_counts[b]; i++) {
2864         blk = &block_tables[b][i];
2865         if (blk->addr != 0 && blk->refcount > max) {
2866           max = blk->refcount;
2867           maxb = blk;
2868         }
2869       }
2870     }
2871     if (maxb == NULL)
2872       break;
2873     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
2874       (double)maxb->refcount / total * 100.0);
2875     maxb->refcount = 0;
2876   }
2877
2878   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
2879     for (i = 0; i < block_counts[b]; i++)
2880       block_tables[b][i].refcount = 0;
2881 }
2882 #else
2883 #define block_stats()
2884 #endif
2885
2886 void sh2_drc_flush_all(void)
2887 {
2888   block_stats();
2889   flush_tcache(0);
2890   flush_tcache(1);
2891   flush_tcache(2);
2892 }
2893
2894 void sh2_drc_mem_setup(SH2 *sh2)
2895 {
2896   // fill the convenience pointers
2897   sh2->p_bios = sh2->is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m;
2898   sh2->p_da = Pico32xMem->data_array[sh2->is_slave];
2899   sh2->p_sdram = Pico32xMem->sdram;
2900   sh2->p_rom = Pico.rom;
2901 }
2902
2903 int sh2_drc_init(SH2 *sh2)
2904 {
2905   int i;
2906
2907   if (block_tables[0] == NULL)
2908   {
2909     for (i = 0; i < TCACHE_BUFFERS; i++) {
2910       block_tables[i] = calloc(block_max_counts[i], sizeof(*block_tables[0]));
2911       if (block_tables[i] == NULL)
2912         goto fail;
2913       // max 2 block links (exits) per block
2914       block_links[i] = calloc(block_max_counts[i] * 2, sizeof(*block_links[0]));
2915       if (block_links[i] == NULL)
2916         goto fail;
2917     }
2918     memset(block_counts, 0, sizeof(block_counts));
2919     memset(block_link_counts, 0, sizeof(block_link_counts));
2920
2921     drc_cmn_init();
2922     tcache_ptr = tcache;
2923     sh2_generate_utils();
2924 #ifdef ARM
2925     cache_flush_d_inval_i(tcache, tcache_ptr);
2926 #endif
2927
2928     tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;
2929     for (i = 1; i < ARRAY_SIZE(tcache_bases); i++)
2930       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
2931
2932     // tmp
2933     PicoOpt |= POPT_DIS_VDP_FIFO;
2934
2935 #if (DRC_DEBUG & 2)
2936     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
2937       tcache_dsm_ptrs[i] = tcache_bases[i];
2938     // disasm the utils
2939     tcache_dsm_ptrs[0] = tcache;
2940     do_host_disasm(0);
2941 #endif
2942 #if (DRC_DEBUG & 1)
2943     hash_collisions = 0;
2944 #endif
2945   }
2946
2947   if (hash_table == NULL) {
2948     hash_table = calloc(sizeof(hash_table[0]), MAX_HASH_ENTRIES);
2949     if (hash_table == NULL)
2950       goto fail;
2951   }
2952
2953   return 0;
2954
2955 fail:
2956   sh2_drc_finish(sh2);
2957   return -1;
2958 }
2959
2960 void sh2_drc_finish(SH2 *sh2)
2961 {
2962   int i;
2963
2964   if (block_tables[0] != NULL) {
2965     block_stats();
2966
2967     for (i = 0; i < TCACHE_BUFFERS; i++) {
2968 #if (DRC_DEBUG & 2)
2969       printf("~~~ tcache %d\n", i);
2970       tcache_dsm_ptrs[i] = tcache_bases[i];
2971       tcache_ptr = tcache_ptrs[i];
2972       do_host_disasm(i);
2973 #endif
2974
2975       if (block_tables[i] != NULL)
2976         free(block_tables[i]);
2977       block_tables[i] = NULL;
2978       if (block_links[i] == NULL)
2979         free(block_links[i]);
2980       block_links[i] = NULL;
2981     }
2982
2983     drc_cmn_cleanup();
2984   }
2985
2986   if (hash_table != NULL) {
2987     free(hash_table);
2988     hash_table = NULL;
2989   }
2990 }