Commit | Line | Data |
---|---|---|
36126f8f LT |
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 | #endif /* _ASM_WORD_AT_A_TIME_H */ |