1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * atomic64_t for 386/486
4 *
5 * Copyright © 2010  Luca Barbieri
6 */
7
8#include <linux/linkage.h>
9#include <asm/alternative.h>
10
11/* if you want SMP support, implement these with real spinlocks */
12.macro LOCK reg
13	pushfl
14	cli
15.endm
16
17.macro UNLOCK reg
18	popfl
19.endm
20
21#define BEGIN(op) \
22.macro endp; \
23SYM_FUNC_END(atomic64_##op##_386); \
24.purgem endp; \
25.endm; \
26SYM_FUNC_START(atomic64_##op##_386); \
27	LOCK v;
28
29#define ENDP endp
30
31#define RET \
32	UNLOCK v; \
33	ret
34
35#define RET_ENDP \
36	RET; \
37	ENDP
38
39#define v %ecx
40BEGIN(read)
41	movl  (v), %eax
42	movl 4(v), %edx
43RET_ENDP
44#undef v
45
46#define v %esi
47BEGIN(set)
48	movl %ebx,  (v)
49	movl %ecx, 4(v)
50RET_ENDP
51#undef v
52
53#define v  %esi
54BEGIN(xchg)
55	movl  (v), %eax
56	movl 4(v), %edx
57	movl %ebx,  (v)
58	movl %ecx, 4(v)
59RET_ENDP
60#undef v
61
62#define v %ecx
63BEGIN(add)
64	addl %eax,  (v)
65	adcl %edx, 4(v)
66RET_ENDP
67#undef v
68
69#define v %ecx
70BEGIN(add_return)
71	addl  (v), %eax
72	adcl 4(v), %edx
73	movl %eax,  (v)
74	movl %edx, 4(v)
75RET_ENDP
76#undef v
77
78#define v %ecx
79BEGIN(sub)
80	subl %eax,  (v)
81	sbbl %edx, 4(v)
82RET_ENDP
83#undef v
84
85#define v %ecx
86BEGIN(sub_return)
87	negl %edx
88	negl %eax
89	sbbl $0, %edx
90	addl  (v), %eax
91	adcl 4(v), %edx
92	movl %eax,  (v)
93	movl %edx, 4(v)
94RET_ENDP
95#undef v
96
97#define v %esi
98BEGIN(inc)
99	addl $1,  (v)
100	adcl $0, 4(v)
101RET_ENDP
102#undef v
103
104#define v %esi
105BEGIN(inc_return)
106	movl  (v), %eax
107	movl 4(v), %edx
108	addl $1, %eax
109	adcl $0, %edx
110	movl %eax,  (v)
111	movl %edx, 4(v)
112RET_ENDP
113#undef v
114
115#define v %esi
116BEGIN(dec)
117	subl $1,  (v)
118	sbbl $0, 4(v)
119RET_ENDP
120#undef v
121
122#define v %esi
123BEGIN(dec_return)
124	movl  (v), %eax
125	movl 4(v), %edx
126	subl $1, %eax
127	sbbl $0, %edx
128	movl %eax,  (v)
129	movl %edx, 4(v)
130RET_ENDP
131#undef v
132
133#define v %esi
134BEGIN(add_unless)
135	addl %eax, %ecx
136	adcl %edx, %edi
137	addl  (v), %eax
138	adcl 4(v), %edx
139	cmpl %eax, %ecx
140	je 3f
1411:
142	movl %eax,  (v)
143	movl %edx, 4(v)
144	movl $1, %eax
1452:
146	RET
1473:
148	cmpl %edx, %edi
149	jne 1b
150	xorl %eax, %eax
151	jmp 2b
152ENDP
153#undef v
154
155#define v %esi
156BEGIN(inc_not_zero)
157	movl  (v), %eax
158	movl 4(v), %edx
159	testl %eax, %eax
160	je 3f
1611:
162	addl $1, %eax
163	adcl $0, %edx
164	movl %eax,  (v)
165	movl %edx, 4(v)
166	movl $1, %eax
1672:
168	RET
1693:
170	testl %edx, %edx
171	jne 1b
172	jmp 2b
173ENDP
174#undef v
175
176#define v %esi
177BEGIN(dec_if_positive)
178	movl  (v), %eax
179	movl 4(v), %edx
180	subl $1, %eax
181	sbbl $0, %edx
182	js 1f
183	movl %eax,  (v)
184	movl %edx, 4(v)
1851:
186RET_ENDP
187#undef v
188