strrchr.S 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* $OpenBSD: strrchr.S,v 1.3 2014/12/09 15:13:57 reyk Exp $ */
  2. /* $NetBSD: strrchr.S,v 1.3 2014/03/22 19:16:34 jakllsch Exp $ */
  3. /*
  4. * Written by J.T. Conklin <jtc@acorntoolworks.com>
  5. * Public domain.
  6. */
  7. #include <machine/asm.h>
  8. STRONG_ALIAS(rindex, strrchr)
  9. ENTRY(strrchr)
  10. movzbq %sil,%rcx
  11. /* zero return value */
  12. xorq %rax,%rax
  13. /*
  14. * Align to word boundary.
  15. * Consider unrolling loop?
  16. */
  17. .Lalign:
  18. testb $7,%dil
  19. je .Lword_aligned
  20. movb (%rdi),%dl
  21. cmpb %cl,%dl
  22. cmoveq %rdi,%rax
  23. incq %rdi
  24. testb %dl,%dl
  25. jne .Lalign
  26. jmp .Ldone
  27. .Lword_aligned:
  28. /* copy char to all bytes in word */
  29. movb %cl,%ch
  30. movq %rcx,%rdx
  31. salq $16,%rcx
  32. orq %rdx,%rcx
  33. movq %rcx,%rdx
  34. salq $32,%rcx
  35. orq %rdx,%rcx
  36. movabsq $0x0101010101010101,%r8
  37. movabsq $0x8080808080808080,%r9
  38. /* Check whether any byte in the word is equal to ch or 0. */
  39. _ALIGN_TEXT
  40. .Lloop:
  41. movq (%rdi),%rdx
  42. addq $8,%rdi
  43. movq %rdx,%rsi
  44. subq %r8,%rdx
  45. xorq %rcx,%rsi
  46. subq %r8,%rsi
  47. orq %rsi,%rdx
  48. testq %r9,%rdx
  49. je .Lloop
  50. /*
  51. * In rare cases, the above loop may exit prematurely. We must
  52. * return to the loop if none of the bytes in the word match
  53. * ch or are equal to 0.
  54. */
  55. movb -8(%rdi),%dl
  56. cmpb %cl,%dl /* 1st byte == ch? */
  57. jne 1f
  58. leaq -8(%rdi),%rax
  59. 1: testb %dl,%dl /* 1st byte == 0? */
  60. je .Ldone
  61. movb -7(%rdi),%dl
  62. cmpb %cl,%dl /* 2nd byte == ch? */
  63. jne 1f
  64. leaq -7(%rdi),%rax
  65. 1: testb %dl,%dl /* 2nd byte == 0? */
  66. je .Ldone
  67. movb -6(%rdi),%dl
  68. cmpb %cl,%dl /* 3rd byte == ch? */
  69. jne 1f
  70. leaq -6(%rdi),%rax
  71. 1: testb %dl,%dl /* 3rd byte == 0? */
  72. je .Ldone
  73. movb -5(%rdi),%dl
  74. cmpb %cl,%dl /* 4th byte == ch? */
  75. jne 1f
  76. leaq -5(%rdi),%rax
  77. 1: testb %dl,%dl /* 4th byte == 0? */
  78. je .Ldone
  79. movb -4(%rdi),%dl
  80. cmpb %cl,%dl /* 5th byte == ch? */
  81. jne 1f
  82. leaq -4(%rdi),%rax
  83. 1: testb %dl,%dl /* 5th byte == 0? */
  84. je .Ldone
  85. movb -3(%rdi),%dl
  86. cmpb %cl,%dl /* 6th byte == ch? */
  87. jne 1f
  88. leaq -3(%rdi),%rax
  89. 1: testb %dl,%dl /* 6th byte == 0? */
  90. je .Ldone
  91. movb -2(%rdi),%dl
  92. cmpb %cl,%dl /* 7th byte == ch? */
  93. jne 1f
  94. leaq -2(%rdi),%rax
  95. 1: testb %dl,%dl /* 7th byte == 0? */
  96. je .Ldone
  97. movb -1(%rdi),%dl
  98. cmpb %cl,%dl /* 8th byte == ch? */
  99. jne 1f
  100. leaq -1(%rdi),%rax
  101. 1: testb %dl,%dl /* 8th byte == 0? */
  102. jne .Lloop
  103. .Ldone:
  104. ret