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