new ability to adjust psx cpu clock
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / assem_arm.c
index 57c6e91..93dbf92 100644 (file)
@@ -245,6 +245,7 @@ int verify_dirty(int addr)
   #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;
@@ -255,6 +256,7 @@ int verify_dirty(int addr)
     }
     source = source+(map_value<<2);
   }
+#endif
   //printf("verify_dirty: %x %x %x\n",source,copy,len);
   return !memcmp((void *)source,(void *)copy,len);
 }
@@ -298,11 +300,13 @@ void get_bounds(int addr,u_int *start,u_int *end)
   #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;
 }
@@ -2780,7 +2784,7 @@ do_readstub(int n)
   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) {
@@ -2944,7 +2948,7 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i
   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_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
   emit_add(2,3,3);
   emit_writeword(3,(int)&Count);
 
@@ -3005,7 +3009,7 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i
   //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
@@ -3022,7 +3026,7 @@ inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, i
   // 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) {
@@ -3122,10 +3126,10 @@ do_writestub(int n)
   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)
@@ -3237,11 +3241,11 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target,
   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);
@@ -3298,7 +3302,7 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target,
   //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
@@ -3312,7 +3316,7 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target,
   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) {
@@ -3351,9 +3355,9 @@ do_unalignedwritestub(int n)
   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);
@@ -3504,10 +3508,12 @@ do_cop1stub(int n)
   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)
@@ -3591,6 +3597,17 @@ generate_map_const(u_int addr,int reg) {
   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)
@@ -4046,7 +4063,7 @@ void cop0_assemble(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);
@@ -4061,19 +4078,21 @@ void cop0_assemble(int i,struct regstat *i_regs)
     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,
@@ -4089,19 +4108,23 @@ void cop0_assemble(int i,struct regstat *i_regs)
         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
@@ -4110,7 +4133,7 @@ void cop0_assemble(int i,struct regstat *i_regs)
     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);
@@ -4142,7 +4165,7 @@ void cop0_assemble(int i,struct regstat *i_regs)
       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);
     }
@@ -4163,7 +4186,7 @@ void cop0_assemble(int i,struct regstat *i_regs)
     {
       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