drc: rework for 64bit, part 1
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / assem_arm.c
index 21640f8..7641bbc 100644 (file)
@@ -43,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;
@@ -121,26 +127,27 @@ static u_int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
 
 /* Linker */
 
-static void set_jump_target(int addr,u_int target)
+static void set_jump_target(void *addr, void *target_)
 {
-  u_char *ptr=(u_char *)addr;
+  u_int target = (u_int)target_;
+  u_char *ptr = addr;
   u_int *ptr2=(u_int *)ptr;
   if(ptr[3]==0xe2) {
     assert((target-(u_int)ptr2-8)<1024);
-    assert((addr&3)==0);
+    assert(((uintptr_t)addr&3)==0);
     assert((target&3)==0);
     *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>2)|0xF00;
-    //printf("target=%x addr=%x insn=%x\n",target,addr,*ptr2);
+    //printf("target=%x addr=%p insn=%x\n",target,addr,*ptr2);
   }
   else if(ptr[3]==0x72) {
     // generated by emit_jno_unlikely
     if((target-(u_int)ptr2-8)<1024) {
-      assert((addr&3)==0);
+      assert(((uintptr_t)addr&3)==0);
       assert((target&3)==0);
       *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>2)|0xF00;
     }
     else if((target-(u_int)ptr2-8)<4096&&!((target-(u_int)ptr2-8)&15)) {
-      assert((addr&3)==0);
+      assert(((uintptr_t)addr&3)==0);
       assert((target&3)==0);
       *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>4)|0xE00;
     }
@@ -221,9 +228,9 @@ static int get_pointer(void *stub)
 
 // Find the "clean" entry point from a "dirty" entry point
 // by skipping past the call to verify_code
-static u_int get_clean_addr(int addr)
+static void *get_clean_addr(void *addr)
 {
-  int *ptr=(int *)addr;
+  signed int *ptr = addr;
   #ifndef HAVE_ARMV7
   ptr+=4;
   #else
@@ -233,22 +240,29 @@ static u_int get_clean_addr(int addr)
   assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
   ptr++;
   if((*ptr&0xFF000000)==0xea000000) {
-    return (int)ptr+((*ptr<<8)>>6)+8; // follow jump
+    return (char *)ptr+((*ptr<<8)>>6)+8; // follow jump
   }
-  return (u_int)ptr;
+  return ptr;
 }
 
 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);
@@ -265,7 +279,7 @@ static int verify_dirty(u_int *ptr)
 
 // This doesn't necessarily find all clean entry points, just
 // guarantees that it's not dirty
-static int isclean(int addr)
+static int isclean(void *addr)
 {
   #ifndef HAVE_ARMV7
   u_int *ptr=((u_int *)addr)+4;
@@ -285,14 +299,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);
@@ -1637,16 +1658,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);
 }
@@ -2406,10 +2468,10 @@ static void literal_pool_jumpover(int n)
   if(n) {
     if((int)out-literals[0][0]<4096-n) return;
   }
-  int jaddr=(int)out;
+  void *jaddr = out;
   emit_jmp(0);
   literal_pool(0);
-  set_jump_target(jaddr,(int)out);
+  set_jump_target(jaddr, out);
 }
 
 static void emit_extjump2(u_int addr, int target, int linker)
@@ -2525,7 +2587,7 @@ static void do_readstub(int n)
 {
   assem_debug("do_readstub %x\n",start+stubs[n][3]*4);
   literal_pool(256);
-  set_jump_target(stubs[n][1],(int)out);
+  set_jump_target(stubs[n][1], out);
   int type=stubs[n][0];
   int i=stubs[n][3];
   int rs=stubs[n][4];
@@ -2539,7 +2601,8 @@ static void do_readstub(int n)
     rt=get_reg(i_regmap,rt1[i]);
   }
   assert(rs>=0);
-  int r,temp=-1,temp2=HOST_TEMPREG,regs_saved=0,restore_jump=0;
+  int r,temp=-1,temp2=HOST_TEMPREG,regs_saved=0;
+  void *restore_jump = NULL;
   reglist|=(1<<rs);
   for(r=0;r<=12;r++) {
     if(((1<<r)&0x13ff)&&((1<<r)&reglist)==0) {
@@ -2569,7 +2632,7 @@ static void do_readstub(int n)
     }
   }
   if(regs_saved) {
-    restore_jump=(int)out;
+    restore_jump=out;
     emit_jcc(0); // jump to reg restore
   }
   else
@@ -2595,7 +2658,7 @@ static void do_readstub(int n)
     mov_loadtype_adj(type,0,rt);
   }
   if(restore_jump)
-    set_jump_target(restore_jump,(int)out);
+    set_jump_target(restore_jump, out);
   restore_regs(reglist);
   emit_jmp(stubs[n][2]); // return address
 }
@@ -2712,7 +2775,7 @@ static void do_writestub(int n)
 {
   assem_debug("do_writestub %x\n",start+stubs[n][3]*4);
   literal_pool(256);
-  set_jump_target(stubs[n][1],(int)out);
+  set_jump_target(stubs[n][1], out);
   int type=stubs[n][0];
   int i=stubs[n][3];
   int rs=stubs[n][4];
@@ -2727,7 +2790,8 @@ static void do_writestub(int n)
   }
   assert(rs>=0);
   assert(rt>=0);
-  int rtmp,temp=-1,temp2=HOST_TEMPREG,regs_saved=0,restore_jump=0,ra;
+  int rtmp,temp=-1,temp2=HOST_TEMPREG,regs_saved=0,ra;
+  void *restore_jump = NULL;
   int reglist2=reglist|(1<<rs)|(1<<rt);
   for(rtmp=0;rtmp<=12;rtmp++) {
     if(((1<<rtmp)&0x13ff)&&((1<<rtmp)&reglist2)==0) {
@@ -2754,7 +2818,7 @@ static void do_writestub(int n)
     default:          assert(0);
   }
   if(regs_saved) {
-    restore_jump=(int)out;
+    restore_jump=out;
     emit_jcc(0); // jump to reg restore
   }
   else
@@ -2782,7 +2846,7 @@ static void do_writestub(int n)
   if(cc<0)
     emit_storereg(CCREG,2);
   if(restore_jump)
-    set_jump_target(restore_jump,(int)out);
+    set_jump_target(restore_jump, out);
   restore_regs(reglist);
   ra=stubs[n][2];
   emit_jmp(ra);
@@ -2828,7 +2892,7 @@ static void do_unalignedwritestub(int n)
 {
   assem_debug("do_unalignedwritestub %x\n",start+stubs[n][3]*4);
   literal_pool(256);
-  set_jump_target(stubs[n][1],(int)out);
+  set_jump_target(stubs[n][1], out);
 
   int i=stubs[n][3];
   struct regstat *i_regs=(struct regstat *)stubs[n][4];
@@ -2916,7 +2980,7 @@ static void do_invstub(int n)
 {
   literal_pool(20);
   u_int reglist=stubs[n][3];
-  set_jump_target(stubs[n][1],(int)out);
+  set_jump_target(stubs[n][1], out);
   save_regs(reglist);
   if(stubs[n][4]!=0) emit_mov(stubs[n][4],0);
   emit_call((int)&invalidate_addr);
@@ -2924,7 +2988,7 @@ static void do_invstub(int n)
   emit_jmp(stubs[n][2]); // return address
 }
 
-int do_dirty_stub(int i)
+void *do_dirty_stub(int i)
 {
   assem_debug("do_dirty_stub %x\n",start+i*4);
   u_int addr=(u_int)source;
@@ -2942,9 +3006,10 @@ int do_dirty_stub(int i)
   #endif
   emit_movimm(start+i*4,0);
   emit_call((int)start<(int)0xC0000000?(int)&verify_code:(int)&verify_code_vm);
-  int entry=(int)out;
+  void *entry = out;
   load_regs_entry(i);
-  if(entry==(int)out) entry=instr_addr[i];
+  if (entry == out)
+    entry = instr_addr[i];
   emit_jmp(instr_addr[i]);
   return entry;
 }
@@ -2971,7 +3036,7 @@ static void do_cop1stub(int n)
 {
   literal_pool(256);
   assem_debug("do_cop1stub %x\n",start+stubs[n][3]*4);
-  set_jump_target(stubs[n][1],(int)out);
+  set_jump_target(stubs[n][1], out);
   int i=stubs[n][3];
 //  int rs=stubs[n][4];
   struct regstat *i_regs=(struct regstat *)stubs[n][5];