drc: make sure dyna_linker is really called from stub
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / new_dynarec.c
index d837138..74451c7 100644 (file)
@@ -1240,6 +1240,8 @@ void add_link(u_int vaddr,void *src)
 {
   u_int page=get_page(vaddr);
   inv_debug("add_link: %x -> %x (%d)\n",(int)src,vaddr,page);
+  int *ptr=(int *)(src+4);
+  assert((*ptr&0x0fff0000)==0x059f0000);
   ll_add(jump_out+page,vaddr,src);
   //int ptr=get_pointer(src);
   //inv_debug("add_link: Pointer is to %x\n",(int)ptr);
@@ -2766,6 +2768,7 @@ void load_assemble(int i,struct regstat *i_regs)
   int offset;
   int jaddr=0;
   int memtarget=0,c=0;
+  int fastload_reg_override=0;
   u_int hr,reglist=0;
   th=get_reg(i_regs->regmap,rt1[i]|64);
   tl=get_reg(i_regs->regmap,rt1[i]);
@@ -2820,6 +2823,7 @@ void load_assemble(int i,struct regstat *i_regs)
         if(sp_in_mirror&&rs1[i]==29) {
           emit_andimm(addr,~0x00e00000,HOST_TEMPREG);
           emit_cmpimm(HOST_TEMPREG,RAM_SIZE);
+          fastload_reg_override=HOST_TEMPREG;
         }
         else
         #endif
@@ -2864,9 +2868,8 @@ void load_assemble(int i,struct regstat *i_regs)
 #else
           if(!c) a=addr;
 #endif
-#ifdef PCSX
-          if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+          if(fastload_reg_override) a=fastload_reg_override;
+
           emit_movsbl_indexed_tlb(x,a,map,tl);
         }
       }
@@ -2892,9 +2895,7 @@ void load_assemble(int i,struct regstat *i_regs)
 #else
           if(!c) a=addr;
 #endif
-#ifdef PCSX
-          if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+          if(fastload_reg_override) a=fastload_reg_override;
           //#ifdef
           //emit_movswl_indexed_tlb(x,tl,map,tl);
           //else
@@ -2920,9 +2921,7 @@ void load_assemble(int i,struct regstat *i_regs)
     if(!c||memtarget) {
       if(!dummy) {
         int a=addr;
-#ifdef PCSX
-        if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+        if(fastload_reg_override) a=fastload_reg_override;
         //emit_readword_indexed((int)rdram-0x80000000,addr,tl);
         #ifdef HOST_IMM_ADDR32
         if(c)
@@ -2956,9 +2955,8 @@ void load_assemble(int i,struct regstat *i_regs)
 #else
           if(!c) a=addr;
 #endif
-#ifdef PCSX
-          if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+          if(fastload_reg_override) a=fastload_reg_override;
+
           emit_movzbl_indexed_tlb(x,a,map,tl);
         }
       }
@@ -2984,9 +2982,7 @@ void load_assemble(int i,struct regstat *i_regs)
 #else
           if(!c) a=addr;
 #endif
-#ifdef PCSX
-          if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+          if(fastload_reg_override) a=fastload_reg_override;
           //#ifdef
           //emit_movzwl_indexed_tlb(x,tl,map,tl);
           //#else
@@ -3013,9 +3009,7 @@ void load_assemble(int i,struct regstat *i_regs)
     if(!c||memtarget) {
       if(!dummy) {
         int a=addr;
-#ifdef PCSX
-        if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+        if(fastload_reg_override) a=fastload_reg_override;
         //emit_readword_indexed((int)rdram-0x80000000,addr,tl);
         #ifdef HOST_IMM_ADDR32
         if(c)
@@ -3036,9 +3030,7 @@ void load_assemble(int i,struct regstat *i_regs)
     if(!c||memtarget) {
       if(!dummy) {
         int a=addr;
-#ifdef PCSX
-        if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+        if(fastload_reg_override) a=fastload_reg_override;
         //gen_tlb_addr_r(tl,map);
         //if(th>=0) emit_readword_indexed((int)rdram-0x80000000,addr,th);
         //emit_readword_indexed((int)rdram-0x7FFFFFFC,addr,tl);
@@ -3103,6 +3095,7 @@ void store_assemble(int i,struct regstat *i_regs)
   int jaddr=0,jaddr2,type;
   int memtarget=0,c=0;
   int agr=AGEN1+(i&1);
+  int faststore_reg_override=0;
   u_int hr,reglist=0;
   th=get_reg(i_regs->regmap,rs2[i]|64);
   tl=get_reg(i_regs->regmap,rs2[i]);
@@ -3131,6 +3124,7 @@ void store_assemble(int i,struct regstat *i_regs)
       if(sp_in_mirror&&rs1[i]==29) {
         emit_andimm(addr,~0x00e00000,HOST_TEMPREG);
         emit_cmpimm(HOST_TEMPREG,RAM_SIZE);
+        faststore_reg_override=HOST_TEMPREG;
       }
       else
       #endif
@@ -3177,9 +3171,7 @@ void store_assemble(int i,struct regstat *i_regs)
 #else
       if(!c) a=addr;
 #endif
-#ifdef PCSX
-      if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+      if(faststore_reg_override) a=faststore_reg_override;
       //gen_tlb_addr_w(temp,map);
       //emit_writebyte_indexed(tl,(int)rdram-0x80000000,temp);
       emit_writebyte_indexed_tlb(tl,x,a,map,a);
@@ -3195,9 +3187,7 @@ void store_assemble(int i,struct regstat *i_regs)
 #else
       if(!c) a=addr;
 #endif
-#ifdef PCSX
-      if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+      if(faststore_reg_override) a=faststore_reg_override;
       //#ifdef
       //emit_writehword_indexed_tlb(tl,x,temp,map,temp);
       //#else
@@ -3212,9 +3202,7 @@ void store_assemble(int i,struct regstat *i_regs)
   if (opcode[i]==0x2B) { // SW
     if(!c||memtarget) {
       int a=addr;
-#ifdef PCSX
-      if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+      if(faststore_reg_override) a=faststore_reg_override;
       //emit_writeword_indexed(tl,(int)rdram-0x80000000,addr);
       emit_writeword_indexed_tlb(tl,0,a,map,temp);
     }
@@ -3223,9 +3211,7 @@ void store_assemble(int i,struct regstat *i_regs)
   if (opcode[i]==0x3F) { // SD
     if(!c||memtarget) {
       int a=addr;
-#ifdef PCSX
-      if(sp_in_mirror&&rs1[i]==29) a=HOST_TEMPREG;
-#endif
+      if(faststore_reg_override) a=faststore_reg_override;
       if(rs2[i]) {
         assert(th>=0);
         //emit_writeword_indexed(th,(int)rdram-0x80000000,addr);
@@ -5152,9 +5138,45 @@ add_to_linker(int addr,int target,int ext)
   linkcount++;
 }
 
+static void ujump_assemble_write_ra(int i)
+{
+  int rt;
+  unsigned int return_address;
+  rt=get_reg(branch_regs[i].regmap,31);
+  assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
+  //assert(rt>=0);
+  return_address=start+i*4+8;
+  if(rt>=0) {
+    #ifdef USE_MINI_HT
+    if(internal_branch(branch_regs[i].is32,return_address)&&rt1[i+1]!=31) {
+      int temp=-1; // note: must be ds-safe
+      #ifdef HOST_TEMPREG
+      temp=HOST_TEMPREG;
+      #endif
+      if(temp>=0) do_miniht_insert(return_address,rt,temp);
+      else emit_movimm(return_address,rt);
+    }
+    else
+    #endif
+    {
+      #ifdef REG_PREFETCH
+      if(temp>=0) 
+      {
+        if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp);
+      }
+      #endif
+      emit_movimm(return_address,rt); // PC into link register
+      #ifdef IMM_PREFETCH
+      emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]);
+      #endif
+    }
+  }
+}
+
 void ujump_assemble(int i,struct regstat *i_regs)
 {
   signed char *i_regmap=i_regs->regmap;
+  int ra_done=0;
   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
   address_generation(i+1,i_regs,regs[i].regmap_entry);
   #ifdef REG_PREFETCH
@@ -5166,38 +5188,9 @@ void ujump_assemble(int i,struct regstat *i_regs)
     if(i_regmap[temp]==PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp);
   }
   #endif
-  if(rt1[i]==31) {
-    int rt;
-    unsigned int return_address;
-    rt=get_reg(branch_regs[i].regmap,31);
-    assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
-    //assert(rt>=0);
-    return_address=start+i*4+8;
-    if(rt>=0) {
-      #ifdef USE_MINI_HT
-      if(internal_branch(branch_regs[i].is32,return_address)&&rt1[i+1]!=31) {
-        int temp=-1; // note: must be ds-safe
-        #ifdef HOST_TEMPREG
-        temp=HOST_TEMPREG;
-        #endif
-        if(temp>=0) do_miniht_insert(return_address,rt,temp);
-        else emit_movimm(return_address,rt);
-      }
-      else
-      #endif
-      {
-        #ifdef REG_PREFETCH
-        if(temp>=0) 
-        {
-          if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp);
-        }
-        #endif
-        emit_movimm(return_address,rt); // PC into link register
-        #ifdef IMM_PREFETCH
-        emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]);
-        #endif
-      }
-    }
+  if(rt1[i]==31&&(rt1[i]==rs1[i+1]||rt1[i]==rs2[i+1])) {
+    ujump_assemble_write_ra(i); // writeback ra for DS
+    ra_done=1;
   }
   ds_assemble(i+1,i_regs);
   uint64_t bc_unneeded=branch_regs[i].u;
@@ -5207,6 +5200,8 @@ void ujump_assemble(int i,struct regstat *i_regs)
   wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32,
                 bc_unneeded,bc_unneeded_upper);
   load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,CCREG,CCREG);
+  if(!ra_done&&rt1[i]==31)
+    ujump_assemble_write_ra(i);
   int cc,adj;
   cc=get_reg(branch_regs[i].regmap,CCREG);
   assert(cc==HOST_CCREG);
@@ -5230,11 +5225,33 @@ void ujump_assemble(int i,struct regstat *i_regs)
   }
 }
 
+static void rjump_assemble_write_ra(int i)
+{
+  int rt,return_address;
+  assert(rt1[i+1]!=rt1[i]);
+  assert(rt2[i+1]!=rt1[i]);
+  rt=get_reg(branch_regs[i].regmap,rt1[i]);
+  assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
+  assert(rt>=0);
+  return_address=start+i*4+8;
+  #ifdef REG_PREFETCH
+  if(temp>=0) 
+  {
+    if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp);
+  }
+  #endif
+  emit_movimm(return_address,rt); // PC into link register
+  #ifdef IMM_PREFETCH
+  emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]);
+  #endif
+}
+
 void rjump_assemble(int i,struct regstat *i_regs)
 {
   signed char *i_regmap=i_regs->regmap;
   int temp;
   int rs,cc,adj;
+  int ra_done=0;
   rs=get_reg(branch_regs[i].regmap,rs1[i]);
   assert(rs>=0);
   if(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1]) {
@@ -5261,6 +5278,10 @@ void rjump_assemble(int i,struct regstat *i_regs)
     if(rh>=0) do_preload_rhash(rh);
   }
   #endif
+  if(rt1[i]!=0&&(rt1[i]==rs1[i+1]||rt1[i]==rs2[i+1])) {
+    rjump_assemble_write_ra(i);
+    ra_done=1;
+  }
   ds_assemble(i+1,i_regs);
   uint64_t bc_unneeded=branch_regs[i].u;
   uint64_t bc_unneeded_upper=branch_regs[i].uu;
@@ -5270,25 +5291,8 @@ void rjump_assemble(int i,struct regstat *i_regs)
   wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,regs[i].is32,
                 bc_unneeded,bc_unneeded_upper);
   load_regs(regs[i].regmap,branch_regs[i].regmap,regs[i].was32,rs1[i],CCREG);
-  if(rt1[i]!=0) {
-    int rt,return_address;
-    assert(rt1[i+1]!=rt1[i]);
-    assert(rt2[i+1]!=rt1[i]);
-    rt=get_reg(branch_regs[i].regmap,rt1[i]);
-    assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
-    assert(rt>=0);
-    return_address=start+i*4+8;
-    #ifdef REG_PREFETCH
-    if(temp>=0) 
-    {
-      if(i_regmap[temp]!=PTEMP) emit_movimm((int)hash_table[((return_address>>16)^return_address)&0xFFFF],temp);
-    }
-    #endif
-    emit_movimm(return_address,rt); // PC into link register
-    #ifdef IMM_PREFETCH
-    emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]);
-    #endif
-  }
+  if(!ra_done&&rt1[i]!=0)
+    rjump_assemble_write_ra(i);
   cc=get_reg(branch_regs[i].regmap,CCREG);
   assert(cc==HOST_CCREG);
   #ifdef USE_MINI_HT
@@ -8251,7 +8255,9 @@ int new_recompile_block(int addr)
       case 0x24: strcpy(insn[i],"LBU"); type=LOAD; break;
       case 0x25: strcpy(insn[i],"LHU"); type=LOAD; break;
       case 0x26: strcpy(insn[i],"LWR"); type=LOADLR; break;
+#ifndef FORCE32
       case 0x27: strcpy(insn[i],"LWU"); type=LOAD; break;
+#endif
       case 0x28: strcpy(insn[i],"SB"); type=STORE; break;
       case 0x29: strcpy(insn[i],"SH"); type=STORE; break;
       case 0x2A: strcpy(insn[i],"SWL"); type=STORELR; break;
@@ -8895,8 +8901,6 @@ int new_recompile_block(int addr)
           clear_const(&current,rt1[i]);
           alloc_cc(&current,i);
           dirty_reg(&current,CCREG);
-          ooo[i]=1;
-          delayslot_alloc(&current,i+1);
           if (rt1[i]==31) {
             alloc_reg(&current,i,31);
             dirty_reg(&current,31);
@@ -8907,6 +8911,8 @@ int new_recompile_block(int addr)
             #endif
             //current.is32|=1LL<<rt1[i];
           }
+          ooo[i]=1;
+          delayslot_alloc(&current,i+1);
           //current.isconst=0; // DEBUG
           ds=1;
           //printf("i=%d, isconst=%x\n",i,current.isconst);
@@ -10986,10 +10992,14 @@ int new_recompile_block(int addr)
 #ifdef PCSX
   if (start == 0x80030000) {
     // nasty hack for fastbios thing
+    // override block entry to this code
     instr_addr0_override=(u_int)out;
     emit_movimm(start,0);
-    emit_readword((int)&pcaddr,1);
+    // abuse io address var as a flag that we
+    // have already returned here once
+    emit_readword((int)&address,1);
     emit_writeword(0,(int)&pcaddr);
+    emit_writeword(0,(int)&address);
     emit_cmp(0,1);
     emit_jne((int)new_dyna_leave);
   }