xtensa: fix atomic_cas reporting value swapped even when not

The atomic_cas function was using incorrect register when determining
whether value was swapped. The swapping instruction s32c1i in
atomic_cas stores the value at memory location in register a4
regardless of whether swapping is done. In this case, the register a4
should be used to determine whether a swap is done. However, register
a3 (containing the oldValue as function argument) is used instead.
Since register a5 contains the old value at address loaded before
the swapping instruction, a3 and a5 contain the same value.
Since a3 == a5 is always true in this case, the function will always
return 1 even though values are not swapped. So fix it by using
the correct register.

Also, in case the value is not swapped, it jumps to where it returns
zero instead of loading from memory and comparing again.
The function was simply looping until swapping was done, which did not
align with the API where it would return 0 when swapping is not done
(regardless whether the memory location contains the old value or not).

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2020-01-06 17:27:27 -08:00 committed by Anas Nashif
parent 0c9109523e
commit 017a8eea4f

View file

@ -391,15 +391,15 @@ atomic_xor:
.align 4
atomic_cas:
ENTRY(48)
.L_LoopCas:
l32ai a5, a2, 0
beq a5, a3, 1f
movi a2, 0
j 2f
beq a5, a3, 2f
1:
movi a2, 0
j 3f
2:
wsr a5, scompare1
s32c1i a4, a2, 0
bne a3, a5, .L_LoopCas
bne a4, a5, 1b
movi a2, 1
2:
3:
RET(48)