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