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