UIQ3 bugfixes, SVP drc indirect jumps, stuff

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@572 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-08-24 09:33:12 +00:00
parent 02ba8788a0
commit f8af96349e
29 changed files with 193 additions and 157 deletions

View file

@ -1663,7 +1663,7 @@ static void emit_block_prologue(void)
// check if there are enough cycles..
// note: r0 must contain PC of current block
EOP_CMP_IMM(11,0,0); // cmp r11, #0
emit_call(A_COND_LE, ssp_drc_end);
emit_jump(A_COND_LE, ssp_drc_end);
}
/* cond:
@ -1684,20 +1684,29 @@ static void emit_block_epilogue(int cycles, int cond, int pc, int end_pc)
if (target != NULL)
emit_jump(A_COND_AL, target);
else {
emit_jump(A_COND_AL, ssp_drc_next);
// cause the next block to be emitted over jump instrction
tcache_ptr--;
int ops = emit_jump(A_COND_AL, ssp_drc_next);
// cause the next block to be emitted over jump instruction
tcache_ptr -= ops;
}
}
else {
u32 *target1 = (pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][pc] : ssp_block_table[pc];
u32 *target1 = (pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][pc] : ssp_block_table[pc];
u32 *target2 = (end_pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][end_pc] : ssp_block_table[end_pc];
if (target1 != NULL)
emit_jump(cond, target1);
else emit_call(cond, ssp_drc_next_patch);
if (target2 != NULL)
emit_jump(tr_neg_cond(cond), target2); // neg_cond, to be able to swap jumps if needed
else emit_call(tr_neg_cond(cond), ssp_drc_next_patch);
#ifndef __EPOC32__
// emit patchable branches
if (target1 == NULL)
emit_call(cond, ssp_drc_next_patch);
if (target2 == NULL)
emit_call(tr_neg_cond(cond), ssp_drc_next_patch);
#else
// won't patch indirect jumps
if (target1 == NULL || target2 == NULL)
emit_jump(A_COND_AL, ssp_drc_next);
#endif
}
}
@ -1708,6 +1717,7 @@ void *ssp_translate_block(int pc)
int ret, end_cond = A_COND_AL, jump_pc = -1;
//printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
block_start = tcache_ptr;
known_regb = 0;
dirty_regb = KRREG_P;
@ -1748,7 +1758,7 @@ void *ssp_translate_block(int pc)
emit_block_epilogue(ccount, end_cond, jump_pc, pc);
if (tcache_ptr - tcache > SSP_TCACHE_SIZE/4) {
elprintf(EL_ANOMALY, "tcache overflow!\n");
elprintf(EL_ANOMALY|EL_STATUS|EL_SVP, "tcache overflow!\n");
fflush(stdout);
exit(1);
}
@ -1825,6 +1835,7 @@ void ssp1601_dyn_reset(ssp1601_t *ssp)
memset(svp->iram_rom, 0, 0x800);
}
void ssp1601_dyn_run(int cycles)
{
if (ssp->emu_status & SSP_WAIT_MASK) return;

View file

@ -178,27 +178,49 @@ static void emit_mov_const(int cond, int d, unsigned int val)
EOP_C_DOP_IMM(cond, need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 0, val&0xff);
}
static void check_offset_24(int val)
static int is_offset_24(int val)
{
if (val >= (int)0xff000000 && val <= 0x00ffffff) return;
printf("offset_24 overflow %08x\n", val);
exit(1);
if (val >= (int)0xff000000 && val <= 0x00ffffff) return 1;
return 0;
}
static void emit_call(int cond, void *target)
static int emit_xbranch(int cond, void *target, int is_call)
{
int val = (unsigned int *)target - tcache_ptr - 2;
check_offset_24(val);
int direct = is_offset_24(val);
u32 *start_ptr = tcache_ptr;
EOP_C_B(cond,1,val & 0xffffff); // bl target
if (direct)
{
EOP_C_B(cond,is_call,val & 0xffffff); // b, bl target
}
else
{
#ifdef __EPOC32__
// elprintf(EL_SVP, "emitting indirect jmp %08x->%08x", tcache_ptr, target);
if (is_call)
EOP_ADD_IMM(14,15,0,8); // add lr,pc,#8
EOP_C_AM2_IMM(cond,1,0,1,15,15,0); // ldrcc pc,[pc]
EOP_MOV_REG_SIMPLE(15,15); // mov pc, pc
EMIT((u32)target);
#else
// should never happen
elprintf(EL_STATUS|EL_SVP|EL_ANOMALY, "indirect jmp %08x->%08x", target, tcache_ptr);
exit(1);
#endif
}
return tcache_ptr - start_ptr;
}
static void emit_jump(int cond, void *target)
static int emit_call(int cond, void *target)
{
int val = (unsigned int *)target - tcache_ptr - 2;
check_offset_24(val);
return emit_xbranch(cond, target, 1);
}
EOP_C_B(cond,0,val & 0xffffff); // b target
static int emit_jump(int cond, void *target)
{
return emit_xbranch(cond, target, 0);
}
static void handle_caches(void)

View file

@ -40,7 +40,6 @@ ssp_block_table_iram:
.space SSP_BLOCKTAB_IRAM_SIZE
.space SSP_BLOCKTAB_ALIGN_SIZE
.text
.align 2
@ -59,6 +58,7 @@ ssp_block_table_iram:
@ r9: r4-r6 (.654)
@ r10: P
@ r11: cycles
@ r12: tmp
#define SSP_OFFS_GR 0x400
@ -207,7 +207,7 @@ ssp_drc_do_patch:
bic r3, r3, #1 @ L bit
orr r3, r3, r12,lsl #6
mov r3, r3, ror #8 @ patched branch instruction
str r3, [r1, #-4]
str r3, [r1, #-4] @ patch the bl/b to jump directly to another handler
ssp_drc_dp_end:
str r2, [r7, #SSP_OFFS_TMP1]