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

数学计算

开发平台:

Unix_Linux

  1. dnl  IA-64 mpn_divrem_2 -- Divide an n-limb number by a 2-limb number.
  2. dnl  Copyright 2004, 2005 Free Software Foundation, Inc.
  3. dnl  This file is part of the GNU MP Library.
  4. dnl  The GNU MP Library is free software; you can redistribute it and/or modify
  5. dnl  it under the terms of the GNU Lesser General Public License as published
  6. dnl  by the Free Software Foundation; either version 3 of the License, or (at
  7. dnl  your option) any later version.
  8. dnl  The GNU MP Library is distributed in the hope that it will be useful, but
  9. dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  11. dnl  License for more details.
  12. dnl  You should have received a copy of the GNU Lesser General Public License
  13. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  14. include(`../config.m4')
  15. C         cycles/limb
  16. C Itanium:    63
  17. C Itanium 2:  46
  18. C TODO
  19. C  * Further optimize the loop.  We could probably do some more trickery with
  20. C    arithmetic in the FPU, or perhaps use a non-zero addend of xma in more
  21. C    places.
  22. C  * Software pipeline for perhaps 5 saved cycles, around the end and start of
  23. C    the loop.
  24. C  * Schedule code outside of loop better.
  25. C  * Update the comments.  They are now using the same name for the same
  26. C    logical quantity.
  27. C  * Handle conditional zeroing of r31 in loop more cleanly.
  28. C  * Inline mpn_invert_limb and schedule its insns across the entire init code.
  29. C  * Ultimately, use 2-limb, or perhaps 3-limb or 4-limb inverse.
  30. define(`qp',`r32')
  31. define(`qxn',`r33')
  32. define(`np',`r34')
  33. define(`nn',`r35')
  34. define(`dp',`r36')
  35. define(`fnh',`f11')
  36. define(`fminus1',`f10')
  37. define(`fd0',`f13')
  38. define(`fd1',`f14')
  39. define(`d0',`r39')
  40. define(`d1',`r36')
  41. define(`fnl',`f32')
  42. define(`fdinv',`f12')
  43. define(`R1',`r38') define(`R0',`r37')
  44. define(`P1',`r28') define(`P0',`r27')
  45. ASM_START()
  46. C HP's assembler requires these declarations for importing mpn_invert_limb
  47. .global mpn_invert_limb
  48. .type mpn_invert_limb,@function
  49. PROLOGUE(mpn_divrem_2)
  50. .prologue
  51. .save ar.pfs, r42
  52. .save ar.lc, r44
  53. .save rp, r41
  54. ifdef(`HAVE_ABI_32',
  55. ` addp4 qp = 0, qp C M I
  56. addp4 np = 0, np C M I
  57. addp4 dp = 0, dp C M I
  58. zxt4 nn = nn C I
  59. zxt4 qxn = qxn C I
  60. ;;
  61. ')
  62. alloc r42 = ar.pfs, 5,8,1,0 C M2
  63. ld8 d0 = [dp], 8 C M0M1 d0
  64. mov r44 = ar.lc C I0
  65. shladd np = nn, 3, np C M I
  66. ;;
  67. ld8 d1 = [dp] C M0M1 d1
  68. mov r41 = b0 C I0
  69. add r15 = -8, np C M I
  70. add np = -16, np C M I
  71. mov r40 = r0 C M I
  72. ;;
  73. ld8 R1 = [r15] C M0M1 n1
  74. ld8 R0 = [r34], -8 C M0M1 n0
  75. ;;
  76. cmp.ltu p6, p0 = d1, R1 C M I
  77. cmp.eq p8, p0 = d1, R1 C M I
  78. ;;
  79.   (p8) cmp.leu p6, p0 = d0, R0
  80. cmp.ltu p8, p9 = R0, d0
  81.   (p6) br.cond.dpnt .L_high_limb_1 C FIXME: inline!
  82. .L8:
  83. mov r45 = d1
  84. br.call.sptk.many b0 = mpn_invert_limb C FIXME: inline+schedule
  85. ;;
  86. setf.sig fd1 = d1 C d1
  87. setf.sig fd0 = d0 C d0
  88. add r14 = r33, r35 C nn + qxn
  89. ;;
  90. setf.sig fdinv = r8 C dinv
  91. mov r9 = -1
  92. add r35 = -3, r14
  93. ;;
  94. setf.sig fminus1 = r9
  95. cmp.gt p6, p0 = r0, r35
  96. shladd qp = r35, 3, qp
  97. mov ar.lc = r35
  98. mov r31 = 0 C n0
  99.   (p6) br.cond.dpnt .Ldone
  100. ;;
  101. ALIGN(16)
  102. C *** MAIN LOOP START ***
  103. .Loop: C 00
  104. mov r15 = R0 C nadj = n10
  105. cmp.le p14, p15 = 0, R0 C check high bit of R0
  106. cmp.le p8, p0 = r33, r35 C dividend limbs remaining?
  107. ;; C 01
  108. .pred.rel "mutex", p14, p15
  109.   (p8) ld8 r31 = [r34], -8 C n0
  110.   (p15) add r15 = d1, R0 C nadj = n10 + d1
  111.   (p15) add r14 = 1, R1 C nh + (nl:63)
  112.   (p14) mov r14 = R1 C nh
  113. cmp.eq p6, p0 = d1, R1 C nh == d1
  114.   (p6) br.cond.spnt .L_R1_eq_d1
  115. ;; C 02
  116. setf.sig f8 = r14 C n2 + (nl:63)
  117. setf.sig f15 = r15 C nadj
  118. sub r23 = -1, R1 C r23 = ~nh
  119. ;; C 03
  120. setf.sig fnh = r23
  121. setf.sig fnl = R0
  122. ;; C 08
  123. xma.hu f7 = fdinv, f8, f15 C xh = HI(dinv*(nh-nmask)+nadj)
  124. ;; C 12
  125. xma.l f7 = f7, fminus1, fnh C nh + xh
  126. ;; C 16
  127. getf.sig r14 = f7
  128. xma.hu f9 = f7, fd1, fnl C xh = HI(q1*d1+nl)
  129. xma.l f33 = f7, fd1, fnl C xh = LO(q1*d1+nl)
  130. ;; C 20
  131. getf.sig r16 = f9
  132. sub r24 = d1, R1
  133. C 21
  134. getf.sig r17 = f33
  135. ;; C 25
  136. cmp.eq p6, p7 = r16, r24
  137. ;; C 26
  138. .pred.rel "mutex", p6, p7
  139.   (p6) xma.l f8 = f7, fminus1, f0 C f8 = -f7
  140.   (p7) xma.l f8 = f7,fminus1,fminus1 C f8 = -f7-1
  141. ;; C 27
  142. .pred.rel "mutex", p6, p7
  143.   (p6) sub r18 = 0, r14 C q = -q1
  144.   (p7) sub r18 = -1, r14 C q = -q1-1
  145.   (p6) add r14 = 0, r17 C n1 = xl
  146.   (p7) add r14 = d1, r17 C n1 = xl + d1
  147. ;; C 30
  148. xma.hu f9 = fd0, f8, f0 C d0*(-f7-1) = -d0*f7-d0
  149. xma.l f35 = fd0, f8, f0
  150. ;; C 34
  151. getf.sig P1 = f9 C P1
  152. C 35
  153. getf.sig P0 = f35 C P0
  154. ;;
  155. .L_adj: C 40
  156. cmp.ltu p8, p0 = r31, P0 C p8 = cy from low limb
  157. cmp.ltu p6, p0 = r14, P1 C p6 = prel cy from high limb
  158. sub R0 = r31, P0
  159. sub R1 = r14, P1
  160. ;; C 41
  161.   (p8) cmp.eq.or p6, p0 = 0, R1 C p6 = final cy from high limb
  162.   (p8) add R1 = -1, R1
  163. cmp.ne p10, p0 = r0, r0 C clear p10 FIXME: use unc below!
  164. cmp.ne p13, p0 = r0, r0 C clear p13 FIXME: use unc below!
  165. ;; C 42
  166.   (p6) add R0 = R0, d0
  167.   (p6) add R1 = R1, d1
  168.   (p6) add r18 = -1, r18 C q--
  169. ;; C 43
  170.   (p6) cmp.ltu p10, p0 = R0, d0
  171.   (p6) cmp.ltu p0, p13 = R1, d1
  172. ;; C 44
  173.   (p10) cmp.ne.and p0, p13 = -1, R1 C p13 = !cy
  174.   (p10) add R1 = 1, R1
  175.   (p13) br.cond.spnt .L_two_too_big C jump if not cy
  176. ;; C 45
  177. st8 [qp] = r18, -8
  178. add r35 = -1, r35
  179. mov r31 = 0 C n0, next iteration
  180. br.cloop.sptk .Loop
  181. C *** MAIN LOOP END ***
  182. ;;
  183. .Ldone:
  184. mov r8 = r40
  185. mov b0 = r41
  186. add r21 = 8, r34
  187. add r22 = 16, r34
  188. ;;
  189. st8 [r21] = R0
  190. st8 [r22] = R1
  191. mov ar.pfs = r42
  192. mov ar.lc = r44
  193. br.ret.sptk.many b0
  194. .L_high_limb_1:
  195. .pred.rel "mutex", p8, p9
  196. sub R0 = R0, d0
  197.   (p8) sub R1 = R1, d1, 1
  198.   (p9) sub R1 = R1, d1
  199. mov r40 = 1
  200. br.sptk .L8
  201. ;;
  202. .L_two_too_big:
  203. add R0 = R0, d0
  204. add R1 = R1, d1
  205. ;;
  206. add r18 = -1, r18 C q--
  207. cmp.ltu p10, p0 = R0, d0
  208. ;;
  209.   (p10) add R1 = 1, R1
  210. st8 [qp] = r18, -8
  211. add r35 = -1, r35
  212. mov r31 = 0 C n0, next iteration
  213. br.cloop.sptk .Loop
  214. br.sptk .Ldone
  215. .L_R1_eq_d1:
  216. add r14 = R0, d1 C r = R0 + d1
  217. mov r18 = -1 C q = -1
  218. ;;
  219. cmp.leu p6, p0 = R0, r14
  220.  (p6) br.cond.spnt .L20 C jump unless cy
  221. ;;
  222. sub P1 = r14, d0
  223. add R0 = r31, d0
  224. ;;
  225. cmp.ltu p8, p9 = R0, r31
  226. ;;
  227. .pred.rel "mutex", p8, p9
  228. st8 [qp] = r18, -8
  229.   (p8) add R1 = r0, P1, 1 C R1 = n1 - P1 - cy
  230.   (p9) add R1 = r0, P1 C R1 = n1 - P1
  231. add r35 = -1, r35
  232. mov r31 = 0 C n0, next iteration
  233. br.cloop.sptk .Loop
  234. br.sptk .Ldone
  235. ;;
  236. .L20: cmp.ne p6, p7 = 0, d0
  237. ;;
  238. .pred.rel "mutex", p6, p7
  239.   (p6) add P1 = -1, d0
  240.   (p7) mov P1 = d0
  241. sub P0 = r0, d0
  242. br.sptk .L_adj
  243. EPILOGUE()
  244. ASM_END()