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=f81c98536f0cfe9c56cb05c4c8b91e7a20fda5af;hp=f45322a8f263e1ff59ef7f015d65d327d2764fba;hb=3d680478922d5f28e3dbe471308cc27a70e31fdf;hpb=32631e6a5d44d1e6aa5d53d5777a039b2d3d4300 diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index f45322a8..f81c9853 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -1095,12 +1095,14 @@ void remove_hash(int vaddr) } } -void ll_remove_matching_addrs(struct ll_entry **head,uintptr_t addr,int shift) +static void ll_remove_matching_addrs(struct ll_entry **head, + uintptr_t base_offs_s, int shift) { struct ll_entry *next; while(*head) { - if(((uintptr_t)((*head)->addr)>>shift)==(addr>>shift) || - ((uintptr_t)((*head)->addr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(addr>>shift)) + uintptr_t o1 = (u_char *)(*head)->addr - ndrc->translation_cache; + uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE; + if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) { inv_debug("EXP: Remove pointer to %p (%x)\n",(*head)->addr,(*head)->vaddr); remove_hash((*head)->vaddr); @@ -1131,13 +1133,15 @@ void ll_clear(struct ll_entry **head) } // Dereference the pointers and remove if it matches -static void ll_kill_pointers(struct ll_entry *head,uintptr_t addr,int shift) +static void ll_kill_pointers(struct ll_entry *head, + uintptr_t base_offs_s, int shift) { while(head) { - uintptr_t ptr = (uintptr_t)get_pointer(head->addr); - inv_debug("EXP: Lookup pointer to %lx at %p (%x)\n",(long)ptr,head->addr,head->vaddr); - if(((ptr>>shift)==(addr>>shift)) || - (((ptr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(addr>>shift))) + u_char *ptr = get_pointer(head->addr); + uintptr_t o1 = ptr - ndrc->translation_cache; + uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE; + inv_debug("EXP: Lookup pointer to %p at %p (%x)\n",ptr,head->addr,head->vaddr); + if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) { inv_debug("EXP: Kill pointer at %p (%x)\n",head->addr,head->vaddr); void *host_addr=find_extjump_insn(head->addr); @@ -1168,7 +1172,7 @@ static void invalidate_page(u_int page) inv_debug("INVALIDATE: kill pointer to %x (%p)\n",head->vaddr,head->addr); void *host_addr=find_extjump_insn(head->addr); mark_clear_cache(host_addr); - set_jump_target(host_addr, head->addr); + set_jump_target(host_addr, head->addr); // point back to dyna_linker next=head->next; free(head); head=next; @@ -1317,14 +1321,13 @@ static void do_invstub(int n) // Add an entry to jump_out after making a link // src should point to code by emit_extjump2() -void add_link(u_int vaddr,void *src) +void add_jump_out(u_int vaddr,void *src) { u_int page=get_page(vaddr); - inv_debug("add_link: %p -> %x (%d)\n",src,vaddr,page); + inv_debug("add_jump_out: %p -> %x (%d)\n",src,vaddr,page); check_extjump2(src); ll_add(jump_out+page,vaddr,src); - //void *ptr=get_pointer(src); - //inv_debug("add_link: Pointer is to %p\n",ptr); + //inv_debug("add_jump_out: to %p\n",get_pointer(src)); } // If a code block was found to be unmodified (bit was set in @@ -5968,7 +5971,7 @@ static void pagespan_assemble(int i,struct regstat *i_regs) emit_extjump_ds(branch_addr, target_addr); if(compiled_target_addr) { set_jump_target(branch_addr, compiled_target_addr); - add_link(target_addr,stub); + add_jump_out(target_addr,stub); } else set_jump_target(branch_addr, stub); if(likely[i]) { @@ -5983,7 +5986,7 @@ static void pagespan_assemble(int i,struct regstat *i_regs) emit_extjump_ds(branch_addr, target_addr); if(compiled_target_addr) { set_jump_target(branch_addr, compiled_target_addr); - add_link(target_addr,stub); + add_jump_out(target_addr,stub); } else set_jump_target(branch_addr, stub); } @@ -5997,7 +6000,7 @@ static void pagespan_ds() u_int page=get_page(vaddr); u_int vpage=get_vpage(vaddr); ll_add(jump_dirty+vpage,vaddr,(void *)out); - do_dirty_stub_ds(); + do_dirty_stub_ds(slen*4); ll_add(jump_in+page,vaddr,(void *)out); assert(regs[0].regmap_entry[HOST_CCREG]==CCREG); if(regs[0].regmap[HOST_CCREG]!=CCREG) @@ -9245,10 +9248,14 @@ int new_recompile_block(u_int addr) literal_pool_jumpover(256); } } - //assert(is_ujump(i-2)); + + assert(slen > 0); + if (itype[slen-1] == INTCALL) { + // no ending needed for this block since INTCALL never returns + } // If the block did not end with an unconditional branch, // add a jump to the next instruction. - if(i>1) { + else if (i > 1) { if(!is_ujump(i-2)&&itype[i-1]!=SPAN) { assert(itype[i-1]!=UJUMP&&itype[i-1]!=CJUMP&&itype[i-1]!=SJUMP&&itype[i-1]!=RJUMP); assert(i==slen); @@ -9328,7 +9335,7 @@ int new_recompile_block(u_int addr) emit_extjump(link_addr[i].addr, link_addr[i].target); if (addr) { set_jump_target(link_addr[i].addr, addr); - add_link(link_addr[i].target,stub); + add_jump_out(link_addr[i].target,stub); } else set_jump_target(link_addr[i].addr, stub); @@ -9346,8 +9353,17 @@ int new_recompile_block(u_int addr) //#endif } } + + u_int source_len = slen*4; + if (itype[slen-1] == INTCALL && source_len > 4) + // no need to treat the last instruction as compiled + // as interpreter fully handles it + source_len -= 4; + + if ((u_char *)copy + source_len > (u_char *)shadow + sizeof(shadow)) + copy = shadow; + // External Branch Targets (jump_in) - if(copy+slen*4>(void *)shadow+sizeof(shadow)) copy=shadow; for(i=0;itranslation_cache+((expirep>>13)<> 13) << shift); // Base offset of this block + uintptr_t base_offs_s = base_offs >> shift; inv_debug("EXP: Phase %d\n",expirep); switch((expirep>>11)&3) { case 0: // Clear jump_in and jump_dirty - ll_remove_matching_addrs(jump_in+(expirep&2047),base,shift); - ll_remove_matching_addrs(jump_dirty+(expirep&2047),base,shift); - ll_remove_matching_addrs(jump_in+2048+(expirep&2047),base,shift); - ll_remove_matching_addrs(jump_dirty+2048+(expirep&2047),base,shift); + ll_remove_matching_addrs(jump_in+(expirep&2047),base_offs_s,shift); + ll_remove_matching_addrs(jump_dirty+(expirep&2047),base_offs_s,shift); + ll_remove_matching_addrs(jump_in+2048+(expirep&2047),base_offs_s,shift); + ll_remove_matching_addrs(jump_dirty+2048+(expirep&2047),base_offs_s,shift); break; case 1: // Clear pointers - ll_kill_pointers(jump_out[expirep&2047],base,shift); - ll_kill_pointers(jump_out[(expirep&2047)+2048],base,shift); + ll_kill_pointers(jump_out[expirep&2047],base_offs_s,shift); + ll_kill_pointers(jump_out[(expirep&2047)+2048],base_offs_s,shift); break; case 2: // Clear hash table for(i=0;i<32;i++) { struct ht_entry *ht_bin = &hash_table[((expirep&2047)<<5)+i]; - if (((uintptr_t)ht_bin->tcaddr[1]>>shift) == (base>>shift) || - (((uintptr_t)ht_bin->tcaddr[1]-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(base>>shift)) { + uintptr_t o1 = (u_char *)ht_bin->tcaddr[1] - ndrc->translation_cache; + uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE; + if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) { inv_debug("EXP: Remove hash %x -> %p\n",ht_bin->vaddr[1],ht_bin->tcaddr[1]); ht_bin->vaddr[1] = -1; ht_bin->tcaddr[1] = NULL; } - if (((uintptr_t)ht_bin->tcaddr[0]>>shift) == (base>>shift) || - (((uintptr_t)ht_bin->tcaddr[0]-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(base>>shift)) { + o1 = (u_char *)ht_bin->tcaddr[0] - ndrc->translation_cache; + o2 = o1 - MAX_OUTPUT_BLOCK_SIZE; + if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) { inv_debug("EXP: Remove hash %x -> %p\n",ht_bin->vaddr[0],ht_bin->tcaddr[0]); ht_bin->vaddr[0] = ht_bin->vaddr[1]; ht_bin->tcaddr[0] = ht_bin->tcaddr[1]; @@ -9454,8 +9473,8 @@ int new_recompile_block(u_int addr) // Clear jump_out if((expirep&2047)==0) do_clear_cache(); - ll_remove_matching_addrs(jump_out+(expirep&2047),base,shift); - ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base,shift); + ll_remove_matching_addrs(jump_out+(expirep&2047),base_offs_s,shift); + ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base_offs_s,shift); break; } expirep=(expirep+1)&65535;