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

数学计算

开发平台:

Unix_Linux

  1. dnl  x86-64 mpn_divrem_1 -- mpn by limb division.
  2. dnl  Copyright 2004, 2005, 2007, 2008, 2009 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 norm unorm frac
  16. C K8 13 13 12
  17. C P4 44.2 44.2 42.3
  18. C P6 core2 25 24.5 19.3
  19. C P6 corei7 21.5 20.7 18
  20. C P6 atom 42 52 37
  21. C TODO
  22. C  * Compute the inverse without relying on the div instruction.
  23. C    Newton's method and mulq, or perhaps the faster fdiv.
  24. C  * Tune prologue.
  25. C  * Optimize for Core 2.
  26. C The code for unnormalized divisors works also for normalized divisors, but
  27. C for some reason it runs really slowly (on K8) for that case.  Use special
  28. C code until we can address this.  The Intel Atom is also affected, but
  29. C understandably (shld slowness).
  30. define(`SPECIAL_CODE_FOR_NORMALIZED_DIVISOR',1)
  31. C mp_limb_t
  32. C mpn_divrem_1 (mp_ptr qp, mp_size_t fn,
  33. C               mp_srcptr np, mp_size_t nn, mp_limb_t d)
  34. C mp_limb_t
  35. C mpn_preinv_divrem_1 (mp_ptr qp, mp_size_t fn,
  36. C                      mp_srcptr np, mp_size_t nn, mp_limb_t d,
  37. C                      mp_limb_t dinv, int cnt)
  38. C INPUT PARAMETERS
  39. define(`qp', `%rdi')
  40. define(`fn_param', `%rsi')
  41. define(`up_param', `%rdx')
  42. define(`un_param', `%rcx')
  43. define(`d', `%r8')
  44. define(`dinv', `%r9') C only for mpn_preinv_divrem_1
  45. C       shift passed on stack C only for mpn_preinv_divrem_1
  46. define(`cnt', `%rcx')
  47. define(`up', `%rsi')
  48. define(`fn', `%r12')
  49. define(`un', `%rbx')
  50. C rax rbx rcx rdx rsi rdi rbp r8  r9  r10 r11 r12 r13 r14 r15
  51. C         cnt         qp      d  dinv
  52. ASM_START()
  53. TEXT
  54. ALIGN(16)
  55. PROLOGUE(mpn_preinv_divrem_1)
  56. xor %eax, %eax
  57. push %r13
  58. push %r12
  59. push %rbp
  60. push %rbx
  61. mov fn_param, fn
  62. mov un_param, un
  63. add fn_param, un_param
  64. mov up_param, up
  65. lea -8(qp,un_param,8), qp
  66. test d, d
  67. js L(nent)
  68. mov 40(%rsp), R8(cnt)
  69. shl R8(cnt), d
  70. jmp L(uent)
  71. EPILOGUE()
  72. ALIGN(16)
  73. PROLOGUE(mpn_divrem_1)
  74. xor %eax, %eax
  75. push %r13
  76. push %r12
  77. push %rbp
  78. push %rbx
  79. mov fn_param, fn
  80. mov un_param, un
  81. add fn_param, un_param
  82. mov up_param, up
  83. je L(ret)
  84. lea -8(qp,un_param,8), qp
  85. xor R32(%rbp), R32(%rbp)
  86. ifdef(`SPECIAL_CODE_FOR_NORMALIZED_DIVISOR',`
  87. test d, d
  88. jns L(unnormalized)
  89. L(normalized):
  90. test un, un
  91. je L(8) C un == 0
  92. mov -8(up,un,8), %rbp
  93. dec un
  94. mov %rbp, %rax
  95. sub d, %rbp
  96. cmovb %rax, %rbp
  97. sbb %eax, %eax
  98. inc %eax
  99. mov %rax, (qp)
  100. lea -8(qp), qp
  101. L(8):
  102. mov d, %rdx
  103. mov $-1, %rax
  104. not %rdx
  105. div d C FREE rax rdx rcx r9 r10 r11
  106. mov %rax, dinv
  107. mov %rbp, %rax
  108. jmp L(nent)
  109. ALIGN(16)
  110. L(nloop): C     cycK8  cycP6  cycP4
  111. mov (up,un,8), %r10 C
  112. lea 1(%rax), %rbp C
  113. mul dinv C      0,13   0,19  0,45
  114. add %r10, %rax C      4      8     12
  115. adc %rbp, %rdx C      5      9     13
  116. mov %rax, %rbp C      5      9     13
  117. mov %rdx, %r13 C      6      11    23
  118. imul d, %rdx C      6      11    23
  119. sub %rdx, %r10 C      10     16    33
  120. mov d, %rax C
  121. add %r10, %rax C      11     17    34
  122. cmp %rbp, %r10 C      11     17    34
  123. cmovb %r10, %rax C      12     18    35
  124. adc $-1, %r13 C
  125. cmp d, %rax C
  126. jae L(nfx) C
  127. L(nok): mov %r13, (qp) C
  128. sub $8, qp C
  129. L(nent):dec un C
  130. jns L(nloop) C
  131. xor %ecx, %ecx
  132. jmp L(87)
  133. L(nfx): sub d, %rax
  134. inc %r13
  135. jmp L(nok)
  136. ')
  137. L(unnormalized):
  138. test un, un
  139. je L(44)
  140. mov -8(up,un,8), %rax
  141. cmp d, %rax
  142. jae L(44)
  143. mov %rbp, (qp)
  144. mov %rax, %rbp
  145. lea -8(qp), qp
  146. je L(ret)
  147. dec un
  148. L(44):
  149. bsr d, %rcx
  150. not %ecx
  151. sal %cl, d
  152. sal %cl, %rbp
  153. mov d, %rdx
  154. mov $-1, %rax
  155. not %rdx
  156. div d C FREE rax rdx r9 r10 r11
  157. test un, un
  158. mov %rax, dinv
  159. mov %rbp, %rax
  160. je L(87)
  161. L(uent):
  162. mov -8(up,un,8), %rbp
  163. shr %cl, %rax
  164. shld %cl, %rbp, %rax
  165. sub $2, un
  166. js L(ulast)
  167. ALIGN(16)
  168. L(uloop):
  169. nop
  170. mov (up,un,8), %r10
  171. lea 1(%rax), %r11
  172. shld %cl, %r10, %rbp
  173. mul dinv
  174. add %rbp, %rax
  175. adc %r11, %rdx
  176. mov %rax, %r11
  177. mov %rdx, %r13
  178. imul d, %rdx
  179. sub %rdx, %rbp
  180. mov d, %rax
  181. add %rbp, %rax
  182. cmp %r11, %rbp
  183. cmovb %rbp, %rax
  184. adc $-1, %r13
  185. cmp d, %rax
  186. jae L(ufx)
  187. L(uok): mov %r13, (qp)
  188. sub $8, qp
  189. dec un
  190. mov %r10, %rbp
  191. jns L(uloop)
  192. L(ulast):
  193. lea 1(%rax), %r11
  194. sal %cl, %rbp
  195. mul dinv
  196. add %rbp, %rax
  197. adc %r11, %rdx
  198. mov %rax, %r11
  199. mov %rdx, %r13
  200. imul d, %rdx
  201. sub %rdx, %rbp
  202. mov d, %rax
  203. add %rbp, %rax
  204. cmp %r11, %rbp
  205. cmovb %rbp, %rax
  206. adc $-1, %r13
  207. cmp d, %rax
  208. jae L(93)
  209. L(69): mov %r13, (qp)
  210. sub $8, qp
  211. jmp L(87)
  212. L(ufx): sub d, %rax
  213. inc %r13
  214. jmp L(uok)
  215. L(93): sub d, %rax
  216. inc %r13
  217. jmp L(69)
  218. L(87): mov d, %rbp
  219. neg %rbp
  220. jmp L(87b)
  221. ALIGN(16)
  222. L(floop): C     cycK8  cycP6  cycP4
  223. lea 1(%rax), %r11 C
  224. mul dinv C      0,12
  225. add %r11, %rdx C      5
  226. mov %rax, %r11 C      4
  227. mov %rdx, %r13 C      6
  228. imul %rbp, %rdx C      6
  229. mov d, %rax C
  230. add %rdx, %rax C      10
  231. cmp %r11, %rdx C      10
  232. cmovb %rdx, %rax C      11
  233. adc $-1, %r13 C
  234. mov %r13, (qp) C
  235. sub $8, qp C
  236. L(87b): dec fn C
  237. jns L(floop) C
  238. shr %cl, %rax
  239. L(ret): pop %rbx
  240. pop %rbp
  241. pop %r12
  242. pop %r13
  243. ret
  244. EPILOGUE()