mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-13 12:31:25 +00:00
Add ARM assembly PIC without TEXTREL
- Adds codepaths that allow for Position Independent Code (PIC) that also avoids having TEXT relocations (TEXTREL) that the dynamic linker needs to patch up
This commit is contained in:
parent
7a8c4dda63
commit
f06257b2c5
@ -44,14 +44,46 @@
|
||||
|
||||
|
||||
#define NO_UNDERSCORES 1
|
||||
#if NO_UNDERSCORES
|
||||
# define SYM(x) =x
|
||||
# define ENTRY(x) .globl x; .balign 16; x##:
|
||||
# define CALL(x) x
|
||||
#else
|
||||
# define SYM(x) =_##x
|
||||
# define ENTRY(x) .globl _##x; .balign 16; _##x##:
|
||||
# define CALL(x) _##x
|
||||
|
||||
#define ENTRY(x) .globl x; .balign 16; .type x, %function; x##:
|
||||
#define CALL(x) x
|
||||
|
||||
// 2015/11/08 NOTE : Android requires all apps targeting API 23 (AKA Marshmallow) to use Position Independent Code (PIC)
|
||||
// that does not have TEXT segment relocations
|
||||
|
||||
#if !defined(__COUNTER__)
|
||||
#error __COUNTER__ macro should be available in modern compilers
|
||||
#endif
|
||||
|
||||
#if PREVENT_TEXTREL
|
||||
|
||||
# define _SYM_ADDR_PRE(reg) \
|
||||
ldr reg, 5f;
|
||||
# define _SYM_ADDR_OFF_THUMB(reg,ct) \
|
||||
4: add reg, pc; \
|
||||
ldr reg, [reg];
|
||||
# define _SYM_ADDR_OFF_ARM(reg,ct) \
|
||||
4: ldr reg, [pc, reg];
|
||||
# define _SYM_ADDR_POST(var,poff) \
|
||||
b 6f; \
|
||||
.align 2; \
|
||||
5: .word var(GOT_PREL)+(. - (4b + poff)); \
|
||||
6:
|
||||
# if defined(THUMB)
|
||||
# define SYM(reg,var) \
|
||||
_SYM_ADDR_PRE(reg) \
|
||||
_SYM_ADDR_OFF_THUMB(reg, __COUNTER__); \
|
||||
_SYM_ADDR_POST(var,4)
|
||||
# else
|
||||
# define SYM(reg,var) \
|
||||
_SYM_ADDR_PRE(reg) \
|
||||
_SYM_ADDR_OFF_ARM(reg, __COUNTER__); \
|
||||
_SYM_ADDR_POST(var,8)
|
||||
# endif
|
||||
#else /* !PREVENT_TEXTREL */
|
||||
# define SYM(reg,var) \
|
||||
ldr reg, =var
|
||||
#endif
|
||||
|
||||
|
||||
#endif // whole file
|
||||
|
@ -18,38 +18,38 @@
|
||||
|
||||
|
||||
#define DecodeFlags \
|
||||
ldr r1, SYM(cpu65_flags_decode); \
|
||||
SYM(r1, cpu65_flags_decode); \
|
||||
ldrb F_Reg, [r1, r0];
|
||||
|
||||
#define EncodeFlags \
|
||||
ldr r1, SYM(cpu65_flags_encode); \
|
||||
SYM(r1, cpu65_flags_encode); \
|
||||
ldrb r0, [r1, F_Reg];
|
||||
|
||||
#define CommonSaveCPUState \
|
||||
/* save EA */ \
|
||||
ldr r0, SYM(cpu65_ea); \
|
||||
SYM(r0, cpu65_ea); \
|
||||
strh EffectiveAddr, [r0]; \
|
||||
/* save stack pointer */ \
|
||||
ldr r0, SYM(cpu65_sp); \
|
||||
SYM(r0, cpu65_sp); \
|
||||
strb SP_Reg, [r0]; \
|
||||
/* save X */ \
|
||||
ldr r0, SYM(cpu65_x); \
|
||||
SYM(r0, cpu65_x); \
|
||||
strb X_Reg, [r0]; \
|
||||
/* save Y */ \
|
||||
ldr r0, SYM(cpu65_y); \
|
||||
SYM(r0, cpu65_y); \
|
||||
strb Y_Reg, [r0]; \
|
||||
/* save A */ \
|
||||
ldr r0, SYM(cpu65_a); \
|
||||
SYM(r0, cpu65_a); \
|
||||
strb A_Reg, [r0]; \
|
||||
/* save flags */ \
|
||||
EncodeFlags \
|
||||
ldr r1, SYM(cpu65_f); \
|
||||
SYM(r1, cpu65_f); \
|
||||
strb r0, [r1]
|
||||
|
||||
// Tracing is necessary for some CPU tests and to verify operation against other emulators
|
||||
#if CPU_TRACING
|
||||
# define TRACE_PROLOGUE \
|
||||
ldr r1, SYM(cpu65_pc); \
|
||||
SYM(r1, cpu65_pc); \
|
||||
strh PC_Reg, [r1]; \
|
||||
bl CALL(cpu65_trace_prologue);
|
||||
# define TRACE_ARG \
|
||||
@ -71,25 +71,25 @@
|
||||
|
||||
|
||||
#define CPUStatsReset \
|
||||
ldr r1, SYM(cpu65_opcode); \
|
||||
SYM(r1, cpu65_opcode); \
|
||||
strb r0, [r1]; /* r0 should be next opcode */ \
|
||||
eor r9, r9, r9; \
|
||||
ldr r1, SYM(cpu65_opcycles); \
|
||||
SYM(r1, cpu65_opcycles); \
|
||||
strb r9, [r1]; \
|
||||
ldr r1, SYM(cpu65_rw); \
|
||||
SYM(r1, cpu65_rw); \
|
||||
strb r9, [r1];
|
||||
#define CPUStatsSetRead \
|
||||
ldr r1, SYM(cpu65_rw); \
|
||||
SYM(r1, cpu65_rw); \
|
||||
ldrb r9, [r1]; \
|
||||
orr r9, r9, #1; \
|
||||
strb r9, [r1];
|
||||
|
||||
#define CPUStatsSetWrite \
|
||||
ldr r1, SYM(cpu65_rw); \
|
||||
SYM(r1, cpu65_rw); \
|
||||
ldrb r9, [r1]; \
|
||||
orr r9, r9, #2; \
|
||||
strb r9, [r1]; \
|
||||
ldr r1, SYM(cpu65_d); \
|
||||
SYM(r1, cpu65_d); \
|
||||
strb r0, [r1];
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -151,7 +151,7 @@
|
||||
TRACE_PROLOGUE \
|
||||
GetFromPC_B \
|
||||
CPUStatsReset \
|
||||
ldr r1, SYM(cpu65__opcodes); \
|
||||
SYM(r1, cpu65__opcodes); \
|
||||
ldr r1, [r1, r0, LSL PTR_SHIFT]; \
|
||||
bx r1;
|
||||
|
||||
@ -172,7 +172,7 @@
|
||||
|
||||
#define PutToEA_B \
|
||||
CPUStatsSetWrite \
|
||||
ldr r1, SYM(cpu65_vmem_w); \
|
||||
SYM(r1, cpu65_vmem_w); \
|
||||
ldr r1, [r1, EffectiveAddr, LSL PTR_SHIFT]; \
|
||||
blx r1;
|
||||
|
||||
@ -194,7 +194,7 @@
|
||||
mov r0, r0, ASR #24;
|
||||
|
||||
#define _IncOpCycles \
|
||||
ldr mem_cycle_count, SYM(cpu65_opcycles); \
|
||||
SYM(mem_cycle_count, cpu65_opcycles); \
|
||||
ldrb scratch_count, [mem_cycle_count]; \
|
||||
add scratch_count, scratch_count, #1;
|
||||
|
||||
@ -285,7 +285,7 @@
|
||||
#define stack_loc r1
|
||||
#ifdef APPLE2_VM
|
||||
#define RestoreAltZP \
|
||||
ldr stack_loc, SYM(base_stackzp); \
|
||||
SYM(stack_loc, base_stackzp); \
|
||||
ldr stack_loc, [stack_loc]; \
|
||||
add stack_loc, stack_loc, #0x100; \
|
||||
add stack_loc, stack_loc, SP_Reg;
|
||||
@ -1186,7 +1186,7 @@ ENTRY(op_BRK)
|
||||
EncodeFlags
|
||||
Push(r0)
|
||||
orr F_Reg, F_Reg, #I_Flag
|
||||
ldr EffectiveAddr, SYM(interrupt_vector)
|
||||
SYM(EffectiveAddr, interrupt_vector)
|
||||
ldrh EffectiveAddr, [EffectiveAddr]
|
||||
GetFromEA_W
|
||||
mov PC_Reg, r0
|
||||
@ -2403,39 +2403,39 @@ ENTRY(op_WAI_65c02)
|
||||
|
||||
#define cycles_exe r0
|
||||
continue:
|
||||
ldr r1, SYM(cpu65__opcycles)
|
||||
ldr r0, SYM(cpu65_opcode)
|
||||
SYM(r1, cpu65__opcycles)
|
||||
SYM(r0, cpu65_opcode)
|
||||
ldrb r0, [r0]
|
||||
ldrb cycles_exe, [r1, r0]
|
||||
ldr r1, SYM(cpu65_opcycles)
|
||||
SYM(r1, cpu65_opcycles)
|
||||
ldrb r9, [r1]
|
||||
add cycles_exe, cycles_exe, r9
|
||||
strb cycles_exe, [r1]
|
||||
TRACE_EPILOGUE
|
||||
|
||||
ldr r1, SYM(gc_cycles_timer_0)
|
||||
SYM(r1, gc_cycles_timer_0)
|
||||
ldr r9, [r1]
|
||||
sub r9, r9, cycles_exe
|
||||
str r9, [r1]
|
||||
|
||||
ldr r1, SYM(gc_cycles_timer_1)
|
||||
SYM(r1, gc_cycles_timer_1)
|
||||
ldr r9, [r1]
|
||||
sub r9, r9, cycles_exe
|
||||
str r9, [r1]
|
||||
|
||||
ldr r1, SYM(cpu65_cycle_count)
|
||||
SYM(r1, cpu65_cycle_count)
|
||||
ldr r9, [r1]
|
||||
add r9, r9, cycles_exe
|
||||
str r9, [r1]
|
||||
|
||||
ldr r1, SYM(cpu65_cycles_to_execute)
|
||||
SYM(r1, cpu65_cycles_to_execute)
|
||||
ldr r9, [r1]
|
||||
subs r9, r9, cycles_exe
|
||||
str r9, [r1]
|
||||
bmi exit_cpu65_run
|
||||
beq exit_cpu65_run
|
||||
|
||||
continue1: ldr r1, SYM(cpu65__signal)
|
||||
continue1: SYM(r1, cpu65__signal)
|
||||
ldrb r0, [r1]
|
||||
orrs r0, r0, r0
|
||||
bne exception
|
||||
@ -2447,19 +2447,19 @@ continue1: ldr r1, SYM(cpu65__signal)
|
||||
|
||||
exception: tst r0, #ResetSig
|
||||
beq ex_irq
|
||||
ldr r1, SYM(joy_button0) // OpenApple
|
||||
SYM(r1, joy_button0) // OpenApple
|
||||
ldrb r0, [r1]
|
||||
tst r0, #0xFF
|
||||
bne exit_reinit
|
||||
ldr r1, SYM(joy_button1) // ClosedApple
|
||||
SYM(r1, joy_button1) // ClosedApple
|
||||
ldrb r0, [r1]
|
||||
tst r0, #0xFF
|
||||
bne exit_reinit
|
||||
|
||||
ex_reset: eor r0, r0, r0
|
||||
ldr r1, SYM(cpu65__signal)
|
||||
SYM(r1, cpu65__signal)
|
||||
strb r0, [r1]
|
||||
ldr EffectiveAddr, SYM(reset_vector)
|
||||
SYM(EffectiveAddr, reset_vector)
|
||||
ldrh EffectiveAddr, [EffectiveAddr]
|
||||
GetFromEA_W
|
||||
mov PC_Reg, r0
|
||||
@ -2478,7 +2478,7 @@ ex_irq: tst F_Reg, #I_Flag // Already interrupt
|
||||
Push(r0)
|
||||
orr F_Reg, F_Reg, #BI_Flags
|
||||
//bic F_Reg, F_Reg, #D_Flag // AppleWin clears Decimal bit?
|
||||
ldr EffectiveAddr, SYM(interrupt_vector)
|
||||
SYM(EffectiveAddr, interrupt_vector)
|
||||
ldrh EffectiveAddr, [EffectiveAddr]
|
||||
GetFromEA_W
|
||||
mov PC_Reg, r0
|
||||
@ -2491,23 +2491,23 @@ ex_irq: tst F_Reg, #I_Flag // Already interrupt
|
||||
ENTRY(cpu65_run)
|
||||
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||
// Restore CPU state when being called from C.
|
||||
ldr reg_vmem_r, SYM(cpu65_vmem_r)
|
||||
ldr r1, SYM(cpu65_ea)
|
||||
SYM(reg_vmem_r, cpu65_vmem_r)
|
||||
SYM(r1, cpu65_ea)
|
||||
ldrh EffectiveAddr, [r1]
|
||||
ldr r1, SYM(cpu65_pc)
|
||||
SYM(r1, cpu65_pc)
|
||||
ldrh PC_Reg, [r1]
|
||||
ldr r1, SYM(cpu65_a)
|
||||
SYM(r1, cpu65_a)
|
||||
ldrb A_Reg, [r1]
|
||||
ldr r1, SYM(cpu65_f)
|
||||
SYM(r1, cpu65_f)
|
||||
ldrb r0, [r1]
|
||||
DecodeFlags
|
||||
ldr r1, SYM(cpu65_x)
|
||||
SYM(r1, cpu65_x)
|
||||
ldrb X_Reg, [r1]
|
||||
ldr r1, SYM(cpu65_y)
|
||||
SYM(r1, cpu65_y)
|
||||
ldrb Y_Reg, [r1]
|
||||
ldr r1, SYM(cpu65_sp)
|
||||
SYM(r1, cpu65_sp)
|
||||
ldrb SP_Reg, [r1]
|
||||
ldr r1, SYM(emul_reinitialize)
|
||||
SYM(r1, emul_reinitialize)
|
||||
ldrb r0, [r1]
|
||||
teq r0, #0
|
||||
eorne r0, r0, r0
|
||||
@ -2521,15 +2521,15 @@ ENTRY(cpu65_run)
|
||||
|
||||
exit_cpu65_run:
|
||||
// Save CPU state when returning from being called from C
|
||||
ldr r1, SYM(cpu65_pc)
|
||||
SYM(r1, cpu65_pc)
|
||||
strh PC_Reg, [r1]
|
||||
CommonSaveCPUState
|
||||
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
|
||||
|
||||
exit_reinit: ldr r1, SYM(cpu65__signal)
|
||||
exit_reinit: SYM(r1, cpu65__signal)
|
||||
mov r0, #0
|
||||
strb r0, [r1]
|
||||
ldr r1, SYM(emul_reinitialize)
|
||||
SYM(r1, emul_reinitialize)
|
||||
mov r0, #1
|
||||
strb r0, [r1]
|
||||
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
|
||||
@ -2544,7 +2544,11 @@ ENTRY(cpu65_direct_write)
|
||||
ldr r0, [r0] // segfault
|
||||
mov pc, lr
|
||||
|
||||
# local data ...
|
||||
.global interrupt_vector
|
||||
.global reset_vector
|
||||
interrupt_vector: .hword 0xFFFE
|
||||
reset_vector: .hword 0xFFFC
|
||||
|
||||
.ltorg
|
||||
|
||||
|
@ -15,9 +15,9 @@
|
||||
#define GLUE_EXTERN_C_READ(func)
|
||||
|
||||
#define GLUE_BANK_MAYBEREAD(func,pointer) \
|
||||
ENTRY(func) ldr r1, SYM(softswitches); \
|
||||
ENTRY(func) SYM(r1, softswitches); \
|
||||
ldr r0, [r1]; \
|
||||
ldr r1, SYM(pointer); \
|
||||
SYM(r1, pointer); \
|
||||
tst r0, $SS_CXROM; \
|
||||
bne 1f; \
|
||||
push {r0, EffectiveAddr, PC_Reg, /*SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg,*/ lr}; \
|
||||
@ -30,19 +30,19 @@ ENTRY(func) ldr r1, SYM(softswitches); \
|
||||
|
||||
|
||||
#define GLUE_BANK_READ(func,pointer) \
|
||||
ENTRY(func) ldr r1, SYM(pointer); \
|
||||
ENTRY(func) SYM(r1, pointer); \
|
||||
ldr r1, [r1]; \
|
||||
ldrb r0, [r1, EffectiveAddr]; \
|
||||
mov pc, lr;
|
||||
|
||||
#define GLUE_BANK_WRITE(func,pointer) \
|
||||
ENTRY(func) ldr r1, SYM(pointer); \
|
||||
ENTRY(func) SYM(r1, pointer); \
|
||||
ldr r1, [r1]; \
|
||||
strb r0, [r1, EffectiveAddr]; \
|
||||
mov pc, lr;
|
||||
|
||||
#define GLUE_BANK_MAYBEWRITE(func,pointer) \
|
||||
ENTRY(func) ldr r1, SYM(pointer); \
|
||||
ENTRY(func) SYM(r1, pointer); \
|
||||
ldr r1, [r1]; \
|
||||
teq r1, #0; \
|
||||
strneb r0, [r1, EffectiveAddr]; \
|
||||
|
Loading…
x
Reference in New Issue
Block a user