1 #ifndef_ASM_BITOPS_H 2 #define_ASM_BITOPS_H 3 /* 4 * Copyright 1992, Linus Torvalds. 5 */ 6
7 #ifdefi386 8 /* 9 * These have to be done with inline assembly: that way the bit-setting 10 * is guaranteed to be atomic. All bitoperations return 0 if the bit 11 * was cleared before the operation and != 0 if it was not. 12 * 13 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). 14 */ 15
16 /* 17 * Some hacks to defeat gcc over-optimizations.. 18 */ 19 struct__dummy{unsignedlonga[100]; };
20 #defineADDR (*(struct__dummy *) addr)
21
22 extern__inline__intset_bit(intnr, void * addr)
/* */ 23 { 24 intoldbit;
25
26 __asm____volatile__("btsl %2,%1\n\tsbbl %0,%0"
27 :"=r" (oldbit),"=m" (ADDR)
28 :"r" (nr));
29 returnoldbit;
30 } 31
32 extern__inline__intclear_bit(intnr, void * addr)
/* */ 33 { 34 intoldbit;
35
36 __asm____volatile__("btrl %2,%1\n\tsbbl %0,%0"
37 :"=r" (oldbit),"=m" (ADDR)
38 :"r" (nr));
39 returnoldbit;
40 } 41
42 extern__inline__intchange_bit(intnr, void * addr)
/* */ 43 { 44 intoldbit;
45
46 __asm____volatile__("btcl %2,%1\n\tsbbl %0,%0"
47 :"=r" (oldbit),"=m" (ADDR)
48 :"r" (nr));
49 returnoldbit;
50 } 51
52 /* 53 * This routine doesn't need to be atomic, but it's faster to code it 54 * this way. 55 */ 56 extern__inline__inttest_bit(intnr, void * addr)
/* */ 57 { 58 intoldbit;
59
60 __asm____volatile__("btl %2,%1\n\tsbbl %0,%0"
61 :"=r" (oldbit)
62 :"m" (ADDR),"r" (nr));
63 returnoldbit;
64 } 65
66 #else 67 /* 68 * For the benefit of those who are trying to port Linux to another 69 * architecture, here are some C-language equivalents. You should 70 * recode these in the native assmebly language, if at all possible. 71 * To guarantee atomicity, these routines call cli() and sti() to 72 * disable interrupts while they operate. (You have to provide inline 73 * routines to cli() and sti().) 74 * 75 * Also note, these routines assume that you have 32 bit integers. 76 * You will have to change this if you are trying to port Linux to the 77 * Alpha architecture or to a Cray. :-) 78 * 79 * C language equivalents written by Theodore Ts'o, 9/26/92 80 */ 81
82 extern__inline__intset_bit(intnr,int * addr)
/* */ 83 { 84 intmask, retval;
85
86 addr += nr >> 5;
87 mask = 1 << (nr & 0x1f);
88 cli();
89 retval = (mask & *addr) != 0;
90 *addr |= mask;
91 sti();
92 returnretval;
93 } 94
95 extern__inline__intclear_bit(intnr, int * addr)
/* */ 96 { 97 intmask, retval;
98
99 addr += nr >> 5;
100 mask = 1 << (nr & 0x1f);
101 cli();
102 retval = (mask & *addr) != 0;
103 *addr &= ~mask;
104 sti();
105 returnretval;
106 } 107
108 extern__inline__inttest_bit(intnr, int * addr)
/* */ 109 { 110 intmask;
111
112 addr += nr >> 5;
113 mask = 1 << (nr & 0x1f);
114 return ((mask & *addr) != 0);
115 } 116 #endif/* i386 */ 117 #endif/* _ASM_BITOPS_H */