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_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)) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue