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

数学计算

开发平台:

Unix_Linux

  1. dnl  Intel P5 mpn_lshift -- mpn left shift.
  2. dnl  Copyright 2000, 2001, 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 P5: 1.75 cycles/limb.
  20. C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
  21. C                       unsigned shift);
  22. C
  23. C Shift src,size left by shift many bits and store the result in dst,size.
  24. C Zeros are shifted in at the right.  Return the bits shifted out at the
  25. C left.
  26. C
  27. C The comments in mpn_rshift apply here too.
  28. defframe(PARAM_SHIFT,16)
  29. defframe(PARAM_SIZE, 12)
  30. defframe(PARAM_SRC,  8)
  31. defframe(PARAM_DST,  4)
  32. deflit(`FRAME',0)
  33. dnl  minimum 5, because the unrolled loop can't handle less
  34. deflit(UNROLL_THRESHOLD, 5)
  35. TEXT
  36. ALIGN(8)
  37. PROLOGUE(mpn_lshift)
  38. pushl %ebx
  39. pushl %edi
  40. deflit(`FRAME',8)
  41. movl PARAM_SIZE, %eax
  42. movl PARAM_DST, %edx
  43. movl PARAM_SRC, %ebx
  44. movl PARAM_SHIFT, %ecx
  45. cmp $UNROLL_THRESHOLD, %eax
  46. jae L(unroll)
  47. movl -4(%ebx,%eax,4), %edi C src high limb
  48. decl %eax
  49. jnz L(simple)
  50. shldl( %cl, %edi, %eax) C eax was decremented to zero
  51. shll %cl, %edi
  52. movl %edi, (%edx) C dst low limb
  53. popl %edi C risk of data cache bank clash
  54. popl %ebx
  55. ret
  56. C -----------------------------------------------------------------------------
  57. L(simple):
  58. C eax size-1
  59. C ebx src
  60. C ecx shift
  61. C edx dst
  62. C esi
  63. C edi
  64. C ebp
  65. deflit(`FRAME',8)
  66. movd (%ebx,%eax,4), %mm5 C src high limb
  67. movd %ecx, %mm6 C lshift
  68. negl %ecx
  69. psllq %mm6, %mm5
  70. addl $32, %ecx
  71. movd %ecx, %mm7
  72. psrlq $32, %mm5 C retval
  73. L(simple_top):
  74. C eax counter, limbs, negative
  75. C ebx src
  76. C ecx
  77. C edx dst
  78. C esi
  79. C edi
  80. C
  81. C mm0 scratch
  82. C mm5 return value
  83. C mm6 shift
  84. C mm7 32-shift
  85. movq -4(%ebx,%eax,4), %mm0
  86. decl %eax
  87. psrlq %mm7, %mm0
  88. C
  89. movd %mm0, 4(%edx,%eax,4)
  90. jnz L(simple_top)
  91. movd (%ebx), %mm0
  92. movd %mm5, %eax
  93. psllq %mm6, %mm0
  94. popl %edi
  95. popl %ebx
  96. movd %mm0, (%edx)
  97. emms
  98. ret
  99. C -----------------------------------------------------------------------------
  100. ALIGN(8)
  101. L(unroll):
  102. C eax size
  103. C ebx src
  104. C ecx shift
  105. C edx dst
  106. C esi
  107. C edi
  108. C ebp
  109. deflit(`FRAME',8)
  110. movd -4(%ebx,%eax,4), %mm5 C src high limb
  111. leal (%ebx,%eax,4), %edi
  112. movd %ecx, %mm6 C lshift
  113. andl $4, %edi
  114. psllq %mm6, %mm5
  115. jz L(start_src_aligned)
  116. C src isn't aligned, process high limb separately (marked xxx) to
  117. C make it so.
  118. C
  119. C  source     -8(ebx,%eax,4)
  120. C                  |
  121. C  +-------+-------+-------+--
  122. C  |               |
  123. C  +-------+-------+-------+--
  124. C        0mod8   4mod8   0mod8
  125. C
  126. C  dest
  127. C     -4(edx,%eax,4)
  128. C          |
  129. C  +-------+-------+--
  130. C  |  xxx  |       |
  131. C  +-------+-------+--
  132. movq -8(%ebx,%eax,4), %mm0 C unaligned load
  133. psllq %mm6, %mm0
  134. decl %eax
  135. psrlq $32, %mm0
  136. C
  137. movd %mm0, (%edx,%eax,4)
  138. L(start_src_aligned):
  139. movq -8(%ebx,%eax,4), %mm1 C src high qword
  140. leal (%edx,%eax,4), %edi
  141. andl $4, %edi
  142. psrlq $32, %mm5 C return value
  143. movq -16(%ebx,%eax,4), %mm3 C src second highest qword
  144. jz L(start_dst_aligned)
  145. C dst isn't aligned, subtract 4 to make it so, and pretend the shift
  146. C is 32 bits extra.  High limb of dst (marked xxx) handled here
  147. C separately.
  148. C
  149. C  source     -8(ebx,%eax,4)
  150. C                  |
  151. C  +-------+-------+--
  152. C  |      mm1      |
  153. C  +-------+-------+--
  154. C                0mod8   4mod8
  155. C
  156. C  dest
  157. C     -4(edx,%eax,4)
  158. C          |
  159. C  +-------+-------+-------+--
  160. C  |  xxx  |               |
  161. C  +-------+-------+-------+--
  162. C        0mod8   4mod8   0mod8
  163. movq %mm1, %mm0
  164. addl $32, %ecx C new shift
  165. psllq %mm6, %mm0
  166. movd %ecx, %mm6
  167. psrlq $32, %mm0
  168. C wasted cycle here waiting for %mm0
  169. movd %mm0, -4(%edx,%eax,4)
  170. subl $4, %edx
  171. L(start_dst_aligned):
  172. psllq %mm6, %mm1
  173. negl %ecx C -shift
  174. addl $64, %ecx C 64-shift
  175. movq %mm3, %mm2
  176. movd %ecx, %mm7
  177. subl $8, %eax C size-8
  178. psrlq %mm7, %mm3
  179. por %mm1, %mm3 C mm3 ready to store
  180. jc L(finish)
  181. C The comments in mpn_rshift apply here too.
  182. ALIGN(8)
  183. L(unroll_loop):
  184. C eax counter, limbs
  185. C ebx src
  186. C ecx
  187. C edx dst
  188. C esi
  189. C edi
  190. C
  191. C mm0
  192. C mm1
  193. C mm2 src qword from 16(%ebx,%eax,4)
  194. C mm3 dst qword ready to store to 24(%edx,%eax,4)
  195. C
  196. C mm5 return value
  197. C mm6 lshift
  198. C mm7 rshift
  199. movq 8(%ebx,%eax,4), %mm0
  200. psllq %mm6, %mm2
  201. movq %mm0, %mm1
  202. psrlq %mm7, %mm0
  203. movq %mm3, 24(%edx,%eax,4) C prev
  204. por %mm2, %mm0
  205. movq (%ebx,%eax,4), %mm3 C
  206. psllq %mm6, %mm1 C
  207. movq %mm0, 16(%edx,%eax,4)
  208. movq %mm3, %mm2 C
  209. psrlq %mm7, %mm3 C
  210. subl $4, %eax
  211. por %mm1, %mm3 C
  212. jnc L(unroll_loop)
  213. L(finish):
  214. C eax -4 to -1 representing respectively 0 to 3 limbs remaining
  215. testb $2, %al
  216. jz L(finish_no_two)
  217. movq 8(%ebx,%eax,4), %mm0
  218. psllq %mm6, %mm2
  219. movq %mm0, %mm1
  220. psrlq %mm7, %mm0
  221. movq %mm3, 24(%edx,%eax,4) C prev
  222. por %mm2, %mm0
  223. movq %mm1, %mm2
  224. movq %mm0, %mm3
  225. subl $2, %eax
  226. L(finish_no_two):
  227. C eax -4 or -3 representing respectively 0 or 1 limbs remaining
  228. C
  229. C mm2 src prev qword, from 16(%ebx,%eax,4)
  230. C mm3 dst qword, for 24(%edx,%eax,4)
  231. testb $1, %al
  232. movd %mm5, %eax C retval
  233. popl %edi
  234. jz L(finish_zero)
  235. C One extra src limb, destination was aligned.
  236. C
  237. C                 source                  ebx
  238. C                 --+---------------+-------+
  239. C                   |      mm2      |       |
  240. C                 --+---------------+-------+
  241. C
  242. C dest         edx+12           edx+4     edx
  243. C --+---------------+---------------+-------+
  244. C   |      mm3      |               |       |
  245. C --+---------------+---------------+-------+
  246. C
  247. C mm6 = shift
  248. C mm7 = ecx = 64-shift
  249. C One extra src limb, destination was unaligned.
  250. C
  251. C                 source                  ebx
  252. C                 --+---------------+-------+
  253. C                   |      mm2      |       |
  254. C                 --+---------------+-------+
  255. C
  256. C         dest         edx+12           edx+4
  257. C         --+---------------+---------------+
  258. C           |      mm3      |               |
  259. C         --+---------------+---------------+
  260. C
  261. C mm6 = shift+32
  262. C mm7 = ecx = 64-(shift+32)
  263. C In both cases there's one extra limb of src to fetch and combine
  264. C with mm2 to make a qword at 4(%edx), and in the aligned case
  265. C there's an extra limb of dst to be formed from that extra src limb
  266. C left shifted.
  267. movd (%ebx), %mm0
  268. psllq %mm6, %mm2
  269. movq %mm3, 12(%edx)
  270. psllq $32, %mm0
  271. movq %mm0, %mm1
  272. psrlq %mm7, %mm0
  273. por %mm2, %mm0
  274. psllq %mm6, %mm1
  275. movq %mm0, 4(%edx)
  276. psrlq $32, %mm1
  277. andl $32, %ecx
  278. popl %ebx
  279. jz L(finish_one_unaligned)
  280. movd %mm1, (%edx)
  281. L(finish_one_unaligned):
  282. emms
  283. ret
  284. L(finish_zero):
  285. C No extra src limbs, destination was aligned.
  286. C
  287. C                 source          ebx
  288. C                 --+---------------+
  289. C                   |      mm2      |
  290. C                 --+---------------+
  291. C
  292. C dest          edx+8             edx
  293. C --+---------------+---------------+
  294. C   |      mm3      |               |
  295. C --+---------------+---------------+
  296. C
  297. C mm6 = shift
  298. C mm7 = ecx = 64-shift
  299. C No extra src limbs, destination was unaligned.
  300. C
  301. C               source            ebx
  302. C                 --+---------------+
  303. C                   |      mm2      |
  304. C                 --+---------------+
  305. C
  306. C         dest          edx+8   edx+4
  307. C         --+---------------+-------+
  308. C           |      mm3      |       |
  309. C         --+---------------+-------+
  310. C
  311. C mm6 = shift+32
  312. C mm7 = ecx = 64-(shift+32)
  313. C The movd for the unaligned case writes the same data to 4(%edx)
  314. C that the movq does for the aligned case.
  315. movq %mm3, 8(%edx)
  316. andl $32, %ecx
  317. psllq %mm6, %mm2
  318. jz L(finish_zero_unaligned)
  319. movq %mm2, (%edx)
  320. L(finish_zero_unaligned):
  321. psrlq $32, %mm2
  322. popl %ebx
  323. movd %mm5, %eax C retval
  324. movd %mm2, 4(%edx)
  325. emms
  326. ret
  327. EPILOGUE()