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
15 /* 16 * Some hacks to defeat gcc over-optimizations.. 17 */ 18 struct__dummy{unsignedlonga[100]; };
19 #defineADDR (*(struct__dummy *) addr)
20
21 externinlineintset_bit(intnr, void * addr)
/* */ 22 { 23 unsignedcharok;
24
25 __asm____volatile__("btsl %2,%1\n\tsetb %0"
26 :"=q" (ok),"=m" (ADDR)
27 :"r" (nr));
28 returnok;
29 } 30
31 externinlineintclear_bit(intnr, void * addr)
/* */ 32 { 33 unsignedcharok;
34
35 __asm____volatile__("btrl %2,%1\n\tsetnb %0"
36 :"=q" (ok),"=m" (ADDR)
37 :"r" (nr));
38 returnok;
39 } 40
41 /* 42 * This routine doesn't need to be atomic, but it's faster to code it 43 * this way. 44 */ 45 externinlineinttest_bit(intnr, void * addr)
/* */ 46 { 47 unsignedcharok;
48
49 __asm____volatile__("btl %2,%1\n\tsetb %0"
50 :"=q" (ok)
51 :"m" (ADDR),"r" (nr));
52 returnok;
53 } 54
55 #else 56 /* 57 * For the benefit of those who are trying to port Linux to another 58 * architecture, here are some C-language equivalents. You should 59 * recode these in the native assmebly language, if at all possible. 60 * To guarantee atomicity, these routines call cli() and sti() to 61 * disable interrupts while they operate. (You have to provide inline 62 * routines to cli() and sti().) 63 * 64 * Also note, these routines assume that you have 32 bit integers. 65 * You will have to change this if you are trying to port Linux to the 66 * Alpha architecture or to a Cray. :-) 67 * 68 * C language equivalents written by Theodore Ts'o, 9/26/92 69 */ 70
71 externinlineintset_bit(intnr,int * addr)
/* */ 72 { 73 intmask, retval;
74
75 addr += nr >> 5;
76 mask = 1 << (nr & 0x1f);
77 cli();
78 retval = (mask & *addr) != 0;
79 *addr |= mask;
80 sti();
81 returnretval;
82 } 83
84 externinlineintclear_bit(intnr, int * addr)
/* */ 85 { 86 intmask, retval;
87
88 addr += nr >> 5;
89 mask = 1 << (nr & 0x1f);
90 cli();
91 retval = (mask & *addr) == 0;
92 *addr &= ~mask;
93 sti();
94 returnretval;
95 } 96
97 externinlineinttest_bit(intnr, int * addr)
/* */ 98 { 99 intmask;
100
101 addr += nr >> 5;
102 mask = 1 << (nr & 0x1f);
103 return ((mask & *addr) != 0);
104 } 105 #endif/* i386 */ 106 #endif/* _ASM_BITOPS_H */