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