memchr.S 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2021 Arm Ltd.
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/assembler.h>
  7. /*
  8. * Find a character in an area of memory.
  9. *
  10. * Parameters:
  11. * x0 - buf
  12. * x1 - c
  13. * x2 - n
  14. * Returns:
  15. * x0 - address of first occurrence of 'c' or 0
  16. */
  17. #define L(label) .L ## label
  18. #define REP8_01 0x0101010101010101
  19. #define REP8_7f 0x7f7f7f7f7f7f7f7f
  20. #define srcin x0
  21. #define chrin w1
  22. #define cntin x2
  23. #define result x0
  24. #define wordcnt x3
  25. #define rep01 x4
  26. #define repchr x5
  27. #define cur_word x6
  28. #define cur_byte w6
  29. #define tmp x7
  30. #define tmp2 x8
  31. .p2align 4
  32. nop
  33. SYM_FUNC_START(__pi_memchr)
  34. and chrin, chrin, #0xff
  35. lsr wordcnt, cntin, #3
  36. cbz wordcnt, L(byte_loop)
  37. mov rep01, #REP8_01
  38. mul repchr, x1, rep01
  39. and cntin, cntin, #7
  40. L(word_loop):
  41. ldr cur_word, [srcin], #8
  42. sub wordcnt, wordcnt, #1
  43. eor cur_word, cur_word, repchr
  44. sub tmp, cur_word, rep01
  45. orr tmp2, cur_word, #REP8_7f
  46. bics tmp, tmp, tmp2
  47. b.ne L(found_word)
  48. cbnz wordcnt, L(word_loop)
  49. L(byte_loop):
  50. cbz cntin, L(not_found)
  51. ldrb cur_byte, [srcin], #1
  52. sub cntin, cntin, #1
  53. cmp cur_byte, chrin
  54. b.ne L(byte_loop)
  55. sub srcin, srcin, #1
  56. ret
  57. L(found_word):
  58. CPU_LE( rev tmp, tmp)
  59. clz tmp, tmp
  60. sub tmp, tmp, #64
  61. add result, srcin, tmp, asr #3
  62. ret
  63. L(not_found):
  64. mov result, #0
  65. ret
  66. SYM_FUNC_END(__pi_memchr)
  67. SYM_FUNC_ALIAS_WEAK(memchr, __pi_memchr)
  68. EXPORT_SYMBOL_NOKASAN(memchr)