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