From: notaz Date: Wed, 12 Mar 2008 21:45:20 +0000 (+0000) Subject: svp compiler: working asm dispatcher X-Git-Tag: v1.85~548 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71bb1b7bd0186eb056609fec62a134dcaadbffdf;p=picodrive.git svp compiler: working asm dispatcher git-svn-id: file:///home/notaz/opt/svn/PicoDrive@383 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/Pico/carthw/svp/compiler.c b/Pico/carthw/svp/compiler.c index c6b5438b..63bc9ab6 100644 --- a/Pico/carthw/svp/compiler.c +++ b/Pico/carthw/svp/compiler.c @@ -2,14 +2,22 @@ #include "../../PicoInt.h" #include "compiler.h" -static unsigned int *block_table[0x5090/2]; -static unsigned int *block_table_iram[15][0x800/2]; -static unsigned int block_ref[0x5090/2]; -static unsigned int block_ref_iram[15][0x800/2]; -static unsigned int *tcache_ptr = NULL; +#define u32 unsigned int + +static u32 *block_table[0x5090/2]; +static u32 *block_table_iram[15][0x800/2]; +static u32 *tcache_ptr = NULL; static int nblocks = 0; -static int iram_context = 0; +static int n_in_ops = 0; + +extern ssp1601_t *ssp; + +#define rPC ssp->gr[SSP_PC].h +#define rPMC ssp->gr[SSP_PMC] + +#define SSP_FLAG_Z (1<<0xd) +#define SSP_FLAG_N (1<<0xf) #ifndef ARM #define DUMP_BLOCK 0x0c9a @@ -18,479 +26,21 @@ void regfile_load(void){} void regfile_store(void){} #endif -#define EMBED_INTERPRETER -#define ssp1601_reset ssp1601_reset_local -#define ssp1601_run ssp1601_run_local - -#define GET_PC() rPC -#define GET_PPC_OFFS() (GET_PC()*2 - 2) -#define SET_PC(d) { rPC = d; } /* must return to dispatcher after this */ -//#define GET_PC() (PC - (unsigned short *)svp->iram_rom) -//#define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2) -//#define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d - -#include "ssp16.c" #include "gen_arm.c" // ----------------------------------------------------- -// ld d, s -static void op00(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - PC = ((unsigned short *)(void *)&op) + 1; /* FIXME: needed for interpreter */ - if (op == 0) return; // nop - if (op == ((SSP_A<<4)|SSP_P)) { // A <- P - // not sure. MAME claims that only hi word is transfered. - read_P(); // update P - rA32 = rP.v; - } - else - { - tmpv = REG_READ(op & 0x0f); - REG_WRITE((op & 0xf0) >> 4, tmpv); - } -} - -// ld d, (ri) -static void op01(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); -} - -// ld (ri), s -static void op02(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv); -} - -// ldi d, imm -static void op04(unsigned int op, unsigned int imm) -{ - REG_WRITE((op & 0xf0) >> 4, imm); -} - -// ld d, ((ri)) -static void op05(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); -} - -// ldi (ri), imm -static void op06(unsigned int op, unsigned int imm) -{ - ptr1_write(op, imm); -} - -// ld adr, a -static void op07(unsigned int op, unsigned int imm) -{ - ssp->RAM[op & 0x1ff] = rA; -} - -// ld d, ri -static void op09(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv); -} - -// ld ri, s -static void op0a(unsigned int op, unsigned int imm) -{ - rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4); -} - -// ldi ri, simm (also op0d op0e op0f) -static void op0c(unsigned int op, unsigned int imm) -{ - rIJ[(op>>8)&7] = op; -} - -// call cond, addr -static void op24(unsigned int op, unsigned int imm) -{ - int cond = 0; - do { - COND_CHECK - if (cond) { int new_PC = imm; write_STACK(GET_PC()); SET_PC(new_PC); } - } - while (0); -} - -// ld d, (a) -static void op25(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ((unsigned short *)svp->iram_rom)[rA]; REG_WRITE((op & 0xf0) >> 4, tmpv); -} - -// bra cond, addr -static void op26(unsigned int op, unsigned int imm) +static int get_inc(int mode) { - do - { - int cond = 0; - COND_CHECK - if (cond) SET_PC(imm); + int inc = (mode >> 11) & 7; + if (inc != 0) { + if (inc != 7) inc--; + inc = 1 << inc; // 0 1 2 4 8 16 32 128 + if (mode & 0x8000) inc = -inc; // decrement mode } - while (0); -} - -// mod cond, op -static void op48(unsigned int op, unsigned int imm) -{ - do - { - int cond = 0; - COND_CHECK - if (cond) { - switch (op & 7) { - case 2: rA32 = (signed int)rA32 >> 1; break; // shr (arithmetic) - case 3: rA32 <<= 1; break; // shl - case 6: rA32 = -(signed int)rA32; break; // neg - case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; // abs - default: elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x", - op&7, GET_PPC_OFFS()); - } - UPD_ACC_ZN // ? - } - } - while(0); -} - -// mpys? -static void op1b(unsigned int op, unsigned int imm) -{ - read_P(); // update P - rA32 -= rP.v; // maybe only upper word? - UPD_ACC_ZN // there checking flags after this - rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?) - rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj -} - -// mpya (rj), (ri), b -static void op4b(unsigned int op, unsigned int imm) -{ - read_P(); // update P - rA32 += rP.v; // confirmed to be 32bit - UPD_ACC_ZN // ? - rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?) - rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj -} - -// mld (rj), (ri), b -static void op5b(unsigned int op, unsigned int imm) -{ - rA32 = 0; - rST &= 0x0fff; // ? - rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?) - rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj -} - -// OP a, s -static void op10(unsigned int op, unsigned int imm) -{ - do - { - unsigned int tmpv; - OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv); - } - while(0); -} - -static void op30(unsigned int op, unsigned int imm) -{ - do - { - unsigned int tmpv; - OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv); - } - while(0); -} - -static void op40(unsigned int op, unsigned int imm) -{ - do - { - unsigned int tmpv; - OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv); - } - while(0); -} - -static void op50(unsigned int op, unsigned int imm) -{ - do - { - unsigned int tmpv; - OP_CHECK32(OP_ANDA32); tmpv = REG_READ(op & 0x0f); OP_ANDA(tmpv); - } - while(0); -} - -static void op60(unsigned int op, unsigned int imm) -{ - do - { - unsigned int tmpv; - OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv); - } - while(0); -} - -static void op70(unsigned int op, unsigned int imm) -{ - do - { - unsigned int tmpv; - OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv); - } - while(0); -} - -// OP a, (ri) -static void op11(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr1_read(op); OP_SUBA(tmpv); -} - -static void op31(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr1_read(op); OP_CMPA(tmpv); -} - -static void op41(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr1_read(op); OP_ADDA(tmpv); -} - -static void op51(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr1_read(op); OP_ANDA(tmpv); -} - -static void op61(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr1_read(op); OP_ORA (tmpv); -} - -static void op71(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr1_read(op); OP_EORA(tmpv); -} - -// OP a, adr -static void op03(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ssp->RAM[op & 0x1ff]; OP_LDA (tmpv); -} - -static void op13(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ssp->RAM[op & 0x1ff]; OP_SUBA(tmpv); + return inc; } -static void op33(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ssp->RAM[op & 0x1ff]; OP_CMPA(tmpv); -} - -static void op43(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ssp->RAM[op & 0x1ff]; OP_ADDA(tmpv); -} - -static void op53(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ssp->RAM[op & 0x1ff]; OP_ANDA(tmpv); -} - -static void op63(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ssp->RAM[op & 0x1ff]; OP_ORA (tmpv); -} - -static void op73(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ssp->RAM[op & 0x1ff]; OP_EORA(tmpv); -} - -// OP a, imm -static void op14(unsigned int op, unsigned int imm) -{ - OP_SUBA(imm); -} - -static void op34(unsigned int op, unsigned int imm) -{ - OP_CMPA(imm); -} - -static void op44(unsigned int op, unsigned int imm) -{ - OP_ADDA(imm); -} - -static void op54(unsigned int op, unsigned int imm) -{ - OP_ANDA(imm); -} - -static void op64(unsigned int op, unsigned int imm) -{ - OP_ORA (imm); -} - -static void op74(unsigned int op, unsigned int imm) -{ - OP_EORA(imm); -} - -// OP a, ((ri)) -static void op15(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr2_read(op); OP_SUBA(tmpv); -} - -static void op35(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr2_read(op); OP_CMPA(tmpv); -} - -static void op45(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr2_read(op); OP_ADDA(tmpv); -} - -static void op55(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr2_read(op); OP_ANDA(tmpv); -} - -static void op65(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr2_read(op); OP_ORA (tmpv); -} - -static void op75(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = ptr2_read(op); OP_EORA(tmpv); -} - -// OP a, ri -static void op19(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = rIJ[IJind]; OP_SUBA(tmpv); -} - -static void op39(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = rIJ[IJind]; OP_CMPA(tmpv); -} - -static void op49(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = rIJ[IJind]; OP_ADDA(tmpv); -} - -static void op59(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = rIJ[IJind]; OP_ANDA(tmpv); -} - -static void op69(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = rIJ[IJind]; OP_ORA (tmpv); -} - -static void op79(unsigned int op, unsigned int imm) -{ - unsigned int tmpv; - tmpv = rIJ[IJind]; OP_EORA(tmpv); -} - -// OP simm -static void op1c(unsigned int op, unsigned int imm) -{ - OP_SUBA(op & 0xff); -} - -static void op3c(unsigned int op, unsigned int imm) -{ - OP_CMPA(op & 0xff); -} - -static void op4c(unsigned int op, unsigned int imm) -{ - OP_ADDA(op & 0xff); -} - -static void op5c(unsigned int op, unsigned int imm) -{ - OP_ANDA(op & 0xff); -} - -static void op6c(unsigned int op, unsigned int imm) -{ - OP_ORA (op & 0xff); -} - -static void op7c(unsigned int op, unsigned int imm) -{ - OP_EORA(op & 0xff); -} - -typedef void (in_func)(unsigned int op, unsigned int imm); - -static in_func *in_funcs[0x80] = -{ - op00, op01, op02, op03, op04, op05, op06, op07, - NULL, op09, op0a, NULL, op0c, op0c, op0c, op0c, - op10, op11, NULL, op13, op14, op15, NULL, NULL, - NULL, op19, NULL, op1b, op1c, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, op24, op25, op26, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - op30, op31, NULL, op33, op34, op35, NULL, NULL, - NULL, op39, NULL, NULL, op3c, NULL, NULL, NULL, - op40, op41, NULL, op43, op44, op45, NULL, NULL, - op48, op49, NULL, op4b, op4c, NULL, NULL, NULL, - op50, op51, NULL, op53, op54, op55, NULL, NULL, - NULL, op59, NULL, op5b, op5c, NULL, NULL, NULL, - op60, op61, NULL, op63, op64, op65, NULL, NULL, - NULL, op69, NULL, NULL, op6c, NULL, NULL, NULL, - op70, op71, NULL, op73, op74, op75, NULL, NULL, - NULL, op79, NULL, NULL, op7c, NULL, NULL, NULL, -}; - - static u32 ssp_pm_read(int reg) { u32 d = 0, mode; @@ -525,6 +75,14 @@ static u32 ssp_pm_read(int reg) return d; } +#define overwrite_write(dst, d) \ +{ \ + if (d & 0xf000) { dst &= ~0xf000; dst |= d & 0xf000; } \ + if (d & 0x0f00) { dst &= ~0x0f00; dst |= d & 0x0f00; } \ + if (d & 0x00f0) { dst &= ~0x00f0; dst |= d & 0x00f0; } \ + if (d & 0x000f) { dst &= ~0x000f; dst |= d & 0x000f; } \ +} + static void ssp_pm_write(u32 d, int reg) { unsigned short *dram; @@ -585,7 +143,7 @@ static unsigned char iram_context_map[] = 13,14, 0, 0, 0, 0, 0, 0 // 38 39 }; -static int get_iram_context(void) +int ssp_get_iram_context(void) { unsigned char *ir = (unsigned char *)svp->iram_rom; int val1, val = ir[0x083^1] + ir[0x4FA^1] + ir[0x5F7^1] + ir[0x47B^1]; @@ -1171,7 +729,7 @@ static void tr_PMX_to_r0(int reg) tr_flush_dirty_ST(); EOP_LDR_IMM(1,7,0x484); // ldr r1, [r7, #0x484] // emu_status EOP_TST_REG_SIMPLE(0,0); - EOP_C_DOP_IMM(A_COND_EQ,A_OP_ADD,0,11,11,22/2,1); // addeq r11, r11, #1024 + EOP_C_DOP_IMM(A_COND_EQ,A_OP_SUB,0,11,11,22/2,1); // subeq r11, r11, #1024 EOP_C_DOP_IMM(A_COND_EQ,A_OP_ORR,0, 1, 1,24/2,flag>>8); // orreq r1, r1, #SSP_WAIT_30FE08 EOP_STR_IMM(1,7,0x484); // str r1, [r7, #0x484] // emu_status } @@ -1542,6 +1100,7 @@ static int tr_detect_set_pm(unsigned int op, int *pc, int imm) known_regb |= KRREG_PMC; dirty_regb |= KRREG_PMC; known_regs.emu_status |= SSP_PMC_SET; + n_in_ops++; // check for possible reg programming tmpv = PROGRAM(*pc); @@ -1556,6 +1115,7 @@ static int tr_detect_set_pm(unsigned int op, int *pc, int imm) dirty_regb |= is_write ? (1 << (reg+25)) : (1 << (reg+20)); known_regs.emu_status &= ~SSP_PMC_SET; (*pc)++; + n_in_ops++; return 5; } @@ -1583,6 +1143,7 @@ static int tr_detect_pm0_block(unsigned int op, int *pc, int imm) known_regb |= 1 << SSP_ST; dirty_regb &= ~KRREG_ST; (*pc) += 3*2; + n_in_ops += 3; return 4*2; } @@ -1599,6 +1160,7 @@ static int tr_detect_rotate(unsigned int op, int *pc, int imm) EOP_ORR_REG_LSR(0, 0, 0, 16); tr_bank_write(0); (*pc) += 2; + n_in_ops += 2; return 3; } @@ -1796,6 +1358,7 @@ static int translate_op(unsigned int op, int *pc, int imm) tmpv = 1; // count while (PROGRAM(*pc) == op && (op & 7) != 6) { (*pc)++; tmpv++; + n_in_ops++; } if ((op&0xf0) != 0) // !always tr_make_dirty_ST(); @@ -1983,10 +1546,12 @@ static int translate_op(unsigned int op, int *pc, int imm) ret++; break; } + n_in_ops++; + return ret; } -static void *translate_block(int pc) +void *ssp_translate_block(int pc) { unsigned int op, op1, imm, ccount = 0; unsigned int *block_start; @@ -2014,32 +1579,8 @@ static void *translate_block(int pc) ret = translate_op(op, &pc, imm); if (ret <= 0) { - tr_flush_dirty_prs(); - tr_flush_dirty_ST(); - tr_flush_dirty_pmcrs(); - known_regs.emu_status = 0; - - emit_mov_const(A_COND_AL, 0, op); - - // need immediate? - if (imm != (u32)-1) - emit_mov_const(A_COND_AL, 1, imm); - - // dump PC - emit_pc_dump(pc); - - if (ret_prev > 0) emit_call(regfile_store); - emit_call(in_funcs[op1]); - emit_call(regfile_load); - - if (in_funcs[op1] == NULL) { - printf("NULL func! op=%08x (%02x)\n", op, op1); - exit(1); - } - ccount++; - hostreg_clear(); - dirty_regb |= KRREG_P; - known_regb = 0; + printf("NULL func! op=%08x (%02x)\n", op, op1); + exit(1); } else { @@ -2067,7 +1608,8 @@ static void *translate_block(int pc) // stats nblocks++; - printf("%i blocks, %i bytes\n", nblocks, (tcache_ptr - tcache)*4); + printf("%i blocks, %i bytes, k=%.3f\n", nblocks, (tcache_ptr - tcache)*4, + (double)(tcache_ptr - tcache) / (double)n_in_ops); #ifdef DUMP_BLOCK { @@ -2092,82 +1634,36 @@ int ssp1601_dyn_startup(void) memset(tcache, 0, TCACHE_SIZE); memset(block_table, 0, sizeof(block_table)); memset(block_table_iram, 0, sizeof(block_table_iram)); - memset(block_ref, 0, sizeof(block_ref)); - memset(block_ref_iram, 0, sizeof(block_ref_iram)); tcache_ptr = tcache; *tcache_ptr++ = 0xffffffff; #ifdef ARM // hle'd blocks block_table[0x400] = (void *) ssp_hle_800; + n_in_ops = 3; // # of hled ops #endif -// TODO: rm -{ -static unsigned short dummy = 0; -PC = &dummy; -} return 0; } void ssp1601_dyn_reset(ssp1601_t *ssp) { - int i, u, total = 0; - for (i = 0; i < 0x5090/2; i++) - total += block_ref[i]; - for (u = 1; u < 15; u++) - for (i = 0; i < 0x800/2; i++) - total += block_ref_iram[u][i]; - - printf("total: %i\n", total); - for (i = 0; i < 0x5090/2; i++) - if (block_ref[i]) - printf("%07i %2.3f%% __:%04x\n", block_ref[i], (double)block_ref[i] / (double)total * 100.0, i<<1); - for (u = 1; u < 15; u++) - for (i = 0; i < 0x800/2; i++) - if (block_ref_iram[u][i]) - printf("%07i %2.3f%% %02i:%04x\n", block_ref_iram[u][i], - (double)block_ref_iram[u][i] / (double)total * 100.0, u, i<<1); - - - ssp1601_reset_local(ssp); - ssp->drc.ptr_rom = (unsigned int) Pico.rom; - ssp->drc.ptr_iram_rom = (unsigned int) svp->iram_rom; - ssp->drc.ptr_dram = (unsigned int) svp->dram; - ssp->drc.iram_dirty = 0; + ssp1601_reset(ssp); + ssp->drc.iram_dirty = 1; + ssp->drc.iram_context = 0; + // must do this here because ssp is not available @ startup() + ssp->drc.ptr_rom = (u32) Pico.rom; + ssp->drc.ptr_iram_rom = (u32) svp->iram_rom; + ssp->drc.ptr_dram = (u32) svp->dram; + ssp->drc.ptr_btable = (u32) block_table; + ssp->drc.ptr_btable_iram = (u32) block_table_iram; } void ssp1601_dyn_run(int cycles) { if (ssp->emu_status & SSP_WAIT_MASK) return; -#ifdef DUMP_BLOCK - rPC = DUMP_BLOCK >> 1; -#endif - while (cycles > 0) - { - int (*trans_entry)(void); - if (rPC < 0x800/2) - { - if (ssp->drc.iram_dirty) { - iram_context = get_iram_context(); - ssp->drc.iram_dirty--; - } - if (block_table_iram[iram_context][rPC] == NULL) - block_table_iram[iram_context][rPC] = translate_block(rPC); - trans_entry = (void *) block_table_iram[iram_context][rPC]; - block_ref_iram[iram_context][rPC]++; - } - else - { - if (block_table[rPC] == NULL) - block_table[rPC] = translate_block(rPC); - trans_entry = (void *) block_table[rPC]; - block_ref[rPC]++; - } - - cycles -= trans_entry(); - } + ssp_drc_entry(cycles); } diff --git a/Pico/carthw/svp/compiler.h b/Pico/carthw/svp/compiler.h index 7550be8c..32db84bd 100644 --- a/Pico/carthw/svp/compiler.h +++ b/Pico/carthw/svp/compiler.h @@ -2,8 +2,10 @@ extern unsigned int tcache[]; -void regfile_load(void); -void regfile_store(void); +void ssp_regfile_load(void); +void ssp_regfile_store(void); +int ssp_drc_entry(int cycles); +void ssp_drc_next(void); void ssp_hle_800(void); diff --git a/Pico/carthw/svp/gen_arm.c b/Pico/carthw/svp/gen_arm.c index bbf28073..70b1a8df 100644 --- a/Pico/carthw/svp/gen_arm.c +++ b/Pico/carthw/svp/gen_arm.c @@ -197,19 +197,14 @@ static void emit_call(void *target) static void emit_block_prologue(void) { - // stack regs - EOP_STMFD_ST(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R14M); // stmfd r13!, {r4-r11,lr} - emit_call(regfile_load); - EOP_MOV_IMM(11, 0, 0); // mov r11, #0 + // nothing } -static void emit_block_epilogue(int icount) +static void emit_block_epilogue(int cycles) { - if (icount > 0xff) { printf("large icount: %i\n", icount); icount = 0xff; } - emit_call(regfile_store); - EOP_ADD_IMM(0,11,0,icount); // add r0, r11, #icount - EOP_LDMFD_ST(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R14M); // ldmfd r13!, {r4-r11,lr} - EOP_BX(14); // bx r14 + if (cycles > 0xff) { printf("large cycle count: %i\n", cycles); cycles = 0xff; } + EOP_SUB_IMM(11,11,0,cycles); // sub r11, r11, #cycles + emit_call(ssp_drc_next); } static void emit_pc_dump(int pc) diff --git a/Pico/carthw/svp/ssp16.c b/Pico/carthw/svp/ssp16.c index 99a496d8..feef99bb 100644 --- a/Pico/carthw/svp/ssp16.c +++ b/Pico/carthw/svp/ssp16.c @@ -214,11 +214,9 @@ #define IJind (((op>>6)&4)|(op&3)) -#ifndef EMBED_INTERPRETER #define GET_PC() (PC - (unsigned short *)svp->iram_rom) #define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2) #define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d -#endif #define REG_READ(r) (((r) <= 4) ? ssp->gr[r].h : read_handlers[r]()) #define REG_WRITE(r,d) { \ @@ -363,9 +361,6 @@ #define CHECK_ST(d) #endif -#ifndef EMBED_INTERPRETER -static -#endif ssp1601_t *ssp = NULL; static unsigned short *PC; static int g_cycles; @@ -526,9 +521,6 @@ static u32 pm_io(int reg, int write, u32 d) elprintf(EL_SVP, "ssp IRAM w [%06x] %04x (inc %i)", (addr<<1)&0x7ff, d, inc); ((unsigned short *)svp->iram_rom)[addr&0x3ff] = d; ssp->pmac_write[reg] += inc; -#ifdef EMBED_INTERPRETER - ssp->drc.iram_dirty = 1; -#endif } else { @@ -578,11 +570,9 @@ static u32 read_PM0(void) if (d != (u32)-1) return d; elprintf(EL_SVP, "PM0 raw r %04x @ %04x", rPM0, GET_PPC_OFFS()); d = rPM0; -#ifndef EMBED_INTERPRETER if (!(d & 2) && (GET_PPC_OFFS() == 0x800 || GET_PPC_OFFS() == 0x1851E)) { ssp->emu_status |= SSP_WAIT_PM0; elprintf(EL_SVP, "det TIGHT loop: PM0"); } -#endif rPM0 &= ~2; // ? return d; } @@ -659,14 +649,12 @@ static void write_XST(u32 d) static u32 read_PM4(void) { u32 d = pm_io(4, 0, 0); -#ifndef EMBED_INTERPRETER if (d == 0) { switch (GET_PPC_OFFS()) { case 0x0854: ssp->emu_status |= SSP_WAIT_30FE08; elprintf(EL_SVP, "det TIGHT loop: [30fe08]"); break; case 0x4f12: ssp->emu_status |= SSP_WAIT_30FE06; elprintf(EL_SVP, "det TIGHT loop: [30fe06]"); break; } } -#endif if (d != (u32)-1) return d; // can be removed? elprintf(EL_SVP|EL_ANOMALY, "PM4 raw r %04x @ %04x", rPM4, GET_PPC_OFFS()); @@ -913,7 +901,7 @@ static u32 ptr2_read(int op) // ----------------------------------------------------- -#if defined(USE_DEBUGGER) //|| defined(EMBED_INTERPRETER) +#if defined(USE_DEBUGGER) static void debug_dump2file(const char *fname, void *mem, int len) { FILE *f = fopen(fname, "wb"); @@ -1029,9 +1017,8 @@ void ssp1601_reset(ssp1601_t *l_ssp) void ssp1601_run(int cycles) { -#ifndef EMBED_INTERPRETER SET_PC(rPC); -#endif + g_cycles = cycles; while (g_cycles > 0 && !(ssp->emu_status & SSP_WAIT_MASK)) @@ -1050,7 +1037,6 @@ void ssp1601_run(int cycles) CHECK_B_SET(); if (op == 0) break; // nop if (op == ((SSP_A<<4)|SSP_P)) { // A <- P - // not sure. MAME claims that only hi word is transfered. read_P(); // update P rA32 = rP.v; } diff --git a/Pico/carthw/svp/ssp16.h b/Pico/carthw/svp/ssp16.h index f6c00770..fddb5ed7 100644 --- a/Pico/carthw/svp/ssp16.h +++ b/Pico/carthw/svp/ssp16.h @@ -57,6 +57,10 @@ typedef struct unsigned int ptr_iram_rom; // 48c unsigned int ptr_dram; // 490 unsigned int iram_dirty; // 494 + unsigned int iram_context; // 498 + unsigned int ptr_btable; // 49c + unsigned int ptr_btable_iram; // 4a0 + unsigned int tmp0; // 4a4 } drc; } ssp1601_t; diff --git a/Pico/carthw/svp/stub_arm.S b/Pico/carthw/svp/stub_arm.S index 531536c4..d2153885 100644 --- a/Pico/carthw/svp/stub_arm.S +++ b/Pico/carthw/svp/stub_arm.S @@ -7,8 +7,10 @@ .global tcache .global flush_inval_caches -.global regfile_load -.global regfile_store +.global ssp_regfile_load +.global ssp_regfile_store +.global ssp_drc_entry +.global ssp_drc_next .global ssp_hle_800 @ translation cache buffer @@ -46,7 +48,7 @@ flush_inval_caches: @ trashes r2,r3 -regfile_load: +ssp_regfile_load: ldr r7, =ssp ldr r7, [r7] add r2, r7, #0x400 @@ -71,7 +73,7 @@ regfile_load: bx lr -regfile_store: +ssp_regfile_store: str r10,[r7, #(0x400+7*4)] @ P str r8, [r7, #0x440] @ r0-r2 str r9, [r7, #0x444] @ r4-r6 @@ -94,34 +96,100 @@ regfile_store: bx lr -#define SSP_OFFS_GR 0x400 -#define SSP_OFFS_EMUST 0x484 -#define SSP_PM0 8 -#define SSP_PC 6 -#define SSP_WAIT_PM0 0x2000 +#define SSP_OFFS_GR 0x400 +#define SSP_PM0 8 +#define SSP_PC 6 +#define SSP_OFFS_EMUSTAT 0x484 // emu_status +#define SSP_OFFS_IRAM_DIRTY 0x494 +#define SSP_OFFS_IRAM_CTX 0x498 // iram_context +#define SSP_OFFS_BLTAB 0x49c // block_table +#define SSP_OFFS_BLTAB_IRAM 0x4a0 +#define SSP_OFFS_TMP0 0x4a4 +#define SSP_WAIT_PM0 0x2000 + + +ssp_drc_entry: + stmfd sp!, {r4-r11, lr} + mov r11, r0 + bl ssp_regfile_load + +ssp_drc_next: + cmp r11, #0 + bmi ssp_drc_end + + ldr r0, [r7, #(SSP_OFFS_GR+SSP_PC*4)] + mov r0, r0, lsr #16 + str r0, [r7, #SSP_OFFS_TMP0] + cmp r0, #0x400 + blt ssp_de_iram + + ldr r1, [r7, #SSP_OFFS_BLTAB] + ldr r1, [r1, r0, lsl #2] + tst r1, r1 + bxne r1 + bl ssp_translate_block + ldr r2, [r7, #SSP_OFFS_TMP0] @ entry PC + ldr r1, [r7, #SSP_OFFS_BLTAB] + str r0, [r1, r2, lsl #2] + bx r0 + +ssp_de_iram: + ldr r1, [r7, #SSP_OFFS_IRAM_DIRTY] + tst r1, r1 + ldreq r1, [r7, #SSP_OFFS_IRAM_CTX] + beq ssp_de_iram_ctx + + bl ssp_get_iram_context + mov r1, #0 + str r1, [r7, #SSP_OFFS_IRAM_DIRTY] + mov r1, r0 + str r1, [r7, #SSP_OFFS_IRAM_CTX] + ldr r0, [r7, #SSP_OFFS_TMP0] @ entry PC + +ssp_de_iram_ctx: + ldr r2, [r7, #SSP_OFFS_BLTAB_IRAM] + add r2, r2, r1, lsl #12 @ block_tab_iram + iram_context * 0x800/2*4 + add r2, r2, r0, lsl #2 + ldr r1, [r2] + tst r1, r1 + bxne r1 + str r2, [r7, #SSP_OFFS_TMP0] + bl ssp_translate_block + ldr r2, [r7, #SSP_OFFS_TMP0] @ &block_table_iram[iram_context][rPC] + str r0, [r2] + bx r0 + +ssp_drc_end: + bl ssp_regfile_store + mov r0, r11 + ldmfd sp!, {r4-r11, lr} + bx lr + + @ ld A, PM0 @ andi 2 @ bra z=1, gloc_0800 ssp_hle_800: @ block prologue - stmfd sp!, {r4-r11, lr} - bl regfile_load - mov r11, #0 +@ stmfd sp!, {r4-r11, lr} +@ bl regfile_load +@ mov r11, #0 ldr r0, [r7, #(SSP_OFFS_GR+SSP_PM0*4)] - ldr r1, [r7, #SSP_OFFS_EMUST] + ldr r1, [r7, #SSP_OFFS_EMUSTAT] tst r0, #0x20000 orreq r1, r1, #SSP_WAIT_PM0 addeq r11,r11, #1024 - streq r1, [r7, #SSP_OFFS_EMUST] + streq r1, [r7, #SSP_OFFS_EMUSTAT] movne r0, #0x04000000 orrne r0, r0, #0x00040000 strne r0, [r7, #(SSP_OFFS_GR+SSP_PC*4)] - bl regfile_store - add r0, r11, #3 - ldmfd sp!, {r4-r11, lr} - bx lr + bl ssp_drc_next +@ bl regfile_store +@ add r0, r11, #3 +@ ldmfd sp!, {r4-r11, lr} +@ bx lr