1 #ifndef _ASM_BITOPS_H
2 /*
3 * Copyright 1992, Linus Torvalds.
4 */
5
6 #ifdef i386
7 /*
8 * These have to be done with inline assembly: that way the bit-setting
9 * is guaranteed to be atomic. Both set_bit and clear_bit return 0
10 * if the bit-setting went ok, != 0 if the bit already was set/cleared.
11 *
12 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
13 */
14 extern inline int set_bit(int nr,int * addr)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
15 {
16 char ok;
17
18 __asm__ __volatile__("btsl %1,%2\n\tsetb %0":
19 "=q" (ok):"r" (nr),"m" (*(addr)));
20 return ok;
21 }
22
23 extern inline int clear_bit(int nr, int * addr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
24 {
25 char ok;
26
27 __asm__ __volatile__("btrl %1,%2\n\tsetnb %0":
28 "=q" (ok):"r" (nr),"m" (*(addr)));
29 return ok;
30 }
31
32 /*
33 * This routine doesn't need to be atomic, but it's faster to code it
34 * this way.
35 */
36 extern inline int test_bit(int nr, int * addr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
37 {
38 char ok;
39
40 __asm__ __volatile__("btl %1,%2\n\tsetb %0":
41 "=q" (ok):"r" (nr),"m" (*(addr)));
42 return ok;
43 }
44
45 #else
46 /*
47 * For the benefit of those who are trying to port Linux to another
48 * architecture, here are some C-language equivalents. You should
49 * recode these in the native assmebly language, if at all possible.
50 * To guarantee atomicity, these routines call cli() and sti() to
51 * disable interrupts while they operate. (You have to provide inline
52 * routines to cli() and sti().)
53 *
54 * Also note, these routines assume that you have 32 bit integers.
55 * You will have to change this if you are trying to port Linux to the
56 * Alpha architecture or to a Cray. :-)
57 *
58 * C language equivalents written by Theodore Ts'o, 9/26/92
59 */
60
61 extern inline int set_bit(int nr,int * addr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
62 {
63 int mask, retval;
64
65 addr += nr >> 5;
66 mask = 1 << (nr & 0x1f);
67 cli();
68 retval = (mask & *addr) != 0;
69 *addr |= mask;
70 sti();
71 return retval;
72 }
73
74 extern inline int clear_bit(int nr, int * addr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
75 {
76 int mask, retval;
77
78 addr += nr >> 5;
79 mask = 1 << (nr & 0x1f);
80 cli();
81 retval = (mask & *addr) == 0;
82 *addr &= ~mask;
83 sti();
84 return retval;
85 }
86
87 extern inline int test_bit(int nr, int * addr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
88 {
89 int mask;
90
91 addr += nr >> 5;
92 mask = 1 << (nr & 0x1f);
93 return ((mask & *addr) != 0);
94 }
95 #endif /* i386 */
96 #endif /* _ASM_BITOPS_H */