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

数学计算

开发平台:

Unix_Linux

  1. dnl  SPARC v9 64-bit mpn_addmul_2 -- Multiply an n limb number with 2-limb
  2. dnl  number and add the result to a n limb vector.
  3. dnl  Copyright 2002, 2003 Free Software Foundation, Inc.
  4. dnl  This file is part of the GNU MP Library.
  5. dnl  The GNU MP Library is free software; you can redistribute it and/or modify
  6. dnl  it under the terms of the GNU Lesser General Public License as published
  7. dnl  by the Free Software Foundation; either version 3 of the License, or (at
  8. dnl  your option) any later version.
  9. dnl  The GNU MP Library is distributed in the hope that it will be useful, but
  10. dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  12. dnl  License for more details.
  13. dnl  You should have received a copy of the GNU Lesser General Public License
  14. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  15. include(`../config.m4')
  16. C                  cycles/limb
  17. C UltraSPARC 1&2:      9
  18. C UltraSPARC 3:       10
  19. C Algorithm: We use 16 floating-point multiplies per limb product, with the
  20. C 2-limb v operand split into eight 16-bit pieces, and the n-limb u operand
  21. C split into 32-bit pieces.  We sum four 48-bit partial products using
  22. C floating-point add, then convert the resulting four 50-bit quantities and
  23. C transfer them to the integer unit.
  24. C Possible optimizations:
  25. C   1. Align the stack area where we transfer the four 50-bit product-sums
  26. C      to a 32-byte boundary.  That would minimize the cache collision.
  27. C      (UltraSPARC-1/2 use a direct-mapped cache.)  (Perhaps even better would
  28. C      be to align the area to map to the area immediately before up?)
  29. C   2. Perform two of the fp->int conversions with integer instructions.  We
  30. C      can get almost ten free IEU slots, if we clean up bookkeeping and the
  31. C      silly carry-limb code.
  32. C   3. For an mpn_addmul_1 based on this, we need to fix the silly carry-limb
  33. C      code.
  34. C OSP (Overlapping software pipeline) version of mpn_mul_basecase:
  35. C Operand swap will require 8 LDDA and 8 FXTOD, which will mean 8 cycles.
  36. C FI = 20
  37. C L =  9 x un * vn
  38. C WDFI = 10 x vn / 2
  39. C WD = 4
  40. C Instruction classification (as per UltraSPARC functional units).
  41. C Assuming silly carry code is fixed.  Includes bookkeeping.
  42. C
  43. C               mpn_addmul_X     mpn_mul_X
  44. C                1       2       1       2
  45. C               ==========      ==========
  46. C      FM        8      16       8      16
  47. C      FA       10      18      10      18
  48. C     MEM       12      12      10      10
  49. C  ISHIFT        6       6       6       6
  50. C IADDLOG       11      11      10      10
  51. C  BRANCH        1       1       1       1
  52. C
  53. C TOTAL IEU     17      17      16      16
  54. C TOTAL         48      64      45      61
  55. C
  56. C IEU cycles     8.5     8.5     8       8
  57. C MEM cycles    12      12      10      10
  58. C ISSUE cycles  12      16      11.25   15.25
  59. C FPU cycles    10      18      10      18
  60. C cycles/loop   12      18      12      18
  61. C cycles/limb   12       9      12       9
  62. C INPUT PARAMETERS
  63. C rp[n + 1] i0
  64. C up[n] i1
  65. C n i2
  66. C vp[2] i3
  67. ASM_START()
  68. REGISTER(%g2,#scratch)
  69. REGISTER(%g3,#scratch)
  70. C Combine registers:
  71. C u00_hi= u32_hi
  72. C u00_lo= u32_lo
  73. C a000  = out000
  74. C a016  = out016
  75. C Free: f52 f54
  76. define(`p000', `%f8')  define(`p016',`%f10')
  77. define(`p032',`%f12')  define(`p048',`%f14')
  78. define(`p064',`%f16')  define(`p080',`%f18')
  79. define(`p096a',`%f20') define(`p112a',`%f22')
  80. define(`p096b',`%f56') define(`p112b',`%f58')
  81. define(`out000',`%f0') define(`out016',`%f6')
  82. define(`v000',`%f24')  define(`v016',`%f26')
  83. define(`v032',`%f28')  define(`v048',`%f30')
  84. define(`v064',`%f44')  define(`v080',`%f46')
  85. define(`v096',`%f48')  define(`v112',`%f50')
  86. define(`u00',`%f32')   define(`u32', `%f34')
  87. define(`a000',`%f36')  define(`a016',`%f38')
  88. define(`a032',`%f40')  define(`a048',`%f42')
  89. define(`a064',`%f60')  define(`a080',`%f62')
  90. define(`u00_hi',`%f2') define(`u32_hi',`%f4')
  91. define(`u00_lo',`%f3') define(`u32_lo',`%f5')
  92. define(`cy',`%g1')
  93. define(`rlimb',`%g3')
  94. define(`i00',`%l0')    define(`i16',`%l1')
  95. define(`r00',`%l2')    define(`r32',`%l3')
  96. define(`xffffffff',`%l7')
  97. define(`xffff',`%o0')
  98. PROLOGUE(mpn_addmul_2)
  99. C Initialization.  (1) Split v operand into eight 16-bit chunks and store them
  100. C as IEEE double in fp registers.  (2) Clear upper 32 bits of fp register pairs
  101. C f2 and f4.  (3) Store masks in registers aliased to `xffff' and `xffffffff'.
  102. C This code could be better scheduled.
  103. save %sp, -256, %sp
  104. ifdef(`HAVE_VIS',
  105. ` mov -1, %g4
  106. wr %g0, 0xD2, %asi
  107. srlx %g4, 32, xffffffff C store mask in register `xffffffff'
  108. ldda [%i3+6] %asi, v000
  109. ldda [%i3+4] %asi, v016
  110. ldda [%i3+2] %asi, v032
  111. ldda [%i3+0] %asi, v048
  112. fxtod v000, v000
  113. ldda [%i3+14] %asi, v064
  114. fxtod v016, v016
  115. ldda [%i3+12] %asi, v080
  116. fxtod v032, v032
  117. ldda [%i3+10] %asi, v096
  118. fxtod v048, v048
  119. ldda [%i3+8] %asi, v112
  120. fxtod v064, v064
  121. fxtod v080, v080
  122. fxtod v096, v096
  123. fxtod v112, v112
  124. fzero u00_hi
  125. fzero u32_hi
  126. ',
  127. ` mov -1, %g4
  128. ldx [%i3+0], %l0 C vp[0]
  129. srlx %g4, 48, xffff C store mask in register `xffff'
  130. ldx [%i3+8], %l1 C vp[1]
  131. and %l0, xffff, %g2
  132. stx %g2, [%sp+2223+0]
  133. srlx %l0, 16, %g3
  134. and %g3, xffff, %g3
  135. stx %g3, [%sp+2223+8]
  136. srlx %l0, 32, %g2
  137. and %g2, xffff, %g2
  138. stx %g2, [%sp+2223+16]
  139. srlx %l0, 48, %g3
  140. stx %g3, [%sp+2223+24]
  141. and %l1, xffff, %g2
  142. stx %g2, [%sp+2223+32]
  143. srlx %l1, 16, %g3
  144. and %g3, xffff, %g3
  145. stx %g3, [%sp+2223+40]
  146. srlx %l1, 32, %g2
  147. and %g2, xffff, %g2
  148. stx %g2, [%sp+2223+48]
  149. srlx %l1, 48, %g3
  150. stx %g3, [%sp+2223+56]
  151. srlx %g4, 32, xffffffff C store mask in register `xffffffff'
  152. ldd [%sp+2223+0], v000
  153. ldd [%sp+2223+8], v016
  154. ldd [%sp+2223+16], v032
  155. ldd [%sp+2223+24], v048
  156. fxtod v000, v000
  157. ldd [%sp+2223+32], v064
  158. fxtod v016, v016
  159. ldd [%sp+2223+40], v080
  160. fxtod v032, v032
  161. ldd [%sp+2223+48], v096
  162. fxtod v048, v048
  163. ldd [%sp+2223+56], v112
  164. fxtod v064, v064
  165. ld [%sp+2223+0], u00_hi C zero u00_hi
  166. fxtod v080, v080
  167. ld [%sp+2223+0], u32_hi C zero u32_hi
  168. fxtod v096, v096
  169. fxtod v112, v112
  170. ')
  171. C Initialization done.
  172. mov 0, %g2
  173. mov 0, rlimb
  174. mov 0, %g4
  175. add %i0, -8, %i0 C BOOKKEEPING
  176. C Start software pipeline.
  177. ld [%i1+4], u00_lo C read low 32 bits of up[i]
  178. fxtod u00_hi, u00
  179. C mid
  180. ld [%i1+0], u32_lo C read high 32 bits of up[i]
  181. fmuld u00, v000, a000
  182. fmuld u00, v016, a016
  183. fmuld u00, v032, a032
  184. fmuld u00, v048, a048
  185. add %i2, -1, %i2 C BOOKKEEPING
  186. fmuld u00, v064, p064
  187. add %i1, 8, %i1 C BOOKKEEPING
  188. fxtod u32_hi, u32
  189. fmuld u00, v080, p080
  190. fmuld u00, v096, p096a
  191. brnz,pt %i2, .L_2_or_more
  192.  fmuld u00, v112, p112a
  193. .L1: fdtox a000, out000
  194. fmuld u32, v000, p000
  195. fdtox a016, out016
  196. fmuld u32, v016, p016
  197. fmovd p064, a064
  198. fmuld u32, v032, p032
  199. fmovd p080, a080
  200. fmuld u32, v048, p048
  201. std out000, [%sp+2223+16]
  202. faddd p000, a032, a000
  203. fmuld u32, v064, p064
  204. std out016, [%sp+2223+24]
  205. fxtod u00_hi, u00
  206. faddd p016, a048, a016
  207. fmuld u32, v080, p080
  208. faddd p032, a064, a032
  209. fmuld u32, v096, p096b
  210. faddd p048, a080, a048
  211. fmuld u32, v112, p112b
  212. C mid
  213. fdtox a000, out000
  214. fdtox a016, out016
  215. faddd p064, p096a, a064
  216. faddd p080, p112a, a080
  217. std out000, [%sp+2223+0]
  218. b .L_wd2
  219.  std out016, [%sp+2223+8]
  220. .L_2_or_more:
  221. ld [%i1+4], u00_lo C read low 32 bits of up[i]
  222. fdtox a000, out000
  223. fmuld u32, v000, p000
  224. fdtox a016, out016
  225. fmuld u32, v016, p016
  226. fmovd p064, a064
  227. fmuld u32, v032, p032
  228. fmovd p080, a080
  229. fmuld u32, v048, p048
  230. std out000, [%sp+2223+16]
  231. faddd p000, a032, a000
  232. fmuld u32, v064, p064
  233. std out016, [%sp+2223+24]
  234. fxtod u00_hi, u00
  235. faddd p016, a048, a016
  236. fmuld u32, v080, p080
  237. faddd p032, a064, a032
  238. fmuld u32, v096, p096b
  239. faddd p048, a080, a048
  240. fmuld u32, v112, p112b
  241. C mid
  242. ld [%i1+0], u32_lo C read high 32 bits of up[i]
  243. fdtox a000, out000
  244. fmuld u00, v000, p000
  245. fdtox a016, out016
  246. fmuld u00, v016, p016
  247. faddd p064, p096a, a064
  248. fmuld u00, v032, p032
  249. faddd p080, p112a, a080
  250. fmuld u00, v048, p048
  251. add %i2, -1, %i2 C BOOKKEEPING
  252. std out000, [%sp+2223+0]
  253. faddd p000, a032, a000
  254. fmuld u00, v064, p064
  255. add %i1, 8, %i1 C BOOKKEEPING
  256. std out016, [%sp+2223+8]
  257. fxtod u32_hi, u32
  258. faddd p016, a048, a016
  259. fmuld u00, v080, p080
  260. faddd p032, a064, a032
  261. fmuld u00, v096, p096a
  262. faddd p048, a080, a048
  263. brnz,pt %i2, .L_3_or_more
  264.  fmuld u00, v112, p112a
  265. b .Lend
  266.  nop
  267. C  64      32       0
  268. C   .       .       .
  269. C   .       |__rXXX_| 32
  270. C   .      |___cy___| 34
  271. C   .  |_______i00__| 50
  272. C  |_______i16__|   . 50
  273. C BEGIN MAIN LOOP
  274. .align 16
  275. .L_3_or_more:
  276. .Loop: ld [%i1+4], u00_lo C read low 32 bits of up[i]
  277. and %g2, xffffffff, %g2
  278. fdtox a000, out000
  279. fmuld u32, v000, p000
  280. C
  281. lduw [%i0+4+8], r00 C read low 32 bits of rp[i]
  282. add %g2, rlimb, %l5
  283. fdtox a016, out016
  284. fmuld u32, v016, p016
  285. C
  286. srlx %l5, 32, cy
  287. ldx [%sp+2223+16], i00
  288. faddd p064, p096b, a064
  289. fmuld u32, v032, p032
  290. C
  291. add %g4, cy, cy C new cy
  292. ldx [%sp+2223+24], i16
  293. faddd p080, p112b, a080
  294. fmuld u32, v048, p048
  295. C
  296. nop
  297. std out000, [%sp+2223+16]
  298. faddd p000, a032, a000
  299. fmuld u32, v064, p064
  300. C
  301. add i00, r00, rlimb
  302. add %i0, 8, %i0 C BOOKKEEPING
  303. std out016, [%sp+2223+24]
  304. fxtod u00_hi, u00
  305. C
  306. sllx i16, 16, %g2
  307. add cy, rlimb, rlimb
  308. faddd p016, a048, a016
  309. fmuld u32, v080, p080
  310. C
  311. srlx i16, 16, %g4
  312. add %g2, rlimb, %l5
  313. faddd p032, a064, a032
  314. fmuld u32, v096, p096b
  315. C
  316. stw %l5, [%i0+4]
  317. nop
  318. faddd p048, a080, a048
  319. fmuld u32, v112, p112b
  320. C midloop
  321. ld [%i1+0], u32_lo C read high 32 bits of up[i]
  322. and %g2, xffffffff, %g2
  323. fdtox a000, out000
  324. fmuld u00, v000, p000
  325. C
  326. lduw [%i0+0], r32 C read high 32 bits of rp[i]
  327. add %g2, rlimb, %l5
  328. fdtox a016, out016
  329. fmuld u00, v016, p016
  330. C
  331. srlx %l5, 32, cy
  332. ldx [%sp+2223+0], i00
  333. faddd p064, p096a, a064
  334. fmuld u00, v032, p032
  335. C
  336. add %g4, cy, cy C new cy
  337. ldx [%sp+2223+8], i16
  338. faddd p080, p112a, a080
  339. fmuld u00, v048, p048
  340. C
  341. add %i2, -1, %i2 C BOOKKEEPING
  342. std out000, [%sp+2223+0]
  343. faddd p000, a032, a000
  344. fmuld u00, v064, p064
  345. C
  346. add i00, r32, rlimb
  347. add %i1, 8, %i1 C BOOKKEEPING
  348. std out016, [%sp+2223+8]
  349. fxtod u32_hi, u32
  350. C
  351. sllx i16, 16, %g2
  352. add cy, rlimb, rlimb
  353. faddd p016, a048, a016
  354. fmuld u00, v080, p080
  355. C
  356. srlx i16, 16, %g4
  357. add %g2, rlimb, %l5
  358. faddd p032, a064, a032
  359. fmuld u00, v096, p096a
  360. C
  361. stw %l5, [%i0+0]
  362. faddd p048, a080, a048
  363. brnz,pt %i2, .Loop
  364.  fmuld u00, v112, p112a
  365. C END MAIN LOOP
  366. C WIND-DOWN PHASE 1
  367. .Lend: and %g2, xffffffff, %g2
  368. fdtox a000, out000
  369. fmuld u32, v000, p000
  370. lduw [%i0+4+8], r00 C read low 32 bits of rp[i]
  371. add %g2, rlimb, %l5
  372. fdtox a016, out016
  373. fmuld u32, v016, p016
  374. srlx %l5, 32, cy
  375. ldx [%sp+2223+16], i00
  376. faddd p064, p096b, a064
  377. fmuld u32, v032, p032
  378. add %g4, cy, cy C new cy
  379. ldx [%sp+2223+24], i16
  380. faddd p080, p112b, a080
  381. fmuld u32, v048, p048
  382. std out000, [%sp+2223+16]
  383. faddd p000, a032, a000
  384. fmuld u32, v064, p064
  385. add i00, r00, rlimb
  386. add %i0, 8, %i0 C BOOKKEEPING
  387. std out016, [%sp+2223+24]
  388. sllx i16, 16, %g2
  389. add cy, rlimb, rlimb
  390. faddd p016, a048, a016
  391. fmuld u32, v080, p080
  392. srlx i16, 16, %g4
  393. add %g2, rlimb, %l5
  394. faddd p032, a064, a032
  395. fmuld u32, v096, p096b
  396. stw %l5, [%i0+4]
  397. faddd p048, a080, a048
  398. fmuld u32, v112, p112b
  399. C mid
  400. and %g2, xffffffff, %g2
  401. fdtox a000, out000
  402. lduw [%i0+0], r32 C read high 32 bits of rp[i]
  403. add %g2, rlimb, %l5
  404. fdtox a016, out016
  405. srlx %l5, 32, cy
  406. ldx [%sp+2223+0], i00
  407. faddd p064, p096a, a064
  408. add %g4, cy, cy C new cy
  409. ldx [%sp+2223+8], i16
  410. faddd p080, p112a, a080
  411. std out000, [%sp+2223+0]
  412. add i00, r32, rlimb
  413. std out016, [%sp+2223+8]
  414. sllx i16, 16, %g2
  415. add cy, rlimb, rlimb
  416. srlx i16, 16, %g4
  417. add %g2, rlimb, %l5
  418. stw %l5, [%i0+0]
  419. C WIND-DOWN PHASE 2
  420. .L_wd2: and %g2, xffffffff, %g2
  421. fdtox a032, out000
  422. lduw [%i0+4+8], r00 C read low 32 bits of rp[i]
  423. add %g2, rlimb, %l5
  424. fdtox a048, out016
  425. srlx %l5, 32, cy
  426. ldx [%sp+2223+16], i00
  427. add %g4, cy, cy C new cy
  428. ldx [%sp+2223+24], i16
  429. std out000, [%sp+2223+16]
  430. add i00, r00, rlimb
  431. add %i0, 8, %i0 C BOOKKEEPING
  432. std out016, [%sp+2223+24]
  433. sllx i16, 16, %g2
  434. add cy, rlimb, rlimb
  435. srlx i16, 16, %g4
  436. add %g2, rlimb, %l5
  437. stw %l5, [%i0+4]
  438. C mid
  439. and %g2, xffffffff, %g2
  440. fdtox a064, out000
  441. lduw [%i0+0], r32 C read high 32 bits of rp[i]
  442. add %g2, rlimb, %l5
  443. fdtox a080, out016
  444. srlx %l5, 32, cy
  445. ldx [%sp+2223+0], i00
  446. add %g4, cy, cy C new cy
  447. ldx [%sp+2223+8], i16
  448. std out000, [%sp+2223+0]
  449. add i00, r32, rlimb
  450. std out016, [%sp+2223+8]
  451. sllx i16, 16, %g2
  452. add cy, rlimb, rlimb
  453. srlx i16, 16, %g4
  454. add %g2, rlimb, %l5
  455. stw %l5, [%i0+0]
  456. C WIND-DOWN PHASE 3
  457. .L_wd3: and %g2, xffffffff, %g2
  458. fdtox p096b, out000
  459. add %g2, rlimb, %l5
  460. fdtox p112b, out016
  461. srlx %l5, 32, cy
  462. ldx [%sp+2223+16], rlimb
  463. add %g4, cy, cy C new cy
  464. ldx [%sp+2223+24], i16
  465. std out000, [%sp+2223+16]
  466. add %i0, 8, %i0 C BOOKKEEPING
  467. std out016, [%sp+2223+24]
  468. sllx i16, 16, %g2
  469. add cy, rlimb, rlimb
  470. srlx i16, 16, %g4
  471. add %g2, rlimb, %l5
  472. stw %l5, [%i0+4]
  473. C mid
  474. and %g2, xffffffff, %g2
  475. add %g2, rlimb, %l5
  476. srlx %l5, 32, cy
  477. ldx [%sp+2223+0], rlimb
  478. add %g4, cy, cy C new cy
  479. ldx [%sp+2223+8], i16
  480. sllx i16, 16, %g2
  481. add cy, rlimb, rlimb
  482. srlx i16, 16, %g4
  483. add %g2, rlimb, %l5
  484. stw %l5, [%i0+0]
  485. and %g2, xffffffff, %g2
  486. add %g2, rlimb, %l5
  487. srlx %l5, 32, cy
  488. ldx [%sp+2223+16], i00
  489. add %g4, cy, cy C new cy
  490. ldx [%sp+2223+24], i16
  491. sllx i16, 16, %g2
  492. add i00, cy, cy
  493. return %i7+8
  494. add %g2, cy, %o0
  495. EPILOGUE(mpn_addmul_2)