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 14struct 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 */ 21static 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 29static 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 45static 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