Unaligned loads: Only save working registers, use jump table to load non-working registers
This commit is contained in:
parent
8ea4ae27e2
commit
3b3f5ea771
1 changed files with 53 additions and 23 deletions
|
@ -273,16 +273,6 @@ UserLoadStoreExceptionHandler:
|
||||||
s32i a3, sp, 0x0c
|
s32i a3, sp, 0x0c
|
||||||
s32i a4, sp, 0x10
|
s32i a4, sp, 0x10
|
||||||
s32i a5, sp, 0x14
|
s32i a5, sp, 0x14
|
||||||
s32i a6, sp, 0x18
|
|
||||||
s32i a7, sp, 0x1c
|
|
||||||
s32i a8, sp, 0x20
|
|
||||||
s32i a9, sp, 0x24
|
|
||||||
s32i a10, sp, 0x28
|
|
||||||
s32i a11, sp, 0x2c
|
|
||||||
s32i a12, sp, 0x30
|
|
||||||
s32i a13, sp, 0x34
|
|
||||||
s32i a14, sp, 0x38
|
|
||||||
s32i a15, sp, 0x3c
|
|
||||||
rsr.sar a0 // save sar in a0
|
rsr.sar a0 // save sar in a0
|
||||||
|
|
||||||
/* Load the instruction we failed to execute */
|
/* Load the instruction we failed to execute */
|
||||||
|
@ -324,8 +314,6 @@ TODO: the exception dump will have some wrong values in it */
|
||||||
/* verified an 8- or 16-bit read
|
/* verified an 8- or 16-bit read
|
||||||
a2 holds instruction, a5 holds mask to apply to read value
|
a2 holds instruction, a5 holds mask to apply to read value
|
||||||
*/
|
*/
|
||||||
extui a2, a2, 4, 4 /* a2 now destination register 0-15 */
|
|
||||||
slli a2, a2, 2 /* a2 now offset of destination register, relative to stack pointer */
|
|
||||||
|
|
||||||
rsr.excvaddr a3 // read faulting address
|
rsr.excvaddr a3 // read faulting address
|
||||||
ssa8l a3 /* sar is now shift to extract a3's byte */
|
ssa8l a3 /* sar is now shift to extract a3's byte */
|
||||||
|
@ -344,11 +332,19 @@ TODO: the exception dump will have some wrong values in it */
|
||||||
bbci a5, 15, .Lextend_sign
|
bbci a5, 15, .Lextend_sign
|
||||||
.Lafter_extend_sign:
|
.Lafter_extend_sign:
|
||||||
/* a4 holds the correctly read value */
|
/* a4 holds the correctly read value */
|
||||||
|
extui a2, a2, 4, 4 /* a2 now destination register 0-15 */
|
||||||
|
|
||||||
/* write read value to register slot */
|
/* test if a4 needs to be written directly to a register (ie not a working register) */
|
||||||
|
bgei a2, 6, .Lwrite_value_direct_reg
|
||||||
|
/* test if a4 needs to be written to a0 */
|
||||||
|
beqz a2, .Lwrite_value_a0_reg
|
||||||
|
|
||||||
|
/* otherwise, a4 needs to be written to a saved working register 'slot' on the stack */
|
||||||
|
slli a2, a2, 2
|
||||||
add a5, sp, a2
|
add a5, sp, a2
|
||||||
s32i a4, a5, 0
|
s32i a4, a5, 0
|
||||||
|
|
||||||
|
.Lafter_write_value:
|
||||||
/* Footer*/
|
/* Footer*/
|
||||||
//Increment PC
|
//Increment PC
|
||||||
rsr.epc1 a2
|
rsr.epc1 a2
|
||||||
|
@ -363,16 +359,6 @@ TODO: the exception dump will have some wrong values in it */
|
||||||
l32i a3, sp, 0x0c
|
l32i a3, sp, 0x0c
|
||||||
l32i a4, sp, 0x10
|
l32i a4, sp, 0x10
|
||||||
l32i a5, sp, 0x14
|
l32i a5, sp, 0x14
|
||||||
l32i a6, sp, 0x18
|
|
||||||
l32i a7, sp, 0x1c
|
|
||||||
l32i a8, sp, 0x20
|
|
||||||
l32i a9, sp, 0x24
|
|
||||||
l32i a10, sp, 0x28
|
|
||||||
l32i a11, sp, 0x2c
|
|
||||||
l32i a12, sp, 0x30
|
|
||||||
l32i a13, sp, 0x34
|
|
||||||
l32i a14, sp, 0x38
|
|
||||||
l32i a15, sp, 0x3c
|
|
||||||
addi sp, sp, 0x40
|
addi sp, sp, 0x40
|
||||||
rfe
|
rfe
|
||||||
|
|
||||||
|
@ -383,6 +369,50 @@ TODO: the exception dump will have some wrong values in it */
|
||||||
or a4, a3, a4 /* set sign bit */
|
or a4, a3, a4 /* set sign bit */
|
||||||
j .Lafter_extend_sign
|
j .Lafter_extend_sign
|
||||||
|
|
||||||
|
.Lwrite_value_direct_reg:
|
||||||
|
/* Directly update register index a2, in range 6-15, using value in a4 */
|
||||||
|
addi a2, a2, -6
|
||||||
|
slli a2, a2, 3 /* offset from a6, x8 */
|
||||||
|
movi a3, .Ldirect_reg_jumptable
|
||||||
|
add a2, a2, a3
|
||||||
|
jx a2
|
||||||
|
.align 8
|
||||||
|
.Ldirect_reg_jumptable:
|
||||||
|
mov a6, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a7, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a8, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a9, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a10, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a11, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a12, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a13, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a14, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
.align 8
|
||||||
|
mov a15, a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
|
||||||
|
.Lwrite_value_a0_reg:
|
||||||
|
/* a0 is saved in excsave1,so just update this with value */
|
||||||
|
wsr.excsave1 a4
|
||||||
|
j .Lafter_write_value
|
||||||
|
|
||||||
.global _xt_user_exit
|
.global _xt_user_exit
|
||||||
.type _xt_user_exit, @function
|
.type _xt_user_exit, @function
|
||||||
_xt_user_exit:
|
_xt_user_exit:
|
||||||
|
|
Loading…
Reference in a new issue