Merge https://github.com/notaz/pcsx_rearmed
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / new_dynarec.c
index cd63d2b..dfa17a7 100644 (file)
 #ifdef VITA
 #include <psp2/kernel/sysmem.h>
 static int sceBlock;
+int getVMBlock();
 #endif
 
 #include "new_dynarec_config.h"
-#include "emu_if.h" //emulator interface
+#include "backends/psx/emu_if.h" //emulator interface
 
 //#define DISASM
 //#define assem_debug printf
@@ -44,13 +45,17 @@ static int sceBlock;
 #define inv_debug(...)
 
 #ifdef __i386__
-#include "assem_x86.h"
+#include "x86/assem_x86.h"
 #endif
 #ifdef __x86_64__
-#include "assem_x64.h"
+#include "x64/assem_x64.h"
 #endif
 #ifdef __arm__
-#include "assem_arm.h"
+#include "arm/assem_arm.h"
+#endif
+
+#ifdef VITA
+int _newlib_vm_size_user = 1 << TARGET_SIZE_2;
 #endif
 
 #define MAXBLOCK 4096
@@ -361,14 +366,16 @@ static u_int get_vpage(u_int vaddr)
 // This is called from the recompiled JR/JALR instructions
 void *get_addr(u_int vaddr)
 {
-  u_int page=get_page(vaddr);
-  u_int vpage=get_vpage(vaddr);
-  struct ll_entry *head;
+  struct ll_entry *head = NULL;
+  u_int page            = get_page(vaddr);
+  u_int vpage           = get_vpage(vaddr);
   //printf("TRACE: count=%d next=%d (get_addr %x,page %d)\n",Count,next_interupt,vaddr,page);
   head=jump_in[page];
-  while(head!=NULL) {
-    if(head->vaddr==vaddr) {
-  //printf("TRACE: count=%d next=%d (get_addr match %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr);
+  while(head!=NULL)
+  {
+    if(head->vaddr==vaddr)
+    {
+      //printf("TRACE: count=%d next=%d (get_addr match %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr);
       u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF];
       ht_bin[3]=ht_bin[1];
       ht_bin[2]=ht_bin[0];
@@ -379,39 +386,47 @@ void *get_addr(u_int vaddr)
     head=head->next;
   }
   head=jump_dirty[vpage];
-  while(head!=NULL) {
-    if(head->vaddr==vaddr) {
+  while(head!=NULL)
+  {
+    if(head->vaddr==vaddr)
+    {
       //printf("TRACE: count=%d next=%d (get_addr match dirty %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr);
       // Don't restore blocks which are about to expire from the cache
       if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2)))
-      if(verify_dirty(head->addr)) {
-        //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;
-        if(vpage<2048) {
-          restore_candidate[vpage>>3]|=1<<(vpage&7);
-        }
-        else restore_candidate[page>>3]|=1<<(page&7);
-        u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF];
-        if(ht_bin[0]==vaddr) {
-          ht_bin[1]=(u_int)head->addr; // Replace existing entry
-        }
-        else
+        if(verify_dirty(head->addr))
         {
-          ht_bin[3]=ht_bin[1];
-          ht_bin[2]=ht_bin[0];
-          ht_bin[1]=(int)head->addr;
-          ht_bin[0]=vaddr;
+          //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;
+          if(vpage<2048)
+          {
+            restore_candidate[vpage>>3]|=1<<(vpage&7);
+          }
+          else
+          {
+            restore_candidate[page>>3]|=1<<(page&7);
+          }
+          u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF];
+
+          if(ht_bin[0]==vaddr)
+            ht_bin[1]=(u_int)head->addr; // Replace existing entry
+          else
+          {
+            ht_bin[3]=ht_bin[1];
+            ht_bin[2]=ht_bin[0];
+            ht_bin[1]=(int)head->addr;
+            ht_bin[0]=vaddr;
+          }
+          return head->addr;
         }
-        return head->addr;
-      }
     }
     head=head->next;
   }
   //printf("TRACE: count=%d next=%d (get_addr no-match %x)\n",Count,next_interupt,vaddr);
   int r=new_recompile_block(vaddr);
-  if(r==0) return get_addr(vaddr);
-  // Execute in unmapped page, generate pagefault execption
+  if(r==0)
+    return get_addr(vaddr);
+  // Execute in unmapped page, generate pagefault exception
   Status|=2;
   Cause=(vaddr<<31)|0x8;
   EPC=(vaddr&1)?vaddr-5:vaddr;
@@ -420,6 +435,7 @@ void *get_addr(u_int vaddr)
   EntryHi=BadVAddr&0xFFFFE000;
   return get_addr_ht(0x80000000);
 }
+
 // Look up address in hash table first
 void *get_addr_ht(u_int vaddr)
 {
@@ -763,13 +779,13 @@ void alloc_all(struct regstat *cur,int i)
 }
 
 #ifdef __i386__
-#include "assem_x86.c"
+#include "x86/assem_x86.c"
 #endif
 #ifdef __x86_64__
-#include "assem_x64.c"
+#include "x64/assem_x64.c"
 #endif
 #ifdef __arm__
-#include "assem_arm.c"
+#include "arm/assem_arm.c"
 #endif
 
 // Add virtual address mapping to linked list
@@ -943,23 +959,26 @@ static void invalidate_block_range(u_int block, u_int first, u_int last)
   assert(first+5>page); // NB: this assumes MAXBLOCK<=4096 (4 pages)
   assert(last<page+5);
   // Invalidate the adjacent pages if a block crosses a 4K boundary
-  while(first<page) {
+  while(first<page)
+  {
     invalidate_page(first);
     first++;
   }
-  for(first=page+1;first<last;first++) {
+  for(first=page+1;first<last;first++)
+  {
     invalidate_page(first);
   }
-  #ifdef __arm__
-    do_clear_cache();
-  #endif
+
+#ifdef __arm__
+  do_clear_cache();
+#endif
 
   // Don't trap writes
   invalid_code[block]=1;
 
-  #ifdef USE_MINI_HT
+#ifdef USE_MINI_HT
   memset(mini_ht,-1,sizeof(mini_ht));
-  #endif
+#endif
 }
 
 void invalidate_block(u_int block)
@@ -967,19 +986,22 @@ void invalidate_block(u_int block)
   u_int page=get_page(block<<12);
   u_int vpage=get_vpage(block<<12);
   inv_debug("INVALIDATE: %x (%d)\n",block<<12,page);
-  //inv_debug("invalid_code[block]=%d\n",invalid_code[block]);
   u_int first,last;
   first=last=page;
   struct ll_entry *head;
   head=jump_dirty[vpage];
   //printf("page=%d vpage=%d\n",page,vpage);
-  while(head!=NULL) {
+  while(head!=NULL)
+  {
     u_int start,end;
-    if(vpage>2047||(head->vaddr>>12)==block) { // Ignore vaddr hash collision
+    if(vpage>2047||(head->vaddr>>12)==block)
+    { // Ignore vaddr hash collision
       get_bounds((int)head->addr,&start,&end);
       //printf("start: %x end: %x\n",start,end);
-      if(page<2048&&start>=(u_int)rdram&&end<(u_int)rdram+RAM_SIZE) {
-        if(((start-(u_int)rdram)>>12)<=page&&((end-1-(u_int)rdram)>>12)>=page) {
+      if(page<2048&&start>=(u_int)rdram&&end<(u_int)rdram+RAM_SIZE)
+      {
+        if(((start-(u_int)rdram)>>12)<=page&&((end-1-(u_int)rdram)>>12)>=page)
+        {
           if((((start-(u_int)rdram)>>12)&2047)<first) first=((start-(u_int)rdram)>>12)&2047;
           if((((end-1-(u_int)rdram)>>12)&2047)>last) last=((end-1-(u_int)rdram)>>12)&2047;
         }
@@ -1050,19 +1072,23 @@ void invalidate_addr(u_int addr)
 
 // This is called when loading a save state.
 // Anything could have changed, so invalidate everything.
-void invalidate_all_pages()
+void invalidate_all_pages(void)
 {
   u_int page;
   for(page=0;page<4096;page++)
     invalidate_page(page);
   for(page=0;page<1048576;page++)
-    if(!invalid_code[page]) {
+  {
+    if(!invalid_code[page])
+    {
       restore_candidate[(page&2047)>>3]|=1<<(page&7);
       restore_candidate[((page&2047)>>3)+256]|=1<<(page&7);
     }
-  #ifdef USE_MINI_HT
+  }
+
+#ifdef USE_MINI_HT
   memset(mini_ht,-1,sizeof(mini_ht));
-  #endif
+#endif
 }
 
 // Add an entry to jump_out after making a link
@@ -1087,37 +1113,48 @@ void clean_blocks(u_int page)
   struct ll_entry *head;
   inv_debug("INV: clean_blocks page=%d\n",page);
   head=jump_dirty[page];
-  while(head!=NULL) {
-    if(!invalid_code[head->vaddr>>12]) {
+  while(head!=NULL)
+  {
+    if(!invalid_code[head->vaddr>>12])
+    {
       // Don't restore blocks which are about to expire from the cache
-      if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) {
+      if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2)))
+      {
         u_int start,end;
-        if(verify_dirty(head->addr)) {
+        if(verify_dirty(head->addr))
+        {
           //printf("Possibly Restore %x (%x)\n",head->vaddr, (int)head->addr);
           u_int i;
           u_int inv=0;
           get_bounds((int)head->addr,&start,&end);
-          if(start-(u_int)rdram<RAM_SIZE) {
-            for(i=(start-(u_int)rdram+0x80000000)>>12;i<=(end-1-(u_int)rdram+0x80000000)>>12;i++) {
+          if(start-(u_int)rdram<RAM_SIZE)
+          {
+            for(i=(start-(u_int)rdram+0x80000000)>>12;i<=(end-1-(u_int)rdram+0x80000000)>>12;i++)
+            {
               inv|=invalid_code[i];
             }
           }
-          else if((signed int)head->vaddr>=(signed int)0x80000000+RAM_SIZE) {
+          else if((signed int)head->vaddr>=(signed int)0x80000000+RAM_SIZE)
+          {
             inv=1;
           }
-          if(!inv) {
+          if(!inv)
+          {
             void * clean_addr=(void *)get_clean_addr((int)head->addr);
-            if((((u_int)clean_addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) {
+            if((((u_int)clean_addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2)))
+            {
               u_int ppage=page;
               inv_debug("INV: Restored %x (%x/%x)\n",head->vaddr, (int)head->addr, (int)clean_addr);
               //printf("page=%x, addr=%x\n",page,head->vaddr);
               //assert(head->vaddr>>12==(page|0x80000));
               ll_add_flags(jump_in+ppage,head->vaddr,head->reg_sv_flags,clean_addr);
               u_int *ht_bin=hash_table[((head->vaddr>>16)^head->vaddr)&0xFFFF];
-              if(ht_bin[0]==head->vaddr) {
+              if(ht_bin[0]==head->vaddr)
+              {
                 ht_bin[1]=(u_int)clean_addr; // Replace existing entry
               }
-              if(ht_bin[2]==head->vaddr) {
+              if(ht_bin[2]==head->vaddr)
+              {
                 ht_bin[3]=(u_int)clean_addr; // Replace existing entry
               }
             }
@@ -1129,15 +1166,17 @@ void clean_blocks(u_int page)
   }
 }
 
-
-void mov_alloc(struct regstat *current,int i)
+static void mov_alloc(struct regstat *current,int i)
 {
   // Note: Don't need to actually alloc the source registers
-  if((~current->is32>>rs1[i])&1) {
+  if((~current->is32>>rs1[i])&1)
+  {
     //alloc_reg64(current,i,rs1[i]);
     alloc_reg64(current,i,rt1[i]);
     current->is32&=~(1LL<<rt1[i]);
-  } else {
+  }
+  else
+  {
     //alloc_reg(current,i,rs1[i]);
     alloc_reg(current,i,rt1[i]);
     current->is32|=(1LL<<rt1[i]);
@@ -1695,7 +1734,8 @@ void syscall_alloc(struct regstat *current,int i)
 
 void delayslot_alloc(struct regstat *current,int i)
 {
-  switch(itype[i]) {
+  switch(itype[i])
+  {
     case UJUMP:
     case CJUMP:
     case SJUMP:
@@ -1845,7 +1885,8 @@ void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32
   }
 }
 
-int mchecksum()
+#if 0
+static int mchecksum(void)
 {
   //if(!tracedebug) return 0;
   int i;
@@ -1858,7 +1899,8 @@ int mchecksum()
   }
   return sum;
 }
-int rchecksum()
+
+static int rchecksum(void)
 {
   int i;
   int sum=0;
@@ -1866,7 +1908,8 @@ int rchecksum()
     sum^=((u_int *)reg)[i];
   return sum;
 }
-void rlist()
+
+static void rlist(void)
 {
   int i;
   printf("TRACE: ");
@@ -1875,12 +1918,12 @@ void rlist()
   printf("\n");
 }
 
-void enabletrace()
+static void enabletrace(void)
 {
   tracedebug=1;
 }
 
-void memdebug(int i)
+static void memdebug(int i)
 {
   //printf("TRACE: count=%d next=%d (checksum %x) lo=%8x%8x\n",Count,next_interupt,mchecksum(),(int)(reg[LOREG]>>32),(int)reg[LOREG]);
   //printf("TRACE: count=%d next=%d (rchecksum %x)\n",Count,next_interupt,rchecksum());
@@ -1905,6 +1948,7 @@ void memdebug(int i)
   }
   //printf("TRACE: %x\n",(&i)[-1]);
 }
+#endif
 
 void alu_assemble(int i,struct regstat *i_regs)
 {
@@ -7016,7 +7060,7 @@ static int new_dynarec_test(void)
 
 // clear the state completely, instead of just marking
 // things invalid like invalidate_all_pages() does
-void new_dynarec_clear_full()
+void new_dynarec_clear_full(void)
 {
   int n;
   out=(u_char *)BASE_ADDR;
@@ -7037,7 +7081,7 @@ void new_dynarec_clear_full()
   for(n=0;n<4096;n++) ll_clear(jump_dirty+n);
 }
 
-void new_dynarec_init()
+void new_dynarec_init(void)
 {
   SysPrintf("Init new dynarec\n");
 
@@ -7045,37 +7089,45 @@ void new_dynarec_init()
   // see assem_arm.h for some explanation
 #if   defined(BASE_ADDR_FIXED)
   if (mmap (translation_cache, 1 << TARGET_SIZE_2,
-            PROT_READ | PROT_WRITE | PROT_EXEC,
-            MAP_PRIVATE | MAP_ANONYMOUS,
-            -1, 0) != translation_cache) {
+        PROT_READ | PROT_WRITE | PROT_EXEC,
+        MAP_PRIVATE | MAP_ANONYMOUS,
+        -1, 0) != translation_cache)
+  {
     SysPrintf("mmap() failed: %s\n", strerror(errno));
     SysPrintf("disable BASE_ADDR_FIXED and recompile\n");
     abort();
   }
 #elif defined(BASE_ADDR_DYNAMIC)
-  #ifdef VITA
-  sceBlock = sceKernelAllocMemBlockForVM("code", 1 << TARGET_SIZE_2);
+#ifdef VITA
+  sceBlock = getVMBlock();//sceKernelAllocMemBlockForVM("code", 1 << TARGET_SIZE_2);
   if (sceBlock < 0)
     SysPrintf("sceKernelAllocMemBlockForVM failed\n");
   int ret = sceKernelGetMemBlockBase(sceBlock, (void **)&translation_cache);
   if (ret < 0)
     SysPrintf("sceKernelGetMemBlockBase failed\n");
-  #else
+    
+  sceKernelOpenVMDomain();
+  sceClibPrintf("translation_cache = 0x%08X \n ", translation_cache);
+#elif defined(_MSC_VER)
+  base_addr = VirtualAlloc(NULL, 1<<TARGET_SIZE_2, MEM_COMMIT | MEM_RESERVE,
+      PAGE_EXECUTE_READWRITE);
+#else
   translation_cache = mmap (NULL, 1 << TARGET_SIZE_2,
-            PROT_READ | PROT_WRITE | PROT_EXEC,
-            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+      PROT_READ | PROT_WRITE | PROT_EXEC,
+      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   if (translation_cache == MAP_FAILED) {
     SysPrintf("mmap() failed: %s\n", strerror(errno));
     abort();
   }
-  #endif
+#endif
 #else
-  #ifndef NO_WRITE_EXEC
+#ifndef NO_WRITE_EXEC
   // not all systems allow execute in data segment by default
   if (mprotect((void *)BASE_ADDR, 1<<TARGET_SIZE_2, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
     SysPrintf("mprotect() failed: %s\n", strerror(errno));
-  #endif
 #endif
+#endif
+
   out=(u_char *)BASE_ADDR;
   cycle_multiplier=200;
   new_dynarec_clear_full();
@@ -7092,24 +7144,28 @@ void new_dynarec_init()
     SysPrintf("warning: RAM is not directly mapped, performance will suffer\n");
 }
 
-void new_dynarec_cleanup()
+void new_dynarec_cleanup(void)
 {
   int n;
 #if defined(BASE_ADDR_FIXED) || defined(BASE_ADDR_DYNAMIC)
-  #ifdef VITA
-  sceKernelFreeMemBlock(sceBlock);
-  sceBlock = -1;
-  #else
+#ifndef VITA
+#if defined(_MSC_VER)
+  VirtualFree(base_addr, 0, MEM_RELEASE);
+#else
   if (munmap ((void *)BASE_ADDR, 1<<TARGET_SIZE_2) < 0)
     SysPrintf("munmap() failed\n");
-  #endif
 #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);
-  #ifdef ROM_COPY
+#endif
+#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);
+#ifdef ROM_COPY
   if (munmap (ROM_COPY, 67108864) < 0) {SysPrintf("munmap() failed\n");}
-  #endif
+#endif
 }
 
 static u_int *get_source_start(u_int addr, u_int *limit)