X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fassem_arm.c;h=93dbf922681f7ceaaf271c08307149df6fb957e0;hp=e29f6c3f9a9d770281f6b0c5cc9f60d86e412e32;hb=2573466affd06edebd68070bf167a62ca764f2b4;hpb=ffb0b9e0f051789f97f5efdcfab0b261e62688f9 diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index e29f6c3f..93dbf922 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -245,6 +245,7 @@ int verify_dirty(int addr) #endif if((*ptr&0xFF000000)!=0xeb000000) ptr++; assert((*ptr&0xFF000000)==0xeb000000); // bl instruction +#ifndef DISABLE_TLB u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) { unsigned int page=source>>12; @@ -255,6 +256,7 @@ int verify_dirty(int addr) } source = source+(map_value<<2); } +#endif //printf("verify_dirty: %x %x %x\n",source,copy,len); return !memcmp((void *)source,(void *)copy,len); } @@ -298,11 +300,13 @@ void get_bounds(int addr,u_int *start,u_int *end) #endif if((*ptr&0xFF000000)!=0xeb000000) ptr++; assert((*ptr&0xFF000000)==0xeb000000); // bl instruction +#ifndef DISABLE_TLB u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) { if(memory_map[source>>12]>=0x80000000) source = 0; else source = source+(memory_map[source>>12]<<2); } +#endif *start=source; *end=source+len; } @@ -2677,9 +2681,18 @@ emit_extjump_ds(int addr, int target) emit_extjump2(addr, target, (int)dyna_linker_ds); } -#ifdef PCSX -#include "pcsxmem_inline.c" -#endif +// put rt_val into rt, potentially making use of rs with value rs_val +static void emit_movimm_from(u_int rs_val,int rs,u_int rt_val,int rt) +{ + u_int xor=rs_val^rt_val; + u_int xs; + for(xs=xor;xs!=0&&(xs&3)==0;xs>>=2) + ; + if(xs<0x100) + emit_xorimm(rs,xor,rt); + else + emit_movimm(rt_val,rt); +} // trashes r2 static void pass_args(int a0, int a1) @@ -2771,7 +2784,7 @@ do_readstub(int n) int cc=get_reg(i_regmap,CCREG); if(cc<0) emit_loadreg(CCREG,2); - emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*stubs[n][6]+2,2); + emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2); emit_call(handler); if(itype[i]==C1LS||itype[i]==C2LS||(rt>=0&&rt1[i]!=0)) { switch(type) { @@ -2906,14 +2919,12 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i assert(rs>=0); #ifdef PCSX u_int handler,host_addr=0; - if(pcsx_direct_read(type,addr,target?rs:-1,rt)) - return; handler=get_direct_memhandler(mem_rtab,addr,type,&host_addr); if (handler==0) { if(rt<0) return; - if(target==0||addr!=host_addr) - emit_movimm(host_addr,rs); + if(addr!=host_addr) + emit_movimm_from(addr,rs,host_addr,rs); switch(type) { case LOADB_STUB: emit_movsbl_indexed(0,rs,rt); break; case LOADBU_STUB: emit_movzbl_indexed(0,rs,rt); break; @@ -2937,7 +2948,7 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i if(cc<0) emit_loadreg(CCREG,2); emit_readword((int)&last_count,3); - emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2); + emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2); emit_add(2,3,3); emit_writeword(3,(int)&Count); @@ -2998,7 +3009,7 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i //emit_movimm(ftable,0); emit_movimm(((u_int *)ftable)[addr>>16],0); //emit_readword((int)&last_count,12); - emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2); + emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2); #ifndef PCSX if((signed int)addr>=(signed int)0xC0000000) { // Pagefault address @@ -3015,7 +3026,7 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i // but not doing so causes random crashes... emit_readword((int)&Count,HOST_TEMPREG); emit_readword((int)&next_interupt,2); - emit_addimm(HOST_TEMPREG,-CLOCK_DIVIDER*(adj+1),HOST_TEMPREG); + emit_addimm(HOST_TEMPREG,-CLOCK_ADJUST(adj+1),HOST_TEMPREG); emit_writeword(2,(int)&last_count); emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc); if(cc<0) { @@ -3115,10 +3126,10 @@ do_writestub(int n) int cc=get_reg(i_regmap,CCREG); if(cc<0) emit_loadreg(CCREG,2); - emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*stubs[n][6]+2,2); + emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2); // returns new cycle_count emit_call(handler); - emit_addimm(0,-CLOCK_DIVIDER*stubs[n][6]-2,cc<0?2:cc); + emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc); if(cc<0) emit_storereg(CCREG,2); if(restore_jump) @@ -3211,12 +3222,10 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, assert(rt>=0); #ifdef PCSX u_int handler,host_addr=0; - if(pcsx_direct_write(type,addr,rs,rt,regmap)) - return; handler=get_direct_memhandler(mem_wtab,addr,type,&host_addr); if (handler==0) { - if(target==0||addr!=host_addr) - emit_movimm(host_addr,rs); + if(addr!=host_addr) + emit_movimm_from(addr,rs,host_addr,rs); switch(type) { case STOREB_STUB: emit_writebyte_indexed(rt,0,rs); break; case STOREH_STUB: emit_writehword_indexed(rt,0,rs); break; @@ -3228,17 +3237,15 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, // call a memhandler save_regs(reglist); - pass_args(target!=0?rs:-1,rt); - if(target==0) - emit_movimm(addr,0); + pass_args(rs,rt); int cc=get_reg(regmap,CCREG); if(cc<0) emit_loadreg(CCREG,2); - emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2); + emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2); emit_movimm(handler,3); // returns new cycle_count emit_call((int)jump_handler_write_h); - emit_addimm(0,-CLOCK_DIVIDER*(adj+1),cc<0?2:cc); + emit_addimm(0,-CLOCK_ADJUST(adj+1),cc<0?2:cc); if(cc<0) emit_storereg(CCREG,2); restore_regs(reglist); @@ -3295,7 +3302,7 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, //emit_movimm(ftable,0); emit_movimm(((u_int *)ftable)[addr>>16],0); //emit_readword((int)&last_count,12); - emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2); + emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2); #ifndef PCSX if((signed int)addr>=(signed int)0xC0000000) { // Pagefault address @@ -3309,7 +3316,7 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, emit_call((int)&indirect_jump); emit_readword((int)&Count,HOST_TEMPREG); emit_readword((int)&next_interupt,2); - emit_addimm(HOST_TEMPREG,-CLOCK_DIVIDER*(adj+1),HOST_TEMPREG); + emit_addimm(HOST_TEMPREG,-CLOCK_ADJUST(adj+1),HOST_TEMPREG); emit_writeword(2,(int)&last_count); emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc); if(cc<0) { @@ -3348,9 +3355,9 @@ 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_DIVIDER*stubs[n][6]+2,2); + emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2); emit_call((int)(opcode[i]==0x2a?jump_handle_swl:jump_handle_swr)); - emit_addimm(0,-CLOCK_DIVIDER*stubs[n][6]-2,cc<0?2:cc); + emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc); if(cc<0) emit_storereg(CCREG,2); restore_regs(reglist); @@ -3501,10 +3508,12 @@ do_cop1stub(int n) wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty); 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_DIVIDER*ccadj[i],HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle... + 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); } +#ifndef DISABLE_TLB + /* TLB */ int do_tlb_r(int s,int ar,int map,int x,int a,int shift,int c,u_int addr) @@ -3588,6 +3597,17 @@ generate_map_const(u_int addr,int reg) { emit_movimm((addr>>12)+(((u_int)memory_map-(u_int)&dynarec_local)>>2),reg); } +#else + +static int do_tlb_r() { return 0; } +static int do_tlb_r_branch() { return 0; } +static int gen_tlb_addr_r() { return 0; } +static int do_tlb_w() { return 0; } +static int do_tlb_w_branch() { return 0; } +static int gen_tlb_addr_w() { return 0; } + +#endif // DISABLE_TLB + /* Special assem */ void shift_assemble_arm(int i,struct regstat *i_regs) @@ -4043,7 +4063,7 @@ void cop0_assemble(int i,struct regstat *i_regs) emit_readword((int)&last_count,ECX); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc emit_add(HOST_CCREG,ECX,HOST_CCREG); - emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); + emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); emit_writeword(HOST_CCREG,(int)&Count); } emit_call((int)MFC0); @@ -4058,19 +4078,21 @@ void cop0_assemble(int i,struct regstat *i_regs) signed char s=get_reg(i_regs->regmap,rs1[i]); char copr=(source[i]>>11)&0x1f; assert(s>=0); +#ifdef MUPEN64 emit_writeword(s,(int)&readmem_dword); wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->is32); -#ifdef MUPEN64 emit_addimm(FP,(int)&fake_pc-(int)&dynarec_local,0); emit_movimm((source[i]>>11)&0x1f,1); emit_writeword(0,(int)&PC); emit_writebyte(1,(int)&(fake_pc.f.r.nrd)); +#else + wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->is32); #endif if(copr==9||copr==11||copr==12||copr==13) { - emit_readword((int)&last_count,ECX); + emit_readword((int)&last_count,HOST_TEMPREG); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc - emit_add(HOST_CCREG,ECX,HOST_CCREG); - emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); + emit_add(HOST_CCREG,HOST_TEMPREG,HOST_CCREG); + emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); emit_writeword(HOST_CCREG,(int)&Count); } // What a mess. The status register (12) can enable interrupts, @@ -4086,19 +4108,23 @@ void cop0_assemble(int i,struct regstat *i_regs) emit_writeword(HOST_CCREG,(int)&last_count); emit_movimm(0,HOST_CCREG); emit_storereg(CCREG,HOST_CCREG); + if(s!=1) + emit_mov(s,1); emit_movimm(copr,0); emit_call((int)pcsx_mtc0_ds); return; } #endif - emit_movimm(start+i*4+4,0); - emit_movimm(0,1); - emit_writeword(0,(int)&pcaddr); - emit_writeword(1,(int)&pending_exception); + emit_movimm(start+i*4+4,HOST_TEMPREG); + emit_writeword(HOST_TEMPREG,(int)&pcaddr); + emit_movimm(0,HOST_TEMPREG); + emit_writeword(HOST_TEMPREG,(int)&pending_exception); } //else if(copr==12&&is_delayslot) emit_call((int)MTC0_R12); //else #ifdef PCSX + if(s!=1) + emit_mov(s,1); emit_movimm(copr,0); emit_call((int)pcsx_mtc0); #else @@ -4107,7 +4133,7 @@ void cop0_assemble(int i,struct regstat *i_regs) if(copr==9||copr==11||copr==12||copr==13) { emit_readword((int)&Count,HOST_CCREG); emit_readword((int)&next_interupt,ECX); - emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*ccadj[i],HOST_CCREG); + emit_addimm(HOST_CCREG,-CLOCK_ADJUST(ccadj[i]),HOST_CCREG); emit_sub(HOST_CCREG,ECX,HOST_CCREG); emit_writeword(ECX,(int)&last_count); emit_storereg(CCREG,HOST_CCREG); @@ -4139,7 +4165,7 @@ void cop0_assemble(int i,struct regstat *i_regs) emit_readword((int)&last_count,ECX); if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); emit_add(HOST_CCREG,ECX,HOST_CCREG); - emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); + emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); emit_writeword(HOST_CCREG,(int)&Count); emit_call((int)TLBWR_new); } @@ -4160,7 +4186,7 @@ void cop0_assemble(int i,struct regstat *i_regs) { int count=ccadj[i]; if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); - emit_addimm(HOST_CCREG,CLOCK_DIVIDER*count,HOST_CCREG); // TODO: Should there be an extra cycle here? + emit_addimm(HOST_CCREG,CLOCK_ADJUST(count),HOST_CCREG); // TODO: Should there be an extra cycle here? emit_jmp((int)jump_eret); } #endif