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 formatis :
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" );
122133return (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-
157166return (int )ret ;
158167}
159168
@@ -173,46 +182,18 @@ tas(volatile slock_t *lock)
173182registerslock_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" );
179189return (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 unsignedint 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- "la1,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 unsignedint 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- "la1,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- registerslock_t _res = 1 ;
229+ registerslock_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" );
259236return (int )_res ;
260237}
261238
@@ -283,11 +260,11 @@ tas(volatile slock_t *lock)
283260int _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"b3f\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" );
303279return _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" );
337312return rv ;
338313}
339314
@@ -357,13 +332,13 @@ tas(volatile slock_t *lock)
357332registerint _res ;
358333
359334__asm__ __volatile__(
360- "movl $1,r0 \n"
361- "bbssi$0, (%1 ), 1f\n"
362- "clrlr0 \n"
363- "1:movlr0, %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 " );
367342return _res ;
368343}
369344
@@ -383,9 +358,11 @@ tas(volatile slock_t *lock)
383358registerint _res ;
384359
385360__asm__ __volatile__(
386- "sbitb0, %0\n"
387- "sfsd%1\n"
388- :"=m" (* lock ),"=r" (_res ));
361+ "sbitb0, %1\n"
362+ "sfsd%0\n"
363+ :"=r" (_res ),"+m" (* lock )
364+ :
365+ :"memory" );
389366return _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{
417388registerslock_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"mov1, $0\n"
425- "stq_c$0, %0 \n"
396+ "stq_c$0, %1 \n"
426397"beq$0, 2f\n"
427398"mb\n"
428399"br3f\n"
429- "2:mov1, %1 \n"
400+ "2:mov1, %0 \n"
430401"3:\n"
431- :"=m" ( * lock ),"=r" ( _res )
402+ :"=&r" ( _res ),"+m" ( * lock )
432403:
433- :"0" );
434-
404+ :"memory" ,"0" );
435405return (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"ldcwx0(0,%2),%0\n"
543- :"=r" (lockval ),"=m" (* lockword )
544- :"r" (lockword ));
520+ :"=r" (lockval ),"+m" (* lockword )
521+ :"r" (lockword )
522+ :"memory" );
545523return (lockval == 0 );
546524}
547525