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