32x: simplify logging a bit
[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, u32 pc)
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, pc);
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, pc);
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, pc);
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, pc);
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, pc);
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, pc);
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, pc);
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, pc);
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, pc);
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, pc);
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, pc);
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(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
2591         sh2->is_slave ? 's' : 'm', op, pc - 2);
2592       break;
2593     }
2594
2595 end_op:
2596     rcache_unlock_all();
2597
2598     cycles += opd->cycles;
2599
2600     if (op_flags[i+1] & OF_DELAY_OP) {
2601       do_host_disasm(tcache_id);
2602       continue;
2603     }
2604
2605     // test irq?
2606     if (drcf.test_irq && !drcf.pending_branch_direct) {
2607       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2608       FLUSH_CYCLES(sr);
2609       if (!drcf.pending_branch_indirect)
2610         emit_move_r_imm32(SHR_PC, pc);
2611       rcache_flush();
2612       emith_call(sh2_drc_test_irq);
2613       drcf.test_irq = 0;
2614     }
2615
2616     // branch handling (with/without delay)
2617     if (drcf.pending_branch_direct)
2618     {
2619       struct op_data *opd_b =
2620         (op_flags[i] & OF_DELAY_OP) ? &ops[i-1] : opd;
2621       u32 target_pc = opd_b->imm;
2622       int cond = -1;
2623       void *target = NULL;
2624
2625       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2626       FLUSH_CYCLES(sr);
2627
2628       if (opd_b->op != OP_BRANCH)
2629         cond = (opd_b->op == OP_BRANCH_CF) ? DCOND_EQ : DCOND_NE;
2630       if (cond != -1) {
2631         int ctaken = (op_flags[i] & OF_DELAY_OP) ? 1 : 2;
2632
2633         if (delay_dep_fw & BITMASK1(SHR_T))
2634           emith_tst_r_imm(sr, T_save);
2635         else
2636           emith_tst_r_imm(sr, T);
2637
2638         emith_sub_r_imm_c(cond, sr, ctaken<<12);
2639       }
2640       rcache_clean();
2641
2642 #if LINK_BRANCHES
2643       if (find_in_array(branch_target_pc, branch_target_count, target_pc) >= 0)
2644       {
2645         // local branch
2646         // XXX: jumps back can be linked already
2647         if (branch_patch_count < MAX_LOCAL_BRANCHES) {
2648           target = tcache_ptr;
2649           branch_patch_pc[branch_patch_count] = target_pc;
2650           branch_patch_ptr[branch_patch_count] = target;
2651           branch_patch_count++;
2652         }
2653         else
2654           dbg(1, "warning: too many local branches");
2655       }
2656
2657       if (target == NULL)
2658 #endif
2659       {
2660         // can't resolve branch locally, make a block exit
2661         emit_move_r_imm32(SHR_PC, target_pc);
2662         rcache_clean();
2663
2664         target = dr_prepare_ext_branch(target_pc, sh2->is_slave, tcache_id);
2665         if (target == NULL)
2666           return NULL;
2667       }
2668
2669       if (cond != -1)
2670         emith_jump_cond_patchable(cond, target);
2671       else {
2672         emith_jump_patchable(target);
2673         rcache_invalidate();
2674       }
2675
2676       drcf.pending_branch_direct = 0;
2677     }
2678     else if (drcf.pending_branch_indirect) {
2679       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2680       FLUSH_CYCLES(sr);
2681       rcache_flush();
2682       emith_jump(sh2_drc_dispatcher);
2683       drcf.pending_branch_indirect = 0;
2684     }
2685
2686     do_host_disasm(tcache_id);
2687   }
2688
2689   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
2690   FLUSH_CYCLES(tmp);
2691   rcache_flush();
2692
2693   // check the last op
2694   if (op_flags[i-1] & OF_DELAY_OP)
2695     opd = &ops[i-2];
2696   else
2697     opd = &ops[i-1];
2698
2699   if (opd->op != OP_BRANCH && opd->op != OP_BRANCH_R
2700       && opd->op != OP_BRANCH_RF && opd->op != OP_RTE)
2701   {
2702     void *target;
2703
2704     emit_move_r_imm32(SHR_PC, pc);
2705     rcache_flush();
2706
2707     target = dr_prepare_ext_branch(pc, sh2->is_slave, tcache_id);
2708     if (target == NULL)
2709       return NULL;
2710     emith_jump_patchable(target);
2711   }
2712
2713   // link local branches
2714   for (i = 0; i < branch_patch_count; i++) {
2715     void *target;
2716     int t;
2717     t = find_in_array(branch_target_pc, branch_target_count, branch_patch_pc[i]);
2718     target = branch_target_ptr[t];
2719     if (target == NULL) {
2720       // flush pc and go back to dispatcher (this should no longer happen)
2721       dbg(1, "stray branch to %08x %p", branch_patch_pc[i], tcache_ptr);
2722       target = tcache_ptr;
2723       emit_move_r_imm32(SHR_PC, branch_patch_pc[i]);
2724       rcache_flush();
2725       emith_jump(sh2_drc_dispatcher);
2726     }
2727     emith_jump_patch(branch_patch_ptr[i], target);
2728   }
2729
2730   // mark memory blocks as containing compiled code
2731   // override any overlay blocks as they become unreachable anyway
2732   if ((block->addr & 0xc7fc0000) == 0x06000000
2733       || (block->addr & 0xfffff000) == 0xc0000000)
2734   {
2735     u16 *drc_ram_blk = NULL;
2736     u32 addr, mask = 0, shift = 0;
2737
2738     if (tcache_id != 0) {
2739       // data array, BIOS
2740       drc_ram_blk = Pico32xMem->drcblk_da[sh2->is_slave];
2741       shift = SH2_DRCBLK_DA_SHIFT;
2742       mask = 0xfff;
2743     }
2744     else {
2745       // SDRAM
2746       drc_ram_blk = Pico32xMem->drcblk_ram;
2747       shift = SH2_DRCBLK_RAM_SHIFT;
2748       mask = 0x3ffff;
2749     }
2750
2751     // mark recompiled insns
2752     drc_ram_blk[(base_pc & mask) >> shift] = 1;
2753     for (pc = base_pc; pc < end_pc; pc += 2)
2754       drc_ram_blk[(pc & mask) >> shift] = 1;
2755
2756     // mark literals
2757     for (i = 0; i < literal_addr_count; i++) {
2758       tmp = literal_addr[i];
2759       drc_ram_blk[(tmp & mask) >> shift] = 1;
2760     }
2761
2762     // add to invalidation lookup lists
2763     addr = base_pc & ~(INVAL_PAGE_SIZE - 1);
2764     for (; addr < end_literals; addr += INVAL_PAGE_SIZE) {
2765       i = (addr & mask) / INVAL_PAGE_SIZE;
2766       add_to_block_list(&inval_lookup[tcache_id][i], block);
2767     }
2768   }
2769
2770   tcache_ptrs[tcache_id] = tcache_ptr;
2771
2772   host_instructions_updated(block_entry_ptr, tcache_ptr);
2773
2774   do_host_disasm(tcache_id);
2775
2776   if (drcf.literals_disabled && literal_addr_count)
2777     dbg(1, "literals_disabled && literal_addr_count?");
2778   dbg(2, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
2779     tcache_id, blkid_main,
2780     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
2781     insns_compiled, host_insn_count, (float)host_insn_count / insns_compiled);
2782   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
2783     dbg(2, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
2784 /*
2785  printf("~~~\n");
2786  tcache_dsm_ptrs[tcache_id] = block_entry_ptr;
2787  do_host_disasm(tcache_id);
2788  printf("~~~\n");
2789 */
2790
2791 #if (DRC_DEBUG & 4)
2792   fflush(stdout);
2793 #endif
2794
2795   return block_entry_ptr;
2796 }
2797
2798 static void sh2_generate_utils(void)
2799 {
2800   int arg0, arg1, arg2, sr, tmp;
2801
2802   sh2_drc_write32 = p32x_sh2_write32;
2803   sh2_drc_read8  = p32x_sh2_read8;
2804   sh2_drc_read16 = p32x_sh2_read16;
2805   sh2_drc_read32 = p32x_sh2_read32;
2806
2807   host_arg2reg(arg0, 0);
2808   host_arg2reg(arg1, 1);
2809   host_arg2reg(arg2, 2);
2810   emith_move_r_r(arg0, arg0); // nop
2811
2812   // sh2_drc_exit(void)
2813   sh2_drc_exit = (void *)tcache_ptr;
2814   emit_do_static_regs(1, arg2);
2815   emith_sh2_drc_exit();
2816
2817   // sh2_drc_dispatcher(void)
2818   sh2_drc_dispatcher = (void *)tcache_ptr;
2819   sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2820   emith_cmp_r_imm(sr, 0);
2821   emith_jump_cond(DCOND_LT, sh2_drc_exit);
2822   rcache_invalidate();
2823   emith_ctx_read(arg0, SHR_PC * 4);
2824   emith_ctx_read(arg1, offsetof(SH2, is_slave));
2825   emith_add_r_r_imm(arg2, CONTEXT_REG, offsetof(SH2, drc_tmp));
2826   emith_call(dr_lookup_block);
2827   emit_block_entry();
2828   // lookup failed, call sh2_translate()
2829   emith_move_r_r(arg0, CONTEXT_REG);
2830   emith_ctx_read(arg1, offsetof(SH2, drc_tmp)); // tcache_id
2831   emith_call(sh2_translate);
2832   emit_block_entry();
2833   // sh2_translate() failed, flush cache and retry
2834   emith_ctx_read(arg0, offsetof(SH2, drc_tmp));
2835   emith_call(flush_tcache);
2836   emith_move_r_r(arg0, CONTEXT_REG);
2837   emith_ctx_read(arg1, offsetof(SH2, drc_tmp));
2838   emith_call(sh2_translate);
2839   emit_block_entry();
2840   // XXX: can't translate, fail
2841   emith_call(dr_failure);
2842
2843   // sh2_drc_test_irq(void)
2844   // assumes it's called from main function (may jump to dispatcher)
2845   sh2_drc_test_irq = (void *)tcache_ptr;
2846   emith_ctx_read(arg1, offsetof(SH2, pending_level));
2847   sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2848   emith_lsr(arg0, sr, I_SHIFT);
2849   emith_and_r_imm(arg0, 0x0f);
2850   emith_cmp_r_r(arg1, arg0); // pending_level > ((sr >> 4) & 0x0f)?
2851   EMITH_SJMP_START(DCOND_GT);
2852   emith_ret_c(DCOND_LE);     // nope, return
2853   EMITH_SJMP_END(DCOND_GT);
2854   // adjust SP
2855   tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
2856   emith_sub_r_imm(tmp, 4*2);
2857   rcache_clean();
2858   // push SR
2859   tmp = rcache_get_reg_arg(0, SHR_SP);
2860   emith_add_r_imm(tmp, 4);
2861   tmp = rcache_get_reg_arg(1, SHR_SR);
2862   emith_clear_msb(tmp, tmp, 22);
2863   emith_move_r_r(arg2, CONTEXT_REG);
2864   emith_call(p32x_sh2_write32); // XXX: use sh2_drc_write32?
2865   rcache_invalidate();
2866   // push PC
2867   rcache_get_reg_arg(0, SHR_SP);
2868   emith_ctx_read(arg1, SHR_PC * 4);
2869   emith_move_r_r(arg2, CONTEXT_REG);
2870   emith_call(p32x_sh2_write32);
2871   rcache_invalidate();
2872   // update I, cycles, do callback
2873   emith_ctx_read(arg1, offsetof(SH2, pending_level));
2874   sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2875   emith_bic_r_imm(sr, I);
2876   emith_or_r_r_lsl(sr, arg1, I_SHIFT);
2877   emith_sub_r_imm(sr, 13 << 12); // at least 13 cycles
2878   rcache_flush();
2879   emith_move_r_r(arg0, CONTEXT_REG);
2880   emith_call_ctx(offsetof(SH2, irq_callback)); // vector = sh2->irq_callback(sh2, level);
2881   // obtain new PC
2882   emith_lsl(arg0, arg0, 2);
2883   emith_ctx_read(arg1, SHR_VBR * 4);
2884   emith_add_r_r(arg0, arg1);
2885   emit_memhandler_read(2);
2886   emith_ctx_write(arg0, SHR_PC * 4);
2887 #ifdef __i386__
2888   emith_add_r_imm(xSP, 4); // fix stack
2889 #endif
2890   emith_jump(sh2_drc_dispatcher);
2891   rcache_invalidate();
2892
2893   // sh2_drc_entry(SH2 *sh2)
2894   sh2_drc_entry = (void *)tcache_ptr;
2895   emith_sh2_drc_entry();
2896   emith_move_r_r(CONTEXT_REG, arg0); // move ctx, arg0
2897   emit_do_static_regs(0, arg2);
2898   emith_call(sh2_drc_test_irq);
2899   emith_jump(sh2_drc_dispatcher);
2900
2901   // sh2_drc_write8(u32 a, u32 d)
2902   sh2_drc_write8 = (void *)tcache_ptr;
2903   emith_ctx_read(arg2, offsetof(SH2, write8_tab));
2904   emith_sh2_wcall(arg0, arg2);
2905
2906   // sh2_drc_write16(u32 a, u32 d)
2907   sh2_drc_write16 = (void *)tcache_ptr;
2908   emith_ctx_read(arg2, offsetof(SH2, write16_tab));
2909   emith_sh2_wcall(arg0, arg2);
2910
2911 #ifdef PDB_NET
2912   // debug
2913   #define MAKE_READ_WRAPPER(func) { \
2914     void *tmp = (void *)tcache_ptr; \
2915     emith_push_ret(); \
2916     emith_call(func); \
2917     emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[0]));  \
2918     emith_addf_r_r(arg2, arg0);                           \
2919     emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[0])); \
2920     emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[1]));  \
2921     emith_adc_r_imm(arg2, 0x01000000);                    \
2922     emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[1])); \
2923     emith_pop_and_ret(); \
2924     func = tmp; \
2925   }
2926   #define MAKE_WRITE_WRAPPER(func) { \
2927     void *tmp = (void *)tcache_ptr; \
2928     emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[0]));  \
2929     emith_addf_r_r(arg2, arg1);                           \
2930     emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[0])); \
2931     emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[1]));  \
2932     emith_adc_r_imm(arg2, 0x01000000);                    \
2933     emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[1])); \
2934     emith_move_r_r(arg2, CONTEXT_REG);                    \
2935     emith_jump(func); \
2936     func = tmp; \
2937   }
2938
2939   MAKE_READ_WRAPPER(sh2_drc_read8);
2940   MAKE_READ_WRAPPER(sh2_drc_read16);
2941   MAKE_READ_WRAPPER(sh2_drc_read32);
2942   MAKE_WRITE_WRAPPER(sh2_drc_write8);
2943   MAKE_WRITE_WRAPPER(sh2_drc_write16);
2944   MAKE_WRITE_WRAPPER(sh2_drc_write32);
2945 #if (DRC_DEBUG & 4)
2946   host_dasm_new_symbol(sh2_drc_read8);
2947   host_dasm_new_symbol(sh2_drc_read16);
2948   host_dasm_new_symbol(sh2_drc_read32);
2949   host_dasm_new_symbol(sh2_drc_write32);
2950 #endif
2951 #endif
2952
2953   rcache_invalidate();
2954 #if (DRC_DEBUG & 4)
2955   host_dasm_new_symbol(sh2_drc_entry);
2956   host_dasm_new_symbol(sh2_drc_dispatcher);
2957   host_dasm_new_symbol(sh2_drc_exit);
2958   host_dasm_new_symbol(sh2_drc_test_irq);
2959   host_dasm_new_symbol(sh2_drc_write8);
2960   host_dasm_new_symbol(sh2_drc_write16);
2961 #endif
2962 }
2963
2964 static void sh2_smc_rm_block_entry(struct block_desc *bd, int tcache_id, u32 ram_mask)
2965 {
2966   struct block_link *bl, *bl_next, *bl_unresolved;
2967   u32 i, addr, end_addr;
2968   void *tmp;
2969
2970   dbg(2, "  killing entry %08x-%08x-%08x, blkid %d,%d",
2971     bd->addr, bd->addr + bd->size_nolit, bd->addr + bd->size,
2972     tcache_id, bd - block_tables[tcache_id]);
2973   if (bd->addr == 0 || bd->entry_count == 0) {
2974     dbg(1, "  killing dead block!? %08x", bd->addr);
2975     return;
2976   }
2977
2978   // remove from inval_lookup
2979   addr = bd->addr & ~(INVAL_PAGE_SIZE - 1);
2980   end_addr = bd->addr + bd->size;
2981   for (; addr < end_addr; addr += INVAL_PAGE_SIZE) {
2982     i = (addr & ram_mask) / INVAL_PAGE_SIZE;
2983     rm_from_block_list(&inval_lookup[tcache_id][i], bd);
2984   }
2985
2986   tmp = tcache_ptr;
2987   bl_unresolved = unresolved_links[tcache_id];
2988
2989   // remove from hash table, make incoming links unresolved
2990   // XXX: maybe patch branches w/flush instead?
2991   for (i = 0; i < bd->entry_count; i++) {
2992     rm_from_hashlist(&bd->entryp[i], tcache_id);
2993
2994     // since we never reuse tcache space of dead blocks,
2995     // insert jump to dispatcher for blocks that are linked to this
2996     tcache_ptr = bd->entryp[i].tcache_ptr;
2997     emit_move_r_imm32(SHR_PC, bd->entryp[i].pc);
2998     rcache_flush();
2999     emith_jump(sh2_drc_dispatcher);
3000
3001     host_instructions_updated(bd->entryp[i].tcache_ptr, tcache_ptr);
3002
3003     for (bl = bd->entryp[i].links; bl != NULL; ) {
3004       bl_next = bl->next;
3005       bl->next = bl_unresolved;
3006       bl_unresolved = bl;
3007       bl = bl_next;
3008     }
3009   }
3010
3011   tcache_ptr = tmp;
3012   unresolved_links[tcache_id] = bl_unresolved;
3013
3014   bd->addr = bd->size = bd->size_nolit = 0;
3015   bd->entry_count = 0;
3016 }
3017
3018 static void sh2_smc_rm_block(u32 a, u16 *drc_ram_blk, int tcache_id, u32 shift, u32 mask)
3019 {
3020   struct block_list **blist = NULL, *entry;
3021   u32 from = ~0, to = 0, end_addr, taddr, i;
3022   struct block_desc *block;
3023
3024   blist = &inval_lookup[tcache_id][(a & mask) / INVAL_PAGE_SIZE];
3025   entry = *blist;
3026   while (entry != NULL) {
3027     block = entry->block;
3028     end_addr = block->addr + block->size;
3029     if (block->addr <= a && a < end_addr) {
3030       // get addr range that includes all removed blocks
3031       if (from > block->addr)
3032         from = block->addr;
3033       if (to < end_addr)
3034         to = end_addr;
3035
3036       sh2_smc_rm_block_entry(block, tcache_id, mask);
3037       if (a >= block->addr + block->size_nolit)
3038         literal_disabled_frames = 3;
3039
3040       // entry lost, restart search
3041       entry = *blist;
3042       continue;
3043     }
3044     entry = entry->next;
3045   }
3046
3047   if (from >= to)
3048     return;
3049
3050   // update range around a to match latest state
3051   from &= ~(INVAL_PAGE_SIZE - 1);
3052   to |= (INVAL_PAGE_SIZE - 1);
3053   for (taddr = from; taddr < to; taddr += INVAL_PAGE_SIZE) {
3054     i = (taddr & mask) / INVAL_PAGE_SIZE;
3055     entry = inval_lookup[tcache_id][i];
3056
3057     for (; entry != NULL; entry = entry->next) {
3058       block = entry->block;
3059
3060       if (block->addr > a) {
3061         if (to > block->addr)
3062           to = block->addr;
3063       }
3064       else {
3065         end_addr = block->addr + block->size;
3066         if (from < end_addr)
3067           from = end_addr;
3068       }
3069     }
3070   }
3071
3072   // clear code marks
3073   if (from < to) {
3074     u16 *p = drc_ram_blk + ((from & mask) >> shift);
3075     memset(p, 0, (to - from) >> (shift - 1));
3076   }
3077 }
3078
3079 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
3080 {
3081   dbg(2, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
3082   sh2_smc_rm_block(a, Pico32xMem->drcblk_ram, 0, SH2_DRCBLK_RAM_SHIFT, 0x3ffff);
3083 }
3084
3085 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
3086 {
3087   dbg(2, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
3088   sh2_smc_rm_block(a, Pico32xMem->drcblk_da[cpuid],
3089     1 + cpuid, SH2_DRCBLK_DA_SHIFT, 0xfff);
3090 }
3091
3092 int sh2_execute(SH2 *sh2c, int cycles)
3093 {
3094   int ret_cycles;
3095
3096   sh2c->cycles_timeslice = cycles;
3097
3098   // cycles are kept in SHR_SR unused bits (upper 20)
3099   // bit11 contains T saved for delay slot
3100   // others are usual SH2 flags
3101   sh2c->sr &= 0x3f3;
3102   sh2c->sr |= cycles << 12;
3103   sh2_drc_entry(sh2c);
3104
3105   // TODO: irq cycles
3106   ret_cycles = (signed int)sh2c->sr >> 12;
3107   if (ret_cycles > 0)
3108     dbg(1, "warning: drc returned with cycles: %d", ret_cycles);
3109
3110   return sh2c->cycles_timeslice - ret_cycles;
3111 }
3112
3113 #if (DRC_DEBUG & 2)
3114 void block_stats(void)
3115 {
3116   int c, b, i, total = 0;
3117
3118   printf("block stats:\n");
3119   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
3120     for (i = 0; i < block_counts[b]; i++)
3121       if (block_tables[b][i].addr != 0)
3122         total += block_tables[b][i].refcount;
3123
3124   for (c = 0; c < 10; c++) {
3125     struct block_desc *blk, *maxb = NULL;
3126     int max = 0;
3127     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
3128       for (i = 0; i < block_counts[b]; i++) {
3129         blk = &block_tables[b][i];
3130         if (blk->addr != 0 && blk->refcount > max) {
3131           max = blk->refcount;
3132           maxb = blk;
3133         }
3134       }
3135     }
3136     if (maxb == NULL)
3137       break;
3138     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
3139       (double)maxb->refcount / total * 100.0);
3140     maxb->refcount = 0;
3141   }
3142
3143   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
3144     for (i = 0; i < block_counts[b]; i++)
3145       block_tables[b][i].refcount = 0;
3146 }
3147 #else
3148 #define block_stats()
3149 #endif
3150
3151 void sh2_drc_flush_all(void)
3152 {
3153   block_stats();
3154   flush_tcache(0);
3155   flush_tcache(1);
3156   flush_tcache(2);
3157 }
3158
3159 void sh2_drc_mem_setup(SH2 *sh2)
3160 {
3161   // fill the convenience pointers
3162   sh2->p_bios = sh2->is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m;
3163   sh2->p_da = sh2->data_array;
3164   sh2->p_sdram = Pico32xMem->sdram;
3165   sh2->p_rom = Pico.rom;
3166 }
3167
3168 void sh2_drc_frame(void)
3169 {
3170   if (literal_disabled_frames > 0)
3171     literal_disabled_frames--;
3172 }
3173
3174 int sh2_drc_init(SH2 *sh2)
3175 {
3176   int i;
3177
3178   if (block_tables[0] == NULL)
3179   {
3180     for (i = 0; i < TCACHE_BUFFERS; i++) {
3181       block_tables[i] = calloc(block_max_counts[i], sizeof(*block_tables[0]));
3182       if (block_tables[i] == NULL)
3183         goto fail;
3184       // max 2 block links (exits) per block
3185       block_link_pool[i] = calloc(block_link_pool_max_counts[i],
3186                           sizeof(*block_link_pool[0]));
3187       if (block_link_pool[i] == NULL)
3188         goto fail;
3189
3190       inval_lookup[i] = calloc(ram_sizes[i] / INVAL_PAGE_SIZE,
3191                                sizeof(inval_lookup[0]));
3192       if (inval_lookup[i] == NULL)
3193         goto fail;
3194
3195       hash_tables[i] = calloc(hash_table_sizes[i], sizeof(*hash_tables[0]));
3196       if (hash_tables[i] == NULL)
3197         goto fail;
3198     }
3199     memset(block_counts, 0, sizeof(block_counts));
3200     memset(block_link_pool_counts, 0, sizeof(block_link_pool_counts));
3201
3202     drc_cmn_init();
3203     tcache_ptr = tcache;
3204     sh2_generate_utils();
3205     host_instructions_updated(tcache, tcache_ptr);
3206
3207     tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;
3208     for (i = 1; i < ARRAY_SIZE(tcache_bases); i++)
3209       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
3210
3211 #if (DRC_DEBUG & 4)
3212     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
3213       tcache_dsm_ptrs[i] = tcache_bases[i];
3214     // disasm the utils
3215     tcache_dsm_ptrs[0] = tcache;
3216     do_host_disasm(0);
3217 #endif
3218 #if (DRC_DEBUG & 1)
3219     hash_collisions = 0;
3220 #endif
3221   }
3222
3223   return 0;
3224
3225 fail:
3226   sh2_drc_finish(sh2);
3227   return -1;
3228 }
3229
3230 void sh2_drc_finish(SH2 *sh2)
3231 {
3232   int i;
3233
3234   if (block_tables[0] == NULL)
3235     return;
3236
3237   sh2_drc_flush_all();
3238
3239   for (i = 0; i < TCACHE_BUFFERS; i++) {
3240 #if (DRC_DEBUG & 4)
3241     printf("~~~ tcache %d\n", i);
3242     tcache_dsm_ptrs[i] = tcache_bases[i];
3243     tcache_ptr = tcache_ptrs[i];
3244     do_host_disasm(i);
3245 #endif
3246
3247     if (block_tables[i] != NULL)
3248       free(block_tables[i]);
3249     block_tables[i] = NULL;
3250     if (block_link_pool[i] == NULL)
3251       free(block_link_pool[i]);
3252     block_link_pool[i] = NULL;
3253
3254     if (inval_lookup[i] == NULL)
3255       free(inval_lookup[i]);
3256     inval_lookup[i] = NULL;
3257
3258     if (hash_tables[i] != NULL) {
3259       free(hash_tables[i]);
3260       hash_tables[i] = NULL;
3261     }
3262   }
3263
3264   drc_cmn_cleanup();
3265 }
3266
3267 #endif /* DRC_SH2 */
3268
3269 static void *dr_get_pc_base(u32 pc, int is_slave)
3270 {
3271   void *ret = NULL;
3272   u32 mask = 0;
3273
3274   if ((pc & ~0x7ff) == 0) {
3275     // BIOS
3276     ret = is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m;
3277     mask = 0x7ff;
3278   }
3279   else if ((pc & 0xfffff000) == 0xc0000000) {
3280     // data array
3281     ret = sh2s[is_slave].data_array;
3282     mask = 0xfff;
3283   }
3284   else if ((pc & 0xc6000000) == 0x06000000) {
3285     // SDRAM
3286     ret = Pico32xMem->sdram;
3287     mask = 0x03ffff;
3288   }
3289   else if ((pc & 0xc6000000) == 0x02000000) {
3290     // ROM
3291     ret = Pico.rom;
3292     mask = 0x3fffff;
3293   }
3294
3295   if (ret == NULL)
3296     return (void *)-1; // NULL is valid value
3297
3298   return (char *)ret - (pc & ~mask);
3299 }
3300
3301 void scan_block(u32 base_pc, int is_slave, u8 *op_flags, u32 *end_pc_out,
3302   u32 *end_literals_out)
3303 {
3304   u16 *dr_pc_base;
3305   u32 pc, op, tmp;
3306   u32 end_pc, end_literals = 0;
3307   u32 lowest_mova = 0;
3308   struct op_data *opd;
3309   int next_is_delay = 0;
3310   int end_block = 0;
3311   int i, i_end;
3312
3313   memset(op_flags, 0, BLOCK_INSN_LIMIT);
3314
3315   dr_pc_base = dr_get_pc_base(base_pc, is_slave);
3316
3317   // 1st pass: disassemble
3318   for (i = 0, pc = base_pc; ; i++, pc += 2) {
3319     // we need an ops[] entry after the last one initialized,
3320     // so do it before end_block checks
3321     opd = &ops[i];
3322     opd->op = OP_UNHANDLED;
3323     opd->rm = -1;
3324     opd->source = opd->dest = 0;
3325     opd->cycles = 1;
3326     opd->imm = 0;
3327
3328     if (next_is_delay) {
3329       op_flags[i] |= OF_DELAY_OP;
3330       next_is_delay = 0;
3331     }
3332     else if (end_block || i >= BLOCK_INSN_LIMIT - 2)
3333       break;
3334
3335     op = FETCH_OP(pc);
3336     switch ((op & 0xf000) >> 12)
3337     {
3338     /////////////////////////////////////////////
3339     case 0x00:
3340       switch (op & 0x0f)
3341       {
3342       case 0x02:
3343         switch (GET_Fx())
3344         {
3345         case 0: // STC SR,Rn  0000nnnn00000010
3346           tmp = SHR_SR;
3347           break;
3348         case 1: // STC GBR,Rn 0000nnnn00010010
3349           tmp = SHR_GBR;
3350           break;
3351         case 2: // STC VBR,Rn 0000nnnn00100010
3352           tmp = SHR_VBR;
3353           break;
3354         default:
3355           goto undefined;
3356         }
3357         opd->op = OP_MOVE;
3358         opd->source = BITMASK1(tmp);
3359         opd->dest = BITMASK1(GET_Rn());
3360         break;
3361       case 0x03:
3362         CHECK_UNHANDLED_BITS(0xd0, undefined);
3363         // BRAF Rm    0000mmmm00100011
3364         // BSRF Rm    0000mmmm00000011
3365         opd->op = OP_BRANCH_RF;
3366         opd->rm = GET_Rn();
3367         opd->source = BITMASK1(opd->rm);
3368         opd->dest = BITMASK1(SHR_PC);
3369         if (!(op & 0x20))
3370           opd->dest |= BITMASK1(SHR_PR);
3371         opd->cycles = 2;
3372         next_is_delay = 1;
3373         end_block = 1;
3374         break;
3375       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
3376       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
3377       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
3378         opd->source = BITMASK3(GET_Rm(), SHR_R0, GET_Rn());
3379         break;
3380       case 0x07:
3381         // MUL.L     Rm,Rn      0000nnnnmmmm0111
3382         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3383         opd->dest = BITMASK1(SHR_MACL);
3384         opd->cycles = 2;
3385         break;
3386       case 0x08:
3387         CHECK_UNHANDLED_BITS(0xf00, undefined);
3388         switch (GET_Fx())
3389         {
3390         case 0: // CLRT               0000000000001000
3391           opd->op = OP_SETCLRT;
3392           opd->dest = BITMASK1(SHR_T);
3393           opd->imm = 0;
3394           break;
3395         case 1: // SETT               0000000000011000
3396           opd->op = OP_SETCLRT;
3397           opd->dest = BITMASK1(SHR_T);
3398           opd->imm = 1;
3399           break;
3400         case 2: // CLRMAC             0000000000101000
3401           opd->dest = BITMASK3(SHR_T, SHR_MACL, SHR_MACH);
3402           break;
3403         default:
3404           goto undefined;
3405         }
3406         break;
3407       case 0x09:
3408         switch (GET_Fx())
3409         {
3410         case 0: // NOP        0000000000001001
3411           CHECK_UNHANDLED_BITS(0xf00, undefined);
3412           break;
3413         case 1: // DIV0U      0000000000011001
3414           CHECK_UNHANDLED_BITS(0xf00, undefined);
3415           opd->dest = BITMASK2(SHR_SR, SHR_T);
3416           break;
3417         case 2: // MOVT Rn    0000nnnn00101001
3418           opd->source = BITMASK1(SHR_T);
3419           opd->dest = BITMASK1(GET_Rn());
3420           break;
3421         default:
3422           goto undefined;
3423         }
3424         break;
3425       case 0x0a:
3426         switch (GET_Fx())
3427         {
3428         case 0: // STS      MACH,Rn   0000nnnn00001010
3429           tmp = SHR_MACH;
3430           break;
3431         case 1: // STS      MACL,Rn   0000nnnn00011010
3432           tmp = SHR_MACL;
3433           break;
3434         case 2: // STS      PR,Rn     0000nnnn00101010
3435           tmp = SHR_PR;
3436           break;
3437         default:
3438           goto undefined;
3439         }
3440         opd->op = OP_MOVE;
3441         opd->source = BITMASK1(tmp);
3442         opd->dest = BITMASK1(GET_Rn());
3443         break;
3444       case 0x0b:
3445         CHECK_UNHANDLED_BITS(0xf00, undefined);
3446         switch (GET_Fx())
3447         {
3448         case 0: // RTS        0000000000001011
3449           opd->op = OP_BRANCH_R;
3450           opd->rm = SHR_PR;
3451           opd->source = BITMASK1(opd->rm);
3452           opd->dest = BITMASK1(SHR_PC);
3453           opd->cycles = 2;
3454           next_is_delay = 1;
3455           end_block = 1;
3456           break;
3457         case 1: // SLEEP      0000000000011011
3458           opd->op = OP_SLEEP;
3459           end_block = 1;
3460           break;
3461         case 2: // RTE        0000000000101011
3462           opd->op = OP_RTE;
3463           opd->source = BITMASK1(SHR_SP);
3464           opd->dest = BITMASK2(SHR_SR, SHR_PC);
3465           opd->cycles = 4;
3466           next_is_delay = 1;
3467           end_block = 1;
3468           break;
3469         default:
3470           goto undefined;
3471         }
3472         break;
3473       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
3474       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
3475       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
3476         opd->source = BITMASK2(GET_Rm(), SHR_R0);
3477         opd->dest = BITMASK1(GET_Rn());
3478         break;
3479       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
3480         opd->source = BITMASK5(GET_Rm(), GET_Rn(), SHR_SR, SHR_MACL, SHR_MACH);
3481         opd->dest = BITMASK4(GET_Rm(), GET_Rn(), SHR_MACL, SHR_MACH);
3482         opd->cycles = 3;
3483         break;
3484       default:
3485         goto undefined;
3486       }
3487       break;
3488
3489     /////////////////////////////////////////////
3490     case 0x01:
3491       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
3492       opd->source = BITMASK1(GET_Rm());
3493       opd->source = BITMASK1(GET_Rn());
3494       opd->imm = (op & 0x0f) * 4;
3495       break;
3496
3497     /////////////////////////////////////////////
3498     case 0x02:
3499       switch (op & 0x0f)
3500       {
3501       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
3502       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
3503       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
3504         opd->source = BITMASK1(GET_Rm());
3505         opd->source = BITMASK1(GET_Rn());
3506         break;
3507       case 0x04: // MOV.B Rm,@-Rn       0010nnnnmmmm0100
3508       case 0x05: // MOV.W Rm,@-Rn       0010nnnnmmmm0101
3509       case 0x06: // MOV.L Rm,@-Rn       0010nnnnmmmm0110
3510         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3511         opd->dest = BITMASK1(GET_Rn());
3512         break;
3513       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
3514         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3515         opd->dest = BITMASK1(SHR_SR);
3516         break;
3517       case 0x08: // TST Rm,Rn           0010nnnnmmmm1000
3518         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3519         opd->dest = BITMASK1(SHR_T);
3520         break;
3521       case 0x09: // AND Rm,Rn           0010nnnnmmmm1001
3522       case 0x0a: // XOR Rm,Rn           0010nnnnmmmm1010
3523       case 0x0b: // OR  Rm,Rn           0010nnnnmmmm1011
3524         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3525         opd->dest = BITMASK1(GET_Rn());
3526         break;
3527       case 0x0c: // CMP/STR Rm,Rn       0010nnnnmmmm1100
3528         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3529         opd->dest = BITMASK1(SHR_T);
3530         break;
3531       case 0x0d: // XTRCT  Rm,Rn        0010nnnnmmmm1101
3532         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3533         opd->dest = BITMASK1(GET_Rn());
3534         break;
3535       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
3536       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
3537         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3538         opd->dest = BITMASK1(SHR_MACL);
3539         break;
3540       default:
3541         goto undefined;
3542       }
3543       break;
3544
3545     /////////////////////////////////////////////
3546     case 0x03:
3547       switch (op & 0x0f)
3548       {
3549       case 0x00: // CMP/EQ Rm,Rn        0011nnnnmmmm0000
3550       case 0x02: // CMP/HS Rm,Rn        0011nnnnmmmm0010
3551       case 0x03: // CMP/GE Rm,Rn        0011nnnnmmmm0011
3552       case 0x06: // CMP/HI Rm,Rn        0011nnnnmmmm0110
3553       case 0x07: // CMP/GT Rm,Rn        0011nnnnmmmm0111
3554         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3555         opd->dest = BITMASK1(SHR_T);
3556         break;
3557       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
3558         opd->source = BITMASK3(GET_Rm(), GET_Rn(), SHR_SR);
3559         opd->dest = BITMASK2(GET_Rn(), SHR_SR);
3560         break;
3561       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
3562       case 0x0d: // DMULS.L Rm,Rn       0011nnnnmmmm1101
3563         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3564         opd->dest = BITMASK2(SHR_MACL, SHR_MACH);
3565         opd->cycles = 2;
3566         break;
3567       case 0x08: // SUB     Rm,Rn       0011nnnnmmmm1000
3568       case 0x0c: // ADD     Rm,Rn       0011nnnnmmmm1100
3569         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3570         opd->dest = BITMASK1(GET_Rn());
3571         break;
3572       case 0x0a: // SUBC    Rm,Rn       0011nnnnmmmm1010
3573       case 0x0e: // ADDC    Rm,Rn       0011nnnnmmmm1110
3574         opd->source = BITMASK3(GET_Rm(), GET_Rn(), SHR_T);
3575         opd->dest = BITMASK2(GET_Rn(), SHR_T);
3576         break;
3577       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
3578       case 0x0f: // ADDV    Rm,Rn       0011nnnnmmmm1111
3579         opd->source = BITMASK2(GET_Rm(), GET_Rn());
3580         opd->dest = BITMASK2(GET_Rn(), SHR_T);
3581         break;
3582       default:
3583         goto undefined;
3584       }
3585       break;
3586
3587     /////////////////////////////////////////////
3588     case 0x04:
3589       switch (op & 0x0f)
3590       {
3591       case 0x00:
3592         switch (GET_Fx())
3593         {
3594         case 0: // SHLL Rn    0100nnnn00000000
3595         case 2: // SHAL Rn    0100nnnn00100000
3596           opd->source = BITMASK1(GET_Rn());
3597           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3598           break;
3599         case 1: // DT Rn      0100nnnn00010000
3600           opd->source = BITMASK1(GET_Rn());
3601           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3602           break;
3603         default:
3604           goto undefined;
3605         }
3606         break;
3607       case 0x01:
3608         switch (GET_Fx())
3609         {
3610         case 0: // SHLR Rn    0100nnnn00000001
3611         case 2: // SHAR Rn    0100nnnn00100001
3612           opd->source = BITMASK1(GET_Rn());
3613           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3614           break;
3615         case 1: // CMP/PZ Rn  0100nnnn00010001
3616           opd->source = BITMASK1(GET_Rn());
3617           opd->dest = BITMASK1(SHR_T);
3618           break;
3619         default:
3620           goto undefined;
3621         }
3622         break;
3623       case 0x02:
3624       case 0x03:
3625         switch (op & 0x3f)
3626         {
3627         case 0x02: // STS.L    MACH,@-Rn 0100nnnn00000010
3628           tmp = SHR_MACH;
3629           break;
3630         case 0x12: // STS.L    MACL,@-Rn 0100nnnn00010010
3631           tmp = SHR_MACL;
3632           break;
3633         case 0x22: // STS.L    PR,@-Rn   0100nnnn00100010
3634           tmp = SHR_PR;
3635           break;
3636         case 0x03: // STC.L    SR,@-Rn   0100nnnn00000011
3637           tmp = SHR_SR;
3638           opd->cycles = 2;
3639           break;
3640         case 0x13: // STC.L    GBR,@-Rn  0100nnnn00010011
3641           tmp = SHR_GBR;
3642           opd->cycles = 2;
3643           break;
3644         case 0x23: // STC.L    VBR,@-Rn  0100nnnn00100011
3645           tmp = SHR_VBR;
3646           opd->cycles = 2;
3647           break;
3648         default:
3649           goto undefined;
3650         }
3651         opd->source = BITMASK2(GET_Rn(), tmp);
3652         opd->dest = BITMASK1(GET_Rn());
3653         break;
3654       case 0x04:
3655       case 0x05:
3656         switch (op & 0x3f)
3657         {
3658         case 0x04: // ROTL   Rn          0100nnnn00000100
3659         case 0x05: // ROTR   Rn          0100nnnn00000101
3660           opd->source = BITMASK1(GET_Rn());
3661           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3662           break;
3663         case 0x24: // ROTCL  Rn          0100nnnn00100100
3664         case 0x25: // ROTCR  Rn          0100nnnn00100101
3665           opd->source = BITMASK2(GET_Rn(), SHR_T);
3666           opd->dest = BITMASK2(GET_Rn(), SHR_T);
3667           break;
3668         case 0x15: // CMP/PL Rn          0100nnnn00010101
3669           opd->source = BITMASK1(GET_Rn());
3670           opd->dest = BITMASK1(SHR_T);
3671           break;
3672         default:
3673           goto undefined;
3674         }
3675         break;
3676       case 0x06:
3677       case 0x07:
3678         switch (op & 0x3f)
3679         {
3680         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
3681           tmp = SHR_MACH;
3682           break;
3683         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
3684           tmp = SHR_MACL;
3685           break;
3686         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
3687           tmp = SHR_PR;
3688           break;
3689         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
3690           tmp = SHR_SR;
3691           opd->cycles = 3;
3692           break;
3693         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
3694           tmp = SHR_GBR;
3695           opd->cycles = 3;
3696           break;
3697         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
3698           tmp = SHR_VBR;
3699           opd->cycles = 3;
3700           break;
3701         default:
3702           goto undefined;
3703         }
3704         opd->source = BITMASK1(GET_Rn());
3705         opd->dest = BITMASK2(GET_Rn(), tmp);
3706         break;
3707       case 0x08:
3708       case 0x09:
3709         switch (GET_Fx())
3710         {
3711         case 0:
3712           // SHLL2 Rn        0100nnnn00001000
3713           // SHLR2 Rn        0100nnnn00001001
3714           break;
3715         case 1:
3716           // SHLL8 Rn        0100nnnn00011000
3717           // SHLR8 Rn        0100nnnn00011001
3718           break;
3719         case 2:
3720           // SHLL16 Rn       0100nnnn00101000
3721           // SHLR16 Rn       0100nnnn00101001
3722           break;
3723         default:
3724           goto undefined;
3725         }
3726         opd->source = BITMASK1(GET_Rn());
3727         opd->dest = BITMASK1(GET_Rn());
3728         break;
3729       case 0x0a:
3730         switch (GET_Fx())
3731         {
3732         case 0: // LDS      Rm,MACH   0100mmmm00001010
3733           tmp = SHR_MACH;
3734           break;
3735         case 1: // LDS      Rm,MACL   0100mmmm00011010
3736           tmp = SHR_MACL;
3737           break;
3738         case 2: // LDS      Rm,PR     0100mmmm00101010
3739           tmp = SHR_PR;
3740           break;
3741         default:
3742           goto undefined;
3743         }
3744         opd->op = OP_MOVE;
3745         opd->source = BITMASK1(GET_Rn());
3746         opd->dest = BITMASK1(tmp);
3747         break;
3748       case 0x0b:
3749         switch (GET_Fx())
3750         {
3751         case 0: // JSR  @Rm   0100mmmm00001011
3752           opd->dest = BITMASK1(SHR_PR);
3753         case 2: // JMP  @Rm   0100mmmm00101011
3754           opd->op = OP_BRANCH_R;
3755           opd->rm = GET_Rn();
3756           opd->source = BITMASK1(opd->rm);
3757           opd->dest |= BITMASK1(SHR_PC);
3758           opd->cycles = 2;
3759           next_is_delay = 1;
3760           end_block = 1;
3761           break;
3762         case 1: // TAS.B @Rn  0100nnnn00011011
3763           opd->source = BITMASK1(GET_Rn());
3764           opd->dest = BITMASK1(SHR_T);
3765           opd->cycles = 4;
3766           break;
3767         default:
3768           goto undefined;
3769         }
3770         break;
3771       case 0x0e:
3772         switch (GET_Fx())
3773         {
3774         case 0: // LDC Rm,SR   0100mmmm00001110
3775           tmp = SHR_SR;
3776           break;
3777         case 1: // LDC Rm,GBR  0100mmmm00011110
3778           tmp = SHR_GBR;
3779           break;
3780         case 2: // LDC Rm,VBR  0100mmmm00101110
3781           tmp = SHR_VBR;
3782           break;
3783         default:
3784           goto undefined;
3785         }
3786         opd->op = OP_MOVE;
3787         opd->source = BITMASK1(GET_Rn());
3788         opd->dest = BITMASK1(tmp);
3789         break;
3790       case 0x0f:
3791         // MAC.W @Rm+,@Rn+  0100nnnnmmmm1111
3792         opd->source = BITMASK5(GET_Rm(), GET_Rn(), SHR_SR, SHR_MACL, SHR_MACH);
3793         opd->dest = BITMASK4(GET_Rm(), GET_Rn(), SHR_MACL, SHR_MACH);
3794         opd->cycles = 3;
3795         break;
3796       default:
3797         goto undefined;
3798       }
3799       break;
3800
3801     /////////////////////////////////////////////
3802     case 0x05:
3803       // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
3804       opd->source = BITMASK1(GET_Rm());
3805       opd->dest = BITMASK1(GET_Rn());
3806       opd->imm = (op & 0x0f) * 4;
3807       break;
3808
3809     /////////////////////////////////////////////
3810     case 0x06:
3811       switch (op & 0x0f)
3812       {
3813       case 0x04: // MOV.B @Rm+,Rn       0110nnnnmmmm0100
3814       case 0x05: // MOV.W @Rm+,Rn       0110nnnnmmmm0101
3815       case 0x06: // MOV.L @Rm+,Rn       0110nnnnmmmm0110
3816         opd->dest = BITMASK1(GET_Rm());
3817       case 0x00: // MOV.B @Rm,Rn        0110nnnnmmmm0000
3818       case 0x01: // MOV.W @Rm,Rn        0110nnnnmmmm0001
3819       case 0x02: // MOV.L @Rm,Rn        0110nnnnmmmm0010
3820         opd->source = BITMASK1(GET_Rm());
3821         opd->dest |= BITMASK1(GET_Rn());
3822         break;
3823       case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
3824         opd->source = BITMASK2(GET_Rm(), SHR_T);
3825         opd->dest = BITMASK2(GET_Rn(), SHR_T);
3826         break;
3827       case 0x03: // MOV    Rm,Rn        0110nnnnmmmm0011
3828         opd->op = OP_MOVE;
3829         goto arith_rmrn;
3830       case 0x07: // NOT    Rm,Rn        0110nnnnmmmm0111
3831       case 0x08: // SWAP.B Rm,Rn        0110nnnnmmmm1000
3832       case 0x09: // SWAP.W Rm,Rn        0110nnnnmmmm1001
3833       case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
3834       case 0x0c: // EXTU.B Rm,Rn        0110nnnnmmmm1100
3835       case 0x0d: // EXTU.W Rm,Rn        0110nnnnmmmm1101
3836       case 0x0e: // EXTS.B Rm,Rn        0110nnnnmmmm1110
3837       case 0x0f: // EXTS.W Rm,Rn        0110nnnnmmmm1111
3838       arith_rmrn:
3839         opd->source = BITMASK1(GET_Rm());
3840         opd->dest = BITMASK1(GET_Rn());
3841         break;
3842       }
3843       break;
3844
3845     /////////////////////////////////////////////
3846     case 0x07:
3847       // ADD #imm,Rn  0111nnnniiiiiiii
3848       opd->source = opd->dest = BITMASK1(GET_Rn());
3849       opd->imm = (int)(signed char)op;
3850       break;
3851
3852     /////////////////////////////////////////////
3853     case 0x08:
3854       switch (op & 0x0f00)
3855       {
3856       case 0x0000: // MOV.B R0,@(disp,Rn)  10000000nnnndddd
3857         opd->source = BITMASK2(GET_Rm(), SHR_R0);
3858         opd->imm = (op & 0x0f);
3859         break;
3860       case 0x0100: // MOV.W R0,@(disp,Rn)  10000001nnnndddd
3861         opd->source = BITMASK2(GET_Rm(), SHR_R0);
3862         opd->imm = (op & 0x0f) * 2;
3863         break;
3864       case 0x0400: // MOV.B @(disp,Rm),R0  10000100mmmmdddd
3865         opd->source = BITMASK1(GET_Rm());
3866         opd->dest = BITMASK1(SHR_R0);
3867         opd->imm = (op & 0x0f);
3868         break;
3869       case 0x0500: // MOV.W @(disp,Rm),R0  10000101mmmmdddd
3870         opd->source = BITMASK1(GET_Rm());
3871         opd->dest = BITMASK1(SHR_R0);
3872         opd->imm = (op & 0x0f) * 2;
3873         break;
3874       case 0x0800: // CMP/EQ #imm,R0       10001000iiiiiiii
3875         opd->source = BITMASK1(SHR_R0);
3876         opd->dest = BITMASK1(SHR_T);
3877         opd->imm = (int)(signed char)op;
3878         break;
3879       case 0x0d00: // BT/S label 10001101dddddddd
3880       case 0x0f00: // BF/S label 10001111dddddddd
3881         next_is_delay = 1;
3882         // fallthrough
3883       case 0x0900: // BT   label 10001001dddddddd
3884       case 0x0b00: // BF   label 10001011dddddddd
3885         opd->op = (op & 0x0200) ? OP_BRANCH_CF : OP_BRANCH_CT;
3886         opd->source = BITMASK1(SHR_T);
3887         opd->dest = BITMASK1(SHR_PC);
3888         opd->imm = ((signed int)(op << 24) >> 23);
3889         opd->imm += pc + 4;
3890         if (base_pc <= opd->imm && opd->imm < base_pc + BLOCK_INSN_LIMIT * 2)
3891           op_flags[(opd->imm - base_pc) / 2] |= OF_BTARGET;
3892         break;
3893       default:
3894         goto undefined;
3895       }
3896       break;
3897
3898     /////////////////////////////////////////////
3899     case 0x09:
3900       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
3901       opd->op = OP_LOAD_POOL;
3902       tmp = pc + 2;
3903       if (op_flags[i] & OF_DELAY_OP) {
3904         if (ops[i-1].op == OP_BRANCH)
3905           tmp = ops[i-1].imm;
3906         else
3907           tmp = 0;
3908       }
3909       opd->source = BITMASK1(SHR_PC);
3910       opd->dest = BITMASK1(GET_Rn());
3911       if (tmp)
3912         opd->imm = tmp + 2 + (op & 0xff) * 2;
3913       opd->size = 1;
3914       break;
3915
3916     /////////////////////////////////////////////
3917     case 0x0b:
3918       // BSR  label 1011dddddddddddd
3919       opd->dest = BITMASK1(SHR_PR);
3920     case 0x0a:
3921       // BRA  label 1010dddddddddddd
3922       opd->op = OP_BRANCH;
3923       opd->dest |= BITMASK1(SHR_PC);
3924       opd->imm = ((signed int)(op << 20) >> 19);
3925       opd->imm += pc + 4;
3926       opd->cycles = 2;
3927       next_is_delay = 1;
3928       end_block = 1;
3929       if (base_pc <= opd->imm && opd->imm < base_pc + BLOCK_INSN_LIMIT * 2)
3930         op_flags[(opd->imm - base_pc) / 2] |= OF_BTARGET;
3931       break;
3932
3933     /////////////////////////////////////////////
3934     case 0x0c:
3935       switch (op & 0x0f00)
3936       {
3937       case 0x0000: // MOV.B R0,@(disp,GBR)   11000000dddddddd
3938       case 0x0100: // MOV.W R0,@(disp,GBR)   11000001dddddddd
3939       case 0x0200: // MOV.L R0,@(disp,GBR)   11000010dddddddd
3940         opd->source = BITMASK2(SHR_GBR, SHR_R0);
3941         opd->size = (op & 0x300) >> 8;
3942         opd->imm = (op & 0xff) << opd->size;
3943         break;
3944       case 0x0400: // MOV.B @(disp,GBR),R0   11000100dddddddd
3945       case 0x0500: // MOV.W @(disp,GBR),R0   11000101dddddddd
3946       case 0x0600: // MOV.L @(disp,GBR),R0   11000110dddddddd
3947         opd->source = BITMASK1(SHR_GBR);
3948         opd->dest = BITMASK1(SHR_R0);
3949         opd->size = (op & 0x300) >> 8;
3950         opd->imm = (op & 0xff) << opd->size;
3951         break;
3952       case 0x0300: // TRAPA #imm      11000011iiiiiiii
3953         opd->source = BITMASK2(SHR_PC, SHR_SR);
3954         opd->dest = BITMASK1(SHR_PC);
3955         opd->imm = (op & 0xff) * 4;
3956         opd->cycles = 8;
3957         end_block = 1; // FIXME
3958         break;
3959       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
3960         opd->op = OP_MOVA;
3961         tmp = pc + 2;
3962         if (op_flags[i] & OF_DELAY_OP) {
3963           if (ops[i-1].op == OP_BRANCH)
3964             tmp = ops[i-1].imm;
3965           else
3966             tmp = 0;
3967         }
3968         opd->dest = BITMASK1(SHR_R0);
3969         if (tmp) {
3970           opd->imm = (tmp + 2 + (op & 0xff) * 4) & ~3;
3971           if (opd->imm >= base_pc) {
3972             if (lowest_mova == 0 || opd->imm < lowest_mova)
3973               lowest_mova = opd->imm;
3974           }
3975         }
3976         break;
3977       case 0x0800: // TST #imm,R0           11001000iiiiiiii
3978         opd->source = BITMASK1(SHR_R0);
3979         opd->dest = BITMASK1(SHR_T);
3980         opd->imm = op & 0xff;
3981         break;
3982       case 0x0900: // AND #imm,R0           11001001iiiiiiii
3983         opd->source = opd->dest = BITMASK1(SHR_R0);
3984         opd->imm = op & 0xff;
3985         break;
3986       case 0x0a00: // XOR #imm,R0           11001010iiiiiiii
3987         opd->source = opd->dest = BITMASK1(SHR_R0);
3988         opd->imm = op & 0xff;
3989         break;
3990       case 0x0b00: // OR  #imm,R0           11001011iiiiiiii
3991         opd->source = opd->dest = BITMASK1(SHR_R0);
3992         opd->imm = op & 0xff;
3993         break;
3994       case 0x0c00: // TST.B #imm,@(R0,GBR)  11001100iiiiiiii
3995         opd->source = BITMASK2(SHR_GBR, SHR_R0);
3996         opd->dest = BITMASK1(SHR_T);
3997         opd->imm = op & 0xff;
3998         opd->cycles = 3;
3999         break;
4000       case 0x0d00: // AND.B #imm,@(R0,GBR)  11001101iiiiiiii
4001       case 0x0e00: // XOR.B #imm,@(R0,GBR)  11001110iiiiiiii
4002       case 0x0f00: // OR.B  #imm,@(R0,GBR)  11001111iiiiiiii
4003         opd->source = BITMASK2(SHR_GBR, SHR_R0);
4004         opd->imm = op & 0xff;
4005         opd->cycles = 3;
4006         break;
4007       default:
4008         goto undefined;
4009       }
4010       break;
4011
4012     /////////////////////////////////////////////
4013     case 0x0d:
4014       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
4015       opd->op = OP_LOAD_POOL;
4016       tmp = pc + 2;
4017       if (op_flags[i] & OF_DELAY_OP) {
4018         if (ops[i-1].op == OP_BRANCH)
4019           tmp = ops[i-1].imm;
4020         else
4021           tmp = 0;
4022       }
4023       opd->source = BITMASK1(SHR_PC);
4024       opd->dest = BITMASK1(GET_Rn());
4025       if (tmp)
4026         opd->imm = (tmp + 2 + (op & 0xff) * 4) & ~3;
4027       opd->size = 2;
4028       break;
4029
4030     /////////////////////////////////////////////
4031     case 0x0e:
4032       // MOV #imm,Rn   1110nnnniiiiiiii
4033       opd->dest = BITMASK1(GET_Rn());
4034       opd->imm = (u32)(signed int)(signed char)op;
4035       break;
4036
4037     default:
4038     undefined:
4039       elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
4040         is_slave ? 's' : 'm', op, pc);
4041       break;
4042     }
4043   }
4044   i_end = i;
4045   end_pc = pc;
4046
4047   // 2nd pass: some analysis
4048   for (i = 0; i < i_end; i++) {
4049     opd = &ops[i];
4050
4051     // propagate T (TODO: DIV0U)
4052     if ((opd->op == OP_SETCLRT && !opd->imm) || opd->op == OP_BRANCH_CT)
4053       op_flags[i + 1] |= OF_T_CLEAR;
4054     else if ((opd->op == OP_SETCLRT && opd->imm) || opd->op == OP_BRANCH_CF)
4055       op_flags[i + 1] |= OF_T_SET;
4056
4057     if ((op_flags[i] & OF_BTARGET) || (opd->dest & BITMASK1(SHR_T)))
4058       op_flags[i] &= ~(OF_T_SET | OF_T_CLEAR);
4059     else
4060       op_flags[i + 1] |= op_flags[i] & (OF_T_SET | OF_T_CLEAR);
4061
4062     if ((opd->op == OP_BRANCH_CT && (op_flags[i] & OF_T_SET))
4063         || (opd->op == OP_BRANCH_CF && (op_flags[i] & OF_T_CLEAR)))
4064     {
4065       opd->op = OP_BRANCH;
4066       opd->cycles = 3;
4067       i_end = i + 1;
4068       if (op_flags[i + 1] & OF_DELAY_OP) {
4069         opd->cycles = 2;
4070         i_end++;
4071       }
4072     }
4073     else if (opd->op == OP_LOAD_POOL)
4074     {
4075       if (opd->imm < end_pc + MAX_LITERAL_OFFSET) {
4076         if (end_literals < opd->imm + opd->size * 2)
4077           end_literals = opd->imm + opd->size * 2;
4078       }
4079     }
4080   }
4081   end_pc = base_pc + i_end * 2;
4082   if (end_literals < end_pc)
4083     end_literals = end_pc;
4084
4085   // end_literals is used to decide to inline a literal or not
4086   // XXX: need better detection if this actually is used in write
4087   if (lowest_mova >= base_pc) {
4088     if (lowest_mova < end_literals) {
4089       dbg(1, "mova for %08x, block %08x", lowest_mova, base_pc);
4090       end_literals = end_pc;
4091     }
4092     if (lowest_mova < end_pc) {
4093       dbg(1, "warning: mova inside of blk for %08x, block %08x",
4094         lowest_mova, base_pc);
4095       end_literals = end_pc;
4096     }
4097   }
4098
4099   *end_pc_out = end_pc;
4100   if (end_literals_out != NULL)
4101     *end_literals_out = end_literals;
4102 }
4103
4104 // vim:shiftwidth=2:ts=2:expandtab