#endif
if((*ptr&0xFF000000)!=0xeb000000) ptr++;
assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
+#ifndef DISABLE_TLB
u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl
if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) {
unsigned int page=source>>12;
}
source = source+(map_value<<2);
}
+#endif
//printf("verify_dirty: %x %x %x\n",source,copy,len);
return !memcmp((void *)source,(void *)copy,len);
}
#endif
if((*ptr&0xFF000000)!=0xeb000000) ptr++;
assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
+#ifndef DISABLE_TLB
u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl
if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) {
if(memory_map[source>>12]>=0x80000000) source = 0;
else source = source+(memory_map[source>>12]<<2);
}
+#endif
*start=source;
*end=source+len;
}
output_w32(0x31a00000|rd_rn_rm(rt,0,rs)|0x20|(imm<<7));
}
+void emit_shrne_imm(int rs,u_int imm,int rt)
+{
+ assert(imm>0);
+ assert(imm<32);
+ assem_debug("lsrne %s,%s,#%d\n",regname[rt],regname[rs],imm);
+ output_w32(0x11a00000|rd_rn_rm(rt,0,rs)|0x20|(imm<<7));
+}
+
void emit_negmi(int rs, int rt)
{
assem_debug("rsbmi %s,%s,#0\n",regname[rt],regname[rs]);
}
}
+static void mov_loadtype_adj(int type,int rs,int rt)
+{
+ switch(type) {
+ case LOADB_STUB: emit_signextend8(rs,rt); break;
+ case LOADBU_STUB: emit_andimm(rs,0xff,rt); break;
+ case LOADH_STUB: emit_signextend16(rs,rt); break;
+ case LOADHU_STUB: emit_andimm(rs,0xffff,rt); break;
+ case LOADW_STUB: if(rs!=rt) emit_mov(rs,rt); break;
+ default: assert(0);
+ }
+}
+
+#ifdef PCSX
+#include "pcsxmem.h"
+#include "pcsxmem_inline.c"
+#endif
+
do_readstub(int n)
{
assem_debug("do_readstub %x\n",start+stubs[n][3]*4);
int cc=get_reg(i_regmap,CCREG);
if(cc<0)
emit_loadreg(CCREG,2);
- emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*stubs[n][6]+2,2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
emit_call(handler);
if(itype[i]==C1LS||itype[i]==C2LS||(rt>=0&&rt1[i]!=0)) {
- switch(type) {
- case LOADB_STUB: emit_signextend8(0,rt); break;
- case LOADBU_STUB: emit_andimm(0,0xff,rt); break;
- case LOADH_STUB: emit_signextend16(0,rt); break;
- case LOADHU_STUB: emit_andimm(0,0xffff,rt); break;
- case LOADW_STUB: if(rt!=0) emit_mov(0,rt); break;
- }
+ mov_loadtype_adj(type,0,rt);
}
if(restore_jump)
set_jump_target(restore_jump,(int)out);
if(rs<0) rs=get_reg(regmap,-1);
assert(rs>=0);
#ifdef PCSX
- u_int handler,host_addr=0;
+ u_int handler,host_addr=0,is_dynamic,far_call=0;
+ int cc=get_reg(regmap,CCREG);
+ if(pcsx_direct_read(type,addr,CLOCK_ADJUST(adj+1),cc,target?rs:-1,rt))
+ return;
handler=get_direct_memhandler(mem_rtab,addr,type,&host_addr);
if (handler==0) {
if(rt<0)
}
return;
}
+ is_dynamic=pcsxmem_is_handler_dynamic(addr);
+ if(is_dynamic) {
+ if(type==LOADB_STUB||type==LOADBU_STUB)
+ handler=(int)jump_handler_read8;
+ if(type==LOADH_STUB||type==LOADHU_STUB)
+ handler=(int)jump_handler_read16;
+ if(type==LOADW_STUB)
+ handler=(int)jump_handler_read32;
+ }
// call a memhandler
if(rt>=0)
emit_movimm(addr,0);
else if(rs!=0)
emit_mov(rs,0);
- int cc=get_reg(regmap,CCREG);
- if(cc<0)
- emit_loadreg(CCREG,2);
- emit_readword((int)&last_count,3);
- emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2);
- emit_add(2,3,3);
- emit_writeword(3,(int)&Count);
-
int offset=(int)handler-(int)out-8;
if(offset<-33554432||offset>=33554432) {
// unreachable memhandler, a plugin func perhaps
- emit_movimm(handler,1);
- emit_callreg(1);
+ emit_movimm(handler,12);
+ far_call=1;
}
+ if(cc<0)
+ emit_loadreg(CCREG,2);
+ if(is_dynamic) {
+ emit_movimm(((u_int *)mem_rtab)[addr>>12]<<1,1);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
+ }
+ else {
+ emit_readword((int)&last_count,3);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
+ emit_add(2,3,2);
+ emit_writeword(2,(int)&Count);
+ }
+
+ if(far_call)
+ emit_callreg(12);
else
emit_call(handler);
+
if(rt>=0) {
switch(type) {
case LOADB_STUB: emit_signextend8(0,rt); break;
//emit_movimm(ftable,0);
emit_movimm(((u_int *)ftable)[addr>>16],0);
//emit_readword((int)&last_count,12);
- emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
#ifndef PCSX
if((signed int)addr>=(signed int)0xC0000000) {
// Pagefault address
// but not doing so causes random crashes...
emit_readword((int)&Count,HOST_TEMPREG);
emit_readword((int)&next_interupt,2);
- emit_addimm(HOST_TEMPREG,-CLOCK_DIVIDER*(adj+1),HOST_TEMPREG);
+ emit_addimm(HOST_TEMPREG,-CLOCK_ADJUST(adj+1),HOST_TEMPREG);
emit_writeword(2,(int)&last_count);
emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc);
if(cc<0) {
int cc=get_reg(i_regmap,CCREG);
if(cc<0)
emit_loadreg(CCREG,2);
- emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*stubs[n][6]+2,2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
// returns new cycle_count
emit_call(handler);
- emit_addimm(0,-CLOCK_DIVIDER*stubs[n][6]-2,cc<0?2:cc);
+ emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc);
if(cc<0)
emit_storereg(CCREG,2);
if(restore_jump)
int cc=get_reg(regmap,CCREG);
if(cc<0)
emit_loadreg(CCREG,2);
- emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
emit_movimm(handler,3);
// returns new cycle_count
emit_call((int)jump_handler_write_h);
- emit_addimm(0,-CLOCK_DIVIDER*(adj+1),cc<0?2:cc);
+ emit_addimm(0,-CLOCK_ADJUST(adj+1),cc<0?2:cc);
if(cc<0)
emit_storereg(CCREG,2);
restore_regs(reglist);
//emit_movimm(ftable,0);
emit_movimm(((u_int *)ftable)[addr>>16],0);
//emit_readword((int)&last_count,12);
- emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
#ifndef PCSX
if((signed int)addr>=(signed int)0xC0000000) {
// Pagefault address
emit_call((int)&indirect_jump);
emit_readword((int)&Count,HOST_TEMPREG);
emit_readword((int)&next_interupt,2);
- emit_addimm(HOST_TEMPREG,-CLOCK_DIVIDER*(adj+1),HOST_TEMPREG);
+ emit_addimm(HOST_TEMPREG,-CLOCK_ADJUST(adj+1),HOST_TEMPREG);
emit_writeword(2,(int)&last_count);
emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc);
if(cc<0) {
int cc=get_reg(i_regmap,CCREG);
if(cc<0)
emit_loadreg(CCREG,2);
- emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*stubs[n][6]+2,2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
emit_call((int)(opcode[i]==0x2a?jump_handle_swl:jump_handle_swr));
- emit_addimm(0,-CLOCK_DIVIDER*stubs[n][6]-2,cc<0?2:cc);
+ emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc);
if(cc<0)
emit_storereg(CCREG,2);
restore_regs(reglist);
wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty);
if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
emit_movimm(start+(i-ds)*4,EAX); // Get PC
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle...
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle...
emit_jmp(ds?(int)fp_exception_ds:(int)fp_exception);
}
+#ifndef DISABLE_TLB
+
/* TLB */
int do_tlb_r(int s,int ar,int map,int x,int a,int shift,int c,u_int addr)
emit_movimm((addr>>12)+(((u_int)memory_map-(u_int)&dynarec_local)>>2),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; }
+
+#endif // DISABLE_TLB
+
/* Special assem */
void shift_assemble_arm(int i,struct regstat *i_regs)
emit_readword((int)&last_count,ECX);
emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc
emit_add(HOST_CCREG,ECX,HOST_CCREG);
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG);
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG);
emit_writeword(HOST_CCREG,(int)&Count);
}
emit_call((int)MFC0);
signed char s=get_reg(i_regs->regmap,rs1[i]);
char copr=(source[i]>>11)&0x1f;
assert(s>=0);
+#ifdef MUPEN64
emit_writeword(s,(int)&readmem_dword);
wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->is32);
-#ifdef MUPEN64
emit_addimm(FP,(int)&fake_pc-(int)&dynarec_local,0);
emit_movimm((source[i]>>11)&0x1f,1);
emit_writeword(0,(int)&PC);
emit_writebyte(1,(int)&(fake_pc.f.r.nrd));
+#else
+ wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->is32);
#endif
if(copr==9||copr==11||copr==12||copr==13) {
- emit_readword((int)&last_count,ECX);
+ emit_readword((int)&last_count,HOST_TEMPREG);
emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc
- emit_add(HOST_CCREG,ECX,HOST_CCREG);
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG);
+ emit_add(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG);
emit_writeword(HOST_CCREG,(int)&Count);
}
// What a mess. The status register (12) can enable interrupts,
emit_writeword(HOST_CCREG,(int)&last_count);
emit_movimm(0,HOST_CCREG);
emit_storereg(CCREG,HOST_CCREG);
+ if(s!=1)
+ emit_mov(s,1);
emit_movimm(copr,0);
emit_call((int)pcsx_mtc0_ds);
return;
}
#endif
- emit_movimm(start+i*4+4,0);
- emit_movimm(0,1);
- emit_writeword(0,(int)&pcaddr);
- emit_writeword(1,(int)&pending_exception);
+ emit_movimm(start+i*4+4,HOST_TEMPREG);
+ emit_writeword(HOST_TEMPREG,(int)&pcaddr);
+ emit_movimm(0,HOST_TEMPREG);
+ emit_writeword(HOST_TEMPREG,(int)&pending_exception);
}
//else if(copr==12&&is_delayslot) emit_call((int)MTC0_R12);
//else
#ifdef PCSX
+ if(s!=1)
+ emit_mov(s,1);
emit_movimm(copr,0);
emit_call((int)pcsx_mtc0);
#else
if(copr==9||copr==11||copr==12||copr==13) {
emit_readword((int)&Count,HOST_CCREG);
emit_readword((int)&next_interupt,ECX);
- emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*ccadj[i],HOST_CCREG);
+ emit_addimm(HOST_CCREG,-CLOCK_ADJUST(ccadj[i]),HOST_CCREG);
emit_sub(HOST_CCREG,ECX,HOST_CCREG);
emit_writeword(ECX,(int)&last_count);
emit_storereg(CCREG,HOST_CCREG);
emit_readword((int)&last_count,ECX);
if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
emit_add(HOST_CCREG,ECX,HOST_CCREG);
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG);
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG);
emit_writeword(HOST_CCREG,(int)&Count);
emit_call((int)TLBWR_new);
}
{
int count=ccadj[i];
if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*count,HOST_CCREG); // TODO: Should there be an extra cycle here?
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(count),HOST_CCREG); // TODO: Should there be an extra cycle here?
emit_jmp((int)jump_eret);
}
#endif