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