32x: drc: more wip, ARM untested
[picodrive.git] / cpu / sh2 / compiler.c
1 /*
2  * vim:shiftwidth=2:expandtab
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <assert.h>
7
8 #include "../../pico/pico_int.h"
9 #include "sh2.h"
10 #include "compiler.h"
11 #include "../drc/cmn.h"
12
13 #ifndef DRC_DEBUG
14 #define DRC_DEBUG 0
15 #endif
16
17 #if DRC_DEBUG
18 #define dbg(l,...) { \
19   if ((l) & DRC_DEBUG) \
20     elprintf(EL_STATUS, ##__VA_ARGS__); \
21 }
22
23 #include "mame/sh2dasm.h"
24 #include <platform/linux/host_dasm.h>
25 static int insns_compiled, hash_collisions, host_insn_count;
26 #define COUNT_OP \
27         host_insn_count++
28 #else // !DRC_DEBUG
29 #define COUNT_OP
30 #define dbg(...)
31 #endif
32
33 #if (DRC_DEBUG & 2)
34 static u8 *tcache_dsm_ptrs[3];
35 static char sh2dasm_buff[64];
36 #define do_host_disasm(tcid) \
37   host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
38   tcache_dsm_ptrs[tcid] = tcache_ptr
39 #else
40 #define do_host_disasm(x)
41 #endif
42
43 #define BLOCK_CYCLE_LIMIT 100
44 #define MAX_BLOCK_SIZE (BLOCK_CYCLE_LIMIT * 6 * 6)
45
46 // we have 3 translation cache buffers, split from one drc/cmn buffer.
47 // BIOS shares tcache with data array because it's only used for init
48 // and can be discarded early
49 static const int tcache_sizes[3] = {
50   DRC_TCACHE_SIZE * 6 / 8, // ROM, DRAM
51   DRC_TCACHE_SIZE / 8, // BIOS, data array in master sh2
52   DRC_TCACHE_SIZE / 8, // ... slave
53 };
54
55 static u8 *tcache_bases[3];
56 static u8 *tcache_ptrs[3];
57
58 // ptr for code emiters
59 static u8 *tcache_ptr;
60
61 // host register tracking
62 enum {
63   HR_FREE,
64   HR_CACHED, // 'val' has sh2_reg_e
65   HR_CACHED_DIRTY,
66   HR_CONST,  // 'val' has constant
67   HR_TEMP,   // reg used for temp storage
68 };
69
70 typedef struct {
71   u8 reg;
72   u8 type;
73   u16 stamp; // kind of a timestamp
74   u32 val;
75 } temp_reg_t;
76
77 // note: reg_temp[] must have at least the amount of
78 // registers used by handlers in worst case (currently 4)
79 #ifdef ARM
80 #include "../drc/emit_arm.c"
81
82 static const int reg_map_g2h[] = {
83   -1, -1, -1, -1,
84   -1, -1, -1, -1,
85   -1, -1, -1, -1,
86   -1, -1, -1, -1,
87   -1, -1, -1, -1,
88   -1, -1, -1, -1,
89 };
90
91 static temp_reg_t reg_temp[] = {
92   {  0, },
93   {  1, },
94   { 12, },
95   { 14, },
96   {  2, },
97   {  3, },
98 };
99
100 #else
101 #include "../drc/emit_x86.c"
102
103 static const int reg_map_g2h[] = {
104   -1, -1, -1, -1,
105   -1, -1, -1, -1,
106   -1, -1, -1, -1,
107   -1, -1, -1, -1,
108   -1, -1, -1, -1,
109   -1, -1, -1, -1,
110 };
111
112 // ax, cx, dx are usually temporaries by convention
113 static temp_reg_t reg_temp[] = {
114   { xAX, },
115   { xBX, },
116   { xCX, },
117   { xDX, },
118 };
119
120 #endif
121
122 #define T       0x00000001
123 #define S       0x00000002
124 #define I       0x000000f0
125 #define Q       0x00000100
126 #define M       0x00000200
127
128 typedef enum {
129   SHR_R0 = 0, SHR_R15 = 15,
130   SHR_PC,  SHR_PPC, SHR_PR,   SHR_SR,
131   SHR_GBR, SHR_VBR, SHR_MACH, SHR_MACL,
132 } sh2_reg_e;
133
134 typedef struct block_desc_ {
135   u32 addr;                     // SH2 PC address
136   u32 end_addr;                 // TODO rm?
137   void *tcache_ptr;             // translated block for above PC
138   struct block_desc_ *next;     // next block with the same PC hash
139 #if (DRC_DEBUG & 1)
140   int refcount;
141 #endif
142 } block_desc;
143
144 static const int block_max_counts[3] = {
145   4*1024,
146   256,
147   256,
148 };
149 static block_desc *block_tables[3];
150 static int block_counts[3];
151
152 // ROM hash table
153 #define MAX_HASH_ENTRIES 1024
154 #define HASH_MASK (MAX_HASH_ENTRIES - 1)
155 static void **hash_table;
156
157 extern void sh2_drc_entry(SH2 *sh2, void *block);
158 extern void sh2_drc_exit(void);
159
160 // tmp
161 extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
162 static void REGPARM(1) sh2_test_irq(SH2 *sh2);
163
164 static void flush_tcache(int tcid)
165 {
166   dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
167     tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
168     block_counts[tcid], block_max_counts[tcid]);
169
170   block_counts[tcid] = 0;
171   tcache_ptrs[tcid] = tcache_bases[tcid];
172   if (tcid == 0) { // ROM, RAM
173     memset(hash_table, 0, sizeof(hash_table[0]) * MAX_HASH_ENTRIES);
174     memset(Pico32xMem->drcblk_ram, 0, sizeof(Pico32xMem->drcblk_ram));
175   }
176   else
177     memset(Pico32xMem->drcblk_da[tcid - 1], 0, sizeof(Pico32xMem->drcblk_da[0]));
178 #if (DRC_DEBUG & 2)
179   tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
180 #endif
181 }
182
183 static void *dr_find_block(block_desc *tab, u32 addr)
184 {
185   for (tab = tab->next; tab != NULL; tab = tab->next)
186     if (tab->addr == addr)
187       break;
188
189   if (tab != NULL)
190     return tab->tcache_ptr;
191
192   printf("block miss for %08x\n", addr);
193   return NULL;
194 }
195
196 static block_desc *dr_add_block(u32 addr, int tcache_id, int *blk_id)
197 {
198   int *bcount = &block_counts[tcache_id];
199   block_desc *bd;
200
201   if (*bcount >= block_max_counts[tcache_id])
202     return NULL;
203
204   bd = &block_tables[tcache_id][*bcount];
205   bd->addr = addr;
206   bd->tcache_ptr = tcache_ptr;
207   *blk_id = *bcount;
208   (*bcount)++;
209
210   return bd;
211 }
212
213 #define HASH_FUNC(hash_tab, addr) \
214   ((block_desc **)(hash_tab))[(addr) & HASH_MASK]
215
216 // ---------------------------------------------------------------
217
218 // register chache
219 static u16 rcache_counter;
220
221 static temp_reg_t *rcache_evict(void)
222 {
223   // evict reg with oldest stamp
224   int i, oldest = -1;
225   u16 min_stamp = (u16)-1;
226
227   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
228     if (reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY)
229       if (reg_temp[i].stamp <= min_stamp) {
230         min_stamp = reg_temp[i].stamp;
231         oldest = i;
232       }
233   }
234
235   if (oldest == -1) {
236     printf("no registers to evict, aborting\n");
237     exit(1);
238   }
239
240   i = oldest;
241   if (reg_temp[i].type == HR_CACHED_DIRTY) {
242     // writeback
243     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
244   }
245
246   return &reg_temp[i];
247 }
248
249 typedef enum {
250   RC_GR_READ,
251   RC_GR_WRITE,
252   RC_GR_RMW,
253 } rc_gr_mode;
254
255 // note: must not be called when doing conditional code
256 static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
257 {
258   temp_reg_t *tr;
259   int i;
260
261   // maybe already statically mapped?
262   i = reg_map_g2h[r];
263   if (i != -1)
264     return i;
265
266   rcache_counter++;
267
268   // maybe already cached?
269   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
270     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
271          reg_temp[i].val == r)
272     {
273       reg_temp[i].stamp = rcache_counter;
274       if (mode != RC_GR_READ)
275         reg_temp[i].type = HR_CACHED_DIRTY;
276       return reg_temp[i].reg;
277     }
278   }
279
280   // use any free reg
281   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
282     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
283       tr = &reg_temp[i];
284       goto do_alloc;
285     }
286   }
287
288   tr = rcache_evict();
289
290 do_alloc:
291   if (mode != RC_GR_WRITE)
292     emith_ctx_read(tr->reg, r * 4);
293
294   tr->type = mode != RC_GR_READ ? HR_CACHED_DIRTY : HR_CACHED;
295   tr->val = r;
296   tr->stamp = rcache_counter;
297   return tr->reg;
298 }
299
300 static int rcache_get_tmp(void)
301 {
302   temp_reg_t *tr;
303   int i;
304
305   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
306     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
307       tr = &reg_temp[i];
308       goto do_alloc;
309     }
310
311   tr = rcache_evict();
312
313 do_alloc:
314   tr->type = HR_TEMP;
315   return tr->reg;
316 }
317
318 static int rcache_get_arg_id(int arg)
319 {
320   int i, r = 0;
321   host_arg2reg(r, arg);
322
323   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
324     if (reg_temp[i].reg == r)
325       break;
326
327   if (i == ARRAY_SIZE(reg_temp))
328     // let's just say it's untracked arg reg
329     return r;
330
331   if (reg_temp[i].type == HR_CACHED_DIRTY) {
332     // writeback
333     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
334   }
335   else if (reg_temp[i].type == HR_TEMP) {
336     printf("arg %d reg %d already used, aborting\n", arg, r);
337     exit(1);
338   }
339
340   return i;
341 }
342
343 // get a reg to be used as function arg
344 // it's assumed that regs are cleaned before call
345 static int rcache_get_tmp_arg(int arg)
346 {
347   int id = rcache_get_arg_id(arg);
348   reg_temp[id].type = HR_TEMP;
349
350   return reg_temp[id].reg;
351 }
352
353 // same but caches reg. RC_GR_READ only.
354 static int rcache_get_reg_arg(int arg, sh2_reg_e r)
355 {
356   int i, srcr, dstr, dstid;
357
358   dstid = rcache_get_arg_id(arg);
359   dstr = reg_temp[dstid].reg;
360
361   // maybe already statically mapped?
362   srcr = reg_map_g2h[r];
363   if (srcr != -1)
364     goto do_cache;
365
366   // maybe already cached?
367   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
368     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
369          reg_temp[i].val == r)
370     {
371       srcr = reg_temp[i].reg;
372       goto do_cache;
373     }
374   }
375
376   // must read
377   srcr = dstr;
378   emith_ctx_read(srcr, r * 4);
379
380 do_cache:
381   if (srcr != dstr)
382     emith_move_r_r(dstr, srcr);
383
384   reg_temp[dstid].stamp = ++rcache_counter;
385   reg_temp[dstid].type = HR_CACHED;
386   reg_temp[dstid].val = r;
387   return dstr;
388 }
389
390 static void rcache_free_tmp(int hr)
391 {
392   int i;
393   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
394     if (reg_temp[i].reg == hr)
395       break;
396
397   if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
398     printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
399     return;
400   }
401
402   reg_temp[i].type = HR_FREE;
403 }
404
405 static void rcache_clean(void)
406 {
407   int i;
408   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
409     if (reg_temp[i].type == HR_CACHED_DIRTY) {
410       // writeback
411       emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
412       reg_temp[i].type = HR_CACHED;
413     }
414 }
415
416 static void rcache_invalidate(void)
417 {
418   int i;
419   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
420     reg_temp[i].type = HR_FREE;
421   rcache_counter = 0;
422 }
423
424 static void rcache_flush(void)
425 {
426   rcache_clean();
427   rcache_invalidate();
428 }
429
430 // ---------------------------------------------------------------
431
432 static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
433 {
434   int hr = rcache_get_reg(dst, RC_GR_WRITE);
435   emith_move_r_imm(hr, imm);
436 }
437
438 static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
439 {
440   int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
441   int hr_s = rcache_get_reg(src, RC_GR_READ);
442
443   emith_move_r_r(hr_d, hr_s);
444 }
445
446 // arguments must be ready
447 // reg cache must be clean before call
448 static int emit_memhandler_read(int size)
449 {
450   int ctxr;
451   host_arg2reg(ctxr, 1);
452   emith_move_r_r(ctxr, CONTEXT_REG);
453   switch (size) {
454   case 0: // 8
455     emith_call(p32x_sh2_read8);
456     break;
457   case 1: // 16
458     emith_call(p32x_sh2_read16);
459     break;
460   case 2: // 32
461     emith_call(p32x_sh2_read32);
462     break;
463   }
464   rcache_invalidate();
465   // assuming arg0 and retval reg matches
466   return rcache_get_tmp_arg(0);
467 }
468
469 static void emit_memhandler_write(int size)
470 {
471   int ctxr;
472   host_arg2reg(ctxr, 2);
473   emith_move_r_r(ctxr, CONTEXT_REG);
474   switch (size) {
475   case 0: // 8
476     emith_call(p32x_sh2_write8);
477     break;
478   case 1: // 16
479     emith_call(p32x_sh2_write16);
480     break;
481   case 2: // 32
482     emith_call(p32x_sh2_write32);
483     break;
484   }
485   rcache_invalidate();
486 }
487
488 /*
489 MOV   #imm,Rn       1110nnnniiiiiiii
490 MOV.W @(disp,PC),Rn 1001nnnndddddddd
491 MOV.L @(disp,PC),Rn 1101nnnndddddddd
492 MOV   Rm,Rn         0110nnnnmmmm0011
493 MOV.B @Rm,Rn        0110nnnnmmmm0000
494 MOV.W @Rm,Rn        0110nnnnmmmm0001
495 MOV.L @Rm,Rn        0110nnnnmmmm0010
496 MOV.B @Rm+,Rn       0110nnnnmmmm0100
497 MOV.W @Rm+,Rn       0110nnnnmmmm0101
498 MOV.L @Rm+,Rn       0110nnnnmmmm0110
499 MOV.B R0,@(disp,Rn) 10000000nnnndddd
500 MOV.W R0,@(disp,Rn) 10000001nnnndddd
501 MOV.B @(disp,Rm),R0 10000100mmmmdddd
502 MOV.W @(disp,Rm),R0 10000101mmmmdddd
503 MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
504 MOV.B    R0,@(disp,GBR)   11000000dddddddd
505 MOV.W    R0,@(disp,GBR)   11000001dddddddd
506 MOV.L    R0,@(disp,GBR)   11000010dddddddd
507 MOV.B    @(disp,GBR),R0   11000100dddddddd
508 MOV.W    @(disp,GBR),R0   11000101dddddddd
509 MOV.L    @(disp,GBR),R0   11000110dddddddd
510 MOVA     @(disp,PC),R0    11000111dddddddd
511 SWAP.B Rm,Rn              0110nnnnmmmm1000
512 SWAP.W Rm,Rn              0110nnnnmmmm1001
513 ADD         #imm,Rn  0111nnnniiiiiiii
514 CMP/EQ      #imm,R0  10001000iiiiiiii
515 EXTS.B Rm,Rn         0110nnnnmmmm1110
516 EXTS.W Rm,Rn         0110nnnnmmmm1111
517 EXTU.B Rm,Rn         0110nnnnmmmm1100
518 EXTU.W Rm,Rn         0110nnnnmmmm1101
519 MAC       @Rm+,@Rn+  0100nnnnmmmm1111
520 NEG       Rm,Rn      0110nnnnmmmm1011
521 NEGC      Rm,Rn      0110nnnnmmmm1010
522 AND      #imm,R0             11001001iiiiiiii
523 AND.B    #imm,@(R0,GBR)      11001101iiiiiiii
524 NOT      Rm,Rn               0110nnnnmmmm0111
525 OR       #imm,R0             11001011iiiiiiii
526 OR.B     #imm,@(R0,GBR)      11001111iiiiiiii
527 TAS.B    @Rn                 0100nnnn00011011
528 TST      #imm,R0             11001000iiiiiiii
529 TST.B    #imm,@(R0,GBR)      11001100iiiiiiii
530 XOR      #imm,R0             11001010iiiiiiii
531 XOR.B    #imm,@(R0,GBR)      11001110iiiiiiii
532 SHLL2    Rn        0100nnnn00001000
533 SHLR2    Rn        0100nnnn00001001
534 SHLL8    Rn        0100nnnn00011000
535 SHLR8    Rn        0100nnnn00011001
536 SHLL16 Rn          0100nnnn00101000
537 SHLR16 Rn          0100nnnn00101001
538 LDC      Rm,GBR    0100mmmm00011110
539 LDC      Rm,VBR    0100mmmm00101110
540 LDS      Rm,MACH   0100mmmm00001010
541 LDS      Rm,MACL   0100mmmm00011010
542 LDS      Rm,PR     0100mmmm00101010
543 TRAPA    #imm      11000011iiiiiiii
544 */
545
546 #define DELAYED_OP \
547   delayed_op = 2
548
549 #define CHECK_UNHANDLED_BITS(mask) { \
550   if ((op & (mask)) != 0) \
551     goto default_; \
552 }
553
554 #define GET_Fx() \
555   ((op >> 4) & 0x0f)
556
557 #define GET_Rm GET_Fx
558
559 #define GET_Rn() \
560   ((op >> 8) & 0x0f)
561
562 #define CHECK_FX_LT(n) \
563   if (GET_Fx() < n) \
564     goto default_
565
566 static void *sh2_translate(SH2 *sh2, block_desc *other_block)
567 {
568   void *block_entry;
569   block_desc *this_block;
570   unsigned int pc = sh2->pc;
571   int op, delayed_op = 0, test_irq = 0;
572   int tcache_id = 0, blkid = 0;
573   int cycles = 0;
574   u32 tmp, tmp2, tmp3, tmp4;
575
576   // validate PC
577   tmp = sh2->pc >> 29;
578   if ((tmp != 0 && tmp != 1 && tmp != 6) || sh2->pc == 0) {
579     printf("invalid PC, aborting: %08x\n", sh2->pc);
580     // FIXME: be less destructive
581     exit(1);
582   }
583
584   if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
585     // data_array, BIOS have separate tcache (shared)
586     tcache_id = 1 + sh2->is_slave;
587   }
588
589   tcache_ptr = tcache_ptrs[tcache_id];
590   this_block = dr_add_block(pc, tcache_id, &blkid);
591
592   tmp = tcache_ptr - tcache_bases[tcache_id];
593   if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE || this_block == NULL) {
594     flush_tcache(tcache_id);
595     tcache_ptr = tcache_ptrs[tcache_id];
596     other_block = NULL; // also gone too due to flush
597     this_block = dr_add_block(pc, tcache_id, &blkid);
598   }
599
600   this_block->next = other_block;
601   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
602     HASH_FUNC(hash_table, pc) = this_block;
603
604   block_entry = tcache_ptr;
605 #if (DRC_DEBUG & 1)
606   printf("== %csh2 block #%d,%d %08x -> %p\n", sh2->is_slave ? 's' : 'm',
607     tcache_id, block_counts[tcache_id], pc, block_entry);
608   if (other_block != NULL) {
609     printf(" hash collision with %08x\n", other_block->addr);
610     hash_collisions++;
611   }
612 #endif
613
614   while (cycles < BLOCK_CYCLE_LIMIT || delayed_op)
615   {
616     if (delayed_op > 0)
617       delayed_op--;
618
619     op = p32x_sh2_read16(pc, sh2);
620
621 #if (DRC_DEBUG & 3)
622     insns_compiled++;
623 #if (DRC_DEBUG & 2)
624     DasmSH2(sh2dasm_buff, pc, op);
625     printf("%08x %04x %s\n", pc, op, sh2dasm_buff);
626 #endif
627 #endif
628
629     pc += 2;
630     cycles++;
631
632     switch ((op >> 12) & 0x0f)
633     {
634     /////////////////////////////////////////////
635     case 0x00:
636       switch (op & 0x0f)
637       {
638       case 0x02:
639         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
640         switch (GET_Fx())
641         {
642         case 0: // STC SR,Rn  0000nnnn00000010
643           tmp2 = SHR_SR;
644           break;
645         case 1: // STC GBR,Rn 0000nnnn00010010
646           tmp2 = SHR_GBR;
647           break;
648         case 2: // STC VBR,Rn 0000nnnn00100010
649           tmp2 = SHR_VBR;
650           break;
651         default:
652           goto default_;
653         }
654         tmp3 = rcache_get_reg(tmp2, RC_GR_READ);
655         emith_move_r_r(tmp, tmp3);
656         if (tmp2 == SHR_SR)
657           emith_clear_msb(tmp, tmp, 20); // reserved bits defined by ISA as 0
658         goto end_op;
659       case 0x03:
660         CHECK_UNHANDLED_BITS(0xd0);
661         // BRAF Rm    0000mmmm00100011
662         // BSRF Rm    0000mmmm00000011
663         DELAYED_OP;
664         if (!(op & 0x20))
665           emit_move_r_imm32(SHR_PR, pc + 2);
666         tmp = rcache_get_reg(SHR_PPC, RC_GR_WRITE);
667         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
668         emith_move_r_r(tmp, tmp2);
669         emith_add_r_imm(tmp, pc + 2);
670         cycles++;
671         goto end_op;
672       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
673       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
674       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
675         rcache_clean();
676         tmp  = rcache_get_reg_arg(0, SHR_R0);
677         tmp2 = rcache_get_reg_arg(1, GET_Rm());
678         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_READ);
679         emith_add_r_r(tmp, tmp3);
680         emit_memhandler_write(op & 3);
681         goto end_op;
682       case 0x07:
683         // MUL.L     Rm,Rn      0000nnnnmmmm0111
684         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
685         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
686         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
687         emith_mul(tmp3, tmp2, tmp);
688         cycles++;
689         goto end_op;
690       case 0x08:
691         CHECK_UNHANDLED_BITS(0xf00);
692         switch (GET_Fx())
693         {
694         case 0: // CLRT               0000000000001000
695           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
696           emith_bic_r_imm(tmp, T);
697           break;
698         case 1: // SETT               0000000000011000
699           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
700           emith_or_r_imm(tmp, T);
701           break;
702         case 2: // CLRMAC             0000000000101000
703           tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
704           emith_move_r_imm(tmp, 0);
705           tmp = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
706           emith_move_r_imm(tmp, 0);
707           break;
708         default:
709           goto default_;
710         }
711         goto end_op;
712       case 0x09:
713         switch (GET_Fx())
714         {
715         case 0: // NOP        0000000000001001
716           CHECK_UNHANDLED_BITS(0xf00);
717           break;
718         case 1: // DIV0U      0000000000011001
719           CHECK_UNHANDLED_BITS(0xf00);
720           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
721           emith_bic_r_imm(tmp, M|Q|T);
722           break;
723         case 2: // MOVT Rn    0000nnnn00101001
724           tmp  = rcache_get_reg(SHR_SR, RC_GR_READ);
725           tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
726           emith_clear_msb(tmp2, tmp, 31);
727           break;
728         default:
729           goto default_;
730         }
731         goto end_op;
732       case 0x0a:
733         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
734         switch (GET_Fx())
735         {
736         case 0: // STS      MACH,Rn   0000nnnn00001010
737           tmp2 = SHR_MACH;
738           break;
739         case 1: // STS      MACL,Rn   0000nnnn00011010
740           tmp2 = SHR_MACL;
741           break;
742         case 2: // STS      PR,Rn     0000nnnn00101010
743           tmp2 = SHR_PR;
744           break;
745         default:
746           goto default_;
747         }
748         tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
749         emith_move_r_r(tmp, tmp2);
750         goto end_op;
751       case 0x0b:
752         CHECK_UNHANDLED_BITS(0xf00);
753         switch (GET_Fx())
754         {
755         case 0: // RTS        0000000000001011
756           DELAYED_OP;
757           emit_move_r_r(SHR_PPC, SHR_PR);
758           cycles++;
759           break;
760         case 1: // SLEEP      0000000000011011
761           emit_move_r_imm32(SHR_PC, pc - 2);
762           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
763           emith_clear_msb(tmp, tmp, 20); // clear cycles
764           test_irq = 1;
765           cycles = 1;
766           break;
767         case 2: // RTE        0000000000101011
768           //emit_move_r_r(SHR_PC, SHR_PR);
769           emit_move_r_imm32(SHR_PC, pc - 2);
770           rcache_flush();
771           emith_pass_arg_r(0, CONTEXT_REG);
772           emith_pass_arg_imm(1, op);
773           emith_call(sh2_do_op);
774           emit_move_r_r(SHR_PPC, SHR_PC);
775           test_irq = 1;
776           cycles += 3;
777           break;
778         default:
779           goto default_;
780         }
781         goto end_op;
782       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
783       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
784       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
785         rcache_clean();
786         tmp  = rcache_get_reg_arg(0, SHR_R0);
787         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
788         emith_add_r_r(tmp, tmp2);
789         tmp  = emit_memhandler_read(op & 3);
790         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
791         rcache_free_tmp(tmp);
792         if ((op & 3) != 2) {
793           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
794         } else
795           emith_move_r_r(tmp2, tmp);
796         goto end_op;
797       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
798         // TODO
799         break;
800       }
801       goto default_;
802
803     /////////////////////////////////////////////
804     case 0x01:
805       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
806       rcache_clean();
807       tmp  = rcache_get_reg_arg(0, GET_Rn());
808       tmp2 = rcache_get_reg_arg(1, GET_Rm());
809       emith_add_r_imm(tmp, (op & 0x0f) * 4);
810       emit_memhandler_write(2);
811       goto end_op;
812
813     case 0x02:
814       switch (op & 0x0f)
815       {
816       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
817       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
818       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
819         rcache_clean();
820         rcache_get_reg_arg(0, GET_Rn());
821         rcache_get_reg_arg(1, GET_Rm());
822         emit_memhandler_write(op & 3);
823         goto end_op;
824       case 0x04: // MOV.B Rm,@–Rn       0010nnnnmmmm0100
825       case 0x05: // MOV.W Rm,@–Rn       0010nnnnmmmm0101
826       case 0x06: // MOV.L Rm,@–Rn       0010nnnnmmmm0110
827         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
828         emith_sub_r_imm(tmp, (1 << (op & 3)));
829         rcache_clean();
830         rcache_get_reg_arg(0, GET_Rn());
831         rcache_get_reg_arg(1, GET_Rm());
832         emit_memhandler_write(op & 3);
833         goto end_op;
834       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
835         tmp  = rcache_get_reg(SHR_SR, RC_GR_RMW);
836         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
837         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
838         emith_bic_r_imm(tmp, M|Q|T);
839         emith_tst_r_imm(tmp2, (1<<31));
840         EMITH_SJMP_START(DCOND_EQ);
841         emith_or_r_imm_c(DCOND_NE, tmp, Q);
842         EMITH_SJMP_END(DCOND_EQ);
843         emith_tst_r_imm(tmp3, (1<<31));
844         EMITH_SJMP_START(DCOND_EQ);
845         emith_or_r_imm_c(DCOND_NE, tmp, M);
846         EMITH_SJMP_END(DCOND_EQ);
847         emith_teq_r_r(tmp2, tmp3);
848         EMITH_SJMP_START(DCOND_PL);
849         emith_or_r_imm_c(DCOND_MI, tmp, T);
850         EMITH_SJMP_END(DCOND_PL);
851         goto end_op;
852       case 0x08: // TST Rm,Rn           0010nnnnmmmm1000
853         tmp  = rcache_get_reg(SHR_SR, RC_GR_RMW);
854         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
855         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
856         emith_bic_r_imm(tmp, T);
857         emith_tst_r_r(tmp2, tmp3);
858         EMITH_SJMP_START(DCOND_NE);
859         emith_or_r_imm_c(DCOND_EQ, tmp, T);
860         EMITH_SJMP_END(DCOND_NE);
861         goto end_op;
862       case 0x09: // AND Rm,Rn           0010nnnnmmmm1001
863         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
864         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
865         emith_and_r_r(tmp, tmp2);
866         goto end_op;
867       case 0x0a: // XOR Rm,Rn           0010nnnnmmmm1010
868         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
869         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
870         emith_eor_r_r(tmp, tmp2);
871         goto end_op;
872       case 0x0b: // OR  Rm,Rn           0010nnnnmmmm1011
873         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
874         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
875         emith_or_r_r(tmp, tmp2);
876         goto end_op;
877       case 0x0c: // CMP/STR Rm,Rn       0010nnnnmmmm1100
878         tmp  = rcache_get_tmp();
879         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
880         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
881         emith_eor_r_r_r(tmp, tmp2, tmp3);
882         tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
883         emith_bic_r_imm(tmp2, T);
884         emith_tst_r_imm(tmp, 0x000000ff);
885         EMITH_SJMP_START(DCOND_NE);
886         emith_or_r_imm_c(DCOND_EQ, tmp2, T);
887         EMITH_SJMP_END(DCOND_NE);
888         emith_tst_r_imm(tmp, 0x0000ff00);
889         EMITH_SJMP_START(DCOND_NE);
890         emith_or_r_imm_c(DCOND_EQ, tmp2, T);
891         EMITH_SJMP_END(DCOND_NE);
892         emith_tst_r_imm(tmp, 0x00ff0000);
893         EMITH_SJMP_START(DCOND_NE);
894         emith_or_r_imm_c(DCOND_EQ, tmp2, T);
895         EMITH_SJMP_END(DCOND_NE);
896         emith_tst_r_imm(tmp, 0xff000000);
897         EMITH_SJMP_START(DCOND_NE);
898         emith_or_r_imm_c(DCOND_EQ, tmp2, T);
899         EMITH_SJMP_END(DCOND_NE);
900         rcache_free_tmp(tmp);
901         goto end_op;
902       case 0x0d: // XTRCT  Rm,Rn        0010nnnnmmmm1101
903         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
904         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
905         emith_lsr(tmp, tmp, 16);
906         emith_or_r_r_r_lsl(tmp, tmp, tmp2, 16);
907         goto end_op;
908       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
909       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
910         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
911         tmp  = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
912         if (op & 1) {
913           emith_sext(tmp, tmp2, 16);
914         } else
915           emith_clear_msb(tmp, tmp2, 16);
916         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
917         tmp2 = rcache_get_tmp();
918         if (op & 1) {
919           emith_sext(tmp2, tmp3, 16);
920         } else
921           emith_clear_msb(tmp2, tmp3, 16);
922         emith_mul(tmp, tmp, tmp2);
923         rcache_free_tmp(tmp2);
924 //      FIXME: causes timing issues in Doom?
925 //        cycles++;
926         goto end_op;
927       }
928       goto default_;
929
930     /////////////////////////////////////////////
931     case 0x03:
932       switch (op & 0x0f)
933       {
934       case 0x00: // CMP/EQ Rm,Rn        0011nnnnmmmm0000
935       case 0x02: // CMP/HS Rm,Rn        0011nnnnmmmm0010
936       case 0x03: // CMP/GE Rm,Rn        0011nnnnmmmm0011
937       case 0x06: // CMP/HI Rm,Rn        0011nnnnmmmm0110
938       case 0x07: // CMP/GT Rm,Rn        0011nnnnmmmm0111
939         tmp  = rcache_get_reg(SHR_SR, RC_GR_RMW);
940         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
941         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
942         emith_bic_r_imm(tmp, T);
943         emith_cmp_r_r(tmp2, tmp3);
944         switch (op & 0x07)
945         {
946         case 0x00: // CMP/EQ
947           EMITH_SJMP_START(DCOND_NE);
948           emith_or_r_imm_c(DCOND_EQ, tmp, T);
949           EMITH_SJMP_END(DCOND_NE);
950           break;
951         case 0x02: // CMP/HS
952           EMITH_SJMP_START(DCOND_LO);
953           emith_or_r_imm_c(DCOND_HS, tmp, T);
954           EMITH_SJMP_END(DCOND_LO);
955           break;
956         case 0x03: // CMP/GE
957           EMITH_SJMP_START(DCOND_LT);
958           emith_or_r_imm_c(DCOND_GE, tmp, T);
959           EMITH_SJMP_END(DCOND_LT);
960           break;
961         case 0x06: // CMP/HI
962           EMITH_SJMP_START(DCOND_LS);
963           emith_or_r_imm_c(DCOND_HI, tmp, T);
964           EMITH_SJMP_END(DCOND_LS);
965           break;
966         case 0x07: // CMP/GT
967           EMITH_SJMP_START(DCOND_LE);
968           emith_or_r_imm_c(DCOND_GT, tmp, T);
969           EMITH_SJMP_END(DCOND_LE);
970           break;
971         }
972         goto end_op;
973       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
974         // TODO
975         break;
976       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
977         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
978         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
979         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
980         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
981         emith_mul_u64(tmp3, tmp4, tmp, tmp2);
982         goto end_op;
983       case 0x08: // SUB     Rm,Rn       0011nnnnmmmm1000
984       case 0x0c: // ADD     Rm,Rn       0011nnnnmmmm1100
985         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
986         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
987         if (op & 4) {
988           emith_add_r_r(tmp, tmp2);
989         } else
990           emith_sub_r_r(tmp, tmp2);
991         goto end_op;
992       case 0x0a: // SUBC    Rm,Rn       0011nnnnmmmm1010
993       case 0x0e: // ADDC    Rm,Rn       0011nnnnmmmm1110
994         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
995         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
996         tmp3 = rcache_get_reg(SHR_SR, RC_GR_RMW);
997         if (op & 4) { // adc
998           emith_set_carry(tmp3);
999           emith_adcf_r_r(tmp, tmp2);
1000           emith_carry_to_t(tmp3, 0);
1001         } else {
1002           emith_set_carry_sub(tmp3);
1003           emith_sbcf_r_r(tmp, tmp2);
1004           emith_carry_to_t(tmp3, 1);
1005         }
1006         goto end_op;
1007       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
1008       case 0x0f: // ADDV    Rm,Rn       0011nnnnmmmm1111
1009         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1010         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1011         tmp3 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1012         emith_bic_r_imm(tmp3, T);
1013         if (op & 4) {
1014           emith_addf_r_r(tmp, tmp2);
1015         } else
1016           emith_subf_r_r(tmp, tmp2);
1017         EMITH_SJMP_START(DCOND_VC);
1018         emith_or_r_imm_c(DCOND_VS, tmp3, T);
1019         EMITH_SJMP_END(DCOND_VC);
1020         goto end_op;
1021       case 0x0d: // DMULS.L Rm,Rn       0011nnnnmmmm1101
1022         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1023         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1024         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1025         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1026         emith_mul_s64(tmp3, tmp4, tmp, tmp2);
1027         goto end_op;
1028       }
1029       goto default_;
1030
1031     /////////////////////////////////////////////
1032     case 0x04:
1033       switch (op & 0x0f)
1034       {
1035       case 0x00:
1036         switch (GET_Fx())
1037         {
1038         case 0: // SHLL Rn    0100nnnn00000000
1039         case 2: // SHAL Rn    0100nnnn00100000
1040           tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1041           tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1042           emith_lslf(tmp, tmp, 1);
1043           emith_carry_to_t(tmp2,  0);
1044           goto end_op;
1045         case 1: // DT Rn      0100nnnn00010000
1046           if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2
1047             emith_sh2_dtbf_loop();
1048             goto end_op;
1049           }
1050           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1051           tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1052           emith_bic_r_imm(tmp2, T);
1053           emith_subf_r_imm(tmp, 1);
1054           EMITH_SJMP_START(DCOND_NE);
1055           emith_or_r_imm_c(DCOND_EQ, tmp2, T);
1056           EMITH_SJMP_END(DCOND_NE);
1057           goto end_op;
1058         }
1059         goto default_;
1060       case 0x01:
1061         switch (GET_Fx())
1062         {
1063         case 0: // SHLR Rn    0100nnnn00000001
1064         case 2: // SHAR Rn    0100nnnn00100001
1065           tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1066           tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1067           if (op & 0x20) {
1068             emith_asrf(tmp, tmp, 1);
1069           } else
1070             emith_lsrf(tmp, tmp, 1);
1071           emith_carry_to_t(tmp2, 0);
1072           goto end_op;
1073         case 1: // CMP/PZ Rn  0100nnnn00010001
1074           tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1075           tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1076           emith_bic_r_imm(tmp2, T);
1077           emith_cmp_r_imm(tmp, 0);
1078           EMITH_SJMP_START(DCOND_LT);
1079           emith_or_r_imm_c(DCOND_GE, tmp2, T);
1080           EMITH_SJMP_END(DCOND_LT);
1081           goto end_op;
1082         }
1083         goto default_;
1084       case 0x02:
1085       case 0x03:
1086         switch (op & 0x3f)
1087         {
1088         case 0x02: // STS.L    MACH,@–Rn 0100nnnn00000010
1089           tmp = SHR_MACH;
1090           break;
1091         case 0x12: // STS.L    MACL,@–Rn 0100nnnn00010010
1092           tmp = SHR_MACL;
1093           break;
1094         case 0x22: // STS.L    PR,@–Rn   0100nnnn00100010
1095           tmp = SHR_PR;
1096           break;
1097         case 0x03: // STC.L    SR,@–Rn   0100nnnn00000011
1098           tmp = SHR_SR;
1099           break;
1100         case 0x13: // STC.L    GBR,@–Rn  0100nnnn00010011
1101           tmp = SHR_GBR;
1102           break;
1103         case 0x23: // STC.L    VBR,@–Rn  0100nnnn00100011
1104           tmp = SHR_VBR;
1105           break;
1106         default:
1107           goto default_;
1108         }
1109         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1110         emith_sub_r_imm(tmp2, 4);
1111         rcache_clean();
1112         rcache_get_reg_arg(0, GET_Rn());
1113         tmp3 = rcache_get_reg_arg(1, tmp);
1114         if (tmp == SHR_SR)
1115           emith_clear_msb(tmp3, tmp3, 20); // reserved bits defined by ISA as 0
1116         emit_memhandler_write(2);
1117         goto end_op;
1118       case 0x04:
1119       case 0x05:
1120         switch (op & 0x3f)
1121         {
1122         case 0x04: // ROTL   Rn          0100nnnn00000100
1123         case 0x05: // ROTR   Rn          0100nnnn00000101
1124           tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1125           tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1126           if (op & 1) {
1127             emith_rorf(tmp, tmp, 1);
1128           } else
1129             emith_rolf(tmp, tmp, 1);
1130           emith_carry_to_t(tmp2, 0);
1131           goto end_op;
1132         case 0x24: // ROTCL  Rn          0100nnnn00100100
1133         case 0x25: // ROTCR  Rn          0100nnnn00100101
1134           tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1135           tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1136           emith_set_carry(tmp2);
1137           if (op & 1) {
1138             emith_rorcf(tmp);
1139           } else
1140             emith_rolcf(tmp);
1141           emith_carry_to_t(tmp2, 0);
1142           goto end_op;
1143         case 0x15: // CMP/PL Rn          0100nnnn00010101
1144           tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1145           tmp2 = rcache_get_reg(SHR_SR, RC_GR_RMW);
1146           emith_bic_r_imm(tmp2, T);
1147           emith_cmp_r_imm(tmp, 0);
1148           EMITH_SJMP_START(DCOND_LE);
1149           emith_or_r_imm_c(DCOND_GT, tmp2, T);
1150           EMITH_SJMP_END(DCOND_LE);
1151           goto end_op;
1152         }
1153         goto default_;
1154       case 0x06:
1155       case 0x07:
1156         switch (op & 0x3f)
1157         {
1158         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
1159           tmp = SHR_MACH;
1160           break;
1161         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
1162           tmp = SHR_MACL;
1163           break;
1164         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
1165           tmp = SHR_PR;
1166           break;
1167         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
1168           tmp = SHR_SR;
1169           break;
1170         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
1171           tmp = SHR_GBR;
1172           break;
1173         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
1174           tmp = SHR_VBR;
1175           break;
1176         default:
1177           goto default_;
1178         }
1179         rcache_clean();
1180         rcache_get_reg_arg(0, GET_Rn());
1181         tmp2 = emit_memhandler_read(2);
1182         if (tmp == SHR_SR) {
1183           emith_write_sr(tmp2);
1184           test_irq = 1;
1185         } else {
1186           tmp = rcache_get_reg(tmp, RC_GR_WRITE);
1187           emith_move_r_r(tmp, tmp2);
1188         }
1189         rcache_free_tmp(tmp2);
1190         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1191         emith_add_r_imm(tmp, 4);
1192         goto end_op;
1193       case 0x0b:
1194         if ((op & 0xd0) != 0)
1195           goto default_;
1196         // JMP  @Rm   0100mmmm00101011
1197         // JSR  @Rm   0100mmmm00001011
1198         DELAYED_OP;
1199         if (!(op & 0x20))
1200           emit_move_r_imm32(SHR_PR, pc + 2);
1201         emit_move_r_r(SHR_PPC, (op >> 8) & 0x0f);
1202         cycles++;
1203         goto end_op;
1204       case 0x0e:
1205         if ((op & 0xf0) != 0)
1206           goto default_;
1207         // LDC Rm,SR  0100mmmm00001110
1208         test_irq = 1;
1209         goto default_;
1210       }
1211       goto default_;
1212
1213     /////////////////////////////////////////////
1214     case 0x08:
1215       switch (op & 0x0f00) {
1216       // BT/S label 10001101dddddddd
1217       case 0x0d00:
1218       // BF/S label 10001111dddddddd
1219       case 0x0f00:
1220         DELAYED_OP;
1221         cycles--;
1222         // fallthrough
1223       // BT   label 10001001dddddddd
1224       case 0x0900:
1225       // BF   label 10001011dddddddd
1226       case 0x0b00: {
1227         // jmp_cond ~ cond when guest doesn't jump
1228         int jmp_cond  = (op & 0x0200) ? DCOND_NE : DCOND_EQ;
1229         int insn_cond = (op & 0x0200) ? DCOND_EQ : DCOND_NE;
1230         signed int offs = ((signed int)(op << 24) >> 23);
1231         tmp = rcache_get_reg(delayed_op ? SHR_PPC : SHR_PC, RC_GR_WRITE);
1232         emith_move_r_imm(tmp, pc + (delayed_op ? 2 : 0));
1233         emith_sh2_test_t();
1234         EMITH_SJMP_START(jmp_cond);
1235         if (!delayed_op)
1236           offs += 2;
1237         if (offs < 0) {
1238           emith_sub_r_imm_c(insn_cond, tmp, -offs);
1239         } else
1240           emith_add_r_imm_c(insn_cond, tmp, offs);
1241         EMITH_SJMP_END(jmp_cond);
1242         cycles += 2;
1243         if (!delayed_op)
1244           goto end_block;
1245         goto end_op;
1246       }}
1247       goto default_;
1248
1249     /////////////////////////////////////////////
1250     case 0x0a:
1251       // BRA  label 1010dddddddddddd
1252       DELAYED_OP;
1253     do_bra:
1254       tmp = ((signed int)(op << 20) >> 19);
1255       emit_move_r_imm32(SHR_PPC, pc + tmp + 2);
1256       cycles++;
1257       break;
1258
1259     /////////////////////////////////////////////
1260     case 0x0b:
1261       // BSR  label 1011dddddddddddd
1262       DELAYED_OP;
1263       emit_move_r_imm32(SHR_PR, pc + 2);
1264       goto do_bra;
1265
1266     default:
1267     default_:
1268       emit_move_r_imm32(SHR_PC, pc - 2);
1269       rcache_flush();
1270       emith_pass_arg_r(0, CONTEXT_REG);
1271       emith_pass_arg_imm(1, op);
1272       emith_call(sh2_do_op);
1273       break;
1274     }
1275
1276 end_op:
1277     if (delayed_op == 1)
1278       emit_move_r_r(SHR_PC, SHR_PPC);
1279
1280     if (test_irq && delayed_op != 2) {
1281       rcache_flush();
1282       emith_pass_arg_r(0, CONTEXT_REG);
1283       emith_call(sh2_test_irq);
1284       break;
1285     }
1286     if (delayed_op == 1)
1287       break;
1288
1289     do_host_disasm(tcache_id);
1290   }
1291
1292 end_block:
1293   this_block->end_addr = pc;
1294
1295   // mark memory blocks as containing compiled code
1296   if ((sh2->pc & 0xe0000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1297     // data array, BIOS
1298     u16 *drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
1299     tmp =  (this_block->addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1300     tmp2 = (this_block->end_addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
1301     Pico32xMem->drcblk_da[sh2->is_slave][tmp] = (blkid << 1) | 1;
1302     for (++tmp; tmp < tmp2; tmp++) {
1303       if (drcblk[tmp])
1304         break; // dont overwrite overlay block
1305       drcblk[tmp] = blkid << 1;
1306     }
1307   }
1308   else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
1309     tmp =  (this_block->addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1310     tmp2 = (this_block->end_addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
1311     Pico32xMem->drcblk_ram[tmp] = (blkid << 1) | 1;
1312     for (++tmp; tmp < tmp2; tmp++) {
1313       if (Pico32xMem->drcblk_ram[tmp])
1314         break;
1315       Pico32xMem->drcblk_ram[tmp] = blkid << 1;
1316     }
1317   }
1318
1319   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
1320   emith_sub_r_imm(tmp, cycles << 12);
1321   rcache_flush();
1322   emith_jump(sh2_drc_exit);
1323   tcache_ptrs[tcache_id] = tcache_ptr;
1324
1325 #ifdef ARM
1326   cache_flush_d_inval_i(block_entry, tcache_ptr);
1327 #endif
1328
1329   do_host_disasm(tcache_id);
1330   dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
1331     tcache_id, block_counts[tcache_id],
1332     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
1333     insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
1334   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
1335     dbg(1, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
1336 #if (DRC_DEBUG & 2)
1337   fflush(stdout);
1338 #endif
1339
1340   return block_entry;
1341 /*
1342 unimplemented:
1343   // last op
1344   do_host_disasm(tcache_id);
1345   exit(1);
1346 */
1347 }
1348
1349 void __attribute__((noinline)) sh2_drc_dispatcher(SH2 *sh2)
1350 {
1351   while (((signed int)sh2->sr >> 12) > 0)
1352   {
1353     void *block = NULL;
1354     block_desc *bd = NULL;
1355
1356     // FIXME: must avoid doing it so often..
1357     sh2_test_irq(sh2);
1358
1359     // we have full block id tables for data_array and RAM
1360     // BIOS goes to data_array table too
1361     if ((sh2->pc & 0xff000000) == 0xc0000000 || (sh2->pc & ~0xfff) == 0) {
1362       int blkid = Pico32xMem->drcblk_da[sh2->is_slave][(sh2->pc & 0xfff) >> SH2_DRCBLK_DA_SHIFT];
1363       if (blkid & 1) {
1364         bd = &block_tables[1 + sh2->is_slave][blkid >> 1];
1365         block = bd->tcache_ptr;
1366       }
1367     }
1368     // RAM
1369     else if ((sh2->pc & 0xc6000000) == 0x06000000) {
1370       int blkid = Pico32xMem->drcblk_ram[(sh2->pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT];
1371       if (blkid & 1) {
1372         bd = &block_tables[0][blkid >> 1];
1373         block = bd->tcache_ptr;
1374       }
1375     }
1376     // ROM
1377     else if ((sh2->pc & 0xc6000000) == 0x02000000) {
1378       bd = HASH_FUNC(hash_table, sh2->pc);
1379
1380       if (bd != NULL) {
1381         if (bd->addr == sh2->pc)
1382           block = bd->tcache_ptr;
1383         else
1384           block = dr_find_block(bd, sh2->pc);
1385       }
1386     }
1387
1388     if (block == NULL)
1389       block = sh2_translate(sh2, bd);
1390
1391     dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
1392       sh2->pc, block, (signed int)sh2->sr >> 12);
1393 #if (DRC_DEBUG & 1)
1394     if (bd != NULL)
1395       bd->refcount++;
1396 #endif
1397     sh2_drc_entry(sh2, block);
1398   }
1399 }
1400
1401 static void sh2_smc_rm_block(u16 *drcblk, u16 *p, block_desc *btab, u32 a)
1402 {
1403   u16 id = *p >> 1;
1404   block_desc *bd = btab + id;
1405
1406   dbg(1, "  killing block %08x", bd->addr);
1407   bd->addr = bd->end_addr = 0;
1408
1409   while (p > drcblk && (p[-1] >> 1) == id)
1410     p--;
1411
1412   // check for possible overlay block
1413   if (p > 0 && p[-1] != 0) {
1414     bd = btab + (p[-1] >> 1);
1415     if (bd->addr <= a && a < bd->end_addr)
1416       sh2_smc_rm_block(drcblk, p - 1, btab, a);
1417   }
1418
1419   do {
1420     *p++ = 0;
1421   }
1422   while ((*p >> 1) == id);
1423 }
1424
1425 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
1426 {
1427   u16 *drcblk = Pico32xMem->drcblk_ram;
1428   u16 *p = drcblk + ((a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT);
1429
1430   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1431   sh2_smc_rm_block(drcblk, p, block_tables[0], a);
1432 }
1433
1434 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
1435 {
1436   u16 *drcblk = Pico32xMem->drcblk_da[cpuid];
1437   u16 *p = drcblk + ((a & 0xfff) >> SH2_DRCBLK_DA_SHIFT);
1438
1439   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
1440   sh2_smc_rm_block(drcblk, p, block_tables[1 + cpuid], a);
1441 }
1442
1443 void sh2_execute(SH2 *sh2, int cycles)
1444 {
1445   sh2->cycles_aim += cycles;
1446   cycles = sh2->cycles_aim - sh2->cycles_done;
1447
1448   // cycles are kept in SHR_SR unused bits (upper 20)
1449   sh2->sr &= 0x3f3;
1450   sh2->sr |= cycles << 12;
1451   sh2_drc_dispatcher(sh2);
1452
1453   sh2->cycles_done += cycles - ((signed int)sh2->sr >> 12);
1454 }
1455
1456 static void REGPARM(1) sh2_test_irq(SH2 *sh2)
1457 {
1458   if (sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
1459   {
1460     if (sh2->pending_irl > sh2->pending_int_irq)
1461       sh2_do_irq(sh2, sh2->pending_irl, 64 + sh2->pending_irl/2);
1462     else {
1463       sh2_do_irq(sh2, sh2->pending_int_irq, sh2->pending_int_vector);
1464       sh2->pending_int_irq = 0; // auto-clear
1465       sh2->pending_level = sh2->pending_irl;
1466     }
1467   }
1468 }
1469
1470 #if (DRC_DEBUG & 1)
1471 static void block_stats(void)
1472 {
1473   int c, b, i, total = 0;
1474
1475   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1476     for (i = 0; i < block_counts[b]; i++)
1477       if (block_tables[b][i].addr != 0)
1478         total += block_tables[b][i].refcount;
1479
1480   for (c = 0; c < 10; c++) {
1481     block_desc *blk, *maxb = NULL;
1482     int max = 0;
1483     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
1484       for (i = 0; i < block_counts[b]; i++) {
1485         blk = &block_tables[b][i];
1486         if (blk->addr != 0 && blk->refcount > max) {
1487           max = blk->refcount;
1488           maxb = blk;
1489         }
1490       }
1491     }
1492     if (maxb == NULL)
1493       break;
1494     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
1495       (double)maxb->refcount / total * 100.0);
1496     maxb->refcount = 0;
1497   }
1498
1499   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
1500     for (i = 0; i < block_counts[b]; i++)
1501       block_tables[b][i].refcount = 0;
1502 }
1503 #else
1504 #define block_stats()
1505 #endif
1506
1507 void sh2_drc_flush_all(void)
1508 {
1509   block_stats();
1510   flush_tcache(0);
1511   flush_tcache(1);
1512   flush_tcache(2);
1513 }
1514
1515 int sh2_drc_init(SH2 *sh2)
1516 {
1517   if (block_tables[0] == NULL) {
1518     int i, cnt;
1519
1520     drc_cmn_init();
1521
1522     cnt = block_max_counts[0] + block_max_counts[1] + block_max_counts[2];
1523     block_tables[0] = calloc(cnt, sizeof(*block_tables[0]));
1524     if (block_tables[0] == NULL)
1525       return -1;
1526
1527     memset(block_counts, 0, sizeof(block_counts));
1528     tcache_bases[0] = tcache_ptrs[0] = tcache;
1529
1530     for (i = 1; i < ARRAY_SIZE(block_tables); i++) {
1531       block_tables[i] = block_tables[i - 1] + block_max_counts[i - 1];
1532       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
1533     }
1534
1535     // tmp
1536     PicoOpt |= POPT_DIS_VDP_FIFO;
1537
1538 #if (DRC_DEBUG & 2)
1539     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
1540       tcache_dsm_ptrs[i] = tcache_bases[i];
1541 #endif
1542 #if (DRC_DEBUG & 1)
1543     hash_collisions = 0;
1544 #endif
1545   }
1546
1547   if (hash_table == NULL) {
1548     hash_table = calloc(sizeof(hash_table[0]), MAX_HASH_ENTRIES);
1549     if (hash_table == NULL)
1550       return -1;
1551   }
1552
1553   return 0;
1554 }
1555
1556 void sh2_drc_finish(SH2 *sh2)
1557 {
1558   if (block_tables[0] != NULL) {
1559     block_stats();
1560     free(block_tables[0]);
1561     memset(block_tables, 0, sizeof(block_tables));
1562
1563     drc_cmn_cleanup();
1564   }
1565
1566   if (hash_table != NULL) {
1567     free(hash_table);
1568     hash_table = NULL;
1569   }
1570 }