X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fnew_dynarec.c;h=1383b2f55f9894ad29c555178e8b54ac21d23ab1;hp=0809a4aa4083b830803f38288a663412051a99e2;hb=687b45804b5c028dd5644bda85981c0235eb4d32;hpb=be516ebe45e48044b599e9d9f9f2d296c3f3ee62 diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 0809a4aa..1383b2f5 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -198,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 */ @@ -299,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) { @@ -970,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); @@ -998,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); @@ -2003,7 +2012,24 @@ void rlist() printf("\n"); } -void alu_assemble(int i,struct regstat *i_regs) +// trashes r2 +static void pass_args(int a0, int a1) +{ + if(a0==1&&a1==0) { + // must swap + emit_mov(a0,2); emit_mov(a1,1); emit_mov(2,0); + } + else if(a0!=0&&a1==0) { + emit_mov(a1,1); + if (a0>=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]) { @@ -2471,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; @@ -6198,6 +6252,13 @@ static void new_dynarec_test(void) int ret[2]; size_t i; + // 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