popham.asm
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:4k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K6-2 mpn_popcount, mpn_hamdist -- mpn bit population count and
  2. dnl  hamming distance.
  3. dnl  Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
  4. dnl
  5. dnl  This file is part of the GNU MP Library.
  6. dnl
  7. dnl  The GNU MP Library is free software; you can redistribute it and/or
  8. dnl  modify it under the terms of the GNU Lesser General Public License as
  9. dnl  published by the Free Software Foundation; either version 3 of the
  10. dnl  License, or (at your option) any later version.
  11. dnl
  12. dnl  The GNU MP Library is distributed in the hope that it will be useful,
  13. dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. dnl  Lesser General Public License for more details.
  16. dnl
  17. dnl  You should have received a copy of the GNU Lesser General Public License
  18. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  19. include(`../config.m4')
  20. C        popcount  hamdist
  21. C K6-2:    9.0       11.5   cycles/limb
  22. C K6:      12.5      13.0
  23. C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
  24. C unsigned long mpn_hamdist (mp_srcptr src, mp_srcptr src2, mp_size_t size);
  25. C
  26. C The code here isn't optimal, but it's already a 2x speedup over the plain
  27. C integer mpn/generic/popcount.c,hamdist.c.
  28. ifdef(`OPERATION_popcount',,
  29. `ifdef(`OPERATION_hamdist',,
  30. `m4_error(`Need OPERATION_popcount or OPERATION_hamdist
  31. ')m4exit(1)')')
  32. define(HAM,
  33. m4_assert_numargs(1)
  34. `ifdef(`OPERATION_hamdist',`$1')')
  35. define(POP,
  36. m4_assert_numargs(1)
  37. `ifdef(`OPERATION_popcount',`$1')')
  38. HAM(`
  39. defframe(PARAM_SIZE,   12)
  40. defframe(PARAM_SRC2,   8)
  41. defframe(PARAM_SRC,    4)
  42. define(M4_function,mpn_hamdist)
  43. ')
  44. POP(`
  45. defframe(PARAM_SIZE,   8)
  46. defframe(PARAM_SRC,    4)
  47. define(M4_function,mpn_popcount)
  48. ')
  49. MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
  50. ifdef(`PIC',,`
  51. dnl  non-PIC
  52. RODATA
  53. ALIGN(8)
  54. L(rodata_AAAAAAAAAAAAAAAA):
  55. .long 0xAAAAAAAA
  56. .long 0xAAAAAAAA
  57. L(rodata_3333333333333333):
  58. .long 0x33333333
  59. .long 0x33333333
  60. L(rodata_0F0F0F0F0F0F0F0F):
  61. .long 0x0F0F0F0F
  62. .long 0x0F0F0F0F
  63. L(rodata_000000FF000000FF):
  64. .long 0x000000FF
  65. .long 0x000000FF
  66. ')
  67. TEXT
  68. ALIGN(32)
  69. POP(`ifdef(`PIC', `
  70. C avoid shrl crossing a 32-byte boundary
  71. nop')')
  72. PROLOGUE(M4_function)
  73. deflit(`FRAME',0)
  74. movl PARAM_SIZE, %ecx
  75. ifdef(`PIC',`
  76. movl $0xAAAAAAAA, %eax
  77. movl $0x33333333, %edx
  78. movd %eax, %mm7
  79. movd %edx, %mm6
  80. movl $0x0F0F0F0F, %eax
  81. movl $0x000000FF, %edx
  82. punpckldq %mm7, %mm7
  83. punpckldq %mm6, %mm6
  84. movd %eax, %mm5
  85. movd %edx, %mm4
  86. punpckldq %mm5, %mm5
  87. punpckldq %mm4, %mm4
  88. ',`
  89. movq L(rodata_AAAAAAAAAAAAAAAA), %mm7
  90. movq L(rodata_3333333333333333), %mm6
  91. movq L(rodata_0F0F0F0F0F0F0F0F), %mm5
  92. movq L(rodata_000000FF000000FF), %mm4
  93. ')
  94. define(REG_AAAAAAAAAAAAAAAA, %mm7)
  95. define(REG_3333333333333333, %mm6)
  96. define(REG_0F0F0F0F0F0F0F0F, %mm5)
  97. define(REG_000000FF000000FF, %mm4)
  98. movl PARAM_SRC, %eax
  99. HAM(` movl PARAM_SRC2, %edx')
  100. pxor %mm2, %mm2 C total
  101. shrl %ecx
  102. jnc L(top)
  103. Zdisp( movd, 0,(%eax,%ecx,8), %mm1)
  104. HAM(`
  105. Zdisp( movd, 0,(%edx,%ecx,8), %mm0)
  106. pxor %mm0, %mm1
  107. ')
  108. incl %ecx
  109. jmp L(loaded)
  110. ALIGN(16)
  111. POP(` nop C alignment to avoid crossing 32-byte boundaries')
  112. L(top):
  113. C eax src
  114. C ebx
  115. C ecx counter, qwords, decrementing
  116. C edx [hamdist] src2
  117. C
  118. C mm0 (scratch)
  119. C mm1 (scratch)
  120. C mm2 total (low dword)
  121. C mm3
  122. C mm4
  123. C mm5 | special constants
  124. C mm6 |
  125. C mm7 /
  126. movq -8(%eax,%ecx,8), %mm1
  127. HAM(` pxor -8(%edx,%ecx,8), %mm1')
  128. L(loaded):
  129. movq %mm1, %mm0
  130. pand REG_AAAAAAAAAAAAAAAA, %mm1
  131. psrlq $1, %mm1
  132. HAM(` nop C code alignment')
  133. psubd %mm1, %mm0 C bit pairs
  134. HAM(` nop C code alignment')
  135. movq %mm0, %mm1
  136. psrlq $2, %mm0
  137. pand REG_3333333333333333, %mm0
  138. pand REG_3333333333333333, %mm1
  139. paddd %mm1, %mm0 C nibbles
  140. movq %mm0, %mm1
  141. psrlq $4, %mm0
  142. pand REG_0F0F0F0F0F0F0F0F, %mm0
  143. pand REG_0F0F0F0F0F0F0F0F, %mm1
  144. paddd %mm1, %mm0 C bytes
  145. movq %mm0, %mm1
  146. psrlq $8, %mm0
  147. paddb %mm1, %mm0 C words
  148. movq %mm0, %mm1
  149. psrlq $16, %mm0
  150. paddd %mm1, %mm0 C dwords
  151. pand REG_000000FF000000FF, %mm0
  152. paddd %mm0, %mm2 C low to total
  153. psrlq $32, %mm0
  154. paddd %mm0, %mm2 C high to total
  155. loop L(top)
  156. movd %mm2, %eax
  157. emms_or_femms
  158. ret
  159. EPILOGUE()