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=8ab31282b01d057deab180351877e488329fe071;hp=74b64b77b197297ba3a5f84b37c3d07c6bc86b36;hb=9be4ba6483d8d4bbd87fd12ade5c5cc7f9e3f116;hpb=d61de97e8764980c0a98d777653396fad745fff4 diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 74b64b77..8ab31282 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -371,6 +371,7 @@ void *get_addr(u_int vaddr) if(verify_dirty(head->addr)) { //printf("restore candidate: %x (%d) d=%d\n",vaddr,page,invalid_code[vaddr>>12]); invalid_code[vaddr>>12]=0; + inv_code_start=inv_code_end=~0; memory_map[vaddr>>12]|=0x40000000; if(vpage<2048) { #ifndef DISABLE_TLB @@ -463,6 +464,7 @@ void *get_addr_32(u_int vaddr,u_int flags) if(verify_dirty(head->addr)) { //printf("restore candidate: %x (%d) d=%d\n",vaddr,page,invalid_code[vaddr>>12]); invalid_code[vaddr>>12]=0; + inv_code_start=inv_code_end=~0; memory_map[vaddr>>12]|=0x40000000; if(vpage<2048) { #ifndef DISABLE_TLB @@ -1127,39 +1129,10 @@ void invalidate_page(u_int page) head=next; } } -void invalidate_block(u_int block) + +static void invalidate_block_range(u_int block, u_int first, u_int last) { u_int page=get_page(block<<12); - u_int vpage=get_vpage(block<<12); - inv_debug("INVALIDATE: %x (%d)\n",block<<12,page); - //inv_debug("invalid_code[block]=%d\n",invalid_code[block]); - u_int first,last; - first=last=page; - struct ll_entry *head; - head=jump_dirty[vpage]; - //printf("page=%d vpage=%d\n",page,vpage); - while(head!=NULL) { - u_int start,end; - if(vpage>2047||(head->vaddr>>12)==block) { // Ignore vaddr hash collision - get_bounds((int)head->addr,&start,&end); - //printf("start: %x end: %x\n",start,end); - if(page<2048&&start>=0x80000000&&end<0x80000000+RAM_SIZE) { - if(((start-(u_int)rdram)>>12)<=page&&((end-1-(u_int)rdram)>>12)>=page) { - if((((start-(u_int)rdram)>>12)&2047)>12)&2047; - if((((end-1-(u_int)rdram)>>12)&2047)>last) last=((end-1-(u_int)rdram)>>12)&2047; - } - } -#ifndef DISABLE_TLB - if(page<2048&&(signed int)start>=(signed int)0xC0000000&&(signed int)end>=(signed int)0xC0000000) { - if(((start+memory_map[start>>12]-(u_int)rdram)>>12)<=page&&((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)>=page) { - if((((start+memory_map[start>>12]-(u_int)rdram)>>12)&2047)>12]-(u_int)rdram)>>12)&2047; - if((((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)&2047)>last) last=((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)&2047; - } - } -#endif - } - head=head->next; - } //printf("first=%d last=%d\n",first,last); invalidate_page(page); assert(first+5>page); // NB: this assumes MAXBLOCK<=4096 (4 pages) @@ -1178,9 +1151,6 @@ 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]) { @@ -1198,10 +1168,98 @@ void invalidate_block(u_int block) memset(mini_ht,-1,sizeof(mini_ht)); #endif } + +void invalidate_block(u_int block) +{ + u_int page=get_page(block<<12); + u_int vpage=get_vpage(block<<12); + inv_debug("INVALIDATE: %x (%d)\n",block<<12,page); + //inv_debug("invalid_code[block]=%d\n",invalid_code[block]); + u_int first,last; + first=last=page; + struct ll_entry *head; + head=jump_dirty[vpage]; + //printf("page=%d vpage=%d\n",page,vpage); + while(head!=NULL) { + u_int start,end; + if(vpage>2047||(head->vaddr>>12)==block) { // Ignore vaddr hash collision + get_bounds((int)head->addr,&start,&end); + //printf("start: %x end: %x\n",start,end); + if(page<2048&&start>=0x80000000&&end<0x80000000+RAM_SIZE) { + if(((start-(u_int)rdram)>>12)<=page&&((end-1-(u_int)rdram)>>12)>=page) { + if((((start-(u_int)rdram)>>12)&2047)>12)&2047; + if((((end-1-(u_int)rdram)>>12)&2047)>last) last=((end-1-(u_int)rdram)>>12)&2047; + } + } +#ifndef DISABLE_TLB + if(page<2048&&(signed int)start>=(signed int)0xC0000000&&(signed int)end>=(signed int)0xC0000000) { + if(((start+memory_map[start>>12]-(u_int)rdram)>>12)<=page&&((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)>=page) { + if((((start+memory_map[start>>12]-(u_int)rdram)>>12)&2047)>12]-(u_int)rdram)>>12)&2047; + if((((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)&2047)>last) last=((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)&2047; + } + } +#endif + } + head=head->next; + } + invalidate_block_range(block,first,last); +} + void invalidate_addr(u_int addr) { +#ifdef PCSX + //static int rhits; + // this check is done by the caller + //if (inv_code_start<=addr&&addr<=inv_code_end) { rhits++; return; } + u_int page=get_page(addr); + if(page<2048) { // RAM + struct ll_entry *head; + u_int addr_min=~0, addr_max=0; + int mask=RAM_SIZE-1; + int pg1; + inv_code_start=addr&~0xfff; + inv_code_end=addr|0xfff; + pg1=page; + if (pg1>0) { + // must check previous page too because of spans.. + pg1--; + inv_code_start-=0x1000; + } + for(;pg1<=page;pg1++) { + for(head=jump_dirty[pg1];head!=NULL;head=head->next) { + u_int start,end; + get_bounds((int)head->addr,&start,&end); + if((start&mask)<=(addr&mask)&&(addr&mask)<(end&mask)) { + if(startaddr_max) addr_max=end; + } + else if(addrinv_code_start) + inv_code_start=end; + } + } + } + if (addr_min!=~0) { + inv_debug("INV ADDR: %08x hit %08x-%08x\n", addr, addr_min, addr_max); + inv_code_start=inv_code_end=~0; + invalidate_block_range(addr>>12,(addr_min&mask)>>12,(addr_max&mask)>>12); + return; + } + else { + inv_debug("INV ADDR: %08x miss, inv %08x-%08x, sk %d\n", addr, inv_code_start, inv_code_end, 0);//rhits); + } + //rhits=0; + if(page!=0) // FIXME: don't know what's up with page 0 (Klonoa) + return; + } +#endif invalidate_block(addr>>12); } + // This is called when loading a save state. // Anything could have changed, so invalidate everything. void invalidate_all_pages() @@ -1240,6 +1298,8 @@ void add_link(u_int vaddr,void *src) { u_int page=get_page(vaddr); inv_debug("add_link: %x -> %x (%d)\n",(int)src,vaddr,page); + int *ptr=(int *)(src+4); + assert((*ptr&0x0fff0000)==0x059f0000); ll_add(jump_out+page,vaddr,src); //int ptr=get_pointer(src); //inv_debug("add_link: Pointer is to %x\n",(int)ptr); @@ -2766,6 +2826,7 @@ void load_assemble(int i,struct regstat *i_regs) int offset; int jaddr=0; int memtarget=0,c=0; + int fastload_reg_override=0; u_int hr,reglist=0; th=get_reg(i_regs->regmap,rt1[i]|64); tl=get_reg(i_regs->regmap,rt1[i]); @@ -2820,6 +2881,7 @@ void load_assemble(int i,struct regstat *i_regs) if(sp_in_mirror&&rs1[i]==29) { emit_andimm(addr,~0x00e00000,HOST_TEMPREG); emit_cmpimm(HOST_TEMPREG,RAM_SIZE); + fastload_reg_override=HOST_TEMPREG; } else #endif @@ -2864,9 +2926,8 @@ void load_assemble(int i,struct regstat *i_regs) #else if(!c) a=addr; #endif -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(fastload_reg_override) a=fastload_reg_override; + emit_movsbl_indexed_tlb(x,a,map,tl); } } @@ -2892,9 +2953,7 @@ void load_assemble(int i,struct regstat *i_regs) #else if(!c) a=addr; #endif -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(fastload_reg_override) a=fastload_reg_override; //#ifdef //emit_movswl_indexed_tlb(x,tl,map,tl); //else @@ -2920,9 +2979,7 @@ void load_assemble(int i,struct regstat *i_regs) if(!c||memtarget) { if(!dummy) { int a=addr; -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(fastload_reg_override) a=fastload_reg_override; //emit_readword_indexed((int)rdram-0x80000000,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) @@ -2956,9 +3013,8 @@ void load_assemble(int i,struct regstat *i_regs) #else if(!c) a=addr; #endif -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(fastload_reg_override) a=fastload_reg_override; + emit_movzbl_indexed_tlb(x,a,map,tl); } } @@ -2984,9 +3040,7 @@ void load_assemble(int i,struct regstat *i_regs) #else if(!c) a=addr; #endif -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(fastload_reg_override) a=fastload_reg_override; //#ifdef //emit_movzwl_indexed_tlb(x,tl,map,tl); //#else @@ -3013,9 +3067,7 @@ void load_assemble(int i,struct regstat *i_regs) if(!c||memtarget) { if(!dummy) { int a=addr; -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(fastload_reg_override) a=fastload_reg_override; //emit_readword_indexed((int)rdram-0x80000000,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) @@ -3036,9 +3088,7 @@ void load_assemble(int i,struct regstat *i_regs) if(!c||memtarget) { if(!dummy) { int a=addr; -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(fastload_reg_override) a=fastload_reg_override; //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); @@ -3103,6 +3153,7 @@ void store_assemble(int i,struct regstat *i_regs) int jaddr=0,jaddr2,type; int memtarget=0,c=0; int agr=AGEN1+(i&1); + int faststore_reg_override=0; u_int hr,reglist=0; th=get_reg(i_regs->regmap,rs2[i]|64); tl=get_reg(i_regs->regmap,rs2[i]); @@ -3131,6 +3182,7 @@ void store_assemble(int i,struct regstat *i_regs) if(sp_in_mirror&&rs1[i]==29) { emit_andimm(addr,~0x00e00000,HOST_TEMPREG); emit_cmpimm(HOST_TEMPREG,RAM_SIZE); + faststore_reg_override=HOST_TEMPREG; } else #endif @@ -3177,9 +3229,7 @@ void store_assemble(int i,struct regstat *i_regs) #else if(!c) a=addr; #endif -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(faststore_reg_override) a=faststore_reg_override; //gen_tlb_addr_w(temp,map); //emit_writebyte_indexed(tl,(int)rdram-0x80000000,temp); emit_writebyte_indexed_tlb(tl,x,a,map,a); @@ -3195,9 +3245,7 @@ void store_assemble(int i,struct regstat *i_regs) #else if(!c) a=addr; #endif -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(faststore_reg_override) a=faststore_reg_override; //#ifdef //emit_writehword_indexed_tlb(tl,x,temp,map,temp); //#else @@ -3212,9 +3260,7 @@ void store_assemble(int i,struct regstat *i_regs) if (opcode[i]==0x2B) { // SW if(!c||memtarget) { int a=addr; -#ifdef PCSX - if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG; -#endif + if(faststore_reg_override) a=faststore_reg_override; //emit_writeword_indexed(tl,(int)rdram-0x80000000,addr); emit_writeword_indexed_tlb(tl,0,a,map,temp); } @@ -3223,9 +3269,7 @@ void store_assemble(int i,struct regstat *i_regs) 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(faststore_reg_override) a=faststore_reg_override; if(rs2[i]) { assert(th>=0); //emit_writeword_indexed(th,(int)rdram-0x80000000,addr); @@ -3274,8 +3318,12 @@ void store_assemble(int i,struct regstat *i_regs) //if(opcode[i]==0x2B) /*if(opcode[i]==0x2B || opcode[i]==0x28 || opcode[i]==0x29 || opcode[i]==0x3F) { - //emit_pusha(); + #ifdef __i386__ + emit_pusha(); + #endif + #ifdef __arm__ save_regs(0x100f); + #endif emit_readword((int)&last_count,ECX); #ifdef __i386__ if(get_reg(i_regs->regmap,CCREG)<0) @@ -3294,8 +3342,12 @@ void store_assemble(int i,struct regstat *i_regs) emit_writeword(0,(int)&Count); #endif emit_call((int)memdebug); - //emit_popa(); + #ifdef __i386__ + emit_popa(); + #endif + #ifdef __arm__ restore_regs(0x100f); + #endif }/**/ } @@ -5144,9 +5196,45 @@ add_to_linker(int addr,int target,int ext) linkcount++; } +static void ujump_assemble_write_ra(int i) +{ + int rt; + unsigned int return_address; + rt=get_reg(branch_regs[i].regmap,31); + assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); + //assert(rt>=0); + return_address=start+i*4+8; + if(rt>=0) { + #ifdef USE_MINI_HT + if(internal_branch(branch_regs[i].is32,return_address)&&rt1[i+1]!=31) { + int temp=-1; // note: must be ds-safe + #ifdef HOST_TEMPREG + temp=HOST_TEMPREG; + #endif + if(temp>=0) do_miniht_insert(return_address,rt,temp); + else emit_movimm(return_address,rt); + } + else + #endif + { + #ifdef REG_PREFETCH + if(temp>=0) + { + if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); + } + #endif + emit_movimm(return_address,rt); // PC into link register + #ifdef IMM_PREFETCH + emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); + #endif + } + } +} + void ujump_assemble(int i,struct regstat *i_regs) { signed char *i_regmap=i_regs->regmap; + int ra_done=0; if(i==(ba[i]-start)>>2) assem_debug("idle loop\n"); address_generation(i+1,i_regs,regs[i].regmap_entry); #ifdef REG_PREFETCH @@ -5158,38 +5246,9 @@ 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 - if(rt1[i]==31) { - int rt; - unsigned int return_address; - rt=get_reg(branch_regs[i].regmap,31); - assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); - //assert(rt>=0); - return_address=start+i*4+8; - if(rt>=0) { - #ifdef USE_MINI_HT - if(internal_branch(branch_regs[i].is32,return_address)&&rt1[i+1]!=31) { - int temp=-1; // note: must be ds-safe - #ifdef HOST_TEMPREG - temp=HOST_TEMPREG; - #endif - if(temp>=0) do_miniht_insert(return_address,rt,temp); - else emit_movimm(return_address,rt); - } - else - #endif - { - #ifdef REG_PREFETCH - if(temp>=0) - { - if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); - } - #endif - emit_movimm(return_address,rt); // PC into link register - #ifdef IMM_PREFETCH - emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); - #endif - } - } + if(rt1[i]==31&&(rt1[i]==rs1[i+1]||rt1[i]==rs2[i+1])) { + ujump_assemble_write_ra(i); // writeback ra for DS + ra_done=1; } ds_assemble(i+1,i_regs); uint64_t bc_unneeded=branch_regs[i].u; @@ -5199,6 +5258,8 @@ void ujump_assemble(int i,struct regstat *i_regs) wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, bc_unneeded,bc_unneeded_upper); load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,CCREG,CCREG); + if(!ra_done&&rt1[i]==31) + ujump_assemble_write_ra(i); int cc,adj; cc=get_reg(branch_regs[i].regmap,CCREG); assert(cc==HOST_CCREG); @@ -5222,11 +5283,33 @@ void ujump_assemble(int i,struct regstat *i_regs) } } +static void rjump_assemble_write_ra(int i) +{ + int rt,return_address; + assert(rt1[i+1]!=rt1[i]); + assert(rt2[i+1]!=rt1[i]); + rt=get_reg(branch_regs[i].regmap,rt1[i]); + assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); + assert(rt>=0); + return_address=start+i*4+8; + #ifdef REG_PREFETCH + if(temp>=0) + { + if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); + } + #endif + emit_movimm(return_address,rt); // PC into link register + #ifdef IMM_PREFETCH + emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); + #endif +} + void rjump_assemble(int i,struct regstat *i_regs) { signed char *i_regmap=i_regs->regmap; int temp; int rs,cc,adj; + int ra_done=0; rs=get_reg(branch_regs[i].regmap,rs1[i]); assert(rs>=0); if(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1]) { @@ -5253,6 +5336,10 @@ void rjump_assemble(int i,struct regstat *i_regs) if(rh>=0) do_preload_rhash(rh); } #endif + if(rt1[i]!=0&&(rt1[i]==rs1[i+1]||rt1[i]==rs2[i+1])) { + rjump_assemble_write_ra(i); + ra_done=1; + } ds_assemble(i+1,i_regs); uint64_t bc_unneeded=branch_regs[i].u; uint64_t bc_unneeded_upper=branch_regs[i].uu; @@ -5262,25 +5349,8 @@ void rjump_assemble(int i,struct regstat *i_regs) wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, bc_unneeded,bc_unneeded_upper); load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,rs1[i],CCREG); - if(rt1[i]!=0) { - int rt,return_address; - assert(rt1[i+1]!=rt1[i]); - assert(rt2[i+1]!=rt1[i]); - rt=get_reg(branch_regs[i].regmap,rt1[i]); - assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]); - assert(rt>=0); - return_address=start+i*4+8; - #ifdef REG_PREFETCH - if(temp>=0) - { - if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); - } - #endif - emit_movimm(return_address,rt); // PC into link register - #ifdef IMM_PREFETCH - emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); - #endif - } + if(!ra_done&&rt1[i]!=0) + rjump_assemble_write_ra(i); cc=get_reg(branch_regs[i].regmap,CCREG); assert(cc==HOST_CCREG); #ifdef USE_MINI_HT @@ -7781,6 +7851,7 @@ void new_dynarec_clear_full() pending_exception=0; literalcount=0; stop_after_jal=0; + inv_code_start=inv_code_end=~0; // TLB #ifndef DISABLE_TLB using_tlb=0; @@ -8243,7 +8314,9 @@ int new_recompile_block(int addr) case 0x24: strcpy(insn[i],"LBU"); type=LOAD; break; case 0x25: strcpy(insn[i],"LHU"); type=LOAD; break; case 0x26: strcpy(insn[i],"LWR"); type=LOADLR; break; +#ifndef FORCE32 case 0x27: strcpy(insn[i],"LWU"); type=LOAD; break; +#endif case 0x28: strcpy(insn[i],"SB"); type=STORE; break; case 0x29: strcpy(insn[i],"SH"); type=STORE; break; case 0x2A: strcpy(insn[i],"SWL"); type=STORELR; break; @@ -8688,7 +8761,9 @@ int new_recompile_block(int addr) } if(temp_is32!=current.is32) { //printf("dumping 32-bit regs (%x)\n",start+i*4); - #ifdef DESTRUCTIVE_WRITEBACK + #ifndef DESTRUCTIVE_WRITEBACK + if(ds) + #endif for(hr=0;hr>2; if(t>0&&(itype[t-1]!=UJUMP&&itype[t-1]!=RJUMP&&itype[t-1]!=CJUMP&&itype[t-1]!=SJUMP&&itype[t-1]!=FJUMP)) // loop_preload can't handle jumps into delay slots - if(t<2||(itype[t-2]!=UJUMP)) // call/ret assumes no registers allocated + if(t<2||(itype[t-2]!=UJUMP&&itype[t-2]!=RJUMP)||rt1[t-2]!=31) // call/ret assumes no registers allocated for(hr=0;hr64) { @@ -9953,7 +10027,7 @@ int new_recompile_block(int addr) // a mov, which is of negligible benefit. So such cases are // skipped below. if(f_regmap[hr]>0) { - if(regs[t].regmap_entry[hr]<0&&get_reg(regmap_pre[t],f_regmap[hr])<0) { + if(regs[t].regmap[hr]==f_regmap[hr]||(regs[t].regmap_entry[hr]<0&&get_reg(regmap_pre[t],f_regmap[hr])<0)) { int r=f_regmap[hr]; for(j=t;j<=i;j++) { @@ -9992,7 +10066,7 @@ int new_recompile_block(int addr) break; } // call/ret fast path assumes no registers allocated - if(k>2&&(itype[k-3]==UJUMP||itype[k-3]==RJUMP)) { + if(k>2&&(itype[k-3]==UJUMP||itype[k-3]==RJUMP)&&rt1[k-3]==31) { break; } if(r>63) { @@ -10140,7 +10214,7 @@ int new_recompile_block(int addr) } } }else{ - int count=0; + // Non branch or undetermined branch target for(hr=0;hr>2; if(t=earliest_available[hr]) { - // Score a point for hoisting loop invariant - if(t1&&itype[t-2]!=UJUMP&&itype[t-2]!=RJUMP)||(t>1&&rt1[t-2]!=31)) { // call/ret assumes no registers allocated + // Score a point for hoisting loop invariant + if(t>2; - if(t==loop_start[maxscore]) regs[t].regmap_entry[maxscore]=reg; + if(t==loop_start[maxscore]) { + if(t==1||(t>1&&itype[t-2]!=UJUMP&&itype[t-2]!=RJUMP)||(t>1&&rt1[t-2]!=31)) // call/ret assumes no registers allocated + regs[t].regmap_entry[maxscore]=reg; + } } else { @@ -10439,6 +10524,7 @@ int new_recompile_block(int addr) } } } + // Preload target address for load instruction (non-constant) if(itype[i+1]==LOAD&&rs1[i+1]&&get_reg(regs[i+1].regmap,rs1[i+1])<0) { if((hr=get_reg(regs[i+1].regmap,rt1[i+1]))>=0) { @@ -10455,6 +10541,7 @@ int new_recompile_block(int addr) } } } + // Load source into target register if(lt1[i+1]&&get_reg(regs[i+1].regmap,rs1[i+1])<0) { if((hr=get_reg(regs[i+1].regmap,rt1[i+1]))>=0) { @@ -10471,6 +10558,7 @@ int new_recompile_block(int addr) } } } + // Preload map address #ifndef HOST_IMM_ADDR32 if(itype[i+1]==LOAD||itype[i+1]==LOADLR||itype[i+1]==STORE||itype[i+1]==STORELR||itype[i+1]==C1LS||itype[i+1]==C2LS) { hr=get_reg(regs[i+1].regmap,TLREG); @@ -10510,6 +10598,7 @@ int new_recompile_block(int addr) } } #endif + // Address for store instruction (non-constant) if(itype[i+1]==STORE||itype[i+1]==STORELR ||(opcode[i+1]&0x3b)==0x39||(opcode[i+1]&0x3b)==0x3a) { // SB/SH/SW/SD/SWC1/SDC1/SWC2/SDC2 if(get_reg(regs[i+1].regmap,rs1[i+1])<0) { @@ -10962,10 +11051,14 @@ int new_recompile_block(int addr) #ifdef PCSX if (start == 0x80030000) { // nasty hack for fastbios thing + // override block entry to this code instr_addr0_override=(u_int)out; emit_movimm(start,0); - emit_readword((int)&pcaddr,1); + // abuse io address var as a flag that we + // have already returned here once + emit_readword((int)&address,1); emit_writeword(0,(int)&pcaddr); + emit_writeword(0,(int)&address); emit_cmp(0,1); emit_jne((int)new_dyna_leave); } @@ -11291,6 +11384,7 @@ int new_recompile_block(int addr) } #endif } + inv_code_start=inv_code_end=~0; #ifdef PCSX // PCSX maps all RAM mirror invalid_code tests to 0x80000000..0x80000000+RAM_SIZE if(get_page(start)<(RAM_SIZE>>12))