1/* include/asm-i386/rwlock.h
2 *
3 *	Helpers used by both rw spinlocks and rw semaphores.
4 *
5 *	Based in part on code from semaphore.h and
6 *	spinlock.h Copyright 1996 Linus Torvalds.
7 *
8 *	Copyright 1999 Red Hat, Inc.
9 *
10 *	Written by Benjamin LaHaise.
11 *
12 *	This program is free software; you can redistribute it and/or
13 *	modify it under the terms of the GNU General Public License
14 *	as published by the Free Software Foundation; either version
15 *	2 of the License, or (at your option) any later version.
16 */
17#ifndef _ASM_I386_RWLOCK_H
18#define _ASM_I386_RWLOCK_H
19
20#define RW_LOCK_BIAS		 0x01000000
21#define RW_LOCK_BIAS_STR	"0x01000000"
22
23#define __build_read_lock_ptr(rw, helper)   \
24	asm volatile(LOCK "subl $1,(%0)\n\t" \
25		     "js 2f\n" \
26		     "1:\n" \
27		     LOCK_SECTION_START("") \
28		     "2:\tcall " helper "\n\t" \
29		     "jmp 1b\n" \
30		     LOCK_SECTION_END \
31		     ::"a" (rw) : "memory")
32
33#define __build_read_lock_const(rw, helper)   \
34	asm volatile(LOCK "subl $1,%0\n\t" \
35		     "js 2f\n" \
36		     "1:\n" \
37		     LOCK_SECTION_START("") \
38		     "2:\tpushl %%eax\n\t" \
39		     "leal %0,%%eax\n\t" \
40		     "call " helper "\n\t" \
41		     "popl %%eax\n\t" \
42		     "jmp 1b\n" \
43		     LOCK_SECTION_END \
44		     :"=m" (*(volatile int *)rw) : : "memory")
45
46#define __build_read_lock(rw, helper)	do { \
47						if (__builtin_constant_p(rw)) \
48							__build_read_lock_const(rw, helper); \
49						else \
50							__build_read_lock_ptr(rw, helper); \
51					} while (0)
52
53#define __build_write_lock_ptr(rw, helper) \
54	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
55		     "jnz 2f\n" \
56		     "1:\n" \
57		     LOCK_SECTION_START("") \
58		     "2:\tcall " helper "\n\t" \
59		     "jmp 1b\n" \
60		     LOCK_SECTION_END \
61		     ::"a" (rw) : "memory")
62
63#define __build_write_lock_const(rw, helper) \
64	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
65		     "jnz 2f\n" \
66		     "1:\n" \
67		     LOCK_SECTION_START("") \
68		     "2:\tpushl %%eax\n\t" \
69		     "leal %0,%%eax\n\t" \
70		     "call " helper "\n\t" \
71		     "popl %%eax\n\t" \
72		     "jmp 1b\n" \
73		     LOCK_SECTION_END \
74		     :"=m" (*(volatile int *)rw) : : "memory")
75
76#define __build_write_lock(rw, helper)	do { \
77						if (__builtin_constant_p(rw)) \
78							__build_write_lock_const(rw, helper); \
79						else \
80							__build_write_lock_ptr(rw, helper); \
81					} while (0)
82
83#endif
84