drc: split disassembly to separate pass
[picodrive.git] / cpu / sh2 / compiler.c
1 /*
2  * SH2 recompiler
3  * (C) notaz, 2009,2010,2013
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_entry->links),
12  *   except jumps between different tcaches
13  *
14  * implemented:
15  * - static register allocation
16  * - remaining register caching and tracking in temporaries
17  * - block-local branch linking
18  * - block linking (except between tcaches)
19  * - some constant propagation
20  *
21  * TODO:
22  * - better constant propagation
23  * - stack caching?
24  * - bug fixing
25  */
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <assert.h>
30
31 #include "../../pico/pico_int.h"
32 #include "sh2.h"
33 #include "compiler.h"
34 #include "../drc/cmn.h"
35 #include "../debug.h"
36
37 // features
38 #define PROPAGATE_CONSTANTS     1
39 #define LINK_BRANCHES           1
40
41 // limits (per block)
42 #define MAX_BLOCK_SIZE          (BLOCK_INSN_LIMIT * 6 * 6)
43
44 // max literal offset from the block end
45 #define MAX_LITERAL_OFFSET      32*2
46 #define MAX_LITERALS            (BLOCK_INSN_LIMIT / 4)
47 #define MAX_LOCAL_BRANCHES      32
48
49 // debug stuff
50 // 1 - warnings/errors
51 // 2 - block info/smc
52 // 4 - asm
53 // 8 - runtime block entry log
54 // {
55 #ifndef DRC_DEBUG
56 #define DRC_DEBUG 0
57 #endif
58
59 #if DRC_DEBUG
60 #define dbg(l,...) { \
61   if ((l) & DRC_DEBUG) \
62     elprintf(EL_STATUS, ##__VA_ARGS__); \
63 }
64 #include "mame/sh2dasm.h"
65 #include <platform/libpicofe/linux/host_dasm.h>
66 static int insns_compiled, hash_collisions, host_insn_count;
67 #define COUNT_OP \
68         host_insn_count++
69 #else // !DRC_DEBUG
70 #define COUNT_OP
71 #define dbg(...)
72 #endif
73
74 ///
75 #define FETCH_OP(pc) \
76   dr_pc_base[(pc) / 2]
77
78 #define FETCH32(a) \
79   ((dr_pc_base[(a) / 2] << 16) | dr_pc_base[(a) / 2 + 1])
80
81 #define CHECK_UNHANDLED_BITS(mask, label) { \
82   if ((op & (mask)) != 0) \
83     goto label; \
84 }
85
86 #define GET_Fx() \
87   ((op >> 4) & 0x0f)
88
89 #define GET_Rm GET_Fx
90
91 #define GET_Rn() \
92   ((op >> 8) & 0x0f)
93
94 #define BITMASK1(v0) (1 << (v0))
95 #define BITMASK2(v0,v1) ((1 << (v0)) | (1 << (v1)))
96 #define BITMASK3(v0,v1,v2) (BITMASK2(v0,v1) | (1 << (v2)))
97 #define BITMASK4(v0,v1,v2,v3) (BITMASK3(v0,v1,v2) | (1 << (v3)))
98 #define BITMASK5(v0,v1,v2,v3,v4) (BITMASK4(v0,v1,v2,v3) | (1 << (v4)))
99
100 #define SHR_T SHR_SR // might make them separate someday
101
102 static struct op_data {
103   u8 op;
104   u8 cycles;
105   u8 size;     // 0, 1, 2 - byte, word, long
106   s8 rm;       // branch or load/store data reg
107   u32 source;  // bitmask of src regs
108   u32 dest;    // bitmask of dest regs
109   u32 imm;     // immediate/io address/branch target
110                // (for literal - address, not value)
111 } ops[BLOCK_INSN_LIMIT];
112
113 enum op_types {
114   OP_UNHANDLED = 0,
115   OP_BRANCH,
116   OP_BRANCH_CT, // conditional, branch if T set
117   OP_BRANCH_CF, // conditional, branch if T clear
118   OP_BRANCH_R,  // indirect
119   OP_BRANCH_RF, // indirect far (PC + Rm)
120   OP_SETCLRT,   // T flag set/clear
121   OP_MOVE,      // register move
122   OP_LOAD_POOL, // literal pool load
123   OP_SLEEP,
124   OP_RTE,
125 };
126
127 #ifdef DRC_SH2
128
129 #if (DRC_DEBUG & 4)
130 static u8 *tcache_dsm_ptrs[3];
131 static char sh2dasm_buff[64];
132 #define do_host_disasm(tcid) \
133   host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
134   tcache_dsm_ptrs[tcid] = tcache_ptr
135 #else
136 #define do_host_disasm(x)
137 #endif
138
139 #if (DRC_DEBUG & 8) || defined(PDB)
140 static void REGPARM(3) *sh2_drc_log_entry(void *block, SH2 *sh2, u32 sr)
141 {
142   if (block != NULL) {
143     dbg(8, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
144       sh2->pc, block, (signed int)sr >> 12);
145     pdb_step(sh2, sh2->pc);
146   }
147   return block;
148 }
149 #endif
150 // } debug
151
152 #define TCACHE_BUFFERS 3
153
154 // we have 3 translation cache buffers, split from one drc/cmn buffer.
155 // BIOS shares tcache with data array because it's only used for init
156 // and can be discarded early
157 // XXX: need to tune sizes
158 static const int tcache_sizes[TCACHE_BUFFERS] = {
159   DRC_TCACHE_SIZE * 6 / 8, // ROM (rarely used), DRAM
160   DRC_TCACHE_SIZE / 8, // BIOS, data array in master sh2
161   DRC_TCACHE_SIZE / 8, // ... slave
162 };
163
164 static u8 *tcache_bases[TCACHE_BUFFERS];
165 static u8 *tcache_ptrs[TCACHE_BUFFERS];
166
167 // ptr for code emiters
168 static u8 *tcache_ptr;
169
170 #define MAX_BLOCK_ENTRIES (BLOCK_INSN_LIMIT / 8)
171
172 struct block_link {
173   u32 target_pc;
174   void *jump;                // insn address
175   struct block_link *next;   // either in block_entry->links or 
176 };
177
178 struct block_entry {
179   u32 pc;
180   void *tcache_ptr;          // translated block for above PC
181   struct block_entry *next;  // next block in hash_table with same pc hash
182   struct block_link *links;  // links to this entry
183 #if (DRC_DEBUG & 2)
184   struct block_desc *block;
185 #endif
186 };
187
188 struct block_desc {
189   u32 addr;                  // block start SH2 PC address
190   u32 end_addr;              // address after last op or literal
191 #if (DRC_DEBUG & 2)
192   int refcount;
193 #endif
194   int entry_count;
195   struct block_entry entryp[MAX_BLOCK_ENTRIES];
196 };
197
198 static const int block_max_counts[TCACHE_BUFFERS] = {
199   4*1024,
200   256,
201   256,
202 };
203 static struct block_desc *block_tables[TCACHE_BUFFERS];
204 static int block_counts[TCACHE_BUFFERS];
205
206 // we have block_link_pool to avoid using mallocs
207 static const int block_link_pool_max_counts[TCACHE_BUFFERS] = {
208   4*1024,
209   256,
210   256,
211 };
212 static struct block_link *block_link_pool[TCACHE_BUFFERS]; 
213 static int block_link_pool_counts[TCACHE_BUFFERS];
214 static struct block_link *unresolved_links[TCACHE_BUFFERS];
215
216 // used for invalidation
217 static const int ram_sizes[TCACHE_BUFFERS] = {
218   0x40000,
219   0x1000,
220   0x1000,
221 };
222 #define ADDR_TO_BLOCK_PAGE 0x100
223
224 struct block_list {
225   struct block_desc *block;
226   struct block_list *next;
227 };
228
229 // array of pointers to block_lists for RAM and 2 data arrays
230 // each array has len: sizeof(mem) / ADDR_TO_BLOCK_PAGE 
231 static struct block_list **inval_lookup[TCACHE_BUFFERS];
232
233 static const int hash_table_sizes[TCACHE_BUFFERS] = {
234   0x1000,
235   0x100,
236   0x100,
237 };
238 static struct block_entry **hash_tables[TCACHE_BUFFERS];
239
240 #define HASH_FUNC(hash_tab, addr, mask) \
241   (hash_tab)[(((addr) >> 20) ^ ((addr) >> 2)) & (mask)]
242
243 // host register tracking
244 enum {
245   HR_FREE,
246   HR_CACHED, // 'val' has sh2_reg_e
247 //  HR_CONST,  // 'val' has a constant
248   HR_TEMP,   // reg used for temp storage
249 };
250
251 enum {
252   HRF_DIRTY  = 1 << 0, // reg has "dirty" value to be written to ctx
253   HRF_LOCKED = 1 << 1, // HR_CACHED can't be evicted
254 };
255
256 typedef struct {
257   u32 hreg:5;   // "host" reg
258   u32 greg:5;   // "guest" reg
259   u32 type:3;
260   u32 flags:3;
261   u32 stamp:16; // kind of a timestamp
262 } temp_reg_t;
263
264 // note: reg_temp[] must have at least the amount of
265 // registers used by handlers in worst case (currently 4)
266 #ifdef __arm__
267 #include "../drc/emit_arm.c"
268
269 static const int reg_map_g2h[] = {
270    4,  5,  6,  7,
271    8, -1, -1, -1,
272   -1, -1, -1, -1,
273   -1, -1, -1,  9, // r12 .. sp
274   -1, -1, -1, 10, // SHR_PC,  SHR_PPC, SHR_PR,   SHR_SR,
275   -1, -1, -1, -1, // SHR_GBR, SHR_VBR, SHR_MACH, SHR_MACL,
276 };
277
278 static temp_reg_t reg_temp[] = {
279   {  0, },
280   {  1, },
281   { 12, },
282   { 14, },
283   {  2, },
284   {  3, },
285 };
286
287 #elif defined(__i386__)
288 #include "../drc/emit_x86.c"
289
290 static const int reg_map_g2h[] = {
291   xSI,-1, -1, -1,
292   -1, -1, -1, -1,
293   -1, -1, -1, -1,
294   -1, -1, -1, -1,
295   -1, -1, -1, xDI,
296   -1, -1, -1, -1,
297 };
298
299 // ax, cx, dx are usually temporaries by convention
300 static temp_reg_t reg_temp[] = {
301   { xAX, },
302   { xBX, },
303   { xCX, },
304   { xDX, },
305 };
306
307 #else
308 #error unsupported arch
309 #endif
310
311 #define T       0x00000001
312 #define S       0x00000002
313 #define I       0x000000f0
314 #define Q       0x00000100
315 #define M       0x00000200
316 #define T_save  0x00000800
317
318 #define I_SHIFT 4
319 #define Q_SHIFT 8
320 #define M_SHIFT 9
321
322 static void REGPARM(1) (*sh2_drc_entry)(SH2 *sh2);
323 static void            (*sh2_drc_dispatcher)(void);
324 static void            (*sh2_drc_exit)(void);
325 static void            (*sh2_drc_test_irq)(void);
326
327 static u32  REGPARM(2) (*sh2_drc_read8)(u32 a, SH2 *sh2);
328 static u32  REGPARM(2) (*sh2_drc_read16)(u32 a, SH2 *sh2);
329 static u32  REGPARM(2) (*sh2_drc_read32)(u32 a, SH2 *sh2);
330 static void REGPARM(2) (*sh2_drc_write8)(u32 a, u32 d);
331 static void REGPARM(2) (*sh2_drc_write16)(u32 a, u32 d);
332 static int  REGPARM(3) (*sh2_drc_write32)(u32 a, u32 d, SH2 *sh2);
333
334 // address space stuff
335 static int dr_ctx_get_mem_ptr(u32 a, u32 *mask)
336 {
337   int poffs = -1;
338
339   if ((a & ~0x7ff) == 0) {
340     // BIOS
341     poffs = offsetof(SH2, p_bios);
342     *mask = 0x7ff;
343   }
344   else if ((a & 0xfffff000) == 0xc0000000) {
345     // data array
346     poffs = offsetof(SH2, p_da);
347     *mask = 0xfff;
348   }
349   else if ((a & 0xc6000000) == 0x06000000) {
350     // SDRAM
351     poffs = offsetof(SH2, p_sdram);
352     *mask = 0x03ffff;
353   }
354   else if ((a & 0xc6000000) == 0x02000000) {
355     // ROM
356     poffs = offsetof(SH2, p_rom);
357     *mask = 0x3fffff;
358   }
359
360   return poffs;
361 }
362
363 static struct block_entry *dr_get_entry(u32 pc, int is_slave, int *tcache_id)
364 {
365   struct block_entry *be;
366   u32 tcid = 0, mask;
367
368   // data arrays have their own caches
369   if ((pc & 0xe0000000) == 0xc0000000 || (pc & ~0xfff) == 0)
370     tcid = 1 + is_slave;
371
372   *tcache_id = tcid;
373
374   mask = hash_table_sizes[tcid] - 1;
375   be = HASH_FUNC(hash_tables[tcid], pc, mask);
376   for (; be != NULL; be = be->next)
377     if (be->pc == pc)
378       return be;
379
380   return NULL;
381 }
382
383 // ---------------------------------------------------------------
384
385 // block management
386 static void add_to_block_list(struct block_list **blist, struct block_desc *block)
387 {
388   struct block_list *added = malloc(sizeof(*added));
389   if (!added) {
390     elprintf(EL_ANOMALY, "drc OOM (1)");
391     return;
392   }
393   added->block = block;
394   added->next = *blist;
395   *blist = added;
396 }
397
398 static void rm_from_block_list(struct block_list **blist, struct block_desc *block)
399 {
400   struct block_list *prev = NULL, *current = *blist;
401   for (; current != NULL; prev = current, current = current->next) {
402     if (current->block == block) {
403       if (prev == NULL)
404         *blist = current->next;
405       else
406         prev->next = current->next;
407       free(current);
408       return;
409     }
410   }
411   dbg(1, "can't rm block %p (%08x-%08x)",
412     block, block->addr, block->end_addr);
413 }
414
415 static void rm_block_list(struct block_list **blist)
416 {
417   struct block_list *tmp, *current = *blist;
418   while (current != NULL) {
419     tmp = current;
420     current = current->next;
421     free(tmp);
422   }
423   *blist = NULL;
424 }
425
426 static void REGPARM(1) flush_tcache(int tcid)
427 {
428   int i;
429
430   dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
431     tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
432     block_counts[tcid], block_max_counts[tcid]);
433
434   block_counts[tcid] = 0;
435   block_link_pool_counts[tcid] = 0;
436   unresolved_links[tcid] = NULL;
437   memset(hash_tables[tcid], 0, sizeof(*hash_tables[0]) * hash_table_sizes[tcid]);
438   tcache_ptrs[tcid] = tcache_bases[tcid];
439   if (Pico32xMem != NULL) {
440     if (tcid == 0) // ROM, RAM
441       memset(Pico32xMem->drcblk_ram, 0,
442              sizeof(Pico32xMem->drcblk_ram));
443     else
444       memset(Pico32xMem->drcblk_da[tcid - 1], 0,
445              sizeof(Pico32xMem->drcblk_da[0]));
446   }
447 #if (DRC_DEBUG & 4)
448   tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
449 #endif
450
451   for (i = 0; i < ram_sizes[tcid] / ADDR_TO_BLOCK_PAGE; i++)
452     rm_block_list(&inval_lookup[tcid][i]);
453 }
454
455 static void add_to_hashlist(struct block_entry *be, int tcache_id)
456 {
457   u32 tcmask = hash_table_sizes[tcache_id] - 1;
458
459   be->next = HASH_FUNC(hash_tables[tcache_id], be->pc, tcmask);
460   HASH_FUNC(hash_tables[tcache_id], be->pc, tcmask) = be;
461
462 #if (DRC_DEBUG & 2)
463   if (be->next != NULL) {
464     printf(" %08x: hash collision with %08x\n",
465       be->pc, be->next->pc);
466     hash_collisions++;
467   }
468 #endif
469 }
470
471 static void rm_from_hashlist(struct block_entry *be, int tcache_id)
472 {
473   u32 tcmask = hash_table_sizes[tcache_id] - 1;
474   struct block_entry *cur, *prev;
475   
476   cur = HASH_FUNC(hash_tables[tcache_id], be->pc, tcmask);
477   if (cur == NULL)
478     goto missing;
479
480   if (be == cur) { // first
481     HASH_FUNC(hash_tables[tcache_id], be->pc, tcmask) = be->next;
482     return;
483   }
484
485   for (prev = cur, cur = cur->next; cur != NULL; cur = cur->next) {
486     if (cur == be) {
487       prev->next = cur->next;
488       return;
489     }
490   }
491
492 missing:
493   dbg(1, "rm_from_hashlist: be %p %08x missing?", be, be->pc);
494 }
495
496 static struct block_desc *dr_add_block(u32 addr, u32 end_addr, int is_slave, int *blk_id)
497 {
498   struct block_entry *be;
499   struct block_desc *bd;
500   int tcache_id;
501   int *bcount;
502
503   // do a lookup to get tcache_id and override check
504   be = dr_get_entry(addr, is_slave, &tcache_id);
505   if (be != NULL)
506     dbg(1, "block override for %08x", addr);
507
508   bcount = &block_counts[tcache_id];
509   if (*bcount >= block_max_counts[tcache_id]) {
510     dbg(1, "bd overflow for tcache %d", tcache_id);
511     return NULL;
512   }
513
514   bd = &block_tables[tcache_id][*bcount];
515   bd->addr = addr;
516   bd->end_addr = end_addr;
517
518   bd->entry_count = 1;
519   bd->entryp[0].pc = addr;
520   bd->entryp[0].tcache_ptr = tcache_ptr;
521   bd->entryp[0].links = NULL;
522 #if (DRC_DEBUG & 2)
523   bd->entryp[0].block = bd;
524   bd->refcount = 0;
525 #endif
526   add_to_hashlist(&bd->entryp[0], tcache_id);
527
528   *blk_id = *bcount;
529   (*bcount)++;
530
531   return bd;
532 }
533
534 static void REGPARM(3) *dr_lookup_block(u32 pc, int is_slave, int *tcache_id)
535 {
536   struct block_entry *be = NULL;
537   void *block = NULL;
538
539   be = dr_get_entry(pc, is_slave, tcache_id);
540   if (be != NULL)
541     block = be->tcache_ptr;
542
543 #if (DRC_DEBUG & 2)
544   if (be != NULL)
545     be->block->refcount++;
546 #endif
547   return block;
548 }
549
550 static void *dr_failure(void)
551 {
552   lprintf("recompilation failed\n");
553   exit(1);
554 }
555
556 static void *dr_prepare_ext_branch(u32 pc, int is_slave, int tcache_id)
557 {
558 #if LINK_BRANCHES
559   struct block_link *bl = block_link_pool[tcache_id];
560   int cnt = block_link_pool_counts[tcache_id];
561   struct block_entry *be = NULL;
562   int target_tcache_id;
563   int i;
564
565   be = dr_get_entry(pc, is_slave, &target_tcache_id);
566   if (target_tcache_id != tcache_id)
567     return sh2_drc_dispatcher;
568
569   // if pool has been freed, reuse
570   for (i = cnt - 1; i >= 0; i--)
571     if (bl[i].target_pc != 0)
572       break;
573   cnt = i + 1;
574   if (cnt >= block_link_pool_max_counts[tcache_id]) {
575     dbg(1, "bl overflow for tcache %d\n", tcache_id);
576     return NULL;
577   }
578   bl += cnt;
579   block_link_pool_counts[tcache_id]++;
580
581   bl->target_pc = pc;
582   bl->jump = tcache_ptr;
583
584   if (be != NULL) {
585     dbg(2, "- early link from %p to pc %08x", bl->jump, pc);
586     bl->next = be->links;
587     be->links = bl;
588     return be->tcache_ptr;
589   }
590   else {
591     bl->next = unresolved_links[tcache_id];
592     unresolved_links[tcache_id] = bl;
593     return sh2_drc_dispatcher;
594   }
595 #else
596   return sh2_drc_dispatcher;
597 #endif
598 }
599
600 static void dr_link_blocks(struct block_entry *be, int tcache_id)
601 {
602 #if LINK_BRANCHES
603   struct block_link *first = unresolved_links[tcache_id];
604   struct block_link *bl, *prev, *tmp;
605   u32 pc = be->pc;
606
607   for (bl = prev = first; bl != NULL; ) {
608     if (bl->target_pc == pc) {
609       dbg(2, "- link from %p to pc %08x", bl->jump, pc);
610       emith_jump_patch(bl->jump, tcache_ptr);
611
612       // move bl from unresolved_links to block_entry
613       tmp = bl->next;
614       bl->next = be->links;
615       be->links = bl;
616
617       if (bl == first)
618         first = prev = bl = tmp;
619       else
620         prev->next = bl = tmp;
621       continue;
622     }
623     prev = bl;
624     bl = bl->next;
625   }
626   unresolved_links[tcache_id] = first;
627
628   // could sync arm caches here, but that's unnecessary
629 #endif
630 }
631
632 #define ADD_TO_ARRAY(array, count, item, failcode) \
633   array[count++] = item; \
634   if (count >= ARRAY_SIZE(array)) { \
635     dbg(1, "warning: " #array " overflow"); \
636     failcode; \
637   }
638
639 static int find_in_array(u32 *array, size_t size, u32 what)
640 {
641   size_t i;
642   for (i = 0; i < size; i++)
643     if (what == array[i])
644       return i;
645
646   return -1;
647 }
648
649 // ---------------------------------------------------------------
650
651 // register cache / constant propagation stuff
652 typedef enum {
653   RC_GR_READ,
654   RC_GR_WRITE,
655   RC_GR_RMW,
656 } rc_gr_mode;
657
658 static int rcache_get_reg_(sh2_reg_e r, rc_gr_mode mode, int do_locking);
659
660 // guest regs with constants
661 static u32 dr_gcregs[24];
662 // a mask of constant/dirty regs
663 static u32 dr_gcregs_mask;
664 static u32 dr_gcregs_dirty;
665
666 #if PROPAGATE_CONSTANTS
667 static void gconst_new(sh2_reg_e r, u32 val)
668 {
669   int i;
670
671   dr_gcregs_mask  |= 1 << r;
672   dr_gcregs_dirty |= 1 << r;
673   dr_gcregs[r] = val;
674
675   // throw away old r that we might have cached
676   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
677     if ((reg_temp[i].type == HR_CACHED) &&
678          reg_temp[i].greg == r) {
679       reg_temp[i].type = HR_FREE;
680       reg_temp[i].flags = 0;
681     }
682   }
683 }
684 #endif
685
686 static int gconst_get(sh2_reg_e r, u32 *val)
687 {
688   if (dr_gcregs_mask & (1 << r)) {
689     *val = dr_gcregs[r];
690     return 1;
691   }
692   return 0;
693 }
694
695 static int gconst_check(sh2_reg_e r)
696 {
697   if ((dr_gcregs_mask | dr_gcregs_dirty) & (1 << r))
698     return 1;
699   return 0;
700 }
701
702 // update hr if dirty, else do nothing
703 static int gconst_try_read(int hr, sh2_reg_e r)
704 {
705   if (dr_gcregs_dirty & (1 << r)) {
706     emith_move_r_imm(hr, dr_gcregs[r]);
707     dr_gcregs_dirty &= ~(1 << r);
708     return 1;
709   }
710   return 0;
711 }
712
713 static void gconst_check_evict(sh2_reg_e r)
714 {
715   if (dr_gcregs_mask & (1 << r))
716     // no longer cached in reg, make dirty again
717     dr_gcregs_dirty |= 1 << r;
718 }
719
720 static void gconst_kill(sh2_reg_e r)
721 {
722   dr_gcregs_mask &= ~(1 << r);
723   dr_gcregs_dirty &= ~(1 << r);
724 }
725
726 static void gconst_clean(void)
727 {
728   int i;
729
730   for (i = 0; i < ARRAY_SIZE(dr_gcregs); i++)
731     if (dr_gcregs_dirty & (1 << i)) {
732       // using RC_GR_READ here: it will call gconst_try_read,
733       // cache the reg and mark it dirty.
734       rcache_get_reg_(i, RC_GR_READ, 0);
735     }
736 }
737
738 static void gconst_invalidate(void)
739 {
740   dr_gcregs_mask = dr_gcregs_dirty = 0;
741 }
742
743 static u16 rcache_counter;
744
745 static temp_reg_t *rcache_evict(void)
746 {
747   // evict reg with oldest stamp
748   int i, oldest = -1;
749   u16 min_stamp = (u16)-1;
750
751   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
752     if (reg_temp[i].type == HR_CACHED && !(reg_temp[i].flags & HRF_LOCKED) &&
753         reg_temp[i].stamp <= min_stamp) {
754       min_stamp = reg_temp[i].stamp;
755       oldest = i;
756     }
757   }
758
759   if (oldest == -1) {
760     printf("no registers to evict, aborting\n");
761     exit(1);
762   }
763
764   i = oldest;
765   if (reg_temp[i].type == HR_CACHED) {
766     if (reg_temp[i].flags & HRF_DIRTY)
767       // writeback
768       emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
769     gconst_check_evict(reg_temp[i].greg);
770   }
771
772   reg_temp[i].type = HR_FREE;
773   reg_temp[i].flags = 0;
774   return &reg_temp[i];
775 }
776
777 static int get_reg_static(sh2_reg_e r, rc_gr_mode mode)
778 {
779   int i = reg_map_g2h[r];
780   if (i != -1) {
781     if (mode != RC_GR_WRITE)
782       gconst_try_read(i, r);
783   }
784   return i;
785 }
786
787 // note: must not be called when doing conditional code
788 static int rcache_get_reg_(sh2_reg_e r, rc_gr_mode mode, int do_locking)
789 {
790   temp_reg_t *tr;
791   int i, ret;
792
793   // maybe statically mapped?
794   ret = get_reg_static(r, mode);
795   if (ret != -1)
796     goto end;
797
798   rcache_counter++;
799
800   // maybe already cached?
801   // if so, prefer against gconst (they must be in sync)
802   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
803     if (reg_temp[i].type == HR_CACHED && reg_temp[i].greg == r) {
804       reg_temp[i].stamp = rcache_counter;
805       if (mode != RC_GR_READ)
806         reg_temp[i].flags |= HRF_DIRTY;
807       ret = reg_temp[i].hreg;
808       goto end;
809     }
810   }
811
812   // use any free reg
813   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
814     if (reg_temp[i].type == HR_FREE) {
815       tr = &reg_temp[i];
816       goto do_alloc;
817     }
818   }
819
820   tr = rcache_evict();
821
822 do_alloc:
823   tr->type = HR_CACHED;
824   if (do_locking)
825     tr->flags |= HRF_LOCKED;
826   if (mode != RC_GR_READ)
827     tr->flags |= HRF_DIRTY;
828   tr->greg = r;
829   tr->stamp = rcache_counter;
830   ret = tr->hreg;
831
832   if (mode != RC_GR_WRITE) {
833     if (gconst_check(r)) {
834       if (gconst_try_read(ret, r))
835         tr->flags |= HRF_DIRTY;
836     }
837     else
838       emith_ctx_read(tr->hreg, r * 4);
839   }
840
841 end:
842   if (mode != RC_GR_READ)
843     gconst_kill(r);
844
845   return ret;
846 }
847
848 static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
849 {
850   return rcache_get_reg_(r, mode, 1);
851 }
852
853 static int rcache_get_tmp(void)
854 {
855   temp_reg_t *tr;
856   int i;
857
858   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
859     if (reg_temp[i].type == HR_FREE) {
860       tr = &reg_temp[i];
861       goto do_alloc;
862     }
863
864   tr = rcache_evict();
865
866 do_alloc:
867   tr->type = HR_TEMP;
868   return tr->hreg;
869 }
870
871 static int rcache_get_arg_id(int arg)
872 {
873   int i, r = 0;
874   host_arg2reg(r, arg);
875
876   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
877     if (reg_temp[i].hreg == r)
878       break;
879
880   if (i == ARRAY_SIZE(reg_temp)) // can't happen
881     exit(1);
882
883   if (reg_temp[i].type == HR_CACHED) {
884     // writeback
885     if (reg_temp[i].flags & HRF_DIRTY)
886       emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
887     gconst_check_evict(reg_temp[i].greg);
888   }
889   else if (reg_temp[i].type == HR_TEMP) {
890     printf("arg %d reg %d already used, aborting\n", arg, r);
891     exit(1);
892   }
893
894   reg_temp[i].type = HR_FREE;
895   reg_temp[i].flags = 0;
896
897   return i;
898 }
899
900 // get a reg to be used as function arg
901 static int rcache_get_tmp_arg(int arg)
902 {
903   int id = rcache_get_arg_id(arg);
904   reg_temp[id].type = HR_TEMP;
905
906   return reg_temp[id].hreg;
907 }
908
909 // same but caches a reg. RC_GR_READ only.
910 static int rcache_get_reg_arg(int arg, sh2_reg_e r)
911 {
912   int i, srcr, dstr, dstid;
913   int dirty = 0, src_dirty = 0;
914
915   dstid = rcache_get_arg_id(arg);
916   dstr = reg_temp[dstid].hreg;
917
918   // maybe already statically mapped?
919   srcr = get_reg_static(r, RC_GR_READ);
920   if (srcr != -1)
921     goto do_cache;
922
923   // maybe already cached?
924   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
925     if ((reg_temp[i].type == HR_CACHED) &&
926          reg_temp[i].greg == r)
927     {
928       srcr = reg_temp[i].hreg;
929       if (reg_temp[i].flags & HRF_DIRTY)
930         src_dirty = 1;
931       goto do_cache;
932     }
933   }
934
935   // must read
936   srcr = dstr;
937   if (gconst_check(r)) {
938     if (gconst_try_read(srcr, r))
939       dirty = 1;
940   }
941   else
942     emith_ctx_read(srcr, r * 4);
943
944 do_cache:
945   if (dstr != srcr)
946     emith_move_r_r(dstr, srcr);
947 #if 1
948   else
949     dirty |= src_dirty;
950
951   if (dirty)
952     // must clean, callers might want to modify the arg before call
953     emith_ctx_write(dstr, r * 4);
954 #else
955   if (dirty)
956     reg_temp[dstid].flags |= HRF_DIRTY;
957 #endif
958
959   reg_temp[dstid].stamp = ++rcache_counter;
960   reg_temp[dstid].type = HR_CACHED;
961   reg_temp[dstid].greg = r;
962   reg_temp[dstid].flags |= HRF_LOCKED;
963   return dstr;
964 }
965
966 static void rcache_free_tmp(int hr)
967 {
968   int i;
969   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
970     if (reg_temp[i].hreg == hr)
971       break;
972
973   if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
974     printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
975     return;
976   }
977
978   reg_temp[i].type = HR_FREE;
979   reg_temp[i].flags = 0;
980 }
981
982 static void rcache_unlock(int hr)
983 {
984   int i;
985   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
986     if (reg_temp[i].type == HR_CACHED && reg_temp[i].hreg == hr)
987       reg_temp[i].flags &= ~HRF_LOCKED;
988 }
989
990 static void rcache_unlock_all(void)
991 {
992   int i;
993   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
994     reg_temp[i].flags &= ~HRF_LOCKED;
995 }
996
997 static void rcache_clean(void)
998 {
999   int i;
1000   gconst_clean();
1001
1002   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
1003     if (reg_temp[i].type == HR_CACHED && (reg_temp[i].flags & HRF_DIRTY)) {
1004       // writeback
1005       emith_ctx_write(reg_temp[i].hreg, reg_temp[i].greg * 4);
1006       reg_temp[i].flags &= ~HRF_DIRTY;
1007     }
1008 }
1009
1010 static void rcache_invalidate(void)
1011 {
1012   int i;
1013   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
1014     reg_temp[i].type = HR_FREE;
1015     reg_temp[i].flags = 0;
1016   }
1017   rcache_counter = 0;
1018
1019   gconst_invalidate();
1020 }
1021
1022 static void rcache_flush(void)
1023 {
1024   rcache_clean();
1025   rcache_invalidate();
1026 }
1027
1028 // ---------------------------------------------------------------
1029
1030 static int emit_get_rbase_and_offs(u32 a, u32 *offs)
1031 {
1032   u32 mask = 0;
1033   int poffs;
1034   int hr;
1035
1036   poffs = dr_ctx_get_mem_ptr(a, &mask);
1037   if (poffs == -1)
1038     return -1;
1039
1040   // XXX: could use some related reg
1041   hr = rcache_get_tmp();
1042   emith_ctx_read(hr, poffs);
1043   emith_add_r_imm(hr, a & mask & ~0xff);
1044   *offs = a & 0xff; // XXX: ARM oriented..
1045   return hr;
1046 }
1047
1048 static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
1049 {
1050 #if PROPAGATE_CONSTANTS
1051   gconst_new(dst, imm);
1052 #else
1053   int hr = rcache_get_reg(dst, RC_GR_WRITE);
1054   emith_move_r_imm(hr, imm);
1055 #endif
1056 }
1057
1058 static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
1059 {
1060   int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
1061   int hr_s = rcache_get_reg(src, RC_GR_READ);
1062
1063   emith_move_r_r(hr_d, hr_s);
1064 }
1065
1066 // T must be clear, and comparison done just before this
1067 static void emit_or_t_if_eq(int srr)
1068 {
1069   EMITH_SJMP_START(DCOND_NE);
1070   emith_or_r_imm_c(DCOND_EQ, srr, T);
1071   EMITH_SJMP_END(DCOND_NE);
1072 }
1073
1074 // arguments must be ready
1075 // reg cache must be clean before call
1076 static int emit_memhandler_read_(int size, int ram_check)
1077 {
1078   int arg0, arg1;
1079   host_arg2reg(arg0, 0);
1080
1081   rcache_clean();
1082
1083   // must writeback cycles for poll detection stuff
1084   // FIXME: rm
1085   if (reg_map_g2h[SHR_SR] != -1)
1086     emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
1087
1088   arg1 = rcache_get_tmp_arg(1);
1089   emith_move_r_r(arg1, CONTEXT_REG);
1090
1091 #ifndef PDB_NET
1092   if (ram_check && Pico.rom == (void *)0x02000000 && Pico32xMem->sdram == (void *)0x06000000) {
1093     int tmp = rcache_get_tmp();
1094     emith_and_r_r_imm(tmp, arg0, 0xfb000000);
1095     emith_cmp_r_imm(tmp, 0x02000000);
1096     switch (size) {
1097     case 0: // 8
1098       EMITH_SJMP3_START(DCOND_NE);
1099       emith_eor_r_imm_c(DCOND_EQ, arg0, 1);
1100       emith_read8_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
1101       EMITH_SJMP3_MID(DCOND_NE);
1102       emith_call_cond(DCOND_NE, sh2_drc_read8);
1103       EMITH_SJMP3_END();
1104       break;
1105     case 1: // 16
1106       EMITH_SJMP3_START(DCOND_NE);
1107       emith_read16_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
1108       EMITH_SJMP3_MID(DCOND_NE);
1109       emith_call_cond(DCOND_NE, sh2_drc_read16);
1110       EMITH_SJMP3_END();
1111       break;
1112     case 2: // 32
1113       EMITH_SJMP3_START(DCOND_NE);
1114       emith_read_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
1115       emith_ror_c(DCOND_EQ, arg0, arg0, 16);
1116       EMITH_SJMP3_MID(DCOND_NE);
1117       emith_call_cond(DCOND_NE, sh2_drc_read32);
1118       EMITH_SJMP3_END();
1119       break;
1120     }
1121   }
1122   else
1123 #endif
1124   {
1125     switch (size) {
1126     case 0: // 8
1127       emith_call(sh2_drc_read8);
1128       break;
1129     case 1: // 16
1130       emith_call(sh2_drc_read16);
1131       break;
1132     case 2: // 32
1133       emith_call(sh2_drc_read32);
1134       break;
1135     }
1136   }
1137   rcache_invalidate();
1138
1139   if (reg_map_g2h[SHR_SR] != -1)
1140     emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4);
1141
1142   // assuming arg0 and retval reg matches
1143   return rcache_get_tmp_arg(0);
1144 }
1145
1146 static int emit_memhandler_read(int size)
1147 {
1148   return emit_memhandler_read_(size, 1);
1149 }
1150
1151 static int emit_memhandler_read_rr(sh2_reg_e rd, sh2_reg_e rs, u32 offs, int size)
1152 {
1153   int hr, hr2, ram_check = 1;
1154   u32 val, offs2;
1155
1156   if (gconst_get(rs, &val)) {
1157     hr = emit_get_rbase_and_offs(val + offs, &offs2);
1158     if (hr != -1) {
1159       hr2 = rcache_get_reg(rd, RC_GR_WRITE);
1160       switch (size) {
1161       case 0: // 8
1162         emith_read8_r_r_offs(hr2, hr, offs2 ^ 1);
1163         emith_sext(hr2, hr2, 8);
1164         break;
1165       case 1: // 16
1166         emith_read16_r_r_offs(hr2, hr, offs2);
1167         emith_sext(hr2, hr2, 16);
1168         break;
1169       case 2: // 32
1170         emith_read_r_r_offs(hr2, hr, offs2);
1171         emith_ror(hr2, hr2, 16);
1172         break;
1173       }
1174       rcache_free_tmp(hr);
1175       return hr2;
1176     }
1177
1178     ram_check = 0;
1179   }
1180
1181   hr = rcache_get_reg_arg(0, rs);
1182   if (offs != 0)
1183     emith_add_r_imm(hr, offs);
1184   hr  = emit_memhandler_read_(size, ram_check);
1185   hr2 = rcache_get_reg(rd, RC_GR_WRITE);
1186   if (size != 2) {
1187     emith_sext(hr2, hr, (size == 1) ? 16 : 8);
1188   } else
1189     emith_move_r_r(hr2, hr);
1190   rcache_free_tmp(hr);
1191
1192   return hr2;
1193 }
1194
1195 static void emit_memhandler_write(int size, u32 pc)
1196 {
1197   int ctxr;
1198   host_arg2reg(ctxr, 2);
1199   if (reg_map_g2h[SHR_SR] != -1)
1200     emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
1201
1202   switch (size) {
1203   case 0: // 8
1204     // XXX: consider inlining sh2_drc_write8
1205     rcache_clean();
1206     emith_call(sh2_drc_write8);
1207     break;
1208   case 1: // 16
1209     rcache_clean();
1210     emith_call(sh2_drc_write16);
1211     break;
1212   case 2: // 32
1213     emith_move_r_r(ctxr, CONTEXT_REG);
1214     emith_call(sh2_drc_write32);
1215     break;
1216   }
1217
1218   rcache_invalidate();
1219   if (reg_map_g2h[SHR_SR] != -1)
1220     emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4);
1221 }
1222
1223 // @(Rx,Ry)
1224 static int emit_indirect_indexed_read(int rx, int ry, int size)
1225 {
1226   int a0, t;
1227   a0 = rcache_get_reg_arg(0, rx);
1228   t  = rcache_get_reg(ry, RC_GR_READ);
1229   emith_add_r_r(a0, t);
1230   return emit_memhandler_read(size);
1231 }
1232
1233 // read @Rn, @rm
1234 static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size)
1235 {
1236   int tmp;
1237
1238   rcache_get_reg_arg(0, rn);
1239   tmp = emit_memhandler_read(size);
1240   emith_ctx_write(tmp, offsetof(SH2, drc_tmp));
1241   rcache_free_tmp(tmp);
1242   tmp = rcache_get_reg(rn, RC_GR_RMW);
1243   emith_add_r_imm(tmp, 1 << size);
1244   rcache_unlock(tmp);
1245
1246   rcache_get_reg_arg(0, rm);
1247   *rmr = emit_memhandler_read(size);
1248   *rnr = rcache_get_tmp();
1249   emith_ctx_read(*rnr, offsetof(SH2, drc_tmp));
1250   tmp = rcache_get_reg(rm, RC_GR_RMW);
1251   emith_add_r_imm(tmp, 1 << size);
1252   rcache_unlock(tmp);
1253 }
1254  
1255 static void emit_do_static_regs(int is_write, int tmpr)
1256 {
1257   int i, r, count;
1258
1259   for (i = 0; i < ARRAY_SIZE(reg_map_g2h); i++) {
1260     r = reg_map_g2h[i];
1261     if (r == -1)
1262       continue;
1263
1264     for (count = 1; i < ARRAY_SIZE(reg_map_g2h) - 1; i++, r++) {
1265       if (reg_map_g2h[i + 1] != r + 1)
1266         break;
1267       count++;
1268     }
1269
1270     if (count > 1) {
1271       // i, r point to last item
1272       if (is_write)
1273         emith_ctx_write_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
1274       else
1275         emith_ctx_read_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
1276     } else {
1277       if (is_write)
1278         emith_ctx_write(r, i * 4);
1279       else
1280         emith_ctx_read(r, i * 4);
1281     }
1282   }
1283 }
1284
1285 static void emit_block_entry(void)
1286 {
1287   int arg0;
1288
1289   host_arg2reg(arg0, 0);
1290
1291 #if (DRC_DEBUG & 8) || defined(PDB)
1292   int arg1, arg2;
1293   host_arg2reg(arg1, 1);
1294   host_arg2reg(arg2, 2);
1295
1296   emit_do_static_regs(1, arg2);
1297   emith_move_r_r(arg1, CONTEXT_REG);
1298   emith_move_r_r(arg2, rcache_get_reg(SHR_SR, RC_GR_READ));
1299   emith_call(sh2_drc_log_entry);
1300   rcache_invalidate();
1301 #endif
1302   emith_tst_r_r(arg0, arg0);
1303   EMITH_SJMP_START(DCOND_EQ);
1304   emith_jump_reg_c(DCOND_NE, arg0);
1305   EMITH_SJMP_END(DCOND_EQ);
1306 }
1307
1308 #define DELAY_SAVE_T(sr) { \
1309   emith_bic_r_imm(sr, T_save); \
1310   emith_tst_r_imm(sr, T);      \
1311   EMITH_SJMP_START(DCOND_EQ);  \
1312   emith_or_r_imm_c(DCOND_NE, sr, T_save); \
1313   EMITH_SJMP_END(DCOND_EQ);    \
1314 }
1315
1316 #define FLUSH_CYCLES(sr) \
1317   if (cycles > 0) { \
1318     emith_sub_r_imm(sr, cycles << 12); \
1319     cycles = 0; \
1320   }
1321
1322 static void *dr_get_pc_base(u32 pc, int is_slave);
1323
1324 static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
1325 {
1326   u32 branch_target_pc[MAX_LOCAL_BRANCHES];
1327   void *branch_target_ptr[MAX_LOCAL_BRANCHES];
1328   int branch_target_count = 0;
1329   void *branch_patch_ptr[MAX_LOCAL_BRANCHES];
1330   u32 branch_patch_pc[MAX_LOCAL_BRANCHES];
1331   int branch_patch_count = 0;
1332   u32 literal_addr[MAX_LITERALS];
1333   int literal_addr_count = 0;
1334   u8 op_flags[BLOCK_INSN_LIMIT];
1335   struct {
1336     u32 test_irq:1;
1337     u32 pending_branch_direct:1;
1338     u32 pending_branch_indirect:1;
1339   } drcf = { 0, };
1340
1341   // PC of current, first, last SH2 insn
1342   u32 pc, base_pc, end_pc;
1343   u32 end_literals;
1344   void *block_entry_ptr;
1345   struct block_desc *block;
1346   u16 *dr_pc_base;
1347   struct op_data *opd;
1348   int blkid_main = 0;
1349   int skip_op = 0;
1350   u32 tmp, tmp2;
1351   int cycles;
1352   int i, v;
1353   int op;
1354
1355   base_pc = sh2->pc;
1356
1357   // get base/validate PC
1358   dr_pc_base = dr_get_pc_base(base_pc, sh2->is_slave);
1359   if (dr_pc_base == (void *)-1) {
1360     printf("invalid PC, aborting: %08x\n", base_pc);
1361     // FIXME: be less destructive
1362     exit(1);
1363   }
1364
1365   tcache_ptr = tcache_ptrs[tcache_id];
1366
1367   // predict tcache overflow
1368   tmp = tcache_ptr - tcache_bases[tcache_id];
1369   if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE) {
1370     dbg(1, "tcache %d overflow", tcache_id);
1371     return NULL;
1372   }
1373
1374   // initial passes to disassemble and analyze the block
1375   scan_block(base_pc, sh2->is_slave, op_flags, &end_pc, &end_literals);
1376
1377   block = dr_add_block(base_pc, end_literals, sh2->is_slave, &blkid_main);
1378   if (block == NULL)
1379     return NULL;
1380
1381   block_entry_ptr = tcache_ptr;
1382   dbg(2, "== %csh2 block #%d,%d %08x-%08x -> %p", sh2->is_slave ? 's' : 'm',
1383     tcache_id, blkid_main, base_pc, end_pc, block_entry_ptr);
1384
1385   dr_link_blocks(&block->entryp[0], tcache_id);
1386
1387   // collect branch_targets that don't land on delay slots
1388   for (pc = base_pc, i = 0; pc < end_pc; i++, pc += 2) {
1389     if (!(op_flags[i] & OF_BTARGET))
1390       continue;
1391     if (op_flags[i] & OF_DELAY_OP) {
1392       op_flags[i] &= ~OF_BTARGET;
1393       continue;
1394     }
1395     ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc, break);
1396   }
1397
1398   if (branch_target_count > 0) {
1399     memset(branch_target_ptr, 0, sizeof(branch_target_ptr[0]) * branch_target_count);
1400   }
1401
1402   // -------------------------------------------------
1403   // 3rd pass: actual compilation
1404   pc = base_pc;
1405   cycles = 0;
1406   for (i = 0; pc < end_pc; i++)
1407   {
1408     u32 delay_dep_fw = 0, delay_dep_bk = 0;
1409     u32 tmp3, tmp4, sr;
1410
1411     opd = &ops[i];
1412     op = FETCH_OP(pc);
1413
1414 #if (DRC_DEBUG & 2)
1415     insns_compiled++;
1416 #endif
1417 #if (DRC_DEBUG & 4)
1418     DasmSH2(sh2dasm_buff, pc, op);
1419     printf("%c%08x %04x %s\n", (op_flags[i] & OF_BTARGET) ? '*' : ' ',
1420       pc, op, sh2dasm_buff);
1421 #endif
1422
1423     if ((op_flags[i] & OF_BTARGET) || pc == base_pc)
1424     {
1425       if (pc != base_pc)
1426       {
1427         sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1428         FLUSH_CYCLES(sr);
1429         rcache_flush();
1430
1431         // make block entry
1432         v = block->entry_count;
1433         if (v < ARRAY_SIZE(block->entryp)) {
1434           block->entryp[v].pc = pc;
1435           block->entryp[v].tcache_ptr = tcache_ptr;
1436           block->entryp[v].links = NULL;
1437 #if (DRC_DEBUG & 2)
1438           block->entryp[v].block = block;
1439 #endif
1440           add_to_hashlist(&block->entryp[v], tcache_id);
1441           block->entry_count++;
1442
1443           dbg(2, "-- %csh2 block #%d,%d entry %08x -> %p",
1444             sh2->is_slave ? 's' : 'm', tcache_id, blkid_main,
1445             pc, tcache_ptr);
1446
1447           // since we made a block entry, link any other blocks
1448           // that jump to current pc
1449           dr_link_blocks(&block->entryp[v], tcache_id);
1450         }
1451         else {
1452           dbg(1, "too many entryp for block #%d,%d pc=%08x",
1453             tcache_id, blkid_main, pc);
1454         }
1455
1456         do_host_disasm(tcache_id);
1457       }
1458
1459       v = find_in_array(branch_target_pc, branch_target_count, pc);
1460       if (v >= 0)
1461         branch_target_ptr[v] = tcache_ptr;
1462
1463       // must update PC
1464       emit_move_r_imm32(SHR_PC, pc);
1465       rcache_clean();
1466
1467       // check cycles
1468       sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1469       emith_cmp_r_imm(sr, 0);
1470       emith_jump_cond(DCOND_LE, sh2_drc_exit);
1471       do_host_disasm(tcache_id);
1472       rcache_unlock_all();
1473     }
1474
1475 #ifdef DRC_CMP
1476     if (!(op_flags[i] & OF_DELAY_OP)) {
1477       emit_move_r_imm32(SHR_PC, pc);
1478       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1479       FLUSH_CYCLES(sr);
1480       // rcache_clean(); // FIXME
1481       rcache_flush();
1482       emit_do_static_regs(1, 0);
1483       emith_pass_arg_r(0, CONTEXT_REG);
1484       emith_call(do_sh2_cmp);
1485     }
1486 #endif
1487
1488     pc += 2;
1489     cycles += opd->cycles;
1490
1491     if (skip_op > 0) {
1492       skip_op--;
1493       continue;
1494     }
1495
1496     if (op_flags[i] & OF_DELAY_OP)
1497     {
1498       // handle delay slot dependencies
1499       delay_dep_fw = opd->dest & ops[i-1].source;
1500       delay_dep_bk = opd->source & ops[i-1].dest;
1501       if (delay_dep_fw & BITMASK1(SHR_T)) {
1502         sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1503         DELAY_SAVE_T(sr);
1504       }
1505       if (delay_dep_fw & ~BITMASK1(SHR_T))
1506         dbg(1, "unhandled delay_dep_fw: %x", delay_dep_fw & ~BITMASK1(SHR_T));
1507       if (delay_dep_bk)
1508         dbg(1, "unhandled delay_dep_bk: %x", delay_dep_bk);
1509     }
1510
1511     switch (opd->op)
1512     {
1513     case OP_BRANCH:
1514     case OP_BRANCH_CT:
1515     case OP_BRANCH_CF:
1516       if (opd->dest & BITMASK1(SHR_PR))
1517         emit_move_r_imm32(SHR_PR, pc + 2);
1518       drcf.pending_branch_direct = 1;
1519       goto end_op;
1520
1521     case OP_BRANCH_R:
1522       if (opd->dest & BITMASK1(SHR_PR))
1523         emit_move_r_imm32(SHR_PR, pc + 2);
1524       emit_move_r_r(SHR_PC, opd->rm);
1525       drcf.pending_branch_indirect = 1;
1526       goto end_op;
1527
1528     case OP_BRANCH_RF:
1529       tmp  = rcache_get_reg(SHR_PC, RC_GR_WRITE);
1530       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1531       if (opd->dest & BITMASK1(SHR_PR)) {
1532         tmp3 = rcache_get_reg(SHR_PR, RC_GR_WRITE);
1533         emith_move_r_imm(tmp3, pc + 2);
1534         emith_add_r_r_r(tmp, tmp2, tmp3);
1535       }
1536       else {
1537         emith_move_r_r(tmp, tmp2);
1538         emith_add_r_imm(tmp, pc + 2);
1539       }
1540       drcf.pending_branch_indirect = 1;
1541       goto end_op;
1542
1543     case OP_SLEEP:
1544       printf("TODO sleep\n");
1545       goto end_op;
1546
1547     case OP_RTE:
1548       // pop PC
1549       emit_memhandler_read_rr(SHR_PC, SHR_SP, 0, 2);
1550       // pop SR
1551       tmp = rcache_get_reg_arg(0, SHR_SP);
1552       emith_add_r_imm(tmp, 4);
1553       tmp = emit_memhandler_read(2);
1554       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1555       emith_write_sr(sr, tmp);
1556       rcache_free_tmp(tmp);
1557       tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
1558       emith_add_r_imm(tmp, 4*2);
1559       drcf.test_irq = 1;
1560       drcf.pending_branch_indirect = 1;
1561       break;
1562     }
1563
1564     switch ((op >> 12) & 0x0f)
1565     {
1566     /////////////////////////////////////////////
1567     case 0x00:
1568       switch (op & 0x0f)
1569       {
1570       case 0x02:
1571         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1572         switch (GET_Fx())
1573         {
1574         case 0: // STC SR,Rn  0000nnnn00000010
1575           tmp2 = SHR_SR;
1576           break;
1577         case 1: // STC GBR,Rn 0000nnnn00010010
1578           tmp2 = SHR_GBR;
1579           break;
1580         case 2: // STC VBR,Rn 0000nnnn00100010
1581           tmp2 = SHR_VBR;
1582           break;
1583         default:
1584           goto default_;
1585         }
1586         tmp3 = rcache_get_reg(tmp2, RC_GR_READ);
1587         emith_move_r_r(tmp, tmp3);
1588         if (tmp2 == SHR_SR)
1589           emith_clear_msb(tmp, tmp, 22); // reserved bits defined by ISA as 0
1590         goto end_op;
1591       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
1592       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
1593       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
1594         rcache_clean();
1595         tmp  = rcache_get_reg_arg(1, GET_Rm());
1596         tmp2 = rcache_get_reg_arg(0, SHR_R0);
1597         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1598         emith_add_r_r(tmp2, tmp3);
1599         emit_memhandler_write(op & 3, pc);
1600         goto end_op;
1601       case 0x07:
1602         // MUL.L     Rm,Rn      0000nnnnmmmm0111
1603         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1604         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1605         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1606         emith_mul(tmp3, tmp2, tmp);
1607         goto end_op;
1608       case 0x08:
1609         switch (GET_Fx())
1610         {
1611         case 0: // CLRT               0000000000001000
1612           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1613           emith_bic_r_imm(sr, T);
1614           break;
1615         case 1: // SETT               0000000000011000
1616           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1617           emith_or_r_imm(sr, T);
1618           break;
1619         case 2: // CLRMAC             0000000000101000
1620           emit_move_r_imm32(SHR_MACL, 0);
1621           emit_move_r_imm32(SHR_MACH, 0);
1622           break;
1623         default:
1624           goto default_;
1625         }
1626         goto end_op;
1627       case 0x09:
1628         switch (GET_Fx())
1629         {
1630         case 0: // NOP        0000000000001001
1631           break;
1632         case 1: // DIV0U      0000000000011001
1633           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1634           emith_bic_r_imm(sr, M|Q|T);
1635           break;
1636         case 2: // MOVT Rn    0000nnnn00101001
1637           sr   = rcache_get_reg(SHR_SR, RC_GR_READ);
1638           tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1639           emith_clear_msb(tmp2, sr, 31);
1640           break;
1641         default:
1642           goto default_;
1643         }
1644         goto end_op;
1645       case 0x0a:
1646         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1647         switch (GET_Fx())
1648         {
1649         case 0: // STS      MACH,Rn   0000nnnn00001010
1650           tmp2 = SHR_MACH;
1651           break;
1652         case 1: // STS      MACL,Rn   0000nnnn00011010
1653           tmp2 = SHR_MACL;
1654           break;
1655         case 2: // STS      PR,Rn     0000nnnn00101010
1656           tmp2 = SHR_PR;
1657           break;
1658         default:
1659           goto default_;
1660         }
1661         tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
1662         emith_move_r_r(tmp, tmp2);
1663         goto end_op;
1664       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
1665       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
1666       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
1667         tmp = emit_indirect_indexed_read(SHR_R0, GET_Rm(), op & 3);
1668         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1669         if ((op & 3) != 2) {
1670           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
1671         } else
1672           emith_move_r_r(tmp2, tmp);
1673         rcache_free_tmp(tmp);
1674         goto end_op;
1675       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
1676         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2);
1677         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
1678         /* MS 16 MAC bits unused if saturated */
1679         sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1680         emith_tst_r_imm(sr, S);
1681         EMITH_SJMP_START(DCOND_EQ);
1682         emith_clear_msb_c(DCOND_NE, tmp4, tmp4, 16);
1683         EMITH_SJMP_END(DCOND_EQ);
1684         rcache_unlock(sr);
1685         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); // might evict SR
1686         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
1687         rcache_free_tmp(tmp2);
1688         sr = rcache_get_reg(SHR_SR, RC_GR_READ); // reget just in case
1689         emith_tst_r_imm(sr, S);
1690
1691         EMITH_JMP_START(DCOND_EQ);
1692         emith_asr(tmp, tmp4, 15);
1693         emith_cmp_r_imm(tmp, -1); // negative overflow (0x80000000..0xffff7fff)
1694         EMITH_SJMP_START(DCOND_GE);
1695         emith_move_r_imm_c(DCOND_LT, tmp4, 0x8000);
1696         emith_move_r_imm_c(DCOND_LT, tmp3, 0x0000);
1697         EMITH_SJMP_END(DCOND_GE);
1698         emith_cmp_r_imm(tmp, 0); // positive overflow (0x00008000..0x7fffffff)
1699         EMITH_SJMP_START(DCOND_LE);
1700         emith_move_r_imm_c(DCOND_GT, tmp4, 0x00007fff);
1701         emith_move_r_imm_c(DCOND_GT, tmp3, 0xffffffff);
1702         EMITH_SJMP_END(DCOND_LE);
1703         EMITH_JMP_END(DCOND_EQ);
1704
1705         rcache_free_tmp(tmp);
1706         goto end_op;
1707       }
1708       goto default_;
1709
1710     /////////////////////////////////////////////
1711     case 0x01:
1712       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
1713       rcache_clean();
1714       tmp  = rcache_get_reg_arg(0, GET_Rn());
1715       tmp2 = rcache_get_reg_arg(1, GET_Rm());
1716       if (op & 0x0f)
1717         emith_add_r_imm(tmp, (op & 0x0f) * 4);
1718       emit_memhandler_write(2, pc);
1719       goto end_op;
1720
1721     case 0x02:
1722       switch (op & 0x0f)
1723       {
1724       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
1725       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
1726       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
1727         rcache_clean();
1728         rcache_get_reg_arg(0, GET_Rn());
1729         rcache_get_reg_arg(1, GET_Rm());
1730         emit_memhandler_write(op & 3, pc);
1731         goto end_op;
1732       case 0x04: // MOV.B Rm,@–Rn       0010nnnnmmmm0100
1733       case 0x05: // MOV.W Rm,@–Rn       0010nnnnmmmm0101
1734       case 0x06: // MOV.L Rm,@–Rn       0010nnnnmmmm0110
1735         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1736         emith_sub_r_imm(tmp, (1 << (op & 3)));
1737         rcache_clean();
1738         rcache_get_reg_arg(0, GET_Rn());
1739         rcache_get_reg_arg(1, GET_Rm());
1740         emit_memhandler_write(op & 3, pc);
1741         goto end_op;
1742       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
1743         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1744         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1745         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1746         emith_bic_r_imm(sr, M|Q|T);
1747         emith_tst_r_imm(tmp2, (1<<31));
1748         EMITH_SJMP_START(DCOND_EQ);
1749         emith_or_r_imm_c(DCOND_NE, sr, Q);
1750         EMITH_SJMP_END(DCOND_EQ);
1751         emith_tst_r_imm(tmp3, (1<<31));
1752         EMITH_SJMP_START(DCOND_EQ);
1753         emith_or_r_imm_c(DCOND_NE, sr, M);
1754         EMITH_SJMP_END(DCOND_EQ);
1755         emith_teq_r_r(tmp2, tmp3);
1756         EMITH_SJMP_START(DCOND_PL);
1757         emith_or_r_imm_c(DCOND_MI, sr, T);
1758         EMITH_SJMP_END(DCOND_PL);
1759         goto end_op;
1760       case 0x08: // TST Rm,Rn           0010nnnnmmmm1000
1761         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1762         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1763         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1764         emith_bic_r_imm(sr, T);
1765         emith_tst_r_r(tmp2, tmp3);
1766         emit_or_t_if_eq(sr);
1767         goto end_op;
1768       case 0x09: // AND Rm,Rn           0010nnnnmmmm1001
1769         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1770         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1771         emith_and_r_r(tmp, tmp2);
1772         goto end_op;
1773       case 0x0a: // XOR Rm,Rn           0010nnnnmmmm1010
1774         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1775         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1776         emith_eor_r_r(tmp, tmp2);
1777         goto end_op;
1778       case 0x0b: // OR  Rm,Rn           0010nnnnmmmm1011
1779         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1780         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1781         emith_or_r_r(tmp, tmp2);
1782         goto end_op;
1783       case 0x0c: // CMP/STR Rm,Rn       0010nnnnmmmm1100
1784         tmp  = rcache_get_tmp();
1785         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1786         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1787         emith_eor_r_r_r(tmp, tmp2, tmp3);
1788         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1789         emith_bic_r_imm(sr, T);
1790         emith_tst_r_imm(tmp, 0x000000ff);
1791         emit_or_t_if_eq(tmp);
1792         emith_tst_r_imm(tmp, 0x0000ff00);
1793         emit_or_t_if_eq(tmp);
1794         emith_tst_r_imm(tmp, 0x00ff0000);
1795         emit_or_t_if_eq(tmp);
1796         emith_tst_r_imm(tmp, 0xff000000);
1797         emit_or_t_if_eq(tmp);
1798         rcache_free_tmp(tmp);
1799         goto end_op;
1800       case 0x0d: // XTRCT  Rm,Rn        0010nnnnmmmm1101
1801         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1802         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1803         emith_lsr(tmp, tmp, 16);
1804         emith_or_r_r_lsl(tmp, tmp2, 16);
1805         goto end_op;
1806       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
1807       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
1808         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1809         tmp  = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1810         if (op & 1) {
1811           emith_sext(tmp, tmp2, 16);
1812         } else
1813           emith_clear_msb(tmp, tmp2, 16);
1814         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1815         tmp2 = rcache_get_tmp();
1816         if (op & 1) {
1817           emith_sext(tmp2, tmp3, 16);
1818         } else
1819           emith_clear_msb(tmp2, tmp3, 16);
1820         emith_mul(tmp, tmp, tmp2);
1821         rcache_free_tmp(tmp2);
1822         goto end_op;
1823       }
1824       goto default_;
1825
1826     /////////////////////////////////////////////
1827     case 0x03:
1828       switch (op & 0x0f)
1829       {
1830       case 0x00: // CMP/EQ Rm,Rn        0011nnnnmmmm0000
1831       case 0x02: // CMP/HS Rm,Rn        0011nnnnmmmm0010
1832       case 0x03: // CMP/GE Rm,Rn        0011nnnnmmmm0011
1833       case 0x06: // CMP/HI Rm,Rn        0011nnnnmmmm0110
1834       case 0x07: // CMP/GT Rm,Rn        0011nnnnmmmm0111
1835         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1836         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1837         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1838         emith_bic_r_imm(sr, T);
1839         emith_cmp_r_r(tmp2, tmp3);
1840         switch (op & 0x07)
1841         {
1842         case 0x00: // CMP/EQ
1843           emit_or_t_if_eq(sr);
1844           break;
1845         case 0x02: // CMP/HS
1846           EMITH_SJMP_START(DCOND_LO);
1847           emith_or_r_imm_c(DCOND_HS, sr, T);
1848           EMITH_SJMP_END(DCOND_LO);
1849           break;
1850         case 0x03: // CMP/GE
1851           EMITH_SJMP_START(DCOND_LT);
1852           emith_or_r_imm_c(DCOND_GE, sr, T);
1853           EMITH_SJMP_END(DCOND_LT);
1854           break;
1855         case 0x06: // CMP/HI
1856           EMITH_SJMP_START(DCOND_LS);
1857           emith_or_r_imm_c(DCOND_HI, sr, T);
1858           EMITH_SJMP_END(DCOND_LS);
1859           break;
1860         case 0x07: // CMP/GT
1861           EMITH_SJMP_START(DCOND_LE);
1862           emith_or_r_imm_c(DCOND_GT, sr, T);
1863           EMITH_SJMP_END(DCOND_LE);
1864           break;
1865         }
1866         goto end_op;
1867       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
1868         // Q1 = carry(Rn = (Rn << 1) | T)
1869         // if Q ^ M
1870         //   Q2 = carry(Rn += Rm)
1871         // else
1872         //   Q2 = carry(Rn -= Rm)
1873         // Q = M ^ Q1 ^ Q2
1874         // T = (Q == M) = !(Q ^ M) = !(Q1 ^ Q2)
1875         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1876         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1877         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1878         emith_tpop_carry(sr, 0);
1879         emith_adcf_r_r(tmp2, tmp2);
1880         emith_tpush_carry(sr, 0);            // keep Q1 in T for now
1881         tmp4 = rcache_get_tmp();
1882         emith_and_r_r_imm(tmp4, sr, M);
1883         emith_eor_r_r_lsr(sr, tmp4, M_SHIFT - Q_SHIFT); // Q ^= M
1884         rcache_free_tmp(tmp4);
1885         // add or sub, invert T if carry to get Q1 ^ Q2
1886         // in: (Q ^ M) passed in Q, Q1 in T
1887         emith_sh2_div1_step(tmp2, tmp3, sr);
1888         emith_bic_r_imm(sr, Q);
1889         emith_tst_r_imm(sr, M);
1890         EMITH_SJMP_START(DCOND_EQ);
1891         emith_or_r_imm_c(DCOND_NE, sr, Q);  // Q = M
1892         EMITH_SJMP_END(DCOND_EQ);
1893         emith_tst_r_imm(sr, T);
1894         EMITH_SJMP_START(DCOND_EQ);
1895         emith_eor_r_imm_c(DCOND_NE, sr, Q); // Q = M ^ Q1 ^ Q2
1896         EMITH_SJMP_END(DCOND_EQ);
1897         emith_eor_r_imm(sr, T);             // T = !(Q1 ^ Q2)
1898         goto end_op;
1899       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
1900         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1901         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1902         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1903         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1904         emith_mul_u64(tmp3, tmp4, tmp, tmp2);
1905         goto end_op;
1906       case 0x08: // SUB     Rm,Rn       0011nnnnmmmm1000
1907       case 0x0c: // ADD     Rm,Rn       0011nnnnmmmm1100
1908         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1909         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1910         if (op & 4) {
1911           emith_add_r_r(tmp, tmp2);
1912         } else
1913           emith_sub_r_r(tmp, tmp2);
1914         goto end_op;
1915       case 0x0a: // SUBC    Rm,Rn       0011nnnnmmmm1010
1916       case 0x0e: // ADDC    Rm,Rn       0011nnnnmmmm1110
1917         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1918         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1919         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1920         if (op & 4) { // adc
1921           emith_tpop_carry(sr, 0);
1922           emith_adcf_r_r(tmp, tmp2);
1923           emith_tpush_carry(sr, 0);
1924         } else {
1925           emith_tpop_carry(sr, 1);
1926           emith_sbcf_r_r(tmp, tmp2);
1927           emith_tpush_carry(sr, 1);
1928         }
1929         goto end_op;
1930       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
1931       case 0x0f: // ADDV    Rm,Rn       0011nnnnmmmm1111
1932         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1933         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1934         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1935         emith_bic_r_imm(sr, T);
1936         if (op & 4) {
1937           emith_addf_r_r(tmp, tmp2);
1938         } else
1939           emith_subf_r_r(tmp, tmp2);
1940         EMITH_SJMP_START(DCOND_VC);
1941         emith_or_r_imm_c(DCOND_VS, sr, T);
1942         EMITH_SJMP_END(DCOND_VC);
1943         goto end_op;
1944       case 0x0d: // DMULS.L Rm,Rn       0011nnnnmmmm1101
1945         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1946         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1947         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1948         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1949         emith_mul_s64(tmp3, tmp4, tmp, tmp2);
1950         goto end_op;
1951       }
1952       goto default_;
1953
1954     /////////////////////////////////////////////
1955     case 0x04:
1956       switch (op & 0x0f)
1957       {
1958       case 0x00:
1959         switch (GET_Fx())
1960         {
1961         case 0: // SHLL Rn    0100nnnn00000000
1962         case 2: // SHAL Rn    0100nnnn00100000
1963           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1964           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1965           emith_tpop_carry(sr, 0); // dummy
1966           emith_lslf(tmp, tmp, 1);
1967           emith_tpush_carry(sr, 0);
1968           goto end_op;
1969         case 1: // DT Rn      0100nnnn00010000
1970           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1971 #ifndef DRC_CMP
1972           if (FETCH_OP(pc) == 0x8bfd) { // BF #-2
1973             if (gconst_get(GET_Rn(), &tmp)) {
1974               // XXX: limit burned cycles
1975               emit_move_r_imm32(GET_Rn(), 0);
1976               emith_or_r_imm(sr, T);
1977               cycles += tmp * 4 + 1; // +1 syncs with noconst version, not sure why
1978               skip_op = 1;
1979             }
1980             else
1981               emith_sh2_dtbf_loop();
1982             goto end_op;
1983           }
1984 #endif
1985           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1986           emith_bic_r_imm(sr, T);
1987           emith_subf_r_imm(tmp, 1);
1988           emit_or_t_if_eq(sr);
1989           goto end_op;
1990         }
1991         goto default_;
1992       case 0x01:
1993         switch (GET_Fx())
1994         {
1995         case 0: // SHLR Rn    0100nnnn00000001
1996         case 2: // SHAR Rn    0100nnnn00100001
1997           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1998           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1999           emith_tpop_carry(sr, 0); // dummy
2000           if (op & 0x20) {
2001             emith_asrf(tmp, tmp, 1);
2002           } else
2003             emith_lsrf(tmp, tmp, 1);
2004           emith_tpush_carry(sr, 0);
2005           goto end_op;
2006         case 1: // CMP/PZ Rn  0100nnnn00010001
2007           tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
2008           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2009           emith_bic_r_imm(sr, T);
2010           emith_cmp_r_imm(tmp, 0);
2011           EMITH_SJMP_START(DCOND_LT);
2012           emith_or_r_imm_c(DCOND_GE, sr, T);
2013           EMITH_SJMP_END(DCOND_LT);
2014           goto end_op;
2015         }
2016         goto default_;
2017       case 0x02:
2018       case 0x03:
2019         switch (op & 0x3f)
2020         {
2021         case 0x02: // STS.L    MACH,@–Rn 0100nnnn00000010
2022           tmp = SHR_MACH;
2023           break;
2024         case 0x12: // STS.L    MACL,@–Rn 0100nnnn00010010
2025           tmp = SHR_MACL;
2026           break;
2027         case 0x22: // STS.L    PR,@–Rn   0100nnnn00100010
2028           tmp = SHR_PR;
2029           break;
2030         case 0x03: // STC.L    SR,@–Rn   0100nnnn00000011
2031           tmp = SHR_SR;
2032           break;
2033         case 0x13: // STC.L    GBR,@–Rn  0100nnnn00010011
2034           tmp = SHR_GBR;
2035           break;
2036         case 0x23: // STC.L    VBR,@–Rn  0100nnnn00100011
2037           tmp = SHR_VBR;
2038           break;
2039         default:
2040           goto default_;
2041         }
2042         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2043         emith_sub_r_imm(tmp2, 4);
2044         rcache_clean();
2045         rcache_get_reg_arg(0, GET_Rn());
2046         tmp3 = rcache_get_reg_arg(1, tmp);
2047         if (tmp == SHR_SR)
2048           emith_clear_msb(tmp3, tmp3, 22); // reserved bits defined by ISA as 0
2049         emit_memhandler_write(2, pc);
2050         goto end_op;
2051       case 0x04:
2052       case 0x05:
2053         switch (op & 0x3f)
2054         {
2055         case 0x04: // ROTL   Rn          0100nnnn00000100
2056         case 0x05: // ROTR   Rn          0100nnnn00000101
2057           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2058           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2059           emith_tpop_carry(sr, 0); // dummy
2060           if (op & 1) {
2061             emith_rorf(tmp, tmp, 1);
2062           } else
2063             emith_rolf(tmp, tmp, 1);
2064           emith_tpush_carry(sr, 0);
2065           goto end_op;
2066         case 0x24: // ROTCL  Rn          0100nnnn00100100
2067         case 0x25: // ROTCR  Rn          0100nnnn00100101
2068           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2069           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2070           emith_tpop_carry(sr, 0);
2071           if (op & 1) {
2072             emith_rorcf(tmp);
2073           } else
2074             emith_rolcf(tmp);
2075           emith_tpush_carry(sr, 0);
2076           goto end_op;
2077         case 0x15: // CMP/PL Rn          0100nnnn00010101
2078           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2079           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2080           emith_bic_r_imm(sr, T);
2081           emith_cmp_r_imm(tmp, 0);
2082           EMITH_SJMP_START(DCOND_LE);
2083           emith_or_r_imm_c(DCOND_GT, sr, T);
2084           EMITH_SJMP_END(DCOND_LE);
2085           goto end_op;
2086         }
2087         goto default_;
2088       case 0x06:
2089       case 0x07:
2090         switch (op & 0x3f)
2091         {
2092         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
2093           tmp = SHR_MACH;
2094           break;
2095         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
2096           tmp = SHR_MACL;
2097           break;
2098         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
2099           tmp = SHR_PR;
2100           break;
2101         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
2102           tmp = SHR_SR;
2103           break;
2104         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
2105           tmp = SHR_GBR;
2106           break;
2107         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
2108           tmp = SHR_VBR;
2109           break;
2110         default:
2111           goto default_;
2112         }
2113         rcache_get_reg_arg(0, GET_Rn());
2114         tmp2 = emit_memhandler_read(2);
2115         if (tmp == SHR_SR) {
2116           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2117           emith_write_sr(sr, tmp2);
2118           drcf.test_irq = 1;
2119         } else {
2120           tmp = rcache_get_reg(tmp, RC_GR_WRITE);
2121           emith_move_r_r(tmp, tmp2);
2122         }
2123         rcache_free_tmp(tmp2);
2124         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2125         emith_add_r_imm(tmp, 4);
2126         goto end_op;
2127       case 0x08:
2128       case 0x09:
2129         switch (GET_Fx())
2130         {
2131         case 0:
2132           // SHLL2 Rn        0100nnnn00001000
2133           // SHLR2 Rn        0100nnnn00001001
2134           tmp = 2;
2135           break;
2136         case 1:
2137           // SHLL8 Rn        0100nnnn00011000
2138           // SHLR8 Rn        0100nnnn00011001
2139           tmp = 8;
2140           break;
2141         case 2:
2142           // SHLL16 Rn       0100nnnn00101000
2143           // SHLR16 Rn       0100nnnn00101001
2144           tmp = 16;
2145           break;
2146         default:
2147           goto default_;
2148         }
2149         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2150         if (op & 1) {
2151           emith_lsr(tmp2, tmp2, tmp);
2152         } else
2153           emith_lsl(tmp2, tmp2, tmp);
2154         goto end_op;
2155       case 0x0a:
2156         switch (GET_Fx())
2157         {
2158         case 0: // LDS      Rm,MACH   0100mmmm00001010
2159           tmp2 = SHR_MACH;
2160           break;
2161         case 1: // LDS      Rm,MACL   0100mmmm00011010
2162           tmp2 = SHR_MACL;
2163           break;
2164         case 2: // LDS      Rm,PR     0100mmmm00101010
2165           tmp2 = SHR_PR;
2166           break;
2167         default:
2168           goto default_;
2169         }
2170         emit_move_r_r(tmp2, GET_Rn());
2171         goto end_op;
2172       case 0x0b:
2173         switch (GET_Fx())
2174         {
2175         case 1: // TAS.B @Rn  0100nnnn00011011
2176           // XXX: is TAS working on 32X?
2177           rcache_get_reg_arg(0, GET_Rn());
2178           tmp = emit_memhandler_read(0);
2179           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2180           emith_bic_r_imm(sr, T);
2181           emith_cmp_r_imm(tmp, 0);
2182           emit_or_t_if_eq(sr);
2183           rcache_clean();
2184           emith_or_r_imm(tmp, 0x80);
2185           tmp2 = rcache_get_tmp_arg(1); // assuming it differs to tmp
2186           emith_move_r_r(tmp2, tmp);
2187           rcache_free_tmp(tmp);
2188           rcache_get_reg_arg(0, GET_Rn());
2189           emit_memhandler_write(0, pc);
2190           break;
2191         default:
2192           goto default_;
2193         }
2194         goto end_op;
2195       case 0x0e:
2196         tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
2197         switch (GET_Fx())
2198         {
2199         case 0: // LDC Rm,SR   0100mmmm00001110
2200           tmp2 = SHR_SR;
2201           break;
2202         case 1: // LDC Rm,GBR  0100mmmm00011110
2203           tmp2 = SHR_GBR;
2204           break;
2205         case 2: // LDC Rm,VBR  0100mmmm00101110
2206           tmp2 = SHR_VBR;
2207           break;
2208         default:
2209           goto default_;
2210         }
2211         if (tmp2 == SHR_SR) {
2212           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2213           emith_write_sr(sr, tmp);
2214           drcf.test_irq = 1;
2215         } else {
2216           tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE);
2217           emith_move_r_r(tmp2, tmp);
2218         }
2219         goto end_op;
2220       case 0x0f:
2221         // MAC.W @Rm+,@Rn+  0100nnnnmmmm1111
2222         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1);
2223         emith_sext(tmp, tmp, 16);
2224         emith_sext(tmp2, tmp2, 16);
2225         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW);
2226         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
2227         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
2228         rcache_free_tmp(tmp2);
2229         // XXX: MACH should be untouched when S is set?
2230         sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2231         emith_tst_r_imm(sr, S);
2232         EMITH_JMP_START(DCOND_EQ);
2233
2234         emith_asr(tmp, tmp3, 31);
2235         emith_eorf_r_r(tmp, tmp4); // tmp = ((signed)macl >> 31) ^ mach
2236         EMITH_JMP_START(DCOND_EQ);
2237         emith_move_r_imm(tmp3, 0x80000000);
2238         emith_tst_r_r(tmp4, tmp4);
2239         EMITH_SJMP_START(DCOND_MI);
2240         emith_sub_r_imm_c(DCOND_PL, tmp3, 1); // positive
2241         EMITH_SJMP_END(DCOND_MI);
2242         EMITH_JMP_END(DCOND_EQ);
2243
2244         EMITH_JMP_END(DCOND_EQ);
2245         rcache_free_tmp(tmp);
2246         goto end_op;
2247       }
2248       goto default_;
2249
2250     /////////////////////////////////////////////
2251     case 0x05:
2252       // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
2253       emit_memhandler_read_rr(GET_Rn(), GET_Rm(), (op & 0x0f) * 4, 2);
2254       goto end_op;
2255
2256     /////////////////////////////////////////////
2257     case 0x06:
2258       switch (op & 0x0f)
2259       {
2260       case 0x00: // MOV.B @Rm,Rn        0110nnnnmmmm0000
2261       case 0x01: // MOV.W @Rm,Rn        0110nnnnmmmm0001
2262       case 0x02: // MOV.L @Rm,Rn        0110nnnnmmmm0010
2263       case 0x04: // MOV.B @Rm+,Rn       0110nnnnmmmm0100
2264       case 0x05: // MOV.W @Rm+,Rn       0110nnnnmmmm0101
2265       case 0x06: // MOV.L @Rm+,Rn       0110nnnnmmmm0110
2266         emit_memhandler_read_rr(GET_Rn(), GET_Rm(), 0, op & 3);
2267         if ((op & 7) >= 4 && GET_Rn() != GET_Rm()) {
2268           tmp = rcache_get_reg(GET_Rm(), RC_GR_RMW);
2269           emith_add_r_imm(tmp, (1 << (op & 3)));
2270         }
2271         goto end_op;
2272       case 0x03:
2273       case 0x07 ... 0x0f:
2274         tmp  = rcache_get_reg(GET_Rm(), RC_GR_READ);
2275         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
2276         switch (op & 0x0f)
2277         {
2278         case 0x03: // MOV    Rm,Rn        0110nnnnmmmm0011
2279           emith_move_r_r(tmp2, tmp);
2280           break;
2281         case 0x07: // NOT    Rm,Rn        0110nnnnmmmm0111
2282           emith_mvn_r_r(tmp2, tmp);
2283           break;
2284         case 0x08: // SWAP.B Rm,Rn        0110nnnnmmmm1000
2285           tmp3 = tmp2;
2286           if (tmp == tmp2)
2287             tmp3 = rcache_get_tmp();
2288           tmp4 = rcache_get_tmp();
2289           emith_lsr(tmp3, tmp, 16);
2290           emith_or_r_r_lsl(tmp3, tmp, 24);
2291           emith_and_r_r_imm(tmp4, tmp, 0xff00);
2292           emith_or_r_r_lsl(tmp3, tmp4, 8);
2293           emith_rol(tmp2, tmp3, 16);
2294           rcache_free_tmp(tmp4);
2295           if (tmp == tmp2)
2296             rcache_free_tmp(tmp3);
2297           break;
2298         case 0x09: // SWAP.W Rm,Rn        0110nnnnmmmm1001
2299           emith_rol(tmp2, tmp, 16);
2300           break;
2301         case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
2302           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2303           emith_tpop_carry(sr, 1);
2304           emith_negcf_r_r(tmp2, tmp);
2305           emith_tpush_carry(sr, 1);
2306           break;
2307         case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
2308           emith_neg_r_r(tmp2, tmp);
2309           break;
2310         case 0x0c: // EXTU.B Rm,Rn        0110nnnnmmmm1100
2311           emith_clear_msb(tmp2, tmp, 24);
2312           break;
2313         case 0x0d: // EXTU.W Rm,Rn        0110nnnnmmmm1101
2314           emith_clear_msb(tmp2, tmp, 16);
2315           break;
2316         case 0x0e: // EXTS.B Rm,Rn        0110nnnnmmmm1110
2317           emith_sext(tmp2, tmp, 8);
2318           break;
2319         case 0x0f: // EXTS.W Rm,Rn        0110nnnnmmmm1111
2320           emith_sext(tmp2, tmp, 16);
2321           break;
2322         }
2323         goto end_op;
2324       }
2325       goto default_;
2326
2327     /////////////////////////////////////////////
2328     case 0x07:
2329       // ADD #imm,Rn  0111nnnniiiiiiii
2330       tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
2331       if (op & 0x80) { // adding negative
2332         emith_sub_r_imm(tmp, -op & 0xff);
2333       } else
2334         emith_add_r_imm(tmp, op & 0xff);
2335       goto end_op;
2336
2337     /////////////////////////////////////////////
2338     case 0x08:
2339       switch (op & 0x0f00)
2340       {
2341       case 0x0000: // MOV.B R0,@(disp,Rn)  10000000nnnndddd
2342       case 0x0100: // MOV.W R0,@(disp,Rn)  10000001nnnndddd
2343         rcache_clean();
2344         tmp  = rcache_get_reg_arg(0, GET_Rm());
2345         tmp2 = rcache_get_reg_arg(1, SHR_R0);
2346         tmp3 = (op & 0x100) >> 8;
2347         if (op & 0x0f)
2348           emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
2349         emit_memhandler_write(tmp3, pc);
2350         goto end_op;
2351       case 0x0400: // MOV.B @(disp,Rm),R0  10000100mmmmdddd
2352       case 0x0500: // MOV.W @(disp,Rm),R0  10000101mmmmdddd
2353         tmp = (op & 0x100) >> 8;
2354         emit_memhandler_read_rr(SHR_R0, GET_Rm(), (op & 0x0f) << tmp, tmp);
2355         goto end_op;
2356       case 0x0800: // CMP/EQ #imm,R0       10001000iiiiiiii
2357         // XXX: could use cmn
2358         tmp  = rcache_get_tmp();
2359         tmp2 = rcache_get_reg(0, RC_GR_READ);
2360         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
2361         emith_move_r_imm_s8(tmp, op & 0xff);
2362         emith_bic_r_imm(sr, T);
2363         emith_cmp_r_r(tmp2, tmp);
2364         emit_or_t_if_eq(sr);
2365         rcache_free_tmp(tmp);
2366         goto end_op;
2367       }
2368       goto default_;
2369
2370     /////////////////////////////////////////////
2371     case 0x09:
2372       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
2373       tmp = pc + (op & 0xff) * 2 + 2;
2374 #if PROPAGATE_CONSTANTS
2375       if (tmp < end_pc + MAX_LITERAL_OFFSET && literal_addr_count < MAX_LITERALS) {
2376         ADD_TO_ARRAY(literal_addr, literal_addr_count, tmp,);
2377         gconst_new(GET_Rn(), (u32)(int)(signed short)FETCH_OP(tmp));
2378       }
2379       else
2380 #endif
2381       {
2382         tmp2 = rcache_get_tmp_arg(0);
2383         emith_move_r_imm(tmp2, tmp);
2384         tmp2 = emit_memhandler_read(1);
2385         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
2386         emith_sext(tmp3, tmp2, 16);
2387         rcache_free_tmp(tmp2);
2388       }
2389       goto end_op;
2390
2391     /////////////////////////////////////////////
2392     case 0x0c:
2393       switch (op & 0x0f00)
2394       {
2395       case 0x0000: // MOV.B R0,@(disp,GBR)   11000000dddddddd
2396       case 0x0100: // MOV.W R0,@(disp,GBR)   11000001dddddddd
2397       case 0x0200: // MOV.L R0,@(disp,GBR)   11000010dddddddd
2398         rcache_clean();
2399         tmp  = rcache_get_reg_arg(0, SHR_GBR);
2400         tmp2 = rcache_get_reg_arg(1, SHR_R0);
2401         tmp3 = (op & 0x300) >> 8;
2402         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
2403         emit_memhandler_write(tmp3, pc);
2404         goto end_op;
2405       case 0x0400: // MOV.B @(disp,GBR),R0   11000100dddddddd
2406       case 0x0500: // MOV.W @(disp,GBR),R0   11000101dddddddd
2407       case 0x0600: // MOV.L @(disp,GBR),R0   11000110dddddddd
2408         tmp = (op & 0x300) >> 8;
2409         emit_memhandler_read_rr(SHR_R0, SHR_GBR, (op & 0xff) << tmp, tmp);
2410         goto end_op;
2411       case 0x0300: // TRAPA #imm      11000011iiiiiiii
2412         tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
2413         emith_sub_r_imm(tmp, 4*2);
2414         // push SR
2415         tmp = rcache_get_reg_arg(0, SHR_SP);
2416         emith_add_r_imm(tmp, 4);
2417         tmp = rcache_get_reg_arg(1, SHR_SR);
2418         emith_clear_msb(tmp, tmp, 22);
2419         emit_memhandler_write(2, pc);
2420         // push PC
2421         rcache_get_reg_arg(0, SHR_SP);
2422         tmp = rcache_get_tmp_arg(1);
2423         emith_move_r_imm(tmp, pc);
2424         emit_memhandler_write(2, pc);
2425         // obtain new PC
2426         emit_memhandler_read_rr(SHR_PC, SHR_VBR, (op & 0xff) * 4, 2);
2427         // indirect jump -> back to dispatcher
2428         emith_jump(sh2_drc_dispatcher);
2429         goto end_op;
2430       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
2431         emit_move_r_imm32(SHR_R0, (pc + (op & 0xff) * 4 + 2) & ~3);
2432         goto end_op;
2433       case 0x0800: // TST #imm,R0           11001000iiiiiiii
2434         tmp = rcache_get_reg(SHR_R0, RC_GR_READ);
2435         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2436         emith_bic_r_imm(sr, T);
2437         emith_tst_r_imm(tmp, op & 0xff);
2438         emit_or_t_if_eq(sr);
2439         goto end_op;
2440       case 0x0900: // AND #imm,R0           11001001iiiiiiii
2441         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2442         emith_and_r_imm(tmp, op & 0xff);
2443         goto end_op;
2444       case 0x0a00: // XOR #imm,R0           11001010iiiiiiii
2445         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2446         emith_eor_r_imm(tmp, op & 0xff);
2447         goto end_op;
2448       case 0x0b00: // OR  #imm,R0           11001011iiiiiiii
2449         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2450         emith_or_r_imm(tmp, op & 0xff);
2451         goto end_op;
2452       case 0x0c00: // TST.B #imm,@(R0,GBR)  11001100iiiiiiii
2453         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2454         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2455         emith_bic_r_imm(sr, T);
2456         emith_tst_r_imm(tmp, op & 0xff);
2457         emit_or_t_if_eq(sr);
2458         rcache_free_tmp(tmp);
2459         goto end_op;
2460       case 0x0d00: // AND.B #imm,@(R0,GBR)  11001101iiiiiiii
2461         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2462         emith_and_r_imm(tmp, op & 0xff);
2463         goto end_rmw_op;
2464       case 0x0e00: // XOR.B #imm,@(R0,GBR)  11001110iiiiiiii
2465         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2466         emith_eor_r_imm(tmp, op & 0xff);
2467         goto end_rmw_op;
2468       case 0x0f00: // OR.B  #imm,@(R0,GBR)  11001111iiiiiiii
2469         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2470         emith_or_r_imm(tmp, op & 0xff);
2471       end_rmw_op:
2472         tmp2 = rcache_get_tmp_arg(1);
2473         emith_move_r_r(tmp2, tmp);
2474         rcache_free_tmp(tmp);
2475         tmp3 = rcache_get_reg_arg(0, SHR_GBR);
2476         tmp4 = rcache_get_reg(SHR_R0, RC_GR_READ);
2477         emith_add_r_r(tmp3, tmp4);
2478         emit_memhandler_write(0, pc);
2479         goto end_op;
2480       }
2481       goto default_;
2482
2483     /////////////////////////////////////////////
2484     case 0x0d:
2485       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
2486       tmp = (pc + (op & 0xff) * 4 + 2) & ~3;
2487 #if PROPAGATE_CONSTANTS
2488       if (tmp < end_pc + MAX_LITERAL_OFFSET && literal_addr_count < MAX_LITERALS) {
2489         ADD_TO_ARRAY(literal_addr, literal_addr_count, tmp,);
2490         gconst_new(GET_Rn(), FETCH32(tmp));
2491       }
2492       else
2493 #endif
2494       {
2495         tmp2 = rcache_get_tmp_arg(0);
2496         emith_move_r_imm(tmp2, tmp);
2497         tmp2 = emit_memhandler_read(2);
2498         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
2499         emith_move_r_r(tmp3, tmp2);
2500         rcache_free_tmp(tmp2);
2501       }
2502       goto end_op;
2503
2504     /////////////////////////////////////////////
2505     case 0x0e:
2506       // MOV #imm,Rn   1110nnnniiiiiiii
2507       emit_move_r_imm32(GET_Rn(), (u32)(signed int)(signed char)op);
2508       goto end_op;
2509
2510     default:
2511     default_:
2512       elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
2513         sh2->is_slave ? 's' : 'm', op, pc - 2);
2514       break;
2515     }
2516
2517 end_op:
2518     rcache_unlock_all();
2519
2520     if (op_flags[i+1] & OF_DELAY_OP) {
2521       do_host_disasm(tcache_id);
2522       continue;
2523     }
2524
2525     // test irq?
2526     if (drcf.test_irq && !drcf.pending_branch_direct) {
2527       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2528       FLUSH_CYCLES(sr);
2529       rcache_flush();
2530       emith_call(sh2_drc_test_irq);
2531       drcf.test_irq = 0;
2532     }
2533
2534     // branch handling (with/without delay)
2535     if (drcf.pending_branch_direct)
2536     {
2537       struct op_data *opd_b =
2538         (op_flags[i] & OF_DELAY_OP) ? &ops[i-1] : opd;
2539       u32 target_pc = opd_b->imm;
2540       int cond = -1;
2541       void *target = NULL;
2542
2543       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2544       FLUSH_CYCLES(sr);
2545
2546       if (opd_b->op != OP_BRANCH)
2547         cond = (opd_b->op == OP_BRANCH_CF) ? DCOND_EQ : DCOND_NE;
2548       if (cond != -1) {
2549         int ctaken = (op_flags[i] & OF_DELAY_OP) ? 1 : 2;
2550
2551         if (delay_dep_fw & BITMASK1(SHR_T))
2552           emith_tst_r_imm(sr, T_save);
2553         else
2554           emith_tst_r_imm(sr, T);
2555
2556         emith_sub_r_imm_c(cond, sr, ctaken<<12);
2557       }
2558       rcache_clean();
2559
2560 #if LINK_BRANCHES
2561       if (find_in_array(branch_target_pc, branch_target_count, target_pc) >= 0)
2562       {
2563         // local branch
2564         // XXX: jumps back can be linked already
2565         if (branch_patch_count < MAX_LOCAL_BRANCHES) {
2566           target = tcache_ptr;
2567           branch_patch_pc[branch_patch_count] = target_pc;
2568           branch_patch_ptr[branch_patch_count] = target;
2569           branch_patch_count++;
2570         }
2571         else
2572           dbg(1, "warning: too many local branches");
2573       }
2574
2575       if (target == NULL)
2576 #endif
2577       {
2578         // can't resolve branch locally, make a block exit
2579         emit_move_r_imm32(SHR_PC, target_pc);
2580         rcache_clean();
2581
2582         target = dr_prepare_ext_branch(target_pc, sh2->is_slave, tcache_id);
2583         if (target == NULL)
2584           return NULL;
2585       }
2586
2587       if (cond != -1)
2588         emith_jump_cond_patchable(cond, target);
2589       else
2590         emith_jump_patchable(target);
2591
2592       drcf.pending_branch_direct = 0;
2593     }
2594     else if (drcf.pending_branch_indirect) {
2595       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2596       FLUSH_CYCLES(sr);
2597       rcache_flush();
2598       emith_jump(sh2_drc_dispatcher);
2599       drcf.pending_branch_indirect = 0;
2600     }
2601
2602     do_host_disasm(tcache_id);
2603   }
2604
2605   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
2606   FLUSH_CYCLES(tmp);
2607   rcache_flush();
2608
2609   // check the last op
2610   if (op_flags[i-1] & OF_DELAY_OP)
2611     opd = &ops[i-2];
2612   else
2613     opd = &ops[i-1];
2614
2615   if (opd->op != OP_BRANCH && opd->op != OP_BRANCH_R
2616       && opd->op != OP_BRANCH_RF && opd->op != OP_RTE)
2617   {
2618     void *target;
2619
2620     emit_move_r_imm32(SHR_PC, pc);
2621     rcache_flush();
2622
2623     target = dr_prepare_ext_branch(pc, sh2->is_slave, tcache_id);
2624     if (target == NULL)
2625       return NULL;
2626     emith_jump_patchable(target);
2627   }
2628
2629   // link local branches
2630   for (i = 0; i < branch_patch_count; i++) {
2631     void *target;
2632     int t;
2633     t = find_in_array(branch_target_pc, branch_target_count, branch_patch_pc[i]);
2634     target = branch_target_ptr[t];
2635     if (target == NULL) {
2636       // flush pc and go back to dispatcher (this should no longer happen)
2637       dbg(1, "stray branch to %08x %p", branch_patch_pc[i], tcache_ptr);
2638       target = tcache_ptr;
2639       emit_move_r_imm32(SHR_PC, branch_patch_pc[i]);
2640       rcache_flush();
2641       emith_jump(sh2_drc_dispatcher);
2642     }
2643     emith_jump_patch(branch_patch_ptr[i], target);
2644   }
2645
2646   // mark memory blocks as containing compiled code
2647   // override any overlay blocks as they become unreachable anyway
2648   if (tcache_id != 0 || (block->addr & 0xc7fc0000) == 0x06000000)
2649   {
2650     u16 *drc_ram_blk = NULL;
2651     u32 addr, mask = 0, shift = 0;
2652
2653     if (tcache_id != 0) {
2654       // data array, BIOS
2655       drc_ram_blk = Pico32xMem->drcblk_da[sh2->is_slave];
2656       shift = SH2_DRCBLK_DA_SHIFT;
2657       mask = 0xfff;
2658     }
2659     else if ((block->addr & 0xc7fc0000) == 0x06000000) {
2660       // SDRAM
2661       drc_ram_blk = Pico32xMem->drcblk_ram;
2662       shift = SH2_DRCBLK_RAM_SHIFT;
2663       mask = 0x3ffff;
2664     }
2665
2666     // mark recompiled insns
2667     drc_ram_blk[(base_pc & mask) >> shift] = 1;
2668     for (pc = base_pc; pc < end_pc; pc += 2)
2669       drc_ram_blk[(pc & mask) >> shift] = 1;
2670
2671     // mark literals
2672     for (i = 0; i < literal_addr_count; i++) {
2673       tmp = literal_addr[i];
2674       drc_ram_blk[(tmp & mask) >> shift] = 1;
2675     }
2676
2677     // add to invalidation lookup lists
2678     addr = base_pc & ~(ADDR_TO_BLOCK_PAGE - 1);
2679     for (; addr < end_literals; addr += ADDR_TO_BLOCK_PAGE) {
2680       i = (addr & mask) / ADDR_TO_BLOCK_PAGE;
2681       add_to_block_list(&inval_lookup[tcache_id][i], block);
2682     }
2683   }
2684
2685   tcache_ptrs[tcache_id] = tcache_ptr;
2686
2687   host_instructions_updated(block_entry_ptr, tcache_ptr);
2688
2689   do_host_disasm(tcache_id);
2690   dbg(2, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
2691     tcache_id, blkid_main,
2692     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
2693     insns_compiled, host_insn_count, (float)host_insn_count / insns_compiled);
2694   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
2695     dbg(2, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
2696 /*
2697  printf("~~~\n");
2698  tcache_dsm_ptrs[tcache_id] = block_entry_ptr;
2699  do_host_disasm(tcache_id);
2700  printf("~~~\n");
2701 */
2702
2703 #if (DRC_DEBUG & 4)
2704   fflush(stdout);
2705 #endif
2706
2707   return block_entry_ptr;
2708 }
2709
2710 static void sh2_generate_utils(void)
2711 {
2712   int arg0, arg1, arg2, sr, tmp;
2713
2714   sh2_drc_write32 = p32x_sh2_write32;
2715   sh2_drc_read8  = p32x_sh2_read8;
2716   sh2_drc_read16 = p32x_sh2_read16;
2717   sh2_drc_read32 = p32x_sh2_read32;
2718
2719   host_arg2reg(arg0, 0);
2720   host_arg2reg(arg1, 1);
2721   host_arg2reg(arg2, 2);
2722   emith_move_r_r(arg0, arg0); // nop
2723
2724   // sh2_drc_exit(void)
2725   sh2_drc_exit = (void *)tcache_ptr;
2726   emit_do_static_regs(1, arg2);
2727   emith_sh2_drc_exit();
2728
2729   // sh2_drc_dispatcher(void)
2730   sh2_drc_dispatcher = (void *)tcache_ptr;
2731   sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2732   emith_cmp_r_imm(sr, 0);
2733   emith_jump_cond(DCOND_LT, sh2_drc_exit);
2734   rcache_invalidate();
2735   emith_ctx_read(arg0, SHR_PC * 4);
2736   emith_ctx_read(arg1, offsetof(SH2, is_slave));
2737   emith_add_r_r_imm(arg2, CONTEXT_REG, offsetof(SH2, drc_tmp));
2738   emith_call(dr_lookup_block);
2739   emit_block_entry();
2740   // lookup failed, call sh2_translate()
2741   emith_move_r_r(arg0, CONTEXT_REG);
2742   emith_ctx_read(arg1, offsetof(SH2, drc_tmp)); // tcache_id
2743   emith_call(sh2_translate);
2744   emit_block_entry();
2745   // sh2_translate() failed, flush cache and retry
2746   emith_ctx_read(arg0, offsetof(SH2, drc_tmp));
2747   emith_call(flush_tcache);
2748   emith_move_r_r(arg0, CONTEXT_REG);
2749   emith_ctx_read(arg1, offsetof(SH2, drc_tmp));
2750   emith_call(sh2_translate);
2751   emit_block_entry();
2752   // XXX: can't translate, fail
2753   emith_call(dr_failure);
2754
2755   // sh2_drc_test_irq(void)
2756   // assumes it's called from main function (may jump to dispatcher)
2757   sh2_drc_test_irq = (void *)tcache_ptr;
2758   emith_ctx_read(arg1, offsetof(SH2, pending_level));
2759   sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2760   emith_lsr(arg0, sr, I_SHIFT);
2761   emith_and_r_imm(arg0, 0x0f);
2762   emith_cmp_r_r(arg1, arg0); // pending_level > ((sr >> 4) & 0x0f)?
2763   EMITH_SJMP_START(DCOND_GT);
2764   emith_ret_c(DCOND_LE);     // nope, return
2765   EMITH_SJMP_END(DCOND_GT);
2766   // adjust SP
2767   tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
2768   emith_sub_r_imm(tmp, 4*2);
2769   rcache_clean();
2770   // push SR
2771   tmp = rcache_get_reg_arg(0, SHR_SP);
2772   emith_add_r_imm(tmp, 4);
2773   tmp = rcache_get_reg_arg(1, SHR_SR);
2774   emith_clear_msb(tmp, tmp, 22);
2775   emith_move_r_r(arg2, CONTEXT_REG);
2776   emith_call(p32x_sh2_write32); // XXX: use sh2_drc_write32?
2777   rcache_invalidate();
2778   // push PC
2779   rcache_get_reg_arg(0, SHR_SP);
2780   emith_ctx_read(arg1, SHR_PC * 4);
2781   emith_move_r_r(arg2, CONTEXT_REG);
2782   emith_call(p32x_sh2_write32);
2783   rcache_invalidate();
2784   // update I, cycles, do callback
2785   emith_ctx_read(arg1, offsetof(SH2, pending_level));
2786   sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2787   emith_bic_r_imm(sr, I);
2788   emith_or_r_r_lsl(sr, arg1, I_SHIFT);
2789   emith_sub_r_imm(sr, 13 << 12); // at least 13 cycles
2790   rcache_flush();
2791   emith_move_r_r(arg0, CONTEXT_REG);
2792   emith_call_ctx(offsetof(SH2, irq_callback)); // vector = sh2->irq_callback(sh2, level);
2793   // obtain new PC
2794   emith_lsl(arg0, arg0, 2);
2795   emith_ctx_read(arg1, SHR_VBR * 4);
2796   emith_add_r_r(arg0, arg1);
2797   emit_memhandler_read(2);
2798   emith_ctx_write(arg0, SHR_PC * 4);
2799 #ifdef __i386__
2800   emith_add_r_imm(xSP, 4); // fix stack
2801 #endif
2802   emith_jump(sh2_drc_dispatcher);
2803   rcache_invalidate();
2804
2805   // sh2_drc_entry(SH2 *sh2)
2806   sh2_drc_entry = (void *)tcache_ptr;
2807   emith_sh2_drc_entry();
2808   emith_move_r_r(CONTEXT_REG, arg0); // move ctx, arg0
2809   emit_do_static_regs(0, arg2);
2810   emith_call(sh2_drc_test_irq);
2811   emith_jump(sh2_drc_dispatcher);
2812
2813   // sh2_drc_write8(u32 a, u32 d)
2814   sh2_drc_write8 = (void *)tcache_ptr;
2815   emith_ctx_read(arg2, offsetof(SH2, write8_tab));
2816   emith_sh2_wcall(arg0, arg2);
2817
2818   // sh2_drc_write16(u32 a, u32 d)
2819   sh2_drc_write16 = (void *)tcache_ptr;
2820   emith_ctx_read(arg2, offsetof(SH2, write16_tab));
2821   emith_sh2_wcall(arg0, arg2);
2822
2823 #ifdef PDB_NET
2824   // debug
2825   #define MAKE_READ_WRAPPER(func) { \
2826     void *tmp = (void *)tcache_ptr; \
2827     emith_push_ret(); \
2828     emith_call(func); \
2829     emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[0]));  \
2830     emith_addf_r_r(arg2, arg0);                           \
2831     emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[0])); \
2832     emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[1]));  \
2833     emith_adc_r_imm(arg2, 0x01000000);                    \
2834     emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[1])); \
2835     emith_pop_and_ret(); \
2836     func = tmp; \
2837   }
2838   #define MAKE_WRITE_WRAPPER(func) { \
2839     void *tmp = (void *)tcache_ptr; \
2840     emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[0]));  \
2841     emith_addf_r_r(arg2, arg1);                           \
2842     emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[0])); \
2843     emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[1]));  \
2844     emith_adc_r_imm(arg2, 0x01000000);                    \
2845     emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[1])); \
2846     emith_move_r_r(arg2, CONTEXT_REG);                    \
2847     emith_jump(func); \
2848     func = tmp; \
2849   }
2850
2851   MAKE_READ_WRAPPER(sh2_drc_read8);
2852   MAKE_READ_WRAPPER(sh2_drc_read16);
2853   MAKE_READ_WRAPPER(sh2_drc_read32);
2854   MAKE_WRITE_WRAPPER(sh2_drc_write8);
2855   MAKE_WRITE_WRAPPER(sh2_drc_write16);
2856   MAKE_WRITE_WRAPPER(sh2_drc_write32);
2857 #if (DRC_DEBUG & 4)
2858   host_dasm_new_symbol(sh2_drc_read8);
2859   host_dasm_new_symbol(sh2_drc_read16);
2860   host_dasm_new_symbol(sh2_drc_read32);
2861   host_dasm_new_symbol(sh2_drc_write32);
2862 #endif
2863 #endif
2864
2865   rcache_invalidate();
2866 #if (DRC_DEBUG & 4)
2867   host_dasm_new_symbol(sh2_drc_entry);
2868   host_dasm_new_symbol(sh2_drc_dispatcher);
2869   host_dasm_new_symbol(sh2_drc_exit);
2870   host_dasm_new_symbol(sh2_drc_test_irq);
2871   host_dasm_new_symbol(sh2_drc_write8);
2872   host_dasm_new_symbol(sh2_drc_write16);
2873 #endif
2874 }
2875
2876 static void sh2_smc_rm_block_entry(struct block_desc *bd, int tcache_id, u32 ram_mask)
2877 {
2878   struct block_link *bl, *bl_next, *bl_unresolved;
2879   void *tmp;
2880   u32 i, addr;
2881
2882   dbg(2, "  killing entry %08x-%08x, blkid %d,%d",
2883     bd->addr, bd->end_addr, tcache_id, bd - block_tables[tcache_id]);
2884   if (bd->addr == 0 || bd->entry_count == 0) {
2885     dbg(1, "  killing dead block!? %08x", bd->addr);
2886     return;
2887   }
2888
2889   // remove from inval_lookup
2890   addr = bd->addr & ~(ADDR_TO_BLOCK_PAGE - 1);
2891   for (; addr < bd->end_addr; addr += ADDR_TO_BLOCK_PAGE) {
2892     i = (addr & ram_mask) / ADDR_TO_BLOCK_PAGE;
2893     rm_from_block_list(&inval_lookup[tcache_id][i], bd);
2894   }
2895
2896   tmp = tcache_ptr;
2897   bl_unresolved = unresolved_links[tcache_id];
2898
2899   // remove from hash table, make incoming links unresolved
2900   // XXX: maybe patch branches w/flush instead?
2901   for (i = 0; i < bd->entry_count; i++) {
2902     rm_from_hashlist(&bd->entryp[i], tcache_id);
2903
2904     // since we never reuse tcache space of dead blocks,
2905     // insert jump to dispatcher for blocks that are linked to this
2906     tcache_ptr = bd->entryp[i].tcache_ptr;
2907     emit_move_r_imm32(SHR_PC, bd->addr);
2908     rcache_flush();
2909     emith_jump(sh2_drc_dispatcher);
2910
2911     host_instructions_updated(bd->entryp[i].tcache_ptr, tcache_ptr);
2912
2913     for (bl = bd->entryp[i].links; bl != NULL; ) {
2914       bl_next = bl->next;
2915       bl->next = bl_unresolved;
2916       bl_unresolved = bl;
2917       bl = bl_next;
2918     }
2919   }
2920
2921   tcache_ptr = tmp;
2922   unresolved_links[tcache_id] = bl_unresolved;
2923
2924   bd->addr = bd->end_addr = 0;
2925   bd->entry_count = 0;
2926 }
2927
2928 static void sh2_smc_rm_block(u32 a, u16 *drc_ram_blk, int tcache_id, u32 shift, u32 mask)
2929 {
2930   struct block_list **blist = NULL, *entry;
2931   u32 from = ~0, to = 0;
2932   struct block_desc *block;
2933
2934   blist = &inval_lookup[tcache_id][(a & mask) / ADDR_TO_BLOCK_PAGE];
2935   entry = *blist;
2936   while (entry != NULL) {
2937     block = entry->block;
2938     if (block->addr <= a && a < block->end_addr) {
2939       if (block->addr < from)
2940         from = block->addr;
2941       if (block->end_addr > to)
2942         to = block->end_addr;
2943
2944       sh2_smc_rm_block_entry(block, tcache_id, mask);
2945
2946       // entry lost, restart search
2947       entry = *blist;
2948       continue;
2949     }
2950     entry = entry->next;
2951   }
2952
2953   // clear entry points
2954   if (from < to) {
2955     u16 *p = drc_ram_blk + ((from & mask) >> shift);
2956     memset(p, 0, (to - from) >> (shift - 1));
2957   }
2958 }
2959
2960 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
2961 {
2962   dbg(2, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
2963   sh2_smc_rm_block(a, Pico32xMem->drcblk_ram, 0, SH2_DRCBLK_RAM_SHIFT, 0x3ffff);
2964 }
2965
2966 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
2967 {
2968   dbg(2, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
2969   sh2_smc_rm_block(a, Pico32xMem->drcblk_da[cpuid],
2970     1 + cpuid, SH2_DRCBLK_DA_SHIFT, 0xfff);
2971 }
2972
2973 int sh2_execute(SH2 *sh2c, int cycles)
2974 {
2975   int ret_cycles;
2976
2977   sh2c->cycles_timeslice = cycles;
2978
2979   // cycles are kept in SHR_SR unused bits (upper 20)
2980   // bit11 contains T saved for delay slot
2981   // others are usual SH2 flags
2982   sh2c->sr &= 0x3f3;
2983   sh2c->sr |= cycles << 12;
2984   sh2_drc_entry(sh2c);
2985
2986   // TODO: irq cycles
2987   ret_cycles = (signed int)sh2c->sr >> 12;
2988   if (ret_cycles > 0)
2989     dbg(1, "warning: drc returned with cycles: %d", ret_cycles);
2990
2991   return sh2c->cycles_timeslice - ret_cycles;
2992 }
2993
2994 #if (DRC_DEBUG & 2)
2995 void block_stats(void)
2996 {
2997   int c, b, i, total = 0;
2998
2999   printf("block stats:\n");
3000   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
3001     for (i = 0; i < block_counts[b]; i++)
3002       if (block_tables[b][i].addr != 0)
3003         total += block_tables[b][i].refcount;
3004
3005   for (c = 0; c < 10; c++) {
3006     struct block_desc *blk, *maxb = NULL;
3007     int max = 0;
3008     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
3009       for (i = 0; i < block_counts[b]; i++) {
3010         blk = &block_tables[b][i];
3011         if (blk->addr != 0 && blk->refcount > max) {
3012           max = blk->refcount;
3013           maxb = blk;
3014         }
3015       }
3016     }
3017     if (maxb == NULL)
3018       break;
3019     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
3020       (double)maxb->refcount / total * 100.0);
3021     maxb->refcount = 0;
3022   }
3023
3024   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
3025     for (i = 0; i < block_counts[b]; i++)
3026       block_tables[b][i].refcount = 0;
3027 }
3028 #else
3029 #define block_stats()
3030 #endif
3031
3032 void sh2_drc_flush_all(void)
3033 {
3034   block_stats();
3035   flush_tcache(0);
3036   flush_tcache(1);
3037   flush_tcache(2);
3038 }
3039
3040 void sh2_drc_mem_setup(SH2 *sh2)
3041 {
3042   // fill the convenience pointers
3043   sh2->p_bios = sh2->is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m;
3044   sh2->p_da = Pico32xMem->data_array[sh2->is_slave];
3045   sh2->p_sdram = Pico32xMem->sdram;
3046   sh2->p_rom = Pico.rom;
3047 }
3048
3049 int sh2_drc_init(SH2 *sh2)
3050 {
3051   int i;
3052
3053   if (block_tables[0] == NULL)
3054   {
3055     for (i = 0; i < TCACHE_BUFFERS; i++) {
3056       block_tables[i] = calloc(block_max_counts[i], sizeof(*block_tables[0]));
3057       if (block_tables[i] == NULL)
3058         goto fail;
3059       // max 2 block links (exits) per block
3060       block_link_pool[i] = calloc(block_link_pool_max_counts[i],
3061                           sizeof(*block_link_pool[0]));
3062       if (block_link_pool[i] == NULL)
3063         goto fail;
3064
3065       inval_lookup[i] = calloc(ram_sizes[i] / ADDR_TO_BLOCK_PAGE,
3066                                sizeof(inval_lookup[0]));
3067       if (inval_lookup[i] == NULL)
3068         goto fail;
3069
3070       hash_tables[i] = calloc(hash_table_sizes[i], sizeof(*hash_tables[0]));
3071       if (hash_tables[i] == NULL)
3072         goto fail;
3073     }
3074     memset(block_counts, 0, sizeof(block_counts));
3075     memset(block_link_pool_counts, 0, sizeof(block_link_pool_counts));
3076
3077     drc_cmn_init();
3078     tcache_ptr = tcache;
3079     sh2_generate_utils();
3080     host_instructions_updated(tcache, tcache_ptr);
3081
3082     tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;
3083     for (i = 1; i < ARRAY_SIZE(tcache_bases); i++)
3084       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
3085
3086     // tmp
3087     PicoOpt |= POPT_DIS_VDP_FIFO;
3088
3089 #if (DRC_DEBUG & 4)
3090     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
3091       tcache_dsm_ptrs[i] = tcache_bases[i];
3092     // disasm the utils
3093     tcache_dsm_ptrs[0] = tcache;
3094     do_host_disasm(0);
3095 #endif
3096 #if (DRC_DEBUG & 1)
3097     hash_collisions = 0;
3098 #endif
3099   }
3100
3101   return 0;
3102
3103 fail:
3104   sh2_drc_finish(sh2);
3105   return -1;
3106 }
3107
3108 void sh2_drc_finish(SH2 *sh2)
3109 {
3110   int i;
3111
3112   if (block_tables[0] == NULL)
3113     return;
3114
3115   sh2_drc_flush_all();
3116
3117   for (i = 0; i < TCACHE_BUFFERS; i++) {
3118 #if (DRC_DEBUG & 4)
3119     printf("~~~ tcache %d\n", i);
3120     tcache_dsm_ptrs[i] = tcache_bases[i];
3121     tcache_ptr = tcache_ptrs[i];
3122     do_host_disasm(i);
3123 #endif
3124
3125     if (block_tables[i] != NULL)
3126       free(block_tables[i]);
3127     block_tables[i] = NULL;
3128     if (block_link_pool[i] == NULL)
3129       free(block_link_pool[i]);
3130     block_link_pool[i] = NULL;
3131
3132     if (inval_lookup[i] == NULL)
3133       free(inval_lookup[i]);
3134     inval_lookup[i] = NULL;
3135
3136     if (hash_tables[i] != NULL) {
3137       free(hash_tables[i]);
3138       hash_tables[i] = NULL;
3139     }
3140   }
3141
3142   drc_cmn_cleanup();
3143 }
3144
3145 #endif /* DRC_SH2 */
3146
3147 static void *dr_get_pc_base(u32 pc, int is_slave)
3148 {
3149   void *ret = NULL;
3150   u32 mask = 0;
3151
3152   if ((pc & ~0x7ff) == 0) {
3153     // BIOS
3154     ret = is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m;
3155     mask = 0x7ff;
3156   }
3157   else if ((pc & 0xfffff000) == 0xc0000000) {
3158     // data array
3159     ret = Pico32xMem->data_array[is_slave];
3160     mask = 0xfff;
3161   }
3162   else if ((pc & 0xc6000000) == 0x06000000) {
3163     // SDRAM
3164     ret = Pico32xMem->sdram;
3165     mask = 0x03ffff;
3166   }
3167   else if ((pc & 0xc6000000) == 0x02000000) {
3168     // ROM
3169     ret = Pico.rom;
3170     mask = 0x3fffff;
3171   }
3172
3173   if (ret == NULL)
3174     return (void *)-1; // NULL is valid value
3175
3176   return (char *)ret - (pc & ~mask);
3177 }
3178
3179 void scan_block(u32 base_pc, int is_slave, u8 *op_flags, u32 *end_pc_out,
3180   u32 *end_literals_out)
3181 {
3182   u16 *dr_pc_base;
3183   u32 pc, op, tmp;
3184   u32 end_pc, end_literals = 0;
3185   struct op_data *opd;
3186   int next_is_delay = 0;
3187   int end_block = 0;
3188   int i, i_end;
3189
3190   memset(op_flags, 0, BLOCK_INSN_LIMIT);
3191
3192   dr_pc_base = dr_get_pc_base(base_pc, is_slave);
3193
3194   // 1st pass: disassemble
3195   for (i = 0, pc = base_pc; ; i++, pc += 2) {
3196     // we need an ops[] entry after the last one initialized,
3197     // so do it before end_block checks
3198     opd = &ops[i];
3199     opd->op = OP_UNHANDLED;
3200     opd->rm = -1;
3201     opd->source = opd->dest = 0;
3202     opd->cycles = 1;
3203     opd->imm = 0;
3204
3205     if (next_is_delay) {
3206       op_flags[i] |= OF_DELAY_OP;
3207       next_is_delay = 0;
3208     }
3209     else if (end_block || i >= BLOCK_INSN_LIMIT - 2)
3210       break;
3211
3212     op = FETCH_OP(pc);
3213     switch ((op & 0xf000) >> 12)
3214     {
3215     /////////////////////////////////////////////
3216     case 0x00:
3217       switch (op & 0x0f)
3218       {
3219       case 0x02:
3220         switch (GET_Fx())
3221         {
3222         case 0: // STC SR,Rn  0000nnnn00000010
3223           tmp = SHR_SR;
3224           break;
3225         case 1: // STC GBR,Rn 0000nnnn00010010
3226           tmp = SHR_GBR;
3227           break;
3228         case 2: // STC VBR,Rn 0000nnnn00100010
3229           tmp = SHR_VBR;
3230           break;
3231         default:
3232           goto undefined;
3233         }
3234         opd->op = OP_MOVE;
3235         opd->source = BITMASK1(tmp);
3236         opd->dest = BITMASK1(GET_Rn());
3237         break;
3238       case 0x03:
3239         CHECK_UNHANDLED_BITS(0xd0, undefined);
3240         // BRAF Rm    0000mmmm00100011
3241         // BSRF Rm    0000mmmm00000011
3242         opd->op = OP_BRANCH_RF;
3243         opd->rm = GET_Rn();
3244         opd->source = BITMASK1(opd->rm);
3245         opd->dest = BITMASK1(SHR_PC);
3246         if (!(op & 0x20))
3247           opd->dest |= BITMASK1(SHR_PR);
3248         opd->cycles = 2;
3249         next_is_delay = 1;
3250         end_block = 1;
3251         break;
3252       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
3253       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
3254       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
3255         opd->source = BITMASK3(GET_Rm(), SHR_R0, GET_Rn());
3256         break;
3257       case 0x07:
3258         // MUL.L     Rm,Rn      0000nnnnmmmm0111
3259         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3260         opd->dest = BITMASK1(SHR_MACL);
3261         opd->cycles = 2;
3262         break;
3263       case 0x08:
3264         CHECK_UNHANDLED_BITS(0xf00, undefined);
3265         switch (GET_Fx())
3266         {
3267         case 0: // CLRT               0000000000001000
3268           opd->op = OP_SETCLRT;
3269           opd->dest = BITMASK1(SHR_T);
3270           opd->imm = 0;
3271           break;
3272         case 1: // SETT               0000000000011000
3273           opd->op = OP_SETCLRT;
3274           opd->dest = BITMASK1(SHR_T);
3275           opd->imm = 1;
3276           break;
3277         case 2: // CLRMAC             0000000000101000
3278           opd->dest = BITMASK3(SHR_T, SHR_MACL, SHR_MACH);
3279           break;
3280         default:
3281           goto undefined;
3282         }
3283         break;
3284       case 0x09:
3285         switch (GET_Fx())
3286         {
3287         case 0: // NOP        0000000000001001
3288           CHECK_UNHANDLED_BITS(0xf00, undefined);
3289           break;
3290         case 1: // DIV0U      0000000000011001
3291           CHECK_UNHANDLED_BITS(0xf00, undefined);
3292           opd->dest = BITMASK2(SHR_SR, SHR_T);
3293           break;
3294         case 2: // MOVT Rn    0000nnnn00101001
3295           opd->source = BITMASK1(SHR_T);
3296           opd->dest = BITMASK1(GET_Rn());
3297           break;
3298         default:
3299           goto undefined;
3300         }
3301         break;
3302       case 0x0a:
3303         switch (GET_Fx())
3304         {
3305         case 0: // STS      MACH,Rn   0000nnnn00001010
3306           tmp = SHR_MACH;
3307           break;
3308         case 1: // STS      MACL,Rn   0000nnnn00011010
3309           tmp = SHR_MACL;
3310           break;
3311         case 2: // STS      PR,Rn     0000nnnn00101010
3312           tmp = SHR_PR;
3313           break;
3314         default:
3315           goto undefined;
3316         }
3317         opd->op = OP_MOVE;
3318         opd->source = BITMASK1(tmp);
3319         opd->dest = BITMASK1(GET_Rn());
3320         break;
3321       case 0x0b:
3322         CHECK_UNHANDLED_BITS(0xf00, undefined);
3323         switch (GET_Fx())
3324         {
3325         case 0: // RTS        0000000000001011
3326           opd->op = OP_BRANCH_R;
3327           opd->rm = SHR_PR;
3328           opd->source = BITMASK1(opd->rm);
3329           opd->dest = BITMASK1(SHR_PC);
3330           opd->cycles = 2;
3331           next_is_delay = 1;
3332           end_block = 1;
3333           break;
3334         case 1: // SLEEP      0000000000011011
3335           opd->op = OP_SLEEP;
3336           end_block = 1;
3337           break;
3338         case 2: // RTE        0000000000101011
3339           opd->op = OP_RTE;
3340           opd->source = BITMASK1(SHR_SP);
3341           opd->dest = BITMASK2(SHR_SR, SHR_PC);
3342           opd->cycles = 4;
3343           next_is_delay = 1;
3344           end_block = 1;
3345           break;
3346         default:
3347           goto undefined;
3348         }
3349         break;
3350       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
3351       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
3352       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
3353         opd->source = BITMASK2(GET_Rm(), SHR_R0);
3354         opd->dest = BITMASK1(GET_Rn());
3355         break;
3356       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
3357         opd->source = BITMASK5(GET_Rm(), GET_Rn(), SHR_SR, SHR_MACL, SHR_MACH);
3358         opd->dest = BITMASK4(GET_Rm(), GET_Rn(), SHR_MACL, SHR_MACH);
3359         opd->cycles = 3;
3360         break;
3361       default:
3362         goto undefined;
3363       }
3364       break;
3365
3366     /////////////////////////////////////////////
3367     case 0x01:
3368       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
3369       opd->source = BITMASK1(GET_Rm());
3370       opd->source = BITMASK1(GET_Rn());
3371       opd->imm = (op & 0x0f) * 4;
3372       break;
3373
3374     /////////////////////////////////////////////
3375     case 0x02:
3376       switch (op & 0x0f)
3377       {
3378       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
3379       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
3380       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
3381         opd->source = BITMASK1(GET_Rm());
3382         opd->source = BITMASK1(GET_Rn());
3383         break;
3384       case 0x04: // MOV.B Rm,@–Rn       0010nnnnmmmm0100
3385       case 0x05: // MOV.W Rm,@–Rn       0010nnnnmmmm0101
3386       case 0x06: // MOV.L Rm,@–Rn       0010nnnnmmmm0110
3387         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3388         opd->dest = BITMASK1(GET_Rn());
3389         break;
3390       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
3391         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3392         opd->dest = BITMASK1(SHR_SR);
3393         break;
3394       case 0x08: // TST Rm,Rn           0010nnnnmmmm1000
3395         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3396         opd->dest = BITMASK1(SHR_T);
3397         break;
3398       case 0x09: // AND Rm,Rn           0010nnnnmmmm1001
3399       case 0x0a: // XOR Rm,Rn           0010nnnnmmmm1010
3400       case 0x0b: // OR  Rm,Rn           0010nnnnmmmm1011
3401         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3402         opd->dest = BITMASK1(GET_Rn());
3403         break;
3404       case 0x0c: // CMP/STR Rm,Rn       0010nnnnmmmm1100
3405         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3406         opd->dest = BITMASK1(SHR_T);
3407         break;
3408       case 0x0d: // XTRCT  Rm,Rn        0010nnnnmmmm1101
3409         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3410         opd->dest = BITMASK1(GET_Rn());
3411         break;
3412       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
3413       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
3414         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3415         opd->dest = BITMASK1(SHR_MACL);
3416         break;
3417       default:
3418         goto undefined;
3419       }
3420       break;
3421
3422     /////////////////////////////////////////////
3423     case 0x03:
3424       switch (op & 0x0f)
3425       {
3426       case 0x00: // CMP/EQ Rm,Rn        0011nnnnmmmm0000
3427       case 0x02: // CMP/HS Rm,Rn        0011nnnnmmmm0010
3428       case 0x03: // CMP/GE Rm,Rn        0011nnnnmmmm0011
3429       case 0x06: // CMP/HI Rm,Rn        0011nnnnmmmm0110
3430       case 0x07: // CMP/GT Rm,Rn        0011nnnnmmmm0111
3431         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3432         opd->dest = BITMASK1(SHR_T);
3433         break;
3434       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
3435         opd->source = BITMASK3(GET_Rm(), GET_Rn(), SHR_SR);
3436         opd->dest = BITMASK2(GET_Rn(), SHR_SR);
3437         break;
3438       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
3439       case 0x0d: // DMULS.L Rm,Rn       0011nnnnmmmm1101
3440         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3441         opd->dest = BITMASK2(SHR_MACL, SHR_MACH);
3442         opd->cycles = 2;
3443         break;
3444       case 0x08: // SUB     Rm,Rn       0011nnnnmmmm1000
3445       case 0x0c: // ADD     Rm,Rn       0011nnnnmmmm1100
3446         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3447         opd->dest = BITMASK1(GET_Rn());
3448         break;
3449       case 0x0a: // SUBC    Rm,Rn       0011nnnnmmmm1010
3450       case 0x0e: // ADDC    Rm,Rn       0011nnnnmmmm1110
3451         opd->source = BITMASK3(GET_Rm(), GET_Rn(), SHR_T);
3452         opd->dest = BITMASK2(GET_Rn(), SHR_T);
3453         break;
3454       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
3455       case 0x0f: // ADDV    Rm,Rn       0011nnnnmmmm1111
3456         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3457         opd->dest = BITMASK2(GET_Rn(), SHR_T);
3458         break;
3459       default:
3460         goto undefined;
3461       }
3462       break;
3463
3464     /////////////////////////////////////////////
3465     case 0x04:
3466       switch (op & 0x0f)
3467       {
3468       case 0x00:
3469         switch (GET_Fx())
3470         {
3471         case 0: // SHLL Rn    0100nnnn00000000
3472         case 2: // SHAL Rn    0100nnnn00100000
3473           opd->source = BITMASK1(GET_Rn());
3474           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3475           break;
3476         case 1: // DT Rn      0100nnnn00010000
3477           opd->source = BITMASK1(GET_Rn());
3478           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3479           break;
3480         default:
3481           goto undefined;
3482         }
3483         break;
3484       case 0x01:
3485         switch (GET_Fx())
3486         {
3487         case 0: // SHLR Rn    0100nnnn00000001
3488         case 2: // SHAR Rn    0100nnnn00100001
3489           opd->source = BITMASK1(GET_Rn());
3490           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3491           break;
3492         case 1: // CMP/PZ Rn  0100nnnn00010001
3493           opd->source = BITMASK1(GET_Rn());
3494           opd->dest = BITMASK1(SHR_T);
3495           break;
3496         default:
3497           goto undefined;
3498         }
3499         break;
3500       case 0x02:
3501       case 0x03:
3502         switch (op & 0x3f)
3503         {
3504         case 0x02: // STS.L    MACH,@–Rn 0100nnnn00000010
3505           tmp = SHR_MACH;
3506           break;
3507         case 0x12: // STS.L    MACL,@–Rn 0100nnnn00010010
3508           tmp = SHR_MACL;
3509           break;
3510         case 0x22: // STS.L    PR,@–Rn   0100nnnn00100010
3511           tmp = SHR_PR;
3512           break;
3513         case 0x03: // STC.L    SR,@–Rn   0100nnnn00000011
3514           tmp = SHR_SR;
3515           opd->cycles = 2;
3516           break;
3517         case 0x13: // STC.L    GBR,@–Rn  0100nnnn00010011
3518           tmp = SHR_GBR;
3519           opd->cycles = 2;
3520           break;
3521         case 0x23: // STC.L    VBR,@–Rn  0100nnnn00100011
3522           tmp = SHR_VBR;
3523           opd->cycles = 2;
3524           break;
3525         default:
3526           goto undefined;
3527         }
3528         opd->source = BITMASK2(GET_Rn(), tmp);
3529         opd->dest = BITMASK1(GET_Rn());
3530         break;
3531       case 0x04:
3532       case 0x05:
3533         switch (op & 0x3f)
3534         {
3535         case 0x04: // ROTL   Rn          0100nnnn00000100
3536         case 0x05: // ROTR   Rn          0100nnnn00000101
3537           opd->source = BITMASK1(GET_Rn());
3538           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3539           break;
3540         case 0x24: // ROTCL  Rn          0100nnnn00100100
3541         case 0x25: // ROTCR  Rn          0100nnnn00100101
3542           opd->source = BITMASK2(GET_Rn(), SHR_T);
3543           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3544           break;
3545         case 0x15: // CMP/PL Rn          0100nnnn00010101
3546           opd->source = BITMASK1(GET_Rn());
3547           opd->dest = BITMASK1(SHR_T);
3548           break;
3549         default:
3550           goto undefined;
3551         }
3552         break;
3553       case 0x06:
3554       case 0x07:
3555         switch (op & 0x3f)
3556         {
3557         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
3558           tmp = SHR_MACH;
3559           break;
3560         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
3561           tmp = SHR_MACL;
3562           break;
3563         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
3564           tmp = SHR_PR;
3565           break;
3566         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
3567           tmp = SHR_SR;
3568           opd->cycles = 3;
3569           break;
3570         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
3571           tmp = SHR_GBR;
3572           opd->cycles = 3;
3573           break;
3574         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
3575           tmp = SHR_VBR;
3576           opd->cycles = 3;
3577           break;
3578         default:
3579           goto undefined;
3580         }
3581         opd->source = BITMASK1(GET_Rn());
3582         opd->dest = BITMASK2(GET_Rn(), tmp);
3583         break;
3584       case 0x08:
3585       case 0x09:
3586         switch (GET_Fx())
3587         {
3588         case 0:
3589           // SHLL2 Rn        0100nnnn00001000
3590           // SHLR2 Rn        0100nnnn00001001
3591           break;
3592         case 1:
3593           // SHLL8 Rn        0100nnnn00011000
3594           // SHLR8 Rn        0100nnnn00011001
3595           break;
3596         case 2:
3597           // SHLL16 Rn       0100nnnn00101000
3598           // SHLR16 Rn       0100nnnn00101001
3599           break;
3600         default:
3601           goto undefined;
3602         }
3603         opd->source = BITMASK1(GET_Rn());
3604         opd->dest = BITMASK1(GET_Rn());
3605         break;
3606       case 0x0a:
3607         switch (GET_Fx())
3608         {
3609         case 0: // LDS      Rm,MACH   0100mmmm00001010
3610           tmp = SHR_MACH;
3611           break;
3612         case 1: // LDS      Rm,MACL   0100mmmm00011010
3613           tmp = SHR_MACL;
3614           break;
3615         case 2: // LDS      Rm,PR     0100mmmm00101010
3616           tmp = SHR_PR;
3617           break;
3618         default:
3619           goto undefined;
3620         }
3621         opd->op = OP_MOVE;
3622         opd->source = BITMASK1(GET_Rn());
3623         opd->dest = BITMASK1(tmp);
3624         break;
3625       case 0x0b:
3626         switch (GET_Fx())
3627         {
3628         case 0: // JSR  @Rm   0100mmmm00001011
3629           opd->dest = BITMASK1(SHR_PR);
3630         case 2: // JMP  @Rm   0100mmmm00101011
3631           opd->op = OP_BRANCH_R;
3632           opd->rm = GET_Rn();
3633           opd->source = BITMASK1(opd->rm);
3634           opd->dest |= BITMASK1(SHR_PC);
3635           opd->cycles = 2;
3636           next_is_delay = 1;
3637           end_block = 1;
3638           break;
3639         case 1: // TAS.B @Rn  0100nnnn00011011
3640           opd->source = BITMASK1(GET_Rn());
3641           opd->dest = BITMASK1(SHR_T);
3642           opd->cycles = 4;
3643           break;
3644         default:
3645           goto undefined;
3646         }
3647         break;
3648       case 0x0e:
3649         switch (GET_Fx())
3650         {
3651         case 0: // LDC Rm,SR   0100mmmm00001110
3652           tmp = SHR_SR;
3653           break;
3654         case 1: // LDC Rm,GBR  0100mmmm00011110
3655           tmp = SHR_GBR;
3656           break;
3657         case 2: // LDC Rm,VBR  0100mmmm00101110
3658           tmp = SHR_VBR;
3659           break;
3660         default:
3661           goto undefined;
3662         }
3663         opd->op = OP_MOVE;
3664         opd->source = BITMASK1(GET_Rn());
3665         opd->dest = BITMASK1(tmp);
3666         break;
3667       case 0x0f:
3668         // MAC.W @Rm+,@Rn+  0100nnnnmmmm1111
3669         opd->source = BITMASK5(GET_Rm(), GET_Rn(), SHR_SR, SHR_MACL, SHR_MACH);
3670         opd->dest = BITMASK4(GET_Rm(), GET_Rn(), SHR_MACL, SHR_MACH);
3671         opd->cycles = 3;
3672         break;
3673       default:
3674         goto undefined;
3675       }
3676       break;
3677
3678     /////////////////////////////////////////////
3679     case 0x05:
3680       // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
3681       opd->source = BITMASK1(GET_Rm());
3682       opd->dest = BITMASK1(GET_Rn());
3683       opd->imm = (op & 0x0f) * 4;
3684       break;
3685
3686     /////////////////////////////////////////////
3687     case 0x06:
3688       switch (op & 0x0f)
3689       {
3690       case 0x04: // MOV.B @Rm+,Rn       0110nnnnmmmm0100
3691       case 0x05: // MOV.W @Rm+,Rn       0110nnnnmmmm0101
3692       case 0x06: // MOV.L @Rm+,Rn       0110nnnnmmmm0110
3693         opd->dest = BITMASK1(GET_Rm());
3694       case 0x00: // MOV.B @Rm,Rn        0110nnnnmmmm0000
3695       case 0x01: // MOV.W @Rm,Rn        0110nnnnmmmm0001
3696       case 0x02: // MOV.L @Rm,Rn        0110nnnnmmmm0010
3697         opd->source = BITMASK1(GET_Rm());
3698         opd->dest |= BITMASK1(GET_Rn());
3699         break;
3700       case 0x03: // MOV    Rm,Rn        0110nnnnmmmm0011
3701         opd->op = OP_MOVE;
3702         goto arith_rmrn;
3703       case 0x07: // NOT    Rm,Rn        0110nnnnmmmm0111
3704       case 0x08: // SWAP.B Rm,Rn        0110nnnnmmmm1000
3705       case 0x09: // SWAP.W Rm,Rn        0110nnnnmmmm1001
3706       case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
3707       case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
3708       case 0x0c: // EXTU.B Rm,Rn        0110nnnnmmmm1100
3709       case 0x0d: // EXTU.W Rm,Rn        0110nnnnmmmm1101
3710       case 0x0e: // EXTS.B Rm,Rn        0110nnnnmmmm1110
3711       case 0x0f: // EXTS.W Rm,Rn        0110nnnnmmmm1111
3712       arith_rmrn:
3713         opd->source = BITMASK1(GET_Rm());
3714         opd->dest = BITMASK1(GET_Rn());
3715         break;
3716       }
3717       break;
3718
3719     /////////////////////////////////////////////
3720     case 0x07:
3721       // ADD #imm,Rn  0111nnnniiiiiiii
3722       opd->source = opd->dest = BITMASK1(GET_Rn());
3723       opd->imm = (int)(signed char)op;
3724       break;
3725
3726     /////////////////////////////////////////////
3727     case 0x08:
3728       switch (op & 0x0f00)
3729       {
3730       case 0x0000: // MOV.B R0,@(disp,Rn)  10000000nnnndddd
3731         opd->source = BITMASK2(GET_Rm(), SHR_R0);
3732         opd->imm = (op & 0x0f);
3733         break;
3734       case 0x0100: // MOV.W R0,@(disp,Rn)  10000001nnnndddd
3735         opd->source = BITMASK2(GET_Rm(), SHR_R0);
3736         opd->imm = (op & 0x0f) * 2;
3737         break;
3738       case 0x0400: // MOV.B @(disp,Rm),R0  10000100mmmmdddd
3739         opd->source = BITMASK1(GET_Rm());
3740         opd->dest = BITMASK1(SHR_R0);
3741         opd->imm = (op & 0x0f);
3742         break;
3743       case 0x0500: // MOV.W @(disp,Rm),R0  10000101mmmmdddd
3744         opd->source = BITMASK1(GET_Rm());
3745         opd->dest = BITMASK1(SHR_R0);
3746         opd->imm = (op & 0x0f) * 2;
3747         break;
3748       case 0x0800: // CMP/EQ #imm,R0       10001000iiiiiiii
3749         opd->source = BITMASK1(SHR_R0);
3750         opd->dest = BITMASK1(SHR_T);
3751         opd->imm = (int)(signed char)op;
3752         break;
3753       case 0x0d00: // BT/S label 10001101dddddddd
3754       case 0x0f00: // BF/S label 10001111dddddddd
3755         next_is_delay = 1;
3756         // fallthrough
3757       case 0x0900: // BT   label 10001001dddddddd
3758       case 0x0b00: // BF   label 10001011dddddddd
3759         opd->op = (op & 0x0200) ? OP_BRANCH_CF : OP_BRANCH_CT;
3760         opd->source = BITMASK1(SHR_T);
3761         opd->dest = BITMASK1(SHR_PC);
3762         opd->imm = ((signed int)(op << 24) >> 23);
3763         opd->imm += pc + 4;
3764         if (base_pc <= opd->imm && opd->imm < base_pc + BLOCK_INSN_LIMIT * 2)
3765           op_flags[(opd->imm - base_pc) / 2] |= OF_BTARGET;
3766         break;
3767       default:
3768         goto undefined;
3769       }
3770       break;
3771
3772     /////////////////////////////////////////////
3773     case 0x09:
3774       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
3775       opd->op = OP_LOAD_POOL;
3776       opd->source = BITMASK1(SHR_PC);
3777       opd->dest = BITMASK1(GET_Rn());
3778       opd->imm = pc + 4 + (op & 0xff) * 2;
3779       opd->size = 1;
3780       break;
3781
3782     /////////////////////////////////////////////
3783     case 0x0b:
3784       // BSR  label 1011dddddddddddd
3785       opd->dest = BITMASK1(SHR_PR);
3786     case 0x0a:
3787       // BRA  label 1010dddddddddddd
3788       opd->op = OP_BRANCH;
3789       opd->dest |= BITMASK1(SHR_PC);
3790       opd->imm = ((signed int)(op << 20) >> 19);
3791       opd->imm += pc + 4;
3792       opd->cycles = 2;
3793       next_is_delay = 1;
3794       end_block = 1;
3795       if (base_pc <= opd->imm && opd->imm < base_pc + BLOCK_INSN_LIMIT * 2)
3796         op_flags[(opd->imm - base_pc) / 2] |= OF_BTARGET;
3797       break;
3798
3799     /////////////////////////////////////////////
3800     case 0x0c:
3801       switch (op & 0x0f00)
3802       {
3803       case 0x0000: // MOV.B R0,@(disp,GBR)   11000000dddddddd
3804       case 0x0100: // MOV.W R0,@(disp,GBR)   11000001dddddddd
3805       case 0x0200: // MOV.L R0,@(disp,GBR)   11000010dddddddd
3806         opd->source = BITMASK2(SHR_GBR, SHR_R0);
3807         opd->size = (op & 0x300) >> 8;
3808         opd->imm = (op & 0xff) << opd->size;
3809         break;
3810       case 0x0400: // MOV.B @(disp,GBR),R0   11000100dddddddd
3811       case 0x0500: // MOV.W @(disp,GBR),R0   11000101dddddddd
3812       case 0x0600: // MOV.L @(disp,GBR),R0   11000110dddddddd
3813         opd->source = BITMASK1(SHR_GBR);
3814         opd->dest = BITMASK1(SHR_R0);
3815         opd->size = (op & 0x300) >> 8;
3816         opd->imm = (op & 0xff) << opd->size;
3817         break;
3818       case 0x0300: // TRAPA #imm      11000011iiiiiiii
3819         opd->source = BITMASK2(SHR_PC, SHR_SR);
3820         opd->dest = BITMASK1(SHR_PC);
3821         opd->imm = (op & 0xff) * 4;
3822         opd->cycles = 8;
3823         end_block = 1; // FIXME
3824         break;
3825       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
3826         opd->dest = BITMASK1(SHR_R0);
3827         opd->imm = (pc + 4 + (op & 0xff) * 4) & ~3;
3828         break;
3829       case 0x0800: // TST #imm,R0           11001000iiiiiiii
3830         opd->source = BITMASK1(SHR_R0);
3831         opd->dest = BITMASK1(SHR_T);
3832         opd->imm = op & 0xff;
3833         break;
3834       case 0x0900: // AND #imm,R0           11001001iiiiiiii
3835         opd->source = opd->dest = BITMASK1(SHR_R0);
3836         opd->imm = op & 0xff;
3837         break;
3838       case 0x0a00: // XOR #imm,R0           11001010iiiiiiii
3839         opd->source = opd->dest = BITMASK1(SHR_R0);
3840         opd->imm = op & 0xff;
3841         break;
3842       case 0x0b00: // OR  #imm,R0           11001011iiiiiiii
3843         opd->source = opd->dest = BITMASK1(SHR_R0);
3844         opd->imm = op & 0xff;
3845         break;
3846       case 0x0c00: // TST.B #imm,@(R0,GBR)  11001100iiiiiiii
3847         opd->source = BITMASK2(SHR_GBR, SHR_R0);
3848         opd->dest = BITMASK1(SHR_T);
3849         opd->imm = op & 0xff;
3850         opd->cycles = 3;
3851         break;
3852       case 0x0d00: // AND.B #imm,@(R0,GBR)  11001101iiiiiiii
3853       case 0x0e00: // XOR.B #imm,@(R0,GBR)  11001110iiiiiiii
3854       case 0x0f00: // OR.B  #imm,@(R0,GBR)  11001111iiiiiiii
3855         opd->source = BITMASK2(SHR_GBR, SHR_R0);
3856         opd->imm = op & 0xff;
3857         opd->cycles = 3;
3858         break;
3859       default:
3860         goto undefined;
3861       }
3862       break;
3863
3864     /////////////////////////////////////////////
3865     case 0x0d:
3866       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
3867       opd->op = OP_LOAD_POOL;
3868       opd->source = BITMASK1(SHR_PC);
3869       opd->dest = BITMASK1(GET_Rn());
3870       opd->imm = (pc + 4 + (op & 0xff) * 2) & ~3;
3871       opd->size = 2;
3872       break;
3873
3874     /////////////////////////////////////////////
3875     case 0x0e:
3876       // MOV #imm,Rn   1110nnnniiiiiiii
3877       opd->dest = BITMASK1(GET_Rn());
3878       opd->imm = (u32)(signed int)(signed char)op;
3879       break;
3880
3881     default:
3882     undefined:
3883       elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
3884         is_slave ? 's' : 'm', op, pc);
3885       break;
3886     }
3887   }
3888   i_end = i;
3889   end_pc = pc;
3890
3891   // 2nd pass: some analysis
3892   for (i = 0; i < i_end; i++) {
3893     opd = &ops[i];
3894
3895     // propagate T (TODO: DIV0U)
3896     if ((opd->op == OP_SETCLRT && !opd->imm) || opd->op == OP_BRANCH_CT)
3897       op_flags[i + 1] |= OF_T_CLEAR;
3898     else if ((opd->op == OP_SETCLRT && opd->imm) || opd->op == OP_BRANCH_CF)
3899       op_flags[i + 1] |= OF_T_SET;
3900
3901     if ((op_flags[i] & OF_BTARGET) || (opd->dest & BITMASK1(SHR_T)))
3902       op_flags[i] &= ~(OF_T_SET | OF_T_CLEAR);
3903     else
3904       op_flags[i + 1] |= op_flags[i] & (OF_T_SET | OF_T_CLEAR);
3905
3906     if ((opd->op == OP_BRANCH_CT && (op_flags[i] & OF_T_SET))
3907         || (opd->op == OP_BRANCH_CF && (op_flags[i] & OF_T_CLEAR)))
3908     {
3909       opd->op = OP_BRANCH;
3910       opd->cycles = 3;
3911       i_end = i + 1;
3912       if (op_flags[i + 1] & OF_DELAY_OP) {
3913         opd->cycles = 2;
3914         i_end++;
3915       }
3916     }
3917     else if (opd->op == OP_LOAD_POOL)
3918     {
3919       if (opd->imm < end_pc + MAX_LITERAL_OFFSET) {
3920         if (end_literals < opd->imm + opd->size * 2)
3921           end_literals = opd->imm + opd->size * 2;
3922       }
3923     }
3924   }
3925   end_pc = base_pc + i_end * 2;
3926   if (end_literals < end_pc)
3927     end_literals = end_pc;
3928
3929   *end_pc_out = end_pc;
3930   if (end_literals_out != NULL)
3931     *end_literals_out = end_literals;
3932 }
3933
3934 // vim:shiftwidth=2:ts=2:expandtab