From: notaz Date: Thu, 12 Nov 2009 16:42:42 +0000 (+0000) Subject: 32x: drc: first implementation finished, no more interpreter dep X-Git-Tag: v1.85~218 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0d7b1faa17e6e0e21c04db2e1b46ae33a808e11;p=picodrive.git 32x: drc: first implementation finished, no more interpreter dep git-svn-id: file:///home/notaz/opt/svn/PicoDrive@832 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/cpu/drc/emit_arm.c b/cpu/drc/emit_arm.c index db6f86ae..135274a4 100644 --- a/cpu/drc/emit_arm.c +++ b/cpu/drc/emit_arm.c @@ -189,8 +189,11 @@ #define EOP_BX(rm) EOP_C_BX(A_COND_AL,rm) +#define EOP_C_B_PTR(ptr,cond,l,signed_immed_24) \ + EMIT_PTR(ptr, ((cond)<<28) | 0x0a000000 | ((l)<<24) | (signed_immed_24)) + #define EOP_C_B(cond,l,signed_immed_24) \ - EMIT(((cond)<<28) | 0x0a000000 | ((l)<<24) | (signed_immed_24)) + EOP_C_B_PTR(tcache_ptr,cond,l,signed_immed_24) #define EOP_B( signed_immed_24) EOP_C_B(A_COND_AL,0,signed_immed_24) #define EOP_BL(signed_immed_24) EOP_C_B(A_COND_AL,1,signed_immed_24) @@ -205,6 +208,9 @@ #define EOP_C_SMULL(cond,s,rdhi,rdlo,rs,rm) \ EMIT(((cond)<<28) | 0x00c00000 | ((s)<<20) | ((rdhi)<<16) | ((rdlo)<<12) | ((rs)<<8) | 0x90 | (rm)) +#define EOP_C_SMLAL(cond,s,rdhi,rdlo,rs,rm) \ + EMIT(((cond)<<28) | 0x00e00000 | ((s)<<20) | ((rdhi)<<16) | ((rdlo)<<12) | ((rs)<<8) | 0x90 | (rm)) + #define EOP_MUL(rd,rm,rs) EOP_C_MUL(A_COND_AL,0,rd,rs,rm) // note: rd != rm #define EOP_C_MRS(cond,rd) \ @@ -308,6 +314,15 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_eor_r_r_r_lsl(d, s1, s2, lslimm) \ EOP_EOR_REG(A_COND_AL,0,d,s1,s2,A_AM1_LSL,lslimm) +#define emith_eor_r_r_r_lsr(d, s1, s2, lsrimm) \ + EOP_EOR_REG(A_COND_AL,0,d,s1,s2,A_AM1_LSR,lsrimm) + +#define emith_or_r_r_lsl(d, s, lslimm) \ + emith_or_r_r_r_lsl(d, d, s, lslimm) + +#define emith_eor_r_r_lsr(d, s, lsrimm) \ + emith_eor_r_r_r_lsr(d, d, s, lsrimm) + #define emith_or_r_r_r(d, s1, s2) \ emith_or_r_r_r_lsl(d, s1, s2, 0) @@ -390,6 +405,9 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_or_r_imm_c(cond, r, imm) \ emith_op_imm(cond, 0, A_OP_ORR, r, imm) +#define emith_eor_r_imm_c(cond, r, imm) \ + emith_op_imm(cond, 0, A_OP_EOR, r, imm) + #define emith_bic_r_imm_c(cond, r, imm) \ emith_op_imm(cond, 0, A_OP_BIC, r, imm) @@ -459,6 +477,9 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_mul_s64(dlo, dhi, s1, s2) \ EOP_C_SMULL(A_COND_AL,0,dhi,dlo,s1,s2) +#define emith_mula_s64(dlo, dhi, s1, s2) \ + EOP_C_SMLAL(A_COND_AL,0,dhi,dlo,s1,s2) + // misc #define emith_ctx_read(r, offs) \ EOP_LDR_IMM(r, CONTEXT_REG, offs) @@ -466,27 +487,42 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_ctx_write(r, offs) \ EOP_STR_IMM(r, CONTEXT_REG, offs) -#define emith_clear_msb(d, s, count) { \ +#define emith_clear_msb_c(cond, d, s, count) { \ u32 t; \ if ((count) <= 8) { \ t = (count) - 8; \ t = (0xff << t) & 0xff; \ EOP_BIC_IMM(d,s,8/2,t); \ + EOP_C_DOP_IMM(cond,A_OP_BIC,0,s,d,8/2,t); \ } else if ((count) >= 24) { \ t = (count) - 24; \ t = 0xff >> t; \ EOP_AND_IMM(d,s,0,t); \ + EOP_C_DOP_IMM(cond,A_OP_AND,0,s,d,0,t); \ } else { \ - EOP_MOV_REG_LSL(d,s,count); \ - EOP_MOV_REG_LSR(d,d,count); \ + EOP_MOV_REG(cond,0,d,s,A_AM1_LSL,count); \ + EOP_MOV_REG(cond,0,d,d,A_AM1_LSR,count); \ } \ } +#define emith_clear_msb(d, s, count) \ + emith_clear_msb_c(A_COND_AL, d, s, count) + #define emith_sext(d, s, bits) { \ EOP_MOV_REG_LSL(d,s,32 - (bits)); \ EOP_MOV_REG_ASR(d,d,32 - (bits)); \ } +#define JMP_POS(ptr) \ + ptr = tcache_ptr; \ + tcache_ptr += sizeof(u32) + +#define JMP_EMIT(cond, ptr) { \ + int val = (u32 *)tcache_ptr - (u32 *)(ptr) - 2; \ + EOP_C_B_PTR(ptr, cond, 0, val & 0xffffff); \ +} + +// _r_r // put bit0 of r0 to carry #define emith_set_carry(r0) \ EOP_TST_REG(A_COND_AL,r0,r0,A_AM1_LSR,1) /* shift out to carry */ \ @@ -564,3 +600,24 @@ static int emith_xbranch(int cond, void *target, int is_call) emith_bic_r_imm_c(A_COND_CC, srr, 1); \ } \ } + +/* + * if Q + * t = carry(Rn += Rm) + * else + * t = carry(Rn -= Rm) + * T ^= t + */ +#define emith_sh2_div1_step(rn, rm, sr) { \ + void *jmp0, *jmp1; \ + emith_tst_r_imm(sr, Q); /* if (Q ^ M) */ \ + JMP_POS(jmp0); /* beq do_sub */ \ + emith_addf_r_r(rn, rm); \ + emith_eor_r_imm_c(A_COND_CS, sr, T); \ + JMP_POS(jmp1); /* b done */ \ + JMP_EMIT(A_COND_EQ, jmp0); /* do_sub: */ \ + emith_subf_r_r(rn, rm); \ + emith_eor_r_imm_c(A_COND_CC, sr, T); \ + JMP_EMIT(A_COND_AL, jmp1); /* done: */ \ +} + diff --git a/cpu/drc/emit_x86.c b/cpu/drc/emit_x86.c index 0ca61201..6ef8ede6 100644 --- a/cpu/drc/emit_x86.c +++ b/cpu/drc/emit_x86.c @@ -1,5 +1,5 @@ /* - * note about silly things like emith_or_r_r_r_lsl: + * note about silly things like emith_eor_r_r_r: * these are here because the compiler was designed * for ARM as it's primary target. */ @@ -9,6 +9,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define CONTEXT_REG xBP +#define IOP_JMP 0xeb #define IOP_JO 0x70 #define IOP_JNO 0x71 #define IOP_JB 0x72 @@ -56,6 +57,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define EMIT_MODRM(mod,r,rm) \ EMIT(((mod)<<6) | ((r)<<3) | (rm), u8) +#define EMIT_SIB(scale,index,base) \ + EMIT(((scale)<<6) | ((index)<<3) | (base), u8) + #define EMIT_OP_MODRM(op,mod,r,rm) { \ EMIT_OP(op); \ EMIT_MODRM(mod, r, rm); \ @@ -139,14 +143,22 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; } \ } -#define emith_or_r_r_r_lsl(d, s1, s2, lslimm) { \ +// _r_r_shift +#define emith_or_r_r_lsl(d, s, lslimm) { \ int tmp_ = rcache_get_tmp(); \ - emith_lsl(tmp_, s2, lslimm); \ - emith_or_r_r(tmp_, s1); \ - emith_move_r_r(d, tmp_); \ + emith_lsl(tmp_, s, lslimm); \ + emith_or_r_r(d, tmp_); \ rcache_free_tmp(tmp_); \ } +// d != s +#define emith_eor_r_r_lsr(d, s, lsrimm) { \ + emith_push(s); \ + emith_lsr(s, s, lsrimm); \ + emith_eor_r_r(d, s); \ + emith_pop(s); \ +} + // _r_imm #define emith_move_r_imm(r, imm) { \ EMIT_OP(0xb8 + (r)); \ @@ -200,6 +212,11 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; emith_or_r_imm(r, imm); \ } +#define emith_eor_r_imm_c(cond, r, imm) { \ + (void)(cond); \ + emith_eor_r_imm(r, imm); \ +} + #define emith_sub_r_imm_c(cond, r, imm) { \ (void)(cond); \ emith_sub_r_imm(r, imm); \ @@ -264,11 +281,22 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; emith_and_r_imm(d, t); \ } +#define emith_clear_msb_c(cond, d, s, count) { \ + (void)(cond); \ + emith_clear_msb(d, s, count); \ +} + #define emith_sext(d, s, bits) { \ emith_lsl(d, s, 32 - (bits)); \ emith_asr(d, d, 32 - (bits)); \ } +#define emith_setc(r) { \ + EMIT_OP(0x0f); \ + EMIT(0x92, u8); \ + EMIT_MODRM(3, 0, r); /* SETC r */ \ +} + // put bit0 of r0 to carry #define emith_set_carry(r0) { \ emith_tst_r_imm(r0, 1); /* clears C */ \ @@ -318,6 +346,19 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define emith_mul(d, s1, s2) \ emith_mul_(4, d, -1, s1, s2) +// (dlo,dhi) += signed(s1) * signed(s2) +#define emith_mula_s64(dlo, dhi, s1, s2) { \ + emith_push(dhi); \ + emith_push(dlo); \ + emith_mul_(5, dlo, dhi, s1, s2); \ + EMIT_OP_MODRM(0x03, 0, dlo, 4); \ + EMIT_SIB(0, 4, 4); /* add dlo, [esp] */ \ + EMIT_OP_MODRM(0x13, 1, dhi, 4); \ + EMIT_SIB(0, 4, 4); \ + EMIT(4, u8); /* adc dhi, [esp+4] */ \ + emith_add_r_imm(xSP, 4*2); \ +} + // "flag" instructions are the same #define emith_subf_r_imm emith_sub_r_imm #define emith_addf_r_r emith_add_r_r @@ -357,6 +398,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; EMIT(disp, u32); \ } +#define emith_call_cond(cond, ptr) \ + emith_call(ptr) + // "simple" or "short" jump #define EMITH_SJMP_START(cond) { \ u8 *cond_ptr; \ @@ -429,11 +473,31 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define emith_carry_to_t(srr, is_sub) { \ int tmp_ = rcache_get_tmp(); \ - EMIT_OP(0x0f); \ - EMIT(0x92, u8); \ - EMIT_MODRM(3, 0, tmp_); /* SETC */ \ + emith_setc(tmp_); \ emith_bic_r_imm(srr, 1); \ EMIT_OP_MODRM(0x08, 3, tmp_, srr); /* OR srrl, tmpl */ \ rcache_free_tmp(tmp_); \ } +/* + * if Q + * t = carry(Rn += Rm) + * else + * t = carry(Rn -= Rm) + * T ^= t + */ +#define emith_sh2_div1_step(rn, rm, sr) { \ + u8 *jmp0, *jmp1; \ + int tmp_ = rcache_get_tmp(); \ + emith_tst_r_imm(sr, Q); /* if (Q ^ M) */ \ + JMP8_POS(jmp0); /* je do_sub */ \ + emith_add_r_r(rn, rm); \ + JMP8_POS(jmp1); /* jmp done */ \ + JMP8_EMIT(IOP_JE, jmp0); /* do_sub: */ \ + emith_sub_r_r(rn, rm); \ + JMP8_EMIT(IOP_JMP, jmp1);/* done: */ \ + emith_setc(tmp_); \ + EMIT_OP_MODRM(0x30, 3, tmp_, sr); /* T = Q1 ^ Q2 (byte) */ \ + rcache_free_tmp(tmp_); \ +} + diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 1f142dd3..02add396 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -1,6 +1,7 @@ /* * vim:shiftwidth=2:expandtab */ +#include #include #include #include @@ -125,6 +126,9 @@ static temp_reg_t reg_temp[] = { #define Q 0x00000100 #define M 0x00000200 +#define Q_SHIFT 8 +#define M_SHIFT 9 + typedef enum { SHR_R0 = 0, SHR_SP = 15, SHR_PC, SHR_PPC, SHR_PR, SHR_SR, @@ -517,6 +521,58 @@ static void emit_indirect_indexed_write(int rx, int ry, int wr, int size) emit_memhandler_write(size); } +// read @Rn, @rm +static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size) +{ + int tmp; + + rcache_clean(); + rcache_get_reg_arg(0, rn); + tmp = emit_memhandler_read(size); + emith_ctx_write(tmp, offsetof(SH2, drc_tmp)); + rcache_free_tmp(tmp); + tmp = rcache_get_reg(rn, RC_GR_RMW); + emith_add_r_imm(tmp, 1 << size); + + rcache_clean(); + rcache_get_reg_arg(0, rm); + *rmr = emit_memhandler_read(size); + *rnr = rcache_get_tmp(); + emith_ctx_read(*rnr, offsetof(SH2, drc_tmp)); + tmp = rcache_get_reg(rm, RC_GR_RMW); + emith_add_r_imm(tmp, 1 << size); +} + +// fixup for saturated MAC, to be called from generated code +// FIXME: statically alloced regs need to be fixed +static void sh2_macl_sat_fixup(void) +{ + if ((signed int)sh2->mach < 0 && sh2->mach < 0xffff8000) + { + sh2->mach = 0x00008000; + sh2->macl = 0x00000000; + } + else if ((signed int)sh2->mach > 0 && sh2->mach > 0x00007fff) + { + sh2->mach = 0x00007fff; + sh2->macl = 0xffffffff; + } +} + +static void sh2_macw_sat_fixup(void) +{ + signed int t = sh2->mach; + if (t < -1 || (t == -1 && !(sh2->macl & 0x80000000))) + { + sh2->mach = 0xffffffff; // ? + sh2->macl = 0x80000000; + } + else if (t > 0 || (t == 0 && (sh2->macl & 0x80000000))) + { + sh2->mach = 0x7fffffff; + sh2->macl = 0xffffffff; + } +} #define DELAYED_OP \ delayed_op = 2 @@ -546,7 +602,7 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) int op, delayed_op = 0, test_irq = 0; int tcache_id = 0, blkid = 0; int cycles = 0; - u32 tmp, tmp2, tmp3, tmp4; + u32 tmp, tmp2, tmp3, tmp4, sr; // validate PC tmp = sh2->pc >> 29; @@ -771,8 +827,27 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) rcache_free_tmp(tmp); goto end_op; case 0x0f: // MAC.L @Rm+,@Rn+ 0000nnnnmmmm1111 - // TODO - break; + emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2); + tmp3 = rcache_get_reg(SHR_SR, RC_GR_READ); + tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW); + /* MS 16 MAC bits unused if saturated */ + emith_tst_r_imm(tmp3, S); + EMITH_SJMP_START(DCOND_EQ); + emith_clear_msb_c(DCOND_NE, tmp4, tmp4, 16); + EMITH_SJMP_END(DCOND_EQ); + tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); // might evict SR + emith_mula_s64(tmp3, tmp4, tmp, tmp2); + rcache_free_tmp(tmp); + rcache_free_tmp(tmp2); + rcache_clean(); + tmp3 = rcache_get_reg(SHR_SR, RC_GR_READ); + emith_tst_r_imm(tmp3, S); + EMITH_SJMP_START(DCOND_EQ); + emith_call_cond(DCOND_NE, sh2_macl_sat_fixup); + EMITH_SJMP_END(DCOND_EQ); + rcache_invalidate(); + cycles += 3; + goto end_op; } goto default_; @@ -869,7 +944,7 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW); tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ); emith_lsr(tmp, tmp, 16); - emith_or_r_r_r_lsl(tmp, tmp, tmp2, 16); + emith_or_r_r_lsl(tmp, tmp2, 16); goto end_op; case 0x0e: // MULU.W Rm,Rn 0010nnnnmmmm1110 case 0x0f: // MULS.W Rm,Rn 0010nnnnmmmm1111 @@ -935,8 +1010,37 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) } goto end_op; case 0x04: // DIV1 Rm,Rn 0011nnnnmmmm0100 - // TODO - break; + // Q1 = carry(Rn = (Rn << 1) | T) + // if Q ^ M + // Q2 = carry(Rn += Rm) + // else + // Q2 = carry(Rn -= Rm) + // Q = M ^ Q1 ^ Q2 + // T = (Q == M) = !(Q ^ M) = !(Q1 ^ Q2) + tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW); + tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ); + sr = rcache_get_reg(SHR_SR, RC_GR_RMW); + emith_set_carry(sr); + emith_adcf_r_r(tmp2, tmp2); + emith_carry_to_t(sr, 0); // keep Q1 in T for now + tmp4 = rcache_get_tmp(); + emith_and_r_r_imm(tmp4, sr, M); + emith_eor_r_r_lsr(sr, tmp4, M_SHIFT - Q_SHIFT); // Q ^= M + rcache_free_tmp(tmp4); + // add or sub, invert T if carry to get Q1 ^ Q2 + // in: (Q ^ M) passed in Q, Q1 in T + emith_sh2_div1_step(tmp2, tmp3, sr); + emith_bic_r_imm(sr, Q); + emith_tst_r_imm(sr, M); + EMITH_SJMP_START(DCOND_EQ); + emith_or_r_imm_c(DCOND_NE, sr, Q); // Q = M + EMITH_SJMP_END(DCOND_EQ); + emith_tst_r_imm(sr, T); + EMITH_SJMP_START(DCOND_EQ); + emith_eor_r_imm_c(DCOND_NE, sr, Q); // Q = M ^ Q1 ^ Q2 + EMITH_SJMP_END(DCOND_EQ); + emith_eor_r_imm(sr, T); // T = !(Q1 ^ Q2) + goto end_op; case 0x05: // DMULU.L Rm,Rn 0011nnnnmmmm0101 tmp = rcache_get_reg(GET_Rn(), RC_GR_READ); tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ); @@ -1248,7 +1352,6 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) } if (tmp2 == SHR_SR) { emith_write_sr(tmp); - emit_move_r_imm32(SHR_PC, pc); test_irq = 1; } else { tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE); @@ -1257,7 +1360,24 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) goto end_op; case 0x0f: // MAC @Rm+,@Rn+ 0100nnnnmmmm1111 - break; // TODO + emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1); + emith_sext(tmp, tmp, 16); + emith_sext(tmp2, tmp2, 16); + tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); + tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW); + emith_mula_s64(tmp3, tmp4, tmp, tmp2); + rcache_free_tmp(tmp); + rcache_free_tmp(tmp2); + rcache_clean(); + // XXX: MACH should be untouched when S is set? + tmp3 = rcache_get_reg(SHR_SR, RC_GR_READ); + emith_tst_r_imm(tmp3, S); + EMITH_SJMP_START(DCOND_EQ); + emith_call_cond(DCOND_NE, sh2_macw_sat_fixup); + EMITH_SJMP_END(DCOND_EQ); + rcache_invalidate(); + cycles += 2; + goto end_op; } goto default_; @@ -1315,9 +1435,9 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) tmp3 = rcache_get_tmp(); tmp4 = rcache_get_tmp(); emith_lsr(tmp3, tmp, 16); - emith_or_r_r_r_lsl(tmp3, tmp3, tmp, 24); + emith_or_r_r_lsl(tmp3, tmp, 24); emith_and_r_r_imm(tmp4, tmp, 0xff00); - emith_or_r_r_r_lsl(tmp3, tmp3, tmp4, 8); + emith_or_r_r_lsl(tmp3, tmp4, 8); emith_rol(tmp2, tmp3, 16); rcache_free_tmp(tmp4); if (tmp == tmp2) @@ -1429,8 +1549,14 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) ///////////////////////////////////////////// case 0x09: // MOV.W @(disp,PC),Rn 1001nnnndddddddd - // TODO - goto default_; + rcache_clean(); + tmp = rcache_get_tmp_arg(0); + emith_move_r_imm(tmp, pc + (op & 0xff) * 2 + 2); + tmp = emit_memhandler_read(1); + tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE); + emith_sext(tmp2, tmp, 16); + rcache_free_tmp(tmp); + goto end_op; ///////////////////////////////////////////// case 0x0a: @@ -1557,8 +1683,14 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) ///////////////////////////////////////////// case 0x0d: // MOV.L @(disp,PC),Rn 1101nnnndddddddd - // TODO - goto default_; + rcache_clean(); + tmp = rcache_get_tmp_arg(0); + emith_move_r_imm(tmp, (pc + (op & 0xff) * 4 + 2) & ~3); + tmp = emit_memhandler_read(2); + tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE); + emith_move_r_r(tmp2, tmp); + rcache_free_tmp(tmp); + goto end_op; ///////////////////////////////////////////// case 0x0e: @@ -1569,11 +1701,15 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) default: default_: + elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x", + sh2->is_slave ? 's' : 'm', op, pc - 2); +#ifdef DRC_DEBUG_INTERP emit_move_r_imm32(SHR_PC, pc - 2); rcache_flush(); emith_pass_arg_r(0, CONTEXT_REG); emith_pass_arg_imm(1, op); emith_call(sh2_do_op); +#endif break; } @@ -1582,10 +1718,12 @@ end_op: emit_move_r_r(SHR_PC, SHR_PPC); if (test_irq && delayed_op != 2) { + if (!delayed_op) + emit_move_r_imm32(SHR_PC, pc); rcache_flush(); emith_pass_arg_r(0, CONTEXT_REG); emith_call(sh2_test_irq); - break; + goto end_block_btf; } if (delayed_op == 1) break; diff --git a/cpu/sh2/mame/sh2.c b/cpu/sh2/mame/sh2.c index 8e84f7eb..7beead30 100644 --- a/cpu/sh2/mame/sh2.c +++ b/cpu/sh2/mame/sh2.c @@ -116,7 +116,7 @@ #define LOG(x) do { if (VERBOSE) logerror x; } while (0) //int sh2_icount; -SH2 *sh2; +//SH2 *sh2; #if 0 INLINE UINT8 RB(offs_t A) diff --git a/cpu/sh2/mame/sh2pico.c b/cpu/sh2/mame/sh2pico.c index 57b7d9c5..9fdbe66e 100644 --- a/cpu/sh2/mame/sh2pico.c +++ b/cpu/sh2/mame/sh2pico.c @@ -33,7 +33,7 @@ typedef unsigned char UINT8; #include "sh2.c" -#ifndef DRC_TMP +#ifndef DRC_SH2 void sh2_execute(SH2 *sh2_, int cycles) { @@ -48,6 +48,7 @@ void sh2_execute(SH2 *sh2_, int cycles) { UINT32 opcode; + /* FIXME: Darxide doesn't like this */ if (sh2->test_irq && !sh2->delay && sh2->pending_level > ((sh2->sr >> 4) & 0x0f)) { if (sh2->pending_irl > sh2->pending_int_irq) @@ -102,7 +103,7 @@ void sh2_execute(SH2 *sh2_, int cycles) sh2->cycles_done += cycles - sh2->icount; } -#else // DRC_TMP +#else // DRC_SH2 #ifdef __i386__ #define REGPARM(x) __attribute__((regparm(x))) @@ -110,7 +111,7 @@ void sh2_execute(SH2 *sh2_, int cycles) #define REGPARM(x) #endif -// tmp +// drc debug void REGPARM(2) sh2_do_op(SH2 *sh2_, int opcode) { sh2 = sh2_; diff --git a/cpu/sh2/sh2.c b/cpu/sh2/sh2.c index cd07bef8..d8d82ed2 100644 --- a/cpu/sh2/sh2.c +++ b/cpu/sh2/sh2.c @@ -4,6 +4,8 @@ #define I 0xf0 +SH2 *sh2; // active sh2 + int sh2_init(SH2 *sh2, int is_slave) { int ret = 0; diff --git a/cpu/sh2/sh2.h b/cpu/sh2/sh2.h index 264bb4e8..8e9f3b05 100644 --- a/cpu/sh2/sh2.h +++ b/cpu/sh2/sh2.h @@ -11,20 +11,20 @@ typedef struct unsigned int gbr, vbr; // 50 unsigned int mach, macl; // 58 - // interpreter stuff - int icount; // 60 cycles left in current timeslice - unsigned int ea; - unsigned int delay; - unsigned int test_irq; - // common - const void *read8_map; // 70 + const void *read8_map; // 60 const void *read16_map; const void **write8_tab; const void **write16_tab; // drc stuff - //void **pc_hashtab; // 80 + int drc_tmp; // 70 + + // interpreter stuff + int icount; // cycles left in current timeslice + unsigned int ea; + unsigned int delay; + unsigned int test_irq; int pending_level; // MAX(pending_irl, pending_int_irq) int pending_irl; @@ -37,7 +37,7 @@ typedef struct unsigned int cycles_done; } SH2; -extern SH2 *sh2; // active sh2 +extern SH2 *sh2; // active sh2. XXX: consider removing int sh2_init(SH2 *sh2, int is_slave); void sh2_finish(SH2 *sh2); diff --git a/platform/common/common.mak b/platform/common/common.mak new file mode 100644 index 00000000..edc8aae5 --- /dev/null +++ b/platform/common/common.mak @@ -0,0 +1,78 @@ +# === CPU cores === +# --- M68k --- +ifeq "$(use_musashi)" "1" +DEFINES += EMU_M68K +OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o +#OBJS += cpu/musashi/m68kdasm.o +endif +ifeq "$(use_cyclone)" "1" +DEFINES += EMU_C68K +OBJS += pico/m68kif_cyclone.o cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o +endif +ifeq "$(use_fame)" "1" +DEFINES += EMU_F68K +OBJS += cpu/fame/famec.o +endif + +# --- Z80 --- +ifeq "$(use_mz80)" "1" +DEFINES += _USE_MZ80 +OBJS += cpu/mz80/mz80.o +endif +# +ifeq "$(use_drz80)" "1" +DEFINES += _USE_DRZ80 +OBJS += cpu/DrZ80/drz80.o +endif +# +ifeq "$(use_cz80)" "1" +DEFINES += _USE_CZ80 +OBJS += cpu/cz80/cz80.o +endif + +# --- SH2 --- +OBJS += cpu/sh2/sh2.o +OBJS += cpu/drc/cmn.o +# +ifeq "$(use_sh2drc)" "1" +DEFINES += DRC_SH2 +OBJS += cpu/sh2/compiler.o +OBJS += cpu/sh2/stub_$(ARCH).o +ifdef drc_debug +DEFINES += DRC_DEBUG=$(drc_debug) +OBJS += cpu/sh2/mame/sh2dasm.o +OBJS += platform/linux/host_dasm.o +LDFLAGS += -lbfd -lopcodes -liberty +endif +ifeq "$(drc_debug_interp)" "1" +DEFINES += DRC_DEBUG_INTERP +use_sh2mame = 1 +endif +endif +# +ifeq "$(use_sh2mame)" "1" +OBJS += cpu/sh2/mame/sh2pico.o +endif + + +# random deps +pico/carthw/svp/compiler.o : ../../cpu/drc/emit_$(ARCH).c +cpu/sh2/compiler.o : ../../cpu/drc/emit_$(ARCH).c +cpu/sh2/mame/sh2pico.o : ../../cpu/sh2/mame/sh2.c +pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h +pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h + +../../cpu/musashi/m68kops.c : + @make -C ../../cpu/musashi + +../../cpu/mz80/mz80.asm : + @make -C ../../cpu/mz80/ + +cpu/fame/famec.o : ../../cpu/fame/famec.c ../../cpu/fame/famec_opcodes.h + @echo ">>>" $< + $(CC) $(CFLAGS) -Wno-unused -c $< -o $@ + +../../cpu/Cyclone/proj/Cyclone.s: + @echo building Cyclone... + @make -C ../../cpu/Cyclone/proj CONFIG_FILE=config_pico.h + diff --git a/platform/common/common_arm.mak b/platform/common/common_arm.mak index 6f8eb9ae..11270a3d 100644 --- a/platform/common/common_arm.mak +++ b/platform/common/common_arm.mak @@ -45,20 +45,6 @@ clean_prof: mkdirs: mkdir -p $(DIRS) -# some deps -pico/carthw/svp/compiler.o : ../../pico/carthw/svp/ssp16.o ../../cpu/drc/emit_arm.c -cpu/sh2/compiler.o : ../../cpu/drc/emit_arm.c -pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h -pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h - -# build Cyclone -../../cpu/Cyclone/proj/Cyclone.s: - @echo building Cyclone... - @make -C ../../cpu/Cyclone/proj CONFIG_FILE=config_pico.h - -../../cpu/musashi/m68kops.c : - @make -C ../../cpu/musashi - # build helix libs ../common/helix/$(CROSS)helix-mp3.a: make -C ../common/helix clean all diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index 934be244..cdfea379 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -1,8 +1,12 @@ -export CROSS = arm-linux- +CROSS ?= arm-linux- # settings -#mz80 = 1 -#debug_cyclone = 1 +use_cyclone = 1 +#use_musashi = 1 +use_drz80 = 1 +use_sh2drc = 1 +#use_sh2mame = 1 + asm_memory = 1 asm_render = 1 asm_ym2612 = 1 @@ -11,8 +15,6 @@ asm_cdpico = 1 asm_cdmemory = 1 amalgamate = 0 #profile = 1 -#use_musashi = 1 -use_sh2drc = 1 #drc_debug = 3 -include Makefile.local @@ -25,10 +27,9 @@ ifeq "$(use_musashi)" "1" # due to CPU stop flag acces asm_cdpico = 0 asm_cdmemory = 0 -else -use_cyclone = 1 endif +ARCH = arm DEFINES += ARM __GP2X__ IN_GP2X IN_EVDEV # BENCHMARK CFLAGS += -Wall -Winline -I../.. -I. ifeq ($(DEBUG),) @@ -94,42 +95,6 @@ OBJS += unzip/unzip.o unzip/unzip_stream.o # zlib OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \ zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o -# debug -ifeq "$(debug_cyclone)" "1" -OBJS += pico/DebugCPU.o cpu/musashi/m68kdasm.o -endif -# CPU cores -ifeq "$(use_musashi)" "1" -DEFINES += EMU_M68K -OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o -endif -ifeq "$(use_cyclone)" "1" -DEFINES += EMU_C68K -OBJS += pico/m68kif_cyclone.o cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o -endif -ifeq "$(mz80)" "1" -DEFINES += _USE_MZ80 -OBJS += cpu/mz80/mz80.o -else -DEFINES += _USE_DRZ80 -OBJS += cpu/DrZ80/drz80.o -endif -OBJS += cpu/sh2/sh2.o -ifeq "$(use_sh2drc)" "1" -DEFINES += DRC_SH2 DRC_TMP -OBJS += cpu/sh2/mame/sh2pico.o -OBJS += cpu/sh2/compiler.o -OBJS += cpu/sh2/stub_arm.o -ifdef drc_debug -DEFINES += DRC_DEBUG=$(drc_debug) -OBJS += cpu/sh2/mame/sh2dasm.o -OBJS += platform/linux/host_dasm.o -LDFLAGS += -lbfd -lopcodes -liberty -endif -else -OBJS += cpu/sh2/mame/sh2pico.o -endif -OBJS += cpu/drc/cmn.o CFLAGS += $(addprefix -D,$(DEFINES)) @@ -144,6 +109,7 @@ DIRS = platform platform/gp2x platform/linux platform/common pico pico/cd pico/p all: mkdirs PicoDrive +include ../common/common.mak include ../common/common_arm.mak include ../common/revision.mak diff --git a/platform/linux/Makefile b/platform/linux/Makefile index 3638286a..6c28e41a 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -1,9 +1,12 @@ # settings use_musashi = 1 #use_fame = 1 -#use_mz80 = 1 +use_cz80 = 1 use_sh2drc = 1 +#use_sh2mame = 1 + #drc_debug = 3 +#drc_debug_interp = 1 #profile = 1 #fake_in_gp2x = 1 @@ -70,47 +73,6 @@ OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \ zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o zlib/uncompr.o # unzip OBJS += unzip/unzip.o unzip/unzip_stream.o -# CPU cores -ifeq "$(use_musashi)" "1" -DEFINES += EMU_M68K -OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o -#OBJS += cpu/musashi/m68kdasm.o -endif -ifeq "$(use_fame)" "1" -DEFINES += EMU_F68K -OBJS += cpu/fame/famec.o -endif -# z80 -ifeq "$(use_mz80)" "1" -DEFINES += _USE_MZ80 -OBJS += cpu/mz80/mz80.o -else -DEFINES += _USE_CZ80 -OBJS += cpu/cz80/cz80.o -endif -# sh2 -OBJS += cpu/sh2/sh2.o -ifeq "$(use_sh2drc)" "1" -DEFINES += DRC_SH2 DRC_TMP -OBJS += cpu/sh2/mame/sh2pico.o -OBJS += cpu/sh2/compiler.o -OBJS += cpu/sh2/stub_$(ARCH).o -ifdef drc_debug -DEFINES += DRC_DEBUG=$(drc_debug) -OBJS += cpu/sh2/mame/sh2dasm.o -OBJS += host_dasm.o -LDFLAGS += -lbfd -lopcodes -liberty -endif -else -OBJS += cpu/sh2/mame/sh2pico.o -endif -OBJS += cpu/drc/cmn.o -# misc -ifeq "$(use_fame)" "1" -ifeq "$(use_musashi)" "1" -OBJS += pico/debugCPU.o -endif -endif CFLAGS += $(addprefix -D,$(DEFINES)) @@ -119,10 +81,13 @@ vpath %.s = ../.. vpath %.S = ../.. vpath %.asm = ../.. -DIRS = platform platform/gp2x platform/common pico pico/cd pico/pico pico/sound pico/carthw/svp \ +DIRS = platform/linux platform/gp2x platform/common pico pico/cd pico/pico pico/sound pico/carthw/svp \ pico/32x zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80 cpu/sh2/mame cpu/drc all: mkdirs PicoDrive + +include ../common/common.mak + clean: tidy @$(RM) PicoDrive tidy: @@ -139,22 +104,6 @@ mkdirs: include ../common/revision.mak -pico/carthw/svp/compiler.o : ../../cpu/drc/emit_arm.c -cpu/sh2/compiler.o : ../../cpu/drc/emit_x86.c -cpu/sh2/mame/sh2pico.o : ../../cpu/sh2/mame/sh2.c -pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h -pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h - -../../cpu/musashi/m68kops.c : - @make -C ../../cpu/musashi - -cpu/mz80/mz80.o : ../../cpu/mz80/mz80.asm - @echo $@ - @nasm -f elf $< -o $@ - -../../cpu/mz80/mz80.asm : - @make -C ../../cpu/mz80/ - .c.o: @echo ">>>" $< $(CC) $(CFLAGS) -c $< -o $@ @@ -165,8 +114,3 @@ cpu/mz80/mz80.o : ../../cpu/mz80/mz80.asm @echo ">>>" $< nasm -f elf $< -o $@ - -cpu/fame/famec.o : ../../cpu/fame/famec.c ../../cpu/fame/famec_opcodes.h - @echo ">>>" $< - $(CC) $(CFLAGS) -Wno-unused -c $< -o $@ -