Chris Metcalf | 5bf6c07 | 2015-04-30 15:12:42 -0400 | [diff] [blame] | 1 | #ifndef _ASM_WORD_AT_A_TIME_H |
| 2 | #define _ASM_WORD_AT_A_TIME_H |
| 3 | |
| 4 | #include <asm/byteorder.h> |
| 5 | |
| 6 | struct word_at_a_time { /* unused */ }; |
| 7 | #define WORD_AT_A_TIME_CONSTANTS {} |
| 8 | |
Chris Metcalf | c753bf3 | 2015-10-06 14:20:45 -0400 | [diff] [blame^] | 9 | /* Generate 0x01 byte values for zero bytes using a SIMD instruction. */ |
Chris Metcalf | 5bf6c07 | 2015-04-30 15:12:42 -0400 | [diff] [blame] | 10 | static inline unsigned long has_zero(unsigned long val, unsigned long *data, |
| 11 | const struct word_at_a_time *c) |
| 12 | { |
| 13 | #ifdef __tilegx__ |
| 14 | unsigned long mask = __insn_v1cmpeqi(val, 0); |
| 15 | #else /* tilepro */ |
| 16 | unsigned long mask = __insn_seqib(val, 0); |
| 17 | #endif |
| 18 | *data = mask; |
| 19 | return mask; |
| 20 | } |
| 21 | |
| 22 | /* These operations are both nops. */ |
| 23 | #define prep_zero_mask(val, data, c) (data) |
| 24 | #define create_zero_mask(data) (data) |
| 25 | |
| 26 | /* And this operation just depends on endianness. */ |
| 27 | static inline long find_zero(unsigned long mask) |
| 28 | { |
| 29 | #ifdef __BIG_ENDIAN |
| 30 | return __builtin_clzl(mask) >> 3; |
| 31 | #else |
| 32 | return __builtin_ctzl(mask) >> 3; |
| 33 | #endif |
| 34 | } |
| 35 | |
Chris Metcalf | c753bf3 | 2015-10-06 14:20:45 -0400 | [diff] [blame^] | 36 | #ifdef __BIG_ENDIAN |
| 37 | #define zero_bytemask(mask) (~1ul << (63 - __builtin_clzl(mask))) |
| 38 | #else |
| 39 | #define zero_bytemask(mask) ((2ul << __builtin_ctzl(mask)) - 1) |
| 40 | #endif |
| 41 | |
Chris Metcalf | 5bf6c07 | 2015-04-30 15:12:42 -0400 | [diff] [blame] | 42 | #endif /* _ASM_WORD_AT_A_TIME_H */ |