diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 12:23:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 12:23:57 -0400 |
commit | 1b674bf106f59e04e24b3825c2f08dcd9a5b7264 (patch) | |
tree | b90b52b692111f0be66eaf7efb040e35a6e763e3 /arch | |
parent | e17fdf5c6778ff77d93dd769910992e4073b9348 (diff) | |
parent | cb8095bba6d24118135a5683a956f4f4fb5f17bb (diff) |
Merge branch 'x86-atomic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86/atomic changes from Ingo Molnar.
* 'x86-atomic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86: atomic64 assembly improvements
x86: Adjust asm constraints in atomic64 wrappers
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/alternative.h | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/atomic64_32.h | 146 | ||||
-rw-r--r-- | arch/x86/lib/atomic64_32.c | 59 | ||||
-rw-r--r-- | arch/x86/lib/atomic64_386_32.S | 6 | ||||
-rw-r--r-- | arch/x86/lib/atomic64_cx8_32.S | 29 |
5 files changed, 101 insertions, 145 deletions
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 37ad100a2210..49331bedc158 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h | |||
@@ -145,6 +145,12 @@ static inline int alternatives_text_reserved(void *start, void *end) | |||
145 | */ | 145 | */ |
146 | #define ASM_OUTPUT2(a...) a | 146 | #define ASM_OUTPUT2(a...) a |
147 | 147 | ||
148 | /* | ||
149 | * use this macro if you need clobbers but no inputs in | ||
150 | * alternative_{input,io,call}() | ||
151 | */ | ||
152 | #define ASM_NO_INPUT_CLOBBER(clbr...) "i" (0) : clbr | ||
153 | |||
148 | struct paravirt_patch_site; | 154 | struct paravirt_patch_site; |
149 | #ifdef CONFIG_PARAVIRT | 155 | #ifdef CONFIG_PARAVIRT |
150 | void apply_paravirt(struct paravirt_patch_site *start, | 156 | void apply_paravirt(struct paravirt_patch_site *start, |
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h index fa13f0ec2874..198119910da5 100644 --- a/arch/x86/include/asm/atomic64_32.h +++ b/arch/x86/include/asm/atomic64_32.h | |||
@@ -14,13 +14,52 @@ typedef struct { | |||
14 | 14 | ||
15 | #define ATOMIC64_INIT(val) { (val) } | 15 | #define ATOMIC64_INIT(val) { (val) } |
16 | 16 | ||
17 | #define __ATOMIC64_DECL(sym) void atomic64_##sym(atomic64_t *, ...) | ||
18 | #ifndef ATOMIC64_EXPORT | ||
19 | #define ATOMIC64_DECL_ONE __ATOMIC64_DECL | ||
20 | #else | ||
21 | #define ATOMIC64_DECL_ONE(sym) __ATOMIC64_DECL(sym); \ | ||
22 | ATOMIC64_EXPORT(atomic64_##sym) | ||
23 | #endif | ||
24 | |||
17 | #ifdef CONFIG_X86_CMPXCHG64 | 25 | #ifdef CONFIG_X86_CMPXCHG64 |
18 | #define ATOMIC64_ALTERNATIVE_(f, g) "call atomic64_" #g "_cx8" | 26 | #define __alternative_atomic64(f, g, out, in...) \ |
27 | asm volatile("call %P[func]" \ | ||
28 | : out : [func] "i" (atomic64_##g##_cx8), ## in) | ||
29 | |||
30 | #define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8) | ||
19 | #else | 31 | #else |
20 | #define ATOMIC64_ALTERNATIVE_(f, g) ALTERNATIVE("call atomic64_" #f "_386", "call atomic64_" #g "_cx8", X86_FEATURE_CX8) | 32 | #define __alternative_atomic64(f, g, out, in...) \ |
33 | alternative_call(atomic64_##f##_386, atomic64_##g##_cx8, \ | ||
34 | X86_FEATURE_CX8, ASM_OUTPUT2(out), ## in) | ||
35 | |||
36 | #define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8); \ | ||
37 | ATOMIC64_DECL_ONE(sym##_386) | ||
38 | |||
39 | ATOMIC64_DECL_ONE(add_386); | ||
40 | ATOMIC64_DECL_ONE(sub_386); | ||
41 | ATOMIC64_DECL_ONE(inc_386); | ||
42 | ATOMIC64_DECL_ONE(dec_386); | ||
21 | #endif | 43 | #endif |
22 | 44 | ||
23 | #define ATOMIC64_ALTERNATIVE(f) ATOMIC64_ALTERNATIVE_(f, f) | 45 | #define alternative_atomic64(f, out, in...) \ |
46 | __alternative_atomic64(f, f, ASM_OUTPUT2(out), ## in) | ||
47 | |||
48 | ATOMIC64_DECL(read); | ||
49 | ATOMIC64_DECL(set); | ||
50 | ATOMIC64_DECL(xchg); | ||
51 | ATOMIC64_DECL(add_return); | ||
52 | ATOMIC64_DECL(sub_return); | ||
53 | ATOMIC64_DECL(inc_return); | ||
54 | ATOMIC64_DECL(dec_return); | ||
55 | ATOMIC64_DECL(dec_if_positive); | ||
56 | ATOMIC64_DECL(inc_not_zero); | ||
57 | ATOMIC64_DECL(add_unless); | ||
58 | |||
59 | #undef ATOMIC64_DECL | ||
60 | #undef ATOMIC64_DECL_ONE | ||
61 | #undef __ATOMIC64_DECL | ||
62 | #undef ATOMIC64_EXPORT | ||
24 | 63 | ||
25 | /** | 64 | /** |
26 | * atomic64_cmpxchg - cmpxchg atomic64 variable | 65 | * atomic64_cmpxchg - cmpxchg atomic64 variable |
@@ -50,11 +89,9 @@ static inline long long atomic64_xchg(atomic64_t *v, long long n) | |||
50 | long long o; | 89 | long long o; |
51 | unsigned high = (unsigned)(n >> 32); | 90 | unsigned high = (unsigned)(n >> 32); |
52 | unsigned low = (unsigned)n; | 91 | unsigned low = (unsigned)n; |
53 | asm volatile(ATOMIC64_ALTERNATIVE(xchg) | 92 | alternative_atomic64(xchg, "=&A" (o), |
54 | : "=A" (o), "+b" (low), "+c" (high) | 93 | "S" (v), "b" (low), "c" (high) |
55 | : "S" (v) | 94 | : "memory"); |
56 | : "memory" | ||
57 | ); | ||
58 | return o; | 95 | return o; |
59 | } | 96 | } |
60 | 97 | ||
@@ -69,11 +106,9 @@ static inline void atomic64_set(atomic64_t *v, long long i) | |||
69 | { | 106 | { |
70 | unsigned high = (unsigned)(i >> 32); | 107 | unsigned high = (unsigned)(i >> 32); |
71 | unsigned low = (unsigned)i; | 108 | unsigned low = (unsigned)i; |
72 | asm volatile(ATOMIC64_ALTERNATIVE(set) | 109 | alternative_atomic64(set, /* no output */, |
73 | : "+b" (low), "+c" (high) | 110 | "S" (v), "b" (low), "c" (high) |
74 | : "S" (v) | 111 | : "eax", "edx", "memory"); |
75 | : "eax", "edx", "memory" | ||
76 | ); | ||
77 | } | 112 | } |
78 | 113 | ||
79 | /** | 114 | /** |
@@ -85,10 +120,7 @@ static inline void atomic64_set(atomic64_t *v, long long i) | |||
85 | static inline long long atomic64_read(const atomic64_t *v) | 120 | static inline long long atomic64_read(const atomic64_t *v) |
86 | { | 121 | { |
87 | long long r; | 122 | long long r; |
88 | asm volatile(ATOMIC64_ALTERNATIVE(read) | 123 | alternative_atomic64(read, "=&A" (r), "c" (v) : "memory"); |
89 | : "=A" (r), "+c" (v) | ||
90 | : : "memory" | ||
91 | ); | ||
92 | return r; | 124 | return r; |
93 | } | 125 | } |
94 | 126 | ||
@@ -101,10 +133,9 @@ static inline long long atomic64_read(const atomic64_t *v) | |||
101 | */ | 133 | */ |
102 | static inline long long atomic64_add_return(long long i, atomic64_t *v) | 134 | static inline long long atomic64_add_return(long long i, atomic64_t *v) |
103 | { | 135 | { |
104 | asm volatile(ATOMIC64_ALTERNATIVE(add_return) | 136 | alternative_atomic64(add_return, |
105 | : "+A" (i), "+c" (v) | 137 | ASM_OUTPUT2("+A" (i), "+c" (v)), |
106 | : : "memory" | 138 | ASM_NO_INPUT_CLOBBER("memory")); |
107 | ); | ||
108 | return i; | 139 | return i; |
109 | } | 140 | } |
110 | 141 | ||
@@ -113,32 +144,25 @@ static inline long long atomic64_add_return(long long i, atomic64_t *v) | |||
113 | */ | 144 | */ |
114 | static inline long long atomic64_sub_return(long long i, atomic64_t *v) | 145 | static inline long long atomic64_sub_return(long long i, atomic64_t *v) |
115 | { | 146 | { |
116 | asm volatile(ATOMIC64_ALTERNATIVE(sub_return) | 147 | alternative_atomic64(sub_return, |
117 | : "+A" (i), "+c" (v) | 148 | ASM_OUTPUT2("+A" (i), "+c" (v)), |
118 | : : "memory" | 149 | ASM_NO_INPUT_CLOBBER("memory")); |
119 | ); | ||
120 | return i; | 150 | return i; |
121 | } | 151 | } |
122 | 152 | ||
123 | static inline long long atomic64_inc_return(atomic64_t *v) | 153 | static inline long long atomic64_inc_return(atomic64_t *v) |
124 | { | 154 | { |
125 | long long a; | 155 | long long a; |
126 | asm volatile(ATOMIC64_ALTERNATIVE(inc_return) | 156 | alternative_atomic64(inc_return, "=&A" (a), |
127 | : "=A" (a) | 157 | "S" (v) : "memory", "ecx"); |
128 | : "S" (v) | ||
129 | : "memory", "ecx" | ||
130 | ); | ||
131 | return a; | 158 | return a; |
132 | } | 159 | } |
133 | 160 | ||
134 | static inline long long atomic64_dec_return(atomic64_t *v) | 161 | static inline long long atomic64_dec_return(atomic64_t *v) |
135 | { | 162 | { |
136 | long long a; | 163 | long long a; |
137 | asm volatile(ATOMIC64_ALTERNATIVE(dec_return) | 164 | alternative_atomic64(dec_return, "=&A" (a), |
138 | : "=A" (a) | 165 | "S" (v) : "memory", "ecx"); |
139 | : "S" (v) | ||
140 | : "memory", "ecx" | ||
141 | ); | ||
142 | return a; | 166 | return a; |
143 | } | 167 | } |
144 | 168 | ||
@@ -151,10 +175,9 @@ static inline long long atomic64_dec_return(atomic64_t *v) | |||
151 | */ | 175 | */ |
152 | static inline long long atomic64_add(long long i, atomic64_t *v) | 176 | static inline long long atomic64_add(long long i, atomic64_t *v) |
153 | { | 177 | { |
154 | asm volatile(ATOMIC64_ALTERNATIVE_(add, add_return) | 178 | __alternative_atomic64(add, add_return, |
155 | : "+A" (i), "+c" (v) | 179 | ASM_OUTPUT2("+A" (i), "+c" (v)), |
156 | : : "memory" | 180 | ASM_NO_INPUT_CLOBBER("memory")); |
157 | ); | ||
158 | return i; | 181 | return i; |
159 | } | 182 | } |
160 | 183 | ||
@@ -167,10 +190,9 @@ static inline long long atomic64_add(long long i, atomic64_t *v) | |||
167 | */ | 190 | */ |
168 | static inline long long atomic64_sub(long long i, atomic64_t *v) | 191 | static inline long long atomic64_sub(long long i, atomic64_t *v) |
169 | { | 192 | { |
170 | asm volatile(ATOMIC64_ALTERNATIVE_(sub, sub_return) | 193 | __alternative_atomic64(sub, sub_return, |
171 | : "+A" (i), "+c" (v) | 194 | ASM_OUTPUT2("+A" (i), "+c" (v)), |
172 | : : "memory" | 195 | ASM_NO_INPUT_CLOBBER("memory")); |
173 | ); | ||
174 | return i; | 196 | return i; |
175 | } | 197 | } |
176 | 198 | ||
@@ -196,10 +218,8 @@ static inline int atomic64_sub_and_test(long long i, atomic64_t *v) | |||
196 | */ | 218 | */ |
197 | static inline void atomic64_inc(atomic64_t *v) | 219 | static inline void atomic64_inc(atomic64_t *v) |
198 | { | 220 | { |
199 | asm volatile(ATOMIC64_ALTERNATIVE_(inc, inc_return) | 221 | __alternative_atomic64(inc, inc_return, /* no output */, |
200 | : : "S" (v) | 222 | "S" (v) : "memory", "eax", "ecx", "edx"); |
201 | : "memory", "eax", "ecx", "edx" | ||
202 | ); | ||
203 | } | 223 | } |
204 | 224 | ||
205 | /** | 225 | /** |
@@ -210,10 +230,8 @@ static inline void atomic64_inc(atomic64_t *v) | |||
210 | */ | 230 | */ |
211 | static inline void atomic64_dec(atomic64_t *v) | 231 | static inline void atomic64_dec(atomic64_t *v) |
212 | { | 232 | { |
213 | asm volatile(ATOMIC64_ALTERNATIVE_(dec, dec_return) | 233 | __alternative_atomic64(dec, dec_return, /* no output */, |
214 | : : "S" (v) | 234 | "S" (v) : "memory", "eax", "ecx", "edx"); |
215 | : "memory", "eax", "ecx", "edx" | ||
216 | ); | ||
217 | } | 235 | } |
218 | 236 | ||
219 | /** | 237 | /** |
@@ -263,15 +281,15 @@ static inline int atomic64_add_negative(long long i, atomic64_t *v) | |||
263 | * @u: ...unless v is equal to u. | 281 | * @u: ...unless v is equal to u. |
264 | * | 282 | * |
265 | * Atomically adds @a to @v, so long as it was not @u. | 283 | * Atomically adds @a to @v, so long as it was not @u. |
266 | * Returns the old value of @v. | 284 | * Returns non-zero if the add was done, zero otherwise. |
267 | */ | 285 | */ |
268 | static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) | 286 | static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) |
269 | { | 287 | { |
270 | unsigned low = (unsigned)u; | 288 | unsigned low = (unsigned)u; |
271 | unsigned high = (unsigned)(u >> 32); | 289 | unsigned high = (unsigned)(u >> 32); |
272 | asm volatile(ATOMIC64_ALTERNATIVE(add_unless) "\n\t" | 290 | alternative_atomic64(add_unless, |
273 | : "+A" (a), "+c" (v), "+S" (low), "+D" (high) | 291 | ASM_OUTPUT2("+A" (a), "+c" (low), "+D" (high)), |
274 | : : "memory"); | 292 | "S" (v) : "memory"); |
275 | return (int)a; | 293 | return (int)a; |
276 | } | 294 | } |
277 | 295 | ||
@@ -279,26 +297,20 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) | |||
279 | static inline int atomic64_inc_not_zero(atomic64_t *v) | 297 | static inline int atomic64_inc_not_zero(atomic64_t *v) |
280 | { | 298 | { |
281 | int r; | 299 | int r; |
282 | asm volatile(ATOMIC64_ALTERNATIVE(inc_not_zero) | 300 | alternative_atomic64(inc_not_zero, "=&a" (r), |
283 | : "=a" (r) | 301 | "S" (v) : "ecx", "edx", "memory"); |
284 | : "S" (v) | ||
285 | : "ecx", "edx", "memory" | ||
286 | ); | ||
287 | return r; | 302 | return r; |
288 | } | 303 | } |
289 | 304 | ||
290 | static inline long long atomic64_dec_if_positive(atomic64_t *v) | 305 | static inline long long atomic64_dec_if_positive(atomic64_t *v) |
291 | { | 306 | { |
292 | long long r; | 307 | long long r; |
293 | asm volatile(ATOMIC64_ALTERNATIVE(dec_if_positive) | 308 | alternative_atomic64(dec_if_positive, "=&A" (r), |
294 | : "=A" (r) | 309 | "S" (v) : "ecx", "memory"); |
295 | : "S" (v) | ||
296 | : "ecx", "memory" | ||
297 | ); | ||
298 | return r; | 310 | return r; |
299 | } | 311 | } |
300 | 312 | ||
301 | #undef ATOMIC64_ALTERNATIVE | 313 | #undef alternative_atomic64 |
302 | #undef ATOMIC64_ALTERNATIVE_ | 314 | #undef __alternative_atomic64 |
303 | 315 | ||
304 | #endif /* _ASM_X86_ATOMIC64_32_H */ | 316 | #endif /* _ASM_X86_ATOMIC64_32_H */ |
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c index 042f6826bf57..a0b4a350daa7 100644 --- a/arch/x86/lib/atomic64_32.c +++ b/arch/x86/lib/atomic64_32.c | |||
@@ -1,59 +1,4 @@ | |||
1 | #include <linux/compiler.h> | 1 | #define ATOMIC64_EXPORT EXPORT_SYMBOL |
2 | #include <linux/module.h> | ||
3 | #include <linux/types.h> | ||
4 | 2 | ||
5 | #include <asm/processor.h> | 3 | #include <linux/export.h> |
6 | #include <asm/cmpxchg.h> | ||
7 | #include <linux/atomic.h> | 4 | #include <linux/atomic.h> |
8 | |||
9 | long long atomic64_read_cx8(long long, const atomic64_t *v); | ||
10 | EXPORT_SYMBOL(atomic64_read_cx8); | ||
11 | long long atomic64_set_cx8(long long, const atomic64_t *v); | ||
12 | EXPORT_SYMBOL(atomic64_set_cx8); | ||
13 | long long atomic64_xchg_cx8(long long, unsigned high); | ||
14 | EXPORT_SYMBOL(atomic64_xchg_cx8); | ||
15 | long long atomic64_add_return_cx8(long long a, atomic64_t *v); | ||
16 | EXPORT_SYMBOL(atomic64_add_return_cx8); | ||
17 | long long atomic64_sub_return_cx8(long long a, atomic64_t *v); | ||
18 | EXPORT_SYMBOL(atomic64_sub_return_cx8); | ||
19 | long long atomic64_inc_return_cx8(long long a, atomic64_t *v); | ||
20 | EXPORT_SYMBOL(atomic64_inc_return_cx8); | ||
21 | long long atomic64_dec_return_cx8(long long a, atomic64_t *v); | ||
22 | EXPORT_SYMBOL(atomic64_dec_return_cx8); | ||
23 | long long atomic64_dec_if_positive_cx8(atomic64_t *v); | ||
24 | EXPORT_SYMBOL(atomic64_dec_if_positive_cx8); | ||
25 | int atomic64_inc_not_zero_cx8(atomic64_t *v); | ||
26 | EXPORT_SYMBOL(atomic64_inc_not_zero_cx8); | ||
27 | int atomic64_add_unless_cx8(atomic64_t *v, long long a, long long u); | ||
28 | EXPORT_SYMBOL(atomic64_add_unless_cx8); | ||
29 | |||
30 | #ifndef CONFIG_X86_CMPXCHG64 | ||
31 | long long atomic64_read_386(long long, const atomic64_t *v); | ||
32 | EXPORT_SYMBOL(atomic64_read_386); | ||
33 | long long atomic64_set_386(long long, const atomic64_t *v); | ||
34 | EXPORT_SYMBOL(atomic64_set_386); | ||
35 | long long atomic64_xchg_386(long long, unsigned high); | ||
36 | EXPORT_SYMBOL(atomic64_xchg_386); | ||
37 | long long atomic64_add_return_386(long long a, atomic64_t *v); | ||
38 | EXPORT_SYMBOL(atomic64_add_return_386); | ||
39 | long long atomic64_sub_return_386(long long a, atomic64_t *v); | ||
40 | EXPORT_SYMBOL(atomic64_sub_return_386); | ||
41 | long long atomic64_inc_return_386(long long a, atomic64_t *v); | ||
42 | EXPORT_SYMBOL(atomic64_inc_return_386); | ||
43 | long long atomic64_dec_return_386(long long a, atomic64_t *v); | ||
44 | EXPORT_SYMBOL(atomic64_dec_return_386); | ||
45 | long long atomic64_add_386(long long a, atomic64_t *v); | ||
46 | EXPORT_SYMBOL(atomic64_add_386); | ||
47 | long long atomic64_sub_386(long long a, atomic64_t *v); | ||
48 | EXPORT_SYMBOL(atomic64_sub_386); | ||
49 | long long atomic64_inc_386(long long a, atomic64_t *v); | ||
50 | EXPORT_SYMBOL(atomic64_inc_386); | ||
51 | long long atomic64_dec_386(long long a, atomic64_t *v); | ||
52 | EXPORT_SYMBOL(atomic64_dec_386); | ||
53 | long long atomic64_dec_if_positive_386(atomic64_t *v); | ||
54 | EXPORT_SYMBOL(atomic64_dec_if_positive_386); | ||
55 | int atomic64_inc_not_zero_386(atomic64_t *v); | ||
56 | EXPORT_SYMBOL(atomic64_inc_not_zero_386); | ||
57 | int atomic64_add_unless_386(atomic64_t *v, long long a, long long u); | ||
58 | EXPORT_SYMBOL(atomic64_add_unless_386); | ||
59 | #endif | ||
diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S index e8e7e0d06f42..00933d5e992f 100644 --- a/arch/x86/lib/atomic64_386_32.S +++ b/arch/x86/lib/atomic64_386_32.S | |||
@@ -137,13 +137,13 @@ BEGIN(dec_return) | |||
137 | RET_ENDP | 137 | RET_ENDP |
138 | #undef v | 138 | #undef v |
139 | 139 | ||
140 | #define v %ecx | 140 | #define v %esi |
141 | BEGIN(add_unless) | 141 | BEGIN(add_unless) |
142 | addl %eax, %esi | 142 | addl %eax, %ecx |
143 | adcl %edx, %edi | 143 | adcl %edx, %edi |
144 | addl (v), %eax | 144 | addl (v), %eax |
145 | adcl 4(v), %edx | 145 | adcl 4(v), %edx |
146 | cmpl %eax, %esi | 146 | cmpl %eax, %ecx |
147 | je 3f | 147 | je 3f |
148 | 1: | 148 | 1: |
149 | movl %eax, (v) | 149 | movl %eax, (v) |
diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S index 391a083674b4..f5cc9eb1d51b 100644 --- a/arch/x86/lib/atomic64_cx8_32.S +++ b/arch/x86/lib/atomic64_cx8_32.S | |||
@@ -55,8 +55,6 @@ ENDPROC(atomic64_set_cx8) | |||
55 | ENTRY(atomic64_xchg_cx8) | 55 | ENTRY(atomic64_xchg_cx8) |
56 | CFI_STARTPROC | 56 | CFI_STARTPROC |
57 | 57 | ||
58 | movl %ebx, %eax | ||
59 | movl %ecx, %edx | ||
60 | 1: | 58 | 1: |
61 | LOCK_PREFIX | 59 | LOCK_PREFIX |
62 | cmpxchg8b (%esi) | 60 | cmpxchg8b (%esi) |
@@ -78,7 +76,7 @@ ENTRY(atomic64_\func\()_return_cx8) | |||
78 | movl %edx, %edi | 76 | movl %edx, %edi |
79 | movl %ecx, %ebp | 77 | movl %ecx, %ebp |
80 | 78 | ||
81 | read64 %ebp | 79 | read64 %ecx |
82 | 1: | 80 | 1: |
83 | movl %eax, %ebx | 81 | movl %eax, %ebx |
84 | movl %edx, %ecx | 82 | movl %edx, %ecx |
@@ -159,23 +157,22 @@ ENTRY(atomic64_add_unless_cx8) | |||
159 | SAVE ebx | 157 | SAVE ebx |
160 | /* these just push these two parameters on the stack */ | 158 | /* these just push these two parameters on the stack */ |
161 | SAVE edi | 159 | SAVE edi |
162 | SAVE esi | 160 | SAVE ecx |
163 | 161 | ||
164 | movl %ecx, %ebp | 162 | movl %eax, %ebp |
165 | movl %eax, %esi | ||
166 | movl %edx, %edi | 163 | movl %edx, %edi |
167 | 164 | ||
168 | read64 %ebp | 165 | read64 %esi |
169 | 1: | 166 | 1: |
170 | cmpl %eax, 0(%esp) | 167 | cmpl %eax, 0(%esp) |
171 | je 4f | 168 | je 4f |
172 | 2: | 169 | 2: |
173 | movl %eax, %ebx | 170 | movl %eax, %ebx |
174 | movl %edx, %ecx | 171 | movl %edx, %ecx |
175 | addl %esi, %ebx | 172 | addl %ebp, %ebx |
176 | adcl %edi, %ecx | 173 | adcl %edi, %ecx |
177 | LOCK_PREFIX | 174 | LOCK_PREFIX |
178 | cmpxchg8b (%ebp) | 175 | cmpxchg8b (%esi) |
179 | jne 1b | 176 | jne 1b |
180 | 177 | ||
181 | movl $1, %eax | 178 | movl $1, %eax |
@@ -199,13 +196,13 @@ ENTRY(atomic64_inc_not_zero_cx8) | |||
199 | 196 | ||
200 | read64 %esi | 197 | read64 %esi |
201 | 1: | 198 | 1: |
202 | testl %eax, %eax | 199 | movl %eax, %ecx |
203 | je 4f | 200 | orl %edx, %ecx |
204 | 2: | 201 | jz 3f |
205 | movl %eax, %ebx | 202 | movl %eax, %ebx |
206 | movl %edx, %ecx | 203 | xorl %ecx, %ecx |
207 | addl $1, %ebx | 204 | addl $1, %ebx |
208 | adcl $0, %ecx | 205 | adcl %edx, %ecx |
209 | LOCK_PREFIX | 206 | LOCK_PREFIX |
210 | cmpxchg8b (%esi) | 207 | cmpxchg8b (%esi) |
211 | jne 1b | 208 | jne 1b |
@@ -214,9 +211,5 @@ ENTRY(atomic64_inc_not_zero_cx8) | |||
214 | 3: | 211 | 3: |
215 | RESTORE ebx | 212 | RESTORE ebx |
216 | ret | 213 | ret |
217 | 4: | ||
218 | testl %edx, %edx | ||
219 | jne 2b | ||
220 | jmp 3b | ||
221 | CFI_ENDPROC | 214 | CFI_ENDPROC |
222 | ENDPROC(atomic64_inc_not_zero_cx8) | 215 | ENDPROC(atomic64_inc_not_zero_cx8) |