From: notaz Date: Mon, 7 Dec 2009 15:30:52 +0000 (+0000) Subject: 32x: drc: enable and fix static reg alloc, carry flag tweaks X-Git-Tag: v1.85~213 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=picodrive.git;a=commitdiff_plain;h=8b4f38f4c6977ff80fff0ec92228914fe930e534 32x: drc: enable and fix static reg alloc, carry flag tweaks git-svn-id: file:///home/notaz/opt/svn/PicoDrive@838 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/cpu/drc/emit_arm.c b/cpu/drc/emit_arm.c index f651dd5..5195483 100644 --- a/cpu/drc/emit_arm.c +++ b/cpu/drc/emit_arm.c @@ -3,7 +3,7 @@ // (c) Copyright 2008-2009, Grazvydas "notaz" Ignotas // Free for non-commercial use. -#define CONTEXT_REG 7 +#define CONTEXT_REG 11 // XXX: tcache_ptr type for SVP and SH2 compilers differs.. #define EMIT_PTR(ptr, x) \ @@ -182,8 +182,11 @@ #define EOP_XXM(cond,p,u,s,w,l,rn,list) \ EMIT(((cond)<<28) | (1<<27) | ((p)<<24) | ((u)<<23) | ((s)<<22) | ((w)<<21) | ((l)<<20) | ((rn)<<16) | (list)) -#define EOP_STMFD(rb,list) EOP_XXM(A_COND_AL,1,0,0,1,0,rb,list) -#define EOP_LDMFD(rb,list) EOP_XXM(A_COND_AL,0,1,0,1,1,rb,list) +#define EOP_STMIA(rb,list) EOP_XXM(A_COND_AL,0,1,0,0,0,rb,list) +#define EOP_LDMIA(rb,list) EOP_XXM(A_COND_AL,0,1,0,0,1,rb,list) + +#define EOP_STMFD_SP(list) EOP_XXM(A_COND_AL,1,0,0,1,0,13,list) +#define EOP_LDMFD_SP(list) EOP_XXM(A_COND_AL,0,1,0,1,1,13,list) /* branches */ #define EOP_C_BX(cond,rm) \ @@ -357,6 +360,9 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_sub_r_r(d, s) \ EOP_SUB_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0) +#define emith_adc_r_r(d, s) \ + EOP_ADC_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0) + #define emith_and_r_r(d, s) \ EOP_AND_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0) @@ -521,25 +527,26 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_ctx_read(r, offs) \ EOP_LDR_IMM(r, CONTEXT_REG, offs) -#define emith_ctx_read_multiple(r, offs, count, tmpr) do { \ - int v_, r_ = r, c_ = count; \ - for (v_ = 0; c_; c_--, r_++) \ - v_ |= 1 << r_; \ - EOP_ADD_IMM(tmpr,CONTEXT_REG,30/2,(offs)>>2); \ - EOP_LDMFD(tmpr,v_); \ -} while(0) - #define emith_ctx_write(r, offs) \ EOP_STR_IMM(r, CONTEXT_REG, offs) -#define emith_ctx_write_multiple(r, offs, count, tmpr) do { \ - int v_, r_ = r, c_ = count; \ - for (v_ = 0; c_; c_--, r_++) \ - v_ |= 1 << r_; \ - EOP_ADD_IMM(tmpr,CONTEXT_REG,30/2,(offs)>>2); \ - EOP_STMFD(tmpr,v_); \ +#define emith_ctx_do_multiple(op, r, offs, count, tmpr) do { \ + int v_, r_ = r, c_ = count, b_ = CONTEXT_REG; \ + for (v_ = 0; c_; c_--, r_++) \ + v_ |= 1 << r_; \ + if ((offs) != 0) { \ + EOP_ADD_IMM(tmpr,CONTEXT_REG,30/2,(offs)>>2);\ + b_ = tmpr; \ + } \ + op(b_,v_); \ } while(0) +#define emith_ctx_read_multiple(r, offs, count, tmpr) \ + emith_ctx_do_multiple(EOP_LDMIA, r, offs, count, tmpr) + +#define emith_ctx_write_multiple(r, offs, count, tmpr) \ + emith_ctx_do_multiple(EOP_STMIA, r, offs, count, tmpr) + #define emith_clear_msb_c(cond, d, s, count) { \ u32 t; \ if ((count) <= 8) { \ @@ -566,19 +573,6 @@ static int emith_xbranch(int cond, void *target, int is_call) EOP_MOV_REG_ASR(d,d,32 - (bits)); \ } -// _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 */ \ - -// put bit0 of r0 to carry (for subtraction, inverted on ARM) -#define emith_set_carry_sub(r0) { \ - int t = rcache_get_tmp(); \ - EOP_EOR_IMM(t,r0,0,1); /* invert */ \ - EOP_MOV_REG(A_COND_AL,1,t,t,A_AM1_LSR,1); /* shift out to carry */ \ - rcache_free_tmp(t); \ -} - #define host_arg2reg(rd, arg) \ rd = arg @@ -606,10 +600,10 @@ static int emith_xbranch(int cond, void *target, int is_call) /* SH2 drc specific */ #define emith_sh2_drc_entry() \ - EOP_STMFD(13,A_R7M|A_R14M) + EOP_STMFD_SP(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R14M) #define emith_sh2_drc_exit() \ - EOP_LDMFD(13,A_R7M|A_R15M) + EOP_LDMFD_SP(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R15M) #define emith_sh2_test_t() { \ int r = rcache_get_reg(SHR_SR, RC_GR_READ); \ @@ -654,6 +648,18 @@ static int emith_xbranch(int cond, void *target, int is_call) } \ } +#define emith_tpop_carry(sr, is_sub) { \ + if (is_sub) \ + emith_eor_r_imm(sr, 1); \ + emith_lsrf(sr, sr, 1); \ +} + +#define emith_tpush_carry(sr, is_sub) { \ + emith_adc_r_r(sr, sr); \ + if (is_sub) \ + emith_eor_r_imm(sr, 1); \ +} + /* * if Q * t = carry(Rn += Rm) diff --git a/cpu/drc/emit_x86.c b/cpu/drc/emit_x86.c index 7f314f0..8f28612 100644 --- a/cpu/drc/emit_x86.c +++ b/cpu/drc/emit_x86.c @@ -1,7 +1,9 @@ /* + * note: + * temp registers must be eax-edx due to use of SETcc. * 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. + * these are here because the compiler was designed + * for ARM as it's primary target. */ #include @@ -298,21 +300,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define emith_setc(r) { \ EMIT_OP(0x0f); \ - EMIT(0x92, u8); \ - EMIT_MODRM(3, 0, r); /* SETC r */ \ + EMIT_OP_MODRM(0x92, 3, 0, r); /* SETC r */ \ } -// put bit0 of r0 to carry -#define emith_set_carry(r0) { \ - emith_tst_r_imm(r0, 1); /* clears C */ \ - EMITH_SJMP_START(DCOND_EQ); \ - EMIT_OP(0xf9); /* STC */ \ - EMITH_SJMP_END(DCOND_EQ); \ -} - -// put bit0 of r0 to carry (for subtraction) -#define emith_set_carry_sub emith_set_carry - // XXX: stupid mess #define emith_mul_(op, dlo, dhi, s1, s2) { \ int rmr; \ @@ -389,7 +379,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define emith_ctx_read_multiple(r, offs, cnt, tmpr) do { \ int r_ = r, offs_ = offs, cnt_ = cnt; \ - for (; cnt > 0; r_++, offs_ += 4, cnt_--) \ + for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \ emith_ctx_read(r_, offs_); \ } while (0) @@ -400,7 +390,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define emith_ctx_write_multiple(r, offs, cnt, tmpr) do { \ int r_ = r, offs_ = offs, cnt_ = cnt; \ - for (; cnt > 0; r_++, offs_ += 4, cnt_--) \ + for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \ emith_ctx_write(r_, offs_); \ } while (0) @@ -457,9 +447,13 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define emith_sh2_drc_entry() { \ emith_push(xBX); \ emith_push(xBP); \ + emith_push(xSI); \ + emith_push(xDI); \ } #define emith_sh2_drc_exit() { \ + emith_pop(xDI); \ + emith_pop(xSI); \ emith_pop(xBP); \ emith_pop(xBX); \ EMIT_OP(0xc3); /* ret */\ @@ -467,8 +461,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define emith_sh2_test_t() { \ int t = rcache_get_reg(SHR_SR, RC_GR_READ); \ - EMIT_OP_MODRM(0xf6, 3, 0, t); \ - EMIT(0x01, u8); /* test , byte 1 */ \ + EMIT(0x66, u8); \ + EMIT_OP_MODRM(0xf7, 3, 0, t); \ + EMIT(0x01, u16); /* test , word 1 */ \ } #define emith_sh2_dtbf_loop() { \ @@ -506,13 +501,11 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; rcache_free_tmp(tmp_); \ } -#define emith_carry_to_t(srr, is_sub) { \ - int tmp_ = rcache_get_tmp(); \ - emith_setc(tmp_); \ - emith_bic_r_imm(srr, 1); \ - EMIT_OP_MODRM(0x08, 3, tmp_, srr); /* OR srrl, tmpl */ \ - rcache_free_tmp(tmp_); \ -} +#define emith_tpop_carry(sr, is_sub) \ + emith_lsr(sr, sr, 1) + +#define emith_tpush_carry(sr, is_sub) \ + emith_adc_r_r(sr, sr) /* * if Q @@ -524,6 +517,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; #define emith_sh2_div1_step(rn, rm, sr) { \ u8 *jmp0, *jmp1; \ int tmp_ = rcache_get_tmp(); \ + emith_eor_r_r(tmp_, tmp_); \ emith_tst_r_imm(sr, Q); /* if (Q ^ M) */ \ JMP8_POS(jmp0); /* je do_sub */ \ emith_add_r_r(rn, rm); \ @@ -532,7 +526,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; 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) */ \ + EMIT_OP_MODRM(0x31, 3, tmp_, sr); /* T = Q1 ^ Q2 */ \ rcache_free_tmp(tmp_); \ } diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 19fb1a9..fc48413 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -84,11 +84,11 @@ typedef struct { #include "../drc/emit_arm.c" static const int reg_map_g2h[] = { + 4, 5, 6, 7, + 8, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, + -1, -1, -1, 9, + -1, -1, -1, 10, -1, -1, -1, -1, }; @@ -105,11 +105,11 @@ static temp_reg_t reg_temp[] = { #include "../drc/emit_x86.c" static const int reg_map_g2h[] = { + xSI,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, + -1, -1, -1, xDI, -1, -1, -1, -1, }; @@ -1051,9 +1051,9 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) 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_tpop_carry(sr, 0); emith_adcf_r_r(tmp2, tmp2); - emith_carry_to_t(sr, 0); // keep Q1 in T for now + emith_tpush_carry(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 @@ -1094,13 +1094,13 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ); sr = rcache_get_reg(SHR_SR, RC_GR_RMW); if (op & 4) { // adc - emith_set_carry(sr); + emith_tpop_carry(sr, 0); emith_adcf_r_r(tmp, tmp2); - emith_carry_to_t(sr, 0); + emith_tpush_carry(sr, 0); } else { - emith_set_carry_sub(sr); + emith_tpop_carry(sr, 1); emith_sbcf_r_r(tmp, tmp2); - emith_carry_to_t(sr, 1); + emith_tpush_carry(sr, 1); } goto end_op; case 0x0b: // SUBV Rm,Rn 0011nnnnmmmm1011 @@ -1138,8 +1138,9 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) case 2: // SHAL Rn 0100nnnn00100000 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW); sr = rcache_get_reg(SHR_SR, RC_GR_RMW); + emith_tpop_carry(sr, 0); // dummy emith_lslf(tmp, tmp, 1); - emith_carry_to_t(sr, 0); + emith_tpush_carry(sr, 0); goto end_op; case 1: // DT Rn 0100nnnn00010000 if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2 @@ -1161,11 +1162,12 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) case 2: // SHAR Rn 0100nnnn00100001 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW); sr = rcache_get_reg(SHR_SR, RC_GR_RMW); + emith_tpop_carry(sr, 0); // dummy if (op & 0x20) { emith_asrf(tmp, tmp, 1); } else emith_lsrf(tmp, tmp, 1); - emith_carry_to_t(sr, 0); + emith_tpush_carry(sr, 0); goto end_op; case 1: // CMP/PZ Rn 0100nnnn00010001 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW); @@ -1220,22 +1222,23 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) case 0x05: // ROTR Rn 0100nnnn00000101 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW); sr = rcache_get_reg(SHR_SR, RC_GR_RMW); + emith_tpop_carry(sr, 0); // dummy if (op & 1) { emith_rorf(tmp, tmp, 1); } else emith_rolf(tmp, tmp, 1); - emith_carry_to_t(sr, 0); + emith_tpush_carry(sr, 0); goto end_op; case 0x24: // ROTCL Rn 0100nnnn00100100 case 0x25: // ROTCR Rn 0100nnnn00100101 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW); sr = rcache_get_reg(SHR_SR, RC_GR_RMW); - emith_set_carry(sr); + emith_tpop_carry(sr, 0); if (op & 1) { emith_rorcf(tmp); } else emith_rolcf(tmp); - emith_carry_to_t(sr, 0); + emith_tpush_carry(sr, 0); goto end_op; case 0x15: // CMP/PL Rn 0100nnnn00010101 tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW); @@ -1487,9 +1490,9 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block) break; case 0x0a: // NEGC Rm,Rn 0110nnnnmmmm1010 sr = rcache_get_reg(SHR_SR, RC_GR_RMW); - emith_set_carry_sub(sr); + emith_tpop_carry(sr, 1); emith_negcf_r_r(tmp2, tmp); - emith_carry_to_t(sr, 1); + emith_tpush_carry(sr, 1); break; case 0x0b: // NEG Rm,Rn 0110nnnnmmmm1011 emith_neg_r_r(tmp2, tmp); @@ -2019,6 +2022,9 @@ int sh2_drc_init(SH2 *sh2) tcache_ptr = tcache; sh2_generate_utils(); +#ifdef ARM + cache_flush_d_inval_i(tcache, tcache_ptr); +#endif memset(block_counts, 0, sizeof(block_counts)); tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;