X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fassem_arm.c;h=940391ce7e9cd812519f273cb59d5f6518314db3;hb=b14b6a8f0009d03d6051056a9dec699b82342f59;hp=9a5e3a94d451af98e97096d0fa44e4ea4b04dc68;hpb=581335b095ed820978d4c88f026abf462128eeb0;p=pcsx_rearmed.git diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index 9a5e3a94..940391ce 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -28,7 +28,10 @@ #include "pcnt.h" #include "arm_features.h" -#if !BASE_ADDR_FIXED +#if defined(BASE_ADDR_FIXED) +#elif defined(BASE_ADDR_DYNAMIC) +char *translation_cache; +#else char translation_cache[1 << TARGET_SIZE_2] __attribute__((aligned(4096))); #endif @@ -40,6 +43,12 @@ char translation_cache[1 << TARGET_SIZE_2] __attribute__((aligned(4096))); #define unused __attribute__((unused)) +#ifdef DRC_DBG +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#endif + extern int cycle_count; extern int last_count; extern int pcaddr; @@ -65,23 +74,24 @@ void jump_vaddr_r9(); void jump_vaddr_r10(); void jump_vaddr_r12(); -const u_int jump_vaddr_reg[16] = { - (int)jump_vaddr_r0, - (int)jump_vaddr_r1, - (int)jump_vaddr_r2, - (int)jump_vaddr_r3, - (int)jump_vaddr_r4, - (int)jump_vaddr_r5, - (int)jump_vaddr_r6, - (int)jump_vaddr_r7, - (int)jump_vaddr_r8, - (int)jump_vaddr_r9, - (int)jump_vaddr_r10, +void * const jump_vaddr_reg[16] = { + jump_vaddr_r0, + jump_vaddr_r1, + jump_vaddr_r2, + jump_vaddr_r3, + jump_vaddr_r4, + jump_vaddr_r5, + jump_vaddr_r6, + jump_vaddr_r7, + jump_vaddr_r8, + jump_vaddr_r9, + jump_vaddr_r10, 0, - (int)jump_vaddr_r12, + jump_vaddr_r12, 0, 0, - 0}; + 0 +}; void invalidate_addr_r0(); void invalidate_addr_r1(); @@ -114,30 +124,31 @@ const u_int invalidate_addr_reg[16] = { 0, 0}; -static unsigned int needs_clear_cache[1<<(TARGET_SIZE_2-17)]; +static u_int needs_clear_cache[1<<(TARGET_SIZE_2-17)]; /* Linker */ -static void set_jump_target(int addr,u_int target) +static void set_jump_target(void *addr, void *target_) { - u_char *ptr=(u_char *)addr; + u_int target = (u_int)target_; + u_char *ptr = addr; u_int *ptr2=(u_int *)ptr; if(ptr[3]==0xe2) { assert((target-(u_int)ptr2-8)<1024); - assert((addr&3)==0); + assert(((uintptr_t)addr&3)==0); assert((target&3)==0); *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>2)|0xF00; - //printf("target=%x addr=%x insn=%x\n",target,addr,*ptr2); + //printf("target=%x addr=%p insn=%x\n",target,addr,*ptr2); } else if(ptr[3]==0x72) { // generated by emit_jno_unlikely if((target-(u_int)ptr2-8)<1024) { - assert((addr&3)==0); + assert(((uintptr_t)addr&3)==0); assert((target&3)==0); *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>2)|0xF00; } else if((target-(u_int)ptr2-8)<4096&&!((target-(u_int)ptr2-8)&15)) { - assert((addr&3)==0); + assert(((uintptr_t)addr&3)==0); assert((target&3)==0); *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>4)|0xE00; } @@ -193,15 +204,15 @@ static void add_literal(int addr,int val) literalcount++; } -static void *kill_pointer(void *stub) +// from a pointer to external jump stub (which was produced by emit_extjump2) +// find where the jumping insn is +static void *find_extjump_insn(void *stub) { int *ptr=(int *)(stub+4); - assert((*ptr&0x0ff00000)==0x05900000); + assert((*ptr&0x0fff0000)==0x059f0000); // ldr rx, [pc, #ofs] u_int offset=*ptr&0xfff; - int **l_ptr=(void *)ptr+offset+8; - int *i_ptr=*l_ptr; - set_jump_target((int)i_ptr,(int)stub); - return i_ptr; + void **l_ptr=(void *)ptr+offset+8; + return *l_ptr; } // find where external branch is liked to using addr of it's stub: @@ -211,20 +222,16 @@ static void *kill_pointer(void *stub) static int get_pointer(void *stub) { //printf("get_pointer(%x)\n",(int)stub); - int *ptr=(int *)(stub+4); - assert((*ptr&0x0fff0000)==0x059f0000); - u_int offset=*ptr&0xfff; - int **l_ptr=(void *)ptr+offset+8; - int *i_ptr=*l_ptr; + int *i_ptr=find_extjump_insn(stub); assert((*i_ptr&0x0f000000)==0x0a000000); return (int)i_ptr+((*i_ptr<<8)>>6)+8; } // Find the "clean" entry point from a "dirty" entry point // by skipping past the call to verify_code -static u_int get_clean_addr(int addr) +static void *get_clean_addr(void *addr) { - int *ptr=(int *)addr; + signed int *ptr = addr; #ifndef HAVE_ARMV7 ptr+=4; #else @@ -234,22 +241,29 @@ static u_int get_clean_addr(int addr) assert((*ptr&0xFF000000)==0xeb000000); // bl instruction ptr++; if((*ptr&0xFF000000)==0xea000000) { - return (int)ptr+((*ptr<<8)>>6)+8; // follow jump + return (char *)ptr+((*ptr<<8)>>6)+8; // follow jump } - return (u_int)ptr; + return ptr; } static int verify_dirty(u_int *ptr) { #ifndef HAVE_ARMV7 + u_int offset; // get from literal pool assert((*ptr&0xFFFF0000)==0xe59f0000); - u_int offset=*ptr&0xfff; - u_int *l_ptr=(void *)ptr+offset+8; - u_int source=l_ptr[0]; - u_int copy=l_ptr[1]; - u_int len=l_ptr[2]; - ptr+=4; + offset=*ptr&0xfff; + u_int source=*(u_int*)((void *)ptr+offset+8); + ptr++; + assert((*ptr&0xFFFF0000)==0xe59f0000); + offset=*ptr&0xfff; + u_int copy=*(u_int*)((void *)ptr+offset+8); + ptr++; + assert((*ptr&0xFFFF0000)==0xe59f0000); + offset=*ptr&0xfff; + u_int len=*(u_int*)((void *)ptr+offset+8); + ptr++; + ptr++; #else // ARMv7 movw/movt assert((*ptr&0xFFF00000)==0xe3000000); @@ -266,7 +280,7 @@ static int verify_dirty(u_int *ptr) // This doesn't necessarily find all clean entry points, just // guarantees that it's not dirty -static int isclean(int addr) +static int isclean(void *addr) { #ifndef HAVE_ARMV7 u_int *ptr=((u_int *)addr)+4; @@ -286,14 +300,21 @@ static void get_bounds(int addr,u_int *start,u_int *end) { u_int *ptr=(u_int *)addr; #ifndef HAVE_ARMV7 + u_int offset; // get from literal pool assert((*ptr&0xFFFF0000)==0xe59f0000); - u_int offset=*ptr&0xfff; - u_int *l_ptr=(void *)ptr+offset+8; - u_int source=l_ptr[0]; - //u_int copy=l_ptr[1]; - u_int len=l_ptr[2]; - ptr+=4; + offset=*ptr&0xfff; + u_int source=*(u_int*)((void *)ptr+offset+8); + ptr++; + //assert((*ptr&0xFFFF0000)==0xe59f0000); + //offset=*ptr&0xfff; + //u_int copy=*(u_int*)((void *)ptr+offset+8); + ptr++; + assert((*ptr&0xFFFF0000)==0xe59f0000); + offset=*ptr&0xfff; + u_int len=*(u_int*)((void *)ptr+offset+8); + ptr++; + ptr++; #else // ARMv7 movw/movt assert((*ptr&0xFFF00000)==0xe3000000); @@ -1638,16 +1659,58 @@ static void emit_set_if_carry64_32(int u1, int l1, int u2, int l2, int rt) emit_cmovb_imm(1,rt); } +#ifdef DRC_DBG +extern void gen_interupt(); +extern void do_insn_cmp(); +#define FUNCNAME(f) { (intptr_t)f, " " #f } +static const struct { + intptr_t addr; + const char *name; +} function_names[] = { + FUNCNAME(cc_interrupt), + FUNCNAME(gen_interupt), + FUNCNAME(get_addr_ht), + FUNCNAME(get_addr), + FUNCNAME(jump_handler_read8), + FUNCNAME(jump_handler_read16), + FUNCNAME(jump_handler_read32), + FUNCNAME(jump_handler_write8), + FUNCNAME(jump_handler_write16), + FUNCNAME(jump_handler_write32), + FUNCNAME(invalidate_addr), + FUNCNAME(verify_code_vm), + FUNCNAME(verify_code), + FUNCNAME(jump_hlecall), + FUNCNAME(jump_syscall_hle), + FUNCNAME(new_dyna_leave), + FUNCNAME(pcsx_mtc0), + FUNCNAME(pcsx_mtc0_ds), + FUNCNAME(do_insn_cmp), +}; + +static const char *func_name(intptr_t a) +{ + int i; + for (i = 0; i < sizeof(function_names)/sizeof(function_names[0]); i++) + if (function_names[i].addr == a) + return function_names[i].name; + return ""; +} +#else +#define func_name(x) "" +#endif + static void emit_call(int a) { - assem_debug("bl %x (%x+%x)\n",a,(int)out,a-(int)out-8); + assem_debug("bl %x (%x+%x)%s\n",a,(int)out,a-(int)out-8,func_name(a)); u_int offset=genjmp(a); output_w32(0xeb000000|offset); } -static void emit_jmp(int a) +static void emit_jmp(const void *a_) { - assem_debug("b %x (%x+%x)\n",a,(int)out,a-(int)out-8); + int a = (int)a_; + assem_debug("b %x (%x+%x)%s\n",a,(int)out,a-(int)out-8,func_name(a)); u_int offset=genjmp(a); output_w32(0xea000000|offset); } @@ -1708,8 +1771,9 @@ static void emit_jc(int a) output_w32(0x2a000000|offset); } -static void emit_jcc(int a) +static void emit_jcc(void *a_) { + int a = (int)a_; assem_debug("bcc %x\n",a); u_int offset=genjmp(a); output_w32(0x3a000000|offset); @@ -2407,13 +2471,13 @@ static void literal_pool_jumpover(int n) if(n) { if((int)out-literals[0][0]<4096-n) return; } - int jaddr=(int)out; + void *jaddr = out; emit_jmp(0); literal_pool(0); - set_jump_target(jaddr,(int)out); + set_jump_target(jaddr, out); } -static void emit_extjump2(u_int addr, int target, int linker) +static void emit_extjump2(u_int addr, int target, void *linker) { u_char *ptr=(u_char *)addr; assert((ptr[3]&0x0e)==0xa); @@ -2438,12 +2502,12 @@ static void emit_extjump2(u_int addr, int target, int linker) static void emit_extjump(int addr, int target) { - emit_extjump2(addr, target, (int)dyna_linker); + emit_extjump2(addr, target, dyna_linker); } static void emit_extjump_ds(int addr, int target) { - emit_extjump2(addr, target, (int)dyna_linker_ds); + emit_extjump2(addr, target, dyna_linker_ds); } // put rt_val into rt, potentially making use of rs with value rs_val @@ -2507,7 +2571,7 @@ static void pass_args(int a0, int a1) } } -static void mov_loadtype_adj(int type,int rs,int rt) +static void mov_loadtype_adj(enum stub_type type,int rs,int rt) { switch(type) { case LOADB_STUB: emit_signextend8(rs,rt); break; @@ -2524,14 +2588,14 @@ static void mov_loadtype_adj(int type,int rs,int rt) static void do_readstub(int n) { - assem_debug("do_readstub %x\n",start+stubs[n][3]*4); + assem_debug("do_readstub %x\n",start+stubs[n].a*4); literal_pool(256); - set_jump_target(stubs[n][1],(int)out); - int type=stubs[n][0]; - int i=stubs[n][3]; - int rs=stubs[n][4]; - struct regstat *i_regs=(struct regstat *)stubs[n][5]; - u_int reglist=stubs[n][7]; + set_jump_target(stubs[n].addr, out); + enum stub_type type=stubs[n].type; + int i=stubs[n].a; + int rs=stubs[n].b; + struct regstat *i_regs=(struct regstat *)stubs[n].c; + u_int reglist=stubs[n].e; signed char *i_regmap=i_regs->regmap; int rt; if(itype[i]==C1LS||itype[i]==C2LS||itype[i]==LOADLR) { @@ -2540,7 +2604,8 @@ static void do_readstub(int n) rt=get_reg(i_regmap,rt1[i]); } assert(rs>=0); - int r,temp=-1,temp2=HOST_TEMPREG,regs_saved=0,restore_jump=0; + int r,temp=-1,temp2=HOST_TEMPREG,regs_saved=0; + void *restore_jump = NULL; reglist|=(1<=0&&rt1[i]!=0)) { mov_loadtype_adj(type,0,rt); } if(restore_jump) - set_jump_target(restore_jump,(int)out); + set_jump_target(restore_jump, out); restore_regs(reglist); - emit_jmp(stubs[n][2]); // return address + emit_jmp(stubs[n].retaddr); // return address } // return memhandler, or get directly accessable address and return 0 -static u_int get_direct_memhandler(void *table,u_int addr,int type,u_int *addr_host) +static u_int get_direct_memhandler(void *table,u_int addr,enum stub_type type,u_int *addr_host) { u_int l1,l2=0; l1=((u_int *)table)[addr>>12]; @@ -2628,7 +2694,7 @@ static u_int get_direct_memhandler(void *table,u_int addr,int type,u_int *addr_h } } -static void inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist) +static void inline_readstub(enum stub_type type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist) { int rs=get_reg(regmap,target); int rt=get_reg(regmap,target); @@ -2711,14 +2777,14 @@ static void inline_readstub(int type, int i, u_int addr, signed char regmap[], i static void do_writestub(int n) { - assem_debug("do_writestub %x\n",start+stubs[n][3]*4); + assem_debug("do_writestub %x\n",start+stubs[n].a*4); literal_pool(256); - set_jump_target(stubs[n][1],(int)out); - int type=stubs[n][0]; - int i=stubs[n][3]; - int rs=stubs[n][4]; - struct regstat *i_regs=(struct regstat *)stubs[n][5]; - u_int reglist=stubs[n][7]; + set_jump_target(stubs[n].addr, out); + enum stub_type type=stubs[n].type; + int i=stubs[n].a; + int rs=stubs[n].b; + struct regstat *i_regs=(struct regstat *)stubs[n].c; + u_int reglist=stubs[n].e; signed char *i_regmap=i_regs->regmap; int rt,r; if(itype[i]==C1LS||itype[i]==C2LS) { @@ -2728,7 +2794,8 @@ static void do_writestub(int n) } assert(rs>=0); assert(rt>=0); - int rtmp,temp=-1,temp2=HOST_TEMPREG,regs_saved=0,restore_jump=0,ra; + int rtmp,temp=-1,temp2=HOST_TEMPREG,regs_saved=0; + void *restore_jump = NULL; int reglist2=reglist|(1<regmap; int temp2=get_reg(i_regmap,FTEMP); int rt; @@ -2852,13 +2919,13 @@ static void do_unalignedwritestub(int n) int cc=get_reg(i_regmap,CCREG); if(cc<0) emit_loadreg(CCREG,2); - emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2); + emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n].d+1),2); emit_call((int)(opcode[i]==0x2a?jump_handle_swl:jump_handle_swr)); - emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc); + emit_addimm(0,-CLOCK_ADJUST((int)stubs[n].d+1),cc<0?2:cc); if(cc<0) emit_storereg(CCREG,2); restore_regs(reglist); - emit_jmp(stubs[n][2]); // return address + emit_jmp(stubs[n].retaddr); // return address #else emit_andimm(addr,0xfffffffc,temp2); emit_writeword(temp2,(int)&address); @@ -2870,7 +2937,7 @@ static void do_unalignedwritestub(int n) emit_loadreg(CCREG,2); } emit_movimm((u_int)readmem,0); - emit_addimm(cc<0?2:cc,2*stubs[n][6]+2,2); + emit_addimm(cc<0?2:cc,2*stubs[n].d+2,2); emit_call((int)&indirect_jump_indexed); restore_regs(reglist); @@ -2902,30 +2969,30 @@ static void do_unalignedwritestub(int n) emit_readword_dualindexedx4(0,1,15); emit_readword((int)&Count,HOST_TEMPREG); emit_readword((int)&next_interupt,2); - emit_addimm(HOST_TEMPREG,-2*stubs[n][6]-2,HOST_TEMPREG); + emit_addimm(HOST_TEMPREG,-2*stubs[n].d-2,HOST_TEMPREG); emit_writeword(2,(int)&last_count); emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc); if(cc<0) { emit_storereg(CCREG,HOST_TEMPREG); } restore_regs(reglist); - emit_jmp(stubs[n][2]); // return address + emit_jmp(stubs[n].retaddr); // return address #endif } static void do_invstub(int n) { literal_pool(20); - u_int reglist=stubs[n][3]; - set_jump_target(stubs[n][1],(int)out); + u_int reglist=stubs[n].a; + set_jump_target(stubs[n].addr, out); save_regs(reglist); - if(stubs[n][4]!=0) emit_mov(stubs[n][4],0); + if(stubs[n].b!=0) emit_mov(stubs[n].b,0); emit_call((int)&invalidate_addr); restore_regs(reglist); - emit_jmp(stubs[n][2]); // return address + emit_jmp(stubs[n].retaddr); // return address } -int do_dirty_stub(int i) +void *do_dirty_stub(int i) { assem_debug("do_dirty_stub %x\n",start+i*4); u_int addr=(u_int)source; @@ -2943,9 +3010,10 @@ int do_dirty_stub(int i) #endif emit_movimm(start+i*4,0); emit_call((int)start<(int)0xC0000000?(int)&verify_code:(int)&verify_code_vm); - int entry=(int)out; + void *entry = out; load_regs_entry(i); - if(entry==(int)out) entry=instr_addr[i]; + if (entry == out) + entry = instr_addr[i]; emit_jmp(instr_addr[i]); return entry; } @@ -2971,12 +3039,12 @@ static void do_dirty_stub_ds() static void do_cop1stub(int n) { literal_pool(256); - assem_debug("do_cop1stub %x\n",start+stubs[n][3]*4); - set_jump_target(stubs[n][1],(int)out); - int i=stubs[n][3]; -// int rs=stubs[n][4]; - struct regstat *i_regs=(struct regstat *)stubs[n][5]; - int ds=stubs[n][6]; + assem_debug("do_cop1stub %x\n",start+stubs[n].a*4); + set_jump_target(stubs[n].addr, out); + int i=stubs[n].a; +// int rs=stubs[n].b; + struct regstat *i_regs=(struct regstat *)stubs[n].c; + int ds=stubs[n].d; if(!ds) { load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i); //if(i_regs!=®s[i]) printf("oops: regs[i]=%x i_regs=%x",(int)®s[i],(int)i_regs); @@ -2986,7 +3054,7 @@ static void do_cop1stub(int n) if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_movimm(start+(i-ds)*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(ds?(int)fp_exception_ds:(int)fp_exception); + emit_jmp(ds?fp_exception_ds:fp_exception); } /* Special assem */ @@ -3219,9 +3287,10 @@ static int get_ptr_mem_type(u_int a) return MTYPE_8000; } -static int emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override) +static void *emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override) { - int jaddr=0,type=0; + void *jaddr = NULL; + int type=0; int mr=rs1[i]; if(((smrv_strong|smrv_weak)>>mr)&1) { type=get_ptr_mem_type(smrv[mr]); @@ -3252,7 +3321,7 @@ static int emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override) if (psxH == (void *)0x1f800000) { emit_addimm(addr,-0x1f800000,HOST_TEMPREG); emit_cmpimm(HOST_TEMPREG,0x1000); - jaddr=(int)out; + jaddr=out; emit_jc(0); } else { @@ -3264,7 +3333,7 @@ static int emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override) if(type==0) { emit_cmpimm(addr,RAM_SIZE); - jaddr=(int)out; + jaddr=out; #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK // Hint to branch predictor that the branch is unlikely to be taken if(rs1[i]>=28) @@ -3287,7 +3356,7 @@ static void loadlr_assemble_arm(int i,struct regstat *i_regs) { int s,th,tl,temp,temp2,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; @@ -3341,7 +3410,7 @@ static void loadlr_assemble_arm(int i,struct regstat *i_regs) if(fastload_reg_override) a=fastload_reg_override; //emit_readword_indexed((int)rdram-0x80000000,temp2,temp2); emit_readword_indexed_tlb(0,a,map,temp2); - if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist); + if(jaddr) add_stub_r(LOADW_STUB,jaddr,out,i,temp2,i_regs,ccadj[i],reglist); } else inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj[i],reglist); @@ -3373,7 +3442,7 @@ static void loadlr_assemble_arm(int i,struct regstat *i_regs) //if(th>=0) emit_readword_indexed((int)rdram-0x80000000,temp2,temp2h); //emit_readword_indexed((int)rdram-0x7FFFFFFC,temp2,temp2); emit_readdword_indexed_tlb(0,temp2,map,temp2h,temp2); - if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist); + if(jaddr) add_stub_r(LOADD_STUB,jaddr,out,i,temp2,i_regs,ccadj[i],reglist); } else inline_readstub(LOADD_STUB,i,(constmap[i][s]+offset)&0xFFFFFFF8,i_regs->regmap,FTEMP,ccadj[i],reglist); @@ -3811,9 +3880,9 @@ static void cop1_unusable(int i,struct regstat *i_regs) { // XXX: should just just do the exception instead if(!cop1_usable) { - int jaddr=(int)out; + void *jaddr=out; emit_jmp(0); - add_stub(FP_STUB,jaddr,(int)out,i,0,(int)i_regs,is_delayslot,0); + add_stub_r(FP_STUB,jaddr,out,i,0,i_regs,is_delayslot,0); cop1_usable=1; } } @@ -3909,7 +3978,7 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs) emit_subcs(remainder,HOST_TEMPREG,remainder); emit_adcs(quotient,quotient,quotient); emit_shrimm(HOST_TEMPREG,1,HOST_TEMPREG); - emit_jcc((int)out-16); // -4 + emit_jcc(out-16); // -4 emit_teq(d1,d2); emit_negmi(quotient,quotient); emit_test(d1,d1); @@ -3945,7 +4014,7 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs) emit_subcs(remainder,d2,remainder); emit_adcs(quotient,quotient,quotient); emit_shrcc_imm(d2,1,d2); - emit_jcc((int)out-16); // -4 + emit_jcc(out-16); // -4 } } else // 64-bit @@ -4094,6 +4163,17 @@ static void wb_invalidate_arm(signed char pre[],signed char entry[],uint64_t dir #define wb_invalidate wb_invalidate_arm */ +static void mark_clear_cache(void *target) +{ + u_long offset = (char *)target - (char *)BASE_ADDR; + u_int mask = 1u << ((offset >> 12) & 31); + if (!(needs_clear_cache[offset >> 17] & mask)) { + char *start = (char *)((u_long)target & ~4095ul); + start_tcache_write(start, start + 4096); + needs_clear_cache[offset >> 17] |= mask; + } +} + // Clearing the cache is rather slow on ARM Linux, so mark the areas // that need to be cleared, and then only clear these areas once. static void do_clear_cache() @@ -4115,7 +4195,7 @@ static void do_clear_cache() end+=4096; j++; }else{ - __clear_cache((void *)start,(void *)end); + end_tcache_write((void *)start,(void *)end); break; } }