1 #ifndef _ASM_WORD_AT_A_TIME_H 2 #define _ASM_WORD_AT_A_TIME_H 3 4 /* 5 * This says "generic", but it's actually big-endian only. 6 * Little-endian can use more efficient versions of these 7 * interfaces, see for example 8 * arch/x86/include/asm/word-at-a-time.h 9 * for those. 10 */ 11 12 #include <linux/kernel.h> 13 14 struct word_at_a_time { 15 const unsigned long high_bits, low_bits; 16 }; 17 18 #define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0xfe) + 1, REPEAT_BYTE(0x7f) } 19 20 /* Bit set in the bytes that have a zero */ 21 static inline long prep_zero_mask(unsigned long val, unsigned long rhs, const struct word_at_a_time *c) 22 { 23 unsigned long mask = (val & c->low_bits) + c->low_bits; 24 return ~(mask | rhs); 25 } 26 27 #define create_zero_mask(mask) (mask) 28 29 static inline long find_zero(unsigned long mask) 30 { 31 long byte = 0; 32 #ifdef CONFIG_64BIT 33 if (mask >> 32) 34 mask >>= 32; 35 else 36 byte = 4; 37 #endif 38 if (mask >> 16) 39 mask >>= 16; 40 else 41 byte += 2; 42 return (mask >> 8) ? byte : byte + 1; 43 } 44 45 static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) 46 { 47 unsigned long rhs = val | c->low_bits; 48 *data = rhs; 49 return (val + c->high_bits) & ~rhs; 50 } 51 52 #ifndef zero_bytemask 53 #define zero_bytemask(mask) (~1ul << __fls(mask)) 54 #endif 55 56 #endif /* _ASM_WORD_AT_A_TIME_H */ 57