From b889883d36b2d247488c82d79d1eaab4dd41d236 Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 20 Sep 2017 00:47:59 +0300 Subject: [PATCH] pass jumptable ptr from C Doing it from asm is painful because different platforms want it done differently, last try had R_ARM_REL32 relocs that ld.gold didn't like. This will also allow multiple jumptables which may be useful. --- Cyclone.h | 14 +++++++++++--- Main.cpp | 47 ++++++++++++++++++----------------------------- tools/idle.h | 9 +++++++-- tools/idle.s | 51 +++++++++++++++++++++++++-------------------------- 4 files changed, 61 insertions(+), 60 deletions(-) diff --git a/Cyclone.h b/Cyclone.h index fdcff59..f3c1835 100644 --- a/Cyclone.h +++ b/Cyclone.h @@ -19,6 +19,8 @@ extern "C" { extern int CycloneVer; // Version number of library +extern long CycloneJumpTab[65536]; // default jump table + struct Cyclone { unsigned int d[8]; // [r7,#0x00] @@ -55,10 +57,14 @@ struct Cyclone }; // Initialize. Used only if Cyclone was compiled with compressed jumptable, see config.h -void CycloneInit(void); +#define CycloneInit() \ + CycloneInitJT(CycloneJumpTab) +void CycloneInitJT(void *jt); // Reset -void CycloneReset(struct Cyclone *pcy); +#define CycloneReset(pcy) \ + CycloneResetJT(pcy, CycloneJumpTab) +void CycloneResetJT(struct Cyclone *pcy, void *jt); // Run cyclone. Cycles should be specified in context (pcy->cycles) void CycloneRun(struct Cyclone *pcy); @@ -78,7 +84,9 @@ void CyclonePack(const struct Cyclone *pcy, void *save_buffer); void CycloneUnpack(struct Cyclone *pcy, const void *save_buffer); // genesis: if 1, switch to normal TAS handlers -void CycloneSetRealTAS(int use_real); +#define CycloneSetRealTAS(use_real) \ + CycloneSetRealTAS_JT(use_real, CycloneJumpTab) +void CycloneSetRealTAS_JT(int use_real, void *jt); // These values are special return values for IrqCallback. diff --git a/Main.cpp b/Main.cpp index 400d3a6..7c6b8e3 100644 --- a/Main.cpp +++ b/Main.cpp @@ -127,13 +127,6 @@ static void ChangeTASGet(unsigned int i) } #endif -static void LoadCycloneJumpTab(int reg, int tmp) -{ - ot(" adr r%d,CycloneOT_JT\n", tmp); - ot(" ldr r%d,[r%d] ;@ CycloneJumpTab-CycloneOT_JT\n", reg, tmp); - ot(" add r%d,r%d,r%d ;@ =CycloneJumpTab\n", reg, reg, tmp); -} - #if EMULATE_ADDRESS_ERRORS_JUMP || EMULATE_ADDRESS_ERRORS_IO static void AddressErrorWrapper(char rw, const char *dataprg, int iw) { @@ -237,14 +230,16 @@ static void PrintFramework() ot("\n"); ot("\n"); - ot("CycloneInit%s\n", ms?"":":"); + ot("CycloneInitJT%s\n", ms?"":":"); #if COMPRESS_JUMPTABLE ot(";@ decompress jump table\n"); - LoadCycloneJumpTab(12, 1); + ot(" mov r12,r0 ;@ jump table\n"); ot(" add r0,r12,#0xe000*4 ;@ ctrl code pointer\n"); ot(" ldr r1,[r0,#-4]\n"); ot(" tst r1,r1\n"); ot(" movne pc,lr ;@ already uncompressed\n"); + ot(" stmfd sp!,{r7,lr}\n"); + ot(" mov r7,r12 ;@ jump table\n"); ot(" add r3,r12,#0xa000*4 ;@ handler table pointer, r12=dest\n"); ot("unc_loop%s\n", ms?"":":"); ot(" ldrh r1,[r0],#2\n"); @@ -266,9 +261,8 @@ static void PrintFramework() ot(" bgt unc_loop_in\n"); ot(" b unc_loop\n"); ot("unc_finish%s\n", ms?"":":"); - LoadCycloneJumpTab(12, 1); ot(" ;@ set a-line and f-line handlers\n"); - ot(" add r0,r12,#0xa000*4\n"); + ot(" add r0,r7,#0xa000*4\n"); ot(" ldr r1,[r0,#4] ;@ a-line handler\n"); ot(" ldr r3,[r0,#8] ;@ f-line handler\n"); ot(" mov r2,#0x1000\n"); @@ -276,31 +270,29 @@ static void PrintFramework() ot(" subs r2,r2,#1\n"); ot(" str r1,[r0],#4\n"); ot(" bgt unc_fill3\n"); - ot(" add r0,r12,#0xf000*4\n"); + ot(" add r0,r7,#0xf000*4\n"); ot(" mov r2,#0x1000\n"); ot("unc_fill4%s\n", ms?"":":"); ot(" subs r2,r2,#1\n"); ot(" str r3,[r0],#4\n"); ot(" bgt unc_fill4\n"); - ot(" bx lr\n"); + ot(" ldmfd sp!,{r7,pc}\n"); ltorg(); #else ot(";@ fix final jumptable entries\n"); - LoadCycloneJumpTab(12, 0); - ot(" add r12,r12,#0x10000*4\n"); - ot(" ldr r0,[r12,#-3*4]\n"); - ot(" str r0,[r12,#-2*4]\n"); - ot(" str r0,[r12,#-1*4]\n"); + ot(" add r0,r0,#0x10000*4\n"); + ot(" ldr r1,[r0,#-3*4]\n"); + ot(" str r1,[r0,#-2*4]\n"); + ot(" str r1,[r0,#-1*4]\n"); ot(" bx lr\n"); #endif ot("\n"); // -------------- - ot("CycloneReset%s\n", ms?"":":"); + ot("CycloneResetJT%s\n", ms?"":":"); ot(" stmfd sp!,{r7,lr}\n"); - LoadCycloneJumpTab(12, 1); ot(" mov r7,r0\n"); - ot(" str r12,[r7,#0x54] ;@ save CycloneJumpTab avoid literal pools\n"); + ot(" str r1,[r7,#0x54] ;@ save CycloneJumpTab avoid literal pools\n"); ot(" mov r0,#0\n"); ot(" str r0,[r7,#0x58] ;@ state_flags\n"); ot(" str r0,[r7,#0x48] ;@ OSP\n"); @@ -324,11 +316,10 @@ static void PrintFramework() ot("\n"); // -------------- - ot("CycloneSetRealTAS%s\n", ms?"":":"); + ot("CycloneSetRealTAS_JT%s\n", ms?"":":"); #if (CYCLONE_FOR_GENESIS == 2) - LoadCycloneJumpTab(12, 1); ot(" tst r0,r0\n"); - ot(" add r12,r12,#0x4a00*4\n"); + ot(" add r12,r1,#0x4a00*4\n"); ot(" add r12,r12,#0x00d0*4\n"); ot(" adr r2,CycloneOT_TAS_\n"); ot(" addeq r2,r2,#%lu*4\n", sizeof(tas_ops) / sizeof(tas_ops[0])); @@ -382,8 +373,6 @@ static void PrintFramework() // -------------- // offset table to avoid .text relocations (forbidden by Android and iOS) - ot("CycloneOT_JT%s\n", ms?"":":"); - ot(" %s %s-CycloneOT_JT\n", ms?"dcd":".long", "CycloneJumpTab"); #if (CYCLONE_FOR_GENESIS == 2) ot("CycloneOT_TAS_%s\n", ms?"":":"); // working TAS (no MD bug) for (size_t i = 0; i < sizeof(tas_ops) / sizeof(tas_ops[0]); i++) @@ -1290,8 +1279,8 @@ static int CycloneMake() for(i=0xf000; i<0x10000; i++) CyJump[i] = -3; // f-line emulation ot(ms?" area |.text|, code\n":" .text\n .align 4\n\n"); - ot(" %s CycloneInit\n",globl); - ot(" %s CycloneReset\n",globl); + ot(" %s CycloneInitJT\n",globl); + ot(" %s CycloneResetJT\n",globl); ot(" %s CycloneRun\n",globl); ot(" %s CycloneSetSr\n",globl); ot(" %s CycloneGetSr\n",globl); @@ -1300,7 +1289,7 @@ static int CycloneMake() ot(" %s CycloneUnpack\n",globl); ot(" %s CycloneVer\n",globl); #if (CYCLONE_FOR_GENESIS == 2) - ot(" %s CycloneSetRealTAS\n",globl); + ot(" %s CycloneSetRealTAS_JT\n",globl); ot(" %s CycloneDoInterrupt\n",globl); ot(" %s CycloneDoTrace\n",globl); ot(" %s CycloneJumpTab\n",globl); diff --git a/tools/idle.h b/tools/idle.h index 254cc57..d8c4133 100644 --- a/tools/idle.h +++ b/tools/idle.h @@ -1,3 +1,8 @@ -void CycloneInitIdle(void); -void CycloneFinishIdle(void); +void CycloneInitIdleJT(void *jt); +void CycloneFinishIdleJT(void *jt); + +#define CycloneInitIdle() \ + CycloneInitIdleJT(CycloneJumpTab) +#define CycloneFinishIdle() \ + CycloneFinishIdleJT(CycloneJumpTab) diff --git a/tools/idle.s b/tools/idle.s index f36588f..7ac8520 100644 --- a/tools/idle.s +++ b/tools/idle.s @@ -8,11 +8,17 @@ .data .align 2 +idle_data: have_patches: .word 0 + .word Op____ + .word Op6002 + .word Op6602 + .word Op6702 .equ patch_desc_table_size, 10 +@ to from patch_desc_table: .word (0x71fa<<16) | 0x66fa, idle_detector_bcc8, idle_bne, Op6602 @ bne.s .word (0x71f8<<16) | 0x66f8, idle_detector_bcc8, idle_bne, Op6602 @ bne.s @@ -30,13 +36,12 @@ patch_desc_table: .align 2 -.global CycloneInitIdle +.global CycloneInitIdleJT @ jt -CycloneInitIdle: +CycloneInitIdleJT: adr r12,offset_table - ldr r3, [r12, #2*4] @ =CycloneJumpTab-ot ldr r2, [r12, #1*4] @ =patch_desc_table-ot - add r3, r3, r12 + mov r3, r0 @ =CycloneJumpTab add r2, r2, r12 mov r12,#patch_desc_table_size @@ -55,29 +60,27 @@ cii_loop: bgt cii_loop adr r12,offset_table - ldr r0, [r12, #0*4] @ =have_patches-ot + ldr r0, [r12, #0*4] @ =idle_data-ot mov r1, #1 - str r1, [r0, r12] + str r1, [r0, r12] @ have_patches bx lr -.global CycloneFinishIdle +.global CycloneFinishIdleJT @ jt -CycloneFinishIdle: +CycloneFinishIdleJT: adr r12,offset_table - ldr r3, [r12, #0*4] @ =have_patches-ot - ldr r0, [r3, r12]! - tst r0, r0 + ldr r3, [r12, #0*4] @ =idle_data-ot + ldr r1, [r3, r12]! @ have_patches + tst r1, r1 bxeq lr 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 r3, r0 @ =CycloneJumpTab + ldr r4, [r5, #1*4] @ =Op____ + add r2, r2, r12 @ =patch_desc_table mov r12,#patch_desc_table_size cfi_loop: @@ -165,12 +168,13 @@ idle_detector_bcc8: @ remove detector from Cyclone adr r12,offset_table + ldr r1, [r12] @ =idle_data-ot mov r0, r8, lsr #8 cmp r0, #0x66 - 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 + add r1, r1, r12 @ =idle_data + ldrlt r1, [r1, #4*2] @ =Op6002-ot + ldreq r1, [r1, #4*3] @ =Op6602-ot + ldrgt r1, [r1, #4*4] @ =Op6702-ot str r1, [r6, r8, lsl #2] bx r1 @@ -183,10 +187,5 @@ exit_detector: b Op6702 offset_table: - .word have_patches - offset_table + .word idle_data - 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 -- 2.39.2