+ emith_jump(sh2_drc_dispatcher);
+ rcache_invalidate();
+
+ // sh2_drc_entry(SH2 *sh2)
+ sh2_drc_entry = (void *)tcache_ptr;
+ emith_sh2_drc_entry();
+ emith_move_r_r(CONTEXT_REG, arg0); // move ctx, arg0
+ emit_do_static_regs(0, arg2);
+ emith_call(sh2_drc_test_irq);
+ emith_jump(sh2_drc_dispatcher);
+
+ // write-caused irq detection
+ sh2_drc_write_end = tcache_ptr;
+ emith_tst_r_r(arg0, arg0);
+ EMITH_SJMP_START(DCOND_NE);
+ emith_jump_ctx_c(DCOND_EQ, offsetof(SH2, drc_tmp)); // return
+ EMITH_SJMP_END(DCOND_NE);
+ emith_call(sh2_drc_test_irq);
+ emith_jump_ctx(offsetof(SH2, drc_tmp));
+
+ // write-caused irq detection for writes in delay slot
+ sh2_drc_write_slot_end = tcache_ptr;
+ emith_tst_r_r(arg0, arg0);
+ EMITH_SJMP_START(DCOND_NE);
+ emith_jump_ctx_c(DCOND_EQ, offsetof(SH2, drc_tmp));
+ EMITH_SJMP_END(DCOND_NE);
+ // just burn cycles to get back to dispatcher after branch is handled
+ sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
+ emith_ctx_write(sr, offsetof(SH2, irq_cycles));
+ emith_clear_msb(sr, sr, 20); // clear cycles
+ rcache_flush();
+ emith_jump_ctx(offsetof(SH2, drc_tmp));
+
+ // sh2_drc_write8(u32 a, u32 d)
+ sh2_drc_write8 = (void *)tcache_ptr;
+ emith_ret_to_ctx(offsetof(SH2, drc_tmp));
+ emith_ctx_read(arg2, offsetof(SH2, write8_tab));
+ emith_sh2_wcall(arg0, arg2, sh2_drc_write_end);
+
+ // sh2_drc_write16(u32 a, u32 d)
+ sh2_drc_write16 = (void *)tcache_ptr;
+ emith_ret_to_ctx(offsetof(SH2, drc_tmp));
+ emith_ctx_read(arg2, offsetof(SH2, write16_tab));
+ emith_sh2_wcall(arg0, arg2, sh2_drc_write_end);
+
+ // sh2_drc_write8_slot(u32 a, u32 d)
+ sh2_drc_write8_slot = (void *)tcache_ptr;
+ emith_ret_to_ctx(offsetof(SH2, drc_tmp));
+ emith_ctx_read(arg2, offsetof(SH2, write8_tab));
+ emith_sh2_wcall(arg0, arg2, sh2_drc_write_slot_end);
+
+ // sh2_drc_write16_slot(u32 a, u32 d)
+ sh2_drc_write16_slot = (void *)tcache_ptr;
+ emith_ret_to_ctx(offsetof(SH2, drc_tmp));
+ emith_ctx_read(arg2, offsetof(SH2, write16_tab));
+ emith_sh2_wcall(arg0, arg2, sh2_drc_write_slot_end);
+
+#ifdef PDB_NET
+ // debug
+ #define MAKE_READ_WRAPPER(func) { \
+ void *tmp = (void *)tcache_ptr; \
+ emith_push_ret(); \
+ emith_call(func); \
+ emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[0])); \
+ emith_addf_r_r(arg2, arg0); \
+ emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[0])); \
+ emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[1])); \
+ emith_adc_r_imm(arg2, 0x01000000); \
+ emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[1])); \
+ emith_pop_and_ret(); \
+ func = tmp; \
+ }
+ #define MAKE_WRITE_WRAPPER(func) { \
+ void *tmp = (void *)tcache_ptr; \
+ emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[0])); \
+ emith_addf_r_r(arg2, arg1); \
+ emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[0])); \
+ emith_ctx_read(arg2, offsetof(SH2, pdb_io_csum[1])); \
+ emith_adc_r_imm(arg2, 0x01000000); \
+ emith_ctx_write(arg2, offsetof(SH2, pdb_io_csum[1])); \
+ emith_move_r_r(arg2, CONTEXT_REG); \
+ emith_jump(func); \
+ func = tmp; \