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 /* 43 * This routine doesn't need to be atomic, but it's faster to code it 44 * this way. 45 */ 46 extern__inline__inttest_bit(intnr, void * addr)
/* */ 47 { 48 intoldbit;
49
50 __asm____volatile__("btl %2,%1\n\tsbbl %0,%0"
51 :"=r" (oldbit)
52 :"m" (ADDR),"r" (nr));
53 returnoldbit;
54 } 55
56 #else 57 /* 58 * For the benefit of those who are trying to port Linux to another 59 * architecture, here are some C-language equivalents. You should 60 * recode these in the native assmebly language, if at all possible. 61 * To guarantee atomicity, these routines call cli() and sti() to 62 * disable interrupts while they operate. (You have to provide inline 63 * routines to cli() and sti().) 64 * 65 * Also note, these routines assume that you have 32 bit integers. 66 * You will have to change this if you are trying to port Linux to the 67 * Alpha architecture or to a Cray. :-) 68 * 69 * C language equivalents written by Theodore Ts'o, 9/26/92 70 */ 71
72 extern__inline__intset_bit(intnr,int * addr)
/* */ 73 { 74 intmask, retval;
75
76 addr += nr >> 5;
77 mask = 1 << (nr & 0x1f);
78 cli();
79 retval = (mask & *addr) != 0;
80 *addr |= mask;
81 sti();
82 returnretval;
83 } 84
85 extern__inline__intclear_bit(intnr, int * addr)
/* */ 86 { 87 intmask, retval;
88
89 addr += nr >> 5;
90 mask = 1 << (nr & 0x1f);
91 cli();
92 retval = (mask & *addr) != 0;
93 *addr &= ~mask;
94 sti();
95 returnretval;
96 } 97
98 extern__inline__inttest_bit(intnr, int * addr)
/* */ 99 { 100 intmask;
101
102 addr += nr >> 5;
103 mask = 1 << (nr & 0x1f);
104 return ((mask & *addr) != 0);
105 } 106 #endif/* i386 */ 107 #endif/* _ASM_BITOPS_H */