|  | /* SPDX-License-Identifier: GPL-2.0 */ | 
|  | // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. | 
|  |  | 
|  | #include <linux/linkage.h> | 
|  | #include <abi/entry.h> | 
|  |  | 
|  | .text | 
|  |  | 
|  | /* | 
|  | * int csky_cmpxchg(int oldval, int newval, int *ptr) | 
|  | * | 
|  | * If *ptr != oldval && return 1, | 
|  | * else *ptr = newval return 0. | 
|  | */ | 
|  | ENTRY(csky_cmpxchg) | 
|  | USPTOKSP | 
|  | mfcr	a3, epc | 
|  | addi	a3, TRAP0_SIZE | 
|  |  | 
|  | subi    sp, 16 | 
|  | stw     a3, (sp, 0) | 
|  | mfcr    a3, epsr | 
|  | stw     a3, (sp, 4) | 
|  | mfcr	a3, usp | 
|  | stw     a3, (sp, 8) | 
|  |  | 
|  | psrset	ee | 
|  | #ifdef CONFIG_CPU_HAS_LDSTEX | 
|  | 1: | 
|  | ldex	a3, (a2) | 
|  | cmpne	a0, a3 | 
|  | bt16	2f | 
|  | mov	a3, a1 | 
|  | stex	a3, (a2) | 
|  | bez	a3, 1b | 
|  | 2: | 
|  | sync.is | 
|  | #else | 
|  | 1: | 
|  | ldw	a3, (a2) | 
|  | cmpne	a0, a3 | 
|  | bt16	3f | 
|  | 2: | 
|  | stw	a1, (a2) | 
|  | 3: | 
|  | #endif | 
|  | mvc	a0 | 
|  | ldw	a3, (sp, 0) | 
|  | mtcr	a3, epc | 
|  | ldw     a3, (sp, 4) | 
|  | mtcr	a3, epsr | 
|  | ldw     a3, (sp, 8) | 
|  | mtcr	a3, usp | 
|  | addi	sp, 16 | 
|  | KSPTOUSP | 
|  | rte | 
|  | END(csky_cmpxchg) | 
|  |  | 
|  | #ifndef CONFIG_CPU_HAS_LDSTEX | 
|  | /* | 
|  | * Called from tlbmodified exception | 
|  | */ | 
|  | ENTRY(csky_cmpxchg_fixup) | 
|  | mfcr	a0, epc | 
|  | lrw	a1, 2b | 
|  | cmpne	a1, a0 | 
|  | bt	1f | 
|  | subi	a1, (2b - 1b) | 
|  | stw	a1, (sp, LSAVE_PC) | 
|  | 1: | 
|  | rts | 
|  | END(csky_cmpxchg_fixup) | 
|  | #endif |