Loading...
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-asm.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; \
23ENDPROC(atomic64_##op##_386); \
24.purgem endp; \
25.endm; \
26ENTRY(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
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