some drc debug patches
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / assem_arm.c
index 9a5e3a9..8693c2d 100644 (file)
 #include "pcnt.h"
 #include "arm_features.h"
 
-#if !BASE_ADDR_FIXED
+#if   defined(BASE_ADDR_FIXED)
+#elif defined(BASE_ADDR_DYNAMIC)
+char *translation_cache;
+#else
 char translation_cache[1 << TARGET_SIZE_2] __attribute__((aligned(4096)));
 #endif
 
@@ -40,6 +43,12 @@ char translation_cache[1 << TARGET_SIZE_2] __attribute__((aligned(4096)));
 
 #define unused __attribute__((unused))
 
+#ifdef DRC_DBG
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
 extern int cycle_count;
 extern int last_count;
 extern int pcaddr;
@@ -114,7 +123,7 @@ const u_int invalidate_addr_reg[16] = {
   0,
   0};
 
-static unsigned int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
+static u_int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
 
 /* Linker */
 
@@ -193,15 +202,15 @@ static void add_literal(int addr,int val)
   literalcount++;
 }
 
-static void *kill_pointer(void *stub)
+// from a pointer to external jump stub (which was produced by emit_extjump2)
+// find where the jumping insn is
+static void *find_extjump_insn(void *stub)
 {
   int *ptr=(int *)(stub+4);
-  assert((*ptr&0x0ff00000)==0x05900000);
+  assert((*ptr&0x0fff0000)==0x059f0000); // ldr rx, [pc, #ofs]
   u_int offset=*ptr&0xfff;
-  int **l_ptr=(void *)ptr+offset+8;
-  int *i_ptr=*l_ptr;
-  set_jump_target((int)i_ptr,(int)stub);
-  return i_ptr;
+  void **l_ptr=(void *)ptr+offset+8;
+  return *l_ptr;
 }
 
 // find where external branch is liked to using addr of it's stub:
@@ -211,11 +220,7 @@ static void *kill_pointer(void *stub)
 static int get_pointer(void *stub)
 {
   //printf("get_pointer(%x)\n",(int)stub);
-  int *ptr=(int *)(stub+4);
-  assert((*ptr&0x0fff0000)==0x059f0000);
-  u_int offset=*ptr&0xfff;
-  int **l_ptr=(void *)ptr+offset+8;
-  int *i_ptr=*l_ptr;
+  int *i_ptr=find_extjump_insn(stub);
   assert((*i_ptr&0x0f000000)==0x0a000000);
   return (int)i_ptr+((*i_ptr<<8)>>6)+8;
 }
@@ -242,14 +247,21 @@ static u_int get_clean_addr(int addr)
 static int verify_dirty(u_int *ptr)
 {
   #ifndef HAVE_ARMV7
+  u_int offset;
   // get from literal pool
   assert((*ptr&0xFFFF0000)==0xe59f0000);
-  u_int offset=*ptr&0xfff;
-  u_int *l_ptr=(void *)ptr+offset+8;
-  u_int source=l_ptr[0];
-  u_int copy=l_ptr[1];
-  u_int len=l_ptr[2];
-  ptr+=4;
+  offset=*ptr&0xfff;
+  u_int source=*(u_int*)((void *)ptr+offset+8);
+  ptr++;
+  assert((*ptr&0xFFFF0000)==0xe59f0000);
+  offset=*ptr&0xfff;
+  u_int copy=*(u_int*)((void *)ptr+offset+8);
+  ptr++;
+  assert((*ptr&0xFFFF0000)==0xe59f0000);
+  offset=*ptr&0xfff;
+  u_int len=*(u_int*)((void *)ptr+offset+8);
+  ptr++;
+  ptr++;
   #else
   // ARMv7 movw/movt
   assert((*ptr&0xFFF00000)==0xe3000000);
@@ -286,14 +298,21 @@ static void get_bounds(int addr,u_int *start,u_int *end)
 {
   u_int *ptr=(u_int *)addr;
   #ifndef HAVE_ARMV7
+  u_int offset;
   // get from literal pool
   assert((*ptr&0xFFFF0000)==0xe59f0000);
-  u_int offset=*ptr&0xfff;
-  u_int *l_ptr=(void *)ptr+offset+8;
-  u_int source=l_ptr[0];
-  //u_int copy=l_ptr[1];
-  u_int len=l_ptr[2];
-  ptr+=4;
+  offset=*ptr&0xfff;
+  u_int source=*(u_int*)((void *)ptr+offset+8);
+  ptr++;
+  //assert((*ptr&0xFFFF0000)==0xe59f0000);
+  //offset=*ptr&0xfff;
+  //u_int copy=*(u_int*)((void *)ptr+offset+8);
+  ptr++;
+  assert((*ptr&0xFFFF0000)==0xe59f0000);
+  offset=*ptr&0xfff;
+  u_int len=*(u_int*)((void *)ptr+offset+8);
+  ptr++;
+  ptr++;
   #else
   // ARMv7 movw/movt
   assert((*ptr&0xFFF00000)==0xe3000000);
@@ -1638,16 +1657,57 @@ static void emit_set_if_carry64_32(int u1, int l1, int u2, int l2, int rt)
   emit_cmovb_imm(1,rt);
 }
 
+#ifdef DRC_DBG
+extern void gen_interupt();
+extern void do_insn_cmp();
+#define FUNCNAME(f) { (intptr_t)f, " " #f }
+static const struct {
+  intptr_t addr;
+  const char *name;
+} function_names[] = {
+  FUNCNAME(cc_interrupt),
+  FUNCNAME(gen_interupt),
+  FUNCNAME(get_addr_ht),
+  FUNCNAME(get_addr),
+  FUNCNAME(jump_handler_read8),
+  FUNCNAME(jump_handler_read16),
+  FUNCNAME(jump_handler_read32),
+  FUNCNAME(jump_handler_write8),
+  FUNCNAME(jump_handler_write16),
+  FUNCNAME(jump_handler_write32),
+  FUNCNAME(invalidate_addr),
+  FUNCNAME(verify_code_vm),
+  FUNCNAME(verify_code),
+  FUNCNAME(jump_hlecall),
+  FUNCNAME(jump_syscall_hle),
+  FUNCNAME(new_dyna_leave),
+  FUNCNAME(pcsx_mtc0),
+  FUNCNAME(pcsx_mtc0_ds),
+  FUNCNAME(do_insn_cmp),
+};
+
+static const char *func_name(intptr_t a)
+{
+  int i;
+  for (i = 0; i < sizeof(function_names)/sizeof(function_names[0]); i++)
+    if (function_names[i].addr == a)
+      return function_names[i].name;
+  return "";
+}
+#else
+#define func_name(x) ""
+#endif
+
 static void emit_call(int a)
 {
-  assem_debug("bl %x (%x+%x)\n",a,(int)out,a-(int)out-8);
+  assem_debug("bl %x (%x+%x)%s\n",a,(int)out,a-(int)out-8,func_name(a));
   u_int offset=genjmp(a);
   output_w32(0xeb000000|offset);
 }
 
 static void emit_jmp(int a)
 {
-  assem_debug("b %x (%x+%x)\n",a,(int)out,a-(int)out-8);
+  assem_debug("b %x (%x+%x)%s\n",a,(int)out,a-(int)out-8,func_name(a));
   u_int offset=genjmp(a);
   output_w32(0xea000000|offset);
 }
@@ -4094,6 +4154,17 @@ static void wb_invalidate_arm(signed char pre[],signed char entry[],uint64_t dir
 #define wb_invalidate wb_invalidate_arm
 */
 
+static void mark_clear_cache(void *target)
+{
+  u_long offset = (char *)target - (char *)BASE_ADDR;
+  u_int mask = 1u << ((offset >> 12) & 31);
+  if (!(needs_clear_cache[offset >> 17] & mask)) {
+    char *start = (char *)((u_long)target & ~4095ul);
+    start_tcache_write(start, start + 4096);
+    needs_clear_cache[offset >> 17] |= mask;
+  }
+}
+
 // Clearing the cache is rather slow on ARM Linux, so mark the areas
 // that need to be cleared, and then only clear these areas once.
 static void do_clear_cache()
@@ -4115,7 +4186,7 @@ static void do_clear_cache()
               end+=4096;
               j++;
             }else{
-              __clear_cache((void *)start,(void *)end);
+              end_tcache_write((void *)start,(void *)end);
               break;
             }
           }