6666 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
6767 * Portions Copyright (c) 1994, Regents of the University of California
6868 *
69- * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.125 2004/01/03 05:47:44 tgl Exp $
69+ * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.126 2004/06/19 23:02:32 tgl Exp $
7070 *
7171 *-------------------------------------------------------------------------
7272 */
8585 * Other compilers use __cpu or __cpu__ so we test for both in those cases.
8686 */
8787
88- /*
89- * Standard gcc asm format is :
90- *
88+ /*----------
89+ * Standard gcc asm format (assuming "volatile slock_t *lock") :
90+
9191 __asm__ __volatile__(
92- " command \n"
93- " command \n"
94- " command \n"
95- : "=r"(_res) return value, in register
96- : "r"(lock) argument, 'lock pointer', in register
97- : "r0"); inline code uses this register
92+ " instruction \n"
93+ " instruction \n"
94+ " instruction \n"
95+ : "=r"(_res), "+m"(*lock) // return register, in/out lock value
96+ : "r"(lock) // lock pointer, in input register
97+ : "memory", "cc"); // show clobbered registers here
98+
99+ * The output-operands list (after first colon) should always include
100+ * "+m"(*lock), whether or not the asm code actually refers to this
101+ * operand directly. This ensures that gcc believes the value in the
102+ * lock variable is used and set by the asm code. Also, the clobbers
103+ * list (after third colon) should always include "memory"; this prevents
104+ * gcc from thinking it can cache the values of shared-memory fields
105+ * across the asm code. Add "cc" if your asm code changes the condition
106+ * code register, and also list any temp registers the code uses.
107+ *----------
98108 */
99109
100110
@@ -117,8 +127,9 @@ tas(volatile slock_t *lock)
117127 " lock \n"
118128 " xchgb %0,%1 \n"
119129 "1: \n"
120- : "=q" (_res ), "=m" (* lock )
121- : "0" (_res ));
130+ : "+q" (_res ), "+m" (* lock )
131+ :
132+ : "memory" , "cc" );
122133 return (int ) _res ;
123134}
124135
@@ -128,8 +139,7 @@ static __inline__ void
128139spin_delay (void )
129140{
130141 __asm__ __volatile__(
131- " rep; nop \n"
132- : : : "memory" );
142+ " rep; nop \n" );
133143}
134144
135145#endif /* __i386__ || __x86_64__ */
@@ -150,10 +160,9 @@ tas(volatile slock_t *lock)
150160
151161 __asm__ __volatile__(
152162 " xchg4 %0=%1,%2 \n"
153- : "=r" (ret ), "= m" (* lock )
154- : "r" (1 ), "1" ( * lock )
163+ : "=r" (ret ), "+ m" (* lock )
164+ : "r" (1 )
155165: "memory" );
156-
157166 return (int ) ret ;
158167}
159168
@@ -173,46 +182,18 @@ tas(volatile slock_t *lock)
173182 register slock_t _res = 1 ;
174183
175184 __asm__ __volatile__(
176- " swpb %0, %0, [%3] \n"
177- : "=r" (_res ), "=m" (* lock )
178- : "0" (_res ), "r" (lock ));
185+ " swpb %0, %0, [%2] \n"
186+ : "+r" (_res ), "+m" (* lock )
187+ : "r" (lock )
188+ : "memory" );
179189 return (int ) _res ;
180190}
181191
182192#endif /* __arm__ */
183193
184194
185- #if defined(__s390__ ) && !defined(__s390x__ )
186- /* S/390 Linux */
187- #define HAS_TEST_AND_SET
188-
189- typedef unsigned int slock_t ;
190-
191- #define TAS (lock ) tas(lock)
192-
193- static __inline__ int
194- tas (volatile slock_t * lock )
195- {
196- int _res ;
197-
198- __asm__ __volatile__(
199- " la 1,1 \n"
200- " l 2,%2 \n"
201- " slr 0,0 \n"
202- " cs 0,1,0(2) \n"
203- " lr %1,0 \n"
204- : "=m" (lock ), "=d" (_res )
205- : "m" (lock )
206- : "0" , "1" , "2" );
207-
208- return (_res );
209- }
210-
211- #endif /* __s390__ */
212-
213-
214- #if defined(__s390x__ )
215- /* S/390x Linux (64-bit zSeries) */
195+ #if defined(__s390__ ) || defined(__s390x__ )
196+ /* S/390 and S/390x Linux (32- and 64-bit zSeries) */
216197#define HAS_TEST_AND_SET
217198
218199typedef unsigned int slock_t ;
@@ -222,22 +203,17 @@ typedef unsigned int slock_t;
222203static __inline__ int
223204tas (volatile slock_t * lock )
224205{
225- int _res ;
206+ int _res = 0 ;
226207
227208 __asm__ __volatile__(
228- " la 1,1 \n"
229- " lg 2,%2 \n"
230- " slr 0,0 \n"
231- " cs 0,1,0(2) \n"
232- " lr %1,0 \n"
233- : "=m" (lock ), "=d" (_res )
234- : "m" (lock )
235- : "0" , "1" , "2" );
236-
237- return (_res );
209+ " cs %0,%3,0(%2) \n"
210+ : "+d" (_res ), "+m" (* lock )
211+ : "a" (lock ), "d" (1 )
212+ : "memory" , "cc" );
213+ return _res ;
238214}
239215
240- #endif /* __s390x__ */
216+ #endif /* __s390__ || __s390x__ */
241217
242218
243219#if defined(__sparc__ )
@@ -250,12 +226,13 @@ typedef unsigned char slock_t;
250226static __inline__ int
251227tas (volatile slock_t * lock )
252228{
253- register slock_t _res = 1 ;
229+ register slock_t _res ;
254230
255231 __asm__ __volatile__(
256232 " ldstub [%2], %0 \n"
257- : "=r" (_res ), "=m" (* lock )
258- : "r" (lock ));
233+ : "=r" (_res ), "+m" (* lock )
234+ : "r" (lock )
235+ : "memory" );
259236 return (int ) _res ;
260237}
261238
@@ -283,11 +260,11 @@ tas(volatile slock_t *lock)
283260 int _res ;
284261
285262 __asm__ __volatile__(
286- " lwarx %0,0,%2 \n"
263+ " lwarx %0,0,%3 \n"
287264" cmpwi %0,0 \n"
288265" bne 1f \n"
289266" addi %0,%0,1 \n"
290- " stwcx. %0,0,%2 \n"
267+ " stwcx. %0,0,%3 \n"
291268" beq 2f \n"
292269"1: li %1,1 \n"
293270" b 3f \n"
@@ -296,10 +273,9 @@ tas(volatile slock_t *lock)
296273" li %1,0 \n"
297274"3: \n"
298275
299- : "=&r" (_t ), "=r" (_res )
300- : "r" (lock )
301- : "cc" , "memory"
302- );
276+ : "=&r" (_t ), "=r" (_res ), "+m" (* lock )
277+ : "r" (lock )
278+ : "memory" , "cc" );
303279 return _res ;
304280}
305281
@@ -330,10 +306,9 @@ tas(volatile slock_t *lock)
330306 " clrl %0 \n"
331307 " tas %1 \n"
332308 " sne %0 \n"
333- : "=d" (rv ), "=m" (* lock )
334- : "1" (* lock )
335- : "cc" );
336-
309+ : "=d" (rv ), "+m" (* lock )
310+ :
311+ : "memory" , "cc" );
337312 return rv ;
338313}
339314
@@ -357,13 +332,13 @@ tas(volatile slock_t *lock)
357332 register int _res ;
358333
359334 __asm__ __volatile__(
360- " movl $1, r0 \n"
361- " bbssi $0, (%1 ), 1f \n"
362- " clrl r0 \n"
363- "1: movl r0, %0 \n"
364- : "=r" (_res )
335+ " movl $1, %0 \n"
336+ " bbssi $0, (%2 ), 1f \n"
337+ " clrl %0 \n"
338+ "1: \n"
339+ : "=& r" (_res ), "+m" ( * lock )
365340: "r" (lock )
366- : "r0 " );
341+ : "memory " );
367342 return _res ;
368343}
369344
@@ -383,9 +358,11 @@ tas(volatile slock_t *lock)
383358 register int _res ;
384359
385360 __asm__ __volatile__(
386- " sbitb 0, %0 \n"
387- " sfsd %1 \n"
388- : "=m" (* lock ), "=r" (_res ));
361+ " sbitb 0, %1 \n"
362+ " sfsd %0 \n"
363+ : "=r" (_res ), "+m" (* lock )
364+ :
365+ : "memory" );
389366 return _res ;
390367}
391368
@@ -404,37 +381,37 @@ tas(volatile slock_t *lock)
404381typedef unsigned long slock_t ;
405382
406383#define TAS (lock ) tas(lock)
407- #define S_UNLOCK (lock ) \
408- do \
409- {\
410- __asm__ __volatile__ (" mb \n"); \
411- *((volatile slock_t *) (lock)) = 0; \
412- } while (0)
413384
414385static __inline__ int
415386tas (volatile slock_t * lock )
416387{
417388 register slock_t _res ;
418389
419390 __asm__ __volatile__(
420- " ldq $0, %0 \n"
391+ " ldq $0, %1 \n"
421392 " bne $0, 2f \n"
422- " ldq_l %1 , %0 \n"
423- " bne %1 , 2f \n"
393+ " ldq_l %0 , %1 \n"
394+ " bne %0 , 2f \n"
424395 " mov 1, $0 \n"
425- " stq_c $0, %0 \n"
396+ " stq_c $0, %1 \n"
426397 " beq $0, 2f \n"
427398 " mb \n"
428399 " br 3f \n"
429- "2: mov 1, %1 \n"
400+ "2: mov 1, %0 \n"
430401 "3: \n"
431- : "=m" ( * lock ), "=r" ( _res )
402+ : "=&r" ( _res ), "+m" ( * lock )
432403:
433- : "0" );
434-
404+ : "memory" , "0" );
435405 return (int ) _res ;
436406}
437407
408+ #define S_UNLOCK (lock ) \
409+ do \
410+ {\
411+ __asm__ __volatile__ (" mb \n"); \
412+ *((volatile slock_t *) (lock)) = 0; \
413+ } while (0)
414+
438415#endif /* __alpha || __alpha__ */
439416
440417
@@ -540,8 +517,9 @@ tas(volatile slock_t *lock)
540517
541518 __asm__ __volatile__(
542519 " ldcwx 0(0,%2),%0 \n"
543- : "=r" (lockval ), "=m" (* lockword )
544- : "r" (lockword ));
520+ : "=r" (lockval ), "+m" (* lockword )
521+ : "r" (lockword )
522+ : "memory" );
545523 return (lockval == 0 );
546524}
547525
0 commit comments