X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fnew_dynarec.c;h=1fe2c0c4114c8f4ff1077623c022e15376c74cbf;hp=edd141311b42347f6346e4e663807aaf591629c5;hb=2adcd6fad4594a18025b4f00c49e43a23f8f8992;hpb=af4ee1fe7361ac0c958e3df25958c94ecee2710b diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index edd14131..1fe2c0c4 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -126,6 +126,7 @@ struct ll_entry #else static const u_int using_tlb=0; #endif + static u_int sp_in_mirror; u_int stop_after_jal; extern u_char restore_candidate[512]; extern int cycle_count; @@ -1186,6 +1187,9 @@ void invalidate_block(u_int block) // Don't trap writes invalid_code[block]=1; +#ifdef PCSX + invalid_code[((u_int)0x80000000>>12)|page]=1; +#endif #ifndef DISABLE_TLB // If there is a valid TLB entry for this page, remove write protect if(tlb_LUT_w[block]) { @@ -2823,6 +2827,13 @@ void load_assemble(int i,struct regstat *i_regs) if(rs1[i]!=29||start<0x80001000||start>=0x80000000+RAM_SIZE) #endif { + #ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) { + emit_andimm(addr,~0x00e00000,HOST_TEMPREG); + emit_cmpimm(HOST_TEMPREG,RAM_SIZE); + } + else + #endif emit_cmpimm(addr,RAM_SIZE); jaddr=(int)out; #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK @@ -2862,6 +2873,9 @@ void load_assemble(int i,struct regstat *i_regs) else x=((constmap[i][s]+offset)^3)-(constmap[i][s]+offset); #else if(!c) a=addr; +#endif +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; #endif emit_movsbl_indexed_tlb(x,a,map,tl); } @@ -2887,6 +2901,9 @@ void load_assemble(int i,struct regstat *i_regs) else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset); #else if(!c) a=addr; +#endif +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; #endif //#ifdef //emit_movswl_indexed_tlb(x,tl,map,tl); @@ -2912,13 +2929,17 @@ void load_assemble(int i,struct regstat *i_regs) if (opcode[i]==0x23) { // LW if(!c||memtarget) { if(!dummy) { + int a=addr; +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; +#endif //emit_readword_indexed((int)rdram-0x80000000,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readword_tlb(constmap[i][s]+offset,map,tl); else #endif - emit_readword_indexed_tlb(0,addr,map,tl); + emit_readword_indexed_tlb(0,a,map,tl); } if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); @@ -2944,6 +2965,9 @@ void load_assemble(int i,struct regstat *i_regs) else x=((constmap[i][s]+offset)^3)-(constmap[i][s]+offset); #else if(!c) a=addr; +#endif +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; #endif emit_movzbl_indexed_tlb(x,a,map,tl); } @@ -2969,6 +2993,9 @@ void load_assemble(int i,struct regstat *i_regs) else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset); #else if(!c) a=addr; +#endif +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; #endif //#ifdef //emit_movzwl_indexed_tlb(x,tl,map,tl); @@ -2995,13 +3022,17 @@ void load_assemble(int i,struct regstat *i_regs) assert(th>=0); if(!c||memtarget) { if(!dummy) { + int a=addr; +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; +#endif //emit_readword_indexed((int)rdram-0x80000000,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readword_tlb(constmap[i][s]+offset,map,tl); else #endif - emit_readword_indexed_tlb(0,addr,map,tl); + emit_readword_indexed_tlb(0,a,map,tl); } if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); @@ -3014,6 +3045,10 @@ void load_assemble(int i,struct regstat *i_regs) if (opcode[i]==0x37) { // LD if(!c||memtarget) { if(!dummy) { + int a=addr; +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; +#endif //gen_tlb_addr_r(tl,map); //if(th>=0) emit_readword_indexed((int)rdram-0x80000000,addr,th); //emit_readword_indexed((int)rdram-0x7FFFFFFC,addr,tl); @@ -3022,7 +3057,7 @@ void load_assemble(int i,struct regstat *i_regs) emit_readdword_tlb(constmap[i][s]+offset,map,th,tl); else #endif - emit_readdword_indexed_tlb(0,addr,map,th,tl); + emit_readdword_indexed_tlb(0,a,map,th,tl); } if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); @@ -3102,9 +3137,15 @@ void store_assemble(int i,struct regstat *i_regs) else addr=s; if(!using_tlb) { if(!c) { + #ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) { + emit_andimm(addr,~0x00e00000,HOST_TEMPREG); + emit_cmpimm(HOST_TEMPREG,RAM_SIZE); + } + else + #endif #ifdef R29_HACK // Strmnnrmn's speed hack - memtarget=1; if(rs1[i]!=29||start<0x80001000||start>=0x80000000+RAM_SIZE) #endif emit_cmpimm(addr,RAM_SIZE); @@ -3112,6 +3153,7 @@ void store_assemble(int i,struct regstat *i_regs) if(s==addr) emit_mov(s,temp); #endif #ifdef R29_HACK + memtarget=1; if(rs1[i]!=29||start<0x80001000||start>=0x80000000+RAM_SIZE) #endif { @@ -3143,6 +3185,9 @@ void store_assemble(int i,struct regstat *i_regs) else x=((constmap[i][s]+offset)^3)-(constmap[i][s]+offset); #else if(!c) a=addr; +#endif +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; #endif //gen_tlb_addr_w(temp,map); //emit_writebyte_indexed(tl,(int)rdram-0x80000000,temp); @@ -3158,6 +3203,9 @@ void store_assemble(int i,struct regstat *i_regs) else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset); #else if(!c) a=addr; +#endif +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; #endif //#ifdef //emit_writehword_indexed_tlb(tl,x,temp,map,temp); @@ -3171,23 +3219,32 @@ void store_assemble(int i,struct regstat *i_regs) type=STOREH_STUB; } if (opcode[i]==0x2B) { // SW - if(!c||memtarget) + if(!c||memtarget) { + int a=addr; +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; +#endif //emit_writeword_indexed(tl,(int)rdram-0x80000000,addr); - emit_writeword_indexed_tlb(tl,0,addr,map,temp); + emit_writeword_indexed_tlb(tl,0,a,map,temp); + } type=STOREW_STUB; } if (opcode[i]==0x3F) { // SD if(!c||memtarget) { + int a=addr; +#ifdef PCSX + if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; +#endif if(rs2[i]) { assert(th>=0); //emit_writeword_indexed(th,(int)rdram-0x80000000,addr); //emit_writeword_indexed(tl,(int)rdram-0x7FFFFFFC,addr); - emit_writedword_indexed_tlb(th,tl,0,addr,map,temp); + emit_writedword_indexed_tlb(th,tl,0,a,map,temp); }else{ // Store zero //emit_writeword_indexed(tl,(int)rdram-0x80000000,temp); //emit_writeword_indexed(tl,(int)rdram-0x7FFFFFFC,temp); - emit_writedword_indexed_tlb(tl,tl,0,addr,map,temp); + emit_writedword_indexed_tlb(tl,tl,0,a,map,temp); } } type=STORED_STUB; @@ -5108,34 +5165,19 @@ void ujump_assemble(int i,struct regstat *i_regs) if(i_regmap[temp]==PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); } #endif - ds_assemble(i+1,i_regs); - uint64_t bc_unneeded=branch_regs[i].u; - uint64_t bc_unneeded_upper=branch_regs[i].uu; - bc_unneeded|=1|(1LL<=0); return_address=start+i*4+8; if(rt>=0) { #ifdef USE_MINI_HT - if(internal_branch(branch_regs[i].is32,return_address)) { - int temp=rt+1; - if(temp==EXCLUDE_REG||temp>=HOST_REGS|| - branch_regs[i].regmap[temp]>=0) - { - temp=get_reg(branch_regs[i].regmap,-1); - } + if(internal_branch(branch_regs[i].is32,return_address)&&rt1[i+1]!=31) { + int temp=-1; // note: must be ds-safe #ifdef HOST_TEMPREG - if(temp<0) temp=HOST_TEMPREG; + temp=HOST_TEMPREG; #endif if(temp>=0) do_miniht_insert(return_address,rt,temp); else emit_movimm(return_address,rt); @@ -5156,6 +5198,14 @@ void ujump_assemble(int i,struct regstat *i_regs) } } } + ds_assemble(i+1,i_regs); + uint64_t bc_unneeded=branch_regs[i].u; + uint64_t bc_unneeded_upper=branch_regs[i].uu; + bc_unneeded|=1|(1LL<0x80200000&& + 0x10000<=psxRegs.GPR.n.sp&&(psxRegs.GPR.n.sp&~0xe0e00000)>26; - opcode2[i+1]=source[i+1]&0x3f; - if((0>14); else ba[i]=-1; - /* Is this the end of the block? */ - if(i>0&&(itype[i-1]==UJUMP||itype[i-1]==RJUMP||(source[i-1]>>16)==0x1000)) { #ifdef PCSX - // check for link register access in delay slot - int rt1_=rt1[i-1]; - if(rt1_!=0&&(rs1[i]==rt1_||rs2[i]==rt1_||rt1[i]==rt1_||rt2[i]==rt1_)) { - printf("link access in delay slot @%08x (%08x)\n", addr + i*4, addr); + if(i>0&&(itype[i-1]==RJUMP||itype[i-1]==UJUMP||itype[i-1]==CJUMP||itype[i-1]==SJUMP||itype[i-1]==FJUMP)) { + int do_in_intrp=0; + // branch in delay slot? + if(type==RJUMP||type==UJUMP||type==CJUMP||type==SJUMP||type==FJUMP) { + // don't handle first branch and call interpreter if it's hit + printf("branch in delay slot @%08x (%08x)\n", addr + i*4, addr); + do_in_intrp=1; + } + // basic load delay detection + else if((type==LOAD||type==LOADLR||type==COP0||type==COP2||type==C2LS)&&rt1[i]!=0) { + int t=(ba[i-1]-start)/4; + if(0 <= t && t < i &&(rt1[i]==rs1[t]||rt1[i]==rs2[t])&&itype[t]!=CJUMP&&itype[t]!=SJUMP) { + // jump target wants DS result - potential load delay effect + printf("load delay @%08x (%08x)\n", addr + i*4, addr); + do_in_intrp=1; + bt[t+1]=1; // expected return from interpreter + } + else if(i>=2&&rt1[i-2]==2&&rt1[i]==2&&rs1[i]!=2&&rs2[i]!=2&&rs1[i-1]!=2&&rs2[i-1]!=2&& + !(i>=3&&(itype[i-3]==RJUMP||itype[i-3]==UJUMP||itype[i-3]==CJUMP||itype[i-3]==SJUMP))) { + // v0 overwrite like this is a sign of trouble, bail out + printf("v0 overwrite @%08x (%08x)\n", addr + i*4, addr); + do_in_intrp=1; + } + } + if(do_in_intrp) { + rs1[i-1]=CCREG; + rs2[i-1]=rt1[i-1]=rt2[i-1]=0; ba[i-1]=-1; itype[i-1]=INTCALL; done=2; + i--; // don't compile the DS } - else + } #endif + /* Is this the end of the block? */ + if(i>0&&(itype[i-1]==UJUMP||itype[i-1]==RJUMP||(source[i-1]>>16)==0x1000)) { if(rt1[i-1]==0) { // Continue past subroutine call (JAL) done=2; } @@ -8818,18 +8886,18 @@ int new_recompile_block(int addr) clear_const(¤t,rt1[i]); alloc_cc(¤t,i); dirty_reg(¤t,CCREG); + ooo[i]=1; + delayslot_alloc(¤t,i+1); if (rt1[i]==31) { alloc_reg(¤t,i,31); dirty_reg(¤t,31); - assert(rs1[i+1]!=31&&rs2[i+1]!=31); - assert(rt1[i+1]!=rt1[i]); + //assert(rs1[i+1]!=31&&rs2[i+1]!=31); + //assert(rt1[i+1]!=rt1[i]); #ifdef REG_PREFETCH alloc_reg(¤t,i,PTEMP); #endif //current.is32|=1LL<>12)) + for(i=start>>12;i<=(start+slen*4)>>12;i++) + invalid_code[((u_int)0x80000000>>12)|i]=0; +#endif /* Pass 10 - Free memory by expiring oldest blocks */