Inline spsr operations
This commit is contained in:
parent
d89977d25d
commit
4bebb6135d
|
@ -46,8 +46,6 @@ void arm_indirect_branch_dual_thumb(u32 address);
|
||||||
|
|
||||||
void execute_store_cpsr(u32 new_cpsr, u32 store_mask, u32 address);
|
void execute_store_cpsr(u32 new_cpsr, u32 store_mask, u32 address);
|
||||||
u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address);
|
u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address);
|
||||||
void execute_store_spsr(u32 new_cpsr, u32 store_mask);
|
|
||||||
u32 execute_read_spsr(void);
|
|
||||||
u32 execute_spsr_restore(u32 address);
|
u32 execute_spsr_restore(u32 address);
|
||||||
|
|
||||||
void execute_swi_arm(u32 pc);
|
void execute_swi_arm(u32 pc);
|
||||||
|
@ -55,9 +53,12 @@ void execute_swi_thumb(u32 pc);
|
||||||
|
|
||||||
void execute_store_u32_safe(u32 address, u32 source);
|
void execute_store_u32_safe(u32 address, u32 source);
|
||||||
|
|
||||||
|
#define STORE_TBL_OFF 0x1DC
|
||||||
|
#define SPSR_RAM_OFF 0x100
|
||||||
|
|
||||||
#define write32(value) \
|
#define write32(value) \
|
||||||
*((u32 *)translation_ptr) = value; \
|
*((u32 *)translation_ptr) = value; \
|
||||||
translation_ptr += 4 \
|
translation_ptr += 4 \
|
||||||
|
|
||||||
#define arm_relative_offset(source, offset) \
|
#define arm_relative_offset(source, offset) \
|
||||||
(((((u32)offset - (u32)source) - 8) >> 2) & 0xFFFFFF) \
|
(((((u32)offset - (u32)source) - 8) >> 2) & 0xFFFFFF) \
|
||||||
|
@ -371,9 +372,6 @@ u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations)
|
||||||
#define generate_function_call(function_location) \
|
#define generate_function_call(function_location) \
|
||||||
ARM_BL(0, arm_relative_offset(translation_ptr, function_location)) \
|
ARM_BL(0, arm_relative_offset(translation_ptr, function_location)) \
|
||||||
|
|
||||||
#define generate_exit_block() \
|
|
||||||
ARM_BX(0, ARMREG_LR) \
|
|
||||||
|
|
||||||
/* The branch target is to be filled in later (thus a 0 for now) */
|
/* The branch target is to be filled in later (thus a 0 for now) */
|
||||||
|
|
||||||
#define generate_branch_filler(condition_code, writeback_location) \
|
#define generate_branch_filler(condition_code, writeback_location) \
|
||||||
|
@ -1175,8 +1173,13 @@ u32 execute_spsr_restore_body(u32 pc)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define arm_psr_read_spsr() \
|
#define arm_psr_read_spsr() \
|
||||||
generate_function_call(execute_read_spsr) \
|
{ \
|
||||||
arm_generate_store_reg(reg_a0, rd) \
|
u32 _rd = arm_prepare_store_reg(reg_a0, rd); \
|
||||||
|
ARM_ADD_REG_IMM(0, reg_a0, reg_base, SPSR_RAM_OFF >> 2, 30); \
|
||||||
|
ARM_LDR_IMM(0, reg_a1, reg_base, CPU_MODE * 4); \
|
||||||
|
ARM_LDR_REG_REG_SHIFT(0, _rd, reg_a0, reg_a1, ARMSHIFT_LSL, 2); \
|
||||||
|
arm_complete_store_reg(_rd, rd); \
|
||||||
|
}
|
||||||
|
|
||||||
#define arm_psr_read(op_type, psr_reg) \
|
#define arm_psr_read(op_type, psr_reg) \
|
||||||
arm_psr_read_##psr_reg() \
|
arm_psr_read_##psr_reg() \
|
||||||
|
@ -1244,7 +1247,13 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
|
||||||
|
|
||||||
#define arm_psr_store_spsr() \
|
#define arm_psr_store_spsr() \
|
||||||
arm_load_imm_32bit(reg_a1, psr_masks[psr_field]); \
|
arm_load_imm_32bit(reg_a1, psr_masks[psr_field]); \
|
||||||
generate_function_call(execute_store_spsr) \
|
ARM_LDR_IMM(0, reg_a2, reg_base, (CPU_MODE * 4)); \
|
||||||
|
ARM_ADD_REG_IMMSHIFT(0, ARMREG_LR, reg_base, reg_a2, ARMSHIFT_LSL, 2); \
|
||||||
|
ARM_AND_REG_IMMSHIFT(0, reg_a0, reg_a0, reg_a1, ARMSHIFT_LSL, 0); \
|
||||||
|
ARM_LDR_IMM(0, reg_a2, ARMREG_LR, SPSR_RAM_OFF); \
|
||||||
|
ARM_BIC_REG_IMMSHIFT(0, reg_a2, reg_a2, reg_a1, ARMSHIFT_LSL, 0); \
|
||||||
|
ARM_ORR_REG_IMMSHIFT(0, reg_a0, reg_a0, reg_a2, ARMSHIFT_LSL, 0); \
|
||||||
|
ARM_STR_IMM(0, reg_a0, ARMREG_LR, SPSR_RAM_OFF); \
|
||||||
|
|
||||||
#define arm_psr_store(op_type, psr_reg) \
|
#define arm_psr_store(op_type, psr_reg) \
|
||||||
arm_psr_load_new_##op_type(); \
|
arm_psr_load_new_##op_type(); \
|
||||||
|
|
|
@ -335,38 +335,6 @@ defsymbl(execute_store_cpsr)
|
||||||
bx r0 @ return to PC ARM address
|
bx r0 @ return to PC ARM address
|
||||||
.size execute_store_cpsr, .-execute_store_cpsr
|
.size execute_store_cpsr, .-execute_store_cpsr
|
||||||
|
|
||||||
@ Update the current spsr.
|
|
||||||
|
|
||||||
@ Input:
|
|
||||||
@ r0: new cpsr value
|
|
||||||
@ r1: bitmask of which bits in spsr to update
|
|
||||||
|
|
||||||
defsymbl(execute_store_spsr)
|
|
||||||
str lr, [reg_base, #REG_SAVE3] @ Save lr
|
|
||||||
ldr r2, [reg_base, #CPU_MODE] @ r2 = CPU_MODE
|
|
||||||
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.
|
|
||||||
|
|
||||||
@ Output:
|
|
||||||
@ r0: spsr
|
|
||||||
|
|
||||||
defsymbl(execute_read_spsr)
|
|
||||||
add r0, reg_base, #SPSR_RAM_OFF @ r0 = spsr
|
|
||||||
ldr r1, [reg_base, #CPU_MODE] @ r1 = CPU_MODE
|
|
||||||
ldr r0, [r0, r1, lsl #2] @ r0 = spsr[CPU_MODE]
|
|
||||||
bx lr @ return
|
|
||||||
.size execute_read_spsr, .-execute_read_spsr
|
|
||||||
|
|
||||||
@ Restore the cpsr from the mode spsr and mode shift.
|
@ Restore the cpsr from the mode spsr and mode shift.
|
||||||
|
|
||||||
@ Input:
|
@ Input:
|
||||||
|
|
Loading…
Reference in New Issue