abiv2_strcmp.S 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 <endian.h>
  8. #include "macro.S"
  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 a3, a0
  23. or a0, a1
  24. andi a0, 0x3
  25. M_BNEZ a0, 4f
  26. 1: // if aligned, load word each time.
  27. ldw a0, (a3, 0)
  28. ldw t0, (a1, 0)
  29. M_BNE a0, t0, 1f // if d[i] != s[i], goto 1f
  30. tstnbz a0 // if d[i] == s[i], check if d or s is at the end.
  31. bf 3f // if at the end, goto 3f (finish comparing)
  32. ldw a0, (a3, 4)
  33. ldw t0, (a1, 4)
  34. M_BNE a0, t0, 1f
  35. tstnbz a0
  36. bf 3f
  37. ldw a0, (a3, 8)
  38. ldw t0, (a1, 8)
  39. M_BNE a0, t0, 1f
  40. tstnbz a0
  41. bf 3f
  42. ldw a0, (a3, 12)
  43. ldw t0, (a1, 12)
  44. M_BNE a0, t0, 1f
  45. tstnbz a0
  46. bf 3f
  47. ldw a0, (a3, 16)
  48. ldw t0, (a1, 16)
  49. M_BNE a0, t0, 1f
  50. tstnbz a0
  51. bf 3f
  52. ldw a0, (a3, 20)
  53. ldw t0, (a1, 20)
  54. M_BNE a0, t0, 1f
  55. tstnbz a0
  56. bf 3f
  57. ldw a0, (a3, 24)
  58. ldw t0, (a1, 24)
  59. M_BNE a0, t0, 1f
  60. tstnbz a0
  61. bf 3f
  62. ldw a0, (a3, 28)
  63. ldw t0, (a1, 28)
  64. M_BNE a0, t0, 1f
  65. tstnbz a0
  66. bf 3f
  67. addi a3, 32
  68. addi a1, 32
  69. br 1b
  70. #ifdef __CSKYBE__
  71. /* d[i] != s[i] in word, so we check byte 0 ? */
  72. 1:
  73. xtrb0 t1, a0
  74. mov a2, t1
  75. xtrb0 t1, t0
  76. M_BNE a2, t1, 2f
  77. cmpnei a2, 0
  78. bf 2f
  79. /* d[i] != s[i] in word, so we check byte 1 ? */
  80. xtrb1 t1, a0
  81. mov a2, t1
  82. xtrb1 t1, t0
  83. M_BNE a2, t1, 2f
  84. cmpnei a2, 0
  85. bf 2f
  86. /* d[i] != s[i] in word, so we check byte 1 ? */
  87. xtrb2 t1, a0
  88. mov a2, t1
  89. xtrb2 t1, t0
  90. M_BNE a2, t1, 2f
  91. cmpnei a2, 0
  92. bf 2f
  93. /* d[i] != s[i] in word, so we check byte 1 ? */
  94. xtrb3 t1, a0
  95. mov a2, t1
  96. xtrb3 t1, t0
  97. #else /* little endian */
  98. /* d[i] != s[i] in word, so we check byte 0 ? */
  99. 1:
  100. xtrb3 t1, a0
  101. mov a2, t1
  102. xtrb3 t1, t0
  103. M_BNE a2, t1, 2f
  104. cmpnei a2, 0
  105. bf 2f
  106. /* d[i] != s[i] in word, so we check byte 1 ? */
  107. xtrb2 t1, a0
  108. mov a2, t1
  109. xtrb2 t1, t0
  110. M_BNE a2, t1, 2f
  111. cmpnei a2, 0
  112. bf 2f
  113. /* d[i] != s[i] in word, so we check byte 1 ? */
  114. xtrb1 t1, a0
  115. mov a2, t1
  116. xtrb1 t1, t0
  117. M_BNE a2, t1, 2f
  118. cmpnei a2, 0
  119. bf 2f
  120. /* d[i] != s[i] in word, so we check byte 1 ? */
  121. xtrb0 t1, a0
  122. mov a2, t1
  123. xtrb0 t1, t0
  124. #endif
  125. /* get the result when d[i] != s[i] */
  126. 2:
  127. subu a2, t1
  128. mov a0, a2
  129. jmp r15
  130. /* return when d[i] == s[i] */
  131. 3:
  132. subu a0, t0
  133. jmp r15
  134. /* cmp when d or s is not aligned */
  135. 4:
  136. ldb a0, (a3,0)
  137. ldb t0, (a1, 0)
  138. M_BNE a0, t0, 3b
  139. addi a1, 1
  140. addi a3, 1
  141. M_BNEZ a0, 4b
  142. jmp r15
  143. .size Wstrcmp, .-Wstrcmp
  144. libc_hidden_def(Wstrcmp)
  145. .weak Wstrcmp
  146. #ifndef __UCLIBC_HAS_LOCALE__
  147. /* libc_hidden_proto(Wstrcoll) */
  148. strong_alias(Wstrcmp,Wstrcoll)
  149. libc_hidden_def(Wstrcoll)
  150. #endif