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