Fix arm32 spsr writes: only write selected bits

Seems no game is affected, even though the current implementration is
broken. Most games seem to not use mask at all.
This commit is contained in:
David Guillen Fandos 2021-10-23 09:06:24 +02:00
parent 8da094d7e0
commit cdb61227bc
2 changed files with 11 additions and 3 deletions

View File

@ -1240,6 +1240,7 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
write32(pc) \
#define arm_psr_store_spsr() \
arm_load_imm_32bit(reg_a1, psr_masks[psr_field]); \
generate_function_call(execute_store_spsr) \
#define arm_psr_store(op_type, psr_reg) \

View File

@ -342,10 +342,17 @@ defsymbl(execute_store_cpsr)
@ r1: bitmask of which bits in spsr to update
defsymbl(execute_store_spsr)
add r1, reg_base, #SPSR_RAM_OFF @ r1 = spsr
str lr, [reg_base, #REG_SAVE3] @ Save lr
ldr r2, [reg_base, #CPU_MODE] @ r2 = CPU_MODE
str r0, [r1, r2, lsl #2] @ spsr[CPU_MODE] = new_spsr
bx lr
add lr, reg_base, r2, lsl #2 @ Access table * 4 + base
and r0, r0, r1 @ r0 = cpsr & mask
ldr r2, [lr, #SPSR_RAM_OFF] @ Read old cpsr
bic r2, r2, r1 @ r2 = old_cprs & ~mask
orr r0, r0, r2 @ new cpsr
str r0, [lr, #SPSR_RAM_OFF] @ spsr[CPU_MODE] = new_spsr
ldr pc, [reg_base, #REG_SAVE3] @ return to saved LR
.size execute_store_spsr, .-execute_store_spsr
@ Read the current spsr.