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