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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K7 mpn_popcount, mpn_hamdist -- population count and hamming
  2. dnl  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 P3 generic 6.5 7
  22. C P3 model 9  (Banias)          ? ?
  23. C P3 model 13 (Dothan) 5.75 6
  24. C K7 5 6
  25. C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
  26. C unsigned long mpn_hamdist (mp_srcptr src, mp_srcptr src2, mp_size_t size);
  27. C
  28. C The code here is almost certainly not optimal, but is already a 3x speedup
  29. C over the generic C code.  The main improvement would be to interleave
  30. C processing of two qwords in the loop so as to fully exploit the available
  31. C execution units, possibly leading to 3.25 c/l (13 cycles for 4 limbs).
  32. C
  33. C The loop is based on the example "Efficient 64-bit population count using
  34. C MMX instructions" in the Athlon Optimization Guide, AMD document 22007,
  35. C page 158 of rev E (reference in mpn/x86/k7/README).
  36. ifdef(`OPERATION_popcount',,
  37. `ifdef(`OPERATION_hamdist',,
  38. `m4_error(`Need OPERATION_popcount or OPERATION_hamdist defined
  39. ')')')
  40. define(HAM,
  41. m4_assert_numargs(1)
  42. `ifdef(`OPERATION_hamdist',`$1')')
  43. define(POP,
  44. m4_assert_numargs(1)
  45. `ifdef(`OPERATION_popcount',`$1')')
  46. HAM(`
  47. defframe(PARAM_SIZE,   12)
  48. defframe(PARAM_SRC2,   8)
  49. defframe(PARAM_SRC,    4)
  50. define(M4_function,mpn_hamdist)
  51. ')
  52. POP(`
  53. defframe(PARAM_SIZE,   8)
  54. defframe(PARAM_SRC,    4)
  55. define(M4_function,mpn_popcount)
  56. ')
  57. MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
  58. ifdef(`PIC',,`
  59. dnl  non-PIC
  60. RODATA
  61. ALIGN(8)
  62. L(rodata_AAAAAAAAAAAAAAAA):
  63. .long 0xAAAAAAAA
  64. .long 0xAAAAAAAA
  65. L(rodata_3333333333333333):
  66. .long 0x33333333
  67. .long 0x33333333
  68. L(rodata_0F0F0F0F0F0F0F0F):
  69. .long 0x0F0F0F0F
  70. .long 0x0F0F0F0F
  71. ')
  72. TEXT
  73. ALIGN(32)
  74. PROLOGUE(M4_function)
  75. deflit(`FRAME',0)
  76. movl PARAM_SIZE, %ecx
  77. ifdef(`PIC',`
  78. movl $0xAAAAAAAA, %eax
  79. movl $0x33333333, %edx
  80. movd %eax, %mm7
  81. movd %edx, %mm6
  82. movl $0x0F0F0F0F, %eax
  83. punpckldq %mm7, %mm7
  84. punpckldq %mm6, %mm6
  85. movd %eax, %mm5
  86. movd %edx, %mm4
  87. punpckldq %mm5, %mm5
  88. ',`
  89. movq L(rodata_AAAAAAAAAAAAAAAA), %mm7
  90. movq L(rodata_3333333333333333), %mm6
  91. movq L(rodata_0F0F0F0F0F0F0F0F), %mm5
  92. ')
  93. pxor %mm4, %mm4
  94. define(REG_AAAAAAAAAAAAAAAA,%mm7)
  95. define(REG_3333333333333333,%mm6)
  96. define(REG_0F0F0F0F0F0F0F0F,%mm5)
  97. define(REG_0000000000000000,%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. movd (%eax,%ecx,8), %mm1
  104. HAM(` movd (%edx,%ecx,8), %mm0
  105. pxor %mm0, %mm1
  106. ')
  107. orl %ecx, %ecx
  108. jmp L(loaded)
  109. ALIGN(16)
  110. L(top):
  111. C eax src
  112. C ebx
  113. C ecx counter, qwords, decrementing
  114. C edx [hamdist] src2
  115. C
  116. C mm0 (scratch)
  117. C mm1 (scratch)
  118. C mm2 total (low dword)
  119. C mm3
  120. C mm4
  121. C mm5 | special constants
  122. C mm6 |
  123. C mm7 /
  124. movq -8(%eax,%ecx,8), %mm1
  125. HAM(` pxor -8(%edx,%ecx,8), %mm1')
  126. decl %ecx
  127. L(loaded):
  128. movq %mm1, %mm0
  129. pand REG_AAAAAAAAAAAAAAAA, %mm1
  130. psrlq $1, %mm1
  131. psubd %mm1, %mm0 C bit pairs
  132. movq %mm0, %mm1
  133. psrlq $2, %mm0
  134. pand REG_3333333333333333, %mm0
  135. pand REG_3333333333333333, %mm1
  136. paddd %mm1, %mm0 C nibbles
  137. movq %mm0, %mm1
  138. psrlq $4, %mm0
  139. pand REG_0F0F0F0F0F0F0F0F, %mm0
  140. pand REG_0F0F0F0F0F0F0F0F, %mm1
  141. paddd %mm1, %mm0 C bytes
  142. psadbw( %mm4, %mm0)
  143. paddd %mm0, %mm2 C add to total
  144. jnz L(top)
  145. movd %mm2, %eax
  146. emms
  147. ret
  148. EPILOGUE()