Merge https://github.com/notaz/pcsx_rearmed
authortwinaphex <libretro@gmail.com>
Wed, 3 May 2017 01:55:32 +0000 (03:55 +0200)
committertwinaphex <libretro@gmail.com>
Wed, 3 May 2017 01:55:32 +0000 (03:55 +0200)
1  2 
libpcsxcore/new_dynarec/arm/linkage_arm.S
libpcsxcore/new_dynarec/new_dynarec.c

@@@ -20,7 -20,7 +20,7 @@@
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  
  #include "arm_features.h"
 -#include "new_dynarec_config.h"
 +#include "../new_dynarec_config.h"
  #include "linkage_offsets.h"
  
  
@@@ -93,7 -93,7 +93,7 @@@ DRC_VAR(restore_candidate, 512
  DRC_VAR(FCR0, 4)
  DRC_VAR(FCR31, 4)
  
- #ifdef __MACH__
+ #ifdef TEXRELS_FORBIDDEN
        .data
        .align 2
  ptr_jump_in:
@@@ -117,21 -117,21 +117,21 @@@ ptr_hash_table
  #endif
  
  .macro load_varadr reg var
- #if defined(HAVE_ARMV7) && !defined(__PIC__)
-       movw    \reg, #:lower16:\var
-       movt    \reg, #:upper16:\var
- #elif defined(HAVE_ARMV7) && defined(__MACH__)
+ #if defined(HAVE_ARMV7) && defined(TEXRELS_FORBIDDEN)
        movw    \reg, #:lower16:(\var-(1678f+8))
        movt    \reg, #:upper16:(\var-(1678f+8))
  1678:
        add     \reg, pc
+ #elif defined(HAVE_ARMV7) && !defined(__PIC__)
+       movw    \reg, #:lower16:\var
+       movt    \reg, #:upper16:\var
  #else
        ldr     \reg, =\var
  #endif
  .endm
  
  .macro load_varadr_ext reg var
- #if defined(HAVE_ARMV7) && defined(__MACH__) && defined(__PIC__)
+ #if defined(HAVE_ARMV7) && defined(TEXRELS_FORBIDDEN)
        movw    \reg, #:lower16:(ptr_\var-(1678f+8))
        movt    \reg, #:upper16:(ptr_\var-(1678f+8))
  1678:
  #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
@@@ -366,16 -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];
      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;
    EntryHi=BadVAddr&0xFFFFE000;
    return get_addr_ht(0x80000000);
  }
 +
  // Look up address in hash table first
  void *get_addr_ht(u_int vaddr)
  {
@@@ -779,13 -763,13 +779,13 @@@ void alloc_all(struct regstat *cur,int 
  }
  
  #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
@@@ -959,26 -943,23 +959,26 @@@ static void invalidate_block_range(u_in
    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)
    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;
          }
@@@ -1072,23 -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
@@@ -1113,48 -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
                }
              }
    }
  }
  
 -
 -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]);
@@@ -1734,8 -1695,7 +1734,8 @@@ void syscall_alloc(struct regstat *curr
  
  void delayslot_alloc(struct regstat *current,int i)
  {
 -  switch(itype[i]) {
 +  switch(itype[i])
 +  {
      case UJUMP:
      case CJUMP:
      case SJUMP:
@@@ -1885,8 -1845,7 +1885,8 @@@ void wb_register(signed char r,signed c
    }
  }
  
 -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)
  {
@@@ -7060,7 -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;
    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");
  
    // 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)
+   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();
      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)