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=6d7069d9c8d2e837294cd5484bc3706fff789c3b;hp=21e7feda9b4051900b1085b782837c6fea6caac3;hb=a151a8d8331cf743eabeab23ce52e9b7726239e5;hpb=9f51b4b9aa4fffa7b9411ca274f5dfb179a6a30a diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 21e7feda..6d7069d9 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -23,7 +23,19 @@ #include #include #include +#ifdef __MACH__ +#include +#endif +#ifdef _3DS +#include <3ds_utils.h> +#endif +#ifdef VITA +#include +static int sceBlock; +#endif +#include "new_dynarec_config.h" +#include "../psxhle.h" //emulator interface #include "emu_if.h" //emulator interface //#define DISASM @@ -42,19 +54,6 @@ #include "assem_arm.h" #endif -#ifdef __BLACKBERRY_QNX__ -#undef __clear_cache -#define __clear_cache(start,end) msync(start, (size_t)((void*)end - (void*)start), MS_SYNC | MS_CACHE_ONLY | MS_INVALIDATE_ICACHE); -#elif defined(__MACH__) -#include -#define __clear_cache mach_clear_cache -static void __clear_cache(void *start, void *end) { - size_t len = (char *)end - (char *)start; - sys_dcache_flush(start, len); - sys_icache_invalidate(start, len); -} -#endif - #define MAXBLOCK 4096 #define MAX_OUTPUT_BLOCK_SIZE 262144 @@ -83,22 +82,29 @@ struct ll_entry struct ll_entry *next; }; - u_int start; - u_int *source; - char insn[MAXBLOCK][10]; - u_char itype[MAXBLOCK]; - u_char opcode[MAXBLOCK]; - u_char opcode2[MAXBLOCK]; - u_char bt[MAXBLOCK]; - u_char rs1[MAXBLOCK]; - u_char rs2[MAXBLOCK]; - u_char rt1[MAXBLOCK]; - u_char rt2[MAXBLOCK]; - u_char us1[MAXBLOCK]; - u_char us2[MAXBLOCK]; - u_char dep1[MAXBLOCK]; - u_char dep2[MAXBLOCK]; - u_char lt1[MAXBLOCK]; + // used by asm: + u_char *out; + u_int hash_table[65536][4] __attribute__((aligned(16))); + struct ll_entry *jump_in[4096] __attribute__((aligned(16))); + struct ll_entry *jump_dirty[4096]; + + static struct ll_entry *jump_out[4096]; + static u_int start; + static u_int *source; + static char insn[MAXBLOCK][10]; + static u_char itype[MAXBLOCK]; + static u_char opcode[MAXBLOCK]; + static u_char opcode2[MAXBLOCK]; + static u_char bt[MAXBLOCK]; + static u_char rs1[MAXBLOCK]; + static u_char rs2[MAXBLOCK]; + static u_char rt1[MAXBLOCK]; + static u_char rt2[MAXBLOCK]; + static u_char us1[MAXBLOCK]; + static u_char us2[MAXBLOCK]; + static u_char dep1[MAXBLOCK]; + static u_char dep2[MAXBLOCK]; + static u_char lt1[MAXBLOCK]; static uint64_t gte_rs[MAXBLOCK]; // gte: 32 data and 32 ctl regs static uint64_t gte_rt[MAXBLOCK]; static uint64_t gte_unneeded[MAXBLOCK]; @@ -107,52 +113,47 @@ struct ll_entry static u_int smrv_weak; // same, but somewhat less likely static u_int smrv_strong_next; // same, but after current insn executes static u_int smrv_weak_next; - int imm[MAXBLOCK]; - u_int ba[MAXBLOCK]; - char likely[MAXBLOCK]; - char is_ds[MAXBLOCK]; - char ooo[MAXBLOCK]; - uint64_t unneeded_reg[MAXBLOCK]; - uint64_t unneeded_reg_upper[MAXBLOCK]; - uint64_t branch_unneeded_reg[MAXBLOCK]; - uint64_t branch_unneeded_reg_upper[MAXBLOCK]; - uint64_t pr32[MAXBLOCK]; - signed char regmap_pre[MAXBLOCK][HOST_REGS]; + static int imm[MAXBLOCK]; + static u_int ba[MAXBLOCK]; + static char likely[MAXBLOCK]; + static char is_ds[MAXBLOCK]; + static char ooo[MAXBLOCK]; + static uint64_t unneeded_reg[MAXBLOCK]; + static uint64_t unneeded_reg_upper[MAXBLOCK]; + static uint64_t branch_unneeded_reg[MAXBLOCK]; + static uint64_t branch_unneeded_reg_upper[MAXBLOCK]; + static signed char regmap_pre[MAXBLOCK][HOST_REGS]; static uint64_t current_constmap[HOST_REGS]; static uint64_t constmap[MAXBLOCK][HOST_REGS]; static struct regstat regs[MAXBLOCK]; static struct regstat branch_regs[MAXBLOCK]; - signed char minimum_free_regs[MAXBLOCK]; - u_int needed_reg[MAXBLOCK]; - u_int wont_dirty[MAXBLOCK]; - u_int will_dirty[MAXBLOCK]; - int ccadj[MAXBLOCK]; - int slen; - u_int instr_addr[MAXBLOCK]; - u_int link_addr[MAXBLOCK][3]; - int linkcount; - u_int stubs[MAXBLOCK*3][8]; - int stubcount; - u_int literals[1024][2]; - int literalcount; - int is_delayslot; - int cop1_usable; - u_char *out; - struct ll_entry *jump_in[4096] __attribute__((aligned(16))); - struct ll_entry *jump_out[4096]; - struct ll_entry *jump_dirty[4096]; - u_int hash_table[65536][4] __attribute__((aligned(16))); - char shadow[1048576] __attribute__((aligned(16))); - void *copy; - int expirep; - int new_dynarec_did_compile; - int new_dynarec_hacks; - u_int stop_after_jal; + static signed char minimum_free_regs[MAXBLOCK]; + static u_int needed_reg[MAXBLOCK]; + static u_int wont_dirty[MAXBLOCK]; + static u_int will_dirty[MAXBLOCK]; + static int ccadj[MAXBLOCK]; + static int slen; + static u_int instr_addr[MAXBLOCK]; + static u_int link_addr[MAXBLOCK][3]; + static int linkcount; + static u_int stubs[MAXBLOCK*3][8]; + static int stubcount; + static u_int literals[1024][2]; + static int literalcount; + static int is_delayslot; + static int cop1_usable; + static char shadow[1048576] __attribute__((aligned(16))); + static void *copy; + static int expirep; + static u_int stop_after_jal; #ifndef RAM_FIXED static u_int ram_offset; #else static const u_int ram_offset=0; #endif + + int new_dynarec_hacks; + int new_dynarec_did_compile; extern u_char restore_candidate[512]; extern int cycle_count; @@ -254,15 +255,80 @@ void jump_intcall(); void new_dyna_leave(); // Needed by assembler -void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32); -void wb_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty); -void wb_needed_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,int addr); -void load_all_regs(signed char i_regmap[]); -void load_needed_regs(signed char i_regmap[],signed char next_regmap[]); -void load_regs_entry(int t); -void load_all_consts(signed char regmap[],int is32,u_int dirty,int i); +static void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32); +static void wb_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty); +static void wb_needed_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,int addr); +static void load_all_regs(signed char i_regmap[]); +static void load_needed_regs(signed char i_regmap[],signed char next_regmap[]); +static void load_regs_entry(int t); +static void load_all_consts(signed char regmap[],int is32,u_int dirty,int i); + +static int verify_dirty(u_int *ptr); +static int get_final_value(int hr, int i, int *value); +static void add_stub(int type,int addr,int retaddr,int a,int b,int c,int d,int e); +static void add_to_linker(int addr,int target,int ext); + +static int tracedebug=0; + +static void mprotect_w_x(void *start, void *end, int is_x) +{ +#ifdef NO_WRITE_EXEC + #if defined(VITA) + // *Open* enables write on all memory that was + // allocated by sceKernelAllocMemBlockForVM()? + if (is_x) + sceKernelCloseVMDomain(); + else + sceKernelOpenVMDomain(); + #else + u_long mstart = (u_long)start & ~4095ul; + u_long mend = (u_long)end; + if (mprotect((void *)mstart, mend - mstart, + PROT_READ | (is_x ? PROT_EXEC : PROT_WRITE)) != 0) + SysPrintf("mprotect(%c) failed: %s\n", is_x ? 'x' : 'w', strerror(errno)); + #endif +#endif +} + +static void start_tcache_write(void *start, void *end) +{ + mprotect_w_x(start, end, 0); +} -int tracedebug=0; +static void end_tcache_write(void *start, void *end) +{ +#ifdef __arm__ + size_t len = (char *)end - (char *)start; + #if defined(__BLACKBERRY_QNX__) + msync(start, len, MS_SYNC | MS_CACHE_ONLY | MS_INVALIDATE_ICACHE); + #elif defined(__MACH__) + sys_cache_control(kCacheFunctionPrepareForExecution, start, len); + #elif defined(VITA) + sceKernelSyncVMDomain(sceBlock, start, len); + #elif defined(_3DS) + ctr_flush_invalidate_cache(); + #else + __clear_cache(start, end); + #endif + (void)len; +#endif + + mprotect_w_x(start, end, 1); +} + +static void *start_block(void) +{ + u_char *end = out + MAX_OUTPUT_BLOCK_SIZE; + if (end > (u_char *)BASE_ADDR + (1<vaddr==vaddr) { //printf("TRACE: count=%d next=%d (get_addr match %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr); - int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; + u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; ht_bin[3]=ht_bin[1]; ht_bin[2]=ht_bin[0]; - ht_bin[1]=(int)head->addr; + ht_bin[1]=(u_int)head->addr; ht_bin[0]=vaddr; return head->addr; } @@ -327,9 +393,9 @@ void *get_addr(u_int vaddr) restore_candidate[vpage>>3]|=1<<(vpage&7); } else restore_candidate[page>>3]|=1<<(page&7); - int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; + u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(ht_bin[0]==vaddr) { - ht_bin[1]=(int)head->addr; // Replace existing entry + ht_bin[1]=(u_int)head->addr; // Replace existing entry } else { @@ -359,7 +425,7 @@ void *get_addr(u_int vaddr) void *get_addr_ht(u_int vaddr) { //printf("TRACE: count=%d next=%d (get_addr_ht %x)\n",Count,next_interupt,vaddr); - int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; + u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(ht_bin[0]==vaddr) return (void *)ht_bin[1]; if(ht_bin[2]==vaddr) return (void *)ht_bin[3]; return get_addr(vaddr); @@ -627,6 +693,7 @@ int needed_again(int r, int i) } }*/ if(rn<10) return 1; + (void)b; return 0; } @@ -774,7 +841,7 @@ void *check_addr(u_int vaddr) void remove_hash(int vaddr) { //printf("remove hash: %x\n",vaddr); - int *ht_bin=hash_table[(((vaddr)>>16)^vaddr)&0xFFFF]; + u_int *ht_bin=hash_table[(((vaddr)>>16)^vaddr)&0xFFFF]; if(ht_bin[2]==vaddr) { ht_bin[2]=ht_bin[3]=-1; } @@ -810,7 +877,7 @@ void ll_clear(struct ll_entry **head) { struct ll_entry *cur; struct ll_entry *next; - if(cur=*head) { + if((cur=*head)) { *head=0; while(cur) { next=cur->next; @@ -821,7 +888,7 @@ void ll_clear(struct ll_entry **head) } // Dereference the pointers and remove if it matches -void ll_kill_pointers(struct ll_entry *head,int addr,int shift) +static void ll_kill_pointers(struct ll_entry *head,int addr,int shift) { while(head) { int ptr=get_pointer(head->addr); @@ -830,10 +897,11 @@ void ll_kill_pointers(struct ll_entry *head,int addr,int shift) (((ptr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(addr>>shift))) { inv_debug("EXP: Kill pointer at %x (%x)\n",(int)head->addr,head->vaddr); - u_int host_addr=(u_int)kill_pointer(head->addr); + void *host_addr=find_extjump_insn(head->addr); #ifdef __arm__ - needs_clear_cache[(host_addr-(u_int)BASE_ADDR)>>17]|=1<<(((host_addr-(u_int)BASE_ADDR)>>12)&31); + mark_clear_cache(host_addr); #endif + set_jump_target((int)host_addr,(int)head->addr); } head=head->next; } @@ -857,10 +925,11 @@ void invalidate_page(u_int page) jump_out[page]=0; while(head!=NULL) { inv_debug("INVALIDATE: kill pointer to %x (%x)\n",head->vaddr,(int)head->addr); - u_int host_addr=(u_int)kill_pointer(head->addr); + void *host_addr=find_extjump_insn(head->addr); #ifdef __arm__ - needs_clear_cache[(host_addr-(u_int)BASE_ADDR)>>17]|=1<<(((host_addr-(u_int)BASE_ADDR)>>12)&31); + mark_clear_cache(host_addr); #endif + set_jump_target((int)host_addr,(int)head->addr); next=head->next; free(head); head=next; @@ -984,7 +1053,7 @@ void invalidate_addr(u_int addr) // Anything could have changed, so invalidate everything. void invalidate_all_pages() { - u_int page,n; + u_int page; for(page=0;page<4096;page++) invalidate_page(page); for(page=0;page<1048576;page++) @@ -992,9 +1061,6 @@ void invalidate_all_pages() restore_candidate[(page&2047)>>3]|=1<<(page&7); restore_candidate[((page&2047)>>3)+256]|=1<<(page&7); } - #ifdef __arm__ - __clear_cache((void *)BASE_ADDR,(void *)BASE_ADDR+(1< %x (%d)\n",(int)src,vaddr,page); int *ptr=(int *)(src+4); assert((*ptr&0x0fff0000)==0x059f0000); + (void)ptr; ll_add(jump_out+page,vaddr,src); //int ptr=get_pointer(src); //inv_debug("add_link: Pointer is to %x\n",(int)ptr); @@ -1026,7 +1093,7 @@ void clean_blocks(u_int page) // Don't restore blocks which are about to expire from the cache if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) { u_int start,end; - if(verify_dirty((int)head->addr)) { + if(verify_dirty(head->addr)) { //printf("Possibly Restore %x (%x)\n",head->vaddr, (int)head->addr); u_int i; u_int inv=0; @@ -1047,12 +1114,12 @@ void clean_blocks(u_int page) //printf("page=%x, addr=%x\n",page,head->vaddr); //assert(head->vaddr>>12==(page|0x80000)); ll_add_flags(jump_in+ppage,head->vaddr,head->reg_sv_flags,clean_addr); - int *ht_bin=hash_table[((head->vaddr>>16)^head->vaddr)&0xFFFF]; + u_int *ht_bin=hash_table[((head->vaddr>>16)^head->vaddr)&0xFFFF]; if(ht_bin[0]==head->vaddr) { - ht_bin[1]=(int)clean_addr; // Replace existing entry + ht_bin[1]=(u_int)clean_addr; // Replace existing entry } if(ht_bin[2]==head->vaddr) { - ht_bin[3]=(int)clean_addr; // Replace existing entry + ht_bin[3]=(u_int)clean_addr; // Replace existing entry } } } @@ -1747,7 +1814,7 @@ static void pagespan_alloc(struct regstat *current,int i) //else ... } -add_stub(int type,int addr,int retaddr,int a,int b,int c,int d,int e) +static void add_stub(int type,int addr,int retaddr,int a,int b,int c,int d,int e) { stubs[stubcount][0]=type; stubs[stubcount][1]=addr; @@ -2326,23 +2393,25 @@ void imm16_assemble(int i,struct regstat *i_regs) emit_mov(sh,th); } } - if(opcode[i]==0x0d) //ORI - if(sl<0) { - emit_orimm(tl,imm[i],tl); - }else{ - if(!((i_regs->wasconst>>sl)&1)) - emit_orimm(sl,imm[i],tl); - else - emit_movimm(constmap[i][sl]|imm[i],tl); + if(opcode[i]==0x0d) { // ORI + if(sl<0) { + emit_orimm(tl,imm[i],tl); + }else{ + if(!((i_regs->wasconst>>sl)&1)) + emit_orimm(sl,imm[i],tl); + else + emit_movimm(constmap[i][sl]|imm[i],tl); + } } - if(opcode[i]==0x0e) //XORI - if(sl<0) { - emit_xorimm(tl,imm[i],tl); - }else{ - if(!((i_regs->wasconst>>sl)&1)) - emit_xorimm(sl,imm[i],tl); - else - emit_movimm(constmap[i][sl]^imm[i],tl); + if(opcode[i]==0x0e) { // XORI + if(sl<0) { + emit_xorimm(tl,imm[i],tl); + }else{ + if(!((i_regs->wasconst>>sl)&1)) + emit_xorimm(sl,imm[i],tl); + else + emit_movimm(constmap[i][sl]^imm[i],tl); + } } } else { @@ -2526,7 +2595,7 @@ void load_assemble(int i,struct regstat *i_regs) //printf("load_assemble: c=%d\n",c); //if(c) printf("load_assemble: const=%x\n",(int)constmap[i][s]+offset); // FIXME: Even if the load is a NOP, we should check for pagefaults... - if(tl<0&&(!c||(((u_int)constmap[i][s]+offset)>>16)==0x1f80) + if((tl<0&&(!c||(((u_int)constmap[i][s]+offset)>>16)==0x1f80)) ||rt1[i]==0) { // could be FIFO, must perform the read // ||dummy read @@ -2783,7 +2852,7 @@ void load_assemble(int i,struct regstat *i_regs) emit_call((int)memdebug); //emit_popa(); restore_regs(0x100f); - }/**/ + }*/ } #ifndef loadlr_assemble @@ -2799,7 +2868,7 @@ void store_assemble(int i,struct regstat *i_regs) int s,th,tl,map=-1; int addr,temp; int offset; - int jaddr=0,jaddr2,type; + int jaddr=0,type; int memtarget=0,c=0; int agr=AGEN1+(i&1); int faststore_reg_override=0; @@ -2918,7 +2987,7 @@ void store_assemble(int i,struct regstat *i_regs) #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT) emit_callne(invalidate_addr_reg[addr]); #else - jaddr2=(int)out; + int jaddr2=(int)out; emit_jne(0); add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<regmap,CCREG); assert(ccreg==HOST_CCREG); assert(!is_delayslot); + (void)ccreg; emit_movimm(start+i*4,EAX); // Get PC emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle... emit_jmp((int)jump_syscall_hle); // XXX @@ -3371,11 +3441,17 @@ void syscall_assemble(int i,struct regstat *i_regs) void hlecall_assemble(int i,struct regstat *i_regs) { + extern void psxNULL(); signed char ccreg=get_reg(i_regs->regmap,CCREG); assert(ccreg==HOST_CCREG); assert(!is_delayslot); + (void)ccreg; emit_movimm(start+i*4+4,0); // Get PC - emit_movimm((int)psxHLEt[source[i]&7],1); + uint32_t hleCode = source[i] & 0x03ffffff; + if (hleCode >= (sizeof(psxHLEt) / sizeof(psxHLEt[0]))) + emit_movimm((int)psxNULL,1); + else + emit_movimm((int)psxHLEt[hleCode],1); emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // XXX emit_jmp((int)jump_hlecall); } @@ -3385,6 +3461,7 @@ void intcall_assemble(int i,struct regstat *i_regs) signed char ccreg=get_reg(i_regs->regmap,CCREG); assert(ccreg==HOST_CCREG); assert(!is_delayslot); + (void)ccreg; emit_movimm(start+i*4,0); // Get PC emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); emit_jmp((int)jump_intcall); @@ -3703,7 +3780,7 @@ void address_generation(int i,struct regstat *i_regs,signed char entry[]) } } -int get_final_value(int hr, int i, int *value) +static int get_final_value(int hr, int i, int *value) { int reg=regs[i].regmap[hr]; while(i=0) reglist|=1<\n"); + drc_dbg_emit_do_cmp(t); if(regs[t].regmap_entry[HOST_CCREG]==CCREG&®s[t].regmap[HOST_CCREG]!=CCREG) wb_register(CCREG,regs[t].regmap_entry,regs[t].wasdirty,regs[t].was32); load_regs(regs[t].regmap_entry,regs[t].regmap,regs[t].was32,rs1[t],rs2[t]); @@ -4584,7 +4684,7 @@ void do_ccstub(int n) emit_jmpreg(EAX);*/ } -add_to_linker(int addr,int target,int ext) +static void add_to_linker(int addr,int target,int ext) { link_addr[linkcount][0]=addr; link_addr[linkcount][1]=target; @@ -4629,7 +4729,6 @@ static void ujump_assemble_write_ra(int i) 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); @@ -4637,6 +4736,7 @@ void ujump_assemble(int i,struct regstat *i_regs) int temp=get_reg(branch_regs[i].regmap,PTEMP); if(rt1[i]==31&&temp>=0) { + signed char *i_regmap=i_regs->regmap; int return_address=start+i*4+8; if(get_reg(branch_regs[i].regmap,31)>0) if(i_regmap[temp]==PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); @@ -4702,9 +4802,8 @@ static void rjump_assemble_write_ra(int i) void rjump_assemble(int i,struct regstat *i_regs) { - signed char *i_regmap=i_regs->regmap; int temp; - int rs,cc,adj; + int rs,cc; int ra_done=0; rs=get_reg(branch_regs[i].regmap,rs1[i]); assert(rs>=0); @@ -4721,6 +4820,7 @@ void rjump_assemble(int i,struct regstat *i_regs) if(rt1[i]==31) { if((temp=get_reg(branch_regs[i].regmap,PTEMP))>=0) { + signed char *i_regmap=i_regs->regmap; int return_address=start+i*4+8; if(i_regmap[temp]==PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); } @@ -4749,6 +4849,7 @@ void rjump_assemble(int i,struct regstat *i_regs) rjump_assemble_write_ra(i); cc=get_reg(branch_regs[i].regmap,CCREG); assert(cc==HOST_CCREG); + (void)cc; #ifdef USE_MINI_HT int rh=get_reg(branch_regs[i].regmap,RHASH); int ht=get_reg(branch_regs[i].regmap,RHTBL); @@ -5754,7 +5855,6 @@ static void pagespan_assemble(int i,struct regstat *i_regs) int s1h=get_reg(i_regs->regmap,rs1[i]|64); int s2l=get_reg(i_regs->regmap,rs2[i]); int s2h=get_reg(i_regs->regmap,rs2[i]|64); - void *nt_branch=NULL; int taken=0; int nottaken=0; int unconditional=0; @@ -5771,7 +5871,7 @@ static void pagespan_assemble(int i,struct regstat *i_regs) s1h=s2h=-1; } int hr=0; - int addr,alt,ntaddr; + int addr=-1,alt=-1,ntaddr=-1; if(i_regs->regmap[HOST_BTREG]<0) {addr=HOST_BTREG;} else { while(hr>r)&1));*/} + }else {/*printf("i: %x (%d) mismatch(+2): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/} } } } @@ -6776,7 +6876,7 @@ void clean_registers(int istart,int iend,int wr) if(r!=EXCLUDE_REG) { if(regs[i].regmap[r]==regmap_pre[i+1][r]) { regs[i+1].wasdirty&=wont_dirty_i|~(1<>r)&1));*/} + }else {/*printf("i: %x (%d) mismatch(+1): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/} } } } @@ -6819,7 +6919,7 @@ void clean_registers(int istart,int iend,int wr) wont_dirty_i|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<>r)&1));*/ + /*printf("i: %x (%d) mismatch: %d\n",start+i*4,i,r);assert(!((will_dirty>>r)&1));*/ } } } @@ -6925,13 +7025,14 @@ static void disassemble_inst(int i) {} static int new_dynarec_test(void) { int (*testfunc)(void) = (void *)out; + void *beginning; int ret; + + beginning = start_block(); emit_movimm(DRC_TEST_VAL,0); // test emit_jmpreg(14); literal_pool(0); -#ifdef __arm__ - __clear_cache((void *)testfunc, out); -#endif + end_block(beginning); SysPrintf("testing if we can run recompiled code..\n"); ret = testfunc(); if (ret == DRC_TEST_VAL) @@ -6968,20 +7069,43 @@ void new_dynarec_clear_full() void new_dynarec_init() { SysPrintf("Init new dynarec\n"); - out=(u_char *)BASE_ADDR; -#if BASE_ADDR_FIXED - if (mmap (out, 1<>12]=0; emit_movimm(start,0); emit_writeword(0,(int)&pcaddr); emit_jmp((int)new_dyna_leave); literal_pool(0); -#ifdef __arm__ - __clear_cache((void *)beginning,out); -#endif + end_block(beginning); ll_add_flags(jump_in+page,start,state_rflags,(void *)beginning); return 0; } @@ -8352,7 +8483,7 @@ int new_recompile_block(int addr) // Create entry (branch target) regmap for(hr=0;hr=0) { if(r!=regmap_pre[i][hr]) { @@ -9871,7 +10002,7 @@ int new_recompile_block(int addr) cop1_usable=0; uint64_t is32_pre=0; u_int dirty_pre=0; - u_int beginning=(u_int)out; + void *beginning=start_block(); if((u_int)addr&1) { ds=1; pagespan_ds(); @@ -9925,6 +10056,8 @@ int new_recompile_block(int addr) // branch target entry point instr_addr[i]=(u_int)out; assem_debug("<->\n"); + drc_dbg_emit_do_cmp(i); + // load regs if(regs[i].regmap_entry[HOST_CCREG]==CCREG&®s[i].regmap[HOST_CCREG]!=CCREG) wb_register(CCREG,regs[i].regmap_entry,regs[i].wasdirty,regs[i].was32); @@ -10144,7 +10277,7 @@ int new_recompile_block(int addr) // replace it with the new address. // Don't add new entries. We'll insert the // ones that actually get used in check_addr(). - int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; + u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(ht_bin[0]==vaddr) { ht_bin[1]=entry_point; } @@ -10161,14 +10294,12 @@ int new_recompile_block(int addr) // Align code if(((u_int)out)&7) emit_addnop(13); #endif - assert((u_int)out-beginning>shift)==(base>>shift) || ((ht_bin[3]-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(base>>shift)) { inv_debug("EXP: Remove hash %x -> %x\n",ht_bin[2],ht_bin[3]);