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=78e53d45e75933b991911503ea598ba7eafc3bd4;hp=c3c470dd2576ec50732a1709ef8997672614de03;hb=643aeae3222be00a799ca1e96e795ff846f81fee;hpb=dd79da89fc4ddf020bb6f8d8c8a733429249bab3 diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index c3c470dd..78e53d45 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -38,6 +38,10 @@ static int sceBlock; #include "../psxhle.h" //emulator interface #include "emu_if.h" //emulator interface +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + //#define DISASM //#define assem_debug printf //#define inv_debug printf @@ -57,6 +61,24 @@ static int sceBlock; #define MAXBLOCK 4096 #define MAX_OUTPUT_BLOCK_SIZE 262144 +// stubs +enum stub_type { + CC_STUB = 1, + FP_STUB = 2, + LOADB_STUB = 3, + LOADH_STUB = 4, + LOADW_STUB = 5, + LOADD_STUB = 6, + LOADBU_STUB = 7, + LOADHU_STUB = 8, + STOREB_STUB = 9, + STOREH_STUB = 10, + STOREW_STUB = 11, + STORED_STUB = 12, + STORELR_STUB = 13, + INVCODE_STUB = 14, +}; + struct regstat { signed char regmap_entry[HOST_REGS]; @@ -82,9 +104,34 @@ struct ll_entry struct ll_entry *next; }; +struct ht_entry +{ + u_int vaddr[2]; + void *tcaddr[2]; +}; + +struct code_stub +{ + enum stub_type type; + void *addr; + void *retaddr; + u_int a; + uintptr_t b; + uintptr_t c; + u_int d; + u_int e; +}; + +struct link_entry +{ + void *addr; + u_int target; + u_int ext; +}; + // used by asm: u_char *out; - u_int hash_table[65536][4] __attribute__((aligned(16))); + struct ht_entry hash_table[65536] __attribute__((aligned(16))); struct ll_entry *jump_in[4096] __attribute__((aligned(16))); struct ll_entry *jump_dirty[4096]; @@ -133,10 +180,10 @@ struct ll_entry 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 void *instr_addr[MAXBLOCK]; + static struct link_entry link_addr[MAXBLOCK]; static int linkcount; - static u_int stubs[MAXBLOCK*3][8]; + static struct code_stub stubs[MAXBLOCK*3]; static int stubcount; static u_int literals[1024][2]; static int literalcount; @@ -214,22 +261,6 @@ struct ll_entry #define C2OP 29 // Coprocessor 2 operation #define INTCALL 30// Call interpreter to handle rare corner cases - /* stubs */ -#define CC_STUB 1 -#define FP_STUB 2 -#define LOADB_STUB 3 -#define LOADH_STUB 4 -#define LOADW_STUB 5 -#define LOADD_STUB 6 -#define LOADBU_STUB 7 -#define LOADHU_STUB 8 -#define STOREB_STUB 9 -#define STOREH_STUB 10 -#define STOREW_STUB 11 -#define STORED_STUB 12 -#define STORELR_STUB 13 -#define INVCODE_STUB 14 - /* branch codes */ #define TAKEN 1 #define NOTTAKEN 2 @@ -265,10 +296,11 @@ 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 add_stub(enum stub_type type, void *addr, void *retaddr, + u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e); +static void add_stub_r(enum stub_type type, void *addr, void *retaddr, + int i, int addr_reg, struct regstat *i_regs, int ccadj, u_int reglist); +static void add_to_linker(void *addr, u_int target, int ext); static void mprotect_w_x(void *start, void *end, int is_x) { @@ -319,8 +351,8 @@ static void end_tcache_write(void *start, void *end) static void *start_block(void) { u_char *end = out + MAX_OUTPUT_BLOCK_SIZE; - if (end > (u_char *)BASE_ADDR + (1< translation_cache + (1<>16)^vaddr)&0xFFFF]; +} + +static void hash_table_add(struct ht_entry *ht_bin, u_int vaddr, void *tcaddr) +{ + ht_bin->vaddr[1] = ht_bin->vaddr[0]; + ht_bin->tcaddr[1] = ht_bin->tcaddr[0]; + ht_bin->vaddr[0] = vaddr; + ht_bin->tcaddr[0] = tcaddr; +} + +// some messy ari64's code, seems to rely on unsigned 32bit overflow +static int doesnt_expire_soon(void *tcaddr) +{ + u_int diff = (u_int)((u_char *)tcaddr - out) << (32-TARGET_SIZE_2); + return diff > (u_int)(0x60000000 + (MAX_OUTPUT_BLOCK_SIZE << (32-TARGET_SIZE_2))); +} + // Get address from virtual address // This is called from the recompiled JR/JALR instructions void *get_addr(u_int vaddr) @@ -369,12 +421,8 @@ void *get_addr(u_int vaddr) head=jump_in[page]; while(head!=NULL) { if(head->vaddr==vaddr) { - //printf("TRACE: count=%d next=%d (get_addr match %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr); - 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]=(u_int)head->addr; - ht_bin[0]=vaddr; + //printf("TRACE: count=%d next=%d (get_addr match %x: %p)\n",Count,next_interupt,vaddr,head->addr); + hash_table_add(hash_table_get(vaddr), vaddr, head->addr); return head->addr; } head=head->next; @@ -382,10 +430,10 @@ void *get_addr(u_int vaddr) head=jump_dirty[vpage]; while(head!=NULL) { if(head->vaddr==vaddr) { - //printf("TRACE: count=%d next=%d (get_addr match dirty %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr); + //printf("TRACE: count=%d next=%d (get_addr match dirty %x: %p)\n",Count,next_interupt,vaddr,head->addr); // 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))) - if(verify_dirty(head->addr)) { + if (doesnt_expire_soon(head->addr)) + 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; @@ -393,17 +441,12 @@ void *get_addr(u_int vaddr) restore_candidate[vpage>>3]|=1<<(vpage&7); } else restore_candidate[page>>3]|=1<<(page&7); - u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; - if(ht_bin[0]==vaddr) { - ht_bin[1]=(u_int)head->addr; // Replace existing entry - } + struct ht_entry *ht_bin = hash_table_get(vaddr); + if (ht_bin->vaddr[0] == vaddr) + ht_bin->tcaddr[0] = head->addr; // Replace existing entry else - { - ht_bin[3]=ht_bin[1]; - ht_bin[2]=ht_bin[0]; - ht_bin[1]=(int)head->addr; - ht_bin[0]=vaddr; - } + hash_table_add(ht_bin, vaddr, head->addr); + return head->addr; } } @@ -425,9 +468,9 @@ 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); - 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]; + const struct ht_entry *ht_bin = hash_table_get(vaddr); + if (ht_bin->vaddr[0] == vaddr) return ht_bin->tcaddr[0]; + if (ht_bin->vaddr[1] == vaddr) return ht_bin->tcaddr[1]; return get_addr(vaddr); } @@ -796,39 +839,39 @@ void ll_add_flags(struct ll_entry **head,int vaddr,u_int reg_sv_flags,void *addr // but don't return addresses which are about to expire from the cache void *check_addr(u_int vaddr) { - u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; - if(ht_bin[0]==vaddr) { - if(((ht_bin[1]-MAX_OUTPUT_BLOCK_SIZE-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) - if(isclean(ht_bin[1])) return (void *)ht_bin[1]; - } - if(ht_bin[2]==vaddr) { - if(((ht_bin[3]-MAX_OUTPUT_BLOCK_SIZE-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) - if(isclean(ht_bin[3])) return (void *)ht_bin[3]; + struct ht_entry *ht_bin = hash_table_get(vaddr); + size_t i; + for (i = 0; i < ARRAY_SIZE(ht_bin->vaddr); i++) { + if (ht_bin->vaddr[i] == vaddr) + if (doesnt_expire_soon((u_char *)ht_bin->tcaddr[i] - MAX_OUTPUT_BLOCK_SIZE)) + if (isclean(ht_bin->tcaddr[i])) + return ht_bin->tcaddr[i]; } u_int page=get_page(vaddr); struct ll_entry *head; head=jump_in[page]; - while(head!=NULL) { - if(head->vaddr==vaddr) { - if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) { + while (head != NULL) { + if (head->vaddr == vaddr) { + if (doesnt_expire_soon(head->addr)) { // Update existing entry with current address - if(ht_bin[0]==vaddr) { - ht_bin[1]=(int)head->addr; + if (ht_bin->vaddr[0] == vaddr) { + ht_bin->tcaddr[0] = head->addr; return head->addr; } - if(ht_bin[2]==vaddr) { - ht_bin[3]=(int)head->addr; + if (ht_bin->vaddr[1] == vaddr) { + ht_bin->tcaddr[1] = head->addr; return head->addr; } // Insert into hash table with low priority. // Don't evict existing entries, as they are probably // addresses that are being accessed frequently. - if(ht_bin[0]==-1) { - ht_bin[1]=(int)head->addr; - ht_bin[0]=vaddr; - }else if(ht_bin[2]==-1) { - ht_bin[3]=(int)head->addr; - ht_bin[2]=vaddr; + if (ht_bin->vaddr[0] == -1) { + ht_bin->vaddr[0] = vaddr; + ht_bin->tcaddr[0] = head->addr; + } + else if (ht_bin->vaddr[1] == -1) { + ht_bin->vaddr[1] = vaddr; + ht_bin->tcaddr[1] = head->addr; } return head->addr; } @@ -841,25 +884,27 @@ void *check_addr(u_int vaddr) void remove_hash(int vaddr) { //printf("remove hash: %x\n",vaddr); - u_int *ht_bin=hash_table[(((vaddr)>>16)^vaddr)&0xFFFF]; - if(ht_bin[2]==vaddr) { - ht_bin[2]=ht_bin[3]=-1; + struct ht_entry *ht_bin = hash_table_get(vaddr); + if (ht_bin->vaddr[1] == vaddr) { + ht_bin->vaddr[1] = -1; + ht_bin->tcaddr[1] = NULL; } - if(ht_bin[0]==vaddr) { - ht_bin[0]=ht_bin[2]; - ht_bin[1]=ht_bin[3]; - ht_bin[2]=ht_bin[3]=-1; + if (ht_bin->vaddr[0] == vaddr) { + ht_bin->vaddr[0] = ht_bin->vaddr[1]; + ht_bin->tcaddr[0] = ht_bin->tcaddr[1]; + ht_bin->vaddr[1] = -1; + ht_bin->tcaddr[1] = NULL; } } -void ll_remove_matching_addrs(struct ll_entry **head,int addr,int shift) +void ll_remove_matching_addrs(struct ll_entry **head,uintptr_t addr,int shift) { struct ll_entry *next; while(*head) { - if(((u_int)((*head)->addr)>>shift)==(addr>>shift) || - ((u_int)((*head)->addr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(addr>>shift)) + if(((uintptr_t)((*head)->addr)>>shift)==(addr>>shift) || + ((uintptr_t)((*head)->addr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(addr>>shift)) { - inv_debug("EXP: Remove pointer to %x (%x)\n",(int)(*head)->addr,(*head)->vaddr); + inv_debug("EXP: Remove pointer to %p (%x)\n",(*head)->addr,(*head)->vaddr); remove_hash((*head)->vaddr); next=(*head)->next; free(*head); @@ -888,20 +933,20 @@ void ll_clear(struct ll_entry **head) } // Dereference the pointers and remove if it matches -static void ll_kill_pointers(struct ll_entry *head,int addr,int shift) +static void ll_kill_pointers(struct ll_entry *head,uintptr_t addr,int shift) { while(head) { - int ptr=get_pointer(head->addr); - inv_debug("EXP: Lookup pointer to %x at %x (%x)\n",(int)ptr,(int)head->addr,head->vaddr); + 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))) { - inv_debug("EXP: Kill pointer at %x (%x)\n",(int)head->addr,head->vaddr); + inv_debug("EXP: Kill pointer at %p (%x)\n",head->addr,head->vaddr); void *host_addr=find_extjump_insn(head->addr); #ifdef __arm__ mark_clear_cache(host_addr); #endif - set_jump_target((int)host_addr,(int)head->addr); + set_jump_target(host_addr, head->addr); } head=head->next; } @@ -924,12 +969,12 @@ void invalidate_page(u_int page) head=jump_out[page]; jump_out[page]=0; while(head!=NULL) { - inv_debug("INVALIDATE: kill pointer to %x (%x)\n",head->vaddr,(int)head->addr); + inv_debug("INVALIDATE: kill pointer to %x (%p)\n",head->vaddr,head->addr); void *host_addr=find_extjump_insn(head->addr); #ifdef __arm__ mark_clear_cache(host_addr); #endif - set_jump_target((int)host_addr,(int)head->addr); + set_jump_target(host_addr, head->addr); next=head->next; free(head); head=next; @@ -977,7 +1022,7 @@ void invalidate_block(u_int block) 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); + get_bounds(head->addr,&start,&end); //printf("start: %x end: %x\n",start,end); if(page<2048&&start>=(u_int)rdram&&end<(u_int)rdram+RAM_SIZE) { if(((start-(u_int)rdram)>>12)<=page&&((end-1-(u_int)rdram)>>12)>=page) { @@ -1014,7 +1059,7 @@ void invalidate_addr(u_int addr) 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); + get_bounds(head->addr,&start,&end); if(ram_offset) { start-=ram_offset; end-=ram_offset; @@ -1070,13 +1115,13 @@ void invalidate_all_pages() 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); + inv_debug("add_link: %p -> %x (%d)\n",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); + //void *ptr=get_pointer(src); + //inv_debug("add_link: Pointer is to %p\n",ptr); } // If a code block was found to be unmodified (bit was set in @@ -1091,13 +1136,13 @@ void clean_blocks(u_int page) while(head!=NULL) { if(!invalid_code[head->vaddr>>12]) { // 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))) { + if (doesnt_expire_soon(head->addr)) { u_int start,end; if(verify_dirty(head->addr)) { - //printf("Possibly Restore %x (%x)\n",head->vaddr, (int)head->addr); + //printf("Possibly Restore %x (%p)\n",head->vaddr, head->addr); u_int i; u_int inv=0; - get_bounds((int)head->addr,&start,&end); + get_bounds(head->addr,&start,&end); if(start-(u_int)rdram>12;i<=(end-1-(u_int)rdram+0x80000000)>>12;i++) { inv|=invalid_code[i]; @@ -1107,20 +1152,18 @@ void clean_blocks(u_int page) inv=1; } if(!inv) { - void * clean_addr=(void *)get_clean_addr((int)head->addr); - if((((u_int)clean_addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) { + void *clean_addr = get_clean_addr(head->addr); + if (doesnt_expire_soon(clean_addr)) { u_int ppage=page; - inv_debug("INV: Restored %x (%x/%x)\n",head->vaddr, (int)head->addr, (int)clean_addr); + inv_debug("INV: Restored %x (%p/%p)\n",head->vaddr, head->addr, clean_addr); //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); - u_int *ht_bin=hash_table[((head->vaddr>>16)^head->vaddr)&0xFFFF]; - if(ht_bin[0]==head->vaddr) { - ht_bin[1]=(u_int)clean_addr; // Replace existing entry - } - if(ht_bin[2]==head->vaddr) { - ht_bin[3]=(u_int)clean_addr; // Replace existing entry - } + struct ht_entry *ht_bin = hash_table_get(head->vaddr); + if (ht_bin->vaddr[0] == head->vaddr) + ht_bin->tcaddr[0] = clean_addr; // Replace existing entry + if (ht_bin->vaddr[1] == head->vaddr) + ht_bin->tcaddr[1] = clean_addr; // Replace existing entry } } } @@ -1814,19 +1857,27 @@ static void pagespan_alloc(struct regstat *current,int i) //else ... } -static void add_stub(int type,int addr,int retaddr,int a,int b,int c,int d,int e) +static void add_stub(enum stub_type type, void *addr, void *retaddr, + u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e) { - stubs[stubcount][0]=type; - stubs[stubcount][1]=addr; - stubs[stubcount][2]=retaddr; - stubs[stubcount][3]=a; - stubs[stubcount][4]=b; - stubs[stubcount][5]=c; - stubs[stubcount][6]=d; - stubs[stubcount][7]=e; + assert(a < ARRAY_SIZE(stubs)); + stubs[stubcount].type = type; + stubs[stubcount].addr = addr; + stubs[stubcount].retaddr = retaddr; + stubs[stubcount].a = a; + stubs[stubcount].b = b; + stubs[stubcount].c = c; + stubs[stubcount].d = d; + stubs[stubcount].e = e; stubcount++; } +static void add_stub_r(enum stub_type type, void *addr, void *retaddr, + int i, int addr_reg, struct regstat *i_regs, int ccadj, u_int reglist) +{ + add_stub(type, addr, retaddr, i, addr_reg, (uintptr_t)i_regs, ccadj, reglist); +} + // Write out a single register void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32) { @@ -1848,7 +1899,6 @@ void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32 int mchecksum() { - //if(!tracedebug) return 0; int i; int sum=0; for(i=0;i<2097152;i++) { @@ -1876,37 +1926,6 @@ void rlist() printf("\n"); } -void enabletrace() -{ - tracedebug=1; -} - -void memdebug(int i) -{ - //printf("TRACE: count=%d next=%d (checksum %x) lo=%8x%8x\n",Count,next_interupt,mchecksum(),(int)(reg[LOREG]>>32),(int)reg[LOREG]); - //printf("TRACE: count=%d next=%d (rchecksum %x)\n",Count,next_interupt,rchecksum()); - //rlist(); - //if(tracedebug) { - //if(Count>=-2084597794) { - if((signed int)Count>=-2084597794&&(signed int)Count<0) { - //if(0) { - printf("TRACE: count=%d next=%d (checksum %x)\n",Count,next_interupt,mchecksum()); - //printf("TRACE: count=%d next=%d (checksum %x) Status=%x\n",Count,next_interupt,mchecksum(),Status); - //printf("TRACE: count=%d next=%d (checksum %x) hi=%8x%8x\n",Count,next_interupt,mchecksum(),(int)(reg[HIREG]>>32),(int)reg[HIREG]); - rlist(); - #ifdef __i386__ - printf("TRACE: %x\n",(&i)[-1]); - #endif - #ifdef __arm__ - int j; - printf("TRACE: %x \n",(&j)[10]); - printf("TRACE: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",(&j)[1],(&j)[2],(&j)[3],(&j)[4],(&j)[5],(&j)[6],(&j)[7],(&j)[8],(&j)[9],(&j)[10],(&j)[11],(&j)[12],(&j)[13],(&j)[14],(&j)[15],(&j)[16],(&j)[17],(&j)[18],(&j)[19],(&j)[20]); - #endif - //fflush(stdout); - } - //printf("TRACE: %x\n",(&i)[-1]); -} - void alu_assemble(int i,struct regstat *i_regs) { if(opcode2[i]>=0x20&&opcode2[i]<=0x23) { // ADD/ADDU/SUB/SUBU @@ -2574,7 +2593,7 @@ void load_assemble(int i,struct regstat *i_regs) { int s,th,tl,addr,map=-1; int offset; - int jaddr=0; + void *jaddr=0; int memtarget=0,c=0; int fastload_reg_override=0; u_int hr,reglist=0; @@ -2593,7 +2612,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); + //if(c) printf("load_assemble: const=%lx\n",(long)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)) ||rt1[i]==0) { @@ -2608,7 +2627,7 @@ void load_assemble(int i,struct regstat *i_regs) //if(tl<0) tl=get_reg(i_regs->regmap,-1); if(tl>=0) { //printf("load_assemble: c=%d\n",c); - //if(c) printf("load_assemble: const=%x\n",(int)constmap[i][s]+offset); + //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset); assert(tl>=0); // Even if the load is a NOP, we must check for pagefaults and I/O reglist&=~(1<=0) reglist&=~(1<regmap,rt1[i],ccadj[i],reglist); @@ -2685,13 +2704,13 @@ void load_assemble(int i,struct regstat *i_regs) #if 1 //def RAM_OFFSET emit_movswl_indexed(x,a,tl); #else - emit_movswl_indexed((int)rdram-0x80000000+x,a,tl); + emit_movswl_indexed(rdram-0x80000000+x,a,tl); #endif } } } if(jaddr) - add_stub(LOADH_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); + add_stub_r(LOADH_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist); } else inline_readstub(LOADH_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); @@ -2701,7 +2720,7 @@ void load_assemble(int i,struct regstat *i_regs) if(!dummy) { int a=addr; if(fastload_reg_override) a=fastload_reg_override; - //emit_readword_indexed((int)rdram-0x80000000,addr,tl); + //emit_readword_indexed(rdram-0x80000000,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readword_tlb(constmap[i][s]+offset,map,tl); @@ -2710,7 +2729,7 @@ void load_assemble(int i,struct regstat *i_regs) 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); + add_stub_r(LOADW_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist); } else inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); @@ -2725,7 +2744,7 @@ void load_assemble(int i,struct regstat *i_regs) #endif { //emit_xorimm(addr,3,tl); - //emit_movzbl_indexed((int)rdram-0x80000000,tl,tl); + //emit_movzbl_indexed(rdram-0x80000000,tl,tl); int x=0,a=tl; #ifdef BIG_ENDIAN_MIPS if(!c) emit_xorimm(addr,3,tl); @@ -2739,7 +2758,7 @@ void load_assemble(int i,struct regstat *i_regs) } } if(jaddr) - add_stub(LOADBU_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); + add_stub_r(LOADBU_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist); } else inline_readstub(LOADBU_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); @@ -2770,13 +2789,13 @@ void load_assemble(int i,struct regstat *i_regs) #if 1 //def RAM_OFFSET emit_movzwl_indexed(x,a,tl); #else - emit_movzwl_indexed((int)rdram-0x80000000+x,a,tl); + emit_movzwl_indexed(rdram-0x80000000+x,a,tl); #endif } } } if(jaddr) - add_stub(LOADHU_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist); + add_stub_r(LOADHU_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist); } else inline_readstub(LOADHU_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); @@ -2787,7 +2806,7 @@ void load_assemble(int i,struct regstat *i_regs) if(!dummy) { int a=addr; if(fastload_reg_override) a=fastload_reg_override; - //emit_readword_indexed((int)rdram-0x80000000,addr,tl); + //emit_readword_indexed(rdram-0x80000000,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readword_tlb(constmap[i][s]+offset,map,tl); @@ -2796,7 +2815,7 @@ void load_assemble(int i,struct regstat *i_regs) 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); + add_stub_r(LOADW_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist); } else { inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); @@ -2808,8 +2827,8 @@ void load_assemble(int i,struct regstat *i_regs) if(!dummy) { int a=addr; if(fastload_reg_override) a=fastload_reg_override; - //if(th>=0) emit_readword_indexed((int)rdram-0x80000000,addr,th); - //emit_readword_indexed((int)rdram-0x7FFFFFFC,addr,tl); + //if(th>=0) emit_readword_indexed(rdram-0x80000000,addr,th); + //emit_readword_indexed(rdram-0x7FFFFFFC,addr,tl); #ifdef HOST_IMM_ADDR32 if(c) emit_readdword_tlb(constmap[i][s]+offset,map,th,tl); @@ -2818,41 +2837,12 @@ void load_assemble(int i,struct regstat *i_regs) 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); + add_stub_r(LOADD_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist); } else inline_readstub(LOADD_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist); } } - //emit_storereg(rt1[i],tl); // DEBUG - //if(opcode[i]==0x23) - //if(opcode[i]==0x24) - //if(opcode[i]==0x23||opcode[i]==0x24) - /*if(opcode[i]==0x21||opcode[i]==0x23||opcode[i]==0x24) - { - //emit_pusha(); - save_regs(0x100f); - emit_readword((int)&last_count,ECX); - #ifdef __i386__ - if(get_reg(i_regs->regmap,CCREG)<0) - emit_loadreg(CCREG,HOST_CCREG); - emit_add(HOST_CCREG,ECX,HOST_CCREG); - emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG); - emit_writeword(HOST_CCREG,(int)&Count); - #endif - #ifdef __arm__ - if(get_reg(i_regs->regmap,CCREG)<0) - emit_loadreg(CCREG,0); - else - emit_mov(HOST_CCREG,0); - emit_add(0,ECX,0); - emit_addimm(0,2*ccadj[i],0); - emit_writeword(0,(int)&Count); - #endif - emit_call((int)memdebug); - //emit_popa(); - restore_regs(0x100f); - }*/ } #ifndef loadlr_assemble @@ -2868,7 +2858,8 @@ void store_assemble(int i,struct regstat *i_regs) int s,th,tl,map=-1; int addr,temp; int offset; - int jaddr=0,type; + void *jaddr=0; + enum stub_type type; int memtarget=0,c=0; int agr=AGEN1+(i&1); int faststore_reg_override=0; @@ -2911,7 +2902,7 @@ void store_assemble(int i,struct regstat *i_regs) if(!c) a=addr; #endif if(faststore_reg_override) a=faststore_reg_override; - //emit_writebyte_indexed(tl,(int)rdram-0x80000000,temp); + //emit_writebyte_indexed(tl,rdram-0x80000000,temp); emit_writebyte_indexed_tlb(tl,x,a,map,a); } type=STOREB_STUB; @@ -2932,7 +2923,7 @@ void store_assemble(int i,struct regstat *i_regs) if(map>=0) { emit_writehword_indexed(tl,x,a); }else - //emit_writehword_indexed(tl,(int)rdram-0x80000000+x,a); + //emit_writehword_indexed(tl,rdram-0x80000000+x,a); emit_writehword_indexed(tl,x,a); } type=STOREH_STUB; @@ -2941,7 +2932,7 @@ void store_assemble(int i,struct regstat *i_regs) if(!c||memtarget) { int a=addr; if(faststore_reg_override) a=faststore_reg_override; - //emit_writeword_indexed(tl,(int)rdram-0x80000000,addr); + //emit_writeword_indexed(tl,rdram-0x80000000,addr); emit_writeword_indexed_tlb(tl,0,a,map,temp); } type=STOREW_STUB; @@ -2952,13 +2943,13 @@ void store_assemble(int i,struct regstat *i_regs) if(faststore_reg_override) a=faststore_reg_override; if(rs2[i]) { assert(th>=0); - //emit_writeword_indexed(th,(int)rdram-0x80000000,addr); - //emit_writeword_indexed(tl,(int)rdram-0x7FFFFFFC,addr); + //emit_writeword_indexed(th,rdram-0x80000000,addr); + //emit_writeword_indexed(tl,rdram-0x7FFFFFFC,addr); 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_writeword_indexed(tl,rdram-0x80000000,temp); + //emit_writeword_indexed(tl,rdram-0x7FFFFFFC,temp); emit_writedword_indexed_tlb(tl,tl,0,a,map,temp); } } @@ -2967,7 +2958,7 @@ void store_assemble(int i,struct regstat *i_regs) if(jaddr) { // PCSX store handlers don't check invcode again reglist|=1<waswritten&(1<=0); emit_cmpmem_indexedsr12_reg(ir,addr,1); #else - emit_cmpmem_indexedsr12_imm((int)invalid_code,addr,1); + emit_cmpmem_indexedsr12_imm(invalid_code,addr,1); #endif #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT) emit_callne(invalidate_addr_reg[addr]); #else - int jaddr2=(int)out; + void *jaddr2 = out; emit_jne(0); - add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<regmap,rs2[i],ccadj[i],reglist); } @@ -3008,47 +2999,10 @@ void store_assemble(int i,struct regstat *i_regs) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i); wb_dirtys(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty); emit_movimm(start+i*4+4,0); - emit_writeword(0,(int)&pcaddr); - emit_jmp((int)do_interrupt); + emit_writeword(0,&pcaddr); + emit_jmp(do_interrupt); } } - //if(opcode[i]==0x2B || opcode[i]==0x3F) - //if(opcode[i]==0x2B || opcode[i]==0x28) - //if(opcode[i]==0x2B || opcode[i]==0x29) - //if(opcode[i]==0x2B) - /*if(opcode[i]==0x2B || opcode[i]==0x28 || opcode[i]==0x29 || opcode[i]==0x3F) - { - #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) - emit_loadreg(CCREG,HOST_CCREG); - emit_add(HOST_CCREG,ECX,HOST_CCREG); - emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG); - emit_writeword(HOST_CCREG,(int)&Count); - #endif - #ifdef __arm__ - if(get_reg(i_regs->regmap,CCREG)<0) - emit_loadreg(CCREG,0); - else - emit_mov(HOST_CCREG,0); - emit_add(0,ECX,0); - emit_addimm(0,2*ccadj[i],0); - emit_writeword(0,(int)&Count); - #endif - emit_call((int)memdebug); - #ifdef __i386__ - emit_popa(); - #endif - #ifdef __arm__ - restore_regs(0x100f); - #endif - }*/ } void storelr_assemble(int i,struct regstat *i_regs) @@ -3057,9 +3011,9 @@ void storelr_assemble(int i,struct regstat *i_regs) int temp; int temp2=-1; int offset; - int jaddr=0; - int case1,case2,case3; - int done0,done1,done2; + void *jaddr=0; + void *case1, *case2, *case3; + void *done0, *done1, *done2; int memtarget=0,c=0; int agr=AGEN1+(i&1); u_int hr,reglist=0; @@ -3083,13 +3037,13 @@ void storelr_assemble(int i,struct regstat *i_regs) if(!c) { emit_cmpimm(s<0||offset?temp:s,RAM_SIZE); if(!offset&&s!=temp) emit_mov(s,temp); - jaddr=(int)out; + jaddr=out; emit_jno(0); } else { if(!memtarget||!rs1[i]) { - jaddr=(int)out; + jaddr=out; emit_jmp(0); } } @@ -3110,10 +3064,10 @@ void storelr_assemble(int i,struct regstat *i_regs) emit_xorimm(temp,3,temp); #endif emit_testimm(temp,2); - case2=(int)out; + case2=out; emit_jne(0); emit_testimm(temp,1); - case1=(int)out; + case1=out; emit_jne(0); // 0 if (opcode[i]==0x2A) { // SWL @@ -3130,10 +3084,10 @@ void storelr_assemble(int i,struct regstat *i_regs) emit_writebyte_indexed(tl,3,temp); if(rs2[i]) emit_shldimm(th,tl,24,temp2); } - done0=(int)out; + done0=out; emit_jmp(0); // 1 - set_jump_target(case1,(int)out); + set_jump_target(case1, out); if (opcode[i]==0x2A) { // SWL // Write 3 msb into three least significant bytes if(rs2[i]) emit_rorimm(tl,8,tl); @@ -3160,12 +3114,12 @@ void storelr_assemble(int i,struct regstat *i_regs) // Write two lsb into two most significant bytes emit_writehword_indexed(tl,1,temp); } - done1=(int)out; + done1=out; emit_jmp(0); // 2 - set_jump_target(case2,(int)out); + set_jump_target(case2, out); emit_testimm(temp,1); - case3=(int)out; + case3=out; emit_jne(0); if (opcode[i]==0x2A) { // SWL // Write two msb into two least significant bytes @@ -3195,10 +3149,10 @@ void storelr_assemble(int i,struct regstat *i_regs) emit_writehword_indexed(tl,0,temp); if(rs2[i]) emit_rorimm(tl,24,tl); } - done2=(int)out; + done2=out; emit_jmp(0); // 3 - set_jump_target(case3,(int)out); + set_jump_target(case3, out); if (opcode[i]==0x2A) { // SWL // Write msb into least significant byte if(rs2[i]) emit_rorimm(tl,24,tl); @@ -3221,27 +3175,27 @@ void storelr_assemble(int i,struct regstat *i_regs) // Write entire word emit_writeword_indexed(tl,-3,temp); } - set_jump_target(done0,(int)out); - set_jump_target(done1,(int)out); - set_jump_target(done2,(int)out); + set_jump_target(done0, out); + set_jump_target(done1, out); + set_jump_target(done2, out); if (opcode[i]==0x2C) { // SDL emit_testimm(temp,4); - done0=(int)out; + done0=out; emit_jne(0); emit_andimm(temp,~3,temp); emit_writeword_indexed(temp2,4,temp); - set_jump_target(done0,(int)out); + set_jump_target(done0, out); } if (opcode[i]==0x2D) { // SDR emit_testimm(temp,4); - done0=(int)out; + done0=out; emit_jeq(0); emit_andimm(temp,~3,temp); emit_writeword_indexed(temp2,-4,temp); - set_jump_target(done0,(int)out); + set_jump_target(done0, out); } if(!c||!memtarget) - add_stub(STORELR_STUB,jaddr,(int)out,i,(int)i_regs,temp,ccadj[i],reglist); + add_stub_r(STORELR_STUB,jaddr,out,i,temp,i_regs,ccadj[i],reglist); if(!(i_regs->waswritten&(1<regmap,ROREG); @@ -3255,29 +3209,16 @@ void storelr_assemble(int i,struct regstat *i_regs) assert(ir>=0); emit_cmpmem_indexedsr12_reg(ir,temp,1); #else - emit_cmpmem_indexedsr12_imm((int)invalid_code,temp,1); + emit_cmpmem_indexedsr12_imm(invalid_code,temp,1); #endif #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT) emit_callne(invalidate_addr_reg[temp]); #else - int jaddr2=(int)out; + void *jaddr2 = out; emit_jne(0); - add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<regmap,CCREG)<0) - emit_loadreg(CCREG,HOST_CCREG); - emit_add(HOST_CCREG,ECX,HOST_CCREG); - emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG); - emit_writeword(HOST_CCREG,(int)&Count); - emit_call((int)memdebug); - emit_popa(); - //restore_regs(0x100f); - */ } void c1ls_assemble(int i,struct regstat *i_regs) @@ -3291,7 +3232,8 @@ void c2ls_assemble(int i,struct regstat *i_regs) int ar; int offset; int memtarget=0,c=0; - int jaddr2=0,type; + void *jaddr2=NULL; + enum stub_type type; int agr=AGEN1+(i&1); int fastio_reg_override=0; u_int hr,reglist=0; @@ -3329,7 +3271,7 @@ void c2ls_assemble(int i,struct regstat *i_regs) type=LOADW_STUB; if(c&&!memtarget) { - jaddr2=(int)out; + jaddr2=out; emit_jmp(0); // inline_readstub/inline_writestub? } else { @@ -3359,7 +3301,7 @@ void c2ls_assemble(int i,struct regstat *i_regs) } } if(jaddr2) - add_stub(type,jaddr2,(int)out,i,ar,(int)i_regs,ccadj[i],reglist); + add_stub_r(type,jaddr2,out,i,ar,i_regs,ccadj[i],reglist); if(opcode[i]==0x3a) // SWC2 if(!(i_regs->waswritten&(1<=0); emit_cmpmem_indexedsr12_reg(ir,ar,1); #else - emit_cmpmem_indexedsr12_imm((int)invalid_code,ar,1); + emit_cmpmem_indexedsr12_imm(invalid_code,ar,1); #endif #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT) emit_callne(invalidate_addr_reg[ar]); #else - int jaddr3=(int)out; + void *jaddr3 = out; emit_jne(0); - add_stub(INVCODE_STUB,jaddr3,(int)out,reglist|(1<regmap,CCREG); assert(ccreg==HOST_CCREG); assert(!is_delayslot); (void)ccreg; emit_movimm(start+i*4+4,0); // Get PC uint32_t hleCode = source[i] & 0x03ffffff; - if (hleCode >= (sizeof(psxHLEt) / sizeof(psxHLEt[0]))) - emit_movimm((int)psxNULL,1); + if (hleCode >= ARRAY_SIZE(psxHLEt)) + emit_movimm((uintptr_t)psxNULL,1); else - emit_movimm((int)psxHLEt[hleCode],1); + emit_movimm((uintptr_t)psxHLEt[hleCode],1); emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // XXX - emit_jmp((int)jump_hlecall); + emit_jmp(jump_hlecall); } void intcall_assemble(int i,struct regstat *i_regs) @@ -3463,7 +3406,7 @@ void intcall_assemble(int i,struct regstat *i_regs) (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); + emit_jmp(jump_intcall); } void ds_assemble(int i,struct regstat *i_regs) @@ -3807,13 +3750,13 @@ static int get_final_value(int hr, int i, int *value) { // Precompute load address *value=constmap[i][hr]+imm[i+1]; - //printf("c=%x imm=%x\n",(int)constmap[i][hr],imm[i+1]); + //printf("c=%x imm=%lx\n",(long)constmap[i][hr],imm[i+1]); return 1; } } } *value=constmap[i][hr]; - //printf("c=%x\n",(int)constmap[i][hr]); + //printf("c=%lx\n",(long)constmap[i][hr]); if(i==slen-1) return 1; if(reg<64) { return !((unneeded_reg[i+1]>>reg)&1); @@ -4262,13 +4205,37 @@ int match_bt(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,int addr) return 1; } +#ifdef DRC_DBG +static void drc_dbg_emit_do_cmp(int i) +{ + extern void do_insn_cmp(); + extern int cycle; + u_int hr,reglist=0; + + for(hr=0;hr=0) reglist|=1<>2; - if(!instr_addr[t]) instr_addr[t]=(u_int)out; + if (!instr_addr[t]) + instr_addr[t] = out; assem_debug("Assemble delay slot at %x\n",ba[i]); assem_debug("<->\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]); @@ -4334,15 +4301,15 @@ void ds_assemble_entry(int i) else assem_debug("branch: external\n"); assert(internal_branch(regs[t].is32,ba[i]+4)); - add_to_linker((int)out,ba[i]+4,internal_branch(regs[t].is32,ba[i]+4)); + add_to_linker(out,ba[i]+4,internal_branch(regs[t].is32,ba[i]+4)); emit_jmp(0); } void do_cc(int i,signed char i_regmap[],int *adj,int addr,int taken,int invert) { int count; - int jaddr; - int idle=0; + void *jaddr; + void *idle=NULL; int t=0; if(itype[i]==RJUMP) { @@ -4363,10 +4330,10 @@ void do_cc(int i,signed char i_regmap[],int *adj,int addr,int taken,int invert) if(taken==TAKEN && i==(ba[i]-start)>>2 && source[i+1]==0) { // Idle loop if(count&1) emit_addimm_and_set_flags(2*(count+2),HOST_CCREG); - idle=(int)out; + idle=out; //emit_subfrommem(&idlecount,HOST_CCREG); // Count idle cycles emit_andimm(HOST_CCREG,3,HOST_CCREG); - jaddr=(int)out; + jaddr=out; emit_jmp(0); } else if(*adj==0||invert) { @@ -4378,40 +4345,40 @@ void do_cc(int i,signed char i_regmap[],int *adj,int addr,int taken,int invert) cycles=CLOCK_ADJUST(*adj)+count+2-*adj; } emit_addimm_and_set_flags(cycles,HOST_CCREG); - jaddr=(int)out; + jaddr=out; emit_jns(0); } else { emit_cmpimm(HOST_CCREG,-CLOCK_ADJUST(count+2)); - jaddr=(int)out; + jaddr=out; emit_jns(0); } - add_stub(CC_STUB,jaddr,idle?idle:(int)out,(*adj==0||invert||idle)?0:(count+2),i,addr,taken,0); + add_stub(CC_STUB,jaddr,idle?idle:out,(*adj==0||invert||idle)?0:(count+2),i,addr,taken,0); } -void do_ccstub(int n) +static void do_ccstub(int n) { literal_pool(256); - assem_debug("do_ccstub %x\n",start+stubs[n][4]*4); - set_jump_target(stubs[n][1],(int)out); - int i=stubs[n][4]; - if(stubs[n][6]==NULLDS) { + assem_debug("do_ccstub %x\n",start+stubs[n].b*4); + set_jump_target(stubs[n].addr, out); + int i=stubs[n].b; + if(stubs[n].d==NULLDS) { // Delay slot instruction is nullified ("likely" branch) wb_dirtys(regs[i].regmap,regs[i].is32,regs[i].dirty); } - else if(stubs[n][6]!=TAKEN) { + else if(stubs[n].d!=TAKEN) { wb_dirtys(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty); } else { if(internal_branch(branch_regs[i].is32,ba[i])) wb_needed_dirtys(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); } - if(stubs[n][5]!=-1) + if(stubs[n].c!=-1) { // Save PC as return address - emit_movimm(stubs[n][5],EAX); - emit_writeword(EAX,(int)&pcaddr); + emit_movimm(stubs[n].c,EAX); + emit_writeword(EAX,&pcaddr); } else { @@ -4592,7 +4559,7 @@ void do_ccstub(int n) emit_cmovne_reg(alt,addr); } } - emit_writeword(addr,(int)&pcaddr); + emit_writeword(addr,&pcaddr); } else if(itype[i]==RJUMP) @@ -4601,70 +4568,43 @@ void do_ccstub(int n) if(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1]) { r=get_reg(branch_regs[i].regmap,RTEMP); } - emit_writeword(r,(int)&pcaddr); + emit_writeword(r,&pcaddr); } else {SysPrintf("Unknown branch type in do_ccstub\n");exit(1);} } // Update cycle count assert(branch_regs[i].regmap[HOST_CCREG]==CCREG||branch_regs[i].regmap[HOST_CCREG]==-1); - if(stubs[n][3]) emit_addimm(HOST_CCREG,CLOCK_ADJUST((int)stubs[n][3]),HOST_CCREG); - emit_call((int)cc_interrupt); - if(stubs[n][3]) emit_addimm(HOST_CCREG,-CLOCK_ADJUST((int)stubs[n][3]),HOST_CCREG); - if(stubs[n][6]==TAKEN) { + if(stubs[n].a) emit_addimm(HOST_CCREG,CLOCK_ADJUST((signed int)stubs[n].a),HOST_CCREG); + emit_call(cc_interrupt); + if(stubs[n].a) emit_addimm(HOST_CCREG,-CLOCK_ADJUST((signed int)stubs[n].a),HOST_CCREG); + if(stubs[n].d==TAKEN) { if(internal_branch(branch_regs[i].is32,ba[i])) load_needed_regs(branch_regs[i].regmap,regs[(ba[i]-start)>>2].regmap_entry); else if(itype[i]==RJUMP) { if(get_reg(branch_regs[i].regmap,RTEMP)>=0) - emit_readword((int)&pcaddr,get_reg(branch_regs[i].regmap,RTEMP)); + emit_readword(&pcaddr,get_reg(branch_regs[i].regmap,RTEMP)); else emit_loadreg(rs1[i],get_reg(branch_regs[i].regmap,rs1[i])); } - }else if(stubs[n][6]==NOTTAKEN) { + }else if(stubs[n].d==NOTTAKEN) { if(i=0) { - if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); + if(i_regmap[temp]!=PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp); } #endif emit_movimm(return_address,rt); // PC into link register #ifdef IMM_PREFETCH - emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); + emit_prefetch(hash_table_get(return_address)); #endif } } @@ -4715,7 +4655,7 @@ void ujump_assemble(int i,struct regstat *i_regs) 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); + if(i_regmap[temp]==PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp); } #endif if(rt1[i]==31&&(rt1[i]==rs1[i+1]||rt1[i]==rs2[i+1])) { @@ -4750,7 +4690,7 @@ void ujump_assemble(int i,struct regstat *i_regs) ds_assemble_entry(i); } else { - add_to_linker((int)out,ba[i],internal_branch(branch_regs[i].is32,ba[i])); + add_to_linker(out,ba[i],internal_branch(branch_regs[i].is32,ba[i])); emit_jmp(0); } } @@ -4767,12 +4707,12 @@ static void rjump_assemble_write_ra(int i) #ifdef REG_PREFETCH if(temp>=0) { - if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp); + if(i_regmap[temp]!=PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp); } #endif emit_movimm(return_address,rt); // PC into link register #ifdef IMM_PREFETCH - emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); + emit_prefetch(hash_table_get(return_address)); #endif } @@ -4798,7 +4738,7 @@ void rjump_assemble(int i,struct regstat *i_regs) 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); + if(i_regmap[temp]==PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp); } } #endif @@ -4855,7 +4795,7 @@ void rjump_assemble(int i,struct regstat *i_regs) //if(adj) emit_addimm(cc,2*(ccadj[i]+2-adj),cc); // ??? - Shouldn't happen //assert(adj==0); emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG); - add_stub(CC_STUB,(int)out,jump_vaddr_reg[rs],0,i,-1,TAKEN,0); + add_stub(CC_STUB,out,jump_vaddr_reg[rs],0,i,-1,TAKEN,0); if(itype[i+1]==COP0&&(source[i+1]&0x3f)==0x10) // special case for RFE emit_jmp(0); @@ -4869,41 +4809,8 @@ void rjump_assemble(int i,struct regstat *i_regs) else #endif { - //if(rs!=EAX) emit_mov(rs,EAX); - //emit_jmp((int)jump_vaddr_eax); emit_jmp(jump_vaddr_reg[rs]); } - /* Check hash table - temp=!rs; - emit_mov(rs,temp); - emit_shrimm(rs,16,rs); - emit_xor(temp,rs,rs); - emit_movzwl_reg(rs,rs); - emit_shlimm(rs,4,rs); - emit_cmpmem_indexed((int)hash_table,rs,temp); - emit_jne((int)out+14); - emit_readword_indexed((int)hash_table+4,rs,rs); - emit_jmpreg(rs); - emit_cmpmem_indexed((int)hash_table+8,rs,temp); - emit_addimm_no_flags(8,rs); - emit_jeq((int)out-17); - // No hit on hash table, call compiler - emit_pushreg(temp); -//DEBUG > -#ifdef DEBUG_CYCLE_COUNT - emit_readword((int)&last_count,ECX); - emit_add(HOST_CCREG,ECX,HOST_CCREG); - emit_readword((int)&next_interupt,ECX); - emit_writeword(HOST_CCREG,(int)&Count); - emit_sub(HOST_CCREG,ECX,HOST_CCREG); - emit_writeword(ECX,(int)&last_count); -#endif -//DEBUG < - emit_storereg(CCREG,HOST_CCREG); - emit_call((int)get_addr); - emit_loadreg(CCREG,HOST_CCREG); - emit_addimm(ESP,4,ESP); - emit_jmpreg(EAX);*/ #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(rt1[i]!=31&&i=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); - nottaken1=(int)out; - emit_jne(1); + nottaken1=out; + emit_jne((void *)1l); } if(opcode[i]==5) // BNE { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); - if(invert) taken=(int)out; - else add_to_linker((int)out,ba[i],internal); + if(invert) taken=out; + else add_to_linker(out,ba[i],internal); emit_jne(0); } if(opcode[i]==6) // BLEZ { emit_test(s1h,s1h); - if(invert) taken=(int)out; - else add_to_linker((int)out,ba[i],internal); + if(invert) taken=out; + else add_to_linker(out,ba[i],internal); emit_js(0); - nottaken1=(int)out; - emit_jne(1); + nottaken1=out; + emit_jne((void *)1l); } if(opcode[i]==7) // BGTZ { emit_test(s1h,s1h); - nottaken1=(int)out; + nottaken1=out; emit_js(1); - if(invert) taken=(int)out; - else add_to_linker((int)out,ba[i],internal); + if(invert) taken=out; + else add_to_linker(out,ba[i],internal); emit_jne(0); } } // if(!only32) @@ -5062,10 +4969,10 @@ void cjump_assemble(int i,struct regstat *i_regs) if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); if(invert){ - nottaken=(int)out; - emit_jne(1); + nottaken=out; + emit_jne((void *)1l); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jeq(0); } } @@ -5074,10 +4981,10 @@ void cjump_assemble(int i,struct regstat *i_regs) if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); if(invert){ - nottaken=(int)out; + nottaken=out; emit_jeq(1); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jne(0); } } @@ -5085,10 +4992,10 @@ void cjump_assemble(int i,struct regstat *i_regs) { emit_cmpimm(s1l,1); if(invert){ - nottaken=(int)out; + nottaken=out; emit_jge(1); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jl(0); } } @@ -5096,23 +5003,23 @@ void cjump_assemble(int i,struct regstat *i_regs) { emit_cmpimm(s1l,1); if(invert){ - nottaken=(int)out; + nottaken=out; emit_jl(1); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jge(0); } } if(invert) { - if(taken) set_jump_target(taken,(int)out); + if(taken) set_jump_target(taken, out); #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(match&&(!internal||!is_ds[(ba[i]-start)>>2])) { if(adj) { emit_addimm(cc,-CLOCK_ADJUST(adj),cc); - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); }else{ emit_addnop(13); - add_to_linker((int)out,ba[i],internal*2); + add_to_linker(out,ba[i],internal*2); } emit_jmp(0); }else @@ -5129,14 +5036,14 @@ void cjump_assemble(int i,struct regstat *i_regs) ds_assemble_entry(i); } else { - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jmp(0); } } - set_jump_target(nottaken,(int)out); + set_jump_target(nottaken, out); } - if(nottaken1) set_jump_target(nottaken1,(int)out); + if(nottaken1) set_jump_target(nottaken1, out); if(adj) { if(!invert) emit_addimm(cc,CLOCK_ADJUST(adj),cc); } @@ -5148,7 +5055,7 @@ void cjump_assemble(int i,struct regstat *i_regs) //if(likely[i]) printf("IOL\n"); //else //printf("IOE\n"); - int taken=0,nottaken=0,nottaken1=0; + void *taken = NULL, *nottaken = NULL, *nottaken1 = NULL; if(!unconditional&&!nop) { if(!only32) { @@ -5157,31 +5064,31 @@ void cjump_assemble(int i,struct regstat *i_regs) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); - nottaken1=(int)out; - emit_jne(2); + nottaken1=out; + emit_jne((void *)2l); } if((opcode[i]&0x2f)==5) // BNE { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); - taken=(int)out; - emit_jne(1); + taken=out; + emit_jne((void *)1l); } if((opcode[i]&0x2f)==6) // BLEZ { emit_test(s1h,s1h); - taken=(int)out; + taken=out; emit_js(1); - nottaken1=(int)out; - emit_jne(2); + nottaken1=out; + emit_jne((void *)2l); } if((opcode[i]&0x2f)==7) // BGTZ { emit_test(s1h,s1h); - nottaken1=(int)out; + nottaken1=out; emit_js(2); - taken=(int)out; - emit_jne(1); + taken=out; + emit_jne((void *)1l); } } // if(!only32) @@ -5191,26 +5098,26 @@ void cjump_assemble(int i,struct regstat *i_regs) { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); - nottaken=(int)out; - emit_jne(2); + nottaken=out; + emit_jne((void *)2l); } if((opcode[i]&0x2f)==5) // BNE { if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); - nottaken=(int)out; + nottaken=out; emit_jeq(2); } if((opcode[i]&0x2f)==6) // BLEZ { emit_cmpimm(s1l,1); - nottaken=(int)out; + nottaken=out; emit_jge(2); } if((opcode[i]&0x2f)==7) // BGTZ { emit_cmpimm(s1l,1); - nottaken=(int)out; + nottaken=out; emit_jl(2); } } // if(!unconditional) @@ -5224,7 +5131,7 @@ void cjump_assemble(int i,struct regstat *i_regs) ds_unneeded_upper|=1; // branch taken if(!nop) { - if(taken) set_jump_target(taken,(int)out); + if(taken) set_jump_target(taken, out); assem_debug("1:\n"); wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, ds_unneeded,ds_unneeded_upper); @@ -5252,15 +5159,15 @@ void cjump_assemble(int i,struct regstat *i_regs) ds_assemble_entry(i); } else { - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jmp(0); } } // branch not taken cop1_usable=prev_cop1_usable; if(!unconditional) { - if(nottaken1) set_jump_target(nottaken1,(int)out); - set_jump_target(nottaken,(int)out); + if(nottaken1) set_jump_target(nottaken1, out); + set_jump_target(nottaken, out); assem_debug("2:\n"); if(!likely[i]) { wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, @@ -5275,18 +5182,18 @@ void cjump_assemble(int i,struct regstat *i_regs) // Cycle count isn't in a register, temporarily load it then write it out emit_loadreg(CCREG,HOST_CCREG); emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG); - int jaddr=(int)out; + void *jaddr=out; emit_jns(0); - add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); + add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0); emit_storereg(CCREG,HOST_CCREG); } else{ cc=get_reg(i_regmap,CCREG); assert(cc==HOST_CCREG); emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc); - int jaddr=(int)out; + void *jaddr=out; emit_jns(0); - add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); + add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); } } } @@ -5361,7 +5268,7 @@ void sjump_assemble(int i,struct regstat *i_regs) return_address=start+i*4+8; emit_movimm(return_address,rt); // PC into link register #ifdef IMM_PREFETCH - if(!nevertaken) emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); + if(!nevertaken) emit_prefetch(hash_table_get(return_address)); #endif } } @@ -5384,7 +5291,7 @@ void sjump_assemble(int i,struct regstat *i_regs) ds_assemble_entry(i); } else { - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jmp(0); } #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK @@ -5394,12 +5301,12 @@ void sjump_assemble(int i,struct regstat *i_regs) } else if(nevertaken) { emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc); - int jaddr=(int)out; + void *jaddr=out; emit_jns(0); - add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); + add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0); } else { - int nottaken=0; + void *nottaken = NULL; do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert); if(adj&&!invert) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc); if(!only32) @@ -5409,10 +5316,10 @@ void sjump_assemble(int i,struct regstat *i_regs) { emit_test(s1h,s1h); if(invert){ - nottaken=(int)out; + nottaken=out; emit_jns(1); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_js(0); } } @@ -5420,10 +5327,10 @@ void sjump_assemble(int i,struct regstat *i_regs) { emit_test(s1h,s1h); if(invert){ - nottaken=(int)out; + nottaken=out; emit_js(1); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jns(0); } } @@ -5435,10 +5342,10 @@ void sjump_assemble(int i,struct regstat *i_regs) { emit_test(s1l,s1l); if(invert){ - nottaken=(int)out; + nottaken=out; emit_jns(1); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_js(0); } } @@ -5446,10 +5353,10 @@ void sjump_assemble(int i,struct regstat *i_regs) { emit_test(s1l,s1l); if(invert){ - nottaken=(int)out; + nottaken=out; emit_js(1); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jns(0); } } @@ -5460,10 +5367,10 @@ void sjump_assemble(int i,struct regstat *i_regs) if(match&&(!internal||!is_ds[(ba[i]-start)>>2])) { if(adj) { emit_addimm(cc,-CLOCK_ADJUST(adj),cc); - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); }else{ emit_addnop(13); - add_to_linker((int)out,ba[i],internal*2); + add_to_linker(out,ba[i],internal*2); } emit_jmp(0); }else @@ -5480,11 +5387,11 @@ void sjump_assemble(int i,struct regstat *i_regs) ds_assemble_entry(i); } else { - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jmp(0); } } - set_jump_target(nottaken,(int)out); + set_jump_target(nottaken, out); } if(adj) { @@ -5496,7 +5403,7 @@ void sjump_assemble(int i,struct regstat *i_regs) { // In-order execution (branch first) //printf("IOE\n"); - int nottaken=0; + void *nottaken = NULL; if(rt1[i]==31) { int rt,return_address; rt=get_reg(branch_regs[i].regmap,31); @@ -5505,7 +5412,7 @@ void sjump_assemble(int i,struct regstat *i_regs) return_address=start+i*4+8; emit_movimm(return_address,rt); // PC into link register #ifdef IMM_PREFETCH - emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); + emit_prefetch(hash_table_get(return_address)); #endif } } @@ -5517,13 +5424,13 @@ void sjump_assemble(int i,struct regstat *i_regs) if((opcode2[i]&0x0d)==0) // BLTZ/BLTZL/BLTZAL/BLTZALL { emit_test(s1h,s1h); - nottaken=(int)out; + nottaken=out; emit_jns(1); } if((opcode2[i]&0x0d)==1) // BGEZ/BGEZL/BGEZAL/BGEZALL { emit_test(s1h,s1h); - nottaken=(int)out; + nottaken=out; emit_js(1); } } // if(!only32) @@ -5533,13 +5440,13 @@ void sjump_assemble(int i,struct regstat *i_regs) if((opcode2[i]&0x0d)==0) // BLTZ/BLTZL/BLTZAL/BLTZALL { emit_test(s1l,s1l); - nottaken=(int)out; + nottaken=out; emit_jns(1); } if((opcode2[i]&0x0d)==1) // BGEZ/BGEZL/BGEZAL/BGEZALL { emit_test(s1l,s1l); - nottaken=(int)out; + nottaken=out; emit_js(1); } } @@ -5581,14 +5488,14 @@ void sjump_assemble(int i,struct regstat *i_regs) ds_assemble_entry(i); } else { - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jmp(0); } } // branch not taken cop1_usable=prev_cop1_usable; if(!unconditional) { - set_jump_target(nottaken,(int)out); + set_jump_target(nottaken, out); assem_debug("1:\n"); if(!likely[i]) { wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, @@ -5603,18 +5510,18 @@ void sjump_assemble(int i,struct regstat *i_regs) // Cycle count isn't in a register, temporarily load it then write it out emit_loadreg(CCREG,HOST_CCREG); emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG); - int jaddr=(int)out; + void *jaddr=out; emit_jns(0); - add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); + add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0); emit_storereg(CCREG,HOST_CCREG); } else{ cc=get_reg(i_regmap,CCREG); assert(cc==HOST_CCREG); emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc); - int jaddr=(int)out; + void *jaddr=out; emit_jns(0); - add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); + add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); } } } @@ -5628,7 +5535,7 @@ void fjump_assemble(int i,struct regstat *i_regs) match=match_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]); assem_debug("fmatch=%d\n",match); int fs,cs; - int eaddr; + void *eaddr; int invert=0; int internal=internal_branch(branch_regs[i].is32,ba[i]); if(i==(ba[i]-start)>>2) assem_debug("idle loop\n"); @@ -5650,9 +5557,9 @@ void fjump_assemble(int i,struct regstat *i_regs) cs=get_reg(i_regmap,CSREG); assert(cs>=0); emit_testimm(cs,0x20000000); - eaddr=(int)out; + eaddr=out; emit_jeq(0); - add_stub(FP_STUB,eaddr,(int)out,i,cs,(int)i_regs,0,0); + add_stub_r(FP_STUB,eaddr,out,i,cs,i_regs,0,0); cop1_usable=1; } @@ -5676,7 +5583,7 @@ void fjump_assemble(int i,struct regstat *i_regs) do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert); assem_debug("cycle count (adj)\n"); if(1) { - int nottaken=0; + void *nottaken = NULL; if(adj&&!invert) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc); if(1) { assert(fs>=0); @@ -5684,19 +5591,19 @@ void fjump_assemble(int i,struct regstat *i_regs) if(source[i]&0x10000) // BC1T { if(invert){ - nottaken=(int)out; + nottaken=out; emit_jeq(1); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jne(0); } } else // BC1F if(invert){ - nottaken=(int)out; - emit_jne(1); + nottaken=out; + emit_jne((void *)1l); }else{ - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jeq(0); } { @@ -5718,10 +5625,10 @@ void fjump_assemble(int i,struct regstat *i_regs) ds_assemble_entry(i); } else { - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jmp(0); } - set_jump_target(nottaken,(int)out); + set_jump_target(nottaken, out); } if(adj) { @@ -5733,7 +5640,7 @@ void fjump_assemble(int i,struct regstat *i_regs) { // In-order execution (branch first) //printf("IOE\n"); - int nottaken=0; + void *nottaken = NULL; if(1) { //printf("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]); if(1) { @@ -5741,13 +5648,13 @@ void fjump_assemble(int i,struct regstat *i_regs) emit_testimm(fs,0x800000); if(source[i]&0x10000) // BC1T { - nottaken=(int)out; + nottaken=out; emit_jeq(1); } else // BC1F { - nottaken=(int)out; - emit_jne(1); + nottaken=out; + emit_jne((void *)1l); } } } // if(!unconditional) @@ -5787,13 +5694,13 @@ void fjump_assemble(int i,struct regstat *i_regs) ds_assemble_entry(i); } else { - add_to_linker((int)out,ba[i],internal); + add_to_linker(out,ba[i],internal); emit_jmp(0); } // branch not taken if(1) { // <- FIXME (don't need this) - set_jump_target(nottaken,(int)out); + set_jump_target(nottaken, out); assem_debug("1:\n"); if(!likely[i]) { wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32, @@ -5808,18 +5715,18 @@ void fjump_assemble(int i,struct regstat *i_regs) // Cycle count isn't in a register, temporarily load it then write it out emit_loadreg(CCREG,HOST_CCREG); emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG); - int jaddr=(int)out; + void *jaddr=out; emit_jns(0); - add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0); + add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0); emit_storereg(CCREG,HOST_CCREG); } else{ cc=get_reg(i_regmap,CCREG); assert(cc==HOST_CCREG); emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc); - int jaddr=(int)out; + void *jaddr=out; emit_jns(0); - add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); + add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0); } } } @@ -5831,8 +5738,8 @@ 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); - int taken=0; - int nottaken=0; + void *taken = NULL; + void *nottaken = NULL; int unconditional=0; if(rs1[i]==0) { @@ -5965,13 +5872,13 @@ static void pagespan_assemble(int i,struct regstat *i_regs) if(s1h>=0) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); - nottaken=(int)out; + nottaken=out; emit_jne(0); } if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); - if(nottaken) set_jump_target(nottaken,(int)out); - nottaken=(int)out; + if(nottaken) set_jump_target(nottaken, out); + nottaken=out; emit_jne(0); } if((opcode[i]&0x3f)==0x15) // BNEL @@ -5979,14 +5886,14 @@ static void pagespan_assemble(int i,struct regstat *i_regs) if(s1h>=0) { if(s2h>=0) emit_cmp(s1h,s2h); else emit_test(s1h,s1h); - taken=(int)out; + taken=out; emit_jne(0); } if(s2l>=0) emit_cmp(s1l,s2l); else emit_test(s1l,s1l); - nottaken=(int)out; + nottaken=out; emit_jeq(0); - if(taken) set_jump_target(taken,(int)out); + if(taken) set_jump_target(taken, out); } if((opcode[i]&0x3f)==6) // BLEZ { @@ -6039,13 +5946,13 @@ static void pagespan_assemble(int i,struct regstat *i_regs) if((source[i]&0x30000)==0x20000) // BC1FL { emit_testimm(s1l,0x800000); - nottaken=(int)out; + nottaken=out; emit_jne(0); } if((source[i]&0x30000)==0x30000) // BC1TL { emit_testimm(s1l,0x800000); - nottaken=(int)out; + nottaken=out; emit_jeq(0); } } @@ -6065,27 +5972,27 @@ static void pagespan_assemble(int i,struct regstat *i_regs) int target_addr=start+i*4+5; void *stub=out; void *compiled_target_addr=check_addr(target_addr); - emit_extjump_ds((int)branch_addr,target_addr); + emit_extjump_ds(branch_addr, target_addr); if(compiled_target_addr) { - set_jump_target((int)branch_addr,(int)compiled_target_addr); + set_jump_target(branch_addr, compiled_target_addr); add_link(target_addr,stub); } - else set_jump_target((int)branch_addr,(int)stub); + else set_jump_target(branch_addr, stub); if(likely[i]) { // Not-taken path - set_jump_target((int)nottaken,(int)out); + set_jump_target(nottaken, out); wb_dirtys(regs[i].regmap,regs[i].is32,regs[i].dirty); void *branch_addr=out; emit_jmp(0); int target_addr=start+i*4+8; void *stub=out; void *compiled_target_addr=check_addr(target_addr); - emit_extjump_ds((int)branch_addr,target_addr); + emit_extjump_ds(branch_addr, target_addr); if(compiled_target_addr) { - set_jump_target((int)branch_addr,(int)compiled_target_addr); + set_jump_target(branch_addr, compiled_target_addr); add_link(target_addr,stub); } - else set_jump_target((int)branch_addr,(int)stub); + else set_jump_target(branch_addr, stub); } } @@ -6103,7 +6010,7 @@ static void pagespan_ds() if(regs[0].regmap[HOST_CCREG]!=CCREG) wb_register(CCREG,regs[0].regmap_entry,regs[0].wasdirty,regs[0].was32); if(regs[0].regmap[HOST_BTREG]!=BTREG) - emit_writeword(HOST_BTREG,(int)&branch_target); + emit_writeword(HOST_BTREG,&branch_target); load_regs(regs[0].regmap_entry,regs[0].regmap,regs[0].was32,rs1[0],rs2[0]); address_generation(0,®s[0],regs[0].regmap_entry); if(itype[0]==STORE||itype[0]==STORELR||(opcode[0]&0x3b)==0x39||(opcode[0]&0x3b)==0x3a) @@ -6163,7 +6070,7 @@ static void pagespan_ds() int btaddr=get_reg(regs[0].regmap,BTREG); if(btaddr<0) { btaddr=get_reg(regs[0].regmap,-1); - emit_readword((int)&branch_target,btaddr); + emit_readword(&branch_target,btaddr); } assert(btaddr!=HOST_CCREG); if(regs[0].regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); @@ -6173,11 +6080,11 @@ static void pagespan_ds() #else emit_cmpimm(btaddr,start+4); #endif - int branch=(int)out; + void *branch = out; emit_jeq(0); store_regs_bt(regs[0].regmap,regs[0].is32,regs[0].dirty,-1); emit_jmp(jump_vaddr_reg[btaddr]); - set_jump_target(branch,(int)out); + set_jump_target(branch, out); store_regs_bt(regs[0].regmap,regs[0].is32,regs[0].dirty,start+4); load_regs_bt(regs[0].regmap,regs[0].is32,regs[0].dirty,start+4); } @@ -7015,7 +6922,7 @@ static int new_dynarec_test(void) SysPrintf("test passed.\n"); else SysPrintf("test failed: %08x\n", ret); - out=(u_char *)BASE_ADDR; + out = translation_cache; return ret == DRC_TEST_VAL; } @@ -7024,7 +6931,7 @@ static int new_dynarec_test(void) void new_dynarec_clear_full() { int n; - out=(u_char *)BASE_ADDR; + out = translation_cache; memset(invalid_code,1,sizeof(invalid_code)); memset(hash_table,0xff,sizeof(hash_table)); memset(mini_ht,-1,sizeof(mini_ht)); @@ -7049,7 +6956,7 @@ void new_dynarec_init() // allocate/prepare a buffer for translation cache // see assem_arm.h for some explanation #if defined(BASE_ADDR_FIXED) - if (mmap (translation_cache, 1 << TARGET_SIZE_2, + if (mmap(translation_cache, 1 << TARGET_SIZE_2, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) != translation_cache) { @@ -7077,11 +6984,11 @@ void new_dynarec_init() #else #ifndef NO_WRITE_EXEC // not all systems allow execute in data segment by default - if (mprotect((void *)BASE_ADDR, 1<next) { tmp_blocks[bcnt].addr = head->vaddr; @@ -7245,16 +7152,11 @@ int new_recompile_block(int addr) u_int state_rflags = 0; int i; - assem_debug("NOTCOMPILED: addr = %x -> %x\n", (int)addr, (int)out); - //printf("NOTCOMPILED: addr = %x -> %x\n", (int)addr, (int)out); + assem_debug("NOTCOMPILED: addr = %x -> %p\n", addr, out); //printf("TRACE: count=%d next=%d (compile %x)\n",Count,next_interupt,addr); //if(debug) //printf("TRACE: count=%d next=%d (checksum %x)\n",Count,next_interupt,mchecksum()); //printf("fpu mapping=%x enabled=%x\n",(Status & 0x04000000)>>26,(Status & 0x20000000)>>29); - /*if(Count>=312978186) { - rlist(); - }*/ - //rlist(); // this is just for speculation for (i = 1; i < 32; i++) { @@ -7273,8 +7175,8 @@ int new_recompile_block(int addr) invalid_code[start>>12]=0; emit_movimm(start,0); - emit_writeword(0,(int)&pcaddr); - emit_jmp((int)new_dyna_leave); + emit_writeword(0,&pcaddr); + emit_jmp(new_dyna_leave); literal_pool(0); end_block(beginning); ll_add_flags(jump_in+page,start,state_rflags,(void *)beginning); @@ -9918,27 +9820,19 @@ int new_recompile_block(int addr) if(regs[i].isconst) { printf("constants: "); #if defined(__i386__) || defined(__x86_64__) - if(regs[i].isconst&1) printf("eax=%x ",(int)constmap[i][0]); - if((regs[i].isconst>>1)&1) printf("ecx=%x ",(int)constmap[i][1]); - if((regs[i].isconst>>2)&1) printf("edx=%x ",(int)constmap[i][2]); - if((regs[i].isconst>>3)&1) printf("ebx=%x ",(int)constmap[i][3]); - if((regs[i].isconst>>5)&1) printf("ebp=%x ",(int)constmap[i][5]); - if((regs[i].isconst>>6)&1) printf("esi=%x ",(int)constmap[i][6]); - if((regs[i].isconst>>7)&1) printf("edi=%x ",(int)constmap[i][7]); + if(regs[i].isconst&1) printf("eax=%x ",(u_int)constmap[i][0]); + if((regs[i].isconst>>1)&1) printf("ecx=%x ",(u_int)constmap[i][1]); + if((regs[i].isconst>>2)&1) printf("edx=%x ",(u_int)constmap[i][2]); + if((regs[i].isconst>>3)&1) printf("ebx=%x ",(u_int)constmap[i][3]); + if((regs[i].isconst>>5)&1) printf("ebp=%x ",(u_int)constmap[i][5]); + if((regs[i].isconst>>6)&1) printf("esi=%x ",(u_int)constmap[i][6]); + if((regs[i].isconst>>7)&1) printf("edi=%x ",(u_int)constmap[i][7]); #endif #ifdef __arm__ - if(regs[i].isconst&1) printf("r0=%x ",(int)constmap[i][0]); - if((regs[i].isconst>>1)&1) printf("r1=%x ",(int)constmap[i][1]); - if((regs[i].isconst>>2)&1) printf("r2=%x ",(int)constmap[i][2]); - if((regs[i].isconst>>3)&1) printf("r3=%x ",(int)constmap[i][3]); - if((regs[i].isconst>>4)&1) printf("r4=%x ",(int)constmap[i][4]); - if((regs[i].isconst>>5)&1) printf("r5=%x ",(int)constmap[i][5]); - if((regs[i].isconst>>6)&1) printf("r6=%x ",(int)constmap[i][6]); - if((regs[i].isconst>>7)&1) printf("r7=%x ",(int)constmap[i][7]); - if((regs[i].isconst>>8)&1) printf("r8=%x ",(int)constmap[i][8]); - if((regs[i].isconst>>9)&1) printf("r9=%x ",(int)constmap[i][9]); - if((regs[i].isconst>>10)&1) printf("r10=%x ",(int)constmap[i][10]); - if((regs[i].isconst>>12)&1) printf("r12=%x ",(int)constmap[i][12]); + int r; + for (r = 0; r < ARRAY_SIZE(constmap[i]); r++) + if ((regs[i].isconst >> r) & 1) + printf(" r%d=%x", r, (u_int)constmap[i][r]); #endif printf("\n"); } @@ -9983,20 +9877,20 @@ int new_recompile_block(int addr) ds=1; pagespan_ds(); } - u_int instr_addr0_override=0; + void *instr_addr0_override = NULL; if (start == 0x80030000) { // nasty hack for fastbios thing // override block entry to this code - instr_addr0_override=(u_int)out; + instr_addr0_override = out; emit_movimm(start,0); // 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_readword(&address,1); + emit_writeword(0,&pcaddr); + emit_writeword(0,&address); emit_cmp(0,1); - emit_jne((int)new_dyna_leave); + emit_jne(new_dyna_leave); } for(i=0;i\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); @@ -10152,7 +10048,7 @@ int new_recompile_block(int addr) store_regs_bt(regs[i-2].regmap,regs[i-2].is32,regs[i-2].dirty,start+i*4); assert(regs[i-2].regmap[HOST_CCREG]==CCREG); } - add_to_linker((int)out,start+i*4,0); + add_to_linker(out,start+i*4,0); emit_jmp(0); } } @@ -10164,7 +10060,7 @@ int new_recompile_block(int addr) if(regs[i-1].regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i-1]+1),HOST_CCREG); - add_to_linker((int)out,start+i*4,0); + add_to_linker(out,start+i*4,0); emit_jmp(0); } @@ -10172,7 +10068,7 @@ int new_recompile_block(int addr) // Stubs for(i=0;i %8x\n",link_addr[i][0],link_addr[i][1]); + assem_debug("%p -> %8x\n",link_addr[i].addr,link_addr[i].target); literal_pool(64); - if(!link_addr[i][2]) + if (!link_addr[i].ext) { - void *stub=out; - void *addr=check_addr(link_addr[i][1]); - emit_extjump(link_addr[i][0],link_addr[i][1]); - if(addr) { - set_jump_target(link_addr[i][0],(int)addr); - add_link(link_addr[i][1],stub); + void *stub = out; + void *addr = check_addr(link_addr[i].target); + 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); } - else set_jump_target(link_addr[i][0],(int)stub); + else + set_jump_target(link_addr[i].addr, stub); } else { // Internal branch - int target=(link_addr[i][1]-start)>>2; + int target=(link_addr[i].target-start)>>2; assert(target>=0&&target>1); + //set_jump_target_fillslot(link_addr[i].addr,instr_addr[target],link_addr[i].ext>>1); //#else - set_jump_target(link_addr[i][0],instr_addr[target]); + set_jump_target(link_addr[i].addr, instr_addr[target]); //#endif } } @@ -10242,22 +10139,20 @@ int new_recompile_block(int addr) u_int vpage=get_vpage(vaddr); literal_pool(256); { - assem_debug("%8x (%d) <- %8x\n",instr_addr[i],i,start+i*4); + assem_debug("%p (%d) <- %8x\n",instr_addr[i],i,start+i*4); assem_debug("jump_in: %x\n",start+i*4); - ll_add(jump_dirty+vpage,vaddr,(void *)out); - int entry_point=do_dirty_stub(i); - ll_add_flags(jump_in+page,vaddr,state_rflags,(void *)entry_point); + ll_add(jump_dirty+vpage,vaddr,out); + void *entry_point = do_dirty_stub(i); + ll_add_flags(jump_in+page,vaddr,state_rflags,entry_point); // If there was an existing entry in the hash table, // replace it with the new address. // Don't add new entries. We'll insert the // ones that actually get used in check_addr(). - u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; - if(ht_bin[0]==vaddr) { - ht_bin[1]=entry_point; - } - if(ht_bin[2]==vaddr) { - ht_bin[3]=entry_point; - } + struct ht_entry *ht_bin = hash_table_get(vaddr); + if (ht_bin->vaddr[0] == vaddr) + ht_bin->tcaddr[0] = entry_point; + if (ht_bin->vaddr[1] == vaddr) + ht_bin->tcaddr[1] = entry_point; } } } @@ -10269,7 +10164,7 @@ int new_recompile_block(int addr) if(((u_int)out)&7) emit_addnop(13); #endif assert((u_int)out-(u_int)beginning(u_int)BASE_ADDR+(1< translation_cache+(1<>12;i<=(start+slen*4)>>12;i++) { @@ -10294,11 +10190,11 @@ int new_recompile_block(int addr) /* Pass 10 - Free memory by expiring oldest blocks */ - int end=((((int)out-(int)BASE_ADDR)>>(TARGET_SIZE_2-16))+16384)&65535; + int end=(((out-translation_cache)>>(TARGET_SIZE_2-16))+16384)&65535; while(expirep!=end) { int shift=TARGET_SIZE_2-3; // Divide into 8 blocks - int base=(int)BASE_ADDR+((expirep>>13)<>13)<>11)&3) { @@ -10317,18 +10213,20 @@ int new_recompile_block(int addr) case 2: // Clear hash table for(i=0;i<32;i++) { - u_int *ht_bin=hash_table[((expirep&2047)<<5)+i]; - if((ht_bin[3]>>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]); - ht_bin[2]=ht_bin[3]=-1; - } - if((ht_bin[1]>>shift)==(base>>shift) || - ((ht_bin[1]-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(base>>shift)) { - inv_debug("EXP: Remove hash %x -> %x\n",ht_bin[0],ht_bin[1]); - ht_bin[0]=ht_bin[2]; - ht_bin[1]=ht_bin[3]; - ht_bin[2]=ht_bin[3]=-1; + 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)) { + 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)) { + 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]; + ht_bin->vaddr[1] = -1; + ht_bin->tcaddr[1] = NULL; } } break;