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=9ce1f069a92bdd5766adb1db2e175aedf489c746;hp=7c59a7e8a707d1032e55659edc0675d3494b1f8e;hb=3968e69e7fa8f9cb0d44ac79477d5929b9649271;hpb=7c3a5182da4384e21a6ace037583fae399de5a02 diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 7c59a7e8..9ce1f069 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -35,9 +35,11 @@ static int sceBlock; #endif #include "new_dynarec_config.h" -#include "../psxhle.h" //emulator interface +#include "../psxhle.h" +#include "../psxinterpreter.h" #include "emu_if.h" //emulator interface +#define noinline __attribute__((noinline,noclone)) #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif @@ -165,7 +167,7 @@ struct link_entry static char ooo[MAXBLOCK]; static uint64_t unneeded_reg[MAXBLOCK]; static uint64_t branch_unneeded_reg[MAXBLOCK]; - static signed char regmap_pre[MAXBLOCK][HOST_REGS]; + static signed char regmap_pre[MAXBLOCK][HOST_REGS]; // pre-instruction i? static uint64_t current_constmap[HOST_REGS]; static uint64_t constmap[MAXBLOCK][HOST_REGS]; static struct regstat regs[MAXBLOCK]; @@ -202,7 +204,7 @@ struct link_entry extern int pcaddr; extern int pending_exception; extern int branch_target; - extern u_int mini_ht[32][2]; + extern uintptr_t mini_ht[32][2]; extern u_char restore_candidate[512]; /* registers that may be allocated */ @@ -271,7 +273,7 @@ struct link_entry #define DJT_2 (void *)2l // asm linkage -int new_recompile_block(int addr); +int new_recompile_block(u_int addr); void *get_addr_ht(u_int vaddr); void invalidate_block(u_int block); void invalidate_addr(u_int addr); @@ -283,9 +285,7 @@ void verify_code_ds(); void cc_interrupt(); void fp_exception(); void fp_exception_ds(); -void jump_syscall_hle(); -void jump_hlecall(); -void jump_intcall(); +void jump_to_new_pc(); void new_dyna_leave(); // Needed by assembler @@ -297,7 +297,7 @@ static void load_needed_regs(signed char i_regmap[],signed char next_regmap[]); static void load_regs_entry(int t); static void load_all_consts(signed char regmap[],u_int dirty,int i); -static int verify_dirty(u_int *ptr); +static int verify_dirty(const u_int *ptr); static int get_final_value(int hr, int i, int *value); static void add_stub(enum stub_type type, void *addr, void *retaddr, u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e); @@ -421,7 +421,7 @@ static int doesnt_expire_soon(void *tcaddr) // Get address from virtual address // This is called from the recompiled JR/JALR instructions -void *get_addr(u_int vaddr) +void noinline *get_addr(u_int vaddr) { u_int page=get_page(vaddr); u_int vpage=get_vpage(vaddr); @@ -489,7 +489,7 @@ void clear_all_regs(signed char regmap[]) for (hr=0;hr %x (%d)\n",src,vaddr,page); - int *ptr=(int *)(src+4); - assert((*ptr&0x0fff0000)==0x059f0000); - (void)ptr; + check_extjump2(src); ll_add(jump_out+page,vaddr,src); //void *ptr=get_pointer(src); //inv_debug("add_link: Pointer is to %p\n",ptr); @@ -1905,7 +1935,7 @@ static void pagespan_alloc(struct regstat *current,int i) static void add_stub(enum stub_type type, void *addr, void *retaddr, u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e) { - assert(a < ARRAY_SIZE(stubs)); + assert(stubcount < ARRAY_SIZE(stubs)); stubs[stubcount].type = type; stubs[stubcount].addr = addr; stubs[stubcount].retaddr = retaddr; @@ -2331,11 +2361,44 @@ void shiftimm_assemble(int i,struct regstat *i_regs) } #ifndef shift_assemble -void shift_assemble(int i,struct regstat *i_regs) +static void shift_assemble(int i,struct regstat *i_regs) { - printf("Need shift_assemble for this architecture.\n"); - abort(); + signed char s,t,shift; + if (rt1[i] == 0) + return; + assert(opcode2[i]<=0x07); // SLLV/SRLV/SRAV + t = get_reg(i_regs->regmap, rt1[i]); + s = get_reg(i_regs->regmap, rs1[i]); + shift = get_reg(i_regs->regmap, rs2[i]); + if (t < 0) + return; + + if(rs1[i]==0) + emit_zeroreg(t); + else if(rs2[i]==0) { + assert(s>=0); + if(s!=t) emit_mov(s,t); + } + else { + host_tempreg_acquire(); + emit_andimm(shift,31,HOST_TEMPREG); + switch(opcode2[i]) { + case 4: // SLLV + emit_shl(s,HOST_TEMPREG,t); + break; + case 6: // SRLV + emit_shr(s,HOST_TEMPREG,t); + break; + case 7: // SRAV + emit_sar(s,HOST_TEMPREG,t); + break; + default: + assert(0); + } + host_tempreg_release(); + } } + #endif enum { @@ -2380,24 +2443,29 @@ static void *emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override) } if(type==MTYPE_8020) { // RAM 80200000+ mirror + host_tempreg_acquire(); emit_andimm(addr,~0x00e00000,HOST_TEMPREG); addr=*addr_reg_override=HOST_TEMPREG; type=0; } else if(type==MTYPE_0000) { // RAM 0 mirror + host_tempreg_acquire(); emit_orimm(addr,0x80000000,HOST_TEMPREG); addr=*addr_reg_override=HOST_TEMPREG; type=0; } else if(type==MTYPE_A000) { // RAM A mirror + host_tempreg_acquire(); emit_andimm(addr,~0x20000000,HOST_TEMPREG); addr=*addr_reg_override=HOST_TEMPREG; type=0; } else if(type==MTYPE_1F80) { // scratchpad if (psxH == (void *)0x1f800000) { - emit_addimm(addr,-0x1f800000,HOST_TEMPREG); + host_tempreg_acquire(); + emit_xorimm(addr,0x1f800000,HOST_TEMPREG); emit_cmpimm(HOST_TEMPREG,0x1000); + host_tempreg_release(); jaddr=out; emit_jc(0); } @@ -2419,6 +2487,7 @@ static void *emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override) #endif emit_jno(0); if(ram_offset!=0) { + host_tempreg_acquire(); emit_addimm(addr,ram_offset,HOST_TEMPREG); addr=*addr_reg_override=HOST_TEMPREG; } @@ -2461,7 +2530,7 @@ static void load_assemble(int i,struct regstat *i_regs) int offset; void *jaddr=0; int memtarget=0,c=0; - int fastload_reg_override=0; + int fastio_reg_override=-1; u_int hr,reglist=0; tl=get_reg(i_regs->regmap,rt1[i]); s=get_reg(i_regs->regmap,rs1[i]); @@ -2501,12 +2570,13 @@ static void load_assemble(int i,struct regstat *i_regs) if(rs1[i]!=29||start<0x80001000||start>=0x80000000+RAM_SIZE) #endif { - jaddr=emit_fastpath_cmp_jump(i,addr,&fastload_reg_override); + jaddr=emit_fastpath_cmp_jump(i,addr,&fastio_reg_override); } } else if(ram_offset&&memtarget) { + host_tempreg_acquire(); emit_addimm(addr,ram_offset,HOST_TEMPREG); - fastload_reg_override=HOST_TEMPREG; + fastio_reg_override=HOST_TEMPREG; } int dummy=(rt1[i]==0)||(tl!=get_reg(i_regs->regmap,rt1[i])); // ignore loads to r0 and unneeded reg if (opcode[i]==0x20) { // LB @@ -2515,7 +2585,7 @@ static void load_assemble(int i,struct regstat *i_regs) { int x=0,a=tl; if(!c) a=addr; - if(fastload_reg_override) a=fastload_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_movsbl_indexed(x,a,tl); } @@ -2531,7 +2601,7 @@ static void load_assemble(int i,struct regstat *i_regs) if(!dummy) { int x=0,a=tl; if(!c) a=addr; - if(fastload_reg_override) a=fastload_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_movswl_indexed(x,a,tl); } if(jaddr) @@ -2544,7 +2614,7 @@ static void load_assemble(int i,struct regstat *i_regs) if(!c||memtarget) { if(!dummy) { int a=addr; - if(fastload_reg_override) a=fastload_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_readword_indexed(0,a,tl); } if(jaddr) @@ -2558,7 +2628,7 @@ static void load_assemble(int i,struct regstat *i_regs) if(!dummy) { int x=0,a=tl; if(!c) a=addr; - if(fastload_reg_override) a=fastload_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_movzbl_indexed(x,a,tl); } @@ -2573,7 +2643,7 @@ static void load_assemble(int i,struct regstat *i_regs) if(!dummy) { int x=0,a=tl; if(!c) a=addr; - if(fastload_reg_override) a=fastload_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_movzwl_indexed(x,a,tl); } if(jaddr) @@ -2589,13 +2659,91 @@ static void load_assemble(int i,struct regstat *i_regs) assert(0); } } + if (fastio_reg_override == HOST_TEMPREG) + host_tempreg_release(); } #ifndef loadlr_assemble -void loadlr_assemble(int i,struct regstat *i_regs) +static void loadlr_assemble(int i,struct regstat *i_regs) { - printf("Need loadlr_assemble for this architecture.\n"); - abort(); + int s,tl,temp,temp2,addr; + int offset; + void *jaddr=0; + int memtarget=0,c=0; + int fastio_reg_override=-1; + u_int hr,reglist=0; + tl=get_reg(i_regs->regmap,rt1[i]); + s=get_reg(i_regs->regmap,rs1[i]); + temp=get_reg(i_regs->regmap,-1); + temp2=get_reg(i_regs->regmap,FTEMP); + addr=get_reg(i_regs->regmap,AGEN1+(i&1)); + assert(addr<0); + offset=imm[i]; + for(hr=0;hrregmap[hr]>=0) reglist|=1<=0) { + c=(i_regs->wasconst>>s)&1; + if(c) { + memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE; + } + } + if(!c) { + emit_shlimm(addr,3,temp); + if (opcode[i]==0x22||opcode[i]==0x26) { + emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR + }else{ + emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR + } + jaddr=emit_fastpath_cmp_jump(i,temp2,&fastio_reg_override); + } + else { + if(ram_offset&&memtarget) { + host_tempreg_acquire(); + emit_addimm(temp2,ram_offset,HOST_TEMPREG); + fastio_reg_override=HOST_TEMPREG; + } + if (opcode[i]==0x22||opcode[i]==0x26) { + emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR + }else{ + emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR + } + } + if (opcode[i]==0x22||opcode[i]==0x26) { // LWL/LWR + if(!c||memtarget) { + int a=temp2; + if(fastio_reg_override>=0) a=fastio_reg_override; + emit_readword_indexed(0,a,temp2); + if(fastio_reg_override==HOST_TEMPREG) host_tempreg_release(); + if(jaddr) add_stub_r(LOADW_STUB,jaddr,out,i,temp2,i_regs,ccadj[i],reglist); + } + else + inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj[i],reglist); + if(rt1[i]) { + assert(tl>=0); + emit_andimm(temp,24,temp); + if (opcode[i]==0x22) // LWL + emit_xorimm(temp,24,temp); + host_tempreg_acquire(); + emit_movimm(-1,HOST_TEMPREG); + if (opcode[i]==0x26) { + emit_shr(temp2,temp,temp2); + emit_bic_lsr(tl,HOST_TEMPREG,temp,tl); + }else{ + emit_shl(temp2,temp,temp2); + emit_bic_lsl(tl,HOST_TEMPREG,temp,tl); + } + host_tempreg_release(); + emit_or(temp2,tl,tl); + } + //emit_storereg(rt1[i],tl); // DEBUG + } + if (opcode[i]==0x1A||opcode[i]==0x1B) { // LDL/LDR + assert(0); + } } #endif @@ -2608,7 +2756,7 @@ void store_assemble(int i,struct regstat *i_regs) enum stub_type type; int memtarget=0,c=0; int agr=AGEN1+(i&1); - int faststore_reg_override=0; + int fastio_reg_override=-1; u_int hr,reglist=0; tl=get_reg(i_regs->regmap,rs2[i]); s=get_reg(i_regs->regmap,rs1[i]); @@ -2630,18 +2778,19 @@ void store_assemble(int i,struct regstat *i_regs) if(offset||s<0||c) addr=temp; else addr=s; if(!c) { - jaddr=emit_fastpath_cmp_jump(i,addr,&faststore_reg_override); + jaddr=emit_fastpath_cmp_jump(i,addr,&fastio_reg_override); } else if(ram_offset&&memtarget) { + host_tempreg_acquire(); emit_addimm(addr,ram_offset,HOST_TEMPREG); - faststore_reg_override=HOST_TEMPREG; + fastio_reg_override=HOST_TEMPREG; } if (opcode[i]==0x28) { // SB if(!c||memtarget) { int x=0,a=temp; if(!c) a=addr; - if(faststore_reg_override) a=faststore_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_writebyte_indexed(tl,x,a); } type=STOREB_STUB; @@ -2650,7 +2799,7 @@ void store_assemble(int i,struct regstat *i_regs) if(!c||memtarget) { int x=0,a=temp; if(!c) a=addr; - if(faststore_reg_override) a=faststore_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_writehword_indexed(tl,x,a); } type=STOREH_STUB; @@ -2658,7 +2807,7 @@ void store_assemble(int i,struct regstat *i_regs) if (opcode[i]==0x2B) { // SW if(!c||memtarget) { int a=addr; - if(faststore_reg_override) a=faststore_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_writeword_indexed(tl,0,a); } type=STOREW_STUB; @@ -2667,6 +2816,8 @@ void store_assemble(int i,struct regstat *i_regs) assert(0); type=STORED_STUB; } + if(fastio_reg_override==HOST_TEMPREG) + host_tempreg_release(); if(jaddr) { // PCSX store handlers don't check invcode again reglist|=1<attract mode) if(c&&start+i*4regmap==regs[i].regmap); // not delay slot @@ -2712,12 +2864,14 @@ void store_assemble(int i,struct regstat *i_regs) wb_dirtys(regs[i].regmap_entry,regs[i].wasdirty); emit_movimm(start+i*4+4,0); emit_writeword(0,&pcaddr); - emit_jmp(do_interrupt); + emit_addimm(HOST_CCREG,2,HOST_CCREG); + emit_call(get_addr_ht); + emit_jmpreg(0); } } } -void storelr_assemble(int i,struct regstat *i_regs) +static void storelr_assemble(int i,struct regstat *i_regs) { int s,tl; int temp; @@ -2757,7 +2911,8 @@ void storelr_assemble(int i,struct regstat *i_regs) emit_jmp(0); } } - emit_addimm_no_flags(ram_offset,temp); + if(ram_offset) + emit_addimm_no_flags(ram_offset,temp); if (opcode[i]==0x2C||opcode[i]==0x2D) { // SDL/SDR assert(0); @@ -2774,15 +2929,11 @@ void storelr_assemble(int i,struct regstat *i_regs) if (opcode[i]==0x2A) { // SWL emit_writeword_indexed(tl,0,temp); } - if (opcode[i]==0x2E) { // SWR + else if (opcode[i]==0x2E) { // SWR emit_writebyte_indexed(tl,3,temp); } - if (opcode[i]==0x2C) { // SDL - assert(0); - } - if (opcode[i]==0x2D) { // SDR + else assert(0); - } done0=out; emit_jmp(0); // 1 @@ -2795,16 +2946,10 @@ void storelr_assemble(int i,struct regstat *i_regs) emit_writebyte_indexed(tl,1,temp); if(rs2[i]) emit_rorimm(tl,8,tl); } - if (opcode[i]==0x2E) { // SWR + else if (opcode[i]==0x2E) { // SWR // Write two lsb into two most significant bytes emit_writehword_indexed(tl,1,temp); } - if (opcode[i]==0x2C) { // SDL - assert(0); - } - if (opcode[i]==0x2D) { // SDR - assert(0); - } done1=out; emit_jmp(0); // 2 @@ -2818,19 +2963,13 @@ void storelr_assemble(int i,struct regstat *i_regs) emit_writehword_indexed(tl,-2,temp); if(rs2[i]) emit_rorimm(tl,16,tl); } - if (opcode[i]==0x2E) { // SWR + else if (opcode[i]==0x2E) { // SWR // Write 3 lsb into three most significant bytes emit_writebyte_indexed(tl,-1,temp); if(rs2[i]) emit_rorimm(tl,8,tl); emit_writehword_indexed(tl,0,temp); if(rs2[i]) emit_rorimm(tl,24,tl); } - if (opcode[i]==0x2C) { // SDL - assert(0); - } - if (opcode[i]==0x2D) { // SDR - assert(0); - } done2=out; emit_jmp(0); // 3 @@ -2841,25 +2980,13 @@ void storelr_assemble(int i,struct regstat *i_regs) emit_writebyte_indexed(tl,-3,temp); if(rs2[i]) emit_rorimm(tl,8,tl); } - if (opcode[i]==0x2E) { // SWR + else if (opcode[i]==0x2E) { // SWR // Write entire word emit_writeword_indexed(tl,-3,temp); } - if (opcode[i]==0x2C) { // SDL - assert(0); - } - if (opcode[i]==0x2D) { // SDR - assert(0); - } set_jump_target(done0, out); set_jump_target(done1, out); set_jump_target(done2, out); - if (opcode[i]==0x2C) { // SDL - assert(0); - } - if (opcode[i]==0x2D) { // SDR - assert(0); - } if(!c||!memtarget) add_stub_r(STORELR_STUB,jaddr,out,i,temp,i_regs,ccadj[i],reglist); if(!(i_regs->waswritten&(1<>16)&0x1f; s=get_reg(i_regs->regmap,rs1[i]); @@ -3146,7 +3263,7 @@ static void c2ls_assemble(int i,struct regstat *i_regs) assert(ar>=0); if (opcode[i]==0x3a) { // SWC2 - cop2_get_dreg(copr,tl,HOST_TEMPREG); + cop2_get_dreg(copr,tl,-1); type=STOREW_STUB; } else @@ -3161,12 +3278,13 @@ static void c2ls_assemble(int i,struct regstat *i_regs) jaddr2=emit_fastpath_cmp_jump(i,ar,&fastio_reg_override); } else if(ram_offset&&memtarget) { + host_tempreg_acquire(); emit_addimm(ar,ram_offset,HOST_TEMPREG); fastio_reg_override=HOST_TEMPREG; } if (opcode[i]==0x32) { // LWC2 int a=ar; - if(fastio_reg_override) a=fastio_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_readword_indexed(0,a,tl); } if (opcode[i]==0x3a) { // SWC2 @@ -3174,10 +3292,12 @@ static void c2ls_assemble(int i,struct regstat *i_regs) if(!offset&&!c&&s>=0) emit_mov(s,ar); #endif int a=ar; - if(fastio_reg_override) a=fastio_reg_override; + if(fastio_reg_override>=0) a=fastio_reg_override; emit_writeword_indexed(tl,0,a); } } + if(fastio_reg_override==HOST_TEMPREG) + host_tempreg_release(); if(jaddr2) add_stub_r(type,jaddr2,out,i,ar,i_regs,ccadj[i],reglist); if(opcode[i]==0x3a) // SWC2 @@ -3198,7 +3318,9 @@ static void c2ls_assemble(int i,struct regstat *i_regs) #endif } if (opcode[i]==0x32) { // LWC2 + host_tempreg_acquire(); cop2_put_dreg(copr,tl,HOST_TEMPREG); + host_tempreg_release(); } } @@ -3235,14 +3357,7 @@ static void cop2_assemble(int i,struct regstat *i_regs) emit_signextend16(sl,temp); break; case 31: - //value = value & 0x7ffff000; - //if (value & 0x7f87e000) value |= 0x80000000; - emit_shrimm(sl,12,temp); - emit_shlimm(temp,12,temp); - emit_testimm(temp,0x7f000000); - emit_testeqimm(temp,0x00870000); - emit_testeqimm(temp,0x0000e000); - emit_orrne_imm(temp,0x80000000,temp); + c2op_ctc2_31_assemble(sl,temp); break; default: temp=sl; @@ -3253,6 +3368,90 @@ static void cop2_assemble(int i,struct regstat *i_regs) } } +static void do_unalignedwritestub(int n) +{ + assem_debug("do_unalignedwritestub %x\n",start+stubs[n].a*4); + literal_pool(256); + set_jump_target(stubs[n].addr, out); + + int i=stubs[n].a; + struct regstat *i_regs=(struct regstat *)stubs[n].c; + int addr=stubs[n].b; + u_int reglist=stubs[n].e; + signed char *i_regmap=i_regs->regmap; + int temp2=get_reg(i_regmap,FTEMP); + int rt; + rt=get_reg(i_regmap,rs2[i]); + assert(rt>=0); + assert(addr>=0); + assert(opcode[i]==0x2a||opcode[i]==0x2e); // SWL/SWR only implemented + reglist|=(1<regmap,CCREG); assert(ccreg==HOST_CCREG); assert(!is_delayslot); (void)ccreg; - emit_movimm(start+i*4,EAX); // Get PC - emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle... - emit_jmp(jump_syscall_hle); // XXX + + emit_movimm(pc,3); // Get PC + emit_readword(&last_count,2); + emit_writeword(3,&psxRegs.pc); + emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // XXX + emit_add(2,HOST_CCREG,2); + emit_writeword(2,&psxRegs.cycle); + emit_call(func); + emit_jmp(jump_to_new_pc); +} + +static void syscall_assemble(int i,struct regstat *i_regs) +{ + emit_movimm(0x20,0); // cause code + emit_movimm(0,1); // not in delay slot + call_c_cpu_handler(i,i_regs,start+i*4,psxException); } static void hlecall_assemble(int i,struct regstat *i_regs) { - extern void psxNULL(); - signed char ccreg=get_reg(i_regs->regmap,CCREG); - assert(ccreg==HOST_CCREG); - assert(!is_delayslot); - (void)ccreg; - emit_movimm(start+i*4+4,0); // Get PC + void *hlefunc = psxNULL; uint32_t hleCode = source[i] & 0x03ffffff; - if (hleCode >= ARRAY_SIZE(psxHLEt)) - emit_movimm((uintptr_t)psxNULL,1); - else - emit_movimm((uintptr_t)psxHLEt[hleCode],1); - emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // XXX - emit_jmp(jump_hlecall); + if (hleCode < ARRAY_SIZE(psxHLEt)) + hlefunc = psxHLEt[hleCode]; + + call_c_cpu_handler(i,i_regs,start+i*4+4,hlefunc); } static void intcall_assemble(int i,struct regstat *i_regs) { - signed char ccreg=get_reg(i_regs->regmap,CCREG); - assert(ccreg==HOST_CCREG); - assert(!is_delayslot); - (void)ccreg; - emit_movimm(start+i*4,0); // Get PC - emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); - emit_jmp(jump_intcall); + call_c_cpu_handler(i,i_regs,start+i*4,execI); } static void speculate_mov(int rs,int rt) @@ -4019,7 +4219,7 @@ static int match_bt(signed char i_regmap[],uint64_t i_dirty,int addr) static void drc_dbg_emit_do_cmp(int i) { extern void do_insn_cmp(); - extern int cycle; + //extern int cycle; u_int hr,reglist=0; for(hr=0;hr(ba[i]-start)>>2) invert=1; #endif + #ifdef __aarch64__ + invert=1; // because of near cond. branches + #endif if(ooo[i]) { s1l=get_reg(branch_regs[i].regmap,rs1[i]); @@ -4890,6 +5104,9 @@ static void sjump_assemble(int i,struct regstat *i_regs) #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK if(i>(ba[i]-start)>>2) invert=1; #endif + #ifdef __aarch64__ + invert=1; // because of near cond. branches + #endif //if(opcode2[i]>=0x10) return; // FIXME (BxxZAL) //assert(opcode2[i]<0x10||rs1[i]==0); // FIXME (BxxZAL) @@ -5430,15 +5647,17 @@ static void pagespan_ds() assert(btaddr!=HOST_CCREG); if(regs[0].regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG); #ifdef HOST_IMM8 + host_tempreg_acquire(); emit_movimm(start+4,HOST_TEMPREG); emit_cmp(btaddr,HOST_TEMPREG); + host_tempreg_release(); #else emit_cmpimm(btaddr,start+4); #endif void *branch = out; emit_jeq(0); store_regs_bt(regs[0].regmap,regs[0].dirty,-1); - emit_jmp(jump_vaddr_reg[btaddr]); + do_jump_vaddr(btaddr); set_jump_target(branch, out); store_regs_bt(regs[0].regmap,regs[0].dirty,start+4); load_regs_bt(regs[0].regmap,regs[0].dirty,start+4); @@ -6416,7 +6635,7 @@ void new_dynarec_load_blocks(const void *save, int size) memcpy(&psxRegs.GPR, regs_save, sizeof(regs_save)); } -int new_recompile_block(int addr) +int new_recompile_block(u_int addr) { u_int pagelimit = 0; u_int state_rflags = 0; @@ -7823,7 +8042,7 @@ int new_recompile_block(int addr) { if(i0) if(regmap_pre[i+1][hr]!=regs[i].regmap[hr]) { SysPrintf("fail: %x (%d %d!=%d)\n",start+i*4,hr,regmap_pre[i+1][hr],regs[i].regmap[hr]); @@ -7838,8 +8057,8 @@ int new_recompile_block(int addr) } } } - } - } + } // if needed + } // for hr } /* Pass 5 - Pre-allocate registers */ @@ -8465,7 +8684,7 @@ int new_recompile_block(int addr) void *instr_addr0_override = NULL; if (start == 0x80030000) { - // nasty hack for fastbios thing + // nasty hack for the fastbios thing // override block entry to this code instr_addr0_override = out; emit_movimm(start,0); @@ -8475,7 +8694,12 @@ int new_recompile_block(int addr) emit_writeword(0,&pcaddr); emit_writeword(0,&address); emit_cmp(0,1); + #ifdef __aarch64__ + emit_jeq(out + 4*2); + emit_jmp(new_dyna_leave); + #else emit_jne(new_dyna_leave); + #endif } for(i=0;i