1819833afSPeter Tyser #ifndef _MICROBLAZE_BITOPS_H 2819833afSPeter Tyser #define _MICROBLAZE_BITOPS_H 3819833afSPeter Tyser 4819833afSPeter Tyser /* 5819833afSPeter Tyser * Copyright 1992, Linus Torvalds. 6819833afSPeter Tyser */ 7819833afSPeter Tyser 8819833afSPeter Tyser #include <asm/byteorder.h> /* swab32 */ 9819833afSPeter Tyser #include <asm/system.h> /* save_flags */ 10*e6e7b7c0SFabio Estevam #include <asm-generic/bitops/fls.h> 11*e6e7b7c0SFabio Estevam #include <asm-generic/bitops/__fls.h> 12*e6e7b7c0SFabio Estevam #include <asm-generic/bitops/fls64.h> 13*e6e7b7c0SFabio Estevam #include <asm-generic/bitops/__ffs.h> 14819833afSPeter Tyser 15819833afSPeter Tyser #ifdef __KERNEL__ 16819833afSPeter Tyser /* 17819833afSPeter Tyser * Function prototypes to keep gcc -Wall happy 18819833afSPeter Tyser */ 19819833afSPeter Tyser 20819833afSPeter Tyser /* 21819833afSPeter Tyser * The __ functions are not atomic 22819833afSPeter Tyser */ 23819833afSPeter Tyser 24819833afSPeter Tyser extern void set_bit(int nr, volatile void * addr); 25819833afSPeter Tyser extern void __set_bit(int nr, volatile void * addr); 26819833afSPeter Tyser 27819833afSPeter Tyser extern void clear_bit(int nr, volatile void * addr); 28819833afSPeter Tyser #define __clear_bit(nr, addr) clear_bit(nr, addr) 29819833afSPeter Tyser #define PLATFORM__CLEAR_BIT 30819833afSPeter Tyser 31819833afSPeter Tyser extern void change_bit(int nr, volatile void * addr); 32819833afSPeter Tyser extern void __change_bit(int nr, volatile void * addr); 33819833afSPeter Tyser extern int test_and_set_bit(int nr, volatile void * addr); 34819833afSPeter Tyser extern int __test_and_set_bit(int nr, volatile void * addr); 35819833afSPeter Tyser extern int test_and_clear_bit(int nr, volatile void * addr); 36819833afSPeter Tyser extern int __test_and_clear_bit(int nr, volatile void * addr); 37819833afSPeter Tyser extern int test_and_change_bit(int nr, volatile void * addr); 38819833afSPeter Tyser extern int __test_and_change_bit(int nr, volatile void * addr); 39819833afSPeter Tyser extern int __constant_test_bit(int nr, const volatile void * addr); 40819833afSPeter Tyser extern int __test_bit(int nr, volatile void * addr); 41819833afSPeter Tyser extern int find_first_zero_bit(void * addr, unsigned size); 42819833afSPeter Tyser extern int find_next_zero_bit (void * addr, int size, int offset); 43819833afSPeter Tyser 44819833afSPeter Tyser /* 45819833afSPeter Tyser * ffz = Find First Zero in word. Undefined if no zero exists, 46819833afSPeter Tyser * so code should check against ~0UL first.. 47819833afSPeter Tyser */ 48819833afSPeter Tyser extern __inline__ unsigned long ffz(unsigned long word) 49819833afSPeter Tyser { 50819833afSPeter Tyser unsigned long result = 0; 51819833afSPeter Tyser 52819833afSPeter Tyser while(word & 1) { 53819833afSPeter Tyser result++; 54819833afSPeter Tyser word >>= 1; 55819833afSPeter Tyser } 56819833afSPeter Tyser return result; 57819833afSPeter Tyser } 58819833afSPeter Tyser 59819833afSPeter Tyser 60819833afSPeter Tyser extern __inline__ void set_bit(int nr, volatile void * addr) 61819833afSPeter Tyser { 62819833afSPeter Tyser int * a = (int *) addr; 63819833afSPeter Tyser int mask; 64819833afSPeter Tyser unsigned long flags; 65819833afSPeter Tyser 66819833afSPeter Tyser a += nr >> 5; 67819833afSPeter Tyser mask = 1 << (nr & 0x1f); 68819833afSPeter Tyser save_flags_cli(flags); 69819833afSPeter Tyser *a |= mask; 70819833afSPeter Tyser restore_flags(flags); 71819833afSPeter Tyser } 72819833afSPeter Tyser 73819833afSPeter Tyser extern __inline__ void __set_bit(int nr, volatile void * addr) 74819833afSPeter Tyser { 75819833afSPeter Tyser int * a = (int *) addr; 76819833afSPeter Tyser int mask; 77819833afSPeter Tyser 78819833afSPeter Tyser a += nr >> 5; 79819833afSPeter Tyser mask = 1 << (nr & 0x1f); 80819833afSPeter Tyser *a |= mask; 81819833afSPeter Tyser } 82819833afSPeter Tyser #define PLATFORM__SET_BIT 83819833afSPeter Tyser 84819833afSPeter Tyser /* 85819833afSPeter Tyser * clear_bit() doesn't provide any barrier for the compiler. 86819833afSPeter Tyser */ 87819833afSPeter Tyser #define smp_mb__before_clear_bit() barrier() 88819833afSPeter Tyser #define smp_mb__after_clear_bit() barrier() 89819833afSPeter Tyser 90819833afSPeter Tyser extern __inline__ void clear_bit(int nr, volatile void * addr) 91819833afSPeter Tyser { 92819833afSPeter Tyser int * a = (int *) addr; 93819833afSPeter Tyser int mask; 94819833afSPeter Tyser unsigned long flags; 95819833afSPeter Tyser 96819833afSPeter Tyser a += nr >> 5; 97819833afSPeter Tyser mask = 1 << (nr & 0x1f); 98819833afSPeter Tyser save_flags_cli(flags); 99819833afSPeter Tyser *a &= ~mask; 100819833afSPeter Tyser restore_flags(flags); 101819833afSPeter Tyser } 102819833afSPeter Tyser 103819833afSPeter Tyser extern __inline__ void change_bit(int nr, volatile void * addr) 104819833afSPeter Tyser { 105819833afSPeter Tyser int mask; 106819833afSPeter Tyser unsigned long flags; 107819833afSPeter Tyser unsigned long *ADDR = (unsigned long *) addr; 108819833afSPeter Tyser 109819833afSPeter Tyser ADDR += nr >> 5; 110819833afSPeter Tyser mask = 1 << (nr & 31); 111819833afSPeter Tyser save_flags_cli(flags); 112819833afSPeter Tyser *ADDR ^= mask; 113819833afSPeter Tyser restore_flags(flags); 114819833afSPeter Tyser } 115819833afSPeter Tyser 116819833afSPeter Tyser extern __inline__ void __change_bit(int nr, volatile void * addr) 117819833afSPeter Tyser { 118819833afSPeter Tyser int mask; 119819833afSPeter Tyser unsigned long *ADDR = (unsigned long *) addr; 120819833afSPeter Tyser 121819833afSPeter Tyser ADDR += nr >> 5; 122819833afSPeter Tyser mask = 1 << (nr & 31); 123819833afSPeter Tyser *ADDR ^= mask; 124819833afSPeter Tyser } 125819833afSPeter Tyser 126819833afSPeter Tyser extern __inline__ int test_and_set_bit(int nr, volatile void * addr) 127819833afSPeter Tyser { 128819833afSPeter Tyser int mask, retval; 129819833afSPeter Tyser volatile unsigned int *a = (volatile unsigned int *) addr; 130819833afSPeter Tyser unsigned long flags; 131819833afSPeter Tyser 132819833afSPeter Tyser a += nr >> 5; 133819833afSPeter Tyser mask = 1 << (nr & 0x1f); 134819833afSPeter Tyser save_flags_cli(flags); 135819833afSPeter Tyser retval = (mask & *a) != 0; 136819833afSPeter Tyser *a |= mask; 137819833afSPeter Tyser restore_flags(flags); 138819833afSPeter Tyser 139819833afSPeter Tyser return retval; 140819833afSPeter Tyser } 141819833afSPeter Tyser 142819833afSPeter Tyser extern __inline__ int __test_and_set_bit(int nr, volatile void * addr) 143819833afSPeter Tyser { 144819833afSPeter Tyser int mask, retval; 145819833afSPeter Tyser volatile unsigned int *a = (volatile unsigned int *) addr; 146819833afSPeter Tyser 147819833afSPeter Tyser a += nr >> 5; 148819833afSPeter Tyser mask = 1 << (nr & 0x1f); 149819833afSPeter Tyser retval = (mask & *a) != 0; 150819833afSPeter Tyser *a |= mask; 151819833afSPeter Tyser return retval; 152819833afSPeter Tyser } 153819833afSPeter Tyser 154819833afSPeter Tyser extern __inline__ int test_and_clear_bit(int nr, volatile void * addr) 155819833afSPeter Tyser { 156819833afSPeter Tyser int mask, retval; 157819833afSPeter Tyser volatile unsigned int *a = (volatile unsigned int *) addr; 158819833afSPeter Tyser unsigned long flags; 159819833afSPeter Tyser 160819833afSPeter Tyser a += nr >> 5; 161819833afSPeter Tyser mask = 1 << (nr & 0x1f); 162819833afSPeter Tyser save_flags_cli(flags); 163819833afSPeter Tyser retval = (mask & *a) != 0; 164819833afSPeter Tyser *a &= ~mask; 165819833afSPeter Tyser restore_flags(flags); 166819833afSPeter Tyser 167819833afSPeter Tyser return retval; 168819833afSPeter Tyser } 169819833afSPeter Tyser 170819833afSPeter Tyser extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr) 171819833afSPeter Tyser { 172819833afSPeter Tyser int mask, retval; 173819833afSPeter Tyser volatile unsigned int *a = (volatile unsigned int *) addr; 174819833afSPeter Tyser 175819833afSPeter Tyser a += nr >> 5; 176819833afSPeter Tyser mask = 1 << (nr & 0x1f); 177819833afSPeter Tyser retval = (mask & *a) != 0; 178819833afSPeter Tyser *a &= ~mask; 179819833afSPeter Tyser return retval; 180819833afSPeter Tyser } 181819833afSPeter Tyser 182819833afSPeter Tyser extern __inline__ int test_and_change_bit(int nr, volatile void * addr) 183819833afSPeter Tyser { 184819833afSPeter Tyser int mask, retval; 185819833afSPeter Tyser volatile unsigned int *a = (volatile unsigned int *) addr; 186819833afSPeter Tyser unsigned long flags; 187819833afSPeter Tyser 188819833afSPeter Tyser a += nr >> 5; 189819833afSPeter Tyser mask = 1 << (nr & 0x1f); 190819833afSPeter Tyser save_flags_cli(flags); 191819833afSPeter Tyser retval = (mask & *a) != 0; 192819833afSPeter Tyser *a ^= mask; 193819833afSPeter Tyser restore_flags(flags); 194819833afSPeter Tyser 195819833afSPeter Tyser return retval; 196819833afSPeter Tyser } 197819833afSPeter Tyser 198819833afSPeter Tyser extern __inline__ int __test_and_change_bit(int nr, volatile void * addr) 199819833afSPeter Tyser { 200819833afSPeter Tyser int mask, retval; 201819833afSPeter Tyser volatile unsigned int *a = (volatile unsigned int *) addr; 202819833afSPeter Tyser 203819833afSPeter Tyser a += nr >> 5; 204819833afSPeter Tyser mask = 1 << (nr & 0x1f); 205819833afSPeter Tyser retval = (mask & *a) != 0; 206819833afSPeter Tyser *a ^= mask; 207819833afSPeter Tyser return retval; 208819833afSPeter Tyser } 209819833afSPeter Tyser 210819833afSPeter Tyser /* 211819833afSPeter Tyser * This routine doesn't need to be atomic. 212819833afSPeter Tyser */ 213819833afSPeter Tyser extern __inline__ int __constant_test_bit(int nr, const volatile void * addr) 214819833afSPeter Tyser { 215819833afSPeter Tyser return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; 216819833afSPeter Tyser } 217819833afSPeter Tyser 218819833afSPeter Tyser extern __inline__ int __test_bit(int nr, volatile void * addr) 219819833afSPeter Tyser { 220819833afSPeter Tyser int * a = (int *) addr; 221819833afSPeter Tyser int mask; 222819833afSPeter Tyser 223819833afSPeter Tyser a += nr >> 5; 224819833afSPeter Tyser mask = 1 << (nr & 0x1f); 225819833afSPeter Tyser return ((mask & *a) != 0); 226819833afSPeter Tyser } 227819833afSPeter Tyser 228819833afSPeter Tyser #define test_bit(nr,addr) \ 229819833afSPeter Tyser (__builtin_constant_p(nr) ? \ 230819833afSPeter Tyser __constant_test_bit((nr),(addr)) : \ 231819833afSPeter Tyser __test_bit((nr),(addr))) 232819833afSPeter Tyser 233819833afSPeter Tyser #define find_first_zero_bit(addr, size) \ 234819833afSPeter Tyser find_next_zero_bit((addr), (size), 0) 235819833afSPeter Tyser 236819833afSPeter Tyser extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) 237819833afSPeter Tyser { 238819833afSPeter Tyser unsigned long *p = ((unsigned long *) addr) + (offset >> 5); 239819833afSPeter Tyser unsigned long result = offset & ~31UL; 240819833afSPeter Tyser unsigned long tmp; 241819833afSPeter Tyser 242819833afSPeter Tyser if (offset >= size) 243819833afSPeter Tyser return size; 244819833afSPeter Tyser size -= result; 245819833afSPeter Tyser offset &= 31UL; 246819833afSPeter Tyser if (offset) { 247819833afSPeter Tyser tmp = *(p++); 248819833afSPeter Tyser tmp |= ~0UL >> (32-offset); 249819833afSPeter Tyser if (size < 32) 250819833afSPeter Tyser goto found_first; 251819833afSPeter Tyser if (~tmp) 252819833afSPeter Tyser goto found_middle; 253819833afSPeter Tyser size -= 32; 254819833afSPeter Tyser result += 32; 255819833afSPeter Tyser } 256819833afSPeter Tyser while (size & ~31UL) { 257819833afSPeter Tyser if (~(tmp = *(p++))) 258819833afSPeter Tyser goto found_middle; 259819833afSPeter Tyser result += 32; 260819833afSPeter Tyser size -= 32; 261819833afSPeter Tyser } 262819833afSPeter Tyser if (!size) 263819833afSPeter Tyser return result; 264819833afSPeter Tyser tmp = *p; 265819833afSPeter Tyser 266819833afSPeter Tyser found_first: 267819833afSPeter Tyser tmp |= ~0UL >> size; 268819833afSPeter Tyser found_middle: 269819833afSPeter Tyser return result + ffz(tmp); 270819833afSPeter Tyser } 271819833afSPeter Tyser 272819833afSPeter Tyser /* 273819833afSPeter Tyser * hweightN: returns the hamming weight (i.e. the number 274819833afSPeter Tyser * of bits set) of a N-bit word 275819833afSPeter Tyser */ 276819833afSPeter Tyser 277819833afSPeter Tyser #define hweight32(x) generic_hweight32(x) 278819833afSPeter Tyser #define hweight16(x) generic_hweight16(x) 279819833afSPeter Tyser #define hweight8(x) generic_hweight8(x) 280819833afSPeter Tyser 281819833afSPeter Tyser 282819833afSPeter Tyser extern __inline__ int ext2_set_bit(int nr, volatile void * addr) 283819833afSPeter Tyser { 284819833afSPeter Tyser int mask, retval; 285819833afSPeter Tyser unsigned long flags; 286819833afSPeter Tyser volatile unsigned char *ADDR = (unsigned char *) addr; 287819833afSPeter Tyser 288819833afSPeter Tyser ADDR += nr >> 3; 289819833afSPeter Tyser mask = 1 << (nr & 0x07); 290819833afSPeter Tyser save_flags_cli(flags); 291819833afSPeter Tyser retval = (mask & *ADDR) != 0; 292819833afSPeter Tyser *ADDR |= mask; 293819833afSPeter Tyser restore_flags(flags); 294819833afSPeter Tyser return retval; 295819833afSPeter Tyser } 296819833afSPeter Tyser 297819833afSPeter Tyser extern __inline__ int ext2_clear_bit(int nr, volatile void * addr) 298819833afSPeter Tyser { 299819833afSPeter Tyser int mask, retval; 300819833afSPeter Tyser unsigned long flags; 301819833afSPeter Tyser volatile unsigned char *ADDR = (unsigned char *) addr; 302819833afSPeter Tyser 303819833afSPeter Tyser ADDR += nr >> 3; 304819833afSPeter Tyser mask = 1 << (nr & 0x07); 305819833afSPeter Tyser save_flags_cli(flags); 306819833afSPeter Tyser retval = (mask & *ADDR) != 0; 307819833afSPeter Tyser *ADDR &= ~mask; 308819833afSPeter Tyser restore_flags(flags); 309819833afSPeter Tyser return retval; 310819833afSPeter Tyser } 311819833afSPeter Tyser 312819833afSPeter Tyser extern __inline__ int ext2_test_bit(int nr, const volatile void * addr) 313819833afSPeter Tyser { 314819833afSPeter Tyser int mask; 315819833afSPeter Tyser const volatile unsigned char *ADDR = (const unsigned char *) addr; 316819833afSPeter Tyser 317819833afSPeter Tyser ADDR += nr >> 3; 318819833afSPeter Tyser mask = 1 << (nr & 0x07); 319819833afSPeter Tyser return ((mask & *ADDR) != 0); 320819833afSPeter Tyser } 321819833afSPeter Tyser 322819833afSPeter Tyser #define ext2_find_first_zero_bit(addr, size) \ 323819833afSPeter Tyser ext2_find_next_zero_bit((addr), (size), 0) 324819833afSPeter Tyser 325548ce4bfSMichal Simek static inline unsigned long ext2_find_next_zero_bit(void *addr, 326548ce4bfSMichal Simek unsigned long size, unsigned long offset) 327819833afSPeter Tyser { 328819833afSPeter Tyser unsigned long *p = ((unsigned long *) addr) + (offset >> 5); 329819833afSPeter Tyser unsigned long result = offset & ~31UL; 330819833afSPeter Tyser unsigned long tmp; 331819833afSPeter Tyser 332819833afSPeter Tyser if (offset >= size) 333819833afSPeter Tyser return size; 334819833afSPeter Tyser size -= result; 335819833afSPeter Tyser offset &= 31UL; 336819833afSPeter Tyser if(offset) { 337819833afSPeter Tyser /* We hold the little endian value in tmp, but then the 338819833afSPeter Tyser * shift is illegal. So we could keep a big endian value 339819833afSPeter Tyser * in tmp, like this: 340819833afSPeter Tyser * 341819833afSPeter Tyser * tmp = __swab32(*(p++)); 342819833afSPeter Tyser * tmp |= ~0UL >> (32-offset); 343819833afSPeter Tyser * 344819833afSPeter Tyser * but this would decrease preformance, so we change the 345819833afSPeter Tyser * shift: 346819833afSPeter Tyser */ 347819833afSPeter Tyser tmp = *(p++); 348819833afSPeter Tyser tmp |= __swab32(~0UL >> (32-offset)); 349819833afSPeter Tyser if(size < 32) 350819833afSPeter Tyser goto found_first; 351819833afSPeter Tyser if(~tmp) 352819833afSPeter Tyser goto found_middle; 353819833afSPeter Tyser size -= 32; 354819833afSPeter Tyser result += 32; 355819833afSPeter Tyser } 356819833afSPeter Tyser while(size & ~31UL) { 357819833afSPeter Tyser if(~(tmp = *(p++))) 358819833afSPeter Tyser goto found_middle; 359819833afSPeter Tyser result += 32; 360819833afSPeter Tyser size -= 32; 361819833afSPeter Tyser } 362819833afSPeter Tyser if(!size) 363819833afSPeter Tyser return result; 364819833afSPeter Tyser tmp = *p; 365819833afSPeter Tyser 366819833afSPeter Tyser found_first: 367819833afSPeter Tyser /* tmp is little endian, so we would have to swab the shift, 368819833afSPeter Tyser * see above. But then we have to swab tmp below for ffz, so 369819833afSPeter Tyser * we might as well do this here. 370819833afSPeter Tyser */ 371819833afSPeter Tyser return result + ffz(__swab32(tmp) | (~0UL << size)); 372819833afSPeter Tyser found_middle: 373819833afSPeter Tyser return result + ffz(__swab32(tmp)); 374819833afSPeter Tyser } 375819833afSPeter Tyser 376819833afSPeter Tyser /* Bitmap functions for the minix filesystem. */ 377819833afSPeter Tyser #define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr) 378819833afSPeter Tyser #define minix_set_bit(nr,addr) set_bit(nr,addr) 379819833afSPeter Tyser #define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr) 380819833afSPeter Tyser #define minix_test_bit(nr,addr) test_bit(nr,addr) 381819833afSPeter Tyser #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) 382819833afSPeter Tyser 383819833afSPeter Tyser /** 384819833afSPeter Tyser * hweightN - returns the hamming weight of a N-bit word 385819833afSPeter Tyser * @x: the word to weigh 386819833afSPeter Tyser * 387819833afSPeter Tyser * The Hamming Weight of a number is the total number of bits set in it. 388819833afSPeter Tyser */ 389819833afSPeter Tyser 390819833afSPeter Tyser #define hweight32(x) generic_hweight32(x) 391819833afSPeter Tyser #define hweight16(x) generic_hweight16(x) 392819833afSPeter Tyser #define hweight8(x) generic_hweight8(x) 393819833afSPeter Tyser 394819833afSPeter Tyser #endif /* __KERNEL__ */ 395819833afSPeter Tyser 396819833afSPeter Tyser #endif /* _MICROBLAZE_BITOPS_H */ 397