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=8fe88fdc4c5553c5d4e694002d2f7dc4e617a705;hp=a88b396b25af320956be47e8f472587c975ec670;hb=57ab9898652b5e6fe6f790a5ca2bd17bf96936e8;hpb=a327ad27099341fb6eed61aa0419dff418429f96 diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index a88b396b..8fe88fdc 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -28,6 +28,7 @@ #include "../gte_neon.h" #include "pcnt.h" #endif +#include "arm_features.h" #if !BASE_ADDR_FIXED char translation_cache[1 << TARGET_SIZE_2] __attribute__((aligned(4096))); @@ -223,7 +224,7 @@ int get_pointer(void *stub) u_int get_clean_addr(int addr) { int *ptr=(int *)addr; - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 ptr+=4; #else ptr+=6; @@ -240,7 +241,7 @@ u_int get_clean_addr(int addr) int verify_dirty(int addr) { u_int *ptr=(u_int *)addr; - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 // get from literal pool assert((*ptr&0xFFFF0000)==0xe59f0000); u_int offset=*ptr&0xfff; @@ -279,7 +280,7 @@ int verify_dirty(int addr) // guarantees that it's not dirty int isclean(int addr) { - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 int *ptr=((u_int *)addr)+4; #else int *ptr=((u_int *)addr)+6; @@ -292,10 +293,11 @@ int isclean(int addr) return 1; } +// get source that block at addr was compiled from (host pointers) void get_bounds(int addr,u_int *start,u_int *end) { u_int *ptr=(u_int *)addr; - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 // get from literal pool assert((*ptr&0xFFFF0000)==0xe59f0000); u_int offset=*ptr&0xfff; @@ -491,7 +493,7 @@ void alloc_reg(struct regstat *cur,int i,signed char reg) } } } - printf("This shouldn't happen (alloc_reg)");exit(1); + SysPrintf("This shouldn't happen (alloc_reg)");exit(1); } void alloc_reg64(struct regstat *cur,int i,signed char reg) @@ -657,7 +659,7 @@ void alloc_reg64(struct regstat *cur,int i,signed char reg) } } } - printf("This shouldn't happen");exit(1); + SysPrintf("This shouldn't happen");exit(1); } // Allocate a temporary register. This is done without regard to @@ -780,7 +782,7 @@ void alloc_reg_temp(struct regstat *cur,int i,signed char reg) } } } - printf("This shouldn't happen");exit(1); + SysPrintf("This shouldn't happen");exit(1); } // Allocate a specific ARM register. void alloc_arm_reg(struct regstat *cur,int i,signed char reg,char hr) @@ -897,7 +899,7 @@ u_int genjmp(u_int addr) int offset=addr-(int)out-8; if(offset<-33554432||offset>=33554432) { if (addr>2) { - printf("genjmp: out of range: %08x\n", offset); + SysPrintf("genjmp: out of range: %08x\n", offset); exit(1); } return 0; @@ -1004,7 +1006,7 @@ void emit_movimm(u_int imm,u_int rt) assem_debug("mvn %s,#%d\n",regname[rt],imm); output_w32(0xe3e00000|rd_rn_rm(rt,0,0)|armval); }else if(imm<65536) { - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 assem_debug("mov %s,#%d\n",regname[rt],imm&0xFF00); output_w32(0xe3a00000|rd_rn_imm_shift(rt,0,imm>>8,8)); assem_debug("add %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF); @@ -1013,7 +1015,7 @@ void emit_movimm(u_int imm,u_int rt) emit_movw(imm,rt); #endif }else{ - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 emit_loadlp(imm,rt); #else emit_movw(imm&0x0000FFFF,rt); @@ -1031,7 +1033,7 @@ void emit_loadreg(int r, int hr) { #ifdef FORCE32 if(r&64) { - printf("64bit load in 32bit mode!\n"); + SysPrintf("64bit load in 32bit mode!\n"); assert(0); return; } @@ -1056,7 +1058,7 @@ void emit_storereg(int r, int hr) { #ifdef FORCE32 if(r&64) { - printf("64bit store in 32bit mode!\n"); + SysPrintf("64bit store in 32bit mode!\n"); assert(0); return; } @@ -1277,7 +1279,7 @@ void emit_andimm(int rs,int imm,int rt) assem_debug("bic %s,%s,#%d\n",regname[rt],regname[rs],imm); output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|armval); }else if(imm==65535) { - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 assem_debug("bic %s,%s,#FF000000\n",regname[rt],regname[rs]); output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|0x4FF); assem_debug("bic %s,%s,#00FF0000\n",regname[rt],regname[rt]); @@ -1288,7 +1290,7 @@ void emit_andimm(int rs,int imm,int rt) #endif }else{ assert(imm>0&&imm<65535); - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 assem_debug("mov r14,#%d\n",imm&0xFF00); output_w32(0xe3a00000|rd_rn_imm_shift(HOST_TEMPREG,0,imm>>8,8)); assem_debug("add r14,r14,#%d\n",imm&0xFF); @@ -1352,6 +1354,14 @@ void emit_lsls_imm(int rs,int imm,int rt) output_w32(0xe1b00000|rd_rn_rm(rt,0,rs)|(imm<<7)); } +void emit_lslpls_imm(int rs,int imm,int rt) +{ + assert(imm>0); + assert(imm<32); + assem_debug("lslpls %s,%s,#%d\n",regname[rt],regname[rs],imm); + output_w32(0x51b00000|rd_rn_rm(rt,0,rs)|(imm<<7)); +} + void emit_shrimm(int rs,u_int imm,int rt) { assert(imm>0); @@ -1402,7 +1412,7 @@ void emit_shrdimm(int rs,int rs2,u_int imm,int rt) void emit_signextend16(int rs,int rt) { - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 emit_shlimm(rs,16,rt); emit_sarimm(rt,16,rt); #else @@ -1413,7 +1423,7 @@ void emit_signextend16(int rs,int rt) void emit_signextend8(int rs,int rt) { - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 emit_shlimm(rs,24,rt); emit_sarimm(rt,24,rt); #else @@ -1501,20 +1511,12 @@ void emit_cmpimm(int rs,int imm) output_w32(0xe3700000|rd_rn_rm(0,rs,0)|armval); }else if(imm>0) { assert(imm<65536); - #ifdef ARMv5_ONLY emit_movimm(imm,HOST_TEMPREG); - #else - emit_movw(imm,HOST_TEMPREG); - #endif assem_debug("cmp %s,r14\n",regname[rs]); output_w32(0xe1500000|rd_rn_rm(0,rs,HOST_TEMPREG)); }else{ assert(imm>-65536); - #ifdef ARMv5_ONLY emit_movimm(-imm,HOST_TEMPREG); - #else - emit_movw(-imm,HOST_TEMPREG); - #endif assem_debug("cmn %s,r14\n",regname[rs]); output_w32(0xe1700000|rd_rn_rm(0,rs,HOST_TEMPREG)); } @@ -2294,7 +2296,7 @@ void emit_cmov2imm_e_ne_compact(int imm1,int imm2,u_int rt) output_w32(0x12400000|rd_rn_rm(rt,rt,0)|armval); } else { - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 emit_movimm(imm1,rt); add_literal((int)out,imm2); assem_debug("ldrne %s,pc+? [=%x]\n",regname[rt],imm2); @@ -2585,6 +2587,14 @@ void emit_andne_imm(int rs,int imm,int rt) output_w32(0x12000000|rd_rn_rm(rt,rs,0)|armval); } +void emit_addpl_imm(int rs,int imm,int rt) +{ + u_int armval; + genimm_checked(imm,&armval); + assem_debug("addpl %s,%s,#%d\n",regname[rt],regname[rs],imm); + output_w32(0x52800000|rd_rn_rm(rt,rs,0)|armval); +} + void emit_jno_unlikely(int a) { //emit_jno(a); @@ -2701,7 +2711,7 @@ void literal_pool_jumpover(int n) set_jump_target(jaddr,(int)out); } -emit_extjump2(int addr, int target, int linker) +emit_extjump2(u_int addr, int target, int linker) { u_char *ptr=(u_char *)addr; assert((ptr[3]&0x0e)==0xa); @@ -3278,7 +3288,7 @@ do_writestub(int n) emit_writeword(rt,(int)&dword); emit_writeword(r?rth:rt,(int)&dword+4); #else - printf("STORED_STUB\n"); + SysPrintf("STORED_STUB\n"); #endif } //emit_pusha(); @@ -3387,7 +3397,7 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, emit_writeword(rt,(int)&dword); emit_writeword(target?rth:rt,(int)&dword+4); #else - printf("STORED_STUB\n"); + SysPrintf("STORED_STUB\n"); #endif } //emit_pusha(); @@ -3564,7 +3574,7 @@ int do_dirty_stub(int i) addr=(u_int)source; #endif // Careful about the code output here, verify_dirty needs to parse it. - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 emit_loadlp(addr,1); emit_loadlp((int)copy,2); emit_loadlp(slen*4,3); @@ -3587,7 +3597,7 @@ int do_dirty_stub(int i) void do_dirty_stub_ds() { // Careful about the code output here, verify_dirty needs to parse it. - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 emit_loadlp((int)start<(int)0xC0000000?(int)source:(int)start,1); emit_loadlp((int)copy,2); emit_loadlp(slen*4,3); @@ -3710,12 +3720,12 @@ generate_map_const(u_int addr,int 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; } +static int do_tlb_r(int a, ...) { return 0; } +static int do_tlb_r_branch(int a, ...) { return 0; } +static int gen_tlb_addr_r(int a, ...) { return 0; } +static int do_tlb_w(int a, ...) { return 0; } +static int do_tlb_w_branch(int a, ...) { return 0; } +static int gen_tlb_addr_w(int a, ...) { return 0; } #endif // DISABLE_TLB @@ -4390,7 +4400,16 @@ static void cop2_put_dreg(u_int copr,signed char sl,signed char temp) case 30: emit_movs(sl,temp); emit_mvnmi(temp,temp); +#ifdef HAVE_ARMV5 emit_clz(temp,temp); +#else + emit_movs(temp,HOST_TEMPREG); + emit_movimm(0,temp); + emit_jeq((int)out+4*4); + emit_addpl_imm(temp,1,temp); + emit_lslpls_imm(HOST_TEMPREG,1,HOST_TEMPREG); + emit_jns((int)out-2*4); +#endif emit_writeword(sl,(int)®_cop2d[30]); emit_writeword(temp,(int)®_cop2d[31]); break; @@ -4513,6 +4532,7 @@ static void c2op_assemble(int i,struct regstat *i_regs) switch(c2op) { #ifndef DRC_DBG case GTE_MVMVA: { +#ifdef HAVE_ARMV5 int v = (source[i] >> 15) & 3; int cv = (source[i] >> 13) & 3; int mx = (source[i] >> 17) & 3; @@ -4551,6 +4571,12 @@ static void c2op_assemble(int i,struct regstat *i_regs) } if(need_flags||need_ir) c2op_call_MACtoIR(lm,need_flags); +#endif +#else /* if not HAVE_ARMV5 */ + c2op_prologue(c2op,reglist); + emit_movimm(source[i],1); // opcode + emit_writeword(1,(int)&psxRegs.code); + emit_call((int)(need_flags?gte_handlers[c2op]:gte_handlers_nf[c2op])); #endif break; } @@ -5291,9 +5317,16 @@ void multdiv_assemble_arm(int i,struct regstat *i_regs) emit_negmi(remainder,remainder); // .. remainder for div0 case (will be negated back after jump) emit_movs(d2,HOST_TEMPREG); emit_jeq((int)out+52); // Division by zero - emit_negmi(HOST_TEMPREG,HOST_TEMPREG); + emit_negsmi(HOST_TEMPREG,HOST_TEMPREG); +#ifdef HAVE_ARMV5 emit_clz(HOST_TEMPREG,quotient); emit_shl(HOST_TEMPREG,quotient,HOST_TEMPREG); +#else + emit_movimm(0,quotient); + emit_addpl_imm(quotient,1,quotient); + emit_lslpls_imm(HOST_TEMPREG,1,HOST_TEMPREG); + emit_jns((int)out-2*4); +#endif emit_orimm(quotient,1<<31,quotient); emit_shr(quotient,quotient,quotient); emit_cmp(remainder,HOST_TEMPREG); @@ -5320,9 +5353,17 @@ void multdiv_assemble_arm(int i,struct regstat *i_regs) emit_movimm(0xffffffff,quotient); // div0 case emit_test(d2,d2); emit_jeq((int)out+40); // Division by zero +#ifdef HAVE_ARMV5 emit_clz(d2,HOST_TEMPREG); emit_movimm(1<<31,quotient); emit_shl(d2,HOST_TEMPREG,d2); +#else + emit_movimm(0,HOST_TEMPREG); + emit_addpl_imm(HOST_TEMPREG,1,HOST_TEMPREG); + emit_lslpls_imm(d2,1,d2); + emit_jns((int)out-2*4); + emit_movimm(1<<31,quotient); +#endif emit_shr(quotient,HOST_TEMPREG,quotient); emit_cmp(remainder,d2); emit_subcs(remainder,d2,remainder); @@ -5553,7 +5594,7 @@ void do_miniht_jump(int rs,int rh,int ht) { } void do_miniht_insert(u_int return_address,int rt,int temp) { - #ifdef ARMv5_ONLY + #ifndef HAVE_ARMV7 emit_movimm(return_address,rt); // PC into link register add_to_linker((int)out,return_address,1); emit_pcreladdr(temp);