xref: /linux/arch/x86/lib/atomic64_386_32.S (revision e9fb13bfec7e017130ddc5c1b5466340470f4900)
1/*
2 * atomic64_t for 386/486
3 *
4 * Copyright © 2010  Luca Barbieri
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/linkage.h>
13#include <asm/alternative-asm.h>
14#include <asm/dwarf2.h>
15
16/* if you want SMP support, implement these with real spinlocks */
17.macro LOCK reg
18	pushfl_cfi
19	cli
20.endm
21
22.macro UNLOCK reg
23	popfl_cfi
24.endm
25
26#define BEGIN(op) \
27.macro endp; \
28	CFI_ENDPROC; \
29ENDPROC(atomic64_##op##_386); \
30.purgem endp; \
31.endm; \
32ENTRY(atomic64_##op##_386); \
33	CFI_STARTPROC; \
34	LOCK v;
35
36#define ENDP endp
37
38#define RET \
39	UNLOCK v; \
40	ret
41
42#define RET_ENDP \
43	RET; \
44	ENDP
45
46#define v %ecx
47BEGIN(read)
48	movl  (v), %eax
49	movl 4(v), %edx
50RET_ENDP
51#undef v
52
53#define v %esi
54BEGIN(set)
55	movl %ebx,  (v)
56	movl %ecx, 4(v)
57RET_ENDP
58#undef v
59
60#define v  %esi
61BEGIN(xchg)
62	movl  (v), %eax
63	movl 4(v), %edx
64	movl %ebx,  (v)
65	movl %ecx, 4(v)
66RET_ENDP
67#undef v
68
69#define v %ecx
70BEGIN(add)
71	addl %eax,  (v)
72	adcl %edx, 4(v)
73RET_ENDP
74#undef v
75
76#define v %ecx
77BEGIN(add_return)
78	addl  (v), %eax
79	adcl 4(v), %edx
80	movl %eax,  (v)
81	movl %edx, 4(v)
82RET_ENDP
83#undef v
84
85#define v %ecx
86BEGIN(sub)
87	subl %eax,  (v)
88	sbbl %edx, 4(v)
89RET_ENDP
90#undef v
91
92#define v %ecx
93BEGIN(sub_return)
94	negl %edx
95	negl %eax
96	sbbl $0, %edx
97	addl  (v), %eax
98	adcl 4(v), %edx
99	movl %eax,  (v)
100	movl %edx, 4(v)
101RET_ENDP
102#undef v
103
104#define v %esi
105BEGIN(inc)
106	addl $1,  (v)
107	adcl $0, 4(v)
108RET_ENDP
109#undef v
110
111#define v %esi
112BEGIN(inc_return)
113	movl  (v), %eax
114	movl 4(v), %edx
115	addl $1, %eax
116	adcl $0, %edx
117	movl %eax,  (v)
118	movl %edx, 4(v)
119RET_ENDP
120#undef v
121
122#define v %esi
123BEGIN(dec)
124	subl $1,  (v)
125	sbbl $0, 4(v)
126RET_ENDP
127#undef v
128
129#define v %esi
130BEGIN(dec_return)
131	movl  (v), %eax
132	movl 4(v), %edx
133	subl $1, %eax
134	sbbl $0, %edx
135	movl %eax,  (v)
136	movl %edx, 4(v)
137RET_ENDP
138#undef v
139
140#define v %ecx
141BEGIN(add_unless)
142	addl %eax, %esi
143	adcl %edx, %edi
144	addl  (v), %eax
145	adcl 4(v), %edx
146	cmpl %eax, %esi
147	je 3f
1481:
149	movl %eax,  (v)
150	movl %edx, 4(v)
151	movl $1, %eax
1522:
153	RET
1543:
155	cmpl %edx, %edi
156	jne 1b
157	xorl %eax, %eax
158	jmp 2b
159ENDP
160#undef v
161
162#define v %esi
163BEGIN(inc_not_zero)
164	movl  (v), %eax
165	movl 4(v), %edx
166	testl %eax, %eax
167	je 3f
1681:
169	addl $1, %eax
170	adcl $0, %edx
171	movl %eax,  (v)
172	movl %edx, 4(v)
173	movl $1, %eax
1742:
175	RET
1763:
177	testl %edx, %edx
178	jne 1b
179	jmp 2b
180ENDP
181#undef v
182
183#define v %esi
184BEGIN(dec_if_positive)
185	movl  (v), %eax
186	movl 4(v), %edx
187	subl $1, %eax
188	sbbl $0, %edx
189	js 1f
190	movl %eax,  (v)
191	movl %edx, 4(v)
1921:
193RET_ENDP
194#undef v
195