sh2 drc comments and missing pandora file
[picodrive.git] / cpu / sh2 / compiler.c
1 /*
2  * vim:shiftwidth=2:expandtab
3  *
4  * notes:
5  * - tcache, block descriptor, link buffer overflows result in sh2_translate()
6  *   failure, followed by full tcache invalidation for that region
7  * - jumps between blocks are tracked for SMC handling (in block_links[]),
8  *   except jumps between different tcaches
9  *
10  * implemented:
11  * - static register allocation
12  * - remaining register caching and tracking in temporaries
13  * - block-local branch linking
14  * - block linking (except between tcaches)
15  *
16  * TODO:
17  * - proper SMC handling
18  * - constant propagation
19  * - stack caching?
20  * - bug fixing
21  */
22 #include <stddef.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <assert.h>
26
27 #include "../../pico/pico_int.h"
28 #include "sh2.h"
29 #include "compiler.h"
30 #include "../drc/cmn.h"
31
32 // debug stuff {
33 #ifndef DRC_DEBUG
34 #define DRC_DEBUG 0
35 #endif
36
37 #if DRC_DEBUG
38 #define dbg(l,...) { \
39   if ((l) & DRC_DEBUG) \
40     elprintf(EL_STATUS, ##__VA_ARGS__); \
41 }
42
43 #include "mame/sh2dasm.h"
44 #include <platform/linux/host_dasm.h>
45 static int insns_compiled, hash_collisions, host_insn_count;
46 #define COUNT_OP \
47         host_insn_count++
48 #else // !DRC_DEBUG
49 #define COUNT_OP
50 #define dbg(...)
51 #endif
52
53 #if (DRC_DEBUG & 2)
54 static u8 *tcache_dsm_ptrs[3];
55 static char sh2dasm_buff[64];
56 #define do_host_disasm(tcid) \
57   host_dasm(tcache_dsm_ptrs[tcid], tcache_ptr - tcache_dsm_ptrs[tcid]); \
58   tcache_dsm_ptrs[tcid] = tcache_ptr
59 #else
60 #define do_host_disasm(x)
61 #endif
62
63 #if (DRC_DEBUG & 4)
64 static void REGPARM(3) *sh2_drc_announce_entry(void *block, SH2 *sh2, u32 sr)
65 {
66   if (block != NULL)
67     dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
68       sh2->pc, block, (signed int)sr >> 12);
69   return block;
70 }
71 #endif
72 // } debug
73
74 #define BLOCK_CYCLE_LIMIT 100
75 #define MAX_BLOCK_SIZE (BLOCK_CYCLE_LIMIT * 6 * 6)
76 #define TCACHE_BUFFERS 3
77
78 // we have 3 translation cache buffers, split from one drc/cmn buffer.
79 // BIOS shares tcache with data array because it's only used for init
80 // and can be discarded early
81 // XXX: need to tune sizes
82 static const int tcache_sizes[TCACHE_BUFFERS] = {
83   DRC_TCACHE_SIZE * 6 / 8, // ROM, DRAM
84   DRC_TCACHE_SIZE / 8, // BIOS, data array in master sh2
85   DRC_TCACHE_SIZE / 8, // ... slave
86 };
87
88 static u8 *tcache_bases[TCACHE_BUFFERS];
89 static u8 *tcache_ptrs[TCACHE_BUFFERS];
90
91 // ptr for code emiters
92 static u8 *tcache_ptr;
93
94 typedef struct block_desc_ {
95   u32 addr;                  // SH2 PC address
96   u32 end_addr;              // TODO rm?
97   void *tcache_ptr;          // translated block for above PC
98   struct block_desc_ *next;  // next block with the same PC hash
99 #if (DRC_DEBUG & 1)
100   int refcount;
101 #endif
102 } block_desc;
103
104 typedef struct block_link_ {
105   u32 target_pc;
106   void *jump;
107 //  struct block_link_ *next;
108 } block_link;
109
110 static const int block_max_counts[TCACHE_BUFFERS] = {
111   4*1024,
112   256,
113   256,
114 };
115 static block_desc *block_tables[TCACHE_BUFFERS];
116 static block_link *block_links[TCACHE_BUFFERS]; 
117 static int block_counts[TCACHE_BUFFERS];
118 static int block_link_counts[TCACHE_BUFFERS];
119
120 // host register tracking
121 enum {
122   HR_FREE,
123   HR_CACHED, // 'val' has sh2_reg_e
124   HR_CACHED_DIRTY,
125   HR_CONST,  // 'val' has constant
126   HR_TEMP,   // reg used for temp storage
127 };
128
129 typedef struct {
130   u8 reg;
131   u8 type;
132   u16 stamp; // kind of a timestamp
133   u32 val;
134 } temp_reg_t;
135
136 // note: reg_temp[] must have at least the amount of
137 // registers used by handlers in worst case (currently 4)
138 #ifdef ARM
139 #include "../drc/emit_arm.c"
140
141 static const int reg_map_g2h[] = {
142    4,  5,  6,  7,
143    8, -1, -1, -1,
144   -1, -1, -1, -1,
145   -1, -1, -1,  9,
146   -1, -1, -1, 10,
147   -1, -1, -1, -1,
148 };
149
150 static temp_reg_t reg_temp[] = {
151   {  0, },
152   {  1, },
153   { 12, },
154   { 14, },
155   {  2, },
156   {  3, },
157 };
158
159 #elif defined(__i386__)
160 #include "../drc/emit_x86.c"
161
162 static const int reg_map_g2h[] = {
163   xSI,-1, -1, -1,
164   -1, -1, -1, -1,
165   -1, -1, -1, -1,
166   -1, -1, -1, -1,
167   -1, -1, -1, xDI,
168   -1, -1, -1, -1,
169 };
170
171 // ax, cx, dx are usually temporaries by convention
172 static temp_reg_t reg_temp[] = {
173   { xAX, },
174   { xBX, },
175   { xCX, },
176   { xDX, },
177 };
178
179 #else
180 #error unsupported arch
181 #endif
182
183 #define T       0x00000001
184 #define S       0x00000002
185 #define I       0x000000f0
186 #define Q       0x00000100
187 #define M       0x00000200
188 #define T_save  0x00000800
189
190 #define I_SHIFT 4
191 #define Q_SHIFT 8
192 #define M_SHIFT 9
193
194 // ROM hash table
195 #define MAX_HASH_ENTRIES 1024
196 #define HASH_MASK (MAX_HASH_ENTRIES - 1)
197 static void **hash_table;
198
199 #define HASH_FUNC(hash_tab, addr) \
200   ((block_desc **)(hash_tab))[(addr) & HASH_MASK]
201
202 static void REGPARM(1) (*sh2_drc_entry)(SH2 *sh2);
203 static void            (*sh2_drc_dispatcher)(void);
204 static void            (*sh2_drc_exit)(void);
205 static void            (*sh2_drc_test_irq)(void);
206 static void REGPARM(2) (*sh2_drc_write8)(u32 a, u32 d);
207 static void REGPARM(2) (*sh2_drc_write8_slot)(u32 a, u32 d);
208 static void REGPARM(2) (*sh2_drc_write16)(u32 a, u32 d);
209 static void REGPARM(2) (*sh2_drc_write16_slot)(u32 a, u32 d);
210
211 extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
212
213 static void flush_tcache(int tcid)
214 {
215   dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
216     tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
217     block_counts[tcid], block_max_counts[tcid]);
218
219   block_counts[tcid] = 0;
220   tcache_ptrs[tcid] = tcache_bases[tcid];
221   if (tcid == 0) { // ROM, RAM
222     memset(hash_table, 0, sizeof(hash_table[0]) * MAX_HASH_ENTRIES);
223     memset(Pico32xMem->drcblk_ram, 0, sizeof(Pico32xMem->drcblk_ram));
224   }
225   else
226     memset(Pico32xMem->drcblk_da[tcid - 1], 0, sizeof(Pico32xMem->drcblk_da[0]));
227 #if (DRC_DEBUG & 2)
228   tcache_dsm_ptrs[tcid] = tcache_bases[tcid];
229 #endif
230 }
231
232 // add block links (tracked branches)
233 static int dr_add_block_link(u32 target_pc, void *jump, int tcache_id)
234 {
235   block_link *bl = block_links[tcache_id];
236   int cnt = block_link_counts[tcache_id];
237
238   if (cnt >= block_max_counts[tcache_id] * 2) {
239     printf("bl overflow for tcache %d\n", tcache_id);
240     return -1;
241   }
242
243   bl[cnt].target_pc = target_pc;
244   bl[cnt].jump = jump;
245   block_link_counts[tcache_id]++;
246
247   return 0;
248 }
249
250 static void *dr_find_block(block_desc *tab, u32 addr)
251 {
252   for (tab = tab->next; tab != NULL; tab = tab->next)
253     if (tab->addr == addr)
254       break;
255
256   if (tab != NULL)
257     return tab->tcache_ptr;
258
259   printf("block miss for %08x\n", addr);
260   return NULL;
261 }
262
263 static block_desc *dr_add_block(u32 addr, int tcache_id, int *blk_id)
264 {
265   int *bcount = &block_counts[tcache_id];
266   block_desc *bd;
267
268   if (*bcount >= block_max_counts[tcache_id]) {
269     printf("bd overflow for tcache %d\n", tcache_id);
270     return NULL;
271   }
272
273   bd = &block_tables[tcache_id][*bcount];
274   bd->addr = addr;
275   bd->tcache_ptr = tcache_ptr;
276   *blk_id = *bcount;
277   (*bcount)++;
278
279   if ((addr & 0xc6000000) == 0x02000000) { // ROM
280     bd->next = HASH_FUNC(hash_table, addr);
281     HASH_FUNC(hash_table, addr) = bd;
282 #if (DRC_DEBUG & 1)
283     if (bd->next != NULL) {
284       printf(" hash collision with %08x\n", bd->next->addr);
285       hash_collisions++;
286     }
287 #endif
288   }
289
290   return bd;
291 }
292
293 #define ADD_TO_ARRAY(array, count, item, failcode) \
294   array[count++] = item; \
295   if (count >= ARRAY_SIZE(array)) { \
296     printf("warning: " #array " overflow\n"); \
297     failcode; \
298   }
299
300 int find_in_array(u32 *array, size_t size, u32 what)
301 {
302   size_t i;
303   for (i = 0; i < size; i++)
304     if (what == array[i])
305       return i;
306
307   return -1;
308 }
309
310 // ---------------------------------------------------------------
311
312 // register chache
313 static u16 rcache_counter;
314
315 static temp_reg_t *rcache_evict(void)
316 {
317   // evict reg with oldest stamp
318   int i, oldest = -1;
319   u16 min_stamp = (u16)-1;
320
321   for (i = 0; i < ARRAY_SIZE(reg_temp); i++) {
322     if (reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY)
323       if (reg_temp[i].stamp <= min_stamp) {
324         min_stamp = reg_temp[i].stamp;
325         oldest = i;
326       }
327   }
328
329   if (oldest == -1) {
330     printf("no registers to evict, aborting\n");
331     exit(1);
332   }
333
334   i = oldest;
335   if (reg_temp[i].type == HR_CACHED_DIRTY) {
336     // writeback
337     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
338   }
339
340   return &reg_temp[i];
341 }
342
343 typedef enum {
344   RC_GR_READ,
345   RC_GR_WRITE,
346   RC_GR_RMW,
347 } rc_gr_mode;
348
349 // note: must not be called when doing conditional code
350 static int rcache_get_reg(sh2_reg_e r, rc_gr_mode mode)
351 {
352   temp_reg_t *tr;
353   int i;
354
355   // maybe already statically mapped?
356   i = reg_map_g2h[r];
357   if (i != -1)
358     return i;
359
360   rcache_counter++;
361
362   // maybe already cached?
363   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
364     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
365          reg_temp[i].val == r)
366     {
367       reg_temp[i].stamp = rcache_counter;
368       if (mode != RC_GR_READ)
369         reg_temp[i].type = HR_CACHED_DIRTY;
370       return reg_temp[i].reg;
371     }
372   }
373
374   // use any free reg
375   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
376     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
377       tr = &reg_temp[i];
378       goto do_alloc;
379     }
380   }
381
382   tr = rcache_evict();
383
384 do_alloc:
385   if (mode != RC_GR_WRITE)
386     emith_ctx_read(tr->reg, r * 4);
387
388   tr->type = mode != RC_GR_READ ? HR_CACHED_DIRTY : HR_CACHED;
389   tr->val = r;
390   tr->stamp = rcache_counter;
391   return tr->reg;
392 }
393
394 static int rcache_get_tmp(void)
395 {
396   temp_reg_t *tr;
397   int i;
398
399   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
400     if (reg_temp[i].type == HR_FREE || reg_temp[i].type == HR_CONST) {
401       tr = &reg_temp[i];
402       goto do_alloc;
403     }
404
405   tr = rcache_evict();
406
407 do_alloc:
408   tr->type = HR_TEMP;
409   return tr->reg;
410 }
411
412 static int rcache_get_arg_id(int arg)
413 {
414   int i, r = 0;
415   host_arg2reg(r, arg);
416
417   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
418     if (reg_temp[i].reg == r)
419       break;
420
421   if (i == ARRAY_SIZE(reg_temp))
422     // let's just say it's untracked arg reg
423     return r;
424
425   if (reg_temp[i].type == HR_CACHED_DIRTY) {
426     // writeback
427     emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
428   }
429   else if (reg_temp[i].type == HR_TEMP) {
430     printf("arg %d reg %d already used, aborting\n", arg, r);
431     exit(1);
432   }
433
434   return i;
435 }
436
437 // get a reg to be used as function arg
438 // it's assumed that regs are cleaned before call
439 static int rcache_get_tmp_arg(int arg)
440 {
441   int id = rcache_get_arg_id(arg);
442   reg_temp[id].type = HR_TEMP;
443
444   return reg_temp[id].reg;
445 }
446
447 // same but caches reg. RC_GR_READ only.
448 static int rcache_get_reg_arg(int arg, sh2_reg_e r)
449 {
450   int i, srcr, dstr, dstid;
451
452   dstid = rcache_get_arg_id(arg);
453   dstr = reg_temp[dstid].reg;
454
455   // maybe already statically mapped?
456   srcr = reg_map_g2h[r];
457   if (srcr != -1)
458     goto do_cache;
459
460   // maybe already cached?
461   for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) {
462     if ((reg_temp[i].type == HR_CACHED || reg_temp[i].type == HR_CACHED_DIRTY) &&
463          reg_temp[i].val == r)
464     {
465       srcr = reg_temp[i].reg;
466       goto do_cache;
467     }
468   }
469
470   // must read
471   srcr = dstr;
472   emith_ctx_read(srcr, r * 4);
473
474 do_cache:
475   if (srcr != dstr)
476     emith_move_r_r(dstr, srcr);
477
478   reg_temp[dstid].stamp = ++rcache_counter;
479   reg_temp[dstid].type = HR_CACHED;
480   reg_temp[dstid].val = r;
481   return dstr;
482 }
483
484 static void rcache_free_tmp(int hr)
485 {
486   int i;
487   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
488     if (reg_temp[i].reg == hr)
489       break;
490
491   if (i == ARRAY_SIZE(reg_temp) || reg_temp[i].type != HR_TEMP) {
492     printf("rcache_free_tmp fail: #%i hr %d, type %d\n", i, hr, reg_temp[i].type);
493     return;
494   }
495
496   reg_temp[i].type = HR_FREE;
497 }
498
499 static void rcache_clean(void)
500 {
501   int i;
502   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
503     if (reg_temp[i].type == HR_CACHED_DIRTY) {
504       // writeback
505       emith_ctx_write(reg_temp[i].reg, reg_temp[i].val * 4);
506       reg_temp[i].type = HR_CACHED;
507     }
508 }
509
510 static void rcache_invalidate(void)
511 {
512   int i;
513   for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
514     reg_temp[i].type = HR_FREE;
515   rcache_counter = 0;
516 }
517
518 static void rcache_flush(void)
519 {
520   rcache_clean();
521   rcache_invalidate();
522 }
523
524 // ---------------------------------------------------------------
525
526 static void emit_move_r_imm32(sh2_reg_e dst, u32 imm)
527 {
528   // TODO: propagate this constant
529   int hr = rcache_get_reg(dst, RC_GR_WRITE);
530   emith_move_r_imm(hr, imm);
531 }
532
533 static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src)
534 {
535   int hr_d = rcache_get_reg(dst, RC_GR_WRITE);
536   int hr_s = rcache_get_reg(src, RC_GR_READ);
537
538   emith_move_r_r(hr_d, hr_s);
539 }
540
541 // T must be clear, and comparison done just before this
542 static void emit_or_t_if_eq(int srr)
543 {
544   EMITH_SJMP_START(DCOND_NE);
545   emith_or_r_imm_c(DCOND_EQ, srr, T);
546   EMITH_SJMP_END(DCOND_NE);
547 }
548
549 // arguments must be ready
550 // reg cache must be clean before call
551 static int emit_memhandler_read(int size)
552 {
553   int arg0, arg1;
554   host_arg2reg(arg0, 0);
555
556   // must writeback cycles for poll detection stuff
557   if (reg_map_g2h[SHR_SR] != -1)
558     emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
559   arg1 = rcache_get_tmp_arg(1);
560   emith_move_r_r(arg1, CONTEXT_REG);
561
562 #if 1
563   if (Pico.rom == (void *)0x02000000 && Pico32xMem->sdram == (void *)0x06000000) {
564     int tmp = rcache_get_tmp();
565     emith_and_r_r_imm(tmp, arg0, 0xfb000000);
566     emith_cmp_r_imm(tmp, 0x02000000);
567     switch (size) {
568     case 0: // 8
569       EMITH_SJMP3_START(DCOND_NE);
570       emith_eor_r_imm_c(DCOND_EQ, arg0, 1);
571       emith_read8_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
572       EMITH_SJMP3_MID(DCOND_NE);
573       emith_call_cond(DCOND_NE, p32x_sh2_read8);
574       EMITH_SJMP3_END();
575       break;
576     case 1: // 16
577       EMITH_SJMP3_START(DCOND_NE);
578       emith_read16_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
579       EMITH_SJMP3_MID(DCOND_NE);
580       emith_call_cond(DCOND_NE, p32x_sh2_read16);
581       EMITH_SJMP3_END();
582       break;
583     case 2: // 32
584       EMITH_SJMP3_START(DCOND_NE);
585       emith_read_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
586       emith_ror_c(DCOND_EQ, arg0, arg0, 16);
587       EMITH_SJMP3_MID(DCOND_NE);
588       emith_call_cond(DCOND_NE, p32x_sh2_read32);
589       EMITH_SJMP3_END();
590       break;
591     }
592   }
593   else
594 #endif
595   {
596     switch (size) {
597     case 0: // 8
598       emith_call(p32x_sh2_read8);
599       break;
600     case 1: // 16
601       emith_call(p32x_sh2_read16);
602       break;
603     case 2: // 32
604       emith_call(p32x_sh2_read32);
605       break;
606     }
607   }
608   rcache_invalidate();
609   // assuming arg0 and retval reg matches
610   return rcache_get_tmp_arg(0);
611 }
612
613 static void emit_memhandler_write(int size, u32 pc, int delay)
614 {
615   int ctxr;
616   host_arg2reg(ctxr, 2);
617   switch (size) {
618   case 0: // 8
619     // XXX: consider inlining sh2_drc_write8
620     if (delay) {
621       emith_call(sh2_drc_write8_slot);
622     } else {
623       emit_move_r_imm32(SHR_PC, pc);
624       rcache_clean();
625       emith_call(sh2_drc_write8);
626     }
627     break;
628   case 1: // 16
629     if (delay) {
630       emith_call(sh2_drc_write16_slot);
631     } else {
632       emit_move_r_imm32(SHR_PC, pc);
633       rcache_clean();
634       emith_call(sh2_drc_write16);
635     }
636     break;
637   case 2: // 32
638     emith_move_r_r(ctxr, CONTEXT_REG);
639     emith_call(p32x_sh2_write32);
640     break;
641   }
642   rcache_invalidate();
643 }
644
645 // @(Rx,Ry)
646 static int emit_indirect_indexed_read(int rx, int ry, int size)
647 {
648   int a0, t;
649   rcache_clean();
650   a0 = rcache_get_reg_arg(0, rx);
651   t  = rcache_get_reg(ry, RC_GR_READ);
652   emith_add_r_r(a0, t);
653   return emit_memhandler_read(size);
654 }
655
656 // read @Rn, @rm
657 static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size)
658 {
659   int tmp;
660
661   rcache_clean();
662   rcache_get_reg_arg(0, rn);
663   tmp = emit_memhandler_read(size);
664   emith_ctx_write(tmp, offsetof(SH2, drc_tmp));
665   rcache_free_tmp(tmp);
666   tmp = rcache_get_reg(rn, RC_GR_RMW);
667   emith_add_r_imm(tmp, 1 << size);
668
669   rcache_clean();
670   rcache_get_reg_arg(0, rm);
671   *rmr = emit_memhandler_read(size);
672   *rnr = rcache_get_tmp();
673   emith_ctx_read(*rnr, offsetof(SH2, drc_tmp));
674   tmp = rcache_get_reg(rm, RC_GR_RMW);
675   emith_add_r_imm(tmp, 1 << size);
676 }
677  
678 static void emit_do_static_regs(int is_write, int tmpr)
679 {
680   int i, r, count;
681
682   for (i = 0; i < ARRAY_SIZE(reg_map_g2h); i++) {
683     r = reg_map_g2h[i];
684     if (r == -1)
685       continue;
686
687     for (count = 1; i < ARRAY_SIZE(reg_map_g2h) - 1; i++, r++) {
688       if (reg_map_g2h[i + 1] != r + 1)
689         break;
690       count++;
691     }
692
693     if (count > 1) {
694       // i, r point to last item
695       if (is_write)
696         emith_ctx_write_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
697       else
698         emith_ctx_read_multiple(r - count + 1, (i - count + 1) * 4, count, tmpr);
699     } else {
700       if (is_write)
701         emith_ctx_write(r, i * 4);
702       else
703         emith_ctx_read(r, i * 4);
704     }
705   }
706 }
707
708 static void emit_block_entry(void)
709 {
710   int arg0, arg1, arg2;
711
712   host_arg2reg(arg0, 0);
713   host_arg2reg(arg1, 1);
714   host_arg2reg(arg2, 2);
715
716 #if (DRC_DEBUG & 4)
717   emith_move_r_r(arg1, CONTEXT_REG);
718   emith_move_r_r(arg2, rcache_get_reg(SHR_SR, RC_GR_READ));
719   emith_call(sh2_drc_announce_entry);
720   rcache_invalidate();
721 #endif
722   emith_tst_r_r(arg0, arg0);
723   EMITH_SJMP_START(DCOND_EQ);
724   emith_jump_reg_c(DCOND_NE, arg0);
725   EMITH_SJMP_END(DCOND_EQ);
726 }
727
728 static void REGPARM(3) *lookup_block(u32 pc, int is_slave, int *tcache_id)
729 {
730   block_desc *bd = NULL;
731   void *block = NULL;
732   *tcache_id = 0;
733
734   // we have full block id tables for data_array and RAM
735   // BIOS goes to data_array table too
736   if ((pc & 0xe0000000) == 0xc0000000 || (pc & ~0xfff) == 0) {
737     int blkid = Pico32xMem->drcblk_da[is_slave][(pc & 0xfff) >> SH2_DRCBLK_DA_SHIFT];
738     *tcache_id = 1 + is_slave;
739     if (blkid & 1) {
740       bd = &block_tables[*tcache_id][blkid >> 1];
741       block = bd->tcache_ptr;
742     }
743   }
744   // RAM
745   else if ((pc & 0xc6000000) == 0x06000000) {
746     int blkid = Pico32xMem->drcblk_ram[(pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT];
747     if (blkid & 1) {
748       bd = &block_tables[0][blkid >> 1];
749       block = bd->tcache_ptr;
750     }
751   }
752   // ROM
753   else if ((pc & 0xc6000000) == 0x02000000) {
754     bd = HASH_FUNC(hash_table, pc);
755
756     if (bd != NULL) {
757       if (bd->addr == pc)
758         block = bd->tcache_ptr;
759       else
760         block = dr_find_block(bd, pc);
761     }
762   }
763
764 #if (DRC_DEBUG & 1)
765   if (bd != NULL)
766     bd->refcount++;
767 #endif
768   return block;
769 }
770
771 void dr_link_blocks(void *target, u32 pc, int tcache_id)
772 {
773   block_link *bl = block_links[tcache_id];
774   int cnt = block_link_counts[tcache_id];
775   int i;
776
777   for (i = 0; i < cnt; i++) {
778     if (bl[i].target_pc == pc) {
779       dbg(1, "- link from %p", bl[i].jump);
780       emith_jump_patch(bl[i].jump, target);
781       // XXX: sync ARM caches (old jump should be fine)?
782     }
783   }
784 }
785
786 void *dr_prepare_ext_branch(u32 pc, SH2 *sh2, int tcache_id)
787 {
788   int target_tcache_id;
789   void *target;
790   int ret;
791
792   target = lookup_block(pc, sh2->is_slave, &target_tcache_id);
793   if (target_tcache_id == tcache_id) {
794     // allow linking blocks only from local cache
795     ret = dr_add_block_link(pc, tcache_ptr, tcache_id);
796     if (ret < 0)
797       return NULL;
798   }
799   if (target == NULL || target_tcache_id != tcache_id)
800     target = sh2_drc_dispatcher;
801
802   return target;
803 }
804
805 #define DELAYED_OP \
806   drcf.delayed_op = 2
807
808 #define DELAY_SAVE_T(sr) { \
809   emith_bic_r_imm(sr, T_save); \
810   emith_tst_r_imm(sr, T);      \
811   EMITH_SJMP_START(DCOND_EQ);  \
812   emith_or_r_imm_c(DCOND_NE, sr, T_save); \
813   EMITH_SJMP_END(DCOND_EQ);    \
814   drcf.use_saved_t = 1;        \
815 }
816
817 #define FLUSH_CYCLES(sr) \
818   if (cycles > 0) { \
819     emith_sub_r_imm(sr, cycles << 12); \
820     cycles = 0; \
821   }
822
823 #define CHECK_UNHANDLED_BITS(mask) { \
824   if ((op & (mask)) != 0) \
825     goto default_; \
826 }
827
828 #define GET_Fx() \
829   ((op >> 4) & 0x0f)
830
831 #define GET_Rm GET_Fx
832
833 #define GET_Rn() \
834   ((op >> 8) & 0x0f)
835
836 #define CHECK_FX_LT(n) \
837   if (GET_Fx() >= n) \
838     goto default_
839
840 #define MAX_LOCAL_BRANCHES 32
841
842 // op_flags: data from 1st pass
843 #define OP_FLAGS(pc) op_flags[((pc) - base_pc) / 2]
844 #define OF_DELAY_OP (1 << 0)
845
846 static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
847 {
848   // XXX: maybe use structs instead?
849   void *branch_target_ptr[MAX_LOCAL_BRANCHES];
850   u32 branch_target_pc[MAX_LOCAL_BRANCHES];
851   int branch_target_count = 0;
852   void *branch_patch_ptr[MAX_LOCAL_BRANCHES];
853   u32 branch_patch_pc[MAX_LOCAL_BRANCHES];
854   int branch_patch_count = 0;
855   int pending_branch_cond = -1;
856   int pending_branch_pc = 0;
857   u8 op_flags[BLOCK_CYCLE_LIMIT + 1];
858   struct {
859     u32 delayed_op:2;
860     u32 test_irq:1;
861     u32 use_saved_t:1; // delayed op modifies T
862   } drcf = { 0, };
863
864   // PC of current, first, last, last_target_blk SH2 insn
865   u32 pc, base_pc, end_pc, out_pc;
866   void *block_entry;
867   block_desc *this_block;
868   int blkid_main = 0;
869   u32 tmp, tmp2;
870   int cycles;
871   int op;
872   int i;
873
874   base_pc = sh2->pc;
875
876   // validate PC
877   tmp = base_pc >> 29;
878   if ((tmp != 0 && tmp != 1 && tmp != 6) || base_pc == 0) {
879     printf("invalid PC, aborting: %08x\n", base_pc);
880     // FIXME: be less destructive
881     exit(1);
882   }
883
884   tcache_ptr = tcache_ptrs[tcache_id];
885   this_block = dr_add_block(base_pc, tcache_id, &blkid_main);
886   if (this_block == NULL)
887     return NULL;
888
889   // predict tcache overflow
890   tmp = tcache_ptr - tcache_bases[tcache_id];
891   if (tmp > tcache_sizes[tcache_id] - MAX_BLOCK_SIZE) {
892     printf("tcache %d overflow\n", tcache_id);
893     return NULL;
894   }
895
896   block_entry = tcache_ptr;
897   dbg(1, "== %csh2 block #%d,%d %08x -> %p", sh2->is_slave ? 's' : 'm',
898     tcache_id, blkid_main, base_pc, block_entry);
899
900   dr_link_blocks(tcache_ptr, base_pc, tcache_id);
901
902   // 1st pass: scan forward for local branches
903   memset(op_flags, 0, sizeof(op_flags));
904   for (cycles = 0, pc = base_pc; cycles < BLOCK_CYCLE_LIMIT; cycles++, pc += 2) {
905     op = p32x_sh2_read16(pc, sh2);
906     if ((op & 0xf000) == 0xa000 || (op & 0xf000) == 0xb000) { // BRA, BSR
907       signed int offs = ((signed int)(op << 20) >> 19);
908       pc += 2;
909       OP_FLAGS(pc) |= OF_DELAY_OP;
910       ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc + offs + 2,);
911       break;
912     }
913     if ((op & 0xf000) == 0) {
914       op &= 0xff;
915       if (op == 0x1b) // SLEEP
916         break;
917       if (op == 0x23 || op == 0x03 || op == 0x0b || op == 0x2b) { // BRAF, BSRF, RTS, RTE
918         pc += 2;
919         OP_FLAGS(pc) |= OF_DELAY_OP;
920         break;
921       }
922       continue;
923     }
924     if ((op & 0xf0df) == 0x400b) { // JMP, JSR
925       pc += 2;
926       OP_FLAGS(pc) |= OF_DELAY_OP;
927       break;
928     }
929     if ((op & 0xf900) == 0x8900) { // BT(S), BF(S)
930       signed int offs = ((signed int)(op << 24) >> 23);
931       if (op & 0x0400)
932         OP_FLAGS(pc + 2) |= OF_DELAY_OP;
933       ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc + offs + 4, break);
934     }
935     if ((op & 0xff00) == 0xc300) // TRAPA
936       break;
937   }
938
939   end_pc = pc;
940
941   // clean branch_targets that are not really local,
942   // and that land on delay slots
943   for (i = 0, tmp = 0; i < branch_target_count; i++) {
944     pc = branch_target_pc[i];
945     if (base_pc <= pc && pc <= end_pc && !(OP_FLAGS(pc) & OF_DELAY_OP))
946       branch_target_pc[tmp++] = branch_target_pc[i];
947   }
948   branch_target_count = tmp;
949   memset(branch_target_ptr, 0, sizeof(branch_target_ptr[0]) * branch_target_count);
950
951   // -------------------------------------------------
952   // 2nd pass: actual compilation
953   out_pc = 0;
954   pc = base_pc;
955   for (cycles = 0; pc <= end_pc || drcf.delayed_op; )
956   {
957     u32 tmp3, tmp4, sr;
958
959     if (drcf.delayed_op > 0)
960       drcf.delayed_op--;
961
962     i = find_in_array(branch_target_pc, branch_target_count, pc);
963     if (i >= 0)
964     {
965       if (pc != sh2->pc)
966       {
967         /* make "subblock" - just a mid-block entry */
968         block_desc *subblock;
969         u16 *drcblk;
970         int blkid;
971
972         sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
973         FLUSH_CYCLES(sr);
974         rcache_flush();
975         do_host_disasm(tcache_id);
976
977         subblock = dr_add_block(pc, tcache_id, &blkid);
978         if (subblock == NULL)
979           return NULL;
980         subblock->end_addr = pc;
981
982         if (tcache_id != 0) { // data array, BIOS
983           drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
984           drcblk += (pc & 0x00fff) >> SH2_DRCBLK_DA_SHIFT;
985           *drcblk = (blkid << 1) | 1;
986         } else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
987           drcblk = Pico32xMem->drcblk_ram;
988           drcblk += (pc & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
989           *drcblk = (blkid << 1) | 1;
990         }
991
992         dbg(1, "-- %csh2 subblock #%d,%d %08x -> %p", sh2->is_slave ? 's' : 'm',
993           tcache_id, blkid, pc, tcache_ptr);
994
995         // since we made a block entry, link any other blocks that jump to current pc
996         dr_link_blocks(tcache_ptr, pc, tcache_id);
997       }
998       branch_target_ptr[i] = tcache_ptr;
999
1000       // must update PC
1001       emit_move_r_imm32(SHR_PC, pc);
1002       rcache_clean();
1003
1004       // check cycles
1005       sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1006       emith_cmp_r_imm(sr, 0);
1007       emith_jump_cond(DCOND_LE, sh2_drc_exit);
1008     }
1009
1010     op = p32x_sh2_read16(pc, sh2);
1011
1012 #if (DRC_DEBUG & 3)
1013     insns_compiled++;
1014 #if (DRC_DEBUG & 2)
1015     DasmSH2(sh2dasm_buff, pc, op);
1016     printf("%08x %04x %s\n", pc, op, sh2dasm_buff);
1017 #endif
1018 #endif
1019
1020     pc += 2;
1021     cycles++;
1022
1023     switch ((op >> 12) & 0x0f)
1024     {
1025     /////////////////////////////////////////////
1026     case 0x00:
1027       switch (op & 0x0f)
1028       {
1029       case 0x02:
1030         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1031         switch (GET_Fx())
1032         {
1033         case 0: // STC SR,Rn  0000nnnn00000010
1034           tmp2 = SHR_SR;
1035           break;
1036         case 1: // STC GBR,Rn 0000nnnn00010010
1037           tmp2 = SHR_GBR;
1038           break;
1039         case 2: // STC VBR,Rn 0000nnnn00100010
1040           tmp2 = SHR_VBR;
1041           break;
1042         default:
1043           goto default_;
1044         }
1045         tmp3 = rcache_get_reg(tmp2, RC_GR_READ);
1046         emith_move_r_r(tmp, tmp3);
1047         if (tmp2 == SHR_SR)
1048           emith_clear_msb(tmp, tmp, 22); // reserved bits defined by ISA as 0
1049         goto end_op;
1050       case 0x03:
1051         CHECK_UNHANDLED_BITS(0xd0);
1052         // BRAF Rm    0000mmmm00100011
1053         // BSRF Rm    0000mmmm00000011
1054         DELAYED_OP;
1055         tmp  = rcache_get_reg(SHR_PC, RC_GR_WRITE);
1056         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1057         emith_move_r_r(tmp, tmp2);
1058         if (op & 0x20)
1059           emith_add_r_imm(tmp, pc + 2);
1060         else { // BSRF
1061           tmp3 = rcache_get_reg(SHR_PR, RC_GR_WRITE);
1062           emith_move_r_imm(tmp3, pc + 2);
1063           emith_add_r_r(tmp, tmp3);
1064         }
1065         out_pc = (u32)-1;
1066         cycles++;
1067         goto end_op;
1068       case 0x04: // MOV.B Rm,@(R0,Rn)   0000nnnnmmmm0100
1069       case 0x05: // MOV.W Rm,@(R0,Rn)   0000nnnnmmmm0101
1070       case 0x06: // MOV.L Rm,@(R0,Rn)   0000nnnnmmmm0110
1071         rcache_clean();
1072         tmp  = rcache_get_reg_arg(1, GET_Rm());
1073         tmp2 = rcache_get_reg_arg(0, SHR_R0);
1074         tmp3 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1075         emith_add_r_r(tmp2, tmp3);
1076         emit_memhandler_write(op & 3, pc, drcf.delayed_op);
1077         goto end_op;
1078       case 0x07:
1079         // MUL.L     Rm,Rn      0000nnnnmmmm0111
1080         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1081         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1082         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1083         emith_mul(tmp3, tmp2, tmp);
1084         cycles++;
1085         goto end_op;
1086       case 0x08:
1087         CHECK_UNHANDLED_BITS(0xf00);
1088         switch (GET_Fx())
1089         {
1090         case 0: // CLRT               0000000000001000
1091           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1092           if (drcf.delayed_op)
1093             DELAY_SAVE_T(sr);
1094           emith_bic_r_imm(sr, T);
1095           break;
1096         case 1: // SETT               0000000000011000
1097           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1098           if (drcf.delayed_op)
1099             DELAY_SAVE_T(sr);
1100           emith_or_r_imm(sr, T);
1101           break;
1102         case 2: // CLRMAC             0000000000101000
1103           tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1104           emith_move_r_imm(tmp, 0);
1105           tmp = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1106           emith_move_r_imm(tmp, 0);
1107           break;
1108         default:
1109           goto default_;
1110         }
1111         goto end_op;
1112       case 0x09:
1113         switch (GET_Fx())
1114         {
1115         case 0: // NOP        0000000000001001
1116           CHECK_UNHANDLED_BITS(0xf00);
1117           break;
1118         case 1: // DIV0U      0000000000011001
1119           CHECK_UNHANDLED_BITS(0xf00);
1120           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1121           if (drcf.delayed_op)
1122             DELAY_SAVE_T(sr);
1123           emith_bic_r_imm(sr, M|Q|T);
1124           break;
1125         case 2: // MOVT Rn    0000nnnn00101001
1126           sr   = rcache_get_reg(SHR_SR, RC_GR_READ);
1127           tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1128           emith_clear_msb(tmp2, sr, 31);
1129           break;
1130         default:
1131           goto default_;
1132         }
1133         goto end_op;
1134       case 0x0a:
1135         tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1136         switch (GET_Fx())
1137         {
1138         case 0: // STS      MACH,Rn   0000nnnn00001010
1139           tmp2 = SHR_MACH;
1140           break;
1141         case 1: // STS      MACL,Rn   0000nnnn00011010
1142           tmp2 = SHR_MACL;
1143           break;
1144         case 2: // STS      PR,Rn     0000nnnn00101010
1145           tmp2 = SHR_PR;
1146           break;
1147         default:
1148           goto default_;
1149         }
1150         tmp2 = rcache_get_reg(tmp2, RC_GR_READ);
1151         emith_move_r_r(tmp, tmp2);
1152         goto end_op;
1153       case 0x0b:
1154         CHECK_UNHANDLED_BITS(0xf00);
1155         switch (GET_Fx())
1156         {
1157         case 0: // RTS        0000000000001011
1158           DELAYED_OP;
1159           emit_move_r_r(SHR_PC, SHR_PR);
1160           out_pc = (u32)-1;
1161           cycles++;
1162           break;
1163         case 1: // SLEEP      0000000000011011
1164           tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
1165           emith_clear_msb(tmp, tmp, 20); // clear cycles
1166           out_pc = out_pc - 2;
1167           cycles = 1;
1168           goto end_op;
1169         case 2: // RTE        0000000000101011
1170           DELAYED_OP;
1171           rcache_clean();
1172           // pop PC
1173           rcache_get_reg_arg(0, SHR_SP);
1174           tmp = emit_memhandler_read(2);
1175           tmp2 = rcache_get_reg(SHR_PC, RC_GR_WRITE);
1176           emith_move_r_r(tmp2, tmp);
1177           rcache_free_tmp(tmp);
1178           rcache_clean();
1179           // pop SR
1180           tmp = rcache_get_reg_arg(0, SHR_SP);
1181           emith_add_r_imm(tmp, 4);
1182           tmp = emit_memhandler_read(2);
1183           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1184           emith_write_sr(sr, tmp);
1185           rcache_free_tmp(tmp);
1186           tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
1187           emith_add_r_imm(tmp, 4*2);
1188           drcf.test_irq = 1;
1189           out_pc = (u32)-1;
1190           cycles += 3;
1191           break;
1192         default:
1193           goto default_;
1194         }
1195         goto end_op;
1196       case 0x0c: // MOV.B    @(R0,Rm),Rn      0000nnnnmmmm1100
1197       case 0x0d: // MOV.W    @(R0,Rm),Rn      0000nnnnmmmm1101
1198       case 0x0e: // MOV.L    @(R0,Rm),Rn      0000nnnnmmmm1110
1199         tmp = emit_indirect_indexed_read(SHR_R0, GET_Rm(), op & 3);
1200         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1201         if ((op & 3) != 2) {
1202           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
1203         } else
1204           emith_move_r_r(tmp2, tmp);
1205         rcache_free_tmp(tmp);
1206         goto end_op;
1207       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
1208         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2);
1209         sr   = rcache_get_reg(SHR_SR, RC_GR_READ);
1210         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
1211         /* MS 16 MAC bits unused if saturated */
1212         emith_tst_r_imm(sr, S);
1213         EMITH_SJMP_START(DCOND_EQ);
1214         emith_clear_msb_c(DCOND_NE, tmp4, tmp4, 16);
1215         EMITH_SJMP_END(DCOND_EQ);
1216         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); // might evict SR
1217         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
1218         rcache_free_tmp(tmp2);
1219         sr = rcache_get_reg(SHR_SR, RC_GR_READ); // reget just in case
1220         emith_tst_r_imm(sr, S);
1221
1222         EMITH_JMP_START(DCOND_EQ);
1223         emith_asr(tmp, tmp4, 15);
1224         emith_cmp_r_imm(tmp, -1); // negative overflow (0x80000000..0xffff7fff)
1225         EMITH_SJMP_START(DCOND_GE);
1226         emith_move_r_imm_c(DCOND_LT, tmp4, 0x8000);
1227         emith_move_r_imm_c(DCOND_LT, tmp3, 0x0000);
1228         EMITH_SJMP_END(DCOND_GE);
1229         emith_cmp_r_imm(tmp, 0); // positive overflow (0x00008000..0x7fffffff)
1230         EMITH_SJMP_START(DCOND_LE);
1231         emith_move_r_imm_c(DCOND_GT, tmp4, 0x00007fff);
1232         emith_move_r_imm_c(DCOND_GT, tmp3, 0xffffffff);
1233         EMITH_SJMP_END(DCOND_LE);
1234         EMITH_JMP_END(DCOND_EQ);
1235
1236         rcache_free_tmp(tmp);
1237         cycles += 3;
1238         goto end_op;
1239       }
1240       goto default_;
1241
1242     /////////////////////////////////////////////
1243     case 0x01:
1244       // MOV.L Rm,@(disp,Rn) 0001nnnnmmmmdddd
1245       rcache_clean();
1246       tmp  = rcache_get_reg_arg(0, GET_Rn());
1247       tmp2 = rcache_get_reg_arg(1, GET_Rm());
1248       emith_add_r_imm(tmp, (op & 0x0f) * 4);
1249       emit_memhandler_write(2, pc, drcf.delayed_op);
1250       goto end_op;
1251
1252     case 0x02:
1253       switch (op & 0x0f)
1254       {
1255       case 0x00: // MOV.B Rm,@Rn        0010nnnnmmmm0000
1256       case 0x01: // MOV.W Rm,@Rn        0010nnnnmmmm0001
1257       case 0x02: // MOV.L Rm,@Rn        0010nnnnmmmm0010
1258         rcache_clean();
1259         rcache_get_reg_arg(0, GET_Rn());
1260         rcache_get_reg_arg(1, GET_Rm());
1261         emit_memhandler_write(op & 3, pc, drcf.delayed_op);
1262         goto end_op;
1263       case 0x04: // MOV.B Rm,@–Rn       0010nnnnmmmm0100
1264       case 0x05: // MOV.W Rm,@–Rn       0010nnnnmmmm0101
1265       case 0x06: // MOV.L Rm,@–Rn       0010nnnnmmmm0110
1266         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1267         emith_sub_r_imm(tmp, (1 << (op & 3)));
1268         rcache_clean();
1269         rcache_get_reg_arg(0, GET_Rn());
1270         rcache_get_reg_arg(1, GET_Rm());
1271         emit_memhandler_write(op & 3, pc, drcf.delayed_op);
1272         goto end_op;
1273       case 0x07: // DIV0S Rm,Rn         0010nnnnmmmm0111
1274         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1275         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1276         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1277         if (drcf.delayed_op)
1278           DELAY_SAVE_T(sr);
1279         emith_bic_r_imm(sr, M|Q|T);
1280         emith_tst_r_imm(tmp2, (1<<31));
1281         EMITH_SJMP_START(DCOND_EQ);
1282         emith_or_r_imm_c(DCOND_NE, sr, Q);
1283         EMITH_SJMP_END(DCOND_EQ);
1284         emith_tst_r_imm(tmp3, (1<<31));
1285         EMITH_SJMP_START(DCOND_EQ);
1286         emith_or_r_imm_c(DCOND_NE, sr, M);
1287         EMITH_SJMP_END(DCOND_EQ);
1288         emith_teq_r_r(tmp2, tmp3);
1289         EMITH_SJMP_START(DCOND_PL);
1290         emith_or_r_imm_c(DCOND_MI, sr, T);
1291         EMITH_SJMP_END(DCOND_PL);
1292         goto end_op;
1293       case 0x08: // TST Rm,Rn           0010nnnnmmmm1000
1294         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1295         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1296         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1297         if (drcf.delayed_op)
1298           DELAY_SAVE_T(sr);
1299         emith_bic_r_imm(sr, T);
1300         emith_tst_r_r(tmp2, tmp3);
1301         emit_or_t_if_eq(sr);
1302         goto end_op;
1303       case 0x09: // AND Rm,Rn           0010nnnnmmmm1001
1304         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1305         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1306         emith_and_r_r(tmp, tmp2);
1307         goto end_op;
1308       case 0x0a: // XOR Rm,Rn           0010nnnnmmmm1010
1309         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1310         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1311         emith_eor_r_r(tmp, tmp2);
1312         goto end_op;
1313       case 0x0b: // OR  Rm,Rn           0010nnnnmmmm1011
1314         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1315         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1316         emith_or_r_r(tmp, tmp2);
1317         goto end_op;
1318       case 0x0c: // CMP/STR Rm,Rn       0010nnnnmmmm1100
1319         tmp  = rcache_get_tmp();
1320         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1321         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1322         emith_eor_r_r_r(tmp, tmp2, tmp3);
1323         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1324         if (drcf.delayed_op)
1325           DELAY_SAVE_T(sr);
1326         emith_bic_r_imm(sr, T);
1327         emith_tst_r_imm(tmp, 0x000000ff);
1328         emit_or_t_if_eq(tmp);
1329         emith_tst_r_imm(tmp, 0x0000ff00);
1330         emit_or_t_if_eq(tmp);
1331         emith_tst_r_imm(tmp, 0x00ff0000);
1332         emit_or_t_if_eq(tmp);
1333         emith_tst_r_imm(tmp, 0xff000000);
1334         emit_or_t_if_eq(tmp);
1335         rcache_free_tmp(tmp);
1336         goto end_op;
1337       case 0x0d: // XTRCT  Rm,Rn        0010nnnnmmmm1101
1338         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1339         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1340         emith_lsr(tmp, tmp, 16);
1341         emith_or_r_r_lsl(tmp, tmp2, 16);
1342         goto end_op;
1343       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
1344       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
1345         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1346         tmp  = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1347         if (op & 1) {
1348           emith_sext(tmp, tmp2, 16);
1349         } else
1350           emith_clear_msb(tmp, tmp2, 16);
1351         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1352         tmp2 = rcache_get_tmp();
1353         if (op & 1) {
1354           emith_sext(tmp2, tmp3, 16);
1355         } else
1356           emith_clear_msb(tmp2, tmp3, 16);
1357         emith_mul(tmp, tmp, tmp2);
1358         rcache_free_tmp(tmp2);
1359 //      FIXME: causes timing issues in Doom?
1360 //        cycles++;
1361         goto end_op;
1362       }
1363       goto default_;
1364
1365     /////////////////////////////////////////////
1366     case 0x03:
1367       switch (op & 0x0f)
1368       {
1369       case 0x00: // CMP/EQ Rm,Rn        0011nnnnmmmm0000
1370       case 0x02: // CMP/HS Rm,Rn        0011nnnnmmmm0010
1371       case 0x03: // CMP/GE Rm,Rn        0011nnnnmmmm0011
1372       case 0x06: // CMP/HI Rm,Rn        0011nnnnmmmm0110
1373       case 0x07: // CMP/GT Rm,Rn        0011nnnnmmmm0111
1374         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1375         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ);
1376         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1377         if (drcf.delayed_op)
1378           DELAY_SAVE_T(sr);
1379         emith_bic_r_imm(sr, T);
1380         emith_cmp_r_r(tmp2, tmp3);
1381         switch (op & 0x07)
1382         {
1383         case 0x00: // CMP/EQ
1384           emit_or_t_if_eq(sr);
1385           break;
1386         case 0x02: // CMP/HS
1387           EMITH_SJMP_START(DCOND_LO);
1388           emith_or_r_imm_c(DCOND_HS, sr, T);
1389           EMITH_SJMP_END(DCOND_LO);
1390           break;
1391         case 0x03: // CMP/GE
1392           EMITH_SJMP_START(DCOND_LT);
1393           emith_or_r_imm_c(DCOND_GE, sr, T);
1394           EMITH_SJMP_END(DCOND_LT);
1395           break;
1396         case 0x06: // CMP/HI
1397           EMITH_SJMP_START(DCOND_LS);
1398           emith_or_r_imm_c(DCOND_HI, sr, T);
1399           EMITH_SJMP_END(DCOND_LS);
1400           break;
1401         case 0x07: // CMP/GT
1402           EMITH_SJMP_START(DCOND_LE);
1403           emith_or_r_imm_c(DCOND_GT, sr, T);
1404           EMITH_SJMP_END(DCOND_LE);
1405           break;
1406         }
1407         goto end_op;
1408       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
1409         // Q1 = carry(Rn = (Rn << 1) | T)
1410         // if Q ^ M
1411         //   Q2 = carry(Rn += Rm)
1412         // else
1413         //   Q2 = carry(Rn -= Rm)
1414         // Q = M ^ Q1 ^ Q2
1415         // T = (Q == M) = !(Q ^ M) = !(Q1 ^ Q2)
1416         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1417         tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1418         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1419         if (drcf.delayed_op)
1420           DELAY_SAVE_T(sr);
1421         emith_tpop_carry(sr, 0);
1422         emith_adcf_r_r(tmp2, tmp2);
1423         emith_tpush_carry(sr, 0);            // keep Q1 in T for now
1424         tmp4 = rcache_get_tmp();
1425         emith_and_r_r_imm(tmp4, sr, M);
1426         emith_eor_r_r_lsr(sr, tmp4, M_SHIFT - Q_SHIFT); // Q ^= M
1427         rcache_free_tmp(tmp4);
1428         // add or sub, invert T if carry to get Q1 ^ Q2
1429         // in: (Q ^ M) passed in Q, Q1 in T
1430         emith_sh2_div1_step(tmp2, tmp3, sr);
1431         emith_bic_r_imm(sr, Q);
1432         emith_tst_r_imm(sr, M);
1433         EMITH_SJMP_START(DCOND_EQ);
1434         emith_or_r_imm_c(DCOND_NE, sr, Q);  // Q = M
1435         EMITH_SJMP_END(DCOND_EQ);
1436         emith_tst_r_imm(sr, T);
1437         EMITH_SJMP_START(DCOND_EQ);
1438         emith_eor_r_imm_c(DCOND_NE, sr, Q); // Q = M ^ Q1 ^ Q2
1439         EMITH_SJMP_END(DCOND_EQ);
1440         emith_eor_r_imm(sr, T);             // T = !(Q1 ^ Q2)
1441         goto end_op;
1442       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
1443         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1444         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1445         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1446         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1447         emith_mul_u64(tmp3, tmp4, tmp, tmp2);
1448         goto end_op;
1449       case 0x08: // SUB     Rm,Rn       0011nnnnmmmm1000
1450       case 0x0c: // ADD     Rm,Rn       0011nnnnmmmm1100
1451         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1452         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1453         if (op & 4) {
1454           emith_add_r_r(tmp, tmp2);
1455         } else
1456           emith_sub_r_r(tmp, tmp2);
1457         goto end_op;
1458       case 0x0a: // SUBC    Rm,Rn       0011nnnnmmmm1010
1459       case 0x0e: // ADDC    Rm,Rn       0011nnnnmmmm1110
1460         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1461         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1462         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1463         if (drcf.delayed_op)
1464           DELAY_SAVE_T(sr);
1465         if (op & 4) { // adc
1466           emith_tpop_carry(sr, 0);
1467           emith_adcf_r_r(tmp, tmp2);
1468           emith_tpush_carry(sr, 0);
1469         } else {
1470           emith_tpop_carry(sr, 1);
1471           emith_sbcf_r_r(tmp, tmp2);
1472           emith_tpush_carry(sr, 1);
1473         }
1474         goto end_op;
1475       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
1476       case 0x0f: // ADDV    Rm,Rn       0011nnnnmmmm1111
1477         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1478         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1479         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1480         if (drcf.delayed_op)
1481           DELAY_SAVE_T(sr);
1482         emith_bic_r_imm(sr, T);
1483         if (op & 4) {
1484           emith_addf_r_r(tmp, tmp2);
1485         } else
1486           emith_subf_r_r(tmp, tmp2);
1487         EMITH_SJMP_START(DCOND_VC);
1488         emith_or_r_imm_c(DCOND_VS, sr, T);
1489         EMITH_SJMP_END(DCOND_VC);
1490         goto end_op;
1491       case 0x0d: // DMULS.L Rm,Rn       0011nnnnmmmm1101
1492         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
1493         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
1494         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_WRITE);
1495         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_WRITE);
1496         emith_mul_s64(tmp3, tmp4, tmp, tmp2);
1497         goto end_op;
1498       }
1499       goto default_;
1500
1501     /////////////////////////////////////////////
1502     case 0x04:
1503       switch (op & 0x0f)
1504       {
1505       case 0x00:
1506         switch (GET_Fx())
1507         {
1508         case 0: // SHLL Rn    0100nnnn00000000
1509         case 2: // SHAL Rn    0100nnnn00100000
1510           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1511           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1512           if (drcf.delayed_op)
1513             DELAY_SAVE_T(sr);
1514           emith_tpop_carry(sr, 0); // dummy
1515           emith_lslf(tmp, tmp, 1);
1516           emith_tpush_carry(sr, 0);
1517           goto end_op;
1518         case 1: // DT Rn      0100nnnn00010000
1519           if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2
1520             emith_sh2_dtbf_loop();
1521             goto end_op;
1522           }
1523           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1524           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1525           if (drcf.delayed_op)
1526             DELAY_SAVE_T(sr);
1527           emith_bic_r_imm(sr, T);
1528           emith_subf_r_imm(tmp, 1);
1529           emit_or_t_if_eq(sr);
1530           goto end_op;
1531         }
1532         goto default_;
1533       case 0x01:
1534         switch (GET_Fx())
1535         {
1536         case 0: // SHLR Rn    0100nnnn00000001
1537         case 2: // SHAR Rn    0100nnnn00100001
1538           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1539           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1540           if (drcf.delayed_op)
1541             DELAY_SAVE_T(sr);
1542           emith_tpop_carry(sr, 0); // dummy
1543           if (op & 0x20) {
1544             emith_asrf(tmp, tmp, 1);
1545           } else
1546             emith_lsrf(tmp, tmp, 1);
1547           emith_tpush_carry(sr, 0);
1548           goto end_op;
1549         case 1: // CMP/PZ Rn  0100nnnn00010001
1550           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1551           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1552           if (drcf.delayed_op)
1553             DELAY_SAVE_T(sr);
1554           emith_bic_r_imm(sr, T);
1555           emith_cmp_r_imm(tmp, 0);
1556           EMITH_SJMP_START(DCOND_LT);
1557           emith_or_r_imm_c(DCOND_GE, sr, T);
1558           EMITH_SJMP_END(DCOND_LT);
1559           goto end_op;
1560         }
1561         goto default_;
1562       case 0x02:
1563       case 0x03:
1564         switch (op & 0x3f)
1565         {
1566         case 0x02: // STS.L    MACH,@–Rn 0100nnnn00000010
1567           tmp = SHR_MACH;
1568           break;
1569         case 0x12: // STS.L    MACL,@–Rn 0100nnnn00010010
1570           tmp = SHR_MACL;
1571           break;
1572         case 0x22: // STS.L    PR,@–Rn   0100nnnn00100010
1573           tmp = SHR_PR;
1574           break;
1575         case 0x03: // STC.L    SR,@–Rn   0100nnnn00000011
1576           tmp = SHR_SR;
1577           break;
1578         case 0x13: // STC.L    GBR,@–Rn  0100nnnn00010011
1579           tmp = SHR_GBR;
1580           break;
1581         case 0x23: // STC.L    VBR,@–Rn  0100nnnn00100011
1582           tmp = SHR_VBR;
1583           break;
1584         default:
1585           goto default_;
1586         }
1587         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1588         emith_sub_r_imm(tmp2, 4);
1589         rcache_clean();
1590         rcache_get_reg_arg(0, GET_Rn());
1591         tmp3 = rcache_get_reg_arg(1, tmp);
1592         if (tmp == SHR_SR)
1593           emith_clear_msb(tmp3, tmp3, 22); // reserved bits defined by ISA as 0
1594         emit_memhandler_write(2, pc, drcf.delayed_op);
1595         goto end_op;
1596       case 0x04:
1597       case 0x05:
1598         switch (op & 0x3f)
1599         {
1600         case 0x04: // ROTL   Rn          0100nnnn00000100
1601         case 0x05: // ROTR   Rn          0100nnnn00000101
1602           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1603           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1604           if (drcf.delayed_op)
1605             DELAY_SAVE_T(sr);
1606           emith_tpop_carry(sr, 0); // dummy
1607           if (op & 1) {
1608             emith_rorf(tmp, tmp, 1);
1609           } else
1610             emith_rolf(tmp, tmp, 1);
1611           emith_tpush_carry(sr, 0);
1612           goto end_op;
1613         case 0x24: // ROTCL  Rn          0100nnnn00100100
1614         case 0x25: // ROTCR  Rn          0100nnnn00100101
1615           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1616           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1617           if (drcf.delayed_op)
1618             DELAY_SAVE_T(sr);
1619           emith_tpop_carry(sr, 0);
1620           if (op & 1) {
1621             emith_rorcf(tmp);
1622           } else
1623             emith_rolcf(tmp);
1624           emith_tpush_carry(sr, 0);
1625           goto end_op;
1626         case 0x15: // CMP/PL Rn          0100nnnn00010101
1627           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1628           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1629           if (drcf.delayed_op)
1630             DELAY_SAVE_T(sr);
1631           emith_bic_r_imm(sr, T);
1632           emith_cmp_r_imm(tmp, 0);
1633           EMITH_SJMP_START(DCOND_LE);
1634           emith_or_r_imm_c(DCOND_GT, sr, T);
1635           EMITH_SJMP_END(DCOND_LE);
1636           goto end_op;
1637         }
1638         goto default_;
1639       case 0x06:
1640       case 0x07:
1641         switch (op & 0x3f)
1642         {
1643         case 0x06: // LDS.L @Rm+,MACH 0100mmmm00000110
1644           tmp = SHR_MACH;
1645           break;
1646         case 0x16: // LDS.L @Rm+,MACL 0100mmmm00010110
1647           tmp = SHR_MACL;
1648           break;
1649         case 0x26: // LDS.L @Rm+,PR   0100mmmm00100110
1650           tmp = SHR_PR;
1651           break;
1652         case 0x07: // LDC.L @Rm+,SR   0100mmmm00000111
1653           tmp = SHR_SR;
1654           break;
1655         case 0x17: // LDC.L @Rm+,GBR  0100mmmm00010111
1656           tmp = SHR_GBR;
1657           break;
1658         case 0x27: // LDC.L @Rm+,VBR  0100mmmm00100111
1659           tmp = SHR_VBR;
1660           break;
1661         default:
1662           goto default_;
1663         }
1664         rcache_clean();
1665         rcache_get_reg_arg(0, GET_Rn());
1666         tmp2 = emit_memhandler_read(2);
1667         if (tmp == SHR_SR) {
1668           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1669           if (drcf.delayed_op)
1670             DELAY_SAVE_T(sr);
1671           emith_write_sr(sr, tmp2);
1672           drcf.test_irq = 1;
1673         } else {
1674           tmp = rcache_get_reg(tmp, RC_GR_WRITE);
1675           emith_move_r_r(tmp, tmp2);
1676         }
1677         rcache_free_tmp(tmp2);
1678         tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1679         emith_add_r_imm(tmp, 4);
1680         goto end_op;
1681       case 0x08:
1682       case 0x09:
1683         switch (GET_Fx())
1684         {
1685         case 0:
1686           // SHLL2 Rn        0100nnnn00001000
1687           // SHLR2 Rn        0100nnnn00001001
1688           tmp = 2;
1689           break;
1690         case 1:
1691           // SHLL8 Rn        0100nnnn00011000
1692           // SHLR8 Rn        0100nnnn00011001
1693           tmp = 8;
1694           break;
1695         case 2:
1696           // SHLL16 Rn       0100nnnn00101000
1697           // SHLR16 Rn       0100nnnn00101001
1698           tmp = 16;
1699           break;
1700         default:
1701           goto default_;
1702         }
1703         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1704         if (op & 1) {
1705           emith_lsr(tmp2, tmp2, tmp);
1706         } else
1707           emith_lsl(tmp2, tmp2, tmp);
1708         goto end_op;
1709       case 0x0a:
1710         switch (GET_Fx())
1711         {
1712         case 0: // LDS      Rm,MACH   0100mmmm00001010
1713           tmp2 = SHR_MACH;
1714           break;
1715         case 1: // LDS      Rm,MACL   0100mmmm00011010
1716           tmp2 = SHR_MACL;
1717           break;
1718         case 2: // LDS      Rm,PR     0100mmmm00101010
1719           tmp2 = SHR_PR;
1720           break;
1721         default:
1722           goto default_;
1723         }
1724         emit_move_r_r(tmp2, GET_Rn());
1725         goto end_op;
1726       case 0x0b:
1727         switch (GET_Fx())
1728         {
1729         case 0: // JSR  @Rm   0100mmmm00001011
1730         case 2: // JMP  @Rm   0100mmmm00101011
1731           DELAYED_OP;
1732           if (!(op & 0x20))
1733             emit_move_r_imm32(SHR_PR, pc + 2);
1734           emit_move_r_r(SHR_PC, (op >> 8) & 0x0f);
1735           out_pc = (u32)-1;
1736           cycles++;
1737           break;
1738         case 1: // TAS.B @Rn  0100nnnn00011011
1739           // XXX: is TAS working on 32X?
1740           rcache_clean();
1741           rcache_get_reg_arg(0, GET_Rn());
1742           tmp = emit_memhandler_read(0);
1743           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
1744           if (drcf.delayed_op)
1745             DELAY_SAVE_T(sr);
1746           emith_bic_r_imm(sr, T);
1747           emith_cmp_r_imm(tmp, 0);
1748           emit_or_t_if_eq(sr);
1749           rcache_clean();
1750           emith_or_r_imm(tmp, 0x80);
1751           tmp2 = rcache_get_tmp_arg(1); // assuming it differs to tmp
1752           emith_move_r_r(tmp2, tmp);
1753           rcache_free_tmp(tmp);
1754           rcache_get_reg_arg(0, GET_Rn());
1755           emit_memhandler_write(0, pc, drcf.delayed_op);
1756           cycles += 3;
1757           break;
1758         default:
1759           goto default_;
1760         }
1761         goto end_op;
1762       case 0x0e:
1763         tmp = rcache_get_reg(GET_Rn(), RC_GR_READ);
1764         switch (GET_Fx())
1765         {
1766         case 0: // LDC Rm,SR   0100mmmm00001110
1767           tmp2 = SHR_SR;
1768           break;
1769         case 1: // LDC Rm,GBR  0100mmmm00011110
1770           tmp2 = SHR_GBR;
1771           break;
1772         case 2: // LDC Rm,VBR  0100mmmm00101110
1773           tmp2 = SHR_VBR;
1774           break;
1775         default:
1776           goto default_;
1777         }
1778         if (tmp2 == SHR_SR) {
1779           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1780           if (drcf.delayed_op)
1781             DELAY_SAVE_T(sr);
1782           emith_write_sr(sr, tmp);
1783           drcf.test_irq = 1;
1784         } else {
1785           tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE);
1786           emith_move_r_r(tmp2, tmp);
1787         }
1788         goto end_op;
1789       case 0x0f:
1790         // MAC @Rm+,@Rn+  0100nnnnmmmm1111
1791         emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1);
1792         emith_sext(tmp, tmp, 16);
1793         emith_sext(tmp2, tmp2, 16);
1794         tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW);
1795         tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
1796         emith_mula_s64(tmp3, tmp4, tmp, tmp2);
1797         rcache_free_tmp(tmp2);
1798         // XXX: MACH should be untouched when S is set?
1799         sr = rcache_get_reg(SHR_SR, RC_GR_READ);
1800         emith_tst_r_imm(sr, S);
1801         EMITH_JMP_START(DCOND_EQ);
1802
1803         emith_asr(tmp, tmp3, 31);
1804         emith_eorf_r_r(tmp, tmp4); // tmp = ((signed)macl >> 31) ^ mach
1805         EMITH_JMP_START(DCOND_EQ);
1806         emith_move_r_imm(tmp3, 0x80000000);
1807         emith_tst_r_r(tmp4, tmp4);
1808         EMITH_SJMP_START(DCOND_MI);
1809         emith_sub_r_imm_c(DCOND_PL, tmp3, 1); // positive
1810         EMITH_SJMP_END(DCOND_MI);
1811         EMITH_JMP_END(DCOND_EQ);
1812
1813         EMITH_JMP_END(DCOND_EQ);
1814         rcache_free_tmp(tmp);
1815         cycles += 2;
1816         goto end_op;
1817       }
1818       goto default_;
1819
1820     /////////////////////////////////////////////
1821     case 0x05:
1822       // MOV.L @(disp,Rm),Rn 0101nnnnmmmmdddd
1823       rcache_clean();
1824       tmp = rcache_get_reg_arg(0, GET_Rm());
1825       emith_add_r_imm(tmp, (op & 0x0f) * 4);
1826       tmp = emit_memhandler_read(2);
1827       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1828       emith_move_r_r(tmp2, tmp);
1829       rcache_free_tmp(tmp);
1830       goto end_op;
1831
1832     /////////////////////////////////////////////
1833     case 0x06:
1834       switch (op & 0x0f)
1835       {
1836       case 0x00: // MOV.B @Rm,Rn        0110nnnnmmmm0000
1837       case 0x01: // MOV.W @Rm,Rn        0110nnnnmmmm0001
1838       case 0x02: // MOV.L @Rm,Rn        0110nnnnmmmm0010
1839       case 0x04: // MOV.B @Rm+,Rn       0110nnnnmmmm0100
1840       case 0x05: // MOV.W @Rm+,Rn       0110nnnnmmmm0101
1841       case 0x06: // MOV.L @Rm+,Rn       0110nnnnmmmm0110
1842         rcache_clean();
1843         rcache_get_reg_arg(0, GET_Rm());
1844         tmp  = emit_memhandler_read(op & 3);
1845         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1846         if ((op & 3) != 2) {
1847           emith_sext(tmp2, tmp, (op & 1) ? 16 : 8);
1848         } else
1849           emith_move_r_r(tmp2, tmp);
1850         rcache_free_tmp(tmp);
1851         if ((op & 7) >= 4 && GET_Rn() != GET_Rm()) {
1852           tmp = rcache_get_reg(GET_Rm(), RC_GR_RMW);
1853           emith_add_r_imm(tmp, (1 << (op & 3)));
1854         }
1855         goto end_op;
1856       case 0x03:
1857       case 0x07 ... 0x0f:
1858         tmp  = rcache_get_reg(GET_Rm(), RC_GR_READ);
1859         tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1860         switch (op & 0x0f)
1861         {
1862         case 0x03: // MOV    Rm,Rn        0110nnnnmmmm0011
1863           emith_move_r_r(tmp2, tmp);
1864           break;
1865         case 0x07: // NOT    Rm,Rn        0110nnnnmmmm0111
1866           emith_mvn_r_r(tmp2, tmp);
1867           break;
1868         case 0x08: // SWAP.B Rm,Rn        0110nnnnmmmm1000
1869           tmp3 = tmp2;
1870           if (tmp == tmp2)
1871             tmp3 = rcache_get_tmp();
1872           tmp4 = rcache_get_tmp();
1873           emith_lsr(tmp3, tmp, 16);
1874           emith_or_r_r_lsl(tmp3, tmp, 24);
1875           emith_and_r_r_imm(tmp4, tmp, 0xff00);
1876           emith_or_r_r_lsl(tmp3, tmp4, 8);
1877           emith_rol(tmp2, tmp3, 16);
1878           rcache_free_tmp(tmp4);
1879           if (tmp == tmp2)
1880             rcache_free_tmp(tmp3);
1881           break;
1882         case 0x09: // SWAP.W Rm,Rn        0110nnnnmmmm1001
1883           emith_rol(tmp2, tmp, 16);
1884           break;
1885         case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
1886           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1887           if (drcf.delayed_op)
1888             DELAY_SAVE_T(sr);
1889           emith_tpop_carry(sr, 1);
1890           emith_negcf_r_r(tmp2, tmp);
1891           emith_tpush_carry(sr, 1);
1892           break;
1893         case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
1894           emith_neg_r_r(tmp2, tmp);
1895           break;
1896         case 0x0c: // EXTU.B Rm,Rn        0110nnnnmmmm1100
1897           emith_clear_msb(tmp2, tmp, 24);
1898           break;
1899         case 0x0d: // EXTU.W Rm,Rn        0110nnnnmmmm1101
1900           emith_clear_msb(tmp2, tmp, 16);
1901           break;
1902         case 0x0e: // EXTS.B Rm,Rn        0110nnnnmmmm1110
1903           emith_sext(tmp2, tmp, 8);
1904           break;
1905         case 0x0f: // EXTS.W Rm,Rn        0110nnnnmmmm1111
1906           emith_sext(tmp2, tmp, 16);
1907           break;
1908         }
1909         goto end_op;
1910       }
1911       goto default_;
1912
1913     /////////////////////////////////////////////
1914     case 0x07:
1915       // ADD #imm,Rn  0111nnnniiiiiiii
1916       tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
1917       if (op & 0x80) { // adding negative
1918         emith_sub_r_imm(tmp, -op & 0xff);
1919       } else
1920         emith_add_r_imm(tmp, op & 0xff);
1921       goto end_op;
1922
1923     /////////////////////////////////////////////
1924     case 0x08:
1925       switch (op & 0x0f00)
1926       {
1927       case 0x0000: // MOV.B R0,@(disp,Rn)  10000000nnnndddd
1928       case 0x0100: // MOV.W R0,@(disp,Rn)  10000001nnnndddd
1929         rcache_clean();
1930         tmp  = rcache_get_reg_arg(0, GET_Rm());
1931         tmp2 = rcache_get_reg_arg(1, SHR_R0);
1932         tmp3 = (op & 0x100) >> 8;
1933         emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
1934         emit_memhandler_write(tmp3, pc, drcf.delayed_op);
1935         goto end_op;
1936       case 0x0400: // MOV.B @(disp,Rm),R0  10000100mmmmdddd
1937       case 0x0500: // MOV.W @(disp,Rm),R0  10000101mmmmdddd
1938         rcache_clean();
1939         tmp  = rcache_get_reg_arg(0, GET_Rm());
1940         tmp3 = (op & 0x100) >> 8;
1941         emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
1942         tmp  = emit_memhandler_read(tmp3);
1943         tmp2 = rcache_get_reg(0, RC_GR_WRITE);
1944         emith_sext(tmp2, tmp, 8 << tmp3);
1945         rcache_free_tmp(tmp);
1946         goto end_op;
1947       case 0x0800: // CMP/EQ #imm,R0       10001000iiiiiiii
1948         // XXX: could use cmn
1949         tmp  = rcache_get_tmp();
1950         tmp2 = rcache_get_reg(0, RC_GR_READ);
1951         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
1952         if (drcf.delayed_op)
1953           DELAY_SAVE_T(sr);
1954         emith_move_r_imm_s8(tmp, op & 0xff);
1955         emith_bic_r_imm(sr, T);
1956         emith_cmp_r_r(tmp2, tmp);
1957         emit_or_t_if_eq(sr);
1958         rcache_free_tmp(tmp);
1959         goto end_op;
1960       case 0x0d00: // BT/S label 10001101dddddddd
1961       case 0x0f00: // BF/S label 10001111dddddddd
1962         DELAYED_OP;
1963         cycles--;
1964         // fallthrough
1965       case 0x0900: // BT   label 10001001dddddddd
1966       case 0x0b00: // BF   label 10001011dddddddd
1967         // will handle conditional branches later
1968         pending_branch_cond = (op & 0x0200) ? DCOND_EQ : DCOND_NE;
1969         i = ((signed int)(op << 24) >> 23);
1970         pending_branch_pc = pc + i + 2;
1971         cycles += 2;
1972         goto end_op;
1973       }
1974       goto default_;
1975
1976     /////////////////////////////////////////////
1977     case 0x09:
1978       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
1979       rcache_clean();
1980       tmp = rcache_get_tmp_arg(0);
1981       emith_move_r_imm(tmp, pc + (op & 0xff) * 2 + 2);
1982       tmp  = emit_memhandler_read(1);
1983       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
1984       emith_sext(tmp2, tmp, 16);
1985       rcache_free_tmp(tmp);
1986       goto end_op;
1987
1988     /////////////////////////////////////////////
1989     case 0x0a:
1990       // BRA  label 1010dddddddddddd
1991       DELAYED_OP;
1992       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
1993       tmp = ((signed int)(op << 20) >> 19);
1994       out_pc = pc + tmp + 2;
1995       if (tmp == (u32)-4)
1996         emith_clear_msb(sr, sr, 20); // burn cycles
1997       cycles++;
1998       break;
1999
2000     /////////////////////////////////////////////
2001     case 0x0b:
2002       // BSR  label 1011dddddddddddd
2003       DELAYED_OP;
2004       emit_move_r_imm32(SHR_PR, pc + 2);
2005       tmp = ((signed int)(op << 20) >> 19);
2006       out_pc = pc + tmp + 2;
2007       cycles++;
2008       break;
2009
2010     /////////////////////////////////////////////
2011     case 0x0c:
2012       switch (op & 0x0f00)
2013       {
2014       case 0x0000: // MOV.B R0,@(disp,GBR)   11000000dddddddd
2015       case 0x0100: // MOV.W R0,@(disp,GBR)   11000001dddddddd
2016       case 0x0200: // MOV.L R0,@(disp,GBR)   11000010dddddddd
2017         rcache_clean();
2018         tmp  = rcache_get_reg_arg(0, SHR_GBR);
2019         tmp2 = rcache_get_reg_arg(1, SHR_R0);
2020         tmp3 = (op & 0x300) >> 8;
2021         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
2022         emit_memhandler_write(tmp3, pc, drcf.delayed_op);
2023         goto end_op;
2024       case 0x0400: // MOV.B @(disp,GBR),R0   11000100dddddddd
2025       case 0x0500: // MOV.W @(disp,GBR),R0   11000101dddddddd
2026       case 0x0600: // MOV.L @(disp,GBR),R0   11000110dddddddd
2027         rcache_clean();
2028         tmp  = rcache_get_reg_arg(0, SHR_GBR);
2029         tmp3 = (op & 0x300) >> 8;
2030         emith_add_r_imm(tmp, (op & 0xff) << tmp3);
2031         tmp  = emit_memhandler_read(tmp3);
2032         tmp2 = rcache_get_reg(0, RC_GR_WRITE);
2033         if (tmp3 != 2) {
2034           emith_sext(tmp2, tmp, 8 << tmp3);
2035         } else
2036           emith_move_r_r(tmp2, tmp);
2037         rcache_free_tmp(tmp);
2038         goto end_op;
2039       case 0x0300: // TRAPA #imm      11000011iiiiiiii
2040         tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
2041         emith_sub_r_imm(tmp, 4*2);
2042         rcache_clean();
2043         // push SR
2044         tmp = rcache_get_reg_arg(0, SHR_SP);
2045         emith_add_r_imm(tmp, 4);
2046         tmp = rcache_get_reg_arg(1, SHR_SR);
2047         emith_clear_msb(tmp, tmp, 22);
2048         emit_memhandler_write(2, pc, drcf.delayed_op);
2049         // push PC
2050         rcache_get_reg_arg(0, SHR_SP);
2051         tmp = rcache_get_tmp_arg(1);
2052         emith_move_r_imm(tmp, pc);
2053         emit_memhandler_write(2, pc, drcf.delayed_op);
2054         // obtain new PC
2055         tmp = rcache_get_reg_arg(0, SHR_VBR);
2056         emith_add_r_imm(tmp, (op & 0xff) * 4);
2057         tmp  = emit_memhandler_read(2);
2058         tmp2 = rcache_get_reg(SHR_PC, RC_GR_WRITE);
2059         emith_move_r_r(tmp2, tmp);
2060         rcache_free_tmp(tmp);
2061         out_pc = (u32)-1;
2062         cycles += 7;
2063         goto end_op;
2064       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
2065         emit_move_r_imm32(SHR_R0, (pc + (op & 0xff) * 4 + 2) & ~3);
2066         goto end_op;
2067       case 0x0800: // TST #imm,R0           11001000iiiiiiii
2068         tmp = rcache_get_reg(SHR_R0, RC_GR_READ);
2069         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2070         if (drcf.delayed_op)
2071           DELAY_SAVE_T(sr);
2072         emith_bic_r_imm(sr, T);
2073         emith_tst_r_imm(tmp, op & 0xff);
2074         emit_or_t_if_eq(sr);
2075         goto end_op;
2076       case 0x0900: // AND #imm,R0           11001001iiiiiiii
2077         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2078         emith_and_r_imm(tmp, op & 0xff);
2079         goto end_op;
2080       case 0x0a00: // XOR #imm,R0           11001010iiiiiiii
2081         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2082         emith_eor_r_imm(tmp, op & 0xff);
2083         goto end_op;
2084       case 0x0b00: // OR  #imm,R0           11001011iiiiiiii
2085         tmp = rcache_get_reg(SHR_R0, RC_GR_RMW);
2086         emith_or_r_imm(tmp, op & 0xff);
2087         goto end_op;
2088       case 0x0c00: // TST.B #imm,@(R0,GBR)  11001100iiiiiiii
2089         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2090         sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
2091         if (drcf.delayed_op)
2092           DELAY_SAVE_T(sr);
2093         emith_bic_r_imm(sr, T);
2094         emith_tst_r_imm(tmp, op & 0xff);
2095         emit_or_t_if_eq(sr);
2096         rcache_free_tmp(tmp);
2097         cycles += 2;
2098         goto end_op;
2099       case 0x0d00: // AND.B #imm,@(R0,GBR)  11001101iiiiiiii
2100         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2101         emith_and_r_imm(tmp, op & 0xff);
2102         goto end_rmw_op;
2103       case 0x0e00: // XOR.B #imm,@(R0,GBR)  11001110iiiiiiii
2104         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2105         emith_eor_r_imm(tmp, op & 0xff);
2106         goto end_rmw_op;
2107       case 0x0f00: // OR.B  #imm,@(R0,GBR)  11001111iiiiiiii
2108         tmp = emit_indirect_indexed_read(SHR_R0, SHR_GBR, 0);
2109         emith_or_r_imm(tmp, op & 0xff);
2110       end_rmw_op:
2111         tmp2 = rcache_get_tmp_arg(1);
2112         emith_move_r_r(tmp2, tmp);
2113         rcache_free_tmp(tmp);
2114         tmp3 = rcache_get_reg_arg(0, SHR_GBR);
2115         tmp4 = rcache_get_reg(SHR_R0, RC_GR_READ);
2116         emith_add_r_r(tmp3, tmp4);
2117         emit_memhandler_write(0, pc, drcf.delayed_op);
2118         cycles += 2;
2119         goto end_op;
2120       }
2121       goto default_;
2122
2123     /////////////////////////////////////////////
2124     case 0x0d:
2125       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
2126       rcache_clean();
2127       tmp = rcache_get_tmp_arg(0);
2128       emith_move_r_imm(tmp, (pc + (op & 0xff) * 4 + 2) & ~3);
2129       tmp  = emit_memhandler_read(2);
2130       tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
2131       emith_move_r_r(tmp2, tmp);
2132       rcache_free_tmp(tmp);
2133       goto end_op;
2134
2135     /////////////////////////////////////////////
2136     case 0x0e:
2137       // MOV #imm,Rn   1110nnnniiiiiiii
2138       tmp = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
2139       emith_move_r_imm_s8(tmp, op & 0xff);
2140       goto end_op;
2141
2142     default:
2143     default_:
2144       elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
2145         sh2->is_slave ? 's' : 'm', op, pc - 2);
2146 #ifdef DRC_DEBUG_INTERP
2147       emit_move_r_imm32(SHR_PC, pc - 2);
2148       rcache_flush();
2149       emith_pass_arg_r(0, CONTEXT_REG);
2150       emith_pass_arg_imm(1, op);
2151       emith_call(sh2_do_op);
2152 #endif
2153       break;
2154     }
2155
2156 end_op:
2157     // conditional branch handling (with/without delay)
2158     if (pending_branch_cond != -1 && drcf.delayed_op != 2)
2159     {
2160       u32 target_pc = pending_branch_pc;
2161       void *target;
2162
2163       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2164       // handle cycles
2165       FLUSH_CYCLES(sr);
2166       rcache_clean();
2167       if (drcf.use_saved_t)
2168         emith_tst_r_imm(sr, T_save);
2169       else
2170         emith_tst_r_imm(sr, T);
2171
2172       if (find_in_array(branch_target_pc, branch_target_count, target_pc) >= 0) {
2173         // local branch
2174         // XXX: jumps back can be linked already
2175         branch_patch_pc[branch_patch_count] = target_pc;
2176         branch_patch_ptr[branch_patch_count] = tcache_ptr;
2177         emith_jump_cond_patchable(pending_branch_cond, tcache_ptr);
2178
2179         branch_patch_count++;
2180         if (branch_patch_count == MAX_LOCAL_BRANCHES) {
2181           printf("warning: too many local branches\n");
2182           break;
2183         }
2184       }
2185       else {
2186         // can't resolve branch locally, make a block exit
2187         emit_move_r_imm32(SHR_PC, target_pc);
2188         rcache_clean();
2189
2190         target = dr_prepare_ext_branch(target_pc, sh2, tcache_id);
2191         if (target == NULL)
2192           return NULL;
2193         emith_jump_cond_patchable(pending_branch_cond, target);
2194       }
2195
2196       drcf.use_saved_t = 0;
2197       pending_branch_cond = -1;
2198     }
2199
2200     // test irq?
2201     // XXX: delay slots..
2202     if (drcf.test_irq && drcf.delayed_op != 2) {
2203       if (!drcf.delayed_op)
2204         emit_move_r_imm32(SHR_PC, pc);
2205       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2206       FLUSH_CYCLES(sr);
2207       rcache_flush();
2208       emith_call(sh2_drc_test_irq);
2209       drcf.test_irq = 0;
2210     }
2211
2212     do_host_disasm(tcache_id);
2213
2214     if (out_pc != 0 && drcf.delayed_op != 2)
2215       break;
2216   }
2217
2218   tmp = rcache_get_reg(SHR_SR, RC_GR_RMW);
2219   FLUSH_CYCLES(tmp);
2220   rcache_flush();
2221
2222   if (out_pc == (u32)-1) {
2223     // indirect jump -> back to dispatcher
2224     emith_jump(sh2_drc_dispatcher);
2225   } else {
2226     void *target;
2227     if (out_pc == 0)
2228       out_pc = pc;
2229     emit_move_r_imm32(SHR_PC, out_pc);
2230     rcache_flush();
2231
2232     target = dr_prepare_ext_branch(out_pc, sh2, tcache_id);
2233     if (target == NULL)
2234       return NULL;
2235     emith_jump_patchable(target);
2236   }
2237
2238   // link local branches
2239   for (i = 0; i < branch_patch_count; i++) {
2240     void *target;
2241     int t;
2242     t = find_in_array(branch_target_pc, branch_target_count, branch_patch_pc[i]);
2243     target = branch_target_ptr[t];
2244     if (target == NULL) {
2245       // flush pc and go back to dispatcher (should no longer happen)
2246       printf("stray branch to %08x %p\n", branch_patch_pc[i], tcache_ptr);
2247       target = tcache_ptr;
2248       emit_move_r_imm32(SHR_PC, branch_patch_pc[i]);
2249       rcache_flush();
2250       emith_jump(sh2_drc_dispatcher);
2251     }
2252     emith_jump_patch(branch_patch_ptr[i], target);
2253   }
2254
2255   this_block->end_addr = pc;
2256
2257   // mark memory blocks as containing compiled code
2258   if (tcache_id != 0) {
2259     // data array, BIOS
2260     u16 *drcblk = Pico32xMem->drcblk_da[sh2->is_slave];
2261     tmp  = (this_block->addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
2262     tmp2 = (this_block->end_addr & 0xfff) >> SH2_DRCBLK_DA_SHIFT;
2263     drcblk[tmp] = (blkid_main << 1) | 1;
2264     for (++tmp; tmp < tmp2; tmp++) {
2265       if (drcblk[tmp])
2266         continue; // dont overwrite overlay block(s)
2267       drcblk[tmp] = blkid_main << 1;
2268     }
2269   }
2270   else if ((this_block->addr & 0xc7fc0000) == 0x06000000) { // DRAM
2271     tmp  = (this_block->addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
2272     tmp2 = (this_block->end_addr & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT;
2273     Pico32xMem->drcblk_ram[tmp] = (blkid_main << 1) | 1;
2274     for (++tmp; tmp < tmp2; tmp++) {
2275       if (Pico32xMem->drcblk_ram[tmp])
2276         continue;
2277       Pico32xMem->drcblk_ram[tmp] = blkid_main << 1;
2278     }
2279   }
2280
2281   tcache_ptrs[tcache_id] = tcache_ptr;
2282
2283 #ifdef ARM
2284   cache_flush_d_inval_i(block_entry, tcache_ptr);
2285 #endif
2286
2287   do_host_disasm(tcache_id);
2288   dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
2289     tcache_id, block_counts[tcache_id],
2290     tcache_ptr - tcache_bases[tcache_id], tcache_sizes[tcache_id],
2291     insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
2292   if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
2293     dbg(1, "  hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
2294 /*
2295  printf("~~~\n");
2296  tcache_dsm_ptrs[tcache_id] = block_entry;
2297  do_host_disasm(tcache_id);
2298  printf("~~~\n");
2299 */
2300
2301 #if (DRC_DEBUG & 2)
2302   fflush(stdout);
2303 #endif
2304
2305   return block_entry;
2306 }
2307
2308 static void sh2_generate_utils(void)
2309 {
2310   int arg0, arg1, arg2, sr, tmp;
2311   void *sh2_drc_write_end, *sh2_drc_write_slot_end;
2312
2313   host_arg2reg(arg0, 0);
2314   host_arg2reg(arg1, 1);
2315   host_arg2reg(arg2, 2);
2316   emith_move_r_r(arg0, arg0); // nop
2317
2318   // sh2_drc_exit(void)
2319   sh2_drc_exit = (void *)tcache_ptr;
2320   emit_do_static_regs(1, arg2);
2321   emith_sh2_drc_exit();
2322
2323   // sh2_drc_dispatcher(void)
2324   sh2_drc_dispatcher = (void *)tcache_ptr;
2325   sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2326   emith_cmp_r_imm(sr, 0);
2327   emith_jump_cond(DCOND_LT, sh2_drc_exit);
2328   rcache_invalidate();
2329   emith_ctx_read(arg0, SHR_PC * 4);
2330   emith_ctx_read(arg1, offsetof(SH2, is_slave));
2331   emith_add_r_r_imm(arg2, CONTEXT_REG, offsetof(SH2, drc_tmp));
2332   emith_call(lookup_block);
2333   emit_block_entry();
2334   // lookup failed, call sh2_translate()
2335   emith_move_r_r(arg0, CONTEXT_REG);
2336   emith_ctx_read(arg1, offsetof(SH2, drc_tmp)); // tcache_id
2337   emith_call(sh2_translate);
2338   emit_block_entry();
2339   // sh2_translate() failed, flush cache and retry
2340   emith_ctx_read(arg0, offsetof(SH2, drc_tmp));
2341   emith_call(flush_tcache);
2342   emith_move_r_r(arg0, CONTEXT_REG);
2343   emith_ctx_read(arg1, offsetof(SH2, drc_tmp));
2344   emith_call(sh2_translate);
2345   emit_block_entry();
2346   // XXX: can't translate, fail
2347   emith_call(exit);
2348
2349   // sh2_drc_test_irq(void)
2350   // assumes it's called from main function (may jump to dispatcher)
2351   sh2_drc_test_irq = (void *)tcache_ptr;
2352   emith_ctx_read(arg1, offsetof(SH2, pending_level));
2353   sr = rcache_get_reg(SHR_SR, RC_GR_READ);
2354   emith_lsr(arg0, sr, I_SHIFT);
2355   emith_and_r_imm(arg0, 0x0f);
2356   emith_cmp_r_r(arg1, arg0); // pending_level > ((sr >> 4) & 0x0f)?
2357   EMITH_SJMP_START(DCOND_GT);
2358   emith_ret_c(DCOND_LE);     // nope, return
2359   EMITH_SJMP_END(DCOND_GT);
2360   // adjust SP
2361   tmp = rcache_get_reg(SHR_SP, RC_GR_RMW);
2362   emith_sub_r_imm(tmp, 4*2);
2363   rcache_clean();
2364   // push SR
2365   tmp = rcache_get_reg_arg(0, SHR_SP);
2366   emith_add_r_imm(tmp, 4);
2367   tmp = rcache_get_reg_arg(1, SHR_SR);
2368   emith_clear_msb(tmp, tmp, 22);
2369   emith_move_r_r(arg2, CONTEXT_REG);
2370   emith_call(p32x_sh2_write32);
2371   rcache_invalidate();
2372   // push PC
2373   rcache_get_reg_arg(0, SHR_SP);
2374   emith_ctx_read(arg1, SHR_PC * 4);
2375   emith_move_r_r(arg2, CONTEXT_REG);
2376   emith_call(p32x_sh2_write32);
2377   rcache_invalidate();
2378   // update I, cycles, do callback
2379   emith_ctx_read(arg1, offsetof(SH2, pending_level));
2380   sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2381   emith_bic_r_imm(sr, I);
2382   emith_or_r_r_lsl(sr, arg1, I_SHIFT);
2383   emith_sub_r_imm(sr, 13 << 12); // at least 13 cycles
2384   rcache_flush();
2385   emith_move_r_r(arg0, CONTEXT_REG);
2386   emith_call_ctx(offsetof(SH2, irq_callback)); // vector = sh2->irq_callback(sh2, level);
2387   // obtain new PC
2388   emith_lsl(arg0, arg0, 2);
2389   emith_ctx_read(arg1, SHR_VBR * 4);
2390   emith_add_r_r(arg0, arg1);
2391   emit_memhandler_read(2);
2392   emith_ctx_write(arg0, SHR_PC * 4);
2393 #ifdef __i386__
2394   emith_add_r_imm(xSP, 4); // fix stack
2395 #endif
2396   emith_jump(sh2_drc_dispatcher);
2397   rcache_invalidate();
2398
2399   // sh2_drc_entry(SH2 *sh2)
2400   sh2_drc_entry = (void *)tcache_ptr;
2401   emith_sh2_drc_entry();
2402   emith_move_r_r(CONTEXT_REG, arg0); // move ctx, arg0
2403   emit_do_static_regs(0, arg2);
2404   emith_call(sh2_drc_test_irq);
2405   emith_jump(sh2_drc_dispatcher);
2406
2407   // write-caused irq detection
2408   sh2_drc_write_end = tcache_ptr;
2409   emith_tst_r_r(arg0, arg0);
2410   EMITH_SJMP_START(DCOND_NE);
2411   emith_jump_ctx_c(DCOND_EQ, offsetof(SH2, drc_tmp)); // return
2412   EMITH_SJMP_END(DCOND_NE);
2413   // since PC is up to date, jump to it's block instead of returning
2414   emith_call(sh2_drc_test_irq);
2415   emith_jump_ctx(offsetof(SH2, drc_tmp));
2416
2417   // write-caused irq detection for writes in delay slot
2418   sh2_drc_write_slot_end = tcache_ptr;
2419   emith_tst_r_r(arg0, arg0);
2420   EMITH_SJMP_START(DCOND_NE);
2421   emith_jump_ctx_c(DCOND_EQ, offsetof(SH2, drc_tmp));
2422   EMITH_SJMP_END(DCOND_NE);
2423   // just burn cycles to get back to dispatcher after branch is handled
2424   sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
2425   emith_ctx_write(sr, offsetof(SH2, irq_cycles));
2426   emith_clear_msb(sr, sr, 20); // clear cycles
2427   rcache_flush();
2428   emith_jump_ctx(offsetof(SH2, drc_tmp));
2429
2430   // sh2_drc_write8(u32 a, u32 d)
2431   sh2_drc_write8 = (void *)tcache_ptr;
2432   emith_ret_to_ctx(offsetof(SH2, drc_tmp));
2433   emith_ctx_read(arg2, offsetof(SH2, write8_tab));
2434   emith_sh2_wcall(arg0, arg2, sh2_drc_write_end);
2435
2436   // sh2_drc_write16(u32 a, u32 d)
2437   sh2_drc_write16 = (void *)tcache_ptr;
2438   emith_ret_to_ctx(offsetof(SH2, drc_tmp));
2439   emith_ctx_read(arg2, offsetof(SH2, write16_tab));
2440   emith_sh2_wcall(arg0, arg2, sh2_drc_write_end);
2441
2442   // sh2_drc_write8_slot(u32 a, u32 d)
2443   sh2_drc_write8_slot = (void *)tcache_ptr;
2444   emith_ret_to_ctx(offsetof(SH2, drc_tmp));
2445   emith_ctx_read(arg2, offsetof(SH2, write8_tab));
2446   emith_sh2_wcall(arg0, arg2, sh2_drc_write_slot_end);
2447
2448   // sh2_drc_write16_slot(u32 a, u32 d)
2449   sh2_drc_write16_slot = (void *)tcache_ptr;
2450   emith_ret_to_ctx(offsetof(SH2, drc_tmp));
2451   emith_ctx_read(arg2, offsetof(SH2, write16_tab));
2452   emith_sh2_wcall(arg0, arg2, sh2_drc_write_slot_end);
2453
2454   rcache_invalidate();
2455 #if (DRC_DEBUG & 2)
2456   host_dasm_new_symbol(sh2_drc_entry);
2457   host_dasm_new_symbol(sh2_drc_dispatcher);
2458   host_dasm_new_symbol(sh2_drc_exit);
2459   host_dasm_new_symbol(sh2_drc_test_irq);
2460   host_dasm_new_symbol(sh2_drc_write_end);
2461   host_dasm_new_symbol(sh2_drc_write_slot_end);
2462   host_dasm_new_symbol(sh2_drc_write8);
2463   host_dasm_new_symbol(sh2_drc_write8_slot);
2464   host_dasm_new_symbol(sh2_drc_write16);
2465   host_dasm_new_symbol(sh2_drc_write16_slot);
2466 #endif
2467 }
2468
2469 static void sh2_smc_rm_block(u16 *drcblk, u16 *p, block_desc *btab, u32 a)
2470 {
2471   u16 id = *p >> 1;
2472   block_desc *bd = btab + id;
2473
2474   // FIXME: skip subblocks; do both directions
2475   // FIXME: collect all branches
2476   dbg(1, "  killing block %08x", bd->addr);
2477   bd->addr = bd->end_addr = 0;
2478
2479   while (p > drcblk && (p[-1] >> 1) == id)
2480     p--;
2481
2482   // check for possible overlay block
2483   if (p > 0 && p[-1] != 0) {
2484     bd = btab + (p[-1] >> 1);
2485     if (bd->addr <= a && a < bd->end_addr)
2486       sh2_smc_rm_block(drcblk, p - 1, btab, a);
2487   }
2488
2489   do {
2490     *p++ = 0;
2491   }
2492   while ((*p >> 1) == id);
2493 }
2494
2495 void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
2496 {
2497   u16 *drcblk = Pico32xMem->drcblk_ram;
2498   u16 *p = drcblk + ((a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT);
2499
2500   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
2501   sh2_smc_rm_block(drcblk, p, block_tables[0], a);
2502 }
2503
2504 void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
2505 {
2506   u16 *drcblk = Pico32xMem->drcblk_da[cpuid];
2507   u16 *p = drcblk + ((a & 0xfff) >> SH2_DRCBLK_DA_SHIFT);
2508
2509   dbg(1, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
2510   sh2_smc_rm_block(drcblk, p, block_tables[1 + cpuid], a);
2511 }
2512
2513 void sh2_execute(SH2 *sh2c, int cycles)
2514 {
2515   int ret_cycles;
2516   sh2 = sh2c; // XXX
2517
2518   sh2c->cycles_aim += cycles;
2519   cycles = sh2c->cycles_aim - sh2c->cycles_done;
2520
2521   // cycles are kept in SHR_SR unused bits (upper 20)
2522   // bit19 contains T saved for delay slot
2523   // others are usual SH2 flags
2524   sh2c->sr &= 0x3f3;
2525   sh2c->sr |= cycles << 12;
2526   sh2_drc_entry(sh2c);
2527
2528   // TODO: irq cycles
2529   ret_cycles = (signed int)sh2c->sr >> 12;
2530   if (ret_cycles > 0)
2531     printf("warning: drc returned with cycles: %d\n", ret_cycles);
2532
2533   sh2c->cycles_done += cycles - ret_cycles;
2534 }
2535
2536 #if (DRC_DEBUG & 1)
2537 void block_stats(void)
2538 {
2539   int c, b, i, total = 0;
2540
2541   printf("block stats:\n");
2542   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
2543     for (i = 0; i < block_counts[b]; i++)
2544       if (block_tables[b][i].addr != 0)
2545         total += block_tables[b][i].refcount;
2546
2547   for (c = 0; c < 10; c++) {
2548     block_desc *blk, *maxb = NULL;
2549     int max = 0;
2550     for (b = 0; b < ARRAY_SIZE(block_tables); b++) {
2551       for (i = 0; i < block_counts[b]; i++) {
2552         blk = &block_tables[b][i];
2553         if (blk->addr != 0 && blk->refcount > max) {
2554           max = blk->refcount;
2555           maxb = blk;
2556         }
2557       }
2558     }
2559     if (maxb == NULL)
2560       break;
2561     printf("%08x %9d %2.3f%%\n", maxb->addr, maxb->refcount,
2562       (double)maxb->refcount / total * 100.0);
2563     maxb->refcount = 0;
2564   }
2565
2566   for (b = 0; b < ARRAY_SIZE(block_tables); b++)
2567     for (i = 0; i < block_counts[b]; i++)
2568       block_tables[b][i].refcount = 0;
2569 }
2570 #else
2571 #define block_stats()
2572 #endif
2573
2574 void sh2_drc_flush_all(void)
2575 {
2576   block_stats();
2577   flush_tcache(0);
2578   flush_tcache(1);
2579   flush_tcache(2);
2580 }
2581
2582 int sh2_drc_init(SH2 *sh2)
2583 {
2584   int i;
2585
2586   if (block_tables[0] == NULL)
2587   {
2588     for (i = 0; i < TCACHE_BUFFERS; i++) {
2589       block_tables[i] = calloc(block_max_counts[i], sizeof(*block_tables[0]));
2590       if (block_tables[i] == NULL)
2591         goto fail;
2592       // max 2 block links (exits) per block
2593       block_links[i] = calloc(block_max_counts[i] * 2, sizeof(*block_links[0]));
2594       if (block_links[i] == NULL)
2595         goto fail;
2596     }
2597     memset(block_counts, 0, sizeof(block_counts));
2598     memset(block_link_counts, 0, sizeof(block_link_counts));
2599
2600     drc_cmn_init();
2601     tcache_ptr = tcache;
2602     sh2_generate_utils();
2603 #ifdef ARM
2604     cache_flush_d_inval_i(tcache, tcache_ptr);
2605 #endif
2606
2607     tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;
2608     for (i = 1; i < ARRAY_SIZE(tcache_bases); i++)
2609       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
2610
2611     // tmp
2612     PicoOpt |= POPT_DIS_VDP_FIFO;
2613
2614 #if (DRC_DEBUG & 2)
2615     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
2616       tcache_dsm_ptrs[i] = tcache_bases[i];
2617     // disasm the utils
2618     tcache_dsm_ptrs[0] = tcache;
2619     do_host_disasm(0);
2620 #endif
2621 #if (DRC_DEBUG & 1)
2622     hash_collisions = 0;
2623 #endif
2624   }
2625
2626   if (hash_table == NULL) {
2627     hash_table = calloc(sizeof(hash_table[0]), MAX_HASH_ENTRIES);
2628     if (hash_table == NULL)
2629       goto fail;
2630   }
2631
2632   return 0;
2633
2634 fail:
2635   sh2_drc_finish(sh2);
2636   return -1;
2637 }
2638
2639 void sh2_drc_finish(SH2 *sh2)
2640 {
2641   int i;
2642
2643   if (block_tables[0] != NULL) {
2644     block_stats();
2645
2646     for (i = 0; i < TCACHE_BUFFERS; i++) {
2647 #if (DRC_DEBUG & 2)
2648       printf("~~~ tcache %d\n", i);
2649       tcache_dsm_ptrs[i] = tcache_bases[i];
2650       tcache_ptr = tcache_ptrs[i];
2651       do_host_disasm(i);
2652 #endif
2653
2654       if (block_tables[i] != NULL)
2655         free(block_tables[i]);
2656       block_tables[i] = NULL;
2657       if (block_links[i] == NULL)
2658         free(block_links[i]);
2659       block_links[i] = NULL;
2660     }
2661
2662     drc_cmn_cleanup();
2663   }
2664
2665   if (hash_table != NULL) {
2666     free(hash_table);
2667     hash_table = NULL;
2668   }
2669 }