memcmp.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3. #include <linux/linkage.h>
  4. #include "sysdep.h"
  5. ENTRY(memcmp)
  6. /* Test if len less than 4 bytes. */
  7. mov r3, r0
  8. movi r0, 0
  9. mov r12, r4
  10. cmplti r2, 4
  11. bt .L_compare_by_byte
  12. andi r13, r0, 3
  13. movi r19, 4
  14. /* Test if s1 is not 4 bytes aligned. */
  15. bnez r13, .L_s1_not_aligned
  16. LABLE_ALIGN
  17. .L_s1_aligned:
  18. /* If dest is aligned, then copy. */
  19. zext r18, r2, 31, 4
  20. /* Test if len less than 16 bytes. */
  21. bez r18, .L_compare_by_word
  22. .L_compare_by_4word:
  23. /* If aligned, load word each time. */
  24. ldw r20, (r3, 0)
  25. ldw r21, (r1, 0)
  26. /* If s1[i] != s2[i], goto .L_byte_check. */
  27. cmpne r20, r21
  28. bt .L_byte_check
  29. ldw r20, (r3, 4)
  30. ldw r21, (r1, 4)
  31. cmpne r20, r21
  32. bt .L_byte_check
  33. ldw r20, (r3, 8)
  34. ldw r21, (r1, 8)
  35. cmpne r20, r21
  36. bt .L_byte_check
  37. ldw r20, (r3, 12)
  38. ldw r21, (r1, 12)
  39. cmpne r20, r21
  40. bt .L_byte_check
  41. PRE_BNEZAD (r18)
  42. addi a3, 16
  43. addi a1, 16
  44. BNEZAD (r18, .L_compare_by_4word)
  45. .L_compare_by_word:
  46. zext r18, r2, 3, 2
  47. bez r18, .L_compare_by_byte
  48. .L_compare_by_word_loop:
  49. ldw r20, (r3, 0)
  50. ldw r21, (r1, 0)
  51. addi r3, 4
  52. PRE_BNEZAD (r18)
  53. cmpne r20, r21
  54. addi r1, 4
  55. bt .L_byte_check
  56. BNEZAD (r18, .L_compare_by_word_loop)
  57. .L_compare_by_byte:
  58. zext r18, r2, 1, 0
  59. bez r18, .L_return
  60. .L_compare_by_byte_loop:
  61. ldb r0, (r3, 0)
  62. ldb r4, (r1, 0)
  63. addi r3, 1
  64. subu r0, r4
  65. PRE_BNEZAD (r18)
  66. addi r1, 1
  67. bnez r0, .L_return
  68. BNEZAD (r18, .L_compare_by_byte_loop)
  69. .L_return:
  70. mov r4, r12
  71. rts
  72. # ifdef __CSKYBE__
  73. /* d[i] != s[i] in word, so we check byte 0. */
  74. .L_byte_check:
  75. xtrb0 r0, r20
  76. xtrb0 r2, r21
  77. subu r0, r2
  78. bnez r0, .L_return
  79. /* check byte 1 */
  80. xtrb1 r0, r20
  81. xtrb1 r2, r21
  82. subu r0, r2
  83. bnez r0, .L_return
  84. /* check byte 2 */
  85. xtrb2 r0, r20
  86. xtrb2 r2, r21
  87. subu r0, r2
  88. bnez r0, .L_return
  89. /* check byte 3 */
  90. xtrb3 r0, r20
  91. xtrb3 r2, r21
  92. subu r0, r2
  93. # else
  94. /* s1[i] != s2[i] in word, so we check byte 3. */
  95. .L_byte_check:
  96. xtrb3 r0, r20
  97. xtrb3 r2, r21
  98. subu r0, r2
  99. bnez r0, .L_return
  100. /* check byte 2 */
  101. xtrb2 r0, r20
  102. xtrb2 r2, r21
  103. subu r0, r2
  104. bnez r0, .L_return
  105. /* check byte 1 */
  106. xtrb1 r0, r20
  107. xtrb1 r2, r21
  108. subu r0, r2
  109. bnez r0, .L_return
  110. /* check byte 0 */
  111. xtrb0 r0, r20
  112. xtrb0 r2, r21
  113. subu r0, r2
  114. br .L_return
  115. # endif /* !__CSKYBE__ */
  116. /* Compare when s1 is not aligned. */
  117. .L_s1_not_aligned:
  118. sub r13, r19, r13
  119. sub r2, r13
  120. .L_s1_not_aligned_loop:
  121. ldb r0, (r3, 0)
  122. ldb r4, (r1, 0)
  123. addi r3, 1
  124. subu r0, r4
  125. PRE_BNEZAD (r13)
  126. addi r1, 1
  127. bnez r0, .L_return
  128. BNEZAD (r13, .L_s1_not_aligned_loop)
  129. br .L_s1_aligned
  130. ENDPROC(memcmp)