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