From 1e973cb0a85b35524ccc99766b8510534659ff65 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 23 Jan 2011 21:33:35 +0200 Subject: [PATCH] drc: add support for interpreter calls; use them for branches in delay slots --- libpcsxcore/new_dynarec/new_dynarec.c | 64 +++++++++++++++++++++------ 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 73185aee..63e21e17 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -179,6 +179,7 @@ struct ll_entry #define COP2 27 // Coprocessor 2 move #define C2LS 28 // Coprocessor 2 load/store #define C2OP 29 // Coprocessor 2 operation +#define INTCALL 30// Call interpreter to handle rare corner cases /* stubs */ #define CC_STUB 1 @@ -220,6 +221,7 @@ void jump_syscall(); void jump_syscall_hle(); void jump_eret(); void jump_hlecall(); +void jump_intcall(); void new_dyna_leave(); // TLB @@ -727,7 +729,7 @@ int needed_again(int r, int i) j++; break; } - if(itype[i+j]==SYSCALL||itype[i+j]==HLECALL||((source[i+j]&0xfc00003f)==0x0d)) + if(itype[i+j]==SYSCALL||itype[i+j]==HLECALL||itype[i+j]==INTCALL||((source[i+j]&0xfc00003f)==0x0d)) { break; } @@ -3748,6 +3750,16 @@ void hlecall_assemble(int i,struct regstat *i_regs) emit_jmp((int)jump_hlecall); } +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); + emit_movimm(start+i*4,0); // Get PC + emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); + emit_jmp((int)jump_intcall); +} + void ds_assemble(int i,struct regstat *i_regs) { is_delayslot=1; @@ -3792,6 +3804,7 @@ void ds_assemble(int i,struct regstat *i_regs) mov_assemble(i,i_regs);break; case SYSCALL: case HLECALL: + case INTCALL: case SPAN: case UJUMP: case RJUMP: @@ -4645,6 +4658,7 @@ void ds_assemble_entry(int i) mov_assemble(t,®s[t]);break; case SYSCALL: case HLECALL: + case INTCALL: case SPAN: case UJUMP: case RJUMP: @@ -6476,6 +6490,7 @@ static void pagespan_ds() mov_assemble(0,®s[0]);break; case SYSCALL: case HLECALL: + case INTCALL: case SPAN: case UJUMP: case RJUMP: @@ -6699,7 +6714,7 @@ void unneeded_registers(int istart,int iend,int r) } } } - else if(itype[i]==SYSCALL||itype[i]==HLECALL) + else if(itype[i]==SYSCALL||itype[i]==HLECALL||itype[i]==INTCALL) { // SYSCALL instruction (software interrupt) u=1; @@ -7065,7 +7080,7 @@ static void provisional_r32() if((regs[i].was32>>dep2[i+1])&1) r32|=1LL<>16)&0x1f,rs1[i],imm[i]); break; + case INTCALL: + printf (" %x: %s (INTCALL)\n",start+i*4,insn[i]); + break; default: //printf (" %s %8x\n",insn[i],source[i]); printf (" %x: %s\n",start+i*4,insn[i]); @@ -8133,6 +8151,18 @@ int new_recompile_block(int addr) printf("NI %08x @%08x (%08x)\n", source[i], addr + i*4, addr); break; } +#ifdef PCSX + /* detect branch in delay slot early */ + if(type==RJUMP||type==UJUMP||type==CJUMP||type==SJUMP||type==FJUMP) { + opcode[i+1]=source[i+1]>>26; + opcode2[i+1]=source[i+1]&0x3f; + if((00&&(itype[i-1]==UJUMP||itype[i-1]==RJUMP||(source[i-1]>>16)==0x1000)) { if(rt1[i-1]==0) { // Continue past subroutine call (JAL) - done=1; - // Does the block continue due to a branch? - for(j=i-1;j>=0;j--) - { - if(ba[j]==start+i*4+4) done=j=0; - if(ba[j]==start+i*4+8) done=j=0; - } + done=2; } else { if(stop_after_jal) done=1; @@ -8386,7 +8411,15 @@ int new_recompile_block(int addr) if(i>MAXBLOCK/2) done=1; } if(itype[i]==SYSCALL&&stop_after_jal) done=1; - if(itype[i]==HLECALL) done=1; + if(itype[i]==HLECALL||itype[i]==INTCALL) done=2; + if(done==2) { + // Does the block continue due to a branch? + for(j=i-1;j>=0;j--) + { + if(ba[j]==start+i*4+4) done=j=0; + if(ba[j]==start+i*4+8) done=j=0; + } + } //assert(i>dep2[i+1])&1) r32|=1LL<