Linux-libre 5.7.6-gnu
[librecmc/linux-libre.git] / arch / csky / kernel / atomic.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4 #include <linux/linkage.h>
5 #include <abi/entry.h>
6
7 .text
8
9 /*
10  * int csky_cmpxchg(int oldval, int newval, int *ptr)
11  *
12  * If *ptr != oldval && return 1,
13  * else *ptr = newval return 0.
14  */
15 ENTRY(csky_cmpxchg)
16         USPTOKSP
17         mfcr    a3, epc
18         addi    a3, TRAP0_SIZE
19
20         subi    sp, 16
21         stw     a3, (sp, 0)
22         mfcr    a3, epsr
23         stw     a3, (sp, 4)
24         mfcr    a3, usp
25         stw     a3, (sp, 8)
26
27         psrset  ee
28 #ifdef CONFIG_CPU_HAS_LDSTEX
29 1:
30         ldex    a3, (a2)
31         cmpne   a0, a3
32         bt16    2f
33         mov     a3, a1
34         stex    a3, (a2)
35         bez     a3, 1b
36 2:
37         sync.is
38 #else
39 1:
40         ldw     a3, (a2)
41         cmpne   a0, a3
42         bt16    3f
43 2:
44         stw     a1, (a2)
45 3:
46 #endif
47         mvc     a0
48         ldw     a3, (sp, 0)
49         mtcr    a3, epc
50         ldw     a3, (sp, 4)
51         mtcr    a3, epsr
52         ldw     a3, (sp, 8)
53         mtcr    a3, usp
54         addi    sp, 16
55         KSPTOUSP
56         rte
57 END(csky_cmpxchg)
58
59 #ifndef CONFIG_CPU_HAS_LDSTEX
60 /*
61  * Called from tlbmodified exception
62  */
63 ENTRY(csky_cmpxchg_fixup)
64         mfcr    a0, epc
65         lrw     a1, 2b
66         cmpne   a1, a0
67         bt      1f
68         subi    a1, (2b - 1b)
69         stw     a1, (sp, LSAVE_PC)
70 1:
71         rts
72 END(csky_cmpxchg_fixup)
73 #endif