strcmp.S 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright (C) 2017 Hangzhou C-SKY Microsystems co.,ltd.
  3. *
  4. * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB
  5. * in this tarball.
  6. */
  7. #include <features.h>
  8. #include <endian.h>
  9. #ifdef WANT_WIDE
  10. # define Wstrcmp wcscmp
  11. # define Wstrcoll wcscoll
  12. #else
  13. # define Wstrcmp strcmp
  14. # define Wstrcoll strcoll
  15. #endif
  16. /* FIXME attention!!! it may be a bug when WANT_WIDE define */
  17. /*libc_hidden_proto(Wstrcmp)*/
  18. .align 2
  19. .global Wstrcmp
  20. .type Wstrcmp, @function
  21. Wstrcmp:
  22. mov r6, r2
  23. or r2, r3
  24. andi r2, 0x3
  25. cmpnei r2, 0x0 /* d or s is aligned ?*/
  26. bt 4f /* if not aligned, goto 4f*/
  27. 1: /* if aligned, load word each time.*/
  28. ldw r2, (r6, 0)
  29. ldw r7, (r3, 0)
  30. cmpne r2, r7
  31. bt 1f /* if d[i] != s[i], goto 1f */
  32. tstnbz r2 /* if d[i] == s[i], check if d or s is at the end. */
  33. bf 3f /* if at the end, goto 3f (finish comparing) */
  34. ldw r2, (r6, 4)
  35. ldw r7, (r3, 4)
  36. cmpne r2, r7
  37. bt 1f
  38. tstnbz r2
  39. bf 3f
  40. ldw r2, (r6, 8)
  41. ldw r7, (r3, 8)
  42. cmpne r2, r7
  43. bt 1f
  44. tstnbz r2
  45. bf 3f
  46. ldw r2, (r6, 12)
  47. ldw r7, (r3, 12)
  48. cmpne r2, r7
  49. bt 1f
  50. tstnbz r2
  51. bf 3f
  52. ldw r2, (r6, 16)
  53. ldw r7, (r3, 16)
  54. cmpne r2, r7
  55. bt 1f
  56. tstnbz r2
  57. bf 3f
  58. ldw r2, (r6, 20)
  59. ldw r7, (r3, 20)
  60. cmpne r2, r7
  61. bt 1f
  62. tstnbz r2
  63. bf 3f
  64. ldw r2, (r6, 24)
  65. ldw r7, (r3, 24)
  66. cmpne r2, r7
  67. bt 1f
  68. tstnbz r2
  69. bf 3f
  70. ldw r2, (r6, 28)
  71. ldw r7, (r3, 28)
  72. cmpne r2, r7
  73. bt 1f
  74. tstnbz r2
  75. bf 3f
  76. addi r6, 32
  77. addi r3, 32
  78. br 1b
  79. #ifdef __CSKYBE__
  80. /* d[i] != s[i] in word, so we check byte 0 ? */
  81. 1:
  82. xtrb0 r1, r2
  83. mov r4, r1
  84. xtrb0 r1, r7
  85. cmpne r4, r1
  86. bt 2f
  87. cmpnei r4, 0
  88. bf 2f
  89. /* d[i] != s[i] in word, so we check byte 1 ? */
  90. xtrb1 r1, r2
  91. mov r4, r1
  92. xtrb1 r1, r7
  93. cmpne r4, r1
  94. bt 2f
  95. cmpnei r4, 0
  96. bf 2f
  97. /* d[i] != s[i] in word, so we check byte 1 ? */
  98. xtrb2 r1, r2
  99. mov r4, r1
  100. xtrb2 r1, r7
  101. cmpne r4, r1
  102. bt 2f
  103. cmpnei r4, 0
  104. bf 2f
  105. /* d[i] != s[i] in word, so we check byte 1 ? */
  106. xtrb3 r1, r2
  107. mov r4, r1
  108. xtrb3 r1, r7
  109. #else /* little endian */
  110. /* d[i] != s[i] in word, so we check byte 0 ? */
  111. 1:
  112. xtrb3 r1, r2
  113. mov r4, r1
  114. xtrb3 r1, r7
  115. cmpne r4, r1
  116. bt 2f
  117. cmpnei r4, 0
  118. bf 2f
  119. /* d[i] != s[i] in word, so we check byte 1 ? */
  120. xtrb2 r1, r2
  121. mov r4, r1
  122. xtrb2 r1, r7
  123. cmpne r4, r1
  124. bt 2f
  125. cmpnei r4, 0
  126. bf 2f
  127. /* d[i] != s[i] in word, so we check byte 1 ? */
  128. xtrb1 r1, r2
  129. mov r4, r1
  130. xtrb1 r1, r7
  131. cmpne r4, r1
  132. bt 2f
  133. cmpnei r4, 0
  134. bf 2f
  135. /* d[i] != s[i] in word, so we check byte 1 ? */
  136. xtrb0 r1, r2
  137. mov r4, r1
  138. xtrb0 r1, r7
  139. #endif
  140. /* get the result when d[i] != s[i] */
  141. 2:
  142. subu r4, r1
  143. mov r2, r4
  144. jmp r15
  145. /* return when d[i] == s[i] */
  146. 3:
  147. subu r2, r7
  148. jmp r15
  149. /* cmp when d or s is not aligned */
  150. 4:
  151. ldb r2, (r6,0)
  152. ldb r7, (r3, 0)
  153. cmpne r2, r7
  154. bt 3b
  155. addi r3, 1
  156. addi r6, 1
  157. cmpnei r2, 0
  158. bt 4b
  159. jmp r15
  160. .size Wstrcmp, .-Wstrcmp
  161. libc_hidden_def(Wstrcmp)
  162. .weak Wstrcmp
  163. #ifndef __UCLIBC_HAS_LOCALE__
  164. /* libc_hidden_proto(Wstrcoll) */
  165. strong_alias(Wstrcmp,Wstrcoll)
  166. libc_hidden_def(Wstrcoll)
  167. #endif