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=d0edaca63eeb26f6dc7a83fb47fd84355ff512b6;hp=57684cce10474fc25104556c3c24a7ec8e18c9ce;hb=cfcba99acf1ade6b95a69e8d04cc4cde9cd95d00;hpb=57871462a0b157066bbc4a763c59b61085436609 diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index 57684cce..d0edaca6 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -24,7 +24,9 @@ extern int pcaddr; extern int pending_exception; extern int branch_target; extern uint64_t readmem_dword; +#ifdef MUPEN64 extern precomp_instr fake_pc; +#endif extern void *dynarec_local; extern u_int memory_map[1048576]; extern u_int mini_ht[32][2]; @@ -203,7 +205,7 @@ int verify_dirty(int addr) #endif if((*ptr&0xFF000000)!=0xeb000000) ptr++; assert((*ptr&0xFF000000)==0xeb000000); // bl instruction - u_int verifier=(int)ptr+((*ptr<<8)>>6)+8; // get target of bl + 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; unsigned int map_value=memory_map[page]; @@ -256,7 +258,7 @@ void get_bounds(int addr,u_int *start,u_int *end) #endif if((*ptr&0xFF000000)!=0xeb000000) ptr++; assert((*ptr&0xFF000000)==0xeb000000); // bl instruction - u_int verifier=(int)ptr+((*ptr<<8)>>6)+8; // get target of bl + 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); @@ -824,7 +826,13 @@ u_int genimm(u_int imm,u_int *encoded) u_int genjmp(u_int addr) { int offset=addr-(int)out-8; - if(offset<-33554432||offset>=33554432) return 0; + if(offset<-33554432||offset>=33554432) { + if (addr>2) { + printf("genjmp: out of range: %08x\n", offset); + exit(1); + } + return 0; + } return ((u_int)offset>>2)&0xffffff; } @@ -902,10 +910,16 @@ void emit_zeroreg(int rt) void emit_loadreg(int r, int hr) { +#ifdef FORCE32 + if(r&64) { + printf("64bit load in 32bit mode!\n"); + exit(1); + } +#endif if((r&63)==0) emit_zeroreg(hr); else { - int addr=((int)reg)+((r&63)<<3)+((r&64)>>4); + int addr=((int)reg)+((r&63)<>4); if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4); if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4); if(r==CCREG) addr=(int)&cycle_count; @@ -920,7 +934,13 @@ void emit_loadreg(int r, int hr) } void emit_storereg(int r, int hr) { - int addr=((int)reg)+((r&63)<<3)+((r&64)>>4); +#ifdef FORCE32 + if(r&64) { + printf("64bit store in 32bit mode!\n"); + exit(1); + } +#endif + int addr=((int)reg)+((r&63)<>4); if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4); if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4); if(r==CCREG) addr=(int)&cycle_count; @@ -2396,10 +2416,12 @@ void wb_consts(signed char i_regmap[],uint64_t i_is32,u_int i_dirty,int i) emit_movimm(value,HOST_TEMPREG); } emit_storereg(i_regmap[hr],HOST_TEMPREG); +#ifndef FORCE32 if((i_is32>>i_regmap[hr])&1) { if(value!=-1&&value!=0) emit_sarimm(HOST_TEMPREG,31,HOST_TEMPREG); emit_storereg(i_regmap[hr]|64,HOST_TEMPREG); } +#endif } } } @@ -2446,7 +2468,7 @@ emit_extjump2(int addr, int target, int linker) assert((ptr[3]&0x0e)==0xa); emit_loadlp(target,0); emit_loadlp(addr,1); - assert(addr>=0x7000000&&addr<0x7FFFFFF); + assert(addr>=BASE_ADDR&&addr<(BASE_ADDR+(1<=0x80000000&&target<0x80800000)||(target>0xA4000000&&target<0xA4001000)); //DEBUG > #ifdef DEBUG_CYCLE_COUNT @@ -2502,8 +2524,11 @@ do_readstub(int n) ftable=(int)readmemh; if(type==LOADW_STUB) ftable=(int)readmem; +#ifndef FORCE32 if(type==LOADD_STUB) ftable=(int)readmemd; +#endif + assert(ftable!=0); emit_writeword(rs,(int)&address); //emit_pusha(); save_regs(reglist); @@ -2574,8 +2599,11 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i ftable=(int)readmemh; if(type==LOADW_STUB) ftable=(int)readmem; +#ifndef FORCE32 if(type==LOADD_STUB) ftable=(int)readmemd; +#endif + assert(ftable!=0); emit_writeword(rs,(int)&address); //emit_pusha(); save_regs(reglist); @@ -2657,8 +2685,11 @@ do_writestub(int n) ftable=(int)writememh; if(type==STOREW_STUB) ftable=(int)writemem; +#ifndef FORCE32 if(type==STORED_STUB) ftable=(int)writememd; +#endif + assert(ftable!=0); emit_writeword(rs,(int)&address); //emit_shrimm(rs,16,rs); //emit_movmem_indexedx4(ftable,rs,rs); @@ -2669,8 +2700,12 @@ do_writestub(int n) if(type==STOREW_STUB) emit_writeword(rt,(int)&word); if(type==STORED_STUB) { +#ifndef FORCE32 emit_writeword(rt,(int)&dword); emit_writeword(r?rth:rt,(int)&dword+4); +#else + printf("STORED_STUB\n"); +#endif } //emit_pusha(); save_regs(reglist); @@ -2724,8 +2759,11 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, ftable=(int)writememh; if(type==STOREW_STUB) ftable=(int)writemem; +#ifndef FORCE32 if(type==STORED_STUB) ftable=(int)writememd; +#endif + assert(ftable!=0); emit_writeword(rs,(int)&address); //emit_shrimm(rs,16,rs); //emit_movmem_indexedx4(ftable,rs,rs); @@ -2736,8 +2774,12 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, if(type==STOREW_STUB) emit_writeword(rt,(int)&word); if(type==STORED_STUB) { +#ifndef FORCE32 emit_writeword(rt,(int)&dword); emit_writeword(target?rth:rt,(int)&dword+4); +#else + printf("STORED_STUB\n"); +#endif } //emit_pusha(); save_regs(reglist); @@ -2843,7 +2885,7 @@ do_cop1stub(int n) 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]; +// int rs=stubs[n][4]; struct regstat *i_regs=(struct regstat *)stubs[n][5]; int ds=stubs[n][6]; if(!ds) { @@ -3194,10 +3236,12 @@ void cop0_assemble(int i,struct regstat *i_regs) char copr=(source[i]>>11)&0x1f; //assert(t>=0); // Why does this happen? OOT is weird if(t>=0) { +#ifdef MUPEN64 /// FIXME 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)); +#endif if(copr==9) { emit_readword((int)&last_count,ECX); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc @@ -3216,10 +3260,12 @@ void cop0_assemble(int i,struct regstat *i_regs) assert(s>=0); emit_writeword(s,(int)&readmem_dword); wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->is32); +#ifdef MUPEN64 /// FIXME 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)); +#endif if(copr==9||copr==11||copr==12) { emit_readword((int)&last_count,ECX); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc @@ -3264,6 +3310,7 @@ void cop0_assemble(int i,struct regstat *i_regs) else { assert(opcode2[i]==0x10); +#ifndef DISABLE_TLB if((source[i]&0x3f)==0x01) // TLBR emit_call((int)TLBR); if((source[i]&0x3f)==0x02) // TLBWI @@ -3280,6 +3327,7 @@ void cop0_assemble(int i,struct regstat *i_regs) } if((source[i]&0x3f)==0x08) // TLBP emit_call((int)TLBP); +#endif if((source[i]&0x3f)==0x18) // ERET { int count=ccadj[i]; @@ -3290,8 +3338,20 @@ void cop0_assemble(int i,struct regstat *i_regs) } } +void cop1_unusable(int i, struct regstat *i_regs) +{ + // XXX: should just just do the exception instead + if(!cop1_usable) { + int jaddr=(int)out; + emit_jmp(0); + add_stub(FP_STUB,jaddr,(int)out,i,0,(int)i_regs,is_delayslot,0); + cop1_usable=1; + } +} + void cop1_assemble(int i,struct regstat *i_regs) { +#ifndef DISABLE_COP1 // Check cop1 unusable if(!cop1_usable) { signed char rs=get_reg(i_regs->regmap,CSREG); @@ -3356,10 +3416,14 @@ void cop1_assemble(int i,struct regstat *i_regs) //emit_fldcw_indexed((int)&rounding_modes,temp); } } +#else + cop1_unusable(i, i_regs); +#endif } void fconv_assemble_arm(int i,struct regstat *i_regs) { +#ifndef DISABLE_COP1 signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); // Check cop1 unusable @@ -3572,11 +3636,15 @@ void fconv_assemble_arm(int i,struct regstat *i_regs) } restore_regs(reglist); +#else + cop1_unusable(i, i_regs); +#endif } #define fconv_assemble fconv_assemble_arm void fcomp_assemble(int i,struct regstat *i_regs) { +#ifndef DISABLE_COP1 signed char fs=get_reg(i_regs->regmap,FSREG); signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); @@ -3701,10 +3769,14 @@ void fcomp_assemble(int i,struct regstat *i_regs) } restore_regs(reglist); emit_loadreg(FSREG,fs); +#else + cop1_unusable(i, i_regs); +#endif } void float_assemble(int i,struct regstat *i_regs) { +#ifndef DISABLE_COP1 signed char temp=get_reg(i_regs->regmap,-1); assert(temp>=0); // Check cop1 unusable @@ -3894,6 +3966,9 @@ void float_assemble(int i,struct regstat *i_regs) } restore_regs(reglist); } +#else + cop1_unusable(i, i_regs); +#endif } void multdiv_assemble_arm(int i,struct regstat *i_regs) @@ -4227,6 +4302,7 @@ void do_miniht_insert(u_int return_address,int rt,int temp) { // as a 64-bit value later. void wb_sx(signed char pre[],signed char entry[],uint64_t dirty,uint64_t is32_pre,uint64_t is32,uint64_t u,uint64_t uu) { +#ifndef FORCE32 if(is32_pre==is32) return; int hr,reg; for(hr=0;hr