Fix Vita port and likely some Linux/Android hidden issues

Using an invalid SP makes Vita crash (for an unkown reason) and makes
things like C signal handlers crash (luckily Retroarch doesn't use
them). It is also a violation of the ABI and not a great idea.
Recycled some little used registers to free SP. Perf should be roughly
the same.
This commit is contained in:
David Guillen Fandos 2021-04-27 19:05:00 +02:00 committed by David G. F
parent ff48af07b0
commit d83f8fbd25
2 changed files with 15 additions and 16 deletions

View file

@ -67,9 +67,10 @@ void execute_store_u32_safe(u32 address, u32 source);
#define reg_a1 ARMREG_R1 #define reg_a1 ARMREG_R1
#define reg_a2 ARMREG_R2 #define reg_a2 ARMREG_R2
/* scratch0 is shared with flags, be careful! */
#define reg_s0 ARMREG_R9 #define reg_s0 ARMREG_R9
#define reg_base ARMREG_SP #define reg_base ARMREG_R11
#define reg_flags ARMREG_R11 #define reg_flags ARMREG_R9
#define reg_cycles ARMREG_R12 #define reg_cycles ARMREG_R12
@ -110,6 +111,7 @@ void execute_store_u32_safe(u32 address, u32 source);
#define reg_x5 ARMREG_R8 #define reg_x5 ARMREG_R8
#define mem_reg (~0U) #define mem_reg (~0U)
#define save1_reg 21
/* /*
@ -1415,7 +1417,6 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
#define arm_block_memory_adjust_pc_load() \ #define arm_block_memory_adjust_pc_load() \
if(reg_list & 0x8000) \ if(reg_list & 0x8000) \
{ \ { \
generate_mov(reg_a0, reg_rv); \
generate_indirect_branch_arm(); \ generate_indirect_branch_arm(); \
} \ } \
@ -1463,12 +1464,14 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
arm_block_memory_offset_##offset_type(); \ arm_block_memory_offset_##offset_type(); \
arm_block_memory_writeback_##access_type(writeback_type); \ arm_block_memory_writeback_##access_type(writeback_type); \
ARM_BIC_REG_IMM(0, reg_s0, reg_s0, 0x03, 0); \ ARM_BIC_REG_IMM(0, reg_s0, reg_s0, 0x03, 0); \
generate_store_reg(reg_s0, save1_reg); \
\ \
for(i = 0; i < 16; i++) \ for(i = 0; i < 16; i++) \
{ \ { \
if((reg_list >> i) & 0x01) \ if((reg_list >> i) & 0x01) \
{ \ { \
cycle_count++; \ cycle_count++; \
generate_load_reg(reg_s0, save1_reg); \
generate_add_reg_reg_imm(reg_a0, reg_s0, offset, 0); \ generate_add_reg_reg_imm(reg_a0, reg_s0, offset, 0); \
if(reg_list & ~((2 << i) - 1)) \ if(reg_list & ~((2 << i) - 1)) \
{ \ { \
@ -1493,12 +1496,12 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
generate_load_reg(reg_a0, rn); \ generate_load_reg(reg_a0, rn); \
generate_function_call(execute_load_##type); \ generate_function_call(execute_load_##type); \
write32((pc + 8)); \ write32((pc + 8)); \
generate_mov(reg_s0, reg_rv); \ generate_mov(reg_a2, reg_rv); \
generate_load_reg(reg_a0, rn); \ generate_load_reg(reg_a0, rn); \
generate_load_reg(reg_a1, rm); \ generate_load_reg(reg_a1, rm); \
generate_store_reg(reg_a2, rd); \
generate_function_call(execute_store_##type); \ generate_function_call(execute_store_##type); \
write32((pc + 4)); \ write32((pc + 4)); \
generate_store_reg(reg_s0, rd); \
} \ } \
@ -1729,13 +1732,14 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
#define thumb_block_memory_extra_down() \ #define thumb_block_memory_extra_down() \
#define thumb_block_memory_extra_pop_pc() \ #define thumb_block_memory_extra_pop_pc() \
generate_load_reg(reg_s0, save1_reg); \
generate_add_reg_reg_imm(reg_a0, reg_s0, (bit_count[reg_list] * 4), 0); \ generate_add_reg_reg_imm(reg_a0, reg_s0, (bit_count[reg_list] * 4), 0); \
generate_function_call(execute_load_u32); \ generate_function_call(execute_load_u32); \
write32((pc + 4)); \ write32((pc + 4)); \
generate_mov(reg_a0, reg_rv); \
generate_indirect_branch_cycle_update(thumb) \ generate_indirect_branch_cycle_update(thumb) \
#define thumb_block_memory_extra_push_lr(base_reg) \ #define thumb_block_memory_extra_push_lr(base_reg) \
generate_load_reg(reg_s0, save1_reg); \
generate_add_reg_reg_imm(reg_a0, reg_s0, (bit_count[reg_list] * 4), 0); \ generate_add_reg_reg_imm(reg_a0, reg_s0, (bit_count[reg_list] * 4), 0); \
generate_load_reg(reg_a1, REG_LR); \ generate_load_reg(reg_a1, REG_LR); \
generate_function_call(execute_store_u32_safe) \ generate_function_call(execute_store_u32_safe) \
@ -1782,12 +1786,14 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
ARM_BIC_REG_IMM(0, reg_s0, reg_s0, 0x03, 0); \ ARM_BIC_REG_IMM(0, reg_s0, reg_s0, 0x03, 0); \
thumb_block_address_preadjust_##pre_op(); \ thumb_block_address_preadjust_##pre_op(); \
thumb_block_address_postadjust_##post_op(base_reg); \ thumb_block_address_postadjust_##post_op(base_reg); \
generate_store_reg(reg_s0, save1_reg); \
\ \
for(i = 0; i < 8; i++) \ for(i = 0; i < 8; i++) \
{ \ { \
if((reg_list >> i) & 0x01) \ if((reg_list >> i) & 0x01) \
{ \ { \
cycle_count++; \ cycle_count++; \
generate_load_reg(reg_s0, save1_reg); \
generate_add_reg_reg_imm(reg_a0, reg_s0, offset, 0); \ generate_add_reg_reg_imm(reg_a0, reg_s0, offset, 0); \
if(reg_list & ~((2 << i) - 1)) \ if(reg_list & ~((2 << i) - 1)) \
{ \ { \

View file

@ -45,15 +45,14 @@ _##symbol:
#define CHANGED_PC_STATUS (31 * 4) #define CHANGED_PC_STATUS (31 * 4)
#define COMPLETED_FRAME (32 * 4) #define COMPLETED_FRAME (32 * 4)
#define OAM_UPDATED (33 * 4) #define OAM_UPDATED (33 * 4)
#define MAIN_THREAD_SP (34 * 4)
#define reg_a0 r0 #define reg_a0 r0
#define reg_a1 r1 #define reg_a1 r1
#define reg_a2 r2 #define reg_a2 r2
#define reg_s0 r9 #define reg_s0 r9
#define reg_base sp #define reg_base r11
#define reg_flags r11 #define reg_flags r9
#define reg_cycles r12 #define reg_cycles r12
@ -151,11 +150,9 @@ _##symbol:
@ registers which are important to the dynarec. @ registers which are important to the dynarec.
#define call_c_function(function) ;\ #define call_c_function(function) ;\
ldr sp, [reg_base, #MAIN_THREAD_SP] ;\
stmdb sp!, { call_c_saved_regs } ;\ stmdb sp!, { call_c_saved_regs } ;\
bl function ;\ bl function ;\
ldmia sp!, { call_c_saved_regs } ;\ ldmia sp!, { call_c_saved_regs } ;\
ldr sp, =reg ;\
@ Jumps to PC (ARM or Thumb modes) @ Jumps to PC (ARM or Thumb modes)
@ This is really two functions/routines in one @ This is really two functions/routines in one
@ -483,9 +480,7 @@ defsymbl(execute_arm_translate)
@ save the registers to be able to return later @ save the registers to be able to return later
stmdb sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr } stmdb sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr }
ldr r1, =reg @ reg to r1 ldr reg_base, =reg @ init base_reg
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 mvn reg_cycles, r0 @ load cycle counter
@ -515,8 +510,6 @@ defsymbl(execute_arm_translate)
@ Epilogue to return to the main thread (whatever called execute_arm_translate) @ Epilogue to return to the main thread (whatever called execute_arm_translate)
return_to_main: return_to_main:
@ restore the stack pointer
ldr sp, [reg_base, #MAIN_THREAD_SP]
@ restore the saved regs and return @ restore the saved regs and return
ldmia sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr } ldmia sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr }
bx lr bx lr