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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD64 mpn_modexact_1_odd -- exact division style remainder.
  2. dnl  Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
  3. dnl  Foundation, Inc.
  4. dnl
  5. dnl  This file is part of the GNU MP Library.
  6. dnl
  7. dnl  The GNU MP Library is free software; you can redistribute it and/or
  8. dnl  modify it under the terms of the GNU Lesser General Public License as
  9. dnl  published by the Free Software Foundation; either version 3 of the
  10. dnl  License, or (at your option) any later version.
  11. dnl
  12. dnl  The GNU MP Library is distributed in the hope that it will be useful,
  13. dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. dnl  Lesser General Public License for more details.
  16. dnl
  17. dnl  You should have received a copy of the GNU Lesser General Public License
  18. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  19. include(`../config.m4')
  20. C      cycles/limb
  21. C K8,K9: 10
  22. C K10: 10
  23. C P4: 33
  24. C P6 core2: 13
  25. C P6 corei7: 14.5
  26. C P6 Atom: 35
  27. C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
  28. C                               mp_limb_t divisor);
  29. C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
  30. C                                mp_limb_t divisor, mp_limb_t carry);
  31. C
  32. C
  33. C The dependent chain in the main loop is
  34. C
  35. C                            cycles
  36. C subq %rdx, %rax 1
  37. C imulq %r9, %rax 4
  38. C mulq %r8 5
  39. C       ----
  40. C       total        10
  41. C
  42. C The movq load from src seems to need to be scheduled back before the jz to
  43. C achieve this speed, out-of-order execution apparently can't completely
  44. C hide the latency otherwise.
  45. C
  46. C The l=src[i]-cbit step is rotated back too, since that allows us to avoid
  47. C it for the first iteration (where there's no cbit).
  48. C
  49. C The code alignment used (32-byte) for the loop also seems necessary.
  50. C Without that the non-PIC case has adcq crossing the 0x60 offset,
  51. C apparently making it run at 11 cycles instead of 10.
  52. C
  53. C Not done:
  54. C
  55. C divq for size==1 was measured at about 79 cycles, compared to the inverse
  56. C at about 25 cycles (both including function call overheads), so that's not
  57. C used.
  58. C
  59. C Enhancements:
  60. C
  61. C For PIC, we shouldn't really need the GOT fetch for binvert_limb_table,
  62. C it'll be in rodata or text in libgmp.so and can be accessed directly %rip
  63. C relative.  This would be for small model only (something we don't
  64. C presently detect, but which is all that gcc 3.3.3 supports), since 8-byte
  65. C PC-relative relocations are apparently not available.  Some rough
  66. C experiments with binutils 2.13 looked worrylingly like it might come out
  67. C with an unwanted text segment relocation though, even with ".protected".
  68. ASM_START()
  69. TEXT
  70. ALIGN(32)
  71. PROLOGUE(mpn_modexact_1_odd)
  72. movl $0, %ecx
  73. PROLOGUE(mpn_modexact_1c_odd)
  74. C rdi src
  75. C rsi size
  76. C rdx divisor
  77. C rcx carry
  78. movq %rdx, %r8 C d
  79. shrl %edx C d/2
  80. ifdef(`PIC',`
  81. movq binvert_limb_table@GOTPCREL(%rip), %r9
  82. ',`
  83. movabsq $binvert_limb_table, %r9
  84. ')
  85. andl $127, %edx
  86. movq %rcx, %r10 C initial carry
  87. movzbl (%r9,%rdx), %edx C inv 8 bits
  88. movq (%rdi), %rax C src[0]
  89. leaq (%rdi,%rsi,8), %r11 C src end
  90. movq %r8, %rdi C d, made available to imull
  91. leal (%rdx,%rdx), %ecx C 2*inv
  92. imull %edx, %edx C inv*inv
  93. negq %rsi C -size
  94. imull %edi, %edx C inv*inv*d
  95. subl %edx, %ecx C inv = 2*inv - inv*inv*d, 16 bits
  96. leal (%rcx,%rcx), %edx C 2*inv
  97. imull %ecx, %ecx C inv*inv
  98. imull %edi, %ecx C inv*inv*d
  99. subl %ecx, %edx C inv = 2*inv - inv*inv*d, 32 bits
  100. xorl %ecx, %ecx C initial cbit
  101. leaq (%rdx,%rdx), %r9 C 2*inv
  102. imulq %rdx, %rdx C inv*inv
  103. imulq %r8, %rdx C inv*inv*d
  104. subq %rdx, %r9 C inv = 2*inv - inv*inv*d, 64 bits
  105. movq %r10, %rdx C initial climb
  106. ASSERT(e,` C d*inv == 1 mod 2^64
  107. movq %r8, %r10
  108. imulq %r9, %r10
  109. cmpq $1, %r10')
  110. incq %rsi
  111. jz L(one)
  112. ALIGN(16)
  113. L(top):
  114. C rax l = src[i]-cbit
  115. C rcx new cbit, 0 or 1
  116. C rdx climb, high of last product
  117. C rsi counter, limbs, negative
  118. C rdi
  119. C r8 divisor
  120. C r9 inverse
  121. C r11 src end ptr
  122. subq %rdx, %rax C l = src[i]-cbit - climb
  123. adcq $0, %rcx C more cbit
  124. imulq %r9, %rax C q = l * inverse
  125. mulq %r8 C climb = high (q * d)
  126. movq (%r11,%rsi,8), %rax C src[i+1]
  127. subq %rcx, %rax C next l = src[i+1] - cbit
  128. setc %cl C new cbit
  129. incq %rsi
  130. jnz L(top)
  131. L(one):
  132. subq %rdx, %rax C l = src[i]-cbit - climb
  133. adcq $0, %rcx C more cbit
  134. imulq %r9, %rax C q = l * inverse
  135. mulq %r8 C climb = high (q * d)
  136. leaq (%rcx,%rdx), %rax C climb+cbit
  137. ret
  138. EPILOGUE(mpn_modexact_1c_odd)
  139. EPILOGUE(mpn_modexact_1_odd)