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