xref: /linux/arch/x86/lib/atomic64_386_32.S (revision b85d45947951d23cb22d90caecf4c1eb81342c96)
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
15/* if you want SMP support, implement these with real spinlocks */
16.macro LOCK reg
17	pushfl
18	cli
19.endm
20
21.macro UNLOCK reg
22	popfl
23.endm
24
25#define BEGIN(op) \
26.macro endp; \
27ENDPROC(atomic64_##op##_386); \
28.purgem endp; \
29.endm; \
30ENTRY(atomic64_##op##_386); \
31	LOCK v;
32
33#define ENDP endp
34
35#define RET \
36	UNLOCK v; \
37	ret
38
39#define RET_ENDP \
40	RET; \
41	ENDP
42
43#define v %ecx
44BEGIN(read)
45	movl  (v), %eax
46	movl 4(v), %edx
47RET_ENDP
48#undef v
49
50#define v %esi
51BEGIN(set)
52	movl %ebx,  (v)
53	movl %ecx, 4(v)
54RET_ENDP
55#undef v
56
57#define v  %esi
58BEGIN(xchg)
59	movl  (v), %eax
60	movl 4(v), %edx
61	movl %ebx,  (v)
62	movl %ecx, 4(v)
63RET_ENDP
64#undef v
65
66#define v %ecx
67BEGIN(add)
68	addl %eax,  (v)
69	adcl %edx, 4(v)
70RET_ENDP
71#undef v
72
73#define v %ecx
74BEGIN(add_return)
75	addl  (v), %eax
76	adcl 4(v), %edx
77	movl %eax,  (v)
78	movl %edx, 4(v)
79RET_ENDP
80#undef v
81
82#define v %ecx
83BEGIN(sub)
84	subl %eax,  (v)
85	sbbl %edx, 4(v)
86RET_ENDP
87#undef v
88
89#define v %ecx
90BEGIN(sub_return)
91	negl %edx
92	negl %eax
93	sbbl $0, %edx
94	addl  (v), %eax
95	adcl 4(v), %edx
96	movl %eax,  (v)
97	movl %edx, 4(v)
98RET_ENDP
99#undef v
100
101#define v %esi
102BEGIN(inc)
103	addl $1,  (v)
104	adcl $0, 4(v)
105RET_ENDP
106#undef v
107
108#define v %esi
109BEGIN(inc_return)
110	movl  (v), %eax
111	movl 4(v), %edx
112	addl $1, %eax
113	adcl $0, %edx
114	movl %eax,  (v)
115	movl %edx, 4(v)
116RET_ENDP
117#undef v
118
119#define v %esi
120BEGIN(dec)
121	subl $1,  (v)
122	sbbl $0, 4(v)
123RET_ENDP
124#undef v
125
126#define v %esi
127BEGIN(dec_return)
128	movl  (v), %eax
129	movl 4(v), %edx
130	subl $1, %eax
131	sbbl $0, %edx
132	movl %eax,  (v)
133	movl %edx, 4(v)
134RET_ENDP
135#undef v
136
137#define v %esi
138BEGIN(add_unless)
139	addl %eax, %ecx
140	adcl %edx, %edi
141	addl  (v), %eax
142	adcl 4(v), %edx
143	cmpl %eax, %ecx
144	je 3f
1451:
146	movl %eax,  (v)
147	movl %edx, 4(v)
148	movl $1, %eax
1492:
150	RET
1513:
152	cmpl %edx, %edi
153	jne 1b
154	xorl %eax, %eax
155	jmp 2b
156ENDP
157#undef v
158
159#define v %esi
160BEGIN(inc_not_zero)
161	movl  (v), %eax
162	movl 4(v), %edx
163	testl %eax, %eax
164	je 3f
1651:
166	addl $1, %eax
167	adcl $0, %edx
168	movl %eax,  (v)
169	movl %edx, 4(v)
170	movl $1, %eax
1712:
172	RET
1733:
174	testl %edx, %edx
175	jne 1b
176	jmp 2b
177ENDP
178#undef v
179
180#define v %esi
181BEGIN(dec_if_positive)
182	movl  (v), %eax
183	movl 4(v), %edx
184	subl $1, %eax
185	sbbl $0, %edx
186	js 1f
187	movl %eax,  (v)
188	movl %edx, 4(v)
1891:
190RET_ENDP
191#undef v
192