word-at-a-time.h 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_WORD_AT_A_TIME_H
  3. #define _ASM_WORD_AT_A_TIME_H
  4. #include <linux/kernel.h>
  5. /*
  6. * This is largely generic for little-endian machines, but the
  7. * optimal byte mask counting is probably going to be something
  8. * that is architecture-specific. If you have a reliably fast
  9. * bit count instruction, that might be better than the multiply
  10. * and shift, for example.
  11. */
  12. struct word_at_a_time {
  13. const unsigned long one_bits, high_bits;
  14. };
  15. #define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
  16. #ifdef CONFIG_64BIT
  17. /*
  18. * Jan Achrenius on G+: microoptimized version of
  19. * the simpler "(mask & ONEBYTES) * ONEBYTES >> 56"
  20. * that works for the bytemasks without having to
  21. * mask them first.
  22. */
  23. static inline long count_masked_bytes(unsigned long mask)
  24. {
  25. return mask*0x0001020304050608ul >> 56;
  26. }
  27. #else /* 32-bit case */
  28. /* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
  29. static inline long count_masked_bytes(long mask)
  30. {
  31. /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
  32. long a = (0x0ff0001+mask) >> 23;
  33. /* Fix the 1 for 00 case */
  34. return a & mask;
  35. }
  36. #endif
  37. /* Return nonzero if it has a zero */
  38. static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
  39. {
  40. unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
  41. *bits = mask;
  42. return mask;
  43. }
  44. static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
  45. {
  46. return bits;
  47. }
  48. static inline unsigned long create_zero_mask(unsigned long bits)
  49. {
  50. bits = (bits - 1) & ~bits;
  51. return bits >> 7;
  52. }
  53. /* The mask we created is directly usable as a bytemask */
  54. #define zero_bytemask(mask) (mask)
  55. static inline unsigned long find_zero(unsigned long mask)
  56. {
  57. return count_masked_bytes(mask);
  58. }
  59. /*
  60. * Load an unaligned word from kernel space.
  61. *
  62. * In the (very unlikely) case of the word being a page-crosser
  63. * and the next page not being mapped, take the exception and
  64. * return zeroes in the non-existing part.
  65. */
  66. static inline unsigned long load_unaligned_zeropad(const void *addr)
  67. {
  68. unsigned long ret;
  69. asm volatile(
  70. "1: mov %[mem], %[ret]\n"
  71. "2:\n"
  72. _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_ZEROPAD)
  73. : [ret] "=r" (ret)
  74. : [mem] "m" (*(unsigned long *)addr));
  75. return ret;
  76. }
  77. #endif /* _ASM_WORD_AT_A_TIME_H */