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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K6-2 mpn_rshift -- mpn right shift.
  2. dnl  Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
  3. dnl
  4. dnl  This file is part of the GNU MP Library.
  5. dnl
  6. dnl  The GNU MP Library is free software; you can redistribute it and/or
  7. dnl  modify it under the terms of the GNU Lesser General Public License as
  8. dnl  published by the Free Software Foundation; either version 3 of the
  9. dnl  License, or (at your option) any later version.
  10. dnl
  11. dnl  The GNU MP Library is distributed in the hope that it will be useful,
  12. dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. dnl  Lesser General Public License for more details.
  15. dnl
  16. dnl  You should have received a copy of the GNU Lesser General Public License
  17. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  18. include(`../config.m4')
  19. C K6-2: 1.75 cycles/limb
  20. C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
  21. C                       unsigned shift);
  22. C
  23. defframe(PARAM_SHIFT,16)
  24. defframe(PARAM_SIZE, 12)
  25. defframe(PARAM_SRC,  8)
  26. defframe(PARAM_DST,  4)
  27. deflit(`FRAME',0)
  28. dnl  Minimum 9, because the unrolled loop can't handle less.
  29. dnl
  30. deflit(UNROLL_THRESHOLD, 9)
  31. TEXT
  32. ALIGN(32)
  33. PROLOGUE(mpn_rshift)
  34. deflit(`FRAME',0)
  35. C The 1 limb case can be done without the push %ebx, but it's then
  36. C still the same speed.  The push is left as a free helping hand for
  37. C the two_or_more code.
  38. movl PARAM_SIZE, %eax
  39. pushl %ebx FRAME_pushl()
  40. movl PARAM_SRC, %ebx
  41. decl %eax
  42. movl PARAM_SHIFT, %ecx
  43. jnz L(two_or_more)
  44. movl (%ebx), %edx C src limb
  45. movl PARAM_DST, %ebx
  46. shrdl( %cl, %edx, %eax) C return value
  47. shrl %cl, %edx
  48. movl %edx, (%ebx) C dst limb
  49. popl %ebx
  50. ret
  51. C -----------------------------------------------------------------------------
  52. ALIGN(16) C avoid offset 0x1f
  53. L(two_or_more):
  54. C eax size-1
  55. C ebx src
  56. C ecx shift
  57. C edx
  58. movl (%ebx), %edx C src low limb
  59. negl %ecx
  60. addl $32, %ecx
  61. movd PARAM_SHIFT, %mm6
  62. shll %cl, %edx
  63. cmpl $UNROLL_THRESHOLD-1, %eax
  64. jae L(unroll)
  65. C eax size-1
  66. C ebx src
  67. C ecx 32-shift
  68. C edx retval
  69. C
  70. C mm6 shift
  71. movl PARAM_DST, %ecx
  72. leal (%ebx,%eax,4), %ebx
  73. leal -4(%ecx,%eax,4), %ecx
  74. negl %eax
  75. C This loop runs at about 3 cycles/limb, which is the amount of
  76. C decoding, and this is despite every second access being unaligned.
  77. L(simple):
  78. C eax counter, -(size-1) to -1
  79. C ebx &src[size-1]
  80. C ecx &dst[size-1]
  81. C edx retval
  82. C
  83. C mm0 scratch
  84. C mm6 shift
  85. Zdisp( movq, 0,(%ebx,%eax,4), %mm0)
  86. incl %eax
  87. psrlq %mm6, %mm0
  88. Zdisp( movd, %mm0, 0,(%ecx,%eax,4))
  89. jnz L(simple)
  90. movq %mm0, (%ecx)
  91. movl %edx, %eax
  92. popl %ebx
  93. femms
  94. ret
  95. C -----------------------------------------------------------------------------
  96. ALIGN(16)
  97. L(unroll):
  98. C eax size-1
  99. C ebx src
  100. C ecx 32-shift
  101. C edx retval
  102. C
  103. C mm6 shift
  104. addl $32, %ecx
  105. subl $7, %eax C size-8
  106. movd %ecx, %mm7
  107. movl PARAM_DST, %ecx
  108. movq (%ebx), %mm2 C src low qword
  109. leal (%ebx,%eax,4), %ebx C src end - 32
  110. testb $4, %cl
  111. leal (%ecx,%eax,4), %ecx C dst end - 32
  112. notl %eax C -(size-7)
  113. jz L(dst_aligned)
  114. psrlq %mm6, %mm2
  115. incl %eax
  116. Zdisp( movd, %mm2, 0,(%ecx,%eax,4)) C dst low limb
  117. movq 4(%ebx,%eax,4), %mm2 C new src low qword
  118. L(dst_aligned):
  119. movq 12(%ebx,%eax,4), %mm0 C src second lowest qword
  120. nop C avoid bad cache line crossing
  121. C This loop is the important bit, the rest is just support for it.
  122. C Four src limbs are held at the start, and four more will be read.
  123. C Four dst limbs will be written.  This schedule seems necessary for
  124. C full speed.
  125. C
  126. C The use of -(size-7) lets the loop stop when %eax becomes >= 0 and
  127. C and leaves 0 to 3 which can be tested with test $1 and $2.
  128. L(top):
  129. C eax counter, -(size-7) step by +4 until >=0
  130. C ebx src end - 32
  131. C ecx dst end - 32
  132. C edx retval
  133. C
  134. C mm0 src next qword
  135. C mm1 scratch
  136. C mm2 src prev qword
  137. C mm6 shift
  138. C mm7 64-shift
  139. psrlq %mm6, %mm2
  140. addl $4, %eax
  141. movq %mm0, %mm1
  142. psllq %mm7, %mm0
  143. por %mm0, %mm2
  144. movq 4(%ebx,%eax,4), %mm0
  145. psrlq %mm6, %mm1
  146. movq %mm2, -12(%ecx,%eax,4)
  147. movq %mm0, %mm2
  148. psllq %mm7, %mm0
  149. por %mm0, %mm1
  150. movq 12(%ebx,%eax,4), %mm0
  151. movq %mm1, -4(%ecx,%eax,4)
  152. ja L(top) C jump if no carry and not zero
  153. C Now have the four limbs in mm2 (low) and mm0 (high), and %eax is 0
  154. C to 3 representing respectively 3 to 0 further limbs.
  155. testl $2, %eax C testl to avoid bad cache line crossings
  156. jnz L(finish_nottwo)
  157. C Two or three extra limbs: rshift mm2, OR it with lshifted mm0, mm0
  158. C becomes new mm2 and a new mm0 is loaded.
  159. psrlq %mm6, %mm2
  160. movq %mm0, %mm1
  161. psllq %mm7, %mm0
  162. addl $2, %eax
  163. por %mm0, %mm2
  164. movq 12(%ebx,%eax,4), %mm0
  165. movq %mm2, -4(%ecx,%eax,4)
  166. movq %mm1, %mm2
  167. L(finish_nottwo):
  168. testb $1, %al
  169. psrlq %mm6, %mm2
  170. movq %mm0, %mm1
  171. psllq %mm7, %mm0
  172. por %mm0, %mm2
  173. psrlq %mm6, %mm1
  174. movq %mm2, 4(%ecx,%eax,4)
  175. jnz L(finish_even)
  176. C one further extra limb to process
  177. movd 32-4(%ebx), %mm0 C src[size-1], most significant limb
  178. popl %ebx
  179. movq %mm0, %mm2
  180. psllq %mm7, %mm0
  181. por %mm0, %mm1
  182. psrlq %mm6, %mm2
  183. movq %mm1, 32-12(%ecx) C dst[size-3,size-2]
  184. movd %mm2, 32-4(%ecx) C dst[size-1]
  185. movl %edx, %eax C retval
  186. femms
  187. ret
  188. nop C avoid bad cache line crossing
  189. L(finish_even):
  190. C no further extra limbs
  191. movq %mm1, 32-8(%ecx) C dst[size-2,size-1]
  192. movl %edx, %eax C retval
  193. popl %ebx
  194. femms
  195. ret
  196. EPILOGUE()