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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K7 mpn_divexact_1 -- mpn by limb exact division.
  2. dnl  Copyright 2001, 2002, 2004, 2007 Free Software Foundation, Inc.
  3. dnl
  4. dnl  This file is part of the GNU MP Library.
  5. dnl
  6. dnl  The GNU MP Library is free software; you can redistribute it and/or
  7. dnl  modify it under the terms of the GNU Lesser General Public License as
  8. dnl  published by the Free Software Foundation; either version 3 of the
  9. dnl  License, or (at your option) any later version.
  10. dnl
  11. dnl  The GNU MP Library is distributed in the hope that it will be useful,
  12. dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. dnl  Lesser General Public License for more details.
  15. dnl
  16. dnl  You should have received a copy of the GNU Lesser General Public License
  17. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  18. include(`../config.m4')
  19. C          cycles/limb
  20. C Athlon:     11.0
  21. C Hammer:      9.0
  22. C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
  23. C                      mp_limb_t divisor);
  24. C
  25. C The dependent chain is mul+imul+sub for 11 cycles and that speed is
  26. C achieved with no special effort.  The load and shrld latencies are hidden
  27. C by out of order execution.
  28. C
  29. C It's a touch faster on size==1 to use the mul-by-inverse than divl.
  30. defframe(PARAM_DIVISOR,16)
  31. defframe(PARAM_SIZE,   12)
  32. defframe(PARAM_SRC,    8)
  33. defframe(PARAM_DST,    4)
  34. defframe(SAVE_EBX,     -4)
  35. defframe(SAVE_ESI,     -8)
  36. defframe(SAVE_EDI,    -12)
  37. defframe(SAVE_EBP,    -16)
  38. defframe(VAR_INVERSE, -20)
  39. defframe(VAR_DST_END, -24)
  40. deflit(STACK_SPACE, 24)
  41. TEXT
  42. ALIGN(16)
  43. PROLOGUE(mpn_divexact_1)
  44. deflit(`FRAME',0)
  45. movl PARAM_DIVISOR, %eax
  46. subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
  47. movl $-1, %ecx C shift count
  48. movl %ebp, SAVE_EBP
  49. movl PARAM_SIZE, %ebp
  50. movl %esi, SAVE_ESI
  51. movl %edi, SAVE_EDI
  52. C If there's usually only one or two trailing zero bits then this
  53. C should be faster than bsfl.
  54. L(strip_twos):
  55. incl %ecx
  56. shrl %eax
  57. jnc L(strip_twos)
  58. movl %ebx, SAVE_EBX
  59. leal 1(%eax,%eax), %ebx C d without twos
  60. andl $127, %eax C d/2, 7 bits
  61. ifdef(`PIC',`
  62. LEA( binvert_limb_table, %edx)
  63. movzbl (%eax,%edx), %eax C inv 8 bits
  64. ',`
  65. movzbl binvert_limb_table(%eax), %eax C inv 8 bits
  66. ')
  67. leal (%eax,%eax), %edx C 2*inv
  68. movl %ebx, PARAM_DIVISOR C d without twos
  69. imull %eax, %eax C inv*inv
  70. movl PARAM_SRC, %esi
  71. movl PARAM_DST, %edi
  72. imull %ebx, %eax C inv*inv*d
  73. subl %eax, %edx C inv = 2*inv - inv*inv*d
  74. leal (%edx,%edx), %eax C 2*inv
  75. imull %edx, %edx C inv*inv
  76. leal (%esi,%ebp,4), %esi C src end
  77. leal (%edi,%ebp,4), %edi C dst end
  78. negl %ebp C -size
  79. imull %ebx, %edx C inv*inv*d
  80. subl %edx, %eax C inv = 2*inv - inv*inv*d
  81. ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
  82. pushl %eax FRAME_pushl()
  83. imull PARAM_DIVISOR, %eax
  84. cmpl $1, %eax
  85. popl %eax FRAME_popl()')
  86. movl %eax, VAR_INVERSE
  87. movl (%esi,%ebp,4), %eax C src[0]
  88. incl %ebp
  89. jz L(one)
  90. movl (%esi,%ebp,4), %edx C src[1]
  91. shrdl( %cl, %edx, %eax)
  92. movl %edi, VAR_DST_END
  93. xorl %ebx, %ebx
  94. jmp L(entry)
  95. ALIGN(8)
  96. L(top):
  97. C eax q
  98. C ebx carry bit, 0 or 1
  99. C ecx shift
  100. C edx
  101. C esi src end
  102. C edi dst end
  103. C ebp counter, limbs, negative
  104. mull PARAM_DIVISOR C carry limb in edx
  105. movl -4(%esi,%ebp,4), %eax
  106. movl (%esi,%ebp,4), %edi
  107. shrdl( %cl, %edi, %eax)
  108. subl %ebx, %eax C apply carry bit
  109. setc %bl
  110. movl VAR_DST_END, %edi
  111. subl %edx, %eax C apply carry limb
  112. adcl $0, %ebx
  113. L(entry):
  114. imull VAR_INVERSE, %eax
  115. movl %eax, -4(%edi,%ebp,4)
  116. incl %ebp
  117. jnz L(top)
  118. mull PARAM_DIVISOR C carry limb in edx
  119. movl -4(%esi), %eax C src high limb
  120. shrl %cl, %eax
  121. movl SAVE_ESI, %esi
  122. subl %ebx, %eax C apply carry bit
  123. movl SAVE_EBX, %ebx
  124. movl SAVE_EBP, %ebp
  125. subl %edx, %eax C apply carry limb
  126. imull VAR_INVERSE, %eax
  127. movl %eax, -4(%edi)
  128. movl SAVE_EDI, %edi
  129. addl $STACK_SPACE, %esp
  130. ret
  131. L(one):
  132. shrl %cl, %eax
  133. movl SAVE_ESI, %esi
  134. movl SAVE_EBX, %ebx
  135. imull VAR_INVERSE, %eax
  136. movl SAVE_EBP, %ebp
  137. movl %eax, -4(%edi)
  138. movl SAVE_EDI, %edi
  139. addl $STACK_SPACE, %esp
  140. ret
  141. EPILOGUE()