char shadow[1048576] __attribute__((aligned(16)));
void *copy;
int expirep;
+#ifndef PCSX
u_int using_tlb;
+#else
+ static const u_int using_tlb=0;
+#endif
u_int stop_after_jal;
extern u_char restore_candidate[512];
extern int cycle_count;
#define CSREG 35 // Coprocessor status
#define CCREG 36 // Cycle count
#define INVCP 37 // Pointer to invalid_code
-#define TEMPREG 38
-#define FTEMP 38 // FPU/LDL/LDR temporary register
-#define PTEMP 39 // Prefetch temporary register
-#define TLREG 40 // TLB mapping offset
-#define RHASH 41 // Return address hash
-#define RHTBL 42 // Return address hash table address
-#define RTEMP 43 // JR/JALR address register
-#define MAXREG 43
-#define AGEN1 44 // Address generation temporary register
-#define AGEN2 45 // Address generation temporary register
-#define MGEN1 46 // Maptable address generation temporary register
-#define MGEN2 47 // Maptable address generation temporary register
-#define BTREG 48 // Branch target temporary register
+#define MMREG 38 // Pointer to memory_map
+#define ROREG 39 // ram offset (if rdram!=0x80000000)
+#define TEMPREG 40
+#define FTEMP 40 // FPU temporary register
+#define PTEMP 41 // Prefetch temporary register
+#define TLREG 42 // TLB mapping offset
+#define RHASH 43 // Return address hash
+#define RHTBL 44 // Return address hash table address
+#define RTEMP 45 // JR/JALR address register
+#define MAXREG 45
+#define AGEN1 46 // Address generation temporary register
+#define AGEN2 47 // Address generation temporary register
+#define MGEN1 48 // Maptable address generation temporary register
+#define MGEN2 49 // Maptable address generation temporary register
+#define BTREG 50 // Branch target temporary register
/* instruction types */
#define NOP 0 // No operation
// Don't trap writes
invalid_code[block]=1;
+#ifdef PCSX
+ invalid_code[((u_int)0x80000000>>12)|page]=1;
+#endif
#ifndef DISABLE_TLB
// If there is a valid TLB entry for this page, remove write protect
if(tlb_LUT_w[block]) {
if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
if(s>=0) {
c=(i_regs->wasconst>>s)&1;
- memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
- if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
+ if (c) {
+ memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
+ if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
+ }
}
//printf("load_assemble: c=%d\n",c);
//if(c) printf("load_assemble: const=%x\n",(int)constmap[i][s]+offset);
offset=imm[i];
if(s>=0) {
c=(i_regs->wasconst>>s)&1;
- memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
- if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
+ if(c) {
+ memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
+ if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
+ }
}
assert(tl>=0);
assert(temp>=0);
if (opcode[i]==0x28) { // SB
if(!c||memtarget) {
- int x=0;
+ int x=0,a=temp;
#ifdef BIG_ENDIAN_MIPS
if(!c) emit_xorimm(addr,3,temp);
else x=((constmap[i][s]+offset)^3)-(constmap[i][s]+offset);
#else
- if(c) x=(constmap[i][s]+offset)-(constmap[i][s]+offset);
- else if (addr!=temp) emit_mov(addr,temp);
+ if(!c) a=addr;
#endif
//gen_tlb_addr_w(temp,map);
//emit_writebyte_indexed(tl,(int)rdram-0x80000000,temp);
- emit_writebyte_indexed_tlb(tl,x,temp,map,temp);
+ emit_writebyte_indexed_tlb(tl,x,a,map,a);
}
type=STOREB_STUB;
}
if (opcode[i]==0x29) { // SH
if(!c||memtarget) {
- int x=0;
+ int x=0,a=temp;
#ifdef BIG_ENDIAN_MIPS
if(!c) emit_xorimm(addr,2,temp);
else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset);
#else
- if(c) x=(constmap[i][s]+offset)-(constmap[i][s]+offset);
- else if (addr!=temp) emit_mov(addr,temp);
+ if(!c) a=addr;
#endif
//#ifdef
//emit_writehword_indexed_tlb(tl,x,temp,map,temp);
//#else
if(map>=0) {
- gen_tlb_addr_w(temp,map);
- emit_writehword_indexed(tl,x,temp);
+ gen_tlb_addr_w(a,map);
+ emit_writehword_indexed(tl,x,a);
}else
- emit_writehword_indexed(tl,(int)rdram-0x80000000+x,temp);
+ emit_writehword_indexed(tl,(int)rdram-0x80000000+x,a);
}
type=STOREH_STUB;
}
#else
emit_cmpmem_indexedsr12_imm((int)invalid_code,addr,1);
#endif
+ #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
+ emit_callne(invalidate_addr_reg[addr]);
+ #else
jaddr2=(int)out;
emit_jne(0);
add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<<HOST_CCREG),addr,0,0,0);
+ #endif
}
}
if(jaddr) {
int jaddr=0,jaddr2;
int case1,case2,case3;
int done0,done1,done2;
- int memtarget,c=0;
+ int memtarget=0,c=0;
int agr=AGEN1+(i&1);
u_int hr,reglist=0;
th=get_reg(i_regs->regmap,rs2[i]|64);
offset=imm[i];
if(s>=0) {
c=(i_regs->isconst>>s)&1;
- memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
- if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
+ if(c) {
+ memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
+ if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
+ }
}
assert(tl>=0);
for(hr=0;hr<HOST_REGS;hr++) {
#else
emit_cmpmem_indexedsr12_imm((int)invalid_code,temp,1);
#endif
+ #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
+ emit_callne(invalidate_addr_reg[temp]);
+ #else
jaddr3=(int)out;
emit_jne(0);
add_stub(INVCODE_STUB,jaddr3,(int)out,reglist|(1<<HOST_CCREG),temp,0,0,0);
+ #endif
}
}
if(jaddr2) add_stub(type,jaddr2,(int)out,i,offset||c||s<0?ar:s,(int)i_regs,ccadj[i],reglist);
#else
emit_cmpmem_indexedsr12_imm((int)invalid_code,ar,1);
#endif
+ #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
+ emit_callne(invalidate_addr_reg[ar]);
+ #else
jaddr3=(int)out;
emit_jne(0);
add_stub(INVCODE_STUB,jaddr3,(int)out,reglist|(1<<HOST_CCREG),ar,0,0,0);
+ #endif
}
if (opcode[i]==0x32) { // LWC2
cop2_put_dreg(copr,tl,HOST_TEMPREG);
}
}
-void new_dynarec_init()
+// clear the state completely, instead of just marking
+// things invalid like invalidate_all_pages() does
+void new_dynarec_clear_full()
{
- printf("Init new dynarec\n");
- out=(u_char *)BASE_ADDR;
- if (mmap (out, 1<<TARGET_SIZE_2,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
- -1, 0) <= 0) {printf("mmap() failed\n");}
-#ifdef MUPEN64
- rdword=&readmem_dword;
- fake_pc.f.r.rs=&readmem_dword;
- fake_pc.f.r.rt=&readmem_dword;
- fake_pc.f.r.rd=&readmem_dword;
-#endif
int n;
for(n=0x80000;n<0x80800;n++)
invalid_code[n]=1;
hash_table[n][0]=hash_table[n][2]=-1;
memset(mini_ht,-1,sizeof(mini_ht));
memset(restore_candidate,0,sizeof(restore_candidate));
+ memset(shadow,0,sizeof(shadow));
copy=shadow;
expirep=16384; // Expiry pointer, +2 blocks
pending_exception=0;
literalcount=0;
-#ifdef HOST_IMM8
- // Copy this into local area so we don't have to put it in every literal pool
- invc_ptr=invalid_code;
-#endif
stop_after_jal=0;
// TLB
+#ifndef DISABLE_TLB
using_tlb=0;
+#endif
for(n=0;n<524288;n++) // 0 .. 0x7FFFFFFF
memory_map[n]=-1;
for(n=524288;n<526336;n++) // 0x80000000 .. 0x807FFFFF
memory_map[n]=((u_int)rdram-0x80000000)>>2;
for(n=526336;n<1048576;n++) // 0x80800000 .. 0xFFFFFFFF
memory_map[n]=-1;
+ for(n=0;n<4096;n++) ll_clear(jump_in+n);
+ for(n=0;n<4096;n++) ll_clear(jump_out+n);
+ for(n=0;n<4096;n++) ll_clear(jump_dirty+n);
+}
+
+void new_dynarec_init()
+{
+ printf("Init new dynarec\n");
+ out=(u_char *)BASE_ADDR;
+ if (mmap (out, 1<<TARGET_SIZE_2,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0) <= 0) {printf("mmap() failed\n");}
+#ifdef MUPEN64
+ rdword=&readmem_dword;
+ fake_pc.f.r.rs=&readmem_dword;
+ fake_pc.f.r.rt=&readmem_dword;
+ fake_pc.f.r.rd=&readmem_dword;
+#endif
+ int n;
+ new_dynarec_clear_full();
+#ifdef HOST_IMM8
+ // Copy this into local area so we don't have to put it in every literal pool
+ invc_ptr=invalid_code;
+#endif
#ifdef MUPEN64
for(n=0;n<0x8000;n++) { // 0 .. 0x7FFFFFFF
writemem[n] = write_nomem_new;
{
cc=0;
}
+#ifdef PCSX
+ else if(/*itype[i]==LOAD||*/itype[i]==STORE||itype[i]==C1LS) // load causes weird timing issues
+ {
+ cc+=2; // 2 cycle penalty (after CLOCK_DIVIDER)
+ }
+ else if(itype[i]==C2LS)
+ {
+ cc+=4;
+ }
+#endif
else
{
cc++;
}
#endif
}
+#ifdef PCSX
+ // PCSX maps all RAM mirror invalid_code tests to 0x80000000..0x80000000+RAM_SIZE
+ if(get_page(start)<(RAM_SIZE>>12))
+ for(i=start>>12;i<=(start+slen*4)>>12;i++)
+ invalid_code[((u_int)0x80000000>>12)|i]=0;
+#endif
/* Pass 10 - Free memory by expiring oldest blocks */