#define MAXBLOCK 4096
#define MAX_OUTPUT_BLOCK_SIZE 262144
-#define CLOCK_DIVIDER 2
+
+int cycle_multiplier; // 100 for 1.0
+#define CLOCK_ADJUST(x) (((x) * cycle_multiplier + 50) / 100)
struct regstat
{
//printf("restore candidate: %x (%d) d=%d\n",vaddr,page,invalid_code[vaddr>>12]);
invalid_code[vaddr>>12]=0;
inv_code_start=inv_code_end=~0;
+#ifndef DISABLE_TLB
memory_map[vaddr>>12]|=0x40000000;
+#endif
if(vpage<2048) {
#ifndef DISABLE_TLB
if(tlb_LUT_r[vaddr>>12]) {
inv|=invalid_code[i];
}
}
+#ifndef DISABLE_TLB
if((signed int)head->vaddr>=(signed int)0xC0000000) {
u_int addr = (head->vaddr+(memory_map[head->vaddr>>12]<<2));
//printf("addr=%x start=%x end=%x\n",addr,start,end);
if(addr<start||addr>=end) inv=1;
}
+#endif
else if((signed int)head->vaddr>=(signed int)0x80000000+RAM_SIZE) {
inv=1;
}
assert(ccreg==HOST_CCREG);
assert(!is_delayslot);
emit_movimm(start+i*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((int)jump_syscall_hle); // XXX
}
assert(!is_delayslot);
emit_movimm(start+i*4+4,0); // Get PC
emit_movimm((int)psxHLEt[source[i]&7],1);
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); // XXX
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // XXX
emit_jmp((int)jump_hlecall);
}
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_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG);
emit_jmp((int)jump_intcall);
}
// printf("poor load scheduling!\n");
}
else if(c) {
+#ifndef DISABLE_TLB
if(rm>=0) {
if(!entry||entry[rm]!=mgr) {
if(itype[i]==STORE||itype[i]==STORELR||(opcode[i]&0x3b)==0x39||(opcode[i]&0x3b)==0x3a) {
}
}
}
+#endif
if(rs1[i]!=rt1[i]||itype[i]!=LOAD) {
if(!entry||entry[ra]!=agr) {
if (opcode[i]==0x22||opcode[i]==0x26) {
// Preload constants for next instruction
if(itype[i+1]==LOAD||itype[i+1]==LOADLR||itype[i+1]==STORE||itype[i+1]==STORELR||itype[i+1]==C1LS||itype[i+1]==C2LS) {
int agr,ra;
- #ifndef HOST_IMM_ADDR32
+ #if !defined(HOST_IMM_ADDR32) && !defined(DISABLE_TLB)
// Mapper entry
agr=MGEN1+((i+1)&1);
ra=get_reg(i_regs->regmap,agr);
void load_regs_entry(int t)
{
int hr;
- if(is_ds[t]) emit_addimm(HOST_CCREG,CLOCK_DIVIDER,HOST_CCREG);
- else if(ccadj[t]) emit_addimm(HOST_CCREG,-ccadj[t]*CLOCK_DIVIDER,HOST_CCREG);
+ if(is_ds[t]) emit_addimm(HOST_CCREG,CLOCK_ADJUST(1),HOST_CCREG);
+ else if(ccadj[t]) emit_addimm(HOST_CCREG,-CLOCK_ADJUST(ccadj[t]),HOST_CCREG);
if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) {
emit_storereg(CCREG,HOST_CCREG);
}
emit_jmp(0);
}
else if(*adj==0||invert) {
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(count+2),HOST_CCREG);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(count+2),HOST_CCREG);
jaddr=(int)out;
emit_jns(0);
}
else
{
- emit_cmpimm(HOST_CCREG,-CLOCK_DIVIDER*(count+2));
+ emit_cmpimm(HOST_CCREG,-CLOCK_ADJUST(count+2));
jaddr=(int)out;
emit_jns(0);
}
}
// Update cycle count
assert(branch_regs[i].regmap[HOST_CCREG]==CCREG||branch_regs[i].regmap[HOST_CCREG]==-1);
- if(stubs[n][3]) emit_addimm(HOST_CCREG,CLOCK_DIVIDER*stubs[n][3],HOST_CCREG);
+ if(stubs[n][3]) emit_addimm(HOST_CCREG,CLOCK_ADJUST((int)stubs[n][3]),HOST_CCREG);
emit_call((int)cc_interrupt);
- if(stubs[n][3]) emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*stubs[n][3],HOST_CCREG);
+ if(stubs[n][3]) emit_addimm(HOST_CCREG,-CLOCK_ADJUST((int)stubs[n][3]),HOST_CCREG);
if(stubs[n][6]==TAKEN) {
if(internal_branch(branch_regs[i].is32,ba[i]))
load_needed_regs(branch_regs[i].regmap,regs[(ba[i]-start)>>2].regmap_entry);
if(rt1[i]==31&&temp>=0) emit_prefetchreg(temp);
#endif
do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
- if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
if(internal_branch(branch_regs[i].is32,ba[i]))
assem_debug("branch: internal\n");
//do_cc(i,branch_regs[i].regmap,&adj,-1,TAKEN);
//if(adj) emit_addimm(cc,2*(ccadj[i]+2-adj),cc); // ??? - Shouldn't happen
//assert(adj==0);
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
add_stub(CC_STUB,(int)out,jump_vaddr_reg[rs],0,i,-1,TAKEN,0);
+#ifdef PCSX
+ if(itype[i+1]==COP0&&(source[i+1]&0x3f)==0x10)
+ // special case for RFE
+ emit_jmp(0);
+ else
+#endif
emit_jns(0);
//load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,-1);
#ifdef USE_MINI_HT
if(unconditional) {
do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
if(i!=(ba[i]-start)>>2 || source[i+1]!=0) {
- if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
if(internal)
assem_debug("branch: internal\n");
}
}
else if(nop) {
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
int jaddr=(int)out;
emit_jns(0);
add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
else {
int taken=0,nottaken=0,nottaken1=0;
do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert);
- if(adj&&!invert) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj&&!invert) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
if(!only32)
{
assert(s1h>=0);
#ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
if(match&&(!internal||!is_ds[(ba[i]-start)>>2])) {
if(adj) {
- emit_addimm(cc,-CLOCK_DIVIDER*adj,cc);
+ emit_addimm(cc,-CLOCK_ADJUST(adj),cc);
add_to_linker((int)out,ba[i],internal);
}else{
emit_addnop(13);
}else
#endif
{
- if(adj) emit_addimm(cc,-CLOCK_DIVIDER*adj,cc);
+ if(adj) emit_addimm(cc,-CLOCK_ADJUST(adj),cc);
store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
if(internal)
if(nottaken1) set_jump_target(nottaken1,(int)out);
if(adj) {
- if(!invert) emit_addimm(cc,CLOCK_DIVIDER*adj,cc);
+ if(!invert) emit_addimm(cc,CLOCK_ADJUST(adj),cc);
}
} // (!unconditional)
} // if(ooo)
store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
assem_debug("cycle count (adj)\n");
- if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
if(internal)
assem_debug("branch: internal\n");
if(cc==-1&&!likely[i]) {
// Cycle count isn't in a register, temporarily load it then write it out
emit_loadreg(CCREG,HOST_CCREG);
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
int jaddr=(int)out;
emit_jns(0);
add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
else{
cc=get_reg(i_regmap,CCREG);
assert(cc==HOST_CCREG);
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
int jaddr=(int)out;
emit_jns(0);
add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
if(unconditional) {
do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
if(i!=(ba[i]-start)>>2 || source[i+1]!=0) {
- if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
if(internal)
assem_debug("branch: internal\n");
}
}
else if(nevertaken) {
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
int jaddr=(int)out;
emit_jns(0);
add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
else {
int nottaken=0;
do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert);
- if(adj&&!invert) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj&&!invert) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
if(!only32)
{
assert(s1h>=0);
#ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
if(match&&(!internal||!is_ds[(ba[i]-start)>>2])) {
if(adj) {
- emit_addimm(cc,-CLOCK_DIVIDER*adj,cc);
+ emit_addimm(cc,-CLOCK_ADJUST(adj),cc);
add_to_linker((int)out,ba[i],internal);
}else{
emit_addnop(13);
}else
#endif
{
- if(adj) emit_addimm(cc,-CLOCK_DIVIDER*adj,cc);
+ if(adj) emit_addimm(cc,-CLOCK_ADJUST(adj),cc);
store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
if(internal)
}
if(adj) {
- if(!invert) emit_addimm(cc,CLOCK_DIVIDER*adj,cc);
+ if(!invert) emit_addimm(cc,CLOCK_ADJUST(adj),cc);
}
} // (!unconditional)
} // if(ooo)
store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
assem_debug("cycle count (adj)\n");
- if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
if(internal)
assem_debug("branch: internal\n");
if(cc==-1&&!likely[i]) {
// Cycle count isn't in a register, temporarily load it then write it out
emit_loadreg(CCREG,HOST_CCREG);
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
int jaddr=(int)out;
emit_jns(0);
add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
else{
cc=get_reg(i_regmap,CCREG);
assert(cc==HOST_CCREG);
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
int jaddr=(int)out;
emit_jns(0);
add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
assem_debug("cycle count (adj)\n");
if(1) {
int nottaken=0;
- if(adj&&!invert) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj&&!invert) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
if(1) {
assert(fs>=0);
emit_testimm(fs,0x800000);
} // if(!only32)
if(invert) {
- if(adj) emit_addimm(cc,-CLOCK_DIVIDER*adj,cc);
+ if(adj) emit_addimm(cc,-CLOCK_ADJUST(adj),cc);
#ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
else if(match) emit_addnop(13);
#endif
}
if(adj) {
- if(!invert) emit_addimm(cc,CLOCK_DIVIDER*adj,cc);
+ if(!invert) emit_addimm(cc,CLOCK_ADJUST(adj),cc);
}
} // (!unconditional)
} // if(ooo)
store_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
assem_debug("cycle count (adj)\n");
- if(adj) emit_addimm(cc,CLOCK_DIVIDER*(ccadj[i]+2-adj),cc);
+ if(adj) emit_addimm(cc,CLOCK_ADJUST(ccadj[i]+2-adj),cc);
load_regs_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
if(internal)
assem_debug("branch: internal\n");
if(cc==-1&&!likely[i]) {
// Cycle count isn't in a register, temporarily load it then write it out
emit_loadreg(CCREG,HOST_CCREG);
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
int jaddr=(int)out;
emit_jns(0);
add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
else{
cc=get_reg(i_regmap,CCREG);
assert(cc==HOST_CCREG);
- emit_addimm_and_set_flags(CLOCK_DIVIDER*(ccadj[i]+2),cc);
+ emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
int jaddr=(int)out;
emit_jns(0);
add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
if((opcode[i]&0x2e)==4||opcode[i]==0x11) { // BEQ/BNE/BEQL/BNEL/BC1
load_regs(regs[i].regmap_entry,regs[i].regmap,regs[i].was32,CCREG,CCREG);
}
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*(ccadj[i]+2),HOST_CCREG);
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
if(opcode[i]==2) // J
{
unconditional=1;
// 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;
+#endif
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);
fake_pc.f.r.rd=&readmem_dword;
#endif
int n;
+ cycle_multiplier=200;
new_dynarec_clear_full();
#ifdef HOST_IMM8
// Copy this into local area so we don't have to put it in every literal pool
store_regs_bt(regs[i-1].regmap,regs[i-1].is32,regs[i-1].dirty,start+i*4);
if(regs[i-1].regmap[HOST_CCREG]!=CCREG)
emit_loadreg(CCREG,HOST_CCREG);
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*(ccadj[i-1]+1),HOST_CCREG);
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i-1]+1),HOST_CCREG);
}
else if(!likely[i-2])
{
store_regs_bt(regs[i-1].regmap,regs[i-1].is32,regs[i-1].dirty,start+i*4);
if(regs[i-1].regmap[HOST_CCREG]!=CCREG)
emit_loadreg(CCREG,HOST_CCREG);
- emit_addimm(HOST_CCREG,CLOCK_DIVIDER*(ccadj[i-1]+1),HOST_CCREG);
+ emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i-1]+1),HOST_CCREG);
add_to_linker((int)out,start+i*4,0);
emit_jmp(0);
}