aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-i386/rwsem.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@macmini.osdl.org>2006-07-08 18:24:18 -0400
committerLinus Torvalds <torvalds@macmini.osdl.org>2006-07-08 18:24:18 -0400
commitb862f3b099f3ea672c7438c0b282ce8201d39dfc (patch)
tree62f8cc2dc2b1c9abb6364b16f3b218a04d121f3e /include/asm-i386/rwsem.h
parente2a3d40258fe20d205f8ed592e1e2c0d5529c2e1 (diff)
i386: improve and correct inline asm memory constraints
Use "+m" rather than a combination of "=m" and "m" for improved clarity and consistency. This also fixes some inlines that incorrectly didn't tell the compiler that they read the old value at all, potentially causing the compiler to generate bogus code. It appear that all of those potential bugs were hidden by the use of extra "volatile" specifiers on the data structures in question, though. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-i386/rwsem.h')
-rw-r--r--include/asm-i386/rwsem.h35
1 files changed, 17 insertions, 18 deletions
diff --git a/include/asm-i386/rwsem.h b/include/asm-i386/rwsem.h
index 2f07601562e7..43113f5608eb 100644
--- a/include/asm-i386/rwsem.h
+++ b/include/asm-i386/rwsem.h
@@ -111,8 +111,8 @@ LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value
111 " jmp 1b\n" 111 " jmp 1b\n"
112 LOCK_SECTION_END 112 LOCK_SECTION_END
113 "# ending down_read\n\t" 113 "# ending down_read\n\t"
114 : "=m"(sem->count) 114 : "+m" (sem->count)
115 : "a"(sem), "m"(sem->count) 115 : "a" (sem)
116 : "memory", "cc"); 116 : "memory", "cc");
117} 117}
118 118
@@ -133,8 +133,8 @@ LOCK_PREFIX " cmpxchgl %2,%0\n\t"
133 " jnz 1b\n\t" 133 " jnz 1b\n\t"
134 "2:\n\t" 134 "2:\n\t"
135 "# ending __down_read_trylock\n\t" 135 "# ending __down_read_trylock\n\t"
136 : "+m"(sem->count), "=&a"(result), "=&r"(tmp) 136 : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
137 : "i"(RWSEM_ACTIVE_READ_BIAS) 137 : "i" (RWSEM_ACTIVE_READ_BIAS)
138 : "memory", "cc"); 138 : "memory", "cc");
139 return result>=0 ? 1 : 0; 139 return result>=0 ? 1 : 0;
140} 140}
@@ -161,8 +161,8 @@ LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the
161 " jmp 1b\n" 161 " jmp 1b\n"
162 LOCK_SECTION_END 162 LOCK_SECTION_END
163 "# ending down_write" 163 "# ending down_write"
164 : "=m"(sem->count), "=d"(tmp) 164 : "+m" (sem->count), "=d" (tmp)
165 : "a"(sem), "1"(tmp), "m"(sem->count) 165 : "a" (sem), "1" (tmp)
166 : "memory", "cc"); 166 : "memory", "cc");
167} 167}
168 168
@@ -205,8 +205,8 @@ LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old valu
205 " jmp 1b\n" 205 " jmp 1b\n"
206 LOCK_SECTION_END 206 LOCK_SECTION_END
207 "# ending __up_read\n" 207 "# ending __up_read\n"
208 : "=m"(sem->count), "=d"(tmp) 208 : "+m" (sem->count), "=d" (tmp)
209 : "a"(sem), "1"(tmp), "m"(sem->count) 209 : "a" (sem), "1" (tmp)
210 : "memory", "cc"); 210 : "memory", "cc");
211} 211}
212 212
@@ -231,8 +231,8 @@ LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 ->
231 " jmp 1b\n" 231 " jmp 1b\n"
232 LOCK_SECTION_END 232 LOCK_SECTION_END
233 "# ending __up_write\n" 233 "# ending __up_write\n"
234 : "=m"(sem->count) 234 : "+m" (sem->count)
235 : "a"(sem), "i"(-RWSEM_ACTIVE_WRITE_BIAS), "m"(sem->count) 235 : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
236 : "memory", "cc", "edx"); 236 : "memory", "cc", "edx");
237} 237}
238 238
@@ -256,8 +256,8 @@ LOCK_PREFIX " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001
256 " jmp 1b\n" 256 " jmp 1b\n"
257 LOCK_SECTION_END 257 LOCK_SECTION_END
258 "# ending __downgrade_write\n" 258 "# ending __downgrade_write\n"
259 : "=m"(sem->count) 259 : "+m" (sem->count)
260 : "a"(sem), "i"(-RWSEM_WAITING_BIAS), "m"(sem->count) 260 : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
261 : "memory", "cc"); 261 : "memory", "cc");
262} 262}
263 263
@@ -268,8 +268,8 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
268{ 268{
269 __asm__ __volatile__( 269 __asm__ __volatile__(
270LOCK_PREFIX "addl %1,%0" 270LOCK_PREFIX "addl %1,%0"
271 : "=m"(sem->count) 271 : "+m" (sem->count)
272 : "ir"(delta), "m"(sem->count)); 272 : "ir" (delta));
273} 273}
274 274
275/* 275/*
@@ -280,10 +280,9 @@ static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
280 int tmp = delta; 280 int tmp = delta;
281 281
282 __asm__ __volatile__( 282 __asm__ __volatile__(
283LOCK_PREFIX "xadd %0,(%2)" 283LOCK_PREFIX "xadd %0,%1"
284 : "+r"(tmp), "=m"(sem->count) 284 : "+r" (tmp), "+m" (sem->count)
285 : "r"(sem), "m"(sem->count) 285 : : "memory");
286 : "memory");
287 286
288 return tmp+delta; 287 return tmp+delta;
289} 288}