#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
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
}
#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
}
#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
// 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
void delayslot_alloc(struct regstat *current,int i)
{
- switch(itype[i]) {
+ switch(itype[i])
+ {
case UJUMP:
case CJUMP:
case SJUMP:
}
}
-int mchecksum()
+#if 0
+static int mchecksum(void)
{
//if(!tracedebug) return 0;
int i;
}
return sum;
}
-int rchecksum()
+
+static int rchecksum(void)
{
int i;
int sum=0;
sum^=((u_int *)reg)[i];
return sum;
}
-void rlist()
+
+static void rlist(void)
{
int i;
printf("TRACE: ");
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());
}
//printf("TRACE: %x\n",(&i)[-1]);
}
+#endif
void alu_assemble(int i,struct regstat *i_regs)
{
// 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;
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
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);