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

数学计算

开发平台:

Unix_Linux

  1. dnl  Intel P5 mpn_sqr_basecase -- square an mpn number.
  2. dnl  Copyright 1999, 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: approx 8 cycles per crossproduct, or 15.5 cycles per triangular
  20. C product at around 20x20 limbs.
  21. C void mpn_sqr_basecase (mp_ptr dst, mp_srcptr src, mp_size_t size);
  22. C
  23. C Calculate src,size squared, storing the result in dst,2*size.
  24. C
  25. C The algorithm is basically the same as mpn/generic/sqr_basecase.c, but a
  26. C lot of function call overheads are avoided, especially when the size is
  27. C small.
  28. defframe(PARAM_SIZE,12)
  29. defframe(PARAM_SRC, 8)
  30. defframe(PARAM_DST, 4)
  31. TEXT
  32. ALIGN(8)
  33. PROLOGUE(mpn_sqr_basecase)
  34. deflit(`FRAME',0)
  35. movl PARAM_SIZE, %edx
  36. movl PARAM_SRC, %eax
  37. cmpl $2, %edx
  38. movl PARAM_DST, %ecx
  39. je L(two_limbs)
  40. movl (%eax), %eax
  41. ja L(three_or_more)
  42. C -----------------------------------------------------------------------------
  43. C one limb only
  44. C eax src
  45. C ebx
  46. C ecx dst
  47. C edx
  48. mull %eax
  49. movl %eax, (%ecx)
  50. movl %edx, 4(%ecx)
  51. ret
  52. C -----------------------------------------------------------------------------
  53. ALIGN(8)
  54. L(two_limbs):
  55. C eax src
  56. C ebx
  57. C ecx dst
  58. C edx size
  59. pushl %ebp
  60. pushl %edi
  61. pushl %esi
  62. pushl %ebx
  63. movl %eax, %ebx
  64. movl (%eax), %eax
  65. mull %eax C src[0]^2
  66. movl %eax, (%ecx) C dst[0]
  67. movl %edx, %esi C dst[1]
  68. movl 4(%ebx), %eax
  69. mull %eax C src[1]^2
  70. movl %eax, %edi C dst[2]
  71. movl %edx, %ebp C dst[3]
  72. movl (%ebx), %eax
  73. mull 4(%ebx) C src[0]*src[1]
  74. addl %eax, %esi
  75. popl %ebx
  76. adcl %edx, %edi
  77. adcl $0, %ebp
  78. addl %esi, %eax
  79. adcl %edi, %edx
  80. movl %eax, 4(%ecx)
  81. adcl $0, %ebp
  82. popl %esi
  83. movl %edx, 8(%ecx)
  84. movl %ebp, 12(%ecx)
  85. popl %edi
  86. popl %ebp
  87. ret
  88. C -----------------------------------------------------------------------------
  89. ALIGN(8)
  90. L(three_or_more):
  91. C eax src low limb
  92. C ebx
  93. C ecx dst
  94. C edx size
  95. cmpl $4, %edx
  96. pushl %ebx
  97. deflit(`FRAME',4)
  98. movl PARAM_SRC, %ebx
  99. jae L(four_or_more)
  100. C -----------------------------------------------------------------------------
  101. C three limbs
  102. C eax src low limb
  103. C ebx src
  104. C ecx dst
  105. C edx size
  106. pushl %ebp
  107. pushl %edi
  108. mull %eax C src[0] ^ 2
  109. movl %eax, (%ecx)
  110. movl %edx, 4(%ecx)
  111. movl 4(%ebx), %eax
  112. xorl %ebp, %ebp
  113. mull %eax C src[1] ^ 2
  114. movl %eax, 8(%ecx)
  115. movl %edx, 12(%ecx)
  116. movl 8(%ebx), %eax
  117. pushl %esi C risk of cache bank clash
  118. mull %eax C src[2] ^ 2
  119. movl %eax, 16(%ecx)
  120. movl %edx, 20(%ecx)
  121. movl (%ebx), %eax
  122. mull 4(%ebx) C src[0] * src[1]
  123. movl %eax, %esi
  124. movl %edx, %edi
  125. movl (%ebx), %eax
  126. mull 8(%ebx) C src[0] * src[2]
  127. addl %eax, %edi
  128. movl %edx, %ebp
  129. adcl $0, %ebp
  130. movl 4(%ebx), %eax
  131. mull 8(%ebx) C src[1] * src[2]
  132. xorl %ebx, %ebx
  133. addl %eax, %ebp
  134. C eax
  135. C ebx zero, will be dst[5]
  136. C ecx dst
  137. C edx dst[4]
  138. C esi dst[1]
  139. C edi dst[2]
  140. C ebp dst[3]
  141. adcl $0, %edx
  142. addl %esi, %esi
  143. adcl %edi, %edi
  144. adcl %ebp, %ebp
  145. adcl %edx, %edx
  146. movl 4(%ecx), %eax
  147. adcl $0, %ebx
  148. addl %esi, %eax
  149. movl %eax, 4(%ecx)
  150. movl 8(%ecx), %eax
  151. adcl %edi, %eax
  152. movl 12(%ecx), %esi
  153. adcl %ebp, %esi
  154. movl 16(%ecx), %edi
  155. movl %eax, 8(%ecx)
  156. movl %esi, 12(%ecx)
  157. adcl %edx, %edi
  158. popl %esi
  159. movl 20(%ecx), %eax
  160. movl %edi, 16(%ecx)
  161. popl %edi
  162. popl %ebp
  163. adcl %ebx, %eax C no carry out of this
  164. popl %ebx
  165. movl %eax, 20(%ecx)
  166. ret
  167. C -----------------------------------------------------------------------------
  168. ALIGN(8)
  169. L(four_or_more):
  170. C eax src low limb
  171. C ebx src
  172. C ecx dst
  173. C edx size
  174. C esi
  175. C edi
  176. C ebp
  177. C
  178. C First multiply src[0]*src[1..size-1] and store at dst[1..size].
  179. deflit(`FRAME',4)
  180. pushl %edi
  181. FRAME_pushl()
  182. pushl %esi
  183. FRAME_pushl()
  184. pushl %ebp
  185. FRAME_pushl()
  186. leal (%ecx,%edx,4), %edi C dst end of this mul1
  187. leal (%ebx,%edx,4), %esi C src end
  188. movl %ebx, %ebp C src
  189. negl %edx C -size
  190. xorl %ebx, %ebx C clear carry limb and carry flag
  191. leal 1(%edx), %ecx C -(size-1)
  192. L(mul1):
  193. C eax scratch
  194. C ebx carry
  195. C ecx counter, negative
  196. C edx scratch
  197. C esi &src[size]
  198. C edi &dst[size]
  199. C ebp src
  200. adcl $0, %ebx
  201. movl (%esi,%ecx,4), %eax
  202. mull (%ebp)
  203. addl %eax, %ebx
  204. movl %ebx, (%edi,%ecx,4)
  205. incl %ecx
  206. movl %edx, %ebx
  207. jnz L(mul1)
  208. C Add products src[n]*src[n+1..size-1] at dst[2*n-1...], for
  209. C n=1..size-2.
  210. C
  211. C The last two products, which are the end corner of the product
  212. C triangle, are handled separately to save looping overhead.  These
  213. C are src[size-3]*src[size-2,size-1] and src[size-2]*src[size-1].
  214. C If size is 4 then it's only these that need to be done.
  215. C
  216. C In the outer loop %esi is a constant, and %edi just advances by 1
  217. C limb each time.  The size of the operation decreases by 1 limb
  218. C each time.
  219. C eax
  220. C ebx carry (needing carry flag added)
  221. C ecx
  222. C edx
  223. C esi &src[size]
  224. C edi &dst[size]
  225. C ebp
  226. adcl $0, %ebx
  227. movl PARAM_SIZE, %edx
  228. movl %ebx, (%edi)
  229. subl $4, %edx
  230. negl %edx
  231. jz L(corner)
  232. L(outer):
  233. C ebx previous carry limb to store
  234. C edx outer loop counter (negative)
  235. C esi &src[size]
  236. C edi dst, pointing at stored carry limb of previous loop
  237. pushl %edx C new outer loop counter
  238. leal -2(%edx), %ecx
  239. movl %ebx, (%edi)
  240. addl $4, %edi
  241. addl $4, %ebp
  242. xorl %ebx, %ebx C initial carry limb, clear carry flag
  243. L(inner):
  244. C eax scratch
  245. C ebx carry (needing carry flag added)
  246. C ecx counter, negative
  247. C edx scratch
  248. C esi &src[size]
  249. C edi dst end of this addmul
  250. C ebp &src[j]
  251. adcl $0, %ebx
  252. movl (%esi,%ecx,4), %eax
  253. mull (%ebp)
  254. addl %ebx, %eax
  255. movl (%edi,%ecx,4), %ebx
  256. adcl $0, %edx
  257. addl %eax, %ebx
  258. movl %ebx, (%edi,%ecx,4)
  259. incl %ecx
  260. movl %edx, %ebx
  261. jnz L(inner)
  262. adcl $0, %ebx
  263. popl %edx C outer loop counter
  264. incl %edx
  265. jnz L(outer)
  266. movl %ebx, (%edi)
  267. L(corner):
  268. C esi &src[size]
  269. C edi &dst[2*size-4]
  270. movl -8(%esi), %eax
  271. movl -4(%edi), %ebx C risk of data cache bank clash here
  272. mull -12(%esi) C src[size-2]*src[size-3]
  273. addl %eax, %ebx
  274. movl %edx, %ecx
  275. adcl $0, %ecx
  276. movl -4(%esi), %eax
  277. mull -12(%esi) C src[size-1]*src[size-3]
  278. addl %ecx, %eax
  279. movl (%edi), %ecx
  280. adcl $0, %edx
  281. movl %ebx, -4(%edi)
  282. addl %eax, %ecx
  283. movl %edx, %ebx
  284. adcl $0, %ebx
  285. movl -4(%esi), %eax
  286. mull -8(%esi) C src[size-1]*src[size-2]
  287. movl %ecx, (%edi)
  288. addl %eax, %ebx
  289. adcl $0, %edx
  290. movl PARAM_SIZE, %eax
  291. negl %eax
  292. movl %ebx, 4(%edi)
  293. addl $1, %eax C -(size-1) and clear carry
  294. movl %edx, 8(%edi)
  295. C -----------------------------------------------------------------------------
  296. C Left shift of dst[1..2*size-2], high bit shifted out becomes dst[2*size-1].
  297. L(lshift):
  298. C eax counter, negative
  299. C ebx next limb
  300. C ecx
  301. C edx
  302. C esi
  303. C edi &dst[2*size-4]
  304. C ebp
  305. movl 12(%edi,%eax,8), %ebx
  306. rcll %ebx
  307. movl 16(%edi,%eax,8), %ecx
  308. rcll %ecx
  309. movl %ebx, 12(%edi,%eax,8)
  310. movl %ecx, 16(%edi,%eax,8)
  311. incl %eax
  312. jnz L(lshift)
  313. adcl %eax, %eax C high bit out
  314. movl PARAM_SRC, %esi
  315. movl PARAM_SIZE, %ecx C risk of cache bank clash
  316. movl %eax, 12(%edi) C dst most significant limb
  317. C -----------------------------------------------------------------------------
  318. C Now add in the squares on the diagonal, namely src[0]^2, src[1]^2, ...,
  319. C src[size-1]^2.  dst[0] hasn't yet been set at all yet, and just gets the
  320. C low limb of src[0]^2.
  321. movl (%esi), %eax C src[0]
  322. leal (%esi,%ecx,4), %esi C src end
  323. negl %ecx
  324. mull %eax
  325. movl %eax, 16(%edi,%ecx,8) C dst[0]
  326. movl %edx, %ebx
  327. addl $1, %ecx C size-1 and clear carry
  328. L(diag):
  329. C eax scratch (low product)
  330. C ebx carry limb
  331. C ecx counter, negative
  332. C edx scratch (high product)
  333. C esi &src[size]
  334. C edi &dst[2*size-4]
  335. C ebp scratch (fetched dst limbs)
  336. movl (%esi,%ecx,4), %eax
  337. adcl $0, %ebx
  338. mull %eax
  339. movl 16-4(%edi,%ecx,8), %ebp
  340. addl %ebp, %ebx
  341. movl 16(%edi,%ecx,8), %ebp
  342. adcl %eax, %ebp
  343. movl %ebx, 16-4(%edi,%ecx,8)
  344. movl %ebp, 16(%edi,%ecx,8)
  345. incl %ecx
  346. movl %edx, %ebx
  347. jnz L(diag)
  348. adcl $0, %edx
  349. movl 16-4(%edi), %eax C dst most significant limb
  350. addl %eax, %edx
  351. popl %ebp
  352. movl %edx, 16-4(%edi)
  353. popl %esi C risk of cache bank clash
  354. popl %edi
  355. popl %ebx
  356. ret
  357. EPILOGUE()