eliminate text relocations
authornotaz <notasas@gmail.com>
Mon, 7 Aug 2017 22:45:57 +0000 (01:45 +0300)
committernotaz <notasas@gmail.com>
Mon, 7 Aug 2017 22:45:57 +0000 (01:45 +0300)
They are forbidden on newer versions of Android and iOS.
A bit more instructions, but only for init stuff.
No performance difference measured (basic tests only).

Cyclone.h
Main.cpp
tools/idle.s

index 1933a46..fdcff59 100644 (file)
--- a/Cyclone.h
+++ b/Cyclone.h
@@ -48,7 +48,10 @@ struct Cyclone
   int  (*IrqCallback)(int int_level);       // [r7,#0x8c] optional irq callback function, see config.h\r
   void (*ResetCallback)(void);              // [r7,#0x90] if enabled in config.h, calls this whenever RESET opcode is encountered.\r
   int  (*UnrecognizedCallback)(void);       // [r7,#0x94] if enabled in config.h, calls this whenever unrecognized opcode is encountered.\r
-  unsigned int internal[6];                 // [r7,#0x98] reserved for internal use, do not change.\r
+  void *internal_CycloneEnd;                // [r7,#0x98] internal, do not modify\r
+  int   internal_s_cycles;                  // [r7,#0x9c] internal, do not modify\r
+  void *internal_s_CycloneEnd;              // [r7,#0xa0] internal, do not modify\r
+  unsigned int internal[3];                 // [r7,#0xa4] reserved for internal use, do not change.\r
 };\r
 \r
 // Initialize. Used only if Cyclone was compiled with compressed jumptable, see config.h\r
index b6f49c3..400d3a6 100644 (file)
--- a/Main.cpp
+++ b/Main.cpp
@@ -111,50 +111,29 @@ void ltorg()
 }\r
 \r
 #if (CYCLONE_FOR_GENESIS == 2)\r
-// r12=ptr to tas in table, trashes r0,r1\r
-static void ChangeTAS(int norm)\r
+static const char *tas_ops[] = {\r
+  "Op4ad0", "Op4ad8", "Op4adf",\r
+  "Op4ae0", "Op4ae7", "Op4ae8",\r
+  "Op4af0", "Op4af8", "Op4af9",\r
+};\r
+\r
+// get handler address in r0, OT (offset table) in r2\r
+static void ChangeTASGet(unsigned int i)\r
 {\r
-  ot("  ldr r0,=Op4ad0%s\n",norm?"_":"");\r
-  ot("  mov r1,#8\n");\r
-  ot("setrtas_loop%i0%s ;@ 4ad0-4ad7\n",norm,ms?"":":");\r
-  ot("  subs r1,r1,#1\n");\r
-  ot("  str r0,[r12],#4\n");\r
-  ot("  bne setrtas_loop%i0\n",norm);\r
-  ot("  ldr r0,=Op4ad8%s\n",norm?"_":"");\r
-  ot("  mov r1,#7\n");\r
-  ot("setrtas_loop%i1%s ;@ 4ad8-4ade\n",norm,ms?"":":");\r
-  ot("  subs r1,r1,#1\n");\r
-  ot("  str r0,[r12],#4\n");\r
-  ot("  bne setrtas_loop%i1\n",norm);\r
-  ot("  ldr r0,=Op4adf%s\n",norm?"_":"");\r
-  ot("  str r0,[r12],#4\n");\r
-  ot("  ldr r0,=Op4ae0%s\n",norm?"_":"");\r
-  ot("  mov r1,#7\n");\r
-  ot("setrtas_loop%i2%s ;@ 4ae0-4ae6\n",norm,ms?"":":");\r
-  ot("  subs r1,r1,#1\n");\r
-  ot("  str r0,[r12],#4\n");\r
-  ot("  bne setrtas_loop%i2\n",norm);\r
-  ot("  ldr r0,=Op4ae7%s\n",norm?"_":"");\r
-  ot("  str r0,[r12],#4\n");\r
-  ot("  ldr r0,=Op4ae8%s\n",norm?"_":"");\r
-  ot("  mov r1,#8\n");\r
-  ot("setrtas_loop%i3%s ;@ 4ae8-4aef\n",norm,ms?"":":");\r
-  ot("  subs r1,r1,#1\n");\r
-  ot("  str r0,[r12],#4\n");\r
-  ot("  bne setrtas_loop%i3\n",norm);\r
-  ot("  ldr r0,=Op4af0%s\n",norm?"_":"");\r
-  ot("  mov r1,#8\n");\r
-  ot("setrtas_loop%i4%s ;@ 4af0-4af7\n",norm,ms?"":":");\r
-  ot("  subs r1,r1,#1\n");\r
-  ot("  str r0,[r12],#4\n");\r
-  ot("  bne setrtas_loop%i4\n",norm);\r
-  ot("  ldr r0,=Op4af8%s\n",norm?"_":"");\r
-  ot("  str r0,[r12],#4\n");\r
-  ot("  ldr r0,=Op4af9%s\n",norm?"_":"");\r
-  ot("  str r0,[r12],#4\n");\r
+  if (i >= sizeof(tas_ops) / sizeof(tas_ops[0]))\r
+    abort();\r
+  ot("  ldr r0,[r2,#%d*4] ;@ %s\n",i,tas_ops[i]);\r
+  ot("  add r0,r0,r2\n");\r
 }\r
 #endif\r
 \r
+static void LoadCycloneJumpTab(int reg, int tmp)\r
+{\r
+  ot("  adr r%d,CycloneOT_JT\n", tmp);\r
+  ot("  ldr r%d,[r%d] ;@ CycloneJumpTab-CycloneOT_JT\n", reg, tmp);\r
+  ot("  add r%d,r%d,r%d ;@ =CycloneJumpTab\n", reg, reg, tmp);\r
+}\r
+\r
 #if EMULATE_ADDRESS_ERRORS_JUMP || EMULATE_ADDRESS_ERRORS_IO\r
 static void AddressErrorWrapper(char rw, const char *dataprg, int iw)\r
 {\r
@@ -198,14 +177,13 @@ static void PrintFramework()
   ot("  mov r7,r0          ;@ r7 = Pointer to Cpu Context\n");\r
   ot("                     ;@ r0-3 = Temporary registers\n");\r
   ot("  ldrb r10,[r7,#0x46]    ;@ r10 = Flags (NZCV)\n");\r
-  ot("  ldr r6,=CycloneJumpTab ;@ r6 = Opcode Jump table\n");\r
+  ot("  ldr r6,[r7,#0x54]  ;@ r6 = Opcode Jump table (from reset)\n");\r
   ot("  ldr r5,[r7,#0x5c]  ;@ r5 = Cycles\n");\r
   ot("  ldr r4,[r7,#0x40]  ;@ r4 = Current PC + Memory Base\n");\r
   ot("                     ;@ r8 = Current Opcode\n");\r
   ot("  ldr r1,[r7,#0x44]  ;@ Get SR high T_S__III and irq level\n");\r
   ot("  mov r10,r10,lsl #28;@ r10 = Flags 0xf0000000, cpsr format\n");\r
   ot("                     ;@ r11 = Source value / Memory Base\n");\r
-  ot("  str r6,[r7,#0x54]  ;@ make a copy to avoid literal pools\n");\r
   ot("\n");\r
 #if (CYCLONE_FOR_GENESIS == 2) || EMULATE_TRACE\r
   ot("  mov r2,#0\n");\r
@@ -262,7 +240,7 @@ static void PrintFramework()
   ot("CycloneInit%s\n", ms?"":":");\r
 #if COMPRESS_JUMPTABLE\r
   ot(";@ decompress jump table\n");\r
-  ot("  ldr r12,=CycloneJumpTab\n");\r
+  LoadCycloneJumpTab(12, 1);\r
   ot("  add r0,r12,#0xe000*4 ;@ ctrl code pointer\n");\r
   ot("  ldr r1,[r0,#-4]\n");\r
   ot("  tst r1,r1\n");\r
@@ -288,7 +266,7 @@ static void PrintFramework()
   ot("  bgt unc_loop_in\n");\r
   ot("  b unc_loop\n");\r
   ot("unc_finish%s\n", ms?"":":");\r
-  ot("  ldr r12,=CycloneJumpTab\n");\r
+  LoadCycloneJumpTab(12, 1);\r
   ot("  ;@ set a-line and f-line handlers\n");\r
   ot("  add r0,r12,#0xa000*4\n");\r
   ot("  ldr r1,[r0,#4] ;@ a-line handler\n");\r
@@ -308,7 +286,7 @@ static void PrintFramework()
   ltorg();\r
 #else\r
   ot(";@ fix final jumptable entries\n");\r
-  ot("  ldr r12,=CycloneJumpTab\n");\r
+  LoadCycloneJumpTab(12, 0);\r
   ot("  add r12,r12,#0x10000*4\n");\r
   ot("  ldr r0,[r12,#-3*4]\n");\r
   ot("  str r0,[r12,#-2*4]\n");\r
@@ -320,7 +298,9 @@ static void PrintFramework()
   // --------------\r
   ot("CycloneReset%s\n", ms?"":":");\r
   ot("  stmfd sp!,{r7,lr}\n");\r
+  LoadCycloneJumpTab(12, 1);\r
   ot("  mov r7,r0\n");\r
+  ot("  str r12,[r7,#0x54] ;@ save CycloneJumpTab avoid literal pools\n");\r
   ot("  mov r0,#0\n");\r
   ot("  str r0,[r7,#0x58] ;@ state_flags\n");\r
   ot("  str r0,[r7,#0x48] ;@ OSP\n");\r
@@ -343,6 +323,77 @@ static void PrintFramework()
   ot("  ldmfd sp!,{r7,pc}\n");\r
   ot("\n");\r
 \r
+  // --------------\r
+  ot("CycloneSetRealTAS%s\n", ms?"":":");\r
+#if (CYCLONE_FOR_GENESIS == 2)\r
+  LoadCycloneJumpTab(12, 1);\r
+  ot("  tst r0,r0\n");\r
+  ot("  add r12,r12,#0x4a00*4\n");\r
+  ot("  add r12,r12,#0x00d0*4\n");\r
+  ot("  adr r2,CycloneOT_TAS_\n");\r
+  ot("  addeq r2,r2,#%lu*4\n", sizeof(tas_ops) / sizeof(tas_ops[0]));\r
+\r
+  ChangeTASGet(0);\r
+  ot("  mov r1,#8\n");\r
+  ot("setrtas_loop0%s ;@ 4ad0-4ad7\n",ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop0\n");\r
+\r
+  ChangeTASGet(1);\r
+  ot("  mov r1,#7\n");\r
+  ot("setrtas_loop1%s ;@ 4ad8-4ade\n",ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop1\n");\r
+\r
+  ChangeTASGet(2);\r
+  ot("  str r0,[r12],#4\n");\r
+  ChangeTASGet(3);\r
+  ot("  mov r1,#7\n");\r
+  ot("setrtas_loop2%s ;@ 4ae0-4ae6\n",ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop2\n");\r
+\r
+  ChangeTASGet(4);\r
+  ot("  str r0,[r12],#4\n");\r
+  ChangeTASGet(5);\r
+  ot("  mov r1,#8\n");\r
+  ot("setrtas_loop3%s ;@ 4ae8-4aef\n",ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop3\n");\r
+\r
+  ChangeTASGet(6);\r
+  ot("  mov r1,#8\n");\r
+  ot("setrtas_loop4%s ;@ 4af0-4af7\n",ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop4\n");\r
+\r
+  ChangeTASGet(7);\r
+  ot("  str r0,[r12],#4\n");\r
+  ChangeTASGet(8);\r
+  ot("  str r0,[r12],#4\n");\r
+#endif\r
+  ot("  bx lr\n");\r
+  ot("\n");\r
+\r
+  // --------------\r
+  // offset table to avoid .text relocations (forbidden by Android and iOS)\r
+  ot("CycloneOT_JT%s\n", ms?"":":");\r
+  ot("  %s %s-CycloneOT_JT\n", ms?"dcd":".long", "CycloneJumpTab");\r
+#if (CYCLONE_FOR_GENESIS == 2)\r
+  ot("CycloneOT_TAS_%s\n", ms?"":":"); // working TAS (no MD bug)\r
+  for (size_t i = 0; i < sizeof(tas_ops) / sizeof(tas_ops[0]); i++)\r
+    ot("  %s %s_-CycloneOT_TAS_\n", ms?"dcd":".long", tas_ops[i]);\r
+  ot("CycloneOT_TAS%s\n", ms?"":":"); // broken TAS\r
+  for (size_t i = 0; i < sizeof(tas_ops) / sizeof(tas_ops[0]); i++)\r
+    ot("  %s %s-CycloneOT_TAS\n", ms?"dcd":".long", tas_ops[i]);\r
+  ot("\n");\r
+#endif\r
+\r
   // --------------\r
   // 68k: XNZVC, ARM: NZCV\r
   ot("CycloneSetSr%s\n", ms?"":":");\r
@@ -494,25 +545,6 @@ static void PrintFramework()
   ot("\n");\r
   ot("\n");\r
 \r
-  // --------------\r
-  ot("CycloneSetRealTAS%s\n", ms?"":":");\r
-#if (CYCLONE_FOR_GENESIS == 2)\r
-  ot("  ldr r12,=CycloneJumpTab\n");\r
-  ot("  tst r0,r0\n");\r
-  ot("  add r12,r12,#0x4a00*4\n");\r
-  ot("  add r12,r12,#0x00d0*4\n");\r
-  ot("  beq setrtas_off\n");\r
-  ChangeTAS(1);\r
-  ot("  bx lr\n");\r
-  ot("setrtas_off%s\n",ms?"":":");\r
-  ChangeTAS(0);\r
-  ot("  bx lr\n");\r
-  ltorg();\r
-#else\r
-  ot("  bx lr\n");\r
-#endif\r
-  ot("\n");\r
-\r
   // --------------\r
   ot(";@ DoInterrupt - r0=IRQ level\n");\r
   ot("CycloneDoInterruptGoBack%s\n", ms?"":":");\r
index e55b5f1..f36588f 100644 (file)
@@ -33,8 +33,11 @@ patch_desc_table:
 .global CycloneInitIdle
 
 CycloneInitIdle:
-    ldr     r3, =CycloneJumpTab
-    ldr     r2, =patch_desc_table
+    adr     r12,offset_table
+    ldr     r3, [r12, #2*4] @ =CycloneJumpTab-ot
+    ldr     r2, [r12, #1*4] @ =patch_desc_table-ot
+    add     r3, r3, r12
+    add     r2, r2, r12
     mov     r12,#patch_desc_table_size
 
 cii_loop:
@@ -51,22 +54,30 @@ cii_loop:
     subs    r12,r12,#1
     bgt     cii_loop
 
-    ldr     r0, =have_patches
+    adr     r12,offset_table
+    ldr     r0, [r12, #0*4] @ =have_patches-ot
     mov     r1, #1
-    str     r1, [r0]
+    str     r1, [r0, r12]
     bx      lr
 
 
 .global CycloneFinishIdle
 
 CycloneFinishIdle:
-    ldr     r0, =have_patches
-    ldr     r0, [r0]
+    adr     r12,offset_table
+    ldr     r3, [r12, #0*4] @ =have_patches-ot
+    ldr     r0, [r3, r12]!
     tst     r0, r0
     bxeq    lr
 
-    ldr     r3, =CycloneJumpTab
-    ldr     r2, =patch_desc_table
+    stmfd   sp!, {r4,r5}
+    mov     r5, r3
+    ldr     r2, [r12, #1*4] @ =patch_desc_table-ot
+    ldr     r3, [r12, #2*4] @ =CycloneJumpTab-ot
+    ldr     r4, [r12, #3*4] @ =Op____-ot
+    add     r2, r2, r12
+    add     r3, r3, r12
+    add     r4, r4, r12
     mov     r12,#patch_desc_table_size
 
 cfi_loop:
@@ -74,17 +85,16 @@ cfi_loop:
     ldr     r1, [r2, #12]         @ normal
     str     r1, [r3, r0, lsl #2]
     ldrh    r0, [r2, #2]
-    ldr     r1, =Op____
     add     r0, r3, r0, lsl #2
-    str     r1, [r0]
-    str     r1, [r0, #0x800]
+    str     r4, [r0]              @ Op____
+    str     r4, [r0, #0x800]
     add     r2, r2, #16
     subs    r12,r12,#1
     bgt     cfi_loop
 
-    ldr     r0, =have_patches
     mov     r1, #0
-    str     r1, [r0]
+    str     r1, [r5]              @ have_patches
+    ldmfd   sp!, {r4,r5}
     bx      lr
 
 
@@ -154,14 +164,15 @@ idle_detector_bcc8:
     ble     exit_detector
 
     @ remove detector from Cyclone
+    adr     r12,offset_table
     mov     r0, r8, lsr #8
     cmp     r0, #0x66
-    ldrlt   r1, =Op6002
-    ldreq   r1, =Op6602
-    ldrgt   r1, =Op6702
+    ldrlt   r1, [r12, #4*4] @ =Op6002-ot
+    ldreq   r1, [r12, #4*5] @ =Op6602-ot
+    ldrgt   r1, [r12, #4*6] @ =Op6702-ot
+    add     r1, r1, r12
 
-    ldr     r3, =CycloneJumpTab
-    str     r1, [r3, r8, lsl #2]
+    str     r1, [r6, r8, lsl #2]
     bx      r1
 
 exit_detector:
@@ -171,3 +182,11 @@ exit_detector:
     beq     Op6602
     b       Op6702
 
+offset_table:
+    .word have_patches - offset_table
+    .word patch_desc_table - offset_table
+    .word CycloneJumpTab - offset_table
+    .word Op____ - offset_table
+    .word Op6002 - offset_table
+    .word Op6602 - offset_table     @ 5
+    .word Op6702 - offset_table