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

数学计算

开发平台:

Unix_Linux

  1. dnl  x86-64 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
  2. dnl  Copyright 2007, 2008 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 frac
  16. C K8 20 20
  17. C P4 73 73
  18. C P6 core2 37 37
  19. C P6 corei7 33 33
  20. C TODO
  21. C  * Perhaps compute the inverse without relying on divq?  Could either use
  22. C    Newton's method and mulq, or perhaps the faster fdiv.
  23. C  * The loop has not been carefully tuned, nor analysed for critical path
  24. C    length.  It seems that 20 c/l is a bit long, compared to the 13 c/l for
  25. C    mpn_divrem_1.
  26. C  * Clean up.  This code is really crude.
  27. C INPUT PARAMETERS
  28. define(`qp', `%rdi')
  29. define(`fn', `%rsi')
  30. define(`up_param', `%rdx')
  31. define(`un_param', `%rcx')
  32. define(`dp', `%r8')
  33. define(`dinv', `%r9')
  34. C rax rbx rcx rdx rsi rdi rbp r8  r9  r10 r11 r12 r13 r14 r15
  35. C         cnt         qp      d  dinv
  36. ASM_START()
  37. TEXT
  38. ALIGN(16)
  39. PROLOGUE(mpn_divrem_2)
  40. push %r15
  41. lea (%rdx,%rcx,8), %rax
  42. push %r14
  43. push %r13
  44. mov %rsi, %r13
  45. push %r12
  46. lea -24(%rax), %r12
  47. push %rbp
  48. mov %rdi, %rbp
  49. push %rbx
  50. mov 8(%r8), %r11
  51. mov -8(%rax), %r9
  52. mov (%r8), %r8
  53. mov -16(%rax), %r10
  54. xor R32(%r15), R32(%r15)
  55. cmp %r9, %r11
  56. ja L(2)
  57. setb %dl
  58. cmp %r10, %r8
  59. setbe %al
  60. or %al, %dl
  61. jne L(23)
  62. L(2):
  63. lea -3(%rcx,%r13), %rbx C un + fn - 3
  64. test %rbx, %rbx
  65. js L(6)
  66. mov %r11, %rdx
  67. mov $-1, %rax
  68. not %rdx
  69. div %r11
  70. mov %r11, %rdx
  71. mov %rax, %rdi
  72. imul %rax, %rdx
  73. mov %rdx, %r14
  74. mul %r8
  75. mov %rdx, %rcx
  76. mov $-1, %rdx
  77. add %r8, %r14
  78. adc $0, %rdx
  79. add %rcx, %r14
  80. adc $0, %rdx
  81. js L(8)
  82. L(18):
  83. dec %rdi
  84. sub %r11, %r14
  85. sbb $0, %rdx
  86. jns L(18)
  87. L(8):
  88. C rax rbx rcx rdx rsi rdi rbp r8 r9 r10 r11 r12 r13 r14 r15
  89. C n2      un      n1 dinv qp  d0        d1  up  fn      msl
  90. C     n2  un     -d1      n1    dinv XX              XX
  91. ifdef(`NEW',`
  92. lea (%rbp,%rbx,8), %rbp
  93. mov %rbx, %rcx C un
  94. mov %r9, %rbx
  95. mov %rdi, %r9 C di
  96. mov %r10, %r14
  97. mov %r11, %rsi
  98. neg %rsi C -d1
  99. ALIGN(16)
  100. L(loop):
  101. mov %r9, %rax C di ncp
  102. mul %rbx C 0, 18
  103. add %r14, %rax C 4
  104. mov %rax, %r10 C q0 5
  105. adc %rbx, %rdx C 5
  106. mov %rdx, %rdi C q 6
  107. imul %rsi, %rdx C 6
  108. mov %r8, %rax C ncp
  109. lea (%rdx, %r14), %rbx C n1 -= ... 7
  110. mul %rdi C 7
  111. xor R32(%r14), R32(%r14) C
  112. cmp %rcx, %r13 C
  113. jg L(19) C
  114. mov (%r12), %r14 C
  115. sub $8, %r12 C
  116. L(19): sub %r8, %r14 C ncp
  117. sbb %r11, %rbx C 9
  118. sub %rax, %r14 C 11
  119. sbb %rdx, %rbx C 12
  120. inc %rdi C 7
  121. xor R32(%rdx), R32(%rdx) C
  122. cmp %r10, %rbx C 13
  123. mov %r8, %rax C d0 ncp
  124. adc $-1, %rdx C mask 14
  125. add %rdx, %rdi C q-- 15
  126. and %rdx, %rax C d0 or 0 15
  127. and %r11, %rdx C d1 or 0 15
  128. add %rax, %r14 C 16
  129. adc %rdx, %rbx C 16
  130. cmp %r11, %rbx C 17
  131. jae L(fix) C
  132. L(bck): mov %rdi, (%rbp) C
  133. sub $8, %rbp C
  134. dec %rcx
  135. jns L(loop)
  136. mov %r14, %r10
  137. mov %rbx, %r9
  138. ',`
  139. lea (%rbp,%rbx,8), %rbp
  140. mov %rbx, %rcx
  141. mov %r9, %rax
  142. mov %r10, %rsi
  143. ALIGN(16)
  144. L(loop):
  145. mov %rax, %r14 C 0, 19
  146. mul %rdi C 0
  147. mov %r11, %r9 C 1
  148. add %rsi, %rax C 4
  149. mov %rax, %rbx C q0 5
  150. adc %r14, %rdx C q 5
  151. lea 1(%rdx), %r10 C 6
  152. mov %rdx, %rax C 6
  153. imul %rdx, %r9 C 6
  154. sub %r9, %rsi C 10
  155. xor R32(%r9), R32(%r9) C
  156. mul %r8 C 7
  157. cmp %rcx, %r13 C
  158. jg L(13) C
  159. mov (%r12), %r9 C
  160. sub $8, %r12 C
  161. L(13): sub %r8, %r9 C ncp
  162. sbb %r11, %rsi C 11
  163. sub %rax, %r9 C 11
  164. sbb %rdx, %rsi C 12
  165. cmp %rbx, %rsi C 13
  166. sbb %rax, %rax C 14
  167. not %rax C 15
  168. add %rax, %r10 C 16
  169. mov %r8, %rbx C ncp
  170. and %rax, %rbx C 16
  171. and %r11, %rax C 16
  172. add %rbx, %r9 C 17
  173. adc %rsi, %rax C 18
  174. cmp %rax, %r11 C 19
  175. jbe L(fix) C
  176. L(bck): mov %r10, (%rbp) C
  177. sub $8, %rbp C
  178. mov %r9, %rsi C 18
  179. dec %rcx
  180. jns L(loop)
  181. mov %rsi, %r10
  182. mov %rax, %r9
  183. ')
  184. L(6):
  185. mov %r10, 8(%r12)
  186. mov %r9, 16(%r12)
  187. pop %rbx
  188. pop %rbp
  189. pop %r12
  190. pop %r13
  191. pop %r14
  192. mov %r15, %rax
  193. pop %r15
  194. ret
  195. L(23): inc R32(%r15)
  196. sub %r8, %r10
  197. sbb %r11, %r9
  198. jmp L(2)
  199. ifdef(`NEW',`
  200. L(fix): seta %dl
  201. cmp %r8, %r14
  202. setae %al
  203. orb %dl, %al
  204. je L(bck)
  205. inc %rdi
  206. sub %r8, %r14
  207. sbb %r11, %rbx
  208. jmp L(bck)
  209. ',`
  210. L(fix): jb L(88)
  211. cmp %r8, %r9
  212. jb L(bck)
  213. L(88): inc %r10
  214. sub %r8, %r9
  215. sbb %r11, %rax
  216. jmp L(bck)
  217. ')
  218. EPILOGUE()