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:
parent
ff48af07b0
commit
d83f8fbd25
2 changed files with 15 additions and 16 deletions
|
@ -67,9 +67,10 @@ void execute_store_u32_safe(u32 address, u32 source);
|
|||
#define reg_a1 ARMREG_R1
|
||||
#define reg_a2 ARMREG_R2
|
||||
|
||||
/* scratch0 is shared with flags, be careful! */
|
||||
#define reg_s0 ARMREG_R9
|
||||
#define reg_base ARMREG_SP
|
||||
#define reg_flags ARMREG_R11
|
||||
#define reg_base ARMREG_R11
|
||||
#define reg_flags ARMREG_R9
|
||||
|
||||
#define reg_cycles ARMREG_R12
|
||||
|
||||
|
@ -110,6 +111,7 @@ void execute_store_u32_safe(u32 address, u32 source);
|
|||
#define reg_x5 ARMREG_R8
|
||||
|
||||
#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() \
|
||||
if(reg_list & 0x8000) \
|
||||
{ \
|
||||
generate_mov(reg_a0, reg_rv); \
|
||||
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_writeback_##access_type(writeback_type); \
|
||||
ARM_BIC_REG_IMM(0, reg_s0, reg_s0, 0x03, 0); \
|
||||
generate_store_reg(reg_s0, save1_reg); \
|
||||
\
|
||||
for(i = 0; i < 16; i++) \
|
||||
{ \
|
||||
if((reg_list >> i) & 0x01) \
|
||||
{ \
|
||||
cycle_count++; \
|
||||
generate_load_reg(reg_s0, save1_reg); \
|
||||
generate_add_reg_reg_imm(reg_a0, reg_s0, offset, 0); \
|
||||
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_function_call(execute_load_##type); \
|
||||
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_a1, rm); \
|
||||
generate_store_reg(reg_a2, rd); \
|
||||
generate_function_call(execute_store_##type); \
|
||||
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_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_function_call(execute_load_u32); \
|
||||
write32((pc + 4)); \
|
||||
generate_mov(reg_a0, reg_rv); \
|
||||
generate_indirect_branch_cycle_update(thumb) \
|
||||
|
||||
#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_load_reg(reg_a1, REG_LR); \
|
||||
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); \
|
||||
thumb_block_address_preadjust_##pre_op(); \
|
||||
thumb_block_address_postadjust_##post_op(base_reg); \
|
||||
generate_store_reg(reg_s0, save1_reg); \
|
||||
\
|
||||
for(i = 0; i < 8; i++) \
|
||||
{ \
|
||||
if((reg_list >> i) & 0x01) \
|
||||
{ \
|
||||
cycle_count++; \
|
||||
generate_load_reg(reg_s0, save1_reg); \
|
||||
generate_add_reg_reg_imm(reg_a0, reg_s0, offset, 0); \
|
||||
if(reg_list & ~((2 << i) - 1)) \
|
||||
{ \
|
||||
|
|
|
@ -45,15 +45,14 @@ _##symbol:
|
|||
#define CHANGED_PC_STATUS (31 * 4)
|
||||
#define COMPLETED_FRAME (32 * 4)
|
||||
#define OAM_UPDATED (33 * 4)
|
||||
#define MAIN_THREAD_SP (34 * 4)
|
||||
|
||||
#define reg_a0 r0
|
||||
#define reg_a1 r1
|
||||
#define reg_a2 r2
|
||||
|
||||
#define reg_s0 r9
|
||||
#define reg_base sp
|
||||
#define reg_flags r11
|
||||
#define reg_base r11
|
||||
#define reg_flags r9
|
||||
|
||||
#define reg_cycles r12
|
||||
|
||||
|
@ -151,11 +150,9 @@ _##symbol:
|
|||
@ registers which are important to the dynarec.
|
||||
|
||||
#define call_c_function(function) ;\
|
||||
ldr sp, [reg_base, #MAIN_THREAD_SP] ;\
|
||||
stmdb sp!, { call_c_saved_regs } ;\
|
||||
bl function ;\
|
||||
ldmia sp!, { call_c_saved_regs } ;\
|
||||
ldr sp, =reg ;\
|
||||
|
||||
@ Jumps to PC (ARM or Thumb modes)
|
||||
@ 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
|
||||
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)
|
||||
ldr reg_base, =reg @ init base_reg
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue