32x: drc: finish MAC, gen drc entry/exit (for statically alloced regs)
[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   -1, -1, -1, -1,
88   -1, -1, -1, -1,
89   -1, -1, -1, -1,
90   -1, -1, -1, -1,
91   -1, -1, -1, -1,
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   -1, -1, -1, -1,
109   -1, -1, -1, -1,
110   -1, -1, -1, -1,
111   -1, -1, -1, -1,
112   -1, -1, -1, -1,
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_set_carry(sr);
1055         emith_adcf_r_r(tmp2, tmp2);
1056         emith_carry_to_t(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_set_carry(sr);
1098           emith_adcf_r_r(tmp, tmp2);
1099           emith_carry_to_t(sr, 0);
1100         } else {
1101           emith_set_carry_sub(sr);
1102           emith_sbcf_r_r(tmp, tmp2);
1103           emith_carry_to_t(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_lslf(tmp, tmp, 1);
1142           emith_carry_to_t(sr, 0);
1143           goto end_op;
1144         case 1: // DT Rn      0100nnnn00010000
1145           if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2
1146             emith_sh2_dtbf_loop();
1147             goto end_op;
1148           }
1149           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1150           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1151           emith_bic_r_imm(sr, T);
1152           emith_subf_r_imm(tmp, 1);
1153           emit_or_t_if_eq(sr);
1154           goto end_op;
1155         }
1156         goto default_;
1157       case 0x01:
1158         switch (GET_Fx())
1159         {
1160         case 0: // SHLR Rn    0100nnnn00000001
1161         case 2: // SHAR Rn    0100nnnn00100001
1162           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1163           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1164           if (op & 0x20) {
1165             emith_asrf(tmp, tmp, 1);
1166           } else
1167             emith_lsrf(tmp, tmp, 1);
1168           emith_carry_to_t(sr, 0);
1169           goto end_op;
1170         case 1: // CMP/PZ Rn  0100nnnn00010001
1171           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1172           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1173           emith_bic_r_imm(sr, T);
1174           emith_cmp_r_imm(tmp, 0);
1175           EMITH_SJMP_START(DCOND_LT);
1176           emith_or_r_imm_c(DCOND_GE, sr, T);
1177           EMITH_SJMP_END(DCOND_LT);
1178           goto end_op;
1179         }
1180         goto default_;
1181       case 0x02:
1182       case 0x03:
1183         switch (op & 0x3f)
1184         {
1185         case 0x02: // STS.L    MACH,@–Rn 0100nnnn00000010
1186           tmp = SHR_MACH;
1187           break;
1188         case 0x12: // STS.L    MACL,@–Rn 0100nnnn00010010
1189           tmp = SHR_MACL;
1190           break;
1191         case 0x22: // STS.L    PR,@–Rn   0100nnnn00100010
1192           tmp = SHR_PR;
1193           break;
1194         case 0x03: // STC.L    SR,@–Rn   0100nnnn00000011
1195           tmp = SHR_SR;
1196           break;
1197         case 0x13: // STC.L    GBR,@–Rn  0100nnnn00010011
1198           tmp = SHR_GBR;
1199           break;
1200         case 0x23: // STC.L    VBR,@–Rn  0100nnnn00100011
1201           tmp = SHR_VBR;
1202           break;
1203         default:
1204           goto default_;
1205         }
1206         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1207         emith_sub_r_imm(tmp2, 4);
1208         rcache_clean();
1209         rcache_get_reg_arg(0, GET_Rn());
1210         tmp3 = rcache_get_reg_arg(1, tmp);
1211         if (tmp == SHR_SR)
1212           emith_clear_msb(tmp3, tmp3, 20); // reserved bits defined by ISA as 0
1213         emit_memhandler_write(2);
1214         goto end_op;
1215       case 0x04:
1216       case 0x05:
1217         switch (op & 0x3f)
1218         {
1219         case 0x04: // ROTL   Rn          0100nnnn00000100
1220         case 0x05: // ROTR   Rn          0100nnnn00000101
1221           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1222           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1223           if (op & 1) {
1224             emith_rorf(tmp, tmp, 1);
1225           } else
1226             emith_rolf(tmp, tmp, 1);
1227           emith_carry_to_t(sr, 0);
1228           goto end_op;
1229         case 0x24: // ROTCL  Rn          0100nnnn00100100
1230         case 0x25: // ROTCR  Rn          0100nnnn00100101
1231           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1232           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1233           emith_set_carry(sr);
1234           if (op & 1) {
1235             emith_rorcf(tmp);
1236           } else
1237             emith_rolcf(tmp);
1238           emith_carry_to_t(sr, 0);
1239           goto end_op;
1240         case 0x15: // CMP/PL Rn          0100nnnn00010101
1241           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1242           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1243           emith_bic_r_imm(sr, T);
1244           emith_cmp_r_imm(tmp, 0);
1245           EMITH_SJMP_START(DCOND_LE);
1246           emith_or_r_imm_c(DCOND_GT, sr, T);
1247           EMITH_SJMP_END(DCOND_LE);
1248           goto end_op;
1249         }
1250         goto default_;
1251       case 0x06:
1252       case 0x07:
1253         switch (op & 0x3f)
1254         {
1255         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
1256           tmp = SHR_MACH;
1257           break;
1258         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
1259           tmp = SHR_MACL;
1260           break;
1261         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
1262           tmp = SHR_PR;
1263           break;
1264         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
1265           tmp = SHR_SR;
1266           break;
1267         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
1268           tmp = SHR_GBR;
1269           break;
1270         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
1271           tmp = SHR_VBR;
1272           break;
1273         default:
1274           goto default_;
1275         }
1276         rcache_clean();
1277         rcache_get_reg_arg(0, GET_Rn());
1278         tmp2 = emit_memhandler_read(2);
1279         if (tmp == SHR_SR) {
1280           emith_write_sr(tmp2);
1281           test_irq = 1;
1282         } else {
1283           tmp = rcache_get_reg(tmp, RC_GR_WRITE);
1284           emith_move_r_r(tmp, tmp2);
1285         }
1286         rcache_free_tmp(tmp2);
1287         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1288         emith_add_r_imm(tmp, 4);
1289         goto end_op;
1290       case 0x08:
1291       case 0x09:
1292         switch (GET_Fx())
1293         {
1294         case 0:
1295           // SHLL2 Rn        0100nnnn00001000
1296           // SHLR2 Rn        0100nnnn00001001
1297           tmp = 2;
1298           break;
1299         case 1:
1300           // SHLL8 Rn        0100nnnn00011000
1301           // SHLR8 Rn        0100nnnn00011001
1302           tmp = 8;
1303           break;
1304         case 2:
1305           // SHLL16 Rn       0100nnnn00101000
1306           // SHLR16 Rn       0100nnnn00101001
1307           tmp = 16;
1308           break;
1309         default:
1310           goto default_;
1311         }
1312         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1313         if (op & 1) {
1314           emith_lsr(tmp2, tmp2, tmp);
1315         } else
1316           emith_lsl(tmp2, tmp2, tmp);
1317         goto end_op;
1318       case 0x0a:
1319         switch (GET_Fx())
1320         {
1321         case 0: // LDS      Rm,MACH   0100mmmm00001010
1322           tmp2 = SHR_MACH;
1323           break;
1324         case 1: // LDS      Rm,MACL   0100mmmm00011010
1325           tmp2 = SHR_MACL;
1326           break;
1327         case 2: // LDS      Rm,PR     0100mmmm00101010
1328           tmp2 = SHR_PR;
1329           break;
1330         default:
1331           goto default_;
1332         }
1333         emit_move_r_r(tmp2, GET_Rn());
1334         goto end_op;
1335       case 0x0b:
1336         switch (GET_Fx())
1337         {
1338         case 0: // JSR  @Rm   0100mmmm00001011
1339         case 2: // JMP  @Rm   0100mmmm00101011
1340           DELAYED_OP;
1341           if (!(op & 0x20))
1342             emit_move_r_imm32(SHR_PR, pc + 2);
1343           emit_move_r_r(SHR_PPC, (op >> 8) & 0x0f);
1344           cycles++;
1345           break;
1346         case 1: // TAS.B @Rn  0100nnnn00011011
1347           // XXX: is TAS working on 32X?
1348           rcache_clean();
1349           rcache_get_reg_arg(0, GET_Rn());
1350           tmp = emit_memhandler_read(0);
1351           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1352           emith_bic_r_imm(sr, T);
1353           emith_cmp_r_imm(tmp, 0);
1354           emit_or_t_if_eq(sr);
1355           rcache_clean();
1356           emith_or_r_imm(tmp, 0x80);
1357           tmp2 = rcache_get_tmp_arg(1); // assuming it differs to tmp
1358           emith_move_r_r(tmp2, tmp);
1359           rcache_free_tmp(tmp);
1360           rcache_get_reg_arg(0, GET_Rn());
1361           emit_memhandler_write(0);
1362           cycles += 3;
1363           break;
1364         default:
1365           goto default_;
1366         }
1367         goto end_op;
1368       case 0x0e:
1369         tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
1370         switch (GET_Fx())
1371         {
1372         case 0: // LDC Rm,SR   0100mmmm00001110
1373           tmp2 = SHR_SR;
1374           break;
1375         case 1: // LDC Rm,GBR  0100mmmm00011110
1376           tmp2 = SHR_GBR;
1377           break;
1378         case 2: // LDC Rm,VBR  0100mmmm00101110
1379           tmp2 = SHR_VBR;
1380           break;
1381         default:
1382           goto default_;
1383         }
1384         if (tmp2 == SHR_SR) {
1385           emith_write_sr(tmp);
1386           test_irq = 1;
1387         } else {
1388           tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE);
1389           emith_move_r_r(tmp2, tmp);
1390         }
1391         goto end_op;
1392       case 0x0f:
1393         // MAC @Rm+,@Rn+  0100nnnnmmmm1111
1394         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1);
1395         emith_sext(tmp, tmp, 16);
1396         emith_sext(tmp2, tmp2, 16);
1397         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW);
1398         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
1399         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
1400         rcache_free_tmp(tmp2);
1401         // XXX: MACH should be untouched when S is set?
1402         sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1403         emith_tst_r_imm(sr, S);
1404         EMITH_JMP_START(DCOND_EQ);
1405
1406         emith_asr(tmp, tmp3, 31);
1407         emith_eorf_r_r(tmp, tmp4); // tmp = ((signed)macl >> 31) ^ mach
1408         EMITH_JMP_START(DCOND_EQ);
1409         emith_move_r_imm(tmp3, 0x80000000);
1410         emith_tst_r_r(tmp4, tmp4);
1411         EMITH_SJMP_START(DCOND_MI);
1412         emith_sub_r_imm_c(DCOND_PL, tmp3, 1); // positive
1413         EMITH_SJMP_END(DCOND_MI);
1414         EMITH_JMP_END(DCOND_EQ);
1415
1416         EMITH_JMP_END(DCOND_EQ);
1417         rcache_free_tmp(tmp);
1418         cycles += 2;
1419         goto end_op;
1420       }
1421       goto default_;
1422
1423     /////////////////////////////////////////////
1424     case 0x05:
1425       // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
1426       rcache_clean();
1427       tmp = rcache_get_reg_arg(0, GET_Rm());
1428       emith_add_r_imm(tmp, (op & 0x0f) * 4);
1429       tmp = emit_memhandler_read(2);
1430       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1431       emith_move_r_r(tmp2, tmp);
1432       rcache_free_tmp(tmp);
1433       goto end_op;
1434
1435     /////////////////////////////////////////////
1436     case 0x06:
1437       switch (op & 0x0f)
1438       {
1439       case 0x00: // MOV.B @Rm,Rn        0110nnnnmmmm0000
1440       case 0x01: // MOV.W @Rm,Rn        0110nnnnmmmm0001
1441       case 0x02: // MOV.L @Rm,Rn        0110nnnnmmmm0010
1442       case 0x04: // MOV.B @Rm+,Rn       0110nnnnmmmm0100
1443       case 0x05: // MOV.W @Rm+,Rn       0110nnnnmmmm0101
1444       case 0x06: // MOV.L @Rm+,Rn       0110nnnnmmmm0110
1445         rcache_clean();
1446         rcache_get_reg_arg(0, GET_Rm());
1447         tmp  = emit_memhandler_read(op & 3);
1448         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1449         if ((op & 3) != 2) {
1450           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
1451         } else
1452           emith_move_r_r(tmp2, tmp);
1453         rcache_free_tmp(tmp);
1454         if ((op & 7) >= 4 && GET_Rn() != GET_Rm()) {
1455           tmp = rcache_get_reg(GET_Rm(), RC_GR_RMW);
1456           emith_add_r_imm(tmp, (1 << (op & 3)));
1457         }
1458         goto end_op;
1459       case 0x03:
1460       case 0x07 ... 0x0f:
1461         tmp  = rcache_get_reg(GET_Rm(), RC_GR_READ);
1462         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1463         switch (op & 0x0f)
1464         {
1465         case 0x03: // MOV    Rm,Rn        0110nnnnmmmm0011
1466           emith_move_r_r(tmp2, tmp);
1467           break;
1468         case 0x07: // NOT    Rm,Rn        0110nnnnmmmm0111
1469           emith_mvn_r_r(tmp2, tmp);
1470           break;
1471         case 0x08: // SWAP.B Rm,Rn        0110nnnnmmmm1000
1472           tmp3 = tmp2;
1473           if (tmp == tmp2)
1474             tmp3 = rcache_get_tmp();
1475           tmp4 = rcache_get_tmp();
1476           emith_lsr(tmp3, tmp, 16);
1477           emith_or_r_r_lsl(tmp3, tmp, 24);
1478           emith_and_r_r_imm(tmp4, tmp, 0xff00);
1479           emith_or_r_r_lsl(tmp3, tmp4, 8);
1480           emith_rol(tmp2, tmp3, 16);
1481           rcache_free_tmp(tmp4);
1482           if (tmp == tmp2)
1483             rcache_free_tmp(tmp3);
1484           break;
1485         case 0x09: // SWAP.W Rm,Rn        0110nnnnmmmm1001
1486           emith_rol(tmp2, tmp, 16);
1487           break;
1488         case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
1489           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1490           emith_set_carry_sub(sr);
1491           emith_negcf_r_r(tmp2, tmp);
1492           emith_carry_to_t(sr, 1);
1493           break;
1494         case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
1495           emith_neg_r_r(tmp2, tmp);
1496           break;
1497         case 0x0c: // EXTU.B Rm,Rn        0110nnnnmmmm1100
1498           emith_clear_msb(tmp2, tmp, 24);
1499           break;
1500         case 0x0d: // EXTU.W Rm,Rn        0110nnnnmmmm1101
1501           emith_clear_msb(tmp2, tmp, 16);
1502           break;
1503         case 0x0e: // EXTS.B Rm,Rn        0110nnnnmmmm1110
1504           emith_sext(tmp2, tmp, 8);
1505           break;
1506         case 0x0f: // EXTS.W Rm,Rn        0110nnnnmmmm1111
1507           emith_sext(tmp2, tmp, 16);
1508           break;
1509         }
1510         goto end_op;
1511       }
1512       goto default_;
1513
1514     /////////////////////////////////////////////
1515     case 0x07:
1516       // ADD #imm,Rn  0111nnnniiiiiiii
1517       tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1518       if (op & 0x80) { // adding negative
1519         emith_sub_r_imm(tmp, -op & 0xff);
1520       } else
1521         emith_add_r_imm(tmp, op & 0xff);
1522       goto end_op;
1523
1524     /////////////////////////////////////////////
1525     case 0x08:
1526       switch (op & 0x0f00)
1527       {
1528       case 0x0000: // MOV.B R0,@(disp,Rn)  10000000nnnndddd
1529       case 0x0100: // MOV.W R0,@(disp,Rn)  10000001nnnndddd
1530         rcache_clean();
1531         tmp  = rcache_get_reg_arg(0, GET_Rm());
1532         tmp2 = rcache_get_reg_arg(1, SHR_R0);
1533         tmp3 = (op & 0x100) >> 8;
1534         emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
1535         emit_memhandler_write(tmp3);
1536         goto end_op;
1537       case 0x0400: // MOV.B @(disp,Rm),R0  10000100mmmmdddd
1538       case 0x0500: // MOV.W @(disp,Rm),R0  10000101mmmmdddd
1539         rcache_clean();
1540         tmp  = rcache_get_reg_arg(0, GET_Rm());
1541         tmp3 = (op & 0x100) >> 8;
1542         emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
1543         tmp  = emit_memhandler_read(tmp3);
1544         tmp2 = rcache_get_reg(0, RC_GR_WRITE);
1545         emith_sext(tmp2, tmp, 8 << tmp3);
1546         rcache_free_tmp(tmp);
1547         goto end_op;
1548       case 0x0800: // CMP/EQ #imm,R0       10001000iiiiiiii
1549         // XXX: could use cmn
1550         tmp  = rcache_get_tmp();
1551         tmp2 = rcache_get_reg(0, RC_GR_READ);
1552         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1553         emith_move_r_imm_s8(tmp, op & 0xff);
1554         emith_bic_r_imm(sr, T);
1555         emith_cmp_r_r(tmp2, tmp);
1556         emit_or_t_if_eq(sr);
1557         rcache_free_tmp(tmp);
1558         goto end_op;
1559       case 0x0d00: // BT/S label 10001101dddddddd
1560       case 0x0f00: // BF/S label 10001111dddddddd
1561         DELAYED_OP;
1562         cycles--;
1563         // fallthrough
1564       case 0x0900:   // BT   label 10001001dddddddd
1565       case 0x0b00: { // BF   label 10001011dddddddd
1566         // jmp_cond ~ cond when guest doesn't jump
1567         int jmp_cond  = (op & 0x0200) ? DCOND_NE : DCOND_EQ;
1568         int insn_cond = (op & 0x0200) ? DCOND_EQ : DCOND_NE;
1569         signed int offs = ((signed int)(op << 24) >> 23);
1570         tmp = rcache_get_reg(delayed_op ? SHR_PPC : SHR_PC, RC_GR_WRITE);
1571         emith_move_r_imm(tmp, pc + (delayed_op ? 2 : 0));
1572         emith_sh2_test_t();
1573         EMITH_SJMP_START(jmp_cond);
1574         if (!delayed_op)
1575           offs += 2;
1576         if (offs < 0) {
1577           emith_sub_r_imm_c(insn_cond, tmp, -offs);
1578         } else
1579           emith_add_r_imm_c(insn_cond, tmp, offs);
1580         EMITH_SJMP_END(jmp_cond);
1581         cycles += 2;
1582         if (!delayed_op)
1583           goto end_block_btf;
1584         goto end_op;
1585       }}
1586       goto default_;
1587
1588     /////////////////////////////////////////////
1589     case 0x09:
1590       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
1591       rcache_clean();
1592       tmp = rcache_get_tmp_arg(0);
1593       emith_move_r_imm(tmp, pc + (op & 0xff) * 2 + 2);
1594       tmp  = emit_memhandler_read(1);
1595       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1596       emith_sext(tmp2, tmp, 16);
1597       rcache_free_tmp(tmp);
1598       goto end_op;
1599
1600     /////////////////////////////////////////////
1601     case 0x0a:
1602       // BRA  label 1010dddddddddddd
1603       DELAYED_OP;
1604     do_bra:
1605       tmp = ((signed int)(op << 20) >> 19);
1606       emit_move_r_imm32(SHR_PPC, pc + tmp + 2);
1607       cycles++;
1608       break;
1609
1610     /////////////////////////////////////////////
1611     case 0x0b:
1612       // BSR  label 1011dddddddddddd
1613       DELAYED_OP;
1614       emit_move_r_imm32(SHR_PR, pc + 2);
1615       goto do_bra;
1616
1617     /////////////////////////////////////////////
1618     case 0x0c:
1619       switch (op & 0x0f00)
1620       {
1621       case 0x0000: // MOV.B R0,@(disp,GBR)   11000000dddddddd
1622       case 0x0100: // MOV.W R0,@(disp,GBR)   11000001dddddddd
1623       case 0x0200: // MOV.L R0,@(disp,GBR)   11000010dddddddd
1624         rcache_clean();
1625         tmp  = rcache_get_reg_arg(0, SHR_GBR);
1626         tmp2 = rcache_get_reg_arg(1, SHR_R0);
1627         tmp3 = (op & 0x300) >> 8;
1628         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
1629         emit_memhandler_write(tmp3);
1630         goto end_op;
1631       case 0x0400: // MOV.B @(disp,GBR),R0   11000100dddddddd
1632       case 0x0500: // MOV.W @(disp,GBR),R0   11000101dddddddd
1633       case 0x0600: // MOV.L @(disp,GBR),R0   11000110dddddddd
1634         rcache_clean();
1635         tmp  = rcache_get_reg_arg(0, SHR_GBR);
1636         tmp3 = (op & 0x300) >> 8;
1637         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
1638         tmp  = emit_memhandler_read(tmp3);
1639         tmp2 = rcache_get_reg(0, RC_GR_WRITE);
1640         if (tmp3 != 2) {
1641           emith_sext(tmp2, tmp, 8 << tmp3);
1642         } else
1643           emith_move_r_r(tmp2, tmp);
1644         rcache_free_tmp(tmp);
1645         goto end_op;
1646       case 0x0300: // TRAPA #imm      11000011iiiiiiii
1647         tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
1648         emith_sub_r_imm(tmp, 4*2);
1649         rcache_clean();
1650         // push SR
1651         tmp = rcache_get_reg_arg(0, SHR_SP);
1652         emith_add_r_imm(tmp, 4);
1653         tmp = rcache_get_reg_arg(1, SHR_SR);
1654         emith_clear_msb(tmp, tmp, 20);
1655         emit_memhandler_write(2);
1656         // push PC
1657         rcache_get_reg_arg(0, SHR_SP);
1658         tmp = rcache_get_tmp_arg(1);
1659         emith_move_r_imm(tmp, pc);
1660         emit_memhandler_write(2);
1661         // obtain new PC
1662         tmp = rcache_get_reg_arg(0, SHR_VBR);
1663         emith_add_r_imm(tmp, (op & 0xff) * 4);
1664         tmp  = emit_memhandler_read(2);
1665         tmp2 = rcache_get_reg(SHR_PC, RC_GR_WRITE);
1666         emith_move_r_r(tmp2, tmp);
1667         rcache_free_tmp(tmp);
1668         cycles += 7;
1669         goto end_block_btf;
1670       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
1671         emit_move_r_imm32(SHR_R0, (pc + (op & 0xff) * 4 + 2) & ~3);
1672         goto end_op;
1673       case 0x0800: // TST #imm,R0           11001000iiiiiiii
1674         tmp = rcache_get_reg(SHR_R0, RC_GR_READ);
1675         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1676         emith_bic_r_imm(sr, T);
1677         emith_tst_r_imm(tmp, op & 0xff);
1678         emit_or_t_if_eq(sr);
1679         goto end_op;
1680       case 0x0900: // AND #imm,R0           11001001iiiiiiii
1681         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1682         emith_and_r_imm(tmp, op & 0xff);
1683         goto end_op;
1684       case 0x0a00: // XOR #imm,R0           11001010iiiiiiii
1685         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1686         emith_eor_r_imm(tmp, op & 0xff);
1687         goto end_op;
1688       case 0x0b00: // OR  #imm,R0           11001011iiiiiiii
1689         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
1690         emith_or_r_imm(tmp, op & 0xff);
1691         goto end_op;
1692       case 0x0c00: // TST.B #imm,@(R0,GBR)  11001100iiiiiiii
1693         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1694         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1695         emith_bic_r_imm(sr, T);
1696         emith_tst_r_imm(tmp, op & 0xff);
1697         emit_or_t_if_eq(sr);
1698         rcache_free_tmp(tmp);
1699         cycles += 2;
1700         goto end_op;
1701       case 0x0d00: // AND.B #imm,@(R0,GBR)  11001101iiiiiiii
1702         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1703         emith_and_r_imm(tmp, op & 0xff);
1704         goto end_rmw_op;
1705       case 0x0e00: // XOR.B #imm,@(R0,GBR)  11001110iiiiiiii
1706         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1707         emith_eor_r_imm(tmp, op & 0xff);
1708         goto end_rmw_op;
1709       case 0x0f00: // OR.B  #imm,@(R0,GBR)  11001111iiiiiiii
1710         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
1711         emith_or_r_imm(tmp, op & 0xff);
1712       end_rmw_op:
1713         tmp2 = rcache_get_tmp_arg(1);
1714         emith_move_r_r(tmp2, tmp);
1715         rcache_free_tmp(tmp);
1716         tmp3 = rcache_get_reg_arg(0, SHR_GBR);
1717         tmp4 = rcache_get_reg(SHR_R0, RC_GR_READ);
1718         emith_add_r_r(tmp3, tmp4);
1719         emit_memhandler_write(0);
1720         cycles += 2;
1721         goto end_op;
1722       }
1723       goto default_;
1724
1725     /////////////////////////////////////////////
1726     case 0x0d:
1727       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
1728       rcache_clean();
1729       tmp = rcache_get_tmp_arg(0);
1730       emith_move_r_imm(tmp, (pc + (op & 0xff) * 4 + 2) & ~3);
1731       tmp  = emit_memhandler_read(2);
1732       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1733       emith_move_r_r(tmp2, tmp);
1734       rcache_free_tmp(tmp);
1735       goto end_op;
1736
1737     /////////////////////////////////////////////
1738     case 0x0e:
1739       // MOV #imm,Rn   1110nnnniiiiiiii
1740       tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1741       emith_move_r_imm_s8(tmp, op & 0xff);
1742       goto end_op;
1743
1744     default:
1745     default_:
1746       elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
1747         sh2->is_slave ? 's' : 'm', op, pc - 2);
1748 #ifdef DRC_DEBUG_INTERP
1749       emit_move_r_imm32(SHR_PC, pc - 2);
1750       rcache_flush();
1751       emith_pass_arg_r(0, CONTEXT_REG);
1752       emith_pass_arg_imm(1, op);
1753       emith_call(sh2_do_op);
1754 #endif
1755       break;
1756     }
1757
1758 end_op:
1759     if (delayed_op == 1)
1760       emit_move_r_r(SHR_PC, SHR_PPC);
1761
1762     if (test_irq && delayed_op != 2) {
1763       if (!delayed_op)
1764         emit_move_r_imm32(SHR_PC, pc);
1765       rcache_flush();
1766       emith_pass_arg_r(0, CONTEXT_REG);
1767       emith_call(sh2_test_irq);
1768       goto end_block_btf;
1769     }
1770     if (delayed_op == 1)
1771       break;
1772
1773     do_host_disasm(tcache_id);
1774   }
1775
1776   // delayed_op means some kind of branch - PC already handled
1777   if (!delayed_op)
1778     emit_move_r_imm32(SHR_PC, pc);
1779
1780 end_block_btf:
1781   this_block->end_addr = pc;
1782
1783   // mark memory blocks as containing compiled code
1784   if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1785     // data array, BIOS
1786     u16 *drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
1787     tmp =  (this_block->addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1788     tmp2 = (this_block->end_addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1789     Pico32xMem->drcblk_da[sh2->is_slave][tmp] = (blkid << 1) | 1;
1790     for (++tmp; tmp < tmp2; tmp++) {
1791       if (drcblk[tmp])
1792         break; // dont overwrite overlay block
1793       drcblk[tmp] = blkid << 1;
1794     }
1795   }
1796   else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
1797     tmp =  (this_block->addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1798     tmp2 = (this_block->end_addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1799     Pico32xMem->drcblk_ram[tmp] = (blkid << 1) | 1;
1800     for (++tmp; tmp < tmp2; tmp++) {
1801       if (Pico32xMem->drcblk_ram[tmp])
1802         break;
1803       Pico32xMem->drcblk_ram[tmp] = blkid << 1;
1804     }
1805   }
1806
1807   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
1808   emith_sub_r_imm(tmp, cycles << 12);
1809   rcache_flush();
1810   emith_jump(sh2_drc_exit);
1811   tcache_ptrs[tcache_id] = tcache_ptr;
1812
1813 #ifdef ARM
1814   cache_flush_d_inval_i(block_entry, tcache_ptr);
1815 #endif
1816
1817   do_host_disasm(tcache_id);
1818   dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
1819     tcache_id, block_counts[tcache_id],
1820     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
1821     insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
1822   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
1823     dbg(1, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
1824 #if (DRC_DEBUG & 2)
1825   fflush(stdout);
1826 #endif
1827
1828   return block_entry;
1829 /*
1830 unimplemented:
1831   // last op
1832   do_host_disasm(tcache_id);
1833   exit(1);
1834 */
1835 }
1836
1837 void __attribute__((noinline)) sh2_drc_dispatcher(SH2 *sh2)
1838 {
1839   // TODO: need to handle self-caused interrupts
1840   sh2_test_irq(sh2);
1841
1842   while (((signed int)sh2->sr >> 12) > 0)
1843   {
1844     void *block = NULL;
1845     block_desc *bd = NULL;
1846
1847     // FIXME: must avoid doing it so often..
1848     //sh2_test_irq(sh2);
1849
1850     // we have full block id tables for data_array and RAM
1851     // BIOS goes to data_array table too
1852     if ((sh2->pc & 0xff000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1853       int blkid = Pico32xMem->drcblk_da[sh2->is_slave][(sh2->pc & 0xfff) >> SH2_DRCBLK_DA_SHIFT];
1854       if (blkid & 1) {
1855         bd = &block_tables[1 + sh2->is_slave][blkid >> 1];
1856         block = bd->tcache_ptr;
1857       }
1858     }
1859     // RAM
1860     else if ((sh2->pc & 0xc6000000) == 0x06000000) {
1861       int blkid = Pico32xMem->drcblk_ram[(sh2->pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT];
1862       if (blkid & 1) {
1863         bd = &block_tables[0][blkid >> 1];
1864         block = bd->tcache_ptr;
1865       }
1866     }
1867     // ROM
1868     else if ((sh2->pc & 0xc6000000) == 0x02000000) {
1869       bd = HASH_FUNC(hash_table, sh2->pc);
1870
1871       if (bd != NULL) {
1872         if (bd->addr == sh2->pc)
1873           block = bd->tcache_ptr;
1874         else
1875           block = dr_find_block(bd, sh2->pc);
1876       }
1877     }
1878
1879     if (block == NULL)
1880       block = sh2_translate(sh2, bd);
1881
1882     dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
1883       sh2->pc, block, (signed int)sh2->sr >> 12);
1884 #if (DRC_DEBUG & 1)
1885     if (bd != NULL)
1886       bd->refcount++;
1887 #endif
1888     sh2_drc_entry(block, sh2);
1889   }
1890 }
1891
1892 static void sh2_smc_rm_block(u16 *drcblk, u16 *p, block_desc *btab, u32 a)
1893 {
1894   u16 id = *p >> 1;
1895   block_desc *bd = btab + id;
1896
1897   dbg(1, "  killing block %08x", bd->addr);
1898   bd->addr = bd->end_addr = 0;
1899
1900   while (p > drcblk && (p[-1] >> 1) == id)
1901     p--;
1902
1903   // check for possible overlay block
1904   if (p > 0 && p[-1] != 0) {
1905     bd = btab + (p[-1] >> 1);
1906     if (bd->addr <= a && a < bd->end_addr)
1907       sh2_smc_rm_block(drcblk, p - 1, btab, a);
1908   }
1909
1910   do {
1911     *p++ = 0;
1912   }
1913   while ((*p >> 1) == id);
1914 }
1915
1916 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
1917 {
1918   u16 *drcblk = Pico32xMem->drcblk_ram;
1919   u16 *p = drcblk + ((a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT);
1920
1921   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1922   sh2_smc_rm_block(drcblk, p, block_tables[0], a);
1923 }
1924
1925 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
1926 {
1927   u16 *drcblk = Pico32xMem->drcblk_da[cpuid];
1928   u16 *p = drcblk + ((a & 0xfff) >> SH2_DRCBLK_DA_SHIFT);
1929
1930   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1931   sh2_smc_rm_block(drcblk, p, block_tables[1 + cpuid], a);
1932 }
1933
1934 void sh2_execute(SH2 *sh2c, int cycles)
1935 {
1936   sh2 = sh2c; // XXX
1937
1938   sh2c->cycles_aim += cycles;
1939   cycles = sh2c->cycles_aim - sh2c->cycles_done;
1940
1941   // cycles are kept in SHR_SR unused bits (upper 20)
1942   sh2c->sr &= 0x3f3;
1943   sh2c->sr |= cycles << 12;
1944   sh2_drc_dispatcher(sh2c);
1945
1946   sh2c->cycles_done += cycles - ((signed int)sh2c->sr >> 12);
1947 }
1948
1949 static void REGPARM(1) sh2_test_irq(SH2 *sh2)
1950 {
1951   if (sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
1952   {
1953     if (sh2->pending_irl > sh2->pending_int_irq)
1954       sh2_do_irq(sh2, sh2->pending_irl, 64 + sh2->pending_irl/2);
1955     else {
1956       sh2_do_irq(sh2, sh2->pending_int_irq, sh2->pending_int_vector);
1957       sh2->pending_int_irq = 0; // auto-clear
1958       sh2->pending_level = sh2->pending_irl;
1959     }
1960   }
1961 }
1962
1963 #if (DRC_DEBUG & 1)
1964 static void block_stats(void)
1965 {
1966   int c, b, i, total = 0;
1967
1968   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1969     for (i = 0; i < block_counts[b]; i++)
1970       if (block_tables[b][i].addr != 0)
1971         total += block_tables[b][i].refcount;
1972
1973   for (c = 0; c < 10; c++) {
1974     block_desc *blk, *maxb = NULL;
1975     int max = 0;
1976     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
1977       for (i = 0; i < block_counts[b]; i++) {
1978         blk = &block_tables[b][i];
1979         if (blk->addr != 0 && blk->refcount > max) {
1980           max = blk->refcount;
1981           maxb = blk;
1982         }
1983       }
1984     }
1985     if (maxb == NULL)
1986       break;
1987     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
1988       (double)maxb->refcount / total * 100.0);
1989     maxb->refcount = 0;
1990   }
1991
1992   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1993     for (i = 0; i < block_counts[b]; i++)
1994       block_tables[b][i].refcount = 0;
1995 }
1996 #else
1997 #define block_stats()
1998 #endif
1999
2000 void sh2_drc_flush_all(void)
2001 {
2002   block_stats();
2003   flush_tcache(0);
2004   flush_tcache(1);
2005   flush_tcache(2);
2006 }
2007
2008 int sh2_drc_init(SH2 *sh2)
2009 {
2010   if (block_tables[0] == NULL) {
2011     int i, cnt;
2012
2013     drc_cmn_init();
2014
2015     cnt = block_max_counts[0] + block_max_counts[1] + block_max_counts[2];
2016     block_tables[0] = calloc(cnt, sizeof(*block_tables[0]));
2017     if (block_tables[0] == NULL)
2018       return -1;
2019
2020     tcache_ptr = tcache;
2021     sh2_generate_utils();
2022
2023     memset(block_counts, 0, sizeof(block_counts));
2024     tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;
2025
2026     for (i = 1; i < ARRAY_SIZE(block_tables); i++) {
2027       block_tables[i] = block_tables[i - 1] + block_max_counts[i - 1];
2028       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
2029     }
2030
2031     // tmp
2032     PicoOpt |= POPT_DIS_VDP_FIFO;
2033
2034 #if (DRC_DEBUG & 2)
2035     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
2036       tcache_dsm_ptrs[i] = tcache_bases[i];
2037     // disasm the utils
2038     tcache_dsm_ptrs[0] = tcache;
2039     do_host_disasm(0);
2040 #endif
2041 #if (DRC_DEBUG & 1)
2042     hash_collisions = 0;
2043 #endif
2044   }
2045
2046   if (hash_table == NULL) {
2047     hash_table = calloc(sizeof(hash_table[0]), MAX_HASH_ENTRIES);
2048     if (hash_table == NULL)
2049       return -1;
2050   }
2051
2052   return 0;
2053 }
2054
2055 void sh2_drc_finish(SH2 *sh2)
2056 {
2057   if (block_tables[0] != NULL) {
2058     block_stats();
2059     free(block_tables[0]);
2060     memset(block_tables, 0, sizeof(block_tables));
2061
2062     drc_cmn_cleanup();
2063   }
2064
2065   if (hash_table != NULL) {
2066     free(hash_table);
2067     hash_table = NULL;
2068   }
2069 }