Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.12-rc4 120 lines 2.8 kB view raw
1#ifndef _ASM_WORD_AT_A_TIME_H 2#define _ASM_WORD_AT_A_TIME_H 3 4#include <linux/kernel.h> 5#include <asm/byteorder.h> 6 7#ifdef __BIG_ENDIAN 8 9struct word_at_a_time { 10 const unsigned long high_bits, low_bits; 11}; 12 13#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0xfe) + 1, REPEAT_BYTE(0x7f) } 14 15/* Bit set in the bytes that have a zero */ 16static inline long prep_zero_mask(unsigned long val, unsigned long rhs, const struct word_at_a_time *c) 17{ 18 unsigned long mask = (val & c->low_bits) + c->low_bits; 19 return ~(mask | rhs); 20} 21 22#define create_zero_mask(mask) (mask) 23 24static inline long find_zero(unsigned long mask) 25{ 26 long byte = 0; 27#ifdef CONFIG_64BIT 28 if (mask >> 32) 29 mask >>= 32; 30 else 31 byte = 4; 32#endif 33 if (mask >> 16) 34 mask >>= 16; 35 else 36 byte += 2; 37 return (mask >> 8) ? byte : byte + 1; 38} 39 40static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) 41{ 42 unsigned long rhs = val | c->low_bits; 43 *data = rhs; 44 return (val + c->high_bits) & ~rhs; 45} 46 47#ifndef zero_bytemask 48#define zero_bytemask(mask) (~1ul << __fls(mask)) 49#endif 50 51#else 52 53/* 54 * The optimal byte mask counting is probably going to be something 55 * that is architecture-specific. If you have a reliably fast 56 * bit count instruction, that might be better than the multiply 57 * and shift, for example. 58 */ 59struct word_at_a_time { 60 const unsigned long one_bits, high_bits; 61}; 62 63#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } 64 65#ifdef CONFIG_64BIT 66 67/* 68 * Jan Achrenius on G+: microoptimized version of 69 * the simpler "(mask & ONEBYTES) * ONEBYTES >> 56" 70 * that works for the bytemasks without having to 71 * mask them first. 72 */ 73static inline long count_masked_bytes(unsigned long mask) 74{ 75 return mask*0x0001020304050608ul >> 56; 76} 77 78#else /* 32-bit case */ 79 80/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ 81static inline long count_masked_bytes(long mask) 82{ 83 /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ 84 long a = (0x0ff0001+mask) >> 23; 85 /* Fix the 1 for 00 case */ 86 return a & mask; 87} 88 89#endif 90 91/* Return nonzero if it has a zero */ 92static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c) 93{ 94 unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits; 95 *bits = mask; 96 return mask; 97} 98 99static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c) 100{ 101 return bits; 102} 103 104static inline unsigned long create_zero_mask(unsigned long bits) 105{ 106 bits = (bits - 1) & ~bits; 107 return bits >> 7; 108} 109 110/* The mask we created is directly usable as a bytemask */ 111#define zero_bytemask(mask) (mask) 112 113static inline unsigned long find_zero(unsigned long mask) 114{ 115 return count_masked_bytes(mask); 116} 117 118#endif /* __BIG_ENDIAN */ 119 120#endif /* _ASM_WORD_AT_A_TIME_H */