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

数学计算

开发平台:

Unix_Linux

  1. dnl  Intel Pentium 4 mpn_popcount, mpn_hamdist -- population count and
  2. dnl  hamming distance.
  3. dnl  Copyright 2000, 2001, 2002, 2007 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 model 9  (Banias) ? ?
  22. C P3 model 13 (Dothan) 6 6
  23. C P4 model 0  (Willamette)
  24. C P4 model 1  (?)
  25. C P4 model 2  (Northwood) 8 9
  26. C P4 model 3  (Prescott) 8 9
  27. C P4 model 4  (Nocona)
  28. C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
  29. C unsigned long mpn_hamdist (mp_srcptr src, mp_srcptr src2, mp_size_t size);
  30. C
  31. C Loading with unaligned movq's costs an extra 1 c/l and hence is avoided.
  32. C Two movd's and a punpckldq seems to be the same speed as an aligned movq,
  33. C and using them saves fiddling about with alignment testing on entry.
  34. C
  35. C For popcount there's 13 mmx instructions in the loop, so perhaps 6.5 c/l
  36. C might be possible, but 8 c/l relying on out-of-order execution is already
  37. C quite reasonable.
  38. ifdef(`OPERATION_popcount',,
  39. `ifdef(`OPERATION_hamdist',,
  40. `m4_error(`Need OPERATION_popcount or OPERATION_hamdist defined
  41. ')')')
  42. define(HAM,
  43. m4_assert_numargs(1)
  44. `ifdef(`OPERATION_hamdist',`$1')')
  45. define(POP,
  46. m4_assert_numargs(1)
  47. `ifdef(`OPERATION_popcount',`$1')')
  48. HAM(`
  49. defframe(PARAM_SIZE, 12)
  50. defframe(PARAM_SRC2,  8)
  51. defframe(PARAM_SRC,   4)
  52. define(M4_function,mpn_hamdist)
  53. ')
  54. POP(`
  55. defframe(PARAM_SIZE,  8)
  56. defframe(PARAM_SRC,   4)
  57. define(M4_function,mpn_popcount)
  58. ')
  59. MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
  60. ifdef(`PIC',,`
  61. dnl  non-PIC
  62. RODATA
  63. ALIGN(8)
  64. L(rodata_AAAAAAAAAAAAAAAA):
  65. .long 0xAAAAAAAA
  66. .long 0xAAAAAAAA
  67. L(rodata_3333333333333333):
  68. .long 0x33333333
  69. .long 0x33333333
  70. L(rodata_0F0F0F0F0F0F0F0F):
  71. .long 0x0F0F0F0F
  72. .long 0x0F0F0F0F
  73. ')
  74. TEXT
  75. ALIGN(16)
  76. PROLOGUE(M4_function)
  77. deflit(`FRAME',0)
  78. movl PARAM_SIZE, %ecx
  79. movl PARAM_SRC, %eax
  80. ifdef(`PIC',`
  81. movl $0xAAAAAAAA, %edx
  82. movd %edx, %mm7
  83. punpckldq %mm7, %mm7
  84. movl $0x33333333, %edx
  85. movd %edx, %mm6
  86. punpckldq %mm6, %mm6
  87. movl $0x0F0F0F0F, %edx
  88. movd %edx, %mm5
  89. punpckldq %mm5, %mm5
  90. HAM(` movl PARAM_SRC2, %edx')
  91. ',`
  92. dnl non-PIC
  93. HAM(` movl PARAM_SRC2, %edx')
  94. movq L(rodata_AAAAAAAAAAAAAAAA), %mm7
  95. movq L(rodata_3333333333333333), %mm6
  96. movq L(rodata_0F0F0F0F0F0F0F0F), %mm5
  97. ')
  98. pxor %mm4, %mm4 C zero
  99. pxor %mm0, %mm0 C total
  100. subl $1, %ecx
  101. ja L(top)
  102. L(last):
  103. movd (%eax,%ecx,4), %mm1 C src high limb
  104. HAM(` movd (%edx,%ecx,4), %mm2
  105. pxor %mm2, %mm1
  106. ')
  107. jmp L(loaded)
  108. L(top):
  109. C eax src
  110. C ebx
  111. C ecx counter, size-1 to 2 or 1, inclusive
  112. C edx [hamdist] src2
  113. C
  114. C mm0 total (low dword)
  115. C mm1 (scratch)
  116. C mm2 (scratch)
  117. C mm3
  118. C mm4 0x0000000000000000
  119. C mm5 0x0F0F0F0F0F0F0F0F
  120. C mm6 0x3333333333333333
  121. C mm7 0xAAAAAAAAAAAAAAAA
  122. movd (%eax), %mm1
  123. movd 4(%eax), %mm2
  124. punpckldq %mm2, %mm1
  125. addl $8, %eax
  126. HAM(` movd (%edx), %mm2
  127. movd 4(%edx), %mm3
  128. punpckldq %mm3, %mm2
  129. pxor %mm2, %mm1
  130. addl $8, %edx
  131. ')
  132. L(loaded):
  133. movq %mm7, %mm2
  134. pand %mm1, %mm2
  135. psrlq $1, %mm2
  136. psubd %mm2, %mm1 C bit pairs
  137. movq %mm6, %mm2
  138. pand %mm1, %mm2
  139. psrlq $2, %mm1
  140. pand %mm6, %mm1
  141. paddd %mm2, %mm1 C nibbles
  142. movq %mm5, %mm2
  143. pand %mm1, %mm2
  144. psrlq $4, %mm1
  145. pand %mm5, %mm1
  146. paddd %mm2, %mm1 C bytes
  147. psadbw( %mm4, %mm1)
  148. paddd %mm1, %mm0 C to total
  149. subl $2, %ecx
  150. jg L(top)
  151. C ecx is 0 or -1 representing respectively 1 or 0 further limbs
  152. jz L(last)
  153. movd %mm0, %eax
  154. emms
  155. ret
  156. EPILOGUE()