(new_dynarec) Update
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / new_dynarec.c
index ec2a6fa..3083e83 100644 (file)
 #ifdef __MACH__
 #include <libkern/OSCacheControl.h>
 #endif
+#ifdef _3DS
+#include <3ds_utils.h>
+#endif
+#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
 #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
@@ -265,11 +277,20 @@ static int tracedebug=0;
 static void mprotect_w_x(void *start, void *end, int is_x)
 {
 #ifdef NO_WRITE_EXEC
+  #if defined(VITA)
+  // *Open* enables write on all memory that was
+  // allocated by sceKernelAllocMemBlockForVM()?
+  if (is_x)
+    sceKernelCloseVMDomain();
+  else
+    sceKernelOpenVMDomain();
+  #else
   u_long mstart = (u_long)start & ~4095ul;
   u_long mend = (u_long)end;
   if (mprotect((void *)mstart, mend - mstart,
                PROT_READ | (is_x ? PROT_EXEC : PROT_WRITE)) != 0)
     SysPrintf("mprotect(%c) failed: %s\n", is_x ? 'x' : 'w', strerror(errno));
+  #endif
 #endif
 }
 
@@ -287,8 +308,9 @@ static void end_tcache_write(void *start, void *end)
   #elif defined(__MACH__)
   sys_cache_control(kCacheFunctionPrepareForExecution, start, len);
   #elif defined(VITA)
-  int block = sceKernelFindMemBlockByAddr(start, len);
-  sceKernelSyncVMDomain(block, start, len);
+  sceKernelSyncVMDomain(sceBlock, start, len);
+  #elif defined(_3DS)
+  ctr_flush_invalidate_cache();
   #else
   __clear_cache(start, end);
   #endif
@@ -746,13 +768,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
@@ -1033,19 +1055,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
@@ -1678,7 +1704,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:
@@ -1828,7 +1855,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;
@@ -1841,7 +1869,8 @@ int mchecksum()
   }
   return sum;
 }
-int rchecksum()
+
+static int rchecksum(void)
 {
   int i;
   int sum=0;
@@ -1849,7 +1878,8 @@ int rchecksum()
     sum^=((u_int *)reg)[i];
   return sum;
 }
-void rlist()
+
+static void rlist(void)
 {
   int i;
   printf("TRACE: ");
@@ -1858,12 +1888,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());
@@ -1888,6 +1918,7 @@ void memdebug(int i)
   }
   //printf("TRACE: %x\n",(&i)[-1]);
 }
+#endif
 
 void alu_assemble(int i,struct regstat *i_regs)
 {
@@ -6999,7 +7030,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;
@@ -7020,22 +7051,47 @@ 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");
-  out=(u_char *)BASE_ADDR;
-#if BASE_ADDR_FIXED
-  if (mmap (out, 1<<TARGET_SIZE_2,
+
+  // allocate/prepare a buffer for translation cache
+  // 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_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
-            -1, 0) <= 0) {
+            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 = 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");
+  sceClibPrintf("translation_cache = 0x%08X \n ", translation_cache);
+  #else
+  translation_cache = mmap (NULL, 1 << TARGET_SIZE_2,
+            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();
   }
-#elif !defined(NO_WRITE_EXEC)
+  #endif
+#else
+  #ifndef NO_WRITE_EXEC
   // not all systems allow execute in data segment by default
   if (mprotect(out, 1<<TARGET_SIZE_2, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
     SysPrintf("mprotect() failed: %s\n", strerror(errno));
+  #endif
 #endif
+  out=(u_char *)BASE_ADDR;
   cycle_multiplier=200;
   new_dynarec_clear_full();
 #ifdef HOST_IMM8
@@ -7051,12 +7107,18 @@ 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 BASE_ADDR_FIXED
-  if (munmap ((void *)BASE_ADDR, 1<<TARGET_SIZE_2) < 0) {SysPrintf("munmap() failed\n");}
+#if defined(BASE_ADDR_FIXED) || defined(BASE_ADDR_DYNAMIC)
+  #ifdef VITA
+  //sceKernelFreeMemBlock(sceBlock);
+  //sceBlock = -1;
+  #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);