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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD64 mpn_bdiv_q_1, mpn_pi1_bdiv_q_1 -- schoolbook Hensel division by
  2. dnl  1-limb divisor, returning quotient only.
  3. dnl  Copyright 2001, 2002, 2004, 2005, 2006, 2009 Free Software Foundation,
  4. dnl  Inc.
  5. dnl  This file is part of the GNU MP Library.
  6. dnl  The GNU MP Library is free software; you can redistribute it and/or modify
  7. dnl  it under the terms of the GNU Lesser General Public License as published
  8. dnl  by the Free Software Foundation; either version 3 of the License, or (at
  9. dnl  your option) any later version.
  10. dnl The GNU MP Library is distributed in the hope that it will be useful, but
  11. dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  13. dnl  License for more details.
  14. dnl  You should have received a copy of the GNU Lesser General Public License
  15. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  16. include(`../config.m4')
  17. C      cycles/limb
  18. C K8,K9: 10
  19. C K10: 10
  20. C P4: 33
  21. C P6 core2: 13.25
  22. C P6 corei7: 14
  23. C P6 atom: 42
  24. C INPUT PARAMETERS
  25. C rp rdi
  26. C up rsi
  27. C n rdx
  28. C d rcx
  29. C di r8 just mpn_pi1_bdiv_q_1
  30. C shift r9 just mpn_pi1_bdiv_q_1
  31. ASM_START()
  32. TEXT
  33. ALIGN(16)
  34. PROLOGUE(mpn_bdiv_q_1)
  35. push %rbx
  36. mov %rcx, %rax
  37. xor R32(%rcx), R32(%rcx) C shift count
  38. mov %rdx, %r10
  39. bt $0, R32(%rax)
  40. jnc L(evn) C skip bsfq unless divisor is even
  41. L(odd): mov %rax, %rbx
  42. shr R32(%rax)
  43. and $127, R32(%rax) C d/2, 7 bits
  44. ifdef(`PIC',`
  45. mov binvert_limb_table@GOTPCREL(%rip), %rdx
  46. ',`
  47. movabs $binvert_limb_table, %rdx
  48. ')
  49. movzbl (%rdx,%rax), R32(%rax) C inv 8 bits
  50. mov %rbx, %r11 C d without twos
  51. lea (%rax,%rax), R32(%rdx) C 2*inv
  52. imul R32(%rax), R32(%rax) C inv*inv
  53. imul R32(%rbx), R32(%rax) C inv*inv*d
  54. sub R32(%rax), R32(%rdx) C inv = 2*inv - inv*inv*d, 16 bits
  55. lea (%rdx,%rdx), R32(%rax) C 2*inv
  56. imul R32(%rdx), R32(%rdx) C inv*inv
  57. imul R32(%rbx), R32(%rdx) C inv*inv*d
  58. sub R32(%rdx), R32(%rax) C inv = 2*inv - inv*inv*d, 32 bits
  59. lea (%rax,%rax), %r8 C 2*inv
  60. imul %rax, %rax C inv*inv
  61. imul %rbx, %rax C inv*inv*d
  62. sub %rax, %r8 C inv = 2*inv - inv*inv*d, 64 bits
  63. jmp L(com)
  64. L(evn): bsf %rax, %rcx
  65. shr R8(%rcx), %rax
  66. jmp L(odd)
  67. EPILOGUE()
  68. PROLOGUE(mpn_pi1_bdiv_q_1)
  69. push %rbx
  70. mov %rcx, %r11 C d
  71. mov %rdx, %r10 C n
  72. mov %r9, %rcx C shift
  73. L(com):
  74. mov (%rsi), %rax C up[0]
  75. dec %r10
  76. jz L(one)
  77. mov 8(%rsi), %rdx C up[1]
  78. lea (%rsi,%r10,8), %rsi C up end
  79. lea (%rdi,%r10,8), %rdi C rp end
  80. neg %r10 C -n
  81. shrd R8(%rcx), %rdx, %rax
  82. xor R32(%rbx), R32(%rbx)
  83. jmp L(ent)
  84. ALIGN(8)
  85. L(top):
  86. C rax q
  87. C rbx carry bit, 0 or 1
  88. C rcx shift
  89. C rdx
  90. C rsi up end
  91. C rdi rp end
  92. C r10 counter, limbs, negative
  93. mul %r11 C carry limb in rdx
  94. mov (%rsi,%r10,8), %rax
  95. mov 8(%rsi,%r10,8), %r9
  96. shrd R8(%rcx), %r9, %rax
  97. nop
  98. sub %rbx, %rax C apply carry bit
  99. setc R8(%rbx)
  100. sub %rdx, %rax C apply carry limb
  101. adc $0, %rbx
  102. L(ent): imul %r8, %rax
  103. mov %rax, (%rdi,%r10,8)
  104. inc %r10
  105. jnz L(top)
  106. mul %r11 C carry limb in rdx
  107. mov (%rsi), %rax C up high limb
  108. shr R8(%rcx), %rax
  109. sub %rbx, %rax C apply carry bit
  110. sub %rdx, %rax C apply carry limb
  111. imul %r8, %rax
  112. mov %rax, (%rdi)
  113. pop %rbx
  114. ret
  115. L(one): shr R8(%rcx), %rax
  116. imul %r8, %rax
  117. mov %rax, (%rdi)
  118. pop %rbx
  119. ret
  120. EPILOGUE()