summaryrefslogtreecommitdiff
path: root/arm
diff options
context:
space:
mode:
authorDavid Guillen Fandos2021-03-08 18:44:03 +0100
committerDavid Guillen Fandos2021-03-08 18:44:03 +0100
commit56dc6ecb70e6fc76d32d6a7194acb273b76bfe0e (patch)
treecf3b14a8d1bc593248398d0c544251ea8987b40e /arm
parent02e35339ee89f92d346d290c24497bbbae59ea79 (diff)
downloadpicogpsp-56dc6ecb70e6fc76d32d6a7194acb273b76bfe0e.tar.gz
picogpsp-56dc6ecb70e6fc76d32d6a7194acb273b76bfe0e.tar.bz2
picogpsp-56dc6ecb70e6fc76d32d6a7194acb273b76bfe0e.zip
Remove libco
This removes libco and all the usages of it (+pthreads). Rewired all dynarecs and interpreter to return after every frame so that libretro can process events. This required to make dynarec re-entrant. Dynarecs were updated to check for new frame on every update (IRQ, cycle exhaustion, I/O write, etc). The performance impact of doing so should be minimal (and definitely outweight the libco gains). While at it, fixed small issues to get a bit more perf: arm dynarec was not idling correctly, mips was using stack when not needed, etc. Tested on PSP (mips), OGA (armv7), Linux (x86 and interpreter). Not tested on Android though.
Diffstat (limited to 'arm')
-rw-r--r--arm/arm_stub.S65
1 files changed, 50 insertions, 15 deletions
diff --git a/arm/arm_stub.S b/arm/arm_stub.S
index 0de4cb4..7deffc0 100644
--- a/arm/arm_stub.S
+++ b/arm/arm_stub.S
@@ -39,9 +39,9 @@
#define CPU_MODE (29 * 4)
#define CPU_HALT_STATE (30 * 4)
#define CHANGED_PC_STATUS (31 * 4)
+#define COMPLETED_FRAME (32 * 4)
-#define REG_HOST_SP (32 * 4)
-
+#define MAIN_THREAD_SP (33 * 4)
#define reg_a0 r0
#define reg_a1 r1
@@ -147,11 +147,11 @@
@ registers which are important to the dynarec.
#define call_c_function(function) ;\
- ldr sp, [reg_base, #REG_HOST_SP] ;\
+ ldr sp, [reg_base, #MAIN_THREAD_SP] ;\
stmdb sp!, { call_c_saved_regs } ;\
bl function ;\
ldmia sp!, { call_c_saved_regs } ;\
- ldr sp, =base_reg_area ;\
+ ldr sp, =reg ;\
@ Update the GBA hardware (video, sound, input, etc)
@@ -186,8 +186,17 @@ _arm_update_gba_##name: ;\
collapse_flags(r0) /* update the flags */;\
;\
store_registers_##mode() /* save out registers */;\
+wait_halt_##name: ;\
call_c_function(update_gba) /* update GBA state */;\
;\
+ ldr r1, [reg_base, #COMPLETED_FRAME] /* return if new frame */;\
+ cmp r1, #0 ;\
+ bne return_to_main ;\
+ ;\
+ ldr r1, [reg_base, #CPU_HALT_STATE] /* keep iterating if halted */;\
+ cmp r1, #0 ;\
+ bne wait_halt_##name ;\
+ ;\
mvn reg_cycles, r0 /* load new cycle count */;\
;\
ldr r0, [reg_base, #CHANGED_PC_STATUS] /* load PC changed status */;\
@@ -479,14 +488,20 @@ execute_swi_function_builder(div, thumb)
.globl _execute_arm_translate
execute_arm_translate:
_execute_arm_translate:
- ldr r1, =base_reg_area @ base_reg_area to r1
- str sp, [r1, #REG_HOST_SP] @ store the current sp
- ldr sp, =base_reg_area @ reg_base = sp (loading addr)
+
+ @ save the registers to be able to return later
+ stmdb sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr }
+
+ ldr r1, =reg @ reg to r1
+ str sp, [r1, #MAIN_THREAD_SP] @ store the current sp
+ ldr sp, =reg @ reg_base = sp (loading addr)
mvn reg_cycles, r0 @ load cycle counter
- mov r0, reg_base @ load reg_base into first param
- call_c_function(move_reg) @ make reg_base the new reg ptr
+ @ Check whether the CPU is sleeping already, we should just wait for IRQs
+ ldr r1, [reg_base, #CPU_HALT_STATE]
+ cmp r1, #0
+ bne alert_loop
ldr r0, [reg_base, #REG_PC] @ r0 = current pc
ldr r1, [reg_base, #REG_CPSR] @ r1 = flags
@@ -506,6 +521,16 @@ _execute_arm_translate:
bx r0 @ jump to first Thumb block
+@ Epilogue to return to the main thread (whatever called execute_arm_translate)
+
+return_to_main:
+ @ restore the stack pointer
+ ldr sp, [reg_base, #MAIN_THREAD_SP]
+ @ restore the saved regs and return
+ ldmia sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr }
+ bx lr
+
+
@ Write out to memory.
@ Input:
@@ -607,10 +632,22 @@ write_epilogue:
bne 1f @ if so do Thumb update
store_registers_arm() @ save ARM registers
+ b alert_loop
-3:
+1:
+ store_registers_thumb() @ save Thumb registers
+
+alert_loop:
call_c_function(update_gba) @ update GBA until CPU isn't halted
+ ldr r1, [reg_base, #COMPLETED_FRAME] @ Check whether a frame was completed
+ cmp r1, #0
+ bne return_to_main
+
+ ldr r1, [reg_base, #CPU_HALT_STATE] @ Check whether the CPU is halted
+ cmp r1, #0
+ bne alert_loop @ Keep looping until it is
+
mvn reg_cycles, r0 @ load new cycle count
ldr r0, [reg_base, #REG_PC] @ load new PC
ldr r1, [reg_base, #REG_CPSR] @ r1 = flags
@@ -622,10 +659,6 @@ write_epilogue:
restore_flags()
bx r0 @ jump to new ARM block
-1:
- store_registers_thumb() @ save Thumb registers
- b 3b
-
2:
load_registers_thumb()
call_c_function(block_lookup_address_thumb)
@@ -735,6 +768,8 @@ execute_load_builder(u32, 32, ldrne, #0xF0000000)
.data
-base_reg_area:
+.globl reg
+.globl _reg
+reg:
.space 0x100, 0