#include "sh2.h"
#include "compiler.h"
#include "../drc/cmn.h"
+#include "../debug.h"
// features
#define PROPAGATE_CONSTANTS 1
#define do_host_disasm(x)
#endif
-#if (DRC_DEBUG & 4)
-static void REGPARM(3) *sh2_drc_announce_entry(void *block, SH2 *sh2, u32 sr)
+#if (DRC_DEBUG & 4) || defined(PDB)
+static void REGPARM(3) *sh2_drc_log_entry(void *block, SH2 *sh2, u32 sr)
{
- if (block != NULL)
+ if (block != NULL) {
dbg(4, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm',
sh2->pc, block, (signed int)sr >> 12);
+ pdb_step(sh2, sh2->pc);
+ }
return block;
}
#endif
static void (*sh2_drc_dispatcher)(void);
static void (*sh2_drc_exit)(void);
static void (*sh2_drc_test_irq)(void);
+
+static u32 REGPARM(2) (*sh2_drc_read8)(u32 a, SH2 *sh2);
+static u32 REGPARM(2) (*sh2_drc_read16)(u32 a, SH2 *sh2);
+static u32 REGPARM(2) (*sh2_drc_read32)(u32 a, SH2 *sh2);
static void REGPARM(2) (*sh2_drc_write8)(u32 a, u32 d);
static void REGPARM(2) (*sh2_drc_write8_slot)(u32 a, u32 d);
static void REGPARM(2) (*sh2_drc_write16)(u32 a, u32 d);
static void REGPARM(2) (*sh2_drc_write16_slot)(u32 a, u32 d);
+static int REGPARM(3) (*sh2_drc_write32)(u32 a, u32 d, SH2 *sh2);
extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
#endif
}
+#if LINK_BRANCHES
// add block links (tracked branches)
static int dr_add_block_link(u32 target_pc, void *jump, int tcache_id)
{
return 0;
}
+#endif
static void *dr_find_block(block_desc *tab, u32 addr)
{
arg1 = rcache_get_tmp_arg(1);
emith_move_r_r(arg1, CONTEXT_REG);
-#if 1
+#ifndef PDB_NET
if (ram_check && Pico.rom == (void *)0x02000000 && Pico32xMem->sdram == (void *)0x06000000) {
int tmp = rcache_get_tmp();
emith_and_r_r_imm(tmp, arg0, 0xfb000000);
emith_eor_r_imm_c(DCOND_EQ, arg0, 1);
emith_read8_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
EMITH_SJMP3_MID(DCOND_NE);
- emith_call_cond(DCOND_NE, p32x_sh2_read8);
+ emith_call_cond(DCOND_NE, sh2_drc_read8);
EMITH_SJMP3_END();
break;
case 1: // 16
EMITH_SJMP3_START(DCOND_NE);
emith_read16_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
EMITH_SJMP3_MID(DCOND_NE);
- emith_call_cond(DCOND_NE, p32x_sh2_read16);
+ emith_call_cond(DCOND_NE, sh2_drc_read16);
EMITH_SJMP3_END();
break;
case 2: // 32
emith_read_r_r_offs_c(DCOND_EQ, arg0, arg0, 0);
emith_ror_c(DCOND_EQ, arg0, arg0, 16);
EMITH_SJMP3_MID(DCOND_NE);
- emith_call_cond(DCOND_NE, p32x_sh2_read32);
+ emith_call_cond(DCOND_NE, sh2_drc_read32);
EMITH_SJMP3_END();
break;
}
{
switch (size) {
case 0: // 8
- emith_call(p32x_sh2_read8);
+ emith_call(sh2_drc_read8);
break;
case 1: // 16
- emith_call(p32x_sh2_read16);
+ emith_call(sh2_drc_read16);
break;
case 2: // 32
- emith_call(p32x_sh2_read32);
+ emith_call(sh2_drc_read32);
break;
}
}
break;
case 2: // 32
emith_move_r_r(ctxr, CONTEXT_REG);
- emith_call(p32x_sh2_write32);
+ emith_call(sh2_drc_write32);
break;
}
rcache_invalidate();
host_arg2reg(arg1, 1);
host_arg2reg(arg2, 2);
-#if (DRC_DEBUG & 4)
+#if (DRC_DEBUG & 4) || defined(PDB)
+ emit_do_static_regs(1, arg2);
emith_move_r_r(arg1, CONTEXT_REG);
emith_move_r_r(arg2, rcache_get_reg(SHR_SR, RC_GR_READ));
- emith_call(sh2_drc_announce_entry);
+ emith_call(sh2_drc_log_entry);
rcache_invalidate();
#endif
emith_tst_r_r(arg0, arg0);
}
branch_target_count = tmp;
memset(branch_target_ptr, 0, sizeof(branch_target_ptr[0]) * branch_target_count);
-#if !LINK_BRANCHES
- // for debug
- branch_target_count = 0;
-#endif
// -------------------------------------------------
// 2nd pass: actual compilation
else
emith_tst_r_imm(sr, T);
+#if LINK_BRANCHES
if (find_in_array(branch_target_pc, branch_target_count, target_pc) >= 0) {
// local branch
// XXX: jumps back can be linked already
break;
}
}
- else {
+ else
+#endif
+ {
// can't resolve branch locally, make a block exit
emit_move_r_imm32(SHR_PC, target_pc);
rcache_clean();
int arg0, arg1, arg2, sr, tmp;
void *sh2_drc_write_end, *sh2_drc_write_slot_end;
+ sh2_drc_write32 = p32x_sh2_write32;
+ sh2_drc_read8 = p32x_sh2_read8;
+ sh2_drc_read16 = p32x_sh2_read16;
+ sh2_drc_read32 = p32x_sh2_read32;
+
host_arg2reg(arg0, 0);
host_arg2reg(arg1, 1);
host_arg2reg(arg2, 2);
tmp = rcache_get_reg_arg(1, SHR_SR);
emith_clear_msb(tmp, tmp, 22);
emith_move_r_r(arg2, CONTEXT_REG);
- emith_call(p32x_sh2_write32);
+ emith_call(p32x_sh2_write32); // XXX: use sh2_drc_write32?
rcache_invalidate();
// push PC
rcache_get_reg_arg(0, SHR_SP);
EMITH_SJMP_START(DCOND_NE);
emith_jump_ctx_c(DCOND_EQ, offsetof(SH2, drc_tmp)); // return
EMITH_SJMP_END(DCOND_NE);
- // since PC is up to date, jump to it's block instead of returning
emith_call(sh2_drc_test_irq);
emith_jump_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_ret_to_ctx(offsetof(SH2, drc_tmp)); \
+ 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_jump_ctx(offsetof(SH2, drc_tmp)); \
+ 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; \
+ }
+
+ MAKE_READ_WRAPPER(sh2_drc_read8);
+ MAKE_READ_WRAPPER(sh2_drc_read16);
+ MAKE_READ_WRAPPER(sh2_drc_read32);
+ MAKE_WRITE_WRAPPER(sh2_drc_write8);
+ MAKE_WRITE_WRAPPER(sh2_drc_write8_slot);
+ MAKE_WRITE_WRAPPER(sh2_drc_write16);
+ MAKE_WRITE_WRAPPER(sh2_drc_write16_slot);
+ MAKE_WRITE_WRAPPER(sh2_drc_write32);
+#if (DRC_DEBUG & 2)
+ host_dasm_new_symbol(sh2_drc_read8);
+ host_dasm_new_symbol(sh2_drc_read16);
+ host_dasm_new_symbol(sh2_drc_read32);
+ host_dasm_new_symbol(sh2_drc_write32);
+#endif
+#endif
+
rcache_invalidate();
#if (DRC_DEBUG & 2)
host_dasm_new_symbol(sh2_drc_entry);