Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
7.3 KiB

4 years ago
  1. #++
  2. #
  3. # Copyright (c) 1993 by
  4. # Digital Equipment Corporation, Maynard, MA
  5. #
  6. # This software is furnished under a license and may be used and copied
  7. # only in accordance with the terms of such license and with the
  8. # inclusion of the above copyright notice. This software or any other
  9. # copies thereof may not be provided or otherwise made available to any
  10. # other person. No title to and ownership of the software is hereby
  11. # transferred.
  12. #
  13. # The information in this software is subject to change without notice
  14. # and should not be construed as a commitment by Digital Equipment
  15. # Corporation.
  16. #
  17. # Digital assumes no responsibility for the use or reliability of its
  18. # software on equipment which is not supplied by Digital.
  19. #
  20. # Facility:
  21. #
  22. # GEM/OTS - GEM compiler system support library
  23. #
  24. # Abstract:
  25. #
  26. # OTS character string support, Alpha version
  27. #
  28. # Authors:
  29. #
  30. # Bill Noyce
  31. #
  32. #
  33. # long ots_strcmp_eqls(char *str1, long strlen, char *str2);
  34. # compares two strings of the same length.
  35. # returns r0=1 if str1=str2, r0=0 otherwise.
  36. # long ots_strcmp_eql(char *str1, long str1len, char *str2, long str2len);
  37. # compares two strings of different lengths, without padding.
  38. # returns r0=1 if str1=str2, r0=0 otherwise.
  39. #
  40. # Special conventions: No stack space, r16-r21 and r27-r28 ONLY,
  41. # no linkage pointer required.
  42. # (Warning: The auto-loader potentially takes some regs across
  43. # the call if this is being used in a shared lib. environment.)
  44. #
  45. # Modification history:
  46. #
  47. # 005 27 Aug 1991 WBN Initial version, replacing BLISS -004
  48. #
  49. # 006 19 May 1992 KDG Changes for common VMS/OSF sources
  50. #
  51. # 007 22 Sep 1992 KDG Add case-sensitive name
  52. #
  53. # 008 26 Jan 1993 KDG Add underscore
  54. #--
  55. #include "ots_defs.hs"
  56. # r16 --> A
  57. # r17 = len
  58. # r18 --> B
  59. # returns r0=1 if equal, r0=0 if not equal
  60. # destroys r16-r21, r27-r28
  61. #.align octa
  62. .globl _OtsStringCompareEqlSameLen
  63. .ent _OtsStringCompareEqlSameLen
  64. _OtsStringCompareEqlSameLen:
  65. .set noat
  66. .set noreorder
  67. .frame sp,0,r26
  68. subq r17, 8, r19 # More than 8 bytes to compare?
  69. beq r17, equal # Done if empty strings
  70. join: ldq_u r20, (r16) # Get first QW containing part of A
  71. addq r18, r17, r27 # Point to end of B
  72. ldq_u r21, (r18) # Get first QW containing part of B
  73. bgt r19, big # Skip if more than 8 bytes
  74. ldq_u r27, -1(r27) # Get last QW containing part of B
  75. addq r16, r17, r28 # Point to end of A
  76. extql r20, r16, r20 # Get first part of A
  77. ldq_u r28, -1(r28) # Get last QW containing part of A
  78. extql r21, r18, r21 # Get first part of B
  79. extqh r27, r18, r27 # Get last part of B
  80. extqh r28, r16, r28 # Get last part of A
  81. or r21, r27, r27 # Combine B
  82. or r20, r28, r28 # Combine A
  83. xor r28, r27, r0 # Are they different?
  84. extqh r0, r19, r0 # Discard differences after length
  85. nop
  86. cmpeq r0, 0, r0 # Return 1 or 0 as xor=0 or not
  87. ret r31, (r26)
  88. equal: mov 1, r0 # Return true
  89. ret r31, (r26)
  90. # r16 --> A
  91. # r17 = A_len
  92. # r18 --> B
  93. # r19 = B_len
  94. # returns r0=1 if equal, r0=0 if not equal
  95. # destroys r16-r21, r27-r28
  96. #
  97. nop #.align octa
  98. nop
  99. .globl _OtsStringCompareEql
  100. .aent _OtsStringCompareEql
  101. _OtsStringCompareEql:
  102. .frame sp,0,r26
  103. cmpeq r17, r19, r0 # Are lengths equal?
  104. beq r17, done # If one is zero, no compares needed
  105. subq r17, 8, r19 # More than 8 bytes to compare?
  106. blbs r0, join # Only compare if lengths equal
  107. done: ret r31, (r26) # Return result of length comparison
  108. #.odd
  109. big: and r16, 7, r0 # A alignment, or amount not compared
  110. subq r18, r0, r18 # Back up B pointer that much
  111. and r18, 7, r17 # Is B now aligned?
  112. addq r19, r0, r19 # (Len-8+align) is amount left to do
  113. ldq_u r27, 8(r18) # Get next QW of B
  114. subq r19, 16, r19 # More than 2 QW's left?
  115. bne r17, unalign # Skip if B alignment doesn't match
  116. xor r20, r21, r0 # Compare first (partial) QW
  117. ldq_u r28, 8(r16) # Get next QW of A
  118. mskqh r0, r16, r0 # Discard junk preceding strings
  119. ble r19, bottom # Skip if two quadwords or less to go
  120. # stall
  121. loop: ldq_u r20, 16(r16) # Get yet another QW of A
  122. bne r0, not_eq # Done if difference in prior compare
  123. xor r28, r27, r0 # Compare prior QW's
  124. ldq r21, 16(r18) # Get yet another QW of B
  125. subq r19, 16, r19 # Decrement length
  126. bne r0, not_eq # Done if difference in this compare
  127. ldq r27, 24(r18) # Get next QW of B
  128. addq r18, 16, r18 # Increment pointer
  129. ldq_u r28, 24(r16) # Get next QW of A
  130. addq r16, 16, r16 # Increment pointer
  131. xor r20, r21, r0 # Compare QW's loaded at top of loop
  132. bgt r19, loop # Repeat until two or less QWs left
  133. bottom: addq r19, 8, r19 # More than 1 QW left?
  134. bne r0, not_eq # Done if difference in prior compare
  135. xor r28, r27, r0 # Compare QW's just loaded
  136. ble r19, last # Skip if this is last compare
  137. ldq_u r28, 16(r16) # Get last QW of A
  138. bne r0, not_eq # Done if difference in this compare
  139. ldq r27, 16(r18) # Get last QW of B
  140. #2 stalls
  141. xor r28, r27, r0 # Compare last QW's
  142. last: extqh r0, r19, r0 # Discard diffs after length
  143. nop
  144. cmpeq r0, 0, r0 # Return 1 or 0 as xor=0 or not
  145. ret r31, (r26)
  146. #.align quad
  147. unalign:
  148. extql r21, r18, r21 # Get first part of B
  149. extqh r27, r18, r0 # Get second part of B
  150. #stall
  151. or r0, r21, r21 # Combine pieces of B
  152. xor r20, r21, r0 # Compare with A
  153. mskqh r0, r16, r0 # Trim junk preceding strings
  154. blt r19, bott_u # Skip if fewer than 16 bytes left
  155. loop_u: ldq_u r21, 16(r18) # Get more B
  156. subq r19, 16, r19 # Decrement length
  157. extql r27, r18, r17 # Get piece of B from prior QW
  158. bne r0, not_eq # Done if r1.ne.r2
  159. ldq_u r27, 24(r18) # Get still more B
  160. addq r18, 16, r18 # Increment B pointer
  161. ldq_u r28, 8(r16) # Get more A
  162. extqh r21, r18, r0 # Get piece of B from first QW in loop
  163. ldq_u r20, 16(r16) # Get still more A
  164. extql r21, r18, r21 # Get second piece of B from there
  165. or r17, r0, r17 # Combine pieces for first B
  166. xor r28, r17, r0 # Compare with first A
  167. extqh r27, r18, r17 # Start building second B
  168. bne r0, not_eq # Done if r28.ne.r17
  169. addq r16, 16, r16 # Increment A pointer
  170. or r17, r21, r21 # Combine pieces for second B
  171. xor r20, r21, r0 # Compare with second A
  172. bge r19, loop_u # Repeat if at least 16 more bytes
  173. bott_u: and r19, 8, r17 # At least 8 more bytes?
  174. bne r0, not_eq # Done if r1.ne.r2
  175. and r19, 7, r19 # How many odd bytes?
  176. beq r17, last_u # Skip if not a whole QW
  177. extql r27, r18, r17 # Get a piece of B
  178. ldq_u r27, 16(r18) # Load another QW of B
  179. addq r18, 8, r18 # Increment B pointer
  180. ldq_u r28, 8(r16) # Load another QW of A
  181. addq r16, 8, r16 # Increment A pointer
  182. extqh r27, r18, r0 # Get a piece of new B QW
  183. #stall
  184. or r17, r0, r17 # Combine pieces
  185. xor r28, r17, r0 # Compare with A
  186. nop
  187. bne r0, not_eq # Done if r28.ne.r17
  188. last_u: addq r18, r19, r17 # Point to end of B
  189. beq r19, eql_u # Return true if no more bytes
  190. ldq_u r28, 8(r16) # Get last QW of A
  191. ldq_u r20, 7(r17) # Get QW containing end of B
  192. extql r27, r18, r27 # Get piece of prior B QW
  193. #stall
  194. extqh r20, r18, r0 # Get a piece of last B QW
  195. #stall
  196. or r27, r0, r27 # Combine
  197. xor r28, r27, r0 # Compare with A
  198. mskql r0, r19, r0 # Discard diffs after strings
  199. nop
  200. eql_u: cmpeq r0, 0, r0 # Return 1 or 0 as xor=0 or not
  201. ret r31, (r26)
  202. not_eq: clr r0 # Return false
  203. ret r31, (r26)
  204. .set at
  205. .set reorder
  206. .end _OtsStringCompareEqlSameLen