X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fnew_dynarec.c;h=1383b2f55f9894ad29c555178e8b54ac21d23ab1;hb=687b45804b5c028dd5644bda85981c0235eb4d32;hp=987892f0b96c5a26cb23fd2382e63bbd38c7fb25;hpb=8062d65a99a541d3092672655e11cb2babfe3857;p=pcsx_rearmed.git diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 987892f0..1383b2f5 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -57,6 +57,9 @@ static int sceBlock; #ifdef __arm__ #include "assem_arm.h" #endif +#ifdef __aarch64__ +#include "assem_arm64.h" +#endif #define MAXBLOCK 4096 #define MAX_OUTPUT_BLOCK_SIZE 262144 @@ -195,8 +198,14 @@ struct link_entry int new_dynarec_hacks; int new_dynarec_did_compile; + + extern int cycle_count; // ... until end of the timeslice, counts -N -> 0 + extern int last_count; // last absolute target, often = next_interupt + extern int pcaddr; + extern int pending_exception; + extern int branch_target; + extern u_int mini_ht[32][2]; extern u_char restore_candidate[512]; - extern int cycle_count; /* registers that may be allocated */ /* 1-31 gpr */ @@ -296,6 +305,9 @@ 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 *emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override); +static void *get_direct_memhandler(void *table, u_int addr, + enum stub_type type, uintptr_t *addr_host); +static void pass_args(int a0, int a1); static void mprotect_w_x(void *start, void *end, int is_x) { @@ -338,6 +350,8 @@ static void end_tcache_write(void *start, void *end) __clear_cache(start, end); #endif (void)len; +#else + __clear_cache(start, end); #endif mprotect_w_x(start, end, 1); @@ -834,6 +848,9 @@ static const char *func_name(intptr_t a) #ifdef __arm__ #include "assem_arm.c" #endif +#ifdef __aarch64__ +#include "assem_arm64.c" +#endif // Add virtual address mapping to linked list void ll_add(struct ll_entry **head,int vaddr,void *addr) @@ -962,7 +979,7 @@ static void ll_kill_pointers(struct ll_entry *head,uintptr_t addr,int shift) { inv_debug("EXP: Kill pointer at %p (%x)\n",head->addr,head->vaddr); void *host_addr=find_extjump_insn(head->addr); - #ifdef __arm__ + #if defined(__arm__) || defined(__aarch64__) mark_clear_cache(host_addr); #endif set_jump_target(host_addr, head->addr); @@ -990,7 +1007,7 @@ void invalidate_page(u_int page) while(head!=NULL) { inv_debug("INVALIDATE: kill pointer to %x (%p)\n",head->vaddr,head->addr); void *host_addr=find_extjump_insn(head->addr); - #ifdef __arm__ + #if defined(__arm__) || defined(__aarch64__) mark_clear_cache(host_addr); #endif set_jump_target(host_addr, head->addr); @@ -1015,7 +1032,7 @@ static void invalidate_block_range(u_int block, u_int first, u_int last) for(first=page+1;first=0) emit_mov(a0,0); + } + else { + if(a0>=0&&a0!=0) emit_mov(a0,0); + if(a1>=0&&a1!=1) emit_mov(a1,1); + } +} + +static void alu_assemble(int i,struct regstat *i_regs) { if(opcode2[i]>=0x20&&opcode2[i]<=0x23) { // ADD/ADDU/SUB/SUBU if(rt1[i]) { @@ -2463,6 +2497,34 @@ static void *emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override) return jaddr; } +// return memhandler, or get directly accessable address and return 0 +static void *get_direct_memhandler(void *table, u_int addr, + enum stub_type type, uintptr_t *addr_host) +{ + uintptr_t l1, l2 = 0; + l1 = ((uintptr_t *)table)[addr>>12]; + if ((l1 & (1ul << (sizeof(l1)*8-1))) == 0) { + uintptr_t v = l1 << 1; + *addr_host = v + addr; + return NULL; + } + else { + l1 <<= 1; + if (type == LOADB_STUB || type == LOADBU_STUB || type == STOREB_STUB) + l2 = ((uintptr_t *)l1)[0x1000/4 + 0x1000/2 + (addr&0xfff)]; + else if (type == LOADH_STUB || type == LOADHU_STUB || type == STOREH_STUB) + l2=((uintptr_t *)l1)[0x1000/4 + (addr&0xfff)/2]; + else + l2=((uintptr_t *)l1)[(addr&0xfff)/4]; + if ((l2 & (1<<31)) == 0) { + uintptr_t v = l2 << 1; + *addr_host = v + (addr&0xfff); + return NULL; + } + return (void *)(l2 << 1); + } +} + static void load_assemble(int i,struct regstat *i_regs) { int s,th,tl,addr; @@ -3112,7 +3174,7 @@ 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 +#if defined(HAVE_ARMV5) || defined(__aarch64__) emit_clz(temp,temp); #else emit_movs(temp,HOST_TEMPREG); @@ -4193,7 +4255,7 @@ void do_cc(int i,signed char i_regmap[],int *adj,int addr,int taken,int invert) static void do_ccstub(int n) { literal_pool(256); - assem_debug("do_ccstub %x\n",start+stubs[n].b*4); + assem_debug("do_ccstub %lx\n",start+stubs[n].b*4); set_jump_target(stubs[n].addr, out); int i=stubs[n].b; if(stubs[n].d==NULLDS) { @@ -6183,25 +6245,39 @@ static void disassemble_inst(int i) {} #define DRC_TEST_VAL 0x74657374 -static int new_dynarec_test(void) +static void new_dynarec_test(void) { - int (*testfunc)(void) = (void *)out; + int (*testfunc)(void); void *beginning; - int ret; + int ret[2]; + size_t i; - beginning = start_block(); - emit_movimm(DRC_TEST_VAL,0); // test - emit_jmpreg(14); - literal_pool(0); - end_block(beginning); - SysPrintf("testing if we can run recompiled code..\n"); - ret = testfunc(); - if (ret == DRC_TEST_VAL) + // check structure linkage + if ((void *)reg != (void *)&psxRegs + || (u_char *)rcnts - (u_char *)reg != sizeof(psxRegs)) + { + SysPrintf("linkage_arm miscompilation/breakage detected.\n"); + } + + SysPrintf("testing if we can run recompiled code...\n"); + ((volatile u_int *)out)[0]++; // make cache dirty + + for (i = 0; i < ARRAY_SIZE(ret); i++) { + out = translation_cache; + beginning = start_block(); + emit_movimm(DRC_TEST_VAL + i, 0); // test + emit_ret(); + literal_pool(0); + end_block(beginning); + testfunc = beginning; + ret[i] = testfunc(); + } + + if (ret[0] == DRC_TEST_VAL && ret[1] == DRC_TEST_VAL + 1) SysPrintf("test passed.\n"); else - SysPrintf("test failed: %08x\n", ret); + SysPrintf("test failed, will likely crash soon (r=%08x %08x)\n", ret[0], ret[1]); out = translation_cache; - return ret == DRC_TEST_VAL; } // clear the state completely, instead of just marking @@ -6645,7 +6721,7 @@ int new_recompile_block(int addr) #endif case 0x12: strcpy(insn[i],"COP2"); type=NI; op2=(source[i]>>21)&0x1f; - //if (op2 & 0x10) { + //if (op2 & 0x10) if (source[i]&0x3f) { // use this hack to support old savestates with patched gte insns if (gte_handlers[source[i]&0x3f]!=NULL) { if (gte_regnames[source[i]&0x3f]!=NULL) @@ -8893,7 +8969,7 @@ int new_recompile_block(int addr) break; case 3: // Clear jump_out - #ifdef __arm__ + #if defined(__arm__) || defined(__aarch64__) if((expirep&2047)==0) do_clear_cache(); #endif