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