Commit e9500dd8 authored by Max Filippov's avatar Max Filippov

xtensa: make fast_unaligned store restartable

fast_unaligned may encounter DTLB miss or SEGFAULT during the store
emulation. Don't update epc1 and lcount until after the store emulation
is complete, so that the faulting store instruction could be replayed.
Remove duplicate code handling zero overhead loops and calculate new
epc1 and lcount in one place.
Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent c3ef1f4d
...@@ -277,18 +277,6 @@ ENTRY(fast_unaligned) ...@@ -277,18 +277,6 @@ ENTRY(fast_unaligned)
/* Set target register. */ /* Set target register. */
1: 1:
#if XCHAL_HAVE_LOOPS
rsr a5, lend # check if we reached LEND
bne a7, a5, 1f
rsr a5, lcount # and LCOUNT != 0
beqz a5, 1f
addi a5, a5, -1 # decrement LCOUNT and set
rsr a7, lbeg # set PC to LBEGIN
wsr a5, lcount
#endif
1: wsr a7, epc1 # skip load instruction
extui a4, a4, INSN_T, 4 # extract target register extui a4, a4, INSN_T, 4 # extract target register
movi a5, .Lload_table movi a5, .Lload_table
addx8 a4, a4, a5 addx8 a4, a4, a5
...@@ -358,17 +346,6 @@ ENTRY(fast_unaligned) ...@@ -358,17 +346,6 @@ ENTRY(fast_unaligned)
/* Get memory address */ /* Get memory address */
1: 1:
#if XCHAL_HAVE_LOOPS
rsr a4, lend # check if we reached LEND
bne a7, a4, 1f
rsr a4, lcount # and LCOUNT != 0
beqz a4, 1f
addi a4, a4, -1 # decrement LCOUNT and set
rsr a7, lbeg # set PC to LBEGIN
wsr a4, lcount
#endif
1: wsr a7, epc1 # skip store instruction
movi a4, ~3 movi a4, ~3
and a4, a4, a8 # align memory address and a4, a4, a8 # align memory address
...@@ -380,25 +357,25 @@ ENTRY(fast_unaligned) ...@@ -380,25 +357,25 @@ ENTRY(fast_unaligned)
#endif #endif
__ssa8r a8 __ssa8r a8
__src_b a7, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE) __src_b a8, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE)
__src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE) __src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE)
#ifdef UNALIGNED_USER_EXCEPTION #ifdef UNALIGNED_USER_EXCEPTION
l32e a5, a4, -8 l32e a5, a4, -8
#else #else
l32i a5, a4, 0 # load lower address word l32i a5, a4, 0 # load lower address word
#endif #endif
and a5, a5, a7 # mask and a5, a5, a8 # mask
__sh a7, a3 # shift value __sh a8, a3 # shift value
or a5, a5, a7 # or with original value or a5, a5, a8 # or with original value
#ifdef UNALIGNED_USER_EXCEPTION #ifdef UNALIGNED_USER_EXCEPTION
s32e a5, a4, -8 s32e a5, a4, -8
l32e a7, a4, -4 l32e a8, a4, -4
#else #else
s32i a5, a4, 0 # store s32i a5, a4, 0 # store
l32i a7, a4, 4 # same for upper address word l32i a8, a4, 4 # same for upper address word
#endif #endif
__sl a5, a3 __sl a5, a3
and a6, a7, a6 and a6, a8, a6
or a6, a6, a5 or a6, a6, a5
#ifdef UNALIGNED_USER_EXCEPTION #ifdef UNALIGNED_USER_EXCEPTION
s32e a6, a4, -4 s32e a6, a4, -4
...@@ -406,9 +383,19 @@ ENTRY(fast_unaligned) ...@@ -406,9 +383,19 @@ ENTRY(fast_unaligned)
s32i a6, a4, 4 s32i a6, a4, 4
#endif #endif
/* Done. restore stack and return */
.Lexit: .Lexit:
#if XCHAL_HAVE_LOOPS
rsr a4, lend # check if we reached LEND
bne a7, a4, 1f
rsr a4, lcount # and LCOUNT != 0
beqz a4, 1f
addi a4, a4, -1 # decrement LCOUNT and set
rsr a7, lbeg # set PC to LBEGIN
wsr a4, lcount
#endif
1: wsr a7, epc1 # skip emulated instruction
movi a4, 0 movi a4, 0
rsr a3, excsave1 rsr a3, excsave1
s32i a4, a3, EXC_TABLE_FIXUP s32i a4, a3, EXC_TABLE_FIXUP
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment