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