32x: drc: enable and fix static reg alloc, carry flag tweaks
[picodrive.git] / cpu / sh2 / compiler.c
1 /*
2  * vim:shiftwidth=2:expandtab
3  */
4 #include <stddef.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <assert.h>
8
9 #include "../../pico/pico_int.h"
10 #include "sh2.h"
11 #include "compiler.h"
12 #include "../drc/cmn.h"
13
14 // debug stuff {
15 #ifndef DRC_DEBUG
16 #define DRC_DEBUG 0
17 #endif
18
19 #if DRC_DEBUG
20 #define dbg(l,...) { \
21   if ((l) & DRC_DEBUG) \
22     elprintf(EL_STATUS, ##__VA_ARGS__); \
23 }
24
25 #include "mame/sh2dasm.h"
26 #include <platform/linux/host_dasm.h>
27 static int insns_compiled, hash_collisions, host_insn_count;
28 #define COUNT_OP \
29         host_insn_count++
30 #else // !DRC_DEBUG
31 #define COUNT_OP
32 #define dbg(...)
33 #endif
34
35 #if (DRC_DEBUG & 2)
36 static u8 *tcache_dsm_ptrs[3];
37 static char sh2dasm_buff[64];
38 #define do_host_disasm(tcid) \
39   host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
40   tcache_dsm_ptrs[tcid] = tcache_ptr
41 #else
42 #define do_host_disasm(x)
43 #endif
44 // } debug
45
46 #define BLOCK_CYCLE_LIMIT 100
47 #define MAX_BLOCK_SIZE (BLOCK_CYCLE_LIMIT * 6 * 6)
48
49 // we have 3 translation cache buffers, split from one drc/cmn buffer.
50 // BIOS shares tcache with data array because it's only used for init
51 // and can be discarded early
52 // XXX: need to tune sizes
53 static const int tcache_sizes[3] = {
54   DRC_TCACHE_SIZE * 6 / 8, // ROM, DRAM
55   DRC_TCACHE_SIZE / 8, // BIOS, data array in master sh2
56   DRC_TCACHE_SIZE / 8, // ... slave
57 };
58
59 static u8 *tcache_bases[3];
60 static u8 *tcache_ptrs[3];
61
62 // ptr for code emiters
63 static u8 *tcache_ptr;
64
65 // host register tracking
66 enum {
67   HR_FREE,
68   HR_CACHED, // 'val' has sh2_reg_e
69   HR_CACHED_DIRTY,
70   HR_CONST,  // 'val' has constant
71   HR_TEMP,   // reg used for temp storage
72 };
73
74 typedef struct {
75   u8 reg;
76   u8 type;
77   u16 stamp; // kind of a timestamp
78   u32 val;
79 } temp_reg_t;
80
81 // note: reg_temp[] must have at least the amount of
82 // registers used by handlers in worst case (currently 4)
83 #ifdef ARM
84 #include "../drc/emit_arm.c"
85
86 static const int reg_map_g2h[] = {
87    4,  5,  6,  7,
88    8, -1, -1, -1,
89   -1, -1, -1, -1,
90   -1, -1, -1,  9,
91   -1, -1, -1, 10,
92   -1, -1, -1, -1,
93 };
94
95 static temp_reg_t reg_temp[] = {
96   {  0, },
97   {  1, },
98   { 12, },
99   { 14, },
100   {  2, },
101   {  3, },
102 };
103
104 #else
105 #include "../drc/emit_x86.c"
106
107 static const int reg_map_g2h[] = {
108   xSI,-1, -1, -1,
109   -1, -1, -1, -1,
110   -1, -1, -1, -1,
111   -1, -1, -1, -1,
112   -1, -1, -1, xDI,
113   -1, -1, -1, -1,
114 };
115
116 // ax, cx, dx are usually temporaries by convention
117 static temp_reg_t reg_temp[] = {
118   { xAX, },
119   { xBX, },
120   { xCX, },
121   { xDX, },
122 };
123
124 #endif
125
126 #define T       0x00000001
127 #define S       0x00000002
128 #define I       0x000000f0
129 #define Q       0x00000100
130 #define M       0x00000200
131
132 #define Q_SHIFT 8
133 #define M_SHIFT 9
134
135 typedef struct block_desc_ {
136   u32 addr;                     // SH2 PC address
137   u32 end_addr;                 // TODO rm?
138   void *tcache_ptr;             // translated block for above PC
139   struct block_desc_ *next;     // next block with the same PC hash
140 #if (DRC_DEBUG & 1)
141   int refcount;
142 #endif
143 } block_desc;
144
145 static const int block_max_counts[3] = {
146   4*1024,
147   256,
148   256,
149 };
150 static block_desc *block_tables[3];
151 static int block_counts[3];
152
153 // ROM hash table
154 #define MAX_HASH_ENTRIES 1024
155 #define HASH_MASK (MAX_HASH_ENTRIES - 1)
156 static void **hash_table;
157
158 static void REGPARM(2) (*sh2_drc_entry)(const void *block, SH2 *sh2);
159 static void (*sh2_drc_exit)(void);
160
161 // tmp
162 extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
163 static void REGPARM(1) sh2_test_irq(SH2 *sh2);
164
165 static void flush_tcache(int tcid)
166 {
167   dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
168     tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
169     block_counts[tcid], block_max_counts[tcid]);
170
171   block_counts[tcid] = 0;
172   tcache_ptrs[tcid] = tcache_bases[tcid];
173   if (tcid == 0) { // ROM, RAM
174     memset(hash_table, 0, sizeof(hash_table[0]) * MAX_HASH_ENTRIES);
175     memset(Pico32xMem->drcblk_ram, 0, sizeof(Pico32xMem->drcblk_ram));
176   }
177   else
178     memset(Pico32xMem->drcblk_da[tcid - 1], 0, sizeof(Pico32xMem->drcblk_da[0]));
179 #if (DRC_DEBUG & 2)
180   tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
181 #endif
182 }
183
184 static void *dr_find_block(block_desc *tab, u32 addr)
185 {
186   for (tab = tab->next; tab != NULL; tab = tab->next)
187     if (tab->addr == addr)
188       break;
189
190   if (tab != NULL)
191     return tab->tcache_ptr;
192
193   printf("block miss for %08x\n", addr);
194   return NULL;
195 }
196
197 static block_desc *dr_add_block(u32 addr, int tcache_id, int *blk_id)
198 {
199   int *bcount = &block_counts[tcache_id];
200   block_desc *bd;
201
202   if (*bcount >= block_max_counts[tcache_id])
203     return NULL;
204
205   bd = &block_tables[tcache_id][*bcount];
206   bd->addr = addr;
207   bd->tcache_ptr = tcache_ptr;
208   *blk_id = *bcount;
209   (*bcount)++;
210
211   return bd;
212 }
213
214 #define HASH_FUNC(hash_tab, addr) \
215   ((block_desc **)(hash_tab))[(addr) & HASH_MASK]
216
217 // ---------------------------------------------------------------
218
219 // register chache
220 static u16 rcache_counter;
221
222 static temp_reg_t *rcache_evict(void)
223 {
224   // evict reg with oldest stamp
225   int i, oldest = -1;
226   u16 min_stamp = (u16)-1;
227
228   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
229     if (reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY)
230       if (reg_temp[i].stamp <= min_stamp) {
231         min_stamp = reg_temp[i].stamp;
232         oldest = i;
233       }
234   }
235
236   if (oldest == -1) {
237     printf("no registers to evict, aborting\n");
238     exit(1);
239   }
240
241   i = oldest;
242   if (reg_temp[i].type == HR_CACHED_DIRTY) {
243     // writeback
244     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
245   }
246
247   return &reg_temp[i];
248 }
249
250 typedef enum {
251   RC_GR_READ,
252   RC_GR_WRITE,
253   RC_GR_RMW,
254 } rc_gr_mode;
255
256 // note: must not be called when doing conditional code
257 static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
258 {
259   temp_reg_t *tr;
260   int i;
261
262   // maybe already statically mapped?
263   i = reg_map_g2h[r];
264   if (i != -1)
265     return i;
266
267   rcache_counter++;
268
269   // maybe already cached?
270   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
271     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
272          reg_temp[i].val == r)
273     {
274       reg_temp[i].stamp = rcache_counter;
275       if (mode != RC_GR_READ)
276         reg_temp[i].type = HR_CACHED_DIRTY;
277       return reg_temp[i].reg;
278     }
279   }
280
281   // use any free reg
282   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
283     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
284       tr = &reg_temp[i];
285       goto do_alloc;
286     }
287   }
288
289   tr = rcache_evict();
290
291 do_alloc:
292   if (mode != RC_GR_WRITE)
293     emith_ctx_read(tr->reg, r * 4);
294
295   tr->type = mode != RC_GR_READ ? HR_CACHED_DIRTY : HR_CACHED;
296   tr->val = r;
297   tr->stamp = rcache_counter;
298   return tr->reg;
299 }
300
301 static int rcache_get_tmp(void)
302 {
303   temp_reg_t *tr;
304   int i;
305
306   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
307     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
308       tr = &reg_temp[i];
309       goto do_alloc;
310     }
311
312   tr = rcache_evict();
313
314 do_alloc:
315   tr->type = HR_TEMP;
316   return tr->reg;
317 }
318
319 static int rcache_get_arg_id(int arg)
320 {
321   int i, r = 0;
322   host_arg2reg(r, arg);
323
324   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
325     if (reg_temp[i].reg == r)
326       break;
327
328   if (i == ARRAY_SIZE(reg_temp))
329     // let's just say it's untracked arg reg
330     return r;
331
332   if (reg_temp[i].type == HR_CACHED_DIRTY) {
333     // writeback
334     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
335   }
336   else if (reg_temp[i].type == HR_TEMP) {
337     printf("arg %d reg %d already used, aborting\n", arg, r);
338     exit(1);
339   }
340
341   return i;
342 }
343
344 // get a reg to be used as function arg
345 // it's assumed that regs are cleaned before call
346 static int rcache_get_tmp_arg(int arg)
347 {
348   int id = rcache_get_arg_id(arg);
349   reg_temp[id].type = HR_TEMP;
350
351   return reg_temp[id].reg;
352 }
353
354 // same but caches reg. RC_GR_READ only.
355 static int rcache_get_reg_arg(int arg, sh2_reg_e r)
356 {
357   int i, srcr, dstr, dstid;
358
359   dstid = rcache_get_arg_id(arg);
360   dstr = reg_temp[dstid].reg;
361
362   // maybe already statically mapped?
363   srcr = reg_map_g2h[r];
364   if (srcr != -1)
365     goto do_cache;
366
367   // maybe already cached?
368   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
369     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
370          reg_temp[i].val == r)
371     {
372       srcr = reg_temp[i].reg;
373       goto do_cache;
374     }
375   }
376
377   // must read
378   srcr = dstr;
379   emith_ctx_read(srcr, r * 4);
380
381 do_cache:
382   if (srcr != dstr)
383     emith_move_r_r(dstr, srcr);
384
385   reg_temp[dstid].stamp = ++rcache_counter;
386   reg_temp[dstid].type = HR_CACHED;
387   reg_temp[dstid].val = r;
388   return dstr;
389 }
390
391 static void rcache_free_tmp(int hr)
392 {
393   int i;
394   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
395     if (reg_temp[i].reg == hr)
396       break;
397
398   if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
399     printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
400     return;
401   }
402
403   reg_temp[i].type = HR_FREE;
404 }
405
406 static void rcache_clean(void)
407 {
408   int i;
409   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
410     if (reg_temp[i].type == HR_CACHED_DIRTY) {
411       // writeback
412       emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
413       reg_temp[i].type = HR_CACHED;
414     }
415 }
416
417 static void rcache_invalidate(void)
418 {
419   int i;
420   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
421     reg_temp[i].type = HR_FREE;
422   rcache_counter = 0;
423 }
424
425 static void rcache_flush(void)
426 {
427   rcache_clean();
428   rcache_invalidate();
429 }
430
431 // ---------------------------------------------------------------
432
433 static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
434 {
435   // TODO: propagate this constant
436   int hr = rcache_get_reg(dst, RC_GR_WRITE);
437   emith_move_r_imm(hr, imm);
438 }
439
440 static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
441 {
442   int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
443   int hr_s = rcache_get_reg(src, RC_GR_READ);
444
445   emith_move_r_r(hr_d, hr_s);
446 }
447
448 // T must be clear, and comparison done just before this
449 static void emit_or_t_if_eq(int srr)
450 {
451   EMITH_SJMP_START(DCOND_NE);
452   emith_or_r_imm_c(DCOND_EQ, srr, T);
453   EMITH_SJMP_END(DCOND_NE);
454 }
455
456 // arguments must be ready
457 // reg cache must be clean before call
458 static int emit_memhandler_read(int size)
459 {
460   int ctxr;
461   host_arg2reg(ctxr, 1);
462   emith_move_r_r(ctxr, CONTEXT_REG);
463   switch (size) {
464   case 0: // 8
465     emith_call(p32x_sh2_read8);
466     break;
467   case 1: // 16
468     emith_call(p32x_sh2_read16);
469     break;
470   case 2: // 32
471     emith_call(p32x_sh2_read32);
472     break;
473   }
474   rcache_invalidate();
475   // assuming arg0 and retval reg matches
476   return rcache_get_tmp_arg(0);
477 }
478
479 static void emit_memhandler_write(int size)
480 {
481   int ctxr;
482   host_arg2reg(ctxr, 2);
483   emith_move_r_r(ctxr, CONTEXT_REG);
484   switch (size) {
485   case 0: // 8
486     emith_call(p32x_sh2_write8);
487     break;
488   case 1: // 16
489     emith_call(p32x_sh2_write16);
490     break;
491   case 2: // 32
492     emith_call(p32x_sh2_write32);
493     break;
494   }
495   rcache_invalidate();
496 }
497
498 // @(Rx,Ry)
499 static int emit_indirect_indexed_read(int rx, int ry, int size)
500 {
501   int a0, t;
502   rcache_clean();
503   a0 = rcache_get_reg_arg(0, rx);
504   t  = rcache_get_reg(ry, RC_GR_READ);
505   emith_add_r_r(a0, t);
506   return emit_memhandler_read(size);
507 }
508
509 // tmp_wr -> @(Rx,Ry)
510 static void emit_indirect_indexed_write(int tmp_wr, int rx, int ry, int size)
511 {
512   int a0, t;
513   rcache_clean();
514   t = rcache_get_tmp_arg(1);
515   emith_move_r_r(t, tmp_wr);
516   a0 = rcache_get_reg_arg(0, rx);
517   t  = rcache_get_reg(ry, RC_GR_READ);
518   emith_add_r_r(a0, t);
519   emit_memhandler_write(size);
520 }
521
522 // read @Rn, @rm
523 static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size)
524 {
525   int tmp;
526
527   rcache_clean();
528   rcache_get_reg_arg(0, rn);
529   tmp = emit_memhandler_read(size);
530   emith_ctx_write(tmp, offsetof(SH2, drc_tmp));
531   rcache_free_tmp(tmp);
532   tmp = rcache_get_reg(rn, RC_GR_RMW);
533   emith_add_r_imm(tmp, 1 << size);
534
535   rcache_clean();
536   rcache_get_reg_arg(0, rm);
537   *rmr = emit_memhandler_read(size);
538   *rnr = rcache_get_tmp();
539   emith_ctx_read(*rnr, offsetof(SH2, drc_tmp));
540   tmp = rcache_get_reg(rm, RC_GR_RMW);
541   emith_add_r_imm(tmp, 1 << size);
542 }
543  
544 static void emit_do_static_regs(int is_write, int tmpr)
545 {
546   int i, r, count;
547
548   for (i = 0; i < ARRAY_SIZE(reg_map_g2h); i++) {
549     r = reg_map_g2h[i];
550     if (r == -1)
551       continue;
552
553     for (count = 1; i < ARRAY_SIZE(reg_map_g2h) - 1; i++, r++) {
554       if (reg_map_g2h[i + 1] != r + 1)
555         break;
556       count++;
557     }
558
559     if (count > 1) {
560       // i, r point to last item
561       if (is_write)
562         emith_ctx_write_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
563       else
564         emith_ctx_read_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
565     } else {
566       if (is_write)
567         emith_ctx_write(r, i * 4);
568       else
569         emith_ctx_read(r, i * 4);
570     }
571   }
572 }
573
574 static void sh2_generate_utils(void)
575 {
576   int ctx, blk, tmp;
577
578   host_arg2reg(blk, 0);
579   host_arg2reg(ctx, 1);
580   host_arg2reg(tmp, 2);
581
582   // sh2_drc_entry(void *block, SH2 *sh2)
583   sh2_drc_entry = (void *)tcache_ptr;
584   emith_sh2_drc_entry();
585   emith_move_r_r(CONTEXT_REG, ctx); // move ctx, arg1
586   emit_do_static_regs(0, tmp);
587   emith_jump_reg(blk); // jump arg0
588
589   // sh2_drc_exit(void)
590   sh2_drc_exit = (void *)tcache_ptr;
591   emit_do_static_regs(1, tmp);
592   emith_sh2_drc_exit();
593
594   rcache_invalidate();
595 }
596
597 #define DELAYED_OP \
598   delayed_op = 2
599
600 #define CHECK_UNHANDLED_BITS(mask) { \
601   if ((op & (mask)) != 0) \
602     goto default_; \
603 }
604
605 #define GET_Fx() \
606   ((op >> 4) & 0x0f)
607
608 #define GET_Rm GET_Fx
609
610 #define GET_Rn() \
611   ((op >> 8) & 0x0f)
612
613 #define CHECK_FX_LT(n) \
614   if (GET_Fx() >= n) \
615     goto default_
616
617 static void *sh2_translate(SH2 *sh2, block_desc *other_block)
618 {
619   void *block_entry;
620   block_desc *this_block;
621   unsigned int pc = sh2->pc;
622   int op, delayed_op = 0, test_irq = 0;
623   int tcache_id = 0, blkid = 0;
624   int cycles = 0;
625   u32 tmp, tmp2, tmp3, tmp4, sr;
626
627   // validate PC
628   tmp = sh2->pc >> 29;
629   if ((tmp != 0 && tmp != 1 && tmp != 6) || sh2->pc == 0) {
630     printf("invalid PC, aborting: %08x\n", sh2->pc);
631     // FIXME: be less destructive
632     exit(1);
633   }
634
635   if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
636     // data_array, BIOS have separate tcache (shared)
637     tcache_id = 1 + sh2->is_slave;
638   }
639
640   tcache_ptr = tcache_ptrs[tcache_id];
641   this_block = dr_add_block(pc, tcache_id, &blkid);
642
643   tmp = tcache_ptr - tcache_bases[tcache_id];
644   if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE || this_block == NULL) {
645     flush_tcache(tcache_id);
646     tcache_ptr = tcache_ptrs[tcache_id];
647     other_block = NULL; // also gone too due to flush
648     this_block = dr_add_block(pc, tcache_id, &blkid);
649   }
650
651   this_block->next = other_block;
652   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
653     HASH_FUNC(hash_table, pc) = this_block;
654
655   block_entry = tcache_ptr;
656 #if (DRC_DEBUG & 1)
657   printf("== %csh2 block #%d,%d %08x -> %p\n", sh2->is_slave ? 's' : 'm',
658     tcache_id, block_counts[tcache_id], pc, block_entry);
659   if (other_block != NULL) {
660     printf(" hash collision with %08x\n", other_block->addr);
661     hash_collisions++;
662   }
663 #endif
664
665   while (cycles < BLOCK_CYCLE_LIMIT || delayed_op)
666   {
667     if (delayed_op > 0)
668       delayed_op--;
669
670     op = p32x_sh2_read16(pc, sh2);
671
672 #if (DRC_DEBUG & 3)
673     insns_compiled++;
674 #if (DRC_DEBUG & 2)
675     DasmSH2(sh2dasm_buff, pc, op);
676     printf("%08x %04x %s\n", pc, op, sh2dasm_buff);
677 #endif
678 #endif
679
680     pc += 2;
681     cycles++;
682
683     switch ((op >> 12) & 0x0f)
684     {
685     /////////////////////////////////////////////
686     case 0x00:
687       switch (op & 0x0f)
688       {
689       case 0x02:
690         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
691         switch (GET_Fx())
692         {
693         case 0: // STC SR,Rn  0000nnnn00000010
694           tmp2 = SHR_SR;
695           break;
696         case 1: // STC GBR,Rn 0000nnnn00010010
697           tmp2 = SHR_GBR;
698           break;
699         case 2: // STC VBR,Rn 0000nnnn00100010
700           tmp2 = SHR_VBR;
701           break;
702         default:
703           goto default_;
704         }
705         tmp3 = rcache_get_reg(tmp2, RC_GR_READ);
706         emith_move_r_r(tmp, tmp3);
707         if (tmp2 == SHR_SR)
708           emith_clear_msb(tmp, tmp, 20); // reserved bits defined by ISA as 0
709         goto end_op;
710       case 0x03:
711         CHECK_UNHANDLED_BITS(0xd0);
712         // BRAF Rm    0000mmmm00100011
713         // BSRF Rm    0000mmmm00000011
714         DELAYED_OP;
715         if (!(op & 0x20))
716           emit_move_r_imm32(SHR_PR, pc + 2);
717         tmp = rcache_get_reg(SHR_PPC, RC_GR_WRITE);
718         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
719         emith_move_r_r(tmp, tmp2);
720         emith_add_r_imm(tmp, pc + 2);
721         cycles++;
722         goto end_op;
723       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
724       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
725       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
726         tmp = rcache_get_reg(GET_Rm(), RC_GR_READ);
727         emit_indirect_indexed_write(tmp, SHR_R0, GET_Rn(), op & 3);
728         goto end_op;
729       case 0x07:
730         // MUL.L     Rm,Rn      0000nnnnmmmm0111
731         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
732         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
733         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
734         emith_mul(tmp3, tmp2, tmp);
735         cycles++;
736         goto end_op;
737       case 0x08:
738         CHECK_UNHANDLED_BITS(0xf00);
739         switch (GET_Fx())
740         {
741         case 0: // CLRT               0000000000001000
742           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
743           emith_bic_r_imm(sr, T);
744           break;
745         case 1: // SETT               0000000000011000
746           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
747           emith_or_r_imm(sr, T);
748           break;
749         case 2: // CLRMAC             0000000000101000
750           tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
751           emith_move_r_imm(tmp, 0);
752           tmp = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
753           emith_move_r_imm(tmp, 0);
754           break;
755         default:
756           goto default_;
757         }
758         goto end_op;
759       case 0x09:
760         switch (GET_Fx())
761         {
762         case 0: // NOP        0000000000001001
763           CHECK_UNHANDLED_BITS(0xf00);
764           break;
765         case 1: // DIV0U      0000000000011001
766           CHECK_UNHANDLED_BITS(0xf00);
767           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
768           emith_bic_r_imm(sr, M|Q|T);
769           break;
770         case 2: // MOVT Rn    0000nnnn00101001
771           sr   = rcache_get_reg(SHR_SR, RC_GR_READ);
772           tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
773           emith_clear_msb(tmp2, sr, 31);
774           break;
775         default:
776           goto default_;
777         }
778         goto end_op;
779       case 0x0a:
780         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
781         switch (GET_Fx())
782         {
783         case 0: // STS      MACH,Rn   0000nnnn00001010
784           tmp2 = SHR_MACH;
785           break;
786         case 1: // STS      MACL,Rn   0000nnnn00011010
787           tmp2 = SHR_MACL;
788           break;
789         case 2: // STS      PR,Rn     0000nnnn00101010
790           tmp2 = SHR_PR;
791           break;
792         default:
793           goto default_;
794         }
795         tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
796         emith_move_r_r(tmp, tmp2);
797         goto end_op;
798       case 0x0b:
799         CHECK_UNHANDLED_BITS(0xf00);
800         switch (GET_Fx())
801         {
802         case 0: // RTS        0000000000001011
803           DELAYED_OP;
804           emit_move_r_r(SHR_PPC, SHR_PR);
805           cycles++;
806           break;
807         case 1: // SLEEP      0000000000011011
808           emit_move_r_imm32(SHR_PC, pc - 2);
809           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
810           emith_clear_msb(tmp, tmp, 20); // clear cycles
811           test_irq = 1;
812           cycles = 1;
813           break;
814         case 2: // RTE        0000000000101011
815           DELAYED_OP;
816           rcache_clean();
817           // pop PC
818           rcache_get_reg_arg(0, SHR_SP);
819           tmp = emit_memhandler_read(2);
820           tmp2 = rcache_get_reg(SHR_PPC, RC_GR_WRITE);
821           emith_move_r_r(tmp2, tmp);
822           rcache_free_tmp(tmp);
823           rcache_clean();
824           // pop SR
825           tmp = rcache_get_reg_arg(0, SHR_SP);
826           emith_add_r_imm(tmp, 4);
827           tmp = emit_memhandler_read(2);
828           emith_write_sr(tmp);
829           rcache_free_tmp(tmp);
830           tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
831           emith_add_r_imm(tmp, 4*2);
832           test_irq = 1;
833           cycles += 3;
834           break;
835         default:
836           goto default_;
837         }
838         goto end_op;
839       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
840       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
841       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
842         tmp = emit_indirect_indexed_read(SHR_R0, GET_Rm(), op & 3);
843         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
844         if ((op & 3) != 2) {
845           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
846         } else
847           emith_move_r_r(tmp2, tmp);
848         rcache_free_tmp(tmp);
849         goto end_op;
850       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
851         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2);
852         sr   = rcache_get_reg(SHR_SR, RC_GR_READ);
853         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
854         /* MS 16 MAC bits unused if saturated */
855         emith_tst_r_imm(sr, S);
856         EMITH_SJMP_START(DCOND_EQ);
857         emith_clear_msb_c(DCOND_NE, tmp4, tmp4, 16);
858         EMITH_SJMP_END(DCOND_EQ);
859         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); // might evict SR
860         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
861         rcache_free_tmp(tmp2);
862         sr = rcache_get_reg(SHR_SR, RC_GR_READ); // reget just in case
863         emith_tst_r_imm(sr, S);
864
865         EMITH_JMP_START(DCOND_EQ);
866         emith_asr(tmp, tmp4, 15);
867         emith_cmp_r_imm(tmp, -1); // negative overflow (0x80000000..0xffff7fff)
868         EMITH_SJMP_START(DCOND_GE);
869         emith_move_r_imm_c(DCOND_LT, tmp4, 0x8000);
870         emith_move_r_imm_c(DCOND_LT, tmp3, 0x0000);
871         EMITH_SJMP_END(DCOND_GE);
872         emith_cmp_r_imm(tmp, 0); // positive overflow (0x00008000..0x7fffffff)
873         EMITH_SJMP_START(DCOND_LE);
874         emith_move_r_imm_c(DCOND_GT, tmp4, 0x00007fff);
875         emith_move_r_imm_c(DCOND_GT, tmp3, 0xffffffff);
876         EMITH_SJMP_END(DCOND_LE);
877         EMITH_JMP_END(DCOND_EQ);
878
879         rcache_free_tmp(tmp);
880         cycles += 3;
881         goto end_op;
882       }
883       goto default_;
884
885     /////////////////////////////////////////////
886     case 0x01:
887       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
888       rcache_clean();
889       tmp  = rcache_get_reg_arg(0, GET_Rn());
890       tmp2 = rcache_get_reg_arg(1, GET_Rm());
891       emith_add_r_imm(tmp, (op & 0x0f) * 4);
892       emit_memhandler_write(2);
893       goto end_op;
894
895     case 0x02:
896       switch (op & 0x0f)
897       {
898       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
899       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
900       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
901         rcache_clean();
902         rcache_get_reg_arg(0, GET_Rn());
903         rcache_get_reg_arg(1, GET_Rm());
904         emit_memhandler_write(op & 3);
905         goto end_op;
906       case 0x04: // MOV.B Rm,@–Rn       0010nnnnmmmm0100
907       case 0x05: // MOV.W Rm,@–Rn       0010nnnnmmmm0101
908       case 0x06: // MOV.L Rm,@–Rn       0010nnnnmmmm0110
909         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
910         emith_sub_r_imm(tmp, (1 << (op & 3)));
911         rcache_clean();
912         rcache_get_reg_arg(0, GET_Rn());
913         rcache_get_reg_arg(1, GET_Rm());
914         emit_memhandler_write(op & 3);
915         goto end_op;
916       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
917         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
918         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
919         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
920         emith_bic_r_imm(sr, M|Q|T);
921         emith_tst_r_imm(tmp2, (1<<31));
922         EMITH_SJMP_START(DCOND_EQ);
923         emith_or_r_imm_c(DCOND_NE, sr, Q);
924         EMITH_SJMP_END(DCOND_EQ);
925         emith_tst_r_imm(tmp3, (1<<31));
926         EMITH_SJMP_START(DCOND_EQ);
927         emith_or_r_imm_c(DCOND_NE, sr, M);
928         EMITH_SJMP_END(DCOND_EQ);
929         emith_teq_r_r(tmp2, tmp3);
930         EMITH_SJMP_START(DCOND_PL);
931         emith_or_r_imm_c(DCOND_MI, sr, T);
932         EMITH_SJMP_END(DCOND_PL);
933         goto end_op;
934       case 0x08: // TST Rm,Rn           0010nnnnmmmm1000
935         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
936         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
937         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
938         emith_bic_r_imm(sr, T);
939         emith_tst_r_r(tmp2, tmp3);
940         emit_or_t_if_eq(sr);
941         goto end_op;
942       case 0x09: // AND Rm,Rn           0010nnnnmmmm1001
943         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
944         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
945         emith_and_r_r(tmp, tmp2);
946         goto end_op;
947       case 0x0a: // XOR Rm,Rn           0010nnnnmmmm1010
948         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
949         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
950         emith_eor_r_r(tmp, tmp2);
951         goto end_op;
952       case 0x0b: // OR  Rm,Rn           0010nnnnmmmm1011
953         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
954         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
955         emith_or_r_r(tmp, tmp2);
956         goto end_op;
957       case 0x0c: // CMP/STR Rm,Rn       0010nnnnmmmm1100
958         tmp  = rcache_get_tmp();
959         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
960         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
961         emith_eor_r_r_r(tmp, tmp2, tmp3);
962         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
963         emith_bic_r_imm(sr, T);
964         emith_tst_r_imm(tmp, 0x000000ff);
965         emit_or_t_if_eq(tmp);
966         emith_tst_r_imm(tmp, 0x0000ff00);
967         emit_or_t_if_eq(tmp);
968         emith_tst_r_imm(tmp, 0x00ff0000);
969         emit_or_t_if_eq(tmp);
970         emith_tst_r_imm(tmp, 0xff000000);
971         emit_or_t_if_eq(tmp);
972         rcache_free_tmp(tmp);
973         goto end_op;
974       case 0x0d: // XTRCT  Rm,Rn        0010nnnnmmmm1101
975         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
976         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
977         emith_lsr(tmp, tmp, 16);
978         emith_or_r_r_lsl(tmp, tmp2, 16);
979         goto end_op;
980       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
981       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
982         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
983         tmp  = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
984         if (op & 1) {
985           emith_sext(tmp, tmp2, 16);
986         } else
987           emith_clear_msb(tmp, tmp2, 16);
988         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
989         tmp2 = rcache_get_tmp();
990         if (op & 1) {
991           emith_sext(tmp2, tmp3, 16);
992         } else
993           emith_clear_msb(tmp2, tmp3, 16);
994         emith_mul(tmp, tmp, tmp2);
995         rcache_free_tmp(tmp2);
996 //      FIXME: causes timing issues in Doom?
997 //        cycles++;
998         goto end_op;
999       }
1000       goto default_;
1001
1002     /////////////////////////////////////////////
1003     case 0x03:
1004       switch (op & 0x0f)
1005       {
1006       case 0x00: // CMP/EQ Rm,Rn        0011nnnnmmmm0000
1007       case 0x02: // CMP/HS Rm,Rn        0011nnnnmmmm0010
1008       case 0x03: // CMP/GE Rm,Rn        0011nnnnmmmm0011
1009       case 0x06: // CMP/HI Rm,Rn        0011nnnnmmmm0110
1010       case 0x07: // CMP/GT Rm,Rn        0011nnnnmmmm0111
1011         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1012         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1013         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1014         emith_bic_r_imm(sr, T);
1015         emith_cmp_r_r(tmp2, tmp3);
1016         switch (op & 0x07)
1017         {
1018         case 0x00: // CMP/EQ
1019           emit_or_t_if_eq(sr);
1020           break;
1021         case 0x02: // CMP/HS
1022           EMITH_SJMP_START(DCOND_LO);
1023           emith_or_r_imm_c(DCOND_HS, sr, T);
1024           EMITH_SJMP_END(DCOND_LO);
1025           break;
1026         case 0x03: // CMP/GE
1027           EMITH_SJMP_START(DCOND_LT);
1028           emith_or_r_imm_c(DCOND_GE, sr, T);
1029           EMITH_SJMP_END(DCOND_LT);
1030           break;
1031         case 0x06: // CMP/HI
1032           EMITH_SJMP_START(DCOND_LS);
1033           emith_or_r_imm_c(DCOND_HI, sr, T);
1034           EMITH_SJMP_END(DCOND_LS);
1035           break;
1036         case 0x07: // CMP/GT
1037           EMITH_SJMP_START(DCOND_LE);
1038           emith_or_r_imm_c(DCOND_GT, sr, T);
1039           EMITH_SJMP_END(DCOND_LE);
1040           break;
1041         }
1042         goto end_op;
1043       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
1044         // Q1 = carry(Rn = (Rn << 1) | T)
1045         // if Q ^ M
1046         //   Q2 = carry(Rn += Rm)
1047         // else
1048         //   Q2 = carry(Rn -= Rm)
1049         // Q = M ^ Q1 ^ Q2
1050         // T = (Q == M) = !(Q ^ M) = !(Q1 ^ Q2)
1051         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1052         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1053         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1054         emith_tpop_carry(sr, 0);
1055         emith_adcf_r_r(tmp2, tmp2);
1056         emith_tpush_carry(sr, 0);            // keep Q1 in T for now
1057         tmp4 = rcache_get_tmp();
1058         emith_and_r_r_imm(tmp4, sr, M);
1059         emith_eor_r_r_lsr(sr, tmp4, M_SHIFT - Q_SHIFT); // Q ^= M
1060         rcache_free_tmp(tmp4);
1061         // add or sub, invert T if carry to get Q1 ^ Q2
1062         // in: (Q ^ M) passed in Q, Q1 in T
1063         emith_sh2_div1_step(tmp2, tmp3, sr);
1064         emith_bic_r_imm(sr, Q);
1065         emith_tst_r_imm(sr, M);
1066         EMITH_SJMP_START(DCOND_EQ);
1067         emith_or_r_imm_c(DCOND_NE, sr, Q);  // Q = M
1068         EMITH_SJMP_END(DCOND_EQ);
1069         emith_tst_r_imm(sr, T);
1070         EMITH_SJMP_START(DCOND_EQ);
1071         emith_eor_r_imm_c(DCOND_NE, sr, Q); // Q = M ^ Q1 ^ Q2
1072         EMITH_SJMP_END(DCOND_EQ);
1073         emith_eor_r_imm(sr, T);             // T = !(Q1 ^ Q2)
1074         goto end_op;
1075       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
1076         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1077         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1078         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1079         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1080         emith_mul_u64(tmp3, tmp4, tmp, tmp2);
1081         goto end_op;
1082       case 0x08: // SUB     Rm,Rn       0011nnnnmmmm1000
1083       case 0x0c: // ADD     Rm,Rn       0011nnnnmmmm1100
1084         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1085         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1086         if (op & 4) {
1087           emith_add_r_r(tmp, tmp2);
1088         } else
1089           emith_sub_r_r(tmp, tmp2);
1090         goto end_op;
1091       case 0x0a: // SUBC    Rm,Rn       0011nnnnmmmm1010
1092       case 0x0e: // ADDC    Rm,Rn       0011nnnnmmmm1110
1093         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1094         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1095         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1096         if (op & 4) { // adc
1097           emith_tpop_carry(sr, 0);
1098           emith_adcf_r_r(tmp, tmp2);
1099           emith_tpush_carry(sr, 0);
1100         } else {
1101           emith_tpop_carry(sr, 1);
1102           emith_sbcf_r_r(tmp, tmp2);
1103           emith_tpush_carry(sr, 1);
1104         }
1105         goto end_op;
1106       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
1107       case 0x0f: // ADDV    Rm,Rn       0011nnnnmmmm1111
1108         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1109         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1110         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1111         emith_bic_r_imm(sr, T);
1112         if (op & 4) {
1113           emith_addf_r_r(tmp, tmp2);
1114         } else
1115           emith_subf_r_r(tmp, tmp2);
1116         EMITH_SJMP_START(DCOND_VC);
1117         emith_or_r_imm_c(DCOND_VS, sr, T);
1118         EMITH_SJMP_END(DCOND_VC);
1119         goto end_op;
1120       case 0x0d: // DMULS.L Rm,Rn       0011nnnnmmmm1101
1121         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1122         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1123         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1124         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1125         emith_mul_s64(tmp3, tmp4, tmp, tmp2);
1126         goto end_op;
1127       }
1128       goto default_;
1129
1130     /////////////////////////////////////////////
1131     case 0x04:
1132       switch (op & 0x0f)
1133       {
1134       case 0x00:
1135         switch (GET_Fx())
1136         {
1137         case 0: // SHLL Rn    0100nnnn00000000
1138         case 2: // SHAL Rn    0100nnnn00100000
1139           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1140           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1141           emith_tpop_carry(sr, 0); // dummy
1142           emith_lslf(tmp, tmp, 1);
1143           emith_tpush_carry(sr, 0);
1144           goto end_op;
1145         case 1: // DT Rn      0100nnnn00010000
1146           if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2
1147             emith_sh2_dtbf_loop();
1148             goto end_op;
1149           }
1150           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1151           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1152           emith_bic_r_imm(sr, T);
1153           emith_subf_r_imm(tmp, 1);
1154           emit_or_t_if_eq(sr);
1155           goto end_op;
1156         }
1157         goto default_;
1158       case 0x01:
1159         switch (GET_Fx())
1160         {
1161         case 0: // SHLR Rn    0100nnnn00000001
1162         case 2: // SHAR Rn    0100nnnn00100001
1163           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1164           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1165           emith_tpop_carry(sr, 0); // dummy
1166           if (op & 0x20) {
1167             emith_asrf(tmp, tmp, 1);
1168           } else
1169             emith_lsrf(tmp, tmp, 1);
1170           emith_tpush_carry(sr, 0);
1171           goto end_op;
1172         case 1: // CMP/PZ Rn  0100nnnn00010001
1173           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1174           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1175           emith_bic_r_imm(sr, T);
1176           emith_cmp_r_imm(tmp, 0);
1177           EMITH_SJMP_START(DCOND_LT);
1178           emith_or_r_imm_c(DCOND_GE, sr, T);
1179           EMITH_SJMP_END(DCOND_LT);
1180           goto end_op;
1181         }
1182         goto default_;
1183       case 0x02:
1184       case 0x03:
1185         switch (op & 0x3f)
1186         {
1187         case 0x02: // STS.L    MACH,@–Rn 0100nnnn00000010
1188           tmp = SHR_MACH;
1189           break;
1190         case 0x12: // STS.L    MACL,@–Rn 0100nnnn00010010
1191           tmp = SHR_MACL;
1192           break;
1193         case 0x22: // STS.L    PR,@–Rn   0100nnnn00100010
1194           tmp = SHR_PR;
1195           break;
1196         case 0x03: // STC.L    SR,@–Rn   0100nnnn00000011
1197           tmp = SHR_SR;
1198           break;
1199         case 0x13: // STC.L    GBR,@–Rn  0100nnnn00010011
1200           tmp = SHR_GBR;
1201           break;
1202         case 0x23: // STC.L    VBR,@–Rn  0100nnnn00100011
1203           tmp = SHR_VBR;
1204           break;
1205         default:
1206           goto default_;
1207         }
1208         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1209         emith_sub_r_imm(tmp2, 4);
1210         rcache_clean();
1211         rcache_get_reg_arg(0, GET_Rn());
1212         tmp3 = rcache_get_reg_arg(1, tmp);
1213         if (tmp == SHR_SR)
1214           emith_clear_msb(tmp3, tmp3, 20); // reserved bits defined by ISA as 0
1215         emit_memhandler_write(2);
1216         goto end_op;
1217       case 0x04:
1218       case 0x05:
1219         switch (op & 0x3f)
1220         {
1221         case 0x04: // ROTL   Rn          0100nnnn00000100
1222         case 0x05: // ROTR   Rn          0100nnnn00000101
1223           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1224           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1225           emith_tpop_carry(sr, 0); // dummy
1226           if (op & 1) {
1227             emith_rorf(tmp, tmp, 1);
1228           } else
1229             emith_rolf(tmp, tmp, 1);
1230           emith_tpush_carry(sr, 0);
1231           goto end_op;
1232         case 0x24: // ROTCL  Rn          0100nnnn00100100
1233         case 0x25: // ROTCR  Rn          0100nnnn00100101
1234           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1235           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1236           emith_tpop_carry(sr, 0);
1237           if (op & 1) {
1238             emith_rorcf(tmp);
1239           } else
1240             emith_rolcf(tmp);
1241           emith_tpush_carry(sr, 0);
1242           goto end_op;
1243         case 0x15: // CMP/PL Rn          0100nnnn00010101
1244           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1245           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1246           emith_bic_r_imm(sr, T);
1247           emith_cmp_r_imm(tmp, 0);
1248           EMITH_SJMP_START(DCOND_LE);
1249           emith_or_r_imm_c(DCOND_GT, sr, T);
1250           EMITH_SJMP_END(DCOND_LE);
1251           goto end_op;
1252         }
1253         goto default_;
1254       case 0x06:
1255       case 0x07:
1256         switch (op & 0x3f)
1257         {
1258         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
1259           tmp = SHR_MACH;
1260           break;
1261         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
1262           tmp = SHR_MACL;
1263           break;
1264         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
1265           tmp = SHR_PR;
1266           break;
1267         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
1268           tmp = SHR_SR;
1269           break;
1270         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
1271           tmp = SHR_GBR;
1272           break;
1273         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
1274           tmp = SHR_VBR;
1275           break;
1276         default:
1277           goto default_;
1278         }
1279         rcache_clean();
1280         rcache_get_reg_arg(0, GET_Rn());
1281         tmp2 = emit_memhandler_read(2);
1282         if (tmp == SHR_SR) {
1283           emith_write_sr(tmp2);
1284           test_irq = 1;
1285         } else {
1286           tmp = rcache_get_reg(tmp, RC_GR_WRITE);
1287           emith_move_r_r(tmp, tmp2);
1288         }
1289         rcache_free_tmp(tmp2);
1290         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1291         emith_add_r_imm(tmp, 4);
1292         goto end_op;
1293       case 0x08:
1294       case 0x09:
1295         switch (GET_Fx())
1296         {
1297         case 0:
1298           // SHLL2 Rn        0100nnnn00001000
1299           // SHLR2 Rn        0100nnnn00001001
1300           tmp = 2;
1301           break;
1302         case 1:
1303           // SHLL8 Rn        0100nnnn00011000
1304           // SHLR8 Rn        0100nnnn00011001
1305           tmp = 8;
1306           break;
1307         case 2:
1308           // SHLL16 Rn       0100nnnn00101000
1309           // SHLR16 Rn       0100nnnn00101001
1310           tmp = 16;
1311           break;
1312         default:
1313           goto default_;
1314         }
1315         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1316         if (op & 1) {
1317           emith_lsr(tmp2, tmp2, tmp);
1318         } else
1319           emith_lsl(tmp2, tmp2, tmp);
1320         goto end_op;
1321       case 0x0a:
1322         switch (GET_Fx())
1323         {
1324         case 0: // LDS      Rm,MACH   0100mmmm00001010
1325           tmp2 = SHR_MACH;
1326           break;
1327         case 1: // LDS      Rm,MACL   0100mmmm00011010
1328           tmp2 = SHR_MACL;
1329           break;
1330         case 2: // LDS      Rm,PR     0100mmmm00101010
1331           tmp2 = SHR_PR;
1332           break;
1333         default:
1334           goto default_;
1335         }
1336         emit_move_r_r(tmp2, GET_Rn());
1337         goto end_op;
1338       case 0x0b:
1339         switch (GET_Fx())
1340         {
1341         case 0: // JSR  @Rm   0100mmmm00001011
1342         case 2: // JMP  @Rm   0100mmmm00101011
1343           DELAYED_OP;
1344           if (!(op & 0x20))
1345             emit_move_r_imm32(SHR_PR, pc + 2);
1346           emit_move_r_r(SHR_PPC, (op >> 8) & 0x0f);
1347           cycles++;
1348           break;
1349         case 1: // TAS.B @Rn  0100nnnn00011011
1350           // XXX: is TAS working on 32X?
1351           rcache_clean();
1352           rcache_get_reg_arg(0, GET_Rn());
1353           tmp = emit_memhandler_read(0);
1354           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1355           emith_bic_r_imm(sr, T);
1356           emith_cmp_r_imm(tmp, 0);
1357           emit_or_t_if_eq(sr);
1358           rcache_clean();
1359           emith_or_r_imm(tmp, 0x80);
1360           tmp2 = rcache_get_tmp_arg(1); // assuming it differs to tmp
1361           emith_move_r_r(tmp2, tmp);
1362           rcache_free_tmp(tmp);
1363           rcache_get_reg_arg(0, GET_Rn());
1364           emit_memhandler_write(0);
1365           cycles += 3;
1366           break;
1367         default:
1368           goto default_;
1369         }
1370         goto end_op;
1371       case 0x0e:
1372         tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
1373         switch (GET_Fx())
1374         {
1375         case 0: // LDC Rm,SR   0100mmmm00001110
1376           tmp2 = SHR_SR;
1377           break;
1378         case 1: // LDC Rm,GBR  0100mmmm00011110
1379           tmp2 = SHR_GBR;
1380           break;
1381         case 2: // LDC Rm,VBR  0100mmmm00101110
1382           tmp2 = SHR_VBR;
1383           break;
1384         default:
1385           goto default_;
1386         }
1387         if (tmp2 == SHR_SR) {
1388           emith_write_sr(tmp);
1389           test_irq = 1;
1390         } else {
1391           tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE);
1392           emith_move_r_r(tmp2, tmp);
1393         }
1394         goto end_op;
1395       case 0x0f:
1396         // MAC @Rm+,@Rn+  0100nnnnmmmm1111
1397         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1);
1398         emith_sext(tmp, tmp, 16);
1399         emith_sext(tmp2, tmp2, 16);
1400         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW);
1401         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
1402         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
1403         rcache_free_tmp(tmp2);
1404         // XXX: MACH should be untouched when S is set?
1405         sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1406         emith_tst_r_imm(sr, S);
1407         EMITH_JMP_START(DCOND_EQ);
1408
1409         emith_asr(tmp, tmp3, 31);
1410         emith_eorf_r_r(tmp, tmp4); // tmp = ((signed)macl >> 31) ^ mach
1411         EMITH_JMP_START(DCOND_EQ);
1412         emith_move_r_imm(tmp3, 0x80000000);
1413         emith_tst_r_r(tmp4, tmp4);
1414         EMITH_SJMP_START(DCOND_MI);
1415         emith_sub_r_imm_c(DCOND_PL, tmp3, 1); // positive
1416         EMITH_SJMP_END(DCOND_MI);
1417         EMITH_JMP_END(DCOND_EQ);
1418
1419         EMITH_JMP_END(DCOND_EQ);
1420         rcache_free_tmp(tmp);
1421         cycles += 2;
1422         goto end_op;
1423       }
1424       goto default_;
1425
1426     /////////////////////////////////////////////
1427     case 0x05:
1428       // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
1429       rcache_clean();
1430       tmp = rcache_get_reg_arg(0, GET_Rm());
1431       emith_add_r_imm(tmp, (op & 0x0f) * 4);
1432       tmp = emit_memhandler_read(2);
1433       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1434       emith_move_r_r(tmp2, tmp);
1435       rcache_free_tmp(tmp);
1436       goto end_op;
1437
1438     /////////////////////////////////////////////
1439     case 0x06:
1440       switch (op & 0x0f)
1441       {
1442       case 0x00: // MOV.B @Rm,Rn        0110nnnnmmmm0000
1443       case 0x01: // MOV.W @Rm,Rn        0110nnnnmmmm0001
1444       case 0x02: // MOV.L @Rm,Rn        0110nnnnmmmm0010
1445       case 0x04: // MOV.B @Rm+,Rn       0110nnnnmmmm0100
1446       case 0x05: // MOV.W @Rm+,Rn       0110nnnnmmmm0101
1447       case 0x06: // MOV.L @Rm+,Rn       0110nnnnmmmm0110
1448         rcache_clean();
1449         rcache_get_reg_arg(0, GET_Rm());
1450         tmp  = emit_memhandler_read(op & 3);
1451         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1452         if ((op & 3) != 2) {
1453           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
1454         } else
1455           emith_move_r_r(tmp2, tmp);
1456         rcache_free_tmp(tmp);
1457         if ((op & 7) >= 4 && GET_Rn() != GET_Rm()) {
1458           tmp = rcache_get_reg(GET_Rm(), RC_GR_RMW);
1459           emith_add_r_imm(tmp, (1 << (op & 3)));
1460         }
1461         goto end_op;
1462       case 0x03:
1463       case 0x07 ... 0x0f:
1464         tmp  = rcache_get_reg(GET_Rm(), RC_GR_READ);
1465         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1466         switch (op & 0x0f)
1467         {
1468         case 0x03: // MOV    Rm,Rn        0110nnnnmmmm0011
1469           emith_move_r_r(tmp2, tmp);
1470           break;
1471         case 0x07: // NOT    Rm,Rn        0110nnnnmmmm0111
1472           emith_mvn_r_r(tmp2, tmp);
1473           break;
1474         case 0x08: // SWAP.B Rm,Rn        0110nnnnmmmm1000
1475           tmp3 = tmp2;
1476           if (tmp == tmp2)
1477             tmp3 = rcache_get_tmp();
1478           tmp4 = rcache_get_tmp();
1479           emith_lsr(tmp3, tmp, 16);
1480           emith_or_r_r_lsl(tmp3, tmp, 24);
1481           emith_and_r_r_imm(tmp4, tmp, 0xff00);
1482           emith_or_r_r_lsl(tmp3, tmp4, 8);
1483           emith_rol(tmp2, tmp3, 16);
1484           rcache_free_tmp(tmp4);
1485           if (tmp == tmp2)
1486             rcache_free_tmp(tmp3);
1487           break;
1488         case 0x09: // SWAP.W Rm,Rn        0110nnnnmmmm1001
1489           emith_rol(tmp2, tmp, 16);
1490           break;
1491         case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
1492           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1493           emith_tpop_carry(sr, 1);
1494           emith_negcf_r_r(tmp2, tmp);
1495           emith_tpush_carry(sr, 1);
1496           break;
1497         case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
1498           emith_neg_r_r(tmp2, tmp);
1499           break;
1500         case 0x0c: // EXTU.B Rm,Rn        0110nnnnmmmm1100
1501           emith_clear_msb(tmp2, tmp, 24);
1502           break;
1503         case 0x0d: // EXTU.W Rm,Rn        0110nnnnmmmm1101
1504           emith_clear_msb(tmp2, tmp, 16);
1505           break;
1506         case 0x0e: // EXTS.B Rm,Rn        0110nnnnmmmm1110
1507           emith_sext(tmp2, tmp, 8);
1508           break;
1509         case 0x0f: // EXTS.W Rm,Rn        0110nnnnmmmm1111
1510           emith_sext(tmp2, tmp, 16);
1511           break;
1512         }
1513         goto end_op;
1514       }
1515       goto default_;
1516
1517     /////////////////////////////////////////////
1518     case 0x07:
1519       // ADD #imm,Rn  0111nnnniiiiiiii
1520       tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1521       if (op & 0x80) { // adding negative
1522         emith_sub_r_imm(tmp, -op & 0xff);
1523       } else
1524         emith_add_r_imm(tmp, op & 0xff);
1525       goto end_op;
1526
1527     /////////////////////////////////////////////
1528     case 0x08:
1529       switch (op & 0x0f00)
1530       {
1531       case 0x0000: // MOV.B R0,@(disp,Rn)  10000000nnnndddd
1532       case 0x0100: // MOV.W R0,@(disp,Rn)  10000001nnnndddd
1533         rcache_clean();
1534         tmp  = rcache_get_reg_arg(0, GET_Rm());
1535         tmp2 = rcache_get_reg_arg(1, SHR_R0);
1536         tmp3 = (op & 0x100) >> 8;
1537         emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
1538         emit_memhandler_write(tmp3);
1539         goto end_op;
1540       case 0x0400: // MOV.B @(disp,Rm),R0  10000100mmmmdddd
1541       case 0x0500: // MOV.W @(disp,Rm),R0  10000101mmmmdddd
1542         rcache_clean();
1543         tmp  = rcache_get_reg_arg(0, GET_Rm());
1544         tmp3 = (op & 0x100) >> 8;
1545         emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
1546         tmp  = emit_memhandler_read(tmp3);
1547         tmp2 = rcache_get_reg(0, RC_GR_WRITE);
1548         emith_sext(tmp2, tmp, 8 << tmp3);
1549         rcache_free_tmp(tmp);
1550         goto end_op;
1551       case 0x0800: // CMP/EQ #imm,R0       10001000iiiiiiii
1552         // XXX: could use cmn
1553         tmp  = rcache_get_tmp();
1554         tmp2 = rcache_get_reg(0, RC_GR_READ);
1555         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1556         emith_move_r_imm_s8(tmp, op & 0xff);
1557         emith_bic_r_imm(sr, T);
1558         emith_cmp_r_r(tmp2, tmp);
1559         emit_or_t_if_eq(sr);
1560         rcache_free_tmp(tmp);
1561         goto end_op;
1562       case 0x0d00: // BT/S label 10001101dddddddd
1563       case 0x0f00: // BF/S label 10001111dddddddd
1564         DELAYED_OP;
1565         cycles--;
1566         // fallthrough
1567       case 0x0900:   // BT   label 10001001dddddddd
1568       case 0x0b00: { // BF   label 10001011dddddddd
1569         // jmp_cond ~ cond when guest doesn't jump
1570         int jmp_cond  = (op & 0x0200) ? DCOND_NE : DCOND_EQ;
1571         int insn_cond = (op & 0x0200) ? DCOND_EQ : DCOND_NE;
1572         signed int offs = ((signed int)(op << 24) >> 23);
1573         tmp = rcache_get_reg(delayed_op ? SHR_PPC : SHR_PC, RC_GR_WRITE);
1574         emith_move_r_imm(tmp, pc + (delayed_op ? 2 : 0));
1575         emith_sh2_test_t();
1576         EMITH_SJMP_START(jmp_cond);
1577         if (!delayed_op)
1578           offs += 2;
1579         if (offs < 0) {
1580           emith_sub_r_imm_c(insn_cond, tmp, -offs);
1581         } else
1582           emith_add_r_imm_c(insn_cond, tmp, offs);
1583         EMITH_SJMP_END(jmp_cond);
1584         cycles += 2;
1585         if (!delayed_op)
1586           goto end_block_btf;
1587         goto end_op;
1588       }}
1589       goto default_;
1590
1591     /////////////////////////////////////////////
1592     case 0x09:
1593       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
1594       rcache_clean();
1595       tmp = rcache_get_tmp_arg(0);
1596       emith_move_r_imm(tmp, pc + (op & 0xff) * 2 + 2);
1597       tmp  = emit_memhandler_read(1);
1598       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1599       emith_sext(tmp2, tmp, 16);
1600       rcache_free_tmp(tmp);
1601       goto end_op;
1602
1603     /////////////////////////////////////////////
1604     case 0x0a:
1605       // BRA  label 1010dddddddddddd
1606       DELAYED_OP;
1607     do_bra:
1608       tmp = ((signed int)(op << 20) >> 19);
1609       emit_move_r_imm32(SHR_PPC, pc + tmp + 2);
1610       cycles++;
1611       break;
1612
1613     /////////////////////////////////////////////
1614     case 0x0b:
1615       // BSR  label 1011dddddddddddd
1616       DELAYED_OP;
1617       emit_move_r_imm32(SHR_PR, pc + 2);
1618       goto do_bra;
1619
1620     /////////////////////////////////////////////
1621     case 0x0c:
1622       switch (op & 0x0f00)
1623       {
1624       case 0x0000: // MOV.B R0,@(disp,GBR)   11000000dddddddd
1625       case 0x0100: // MOV.W R0,@(disp,GBR)   11000001dddddddd
1626       case 0x0200: // MOV.L R0,@(disp,GBR)   11000010dddddddd
1627         rcache_clean();
1628         tmp  = rcache_get_reg_arg(0, SHR_GBR);
1629         tmp2 = rcache_get_reg_arg(1, SHR_R0);
1630         tmp3 = (op & 0x300) >> 8;
1631         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
1632         emit_memhandler_write(tmp3);
1633         goto end_op;
1634       case 0x0400: // MOV.B @(disp,GBR),R0   11000100dddddddd
1635       case 0x0500: // MOV.W @(disp,GBR),R0   11000101dddddddd
1636       case 0x0600: // MOV.L @(disp,GBR),R0   11000110dddddddd
1637         rcache_clean();
1638         tmp  = rcache_get_reg_arg(0, SHR_GBR);
1639         tmp3 = (op & 0x300) >> 8;
1640         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
1641         tmp  = emit_memhandler_read(tmp3);
1642         tmp2 = rcache_get_reg(0, RC_GR_WRITE);
1643         if (tmp3 != 2) {
1644           emith_sext(tmp2, tmp, 8 << tmp3);
1645         } else
1646           emith_move_r_r(tmp2, tmp);
1647         rcache_free_tmp(tmp);
1648         goto end_op;
1649       case 0x0300: // TRAPA #imm      11000011iiiiiiii
1650         tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
1651         emith_sub_r_imm(tmp, 4*2);
1652         rcache_clean();
1653         // push SR
1654         tmp = rcache_get_reg_arg(0, SHR_SP);
1655         emith_add_r_imm(tmp, 4);
1656         tmp = rcache_get_reg_arg(1, SHR_SR);
1657         emith_clear_msb(tmp, tmp, 20);
1658         emit_memhandler_write(2);
1659         // push PC
1660         rcache_get_reg_arg(0, SHR_SP);
1661         tmp = rcache_get_tmp_arg(1);
1662         emith_move_r_imm(tmp, pc);
1663         emit_memhandler_write(2);
1664         // obtain new PC
1665         tmp = rcache_get_reg_arg(0, SHR_VBR);
1666         emith_add_r_imm(tmp, (op & 0xff) * 4);
1667         tmp  = emit_memhandler_read(2);
1668         tmp2 = rcache_get_reg(SHR_PC, RC_GR_WRITE);
1669         emith_move_r_r(tmp2, tmp);
1670         rcache_free_tmp(tmp);
1671         cycles += 7;
1672         goto end_block_btf;
1673       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
1674         emit_move_r_imm32(SHR_R0, (pc + (op & 0xff) * 4 + 2) & ~3);
1675         goto end_op;
1676       case 0x0800: // TST #imm,R0           11001000iiiiiiii
1677         tmp = rcache_get_reg(SHR_R0, RC_GR_READ);
1678         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1679         emith_bic_r_imm(sr, T);
1680         emith_tst_r_imm(tmp, op & 0xff);
1681         emit_or_t_if_eq(sr);
1682         goto end_op;
1683       case 0x0900: // AND #imm,R0           11001001iiiiiiii
1684         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1685         emith_and_r_imm(tmp, op & 0xff);
1686         goto end_op;
1687       case 0x0a00: // XOR #imm,R0           11001010iiiiiiii
1688         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1689         emith_eor_r_imm(tmp, op & 0xff);
1690         goto end_op;
1691       case 0x0b00: // OR  #imm,R0           11001011iiiiiiii
1692         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1693         emith_or_r_imm(tmp, op & 0xff);
1694         goto end_op;
1695       case 0x0c00: // TST.B #imm,@(R0,GBR)  11001100iiiiiiii
1696         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1697         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1698         emith_bic_r_imm(sr, T);
1699         emith_tst_r_imm(tmp, op & 0xff);
1700         emit_or_t_if_eq(sr);
1701         rcache_free_tmp(tmp);
1702         cycles += 2;
1703         goto end_op;
1704       case 0x0d00: // AND.B #imm,@(R0,GBR)  11001101iiiiiiii
1705         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1706         emith_and_r_imm(tmp, op & 0xff);
1707         goto end_rmw_op;
1708       case 0x0e00: // XOR.B #imm,@(R0,GBR)  11001110iiiiiiii
1709         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1710         emith_eor_r_imm(tmp, op & 0xff);
1711         goto end_rmw_op;
1712       case 0x0f00: // OR.B  #imm,@(R0,GBR)  11001111iiiiiiii
1713         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1714         emith_or_r_imm(tmp, op & 0xff);
1715       end_rmw_op:
1716         tmp2 = rcache_get_tmp_arg(1);
1717         emith_move_r_r(tmp2, tmp);
1718         rcache_free_tmp(tmp);
1719         tmp3 = rcache_get_reg_arg(0, SHR_GBR);
1720         tmp4 = rcache_get_reg(SHR_R0, RC_GR_READ);
1721         emith_add_r_r(tmp3, tmp4);
1722         emit_memhandler_write(0);
1723         cycles += 2;
1724         goto end_op;
1725       }
1726       goto default_;
1727
1728     /////////////////////////////////////////////
1729     case 0x0d:
1730       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
1731       rcache_clean();
1732       tmp = rcache_get_tmp_arg(0);
1733       emith_move_r_imm(tmp, (pc + (op & 0xff) * 4 + 2) & ~3);
1734       tmp  = emit_memhandler_read(2);
1735       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1736       emith_move_r_r(tmp2, tmp);
1737       rcache_free_tmp(tmp);
1738       goto end_op;
1739
1740     /////////////////////////////////////////////
1741     case 0x0e:
1742       // MOV #imm,Rn   1110nnnniiiiiiii
1743       tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1744       emith_move_r_imm_s8(tmp, op & 0xff);
1745       goto end_op;
1746
1747     default:
1748     default_:
1749       elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
1750         sh2->is_slave ? 's' : 'm', op, pc - 2);
1751 #ifdef DRC_DEBUG_INTERP
1752       emit_move_r_imm32(SHR_PC, pc - 2);
1753       rcache_flush();
1754       emith_pass_arg_r(0, CONTEXT_REG);
1755       emith_pass_arg_imm(1, op);
1756       emith_call(sh2_do_op);
1757 #endif
1758       break;
1759     }
1760
1761 end_op:
1762     if (delayed_op == 1)
1763       emit_move_r_r(SHR_PC, SHR_PPC);
1764
1765     if (test_irq && delayed_op != 2) {
1766       if (!delayed_op)
1767         emit_move_r_imm32(SHR_PC, pc);
1768       rcache_flush();
1769       emith_pass_arg_r(0, CONTEXT_REG);
1770       emith_call(sh2_test_irq);
1771       goto end_block_btf;
1772     }
1773     if (delayed_op == 1)
1774       break;
1775
1776     do_host_disasm(tcache_id);
1777   }
1778
1779   // delayed_op means some kind of branch - PC already handled
1780   if (!delayed_op)
1781     emit_move_r_imm32(SHR_PC, pc);
1782
1783 end_block_btf:
1784   this_block->end_addr = pc;
1785
1786   // mark memory blocks as containing compiled code
1787   if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1788     // data array, BIOS
1789     u16 *drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
1790     tmp =  (this_block->addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1791     tmp2 = (this_block->end_addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1792     Pico32xMem->drcblk_da[sh2->is_slave][tmp] = (blkid << 1) | 1;
1793     for (++tmp; tmp < tmp2; tmp++) {
1794       if (drcblk[tmp])
1795         break; // dont overwrite overlay block
1796       drcblk[tmp] = blkid << 1;
1797     }
1798   }
1799   else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
1800     tmp =  (this_block->addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1801     tmp2 = (this_block->end_addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1802     Pico32xMem->drcblk_ram[tmp] = (blkid << 1) | 1;
1803     for (++tmp; tmp < tmp2; tmp++) {
1804       if (Pico32xMem->drcblk_ram[tmp])
1805         break;
1806       Pico32xMem->drcblk_ram[tmp] = blkid << 1;
1807     }
1808   }
1809
1810   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
1811   emith_sub_r_imm(tmp, cycles << 12);
1812   rcache_flush();
1813   emith_jump(sh2_drc_exit);
1814   tcache_ptrs[tcache_id] = tcache_ptr;
1815
1816 #ifdef ARM
1817   cache_flush_d_inval_i(block_entry, tcache_ptr);
1818 #endif
1819
1820   do_host_disasm(tcache_id);
1821   dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
1822     tcache_id, block_counts[tcache_id],
1823     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
1824     insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
1825   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
1826     dbg(1, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
1827 #if (DRC_DEBUG & 2)
1828   fflush(stdout);
1829 #endif
1830
1831   return block_entry;
1832 /*
1833 unimplemented:
1834   // last op
1835   do_host_disasm(tcache_id);
1836   exit(1);
1837 */
1838 }
1839
1840 void __attribute__((noinline)) sh2_drc_dispatcher(SH2 *sh2)
1841 {
1842   // TODO: need to handle self-caused interrupts
1843   sh2_test_irq(sh2);
1844
1845   while (((signed int)sh2->sr >> 12) > 0)
1846   {
1847     void *block = NULL;
1848     block_desc *bd = NULL;
1849
1850     // FIXME: must avoid doing it so often..
1851     //sh2_test_irq(sh2);
1852
1853     // we have full block id tables for data_array and RAM
1854     // BIOS goes to data_array table too
1855     if ((sh2->pc & 0xff000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1856       int blkid = Pico32xMem->drcblk_da[sh2->is_slave][(sh2->pc & 0xfff) >> SH2_DRCBLK_DA_SHIFT];
1857       if (blkid & 1) {
1858         bd = &block_tables[1 + sh2->is_slave][blkid >> 1];
1859         block = bd->tcache_ptr;
1860       }
1861     }
1862     // RAM
1863     else if ((sh2->pc & 0xc6000000) == 0x06000000) {
1864       int blkid = Pico32xMem->drcblk_ram[(sh2->pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT];
1865       if (blkid & 1) {
1866         bd = &block_tables[0][blkid >> 1];
1867         block = bd->tcache_ptr;
1868       }
1869     }
1870     // ROM
1871     else if ((sh2->pc & 0xc6000000) == 0x02000000) {
1872       bd = HASH_FUNC(hash_table, sh2->pc);
1873
1874       if (bd != NULL) {
1875         if (bd->addr == sh2->pc)
1876           block = bd->tcache_ptr;
1877         else
1878           block = dr_find_block(bd, sh2->pc);
1879       }
1880     }
1881
1882     if (block == NULL)
1883       block = sh2_translate(sh2, bd);
1884
1885     dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
1886       sh2->pc, block, (signed int)sh2->sr >> 12);
1887 #if (DRC_DEBUG & 1)
1888     if (bd != NULL)
1889       bd->refcount++;
1890 #endif
1891     sh2_drc_entry(block, sh2);
1892   }
1893 }
1894
1895 static void sh2_smc_rm_block(u16 *drcblk, u16 *p, block_desc *btab, u32 a)
1896 {
1897   u16 id = *p >> 1;
1898   block_desc *bd = btab + id;
1899
1900   dbg(1, "  killing block %08x", bd->addr);
1901   bd->addr = bd->end_addr = 0;
1902
1903   while (p > drcblk && (p[-1] >> 1) == id)
1904     p--;
1905
1906   // check for possible overlay block
1907   if (p > 0 && p[-1] != 0) {
1908     bd = btab + (p[-1] >> 1);
1909     if (bd->addr <= a && a < bd->end_addr)
1910       sh2_smc_rm_block(drcblk, p - 1, btab, a);
1911   }
1912
1913   do {
1914     *p++ = 0;
1915   }
1916   while ((*p >> 1) == id);
1917 }
1918
1919 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
1920 {
1921   u16 *drcblk = Pico32xMem->drcblk_ram;
1922   u16 *p = drcblk + ((a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT);
1923
1924   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1925   sh2_smc_rm_block(drcblk, p, block_tables[0], a);
1926 }
1927
1928 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
1929 {
1930   u16 *drcblk = Pico32xMem->drcblk_da[cpuid];
1931   u16 *p = drcblk + ((a & 0xfff) >> SH2_DRCBLK_DA_SHIFT);
1932
1933   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1934   sh2_smc_rm_block(drcblk, p, block_tables[1 + cpuid], a);
1935 }
1936
1937 void sh2_execute(SH2 *sh2c, int cycles)
1938 {
1939   sh2 = sh2c; // XXX
1940
1941   sh2c->cycles_aim += cycles;
1942   cycles = sh2c->cycles_aim - sh2c->cycles_done;
1943
1944   // cycles are kept in SHR_SR unused bits (upper 20)
1945   sh2c->sr &= 0x3f3;
1946   sh2c->sr |= cycles << 12;
1947   sh2_drc_dispatcher(sh2c);
1948
1949   sh2c->cycles_done += cycles - ((signed int)sh2c->sr >> 12);
1950 }
1951
1952 static void REGPARM(1) sh2_test_irq(SH2 *sh2)
1953 {
1954   if (sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
1955   {
1956     if (sh2->pending_irl > sh2->pending_int_irq)
1957       sh2_do_irq(sh2, sh2->pending_irl, 64 + sh2->pending_irl/2);
1958     else {
1959       sh2_do_irq(sh2, sh2->pending_int_irq, sh2->pending_int_vector);
1960       sh2->pending_int_irq = 0; // auto-clear
1961       sh2->pending_level = sh2->pending_irl;
1962     }
1963   }
1964 }
1965
1966 #if (DRC_DEBUG & 1)
1967 static void block_stats(void)
1968 {
1969   int c, b, i, total = 0;
1970
1971   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1972     for (i = 0; i < block_counts[b]; i++)
1973       if (block_tables[b][i].addr != 0)
1974         total += block_tables[b][i].refcount;
1975
1976   for (c = 0; c < 10; c++) {
1977     block_desc *blk, *maxb = NULL;
1978     int max = 0;
1979     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
1980       for (i = 0; i < block_counts[b]; i++) {
1981         blk = &block_tables[b][i];
1982         if (blk->addr != 0 && blk->refcount > max) {
1983           max = blk->refcount;
1984           maxb = blk;
1985         }
1986       }
1987     }
1988     if (maxb == NULL)
1989       break;
1990     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
1991       (double)maxb->refcount / total * 100.0);
1992     maxb->refcount = 0;
1993   }
1994
1995   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1996     for (i = 0; i < block_counts[b]; i++)
1997       block_tables[b][i].refcount = 0;
1998 }
1999 #else
2000 #define block_stats()
2001 #endif
2002
2003 void sh2_drc_flush_all(void)
2004 {
2005   block_stats();
2006   flush_tcache(0);
2007   flush_tcache(1);
2008   flush_tcache(2);
2009 }
2010
2011 int sh2_drc_init(SH2 *sh2)
2012 {
2013   if (block_tables[0] == NULL) {
2014     int i, cnt;
2015
2016     drc_cmn_init();
2017
2018     cnt = block_max_counts[0] + block_max_counts[1] + block_max_counts[2];
2019     block_tables[0] = calloc(cnt, sizeof(*block_tables[0]));
2020     if (block_tables[0] == NULL)
2021       return -1;
2022
2023     tcache_ptr = tcache;
2024     sh2_generate_utils();
2025 #ifdef ARM
2026     cache_flush_d_inval_i(tcache, tcache_ptr);
2027 #endif
2028
2029     memset(block_counts, 0, sizeof(block_counts));
2030     tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;
2031
2032     for (i = 1; i < ARRAY_SIZE(block_tables); i++) {
2033       block_tables[i] = block_tables[i - 1] + block_max_counts[i - 1];
2034       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
2035     }
2036
2037     // tmp
2038     PicoOpt |= POPT_DIS_VDP_FIFO;
2039
2040 #if (DRC_DEBUG & 2)
2041     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
2042       tcache_dsm_ptrs[i] = tcache_bases[i];
2043     // disasm the utils
2044     tcache_dsm_ptrs[0] = tcache;
2045     do_host_disasm(0);
2046 #endif
2047 #if (DRC_DEBUG & 1)
2048     hash_collisions = 0;
2049 #endif
2050   }
2051
2052   if (hash_table == NULL) {
2053     hash_table = calloc(sizeof(hash_table[0]), MAX_HASH_ENTRIES);
2054     if (hash_table == NULL)
2055       return -1;
2056   }
2057
2058   return 0;
2059 }
2060
2061 void sh2_drc_finish(SH2 *sh2)
2062 {
2063   if (block_tables[0] != NULL) {
2064     block_stats();
2065     free(block_tables[0]);
2066     memset(block_tables, 0, sizeof(block_tables));
2067
2068     drc_cmn_cleanup();
2069   }
2070
2071   if (hash_table != NULL) {
2072     free(hash_table);
2073     hash_table = NULL;
2074   }
2075 }