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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K6 mpn_mod_34lsub1 -- mpn remainder modulo 2**24-1.
  2. dnl  Copyright 2000, 2001, 2002 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 K6: 2.66 cycles/limb
  20. C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
  21. C
  22. C An attempt was made to use a loop like
  23. C
  24. C L(top):
  25. C adcl (%edx), %eax
  26. C adcl 4(%edx), %ebx
  27. C adcl 8(%edx), %esi
  28. C leal 12(%edx), %edx
  29. C loop L(top)
  30. C
  31. C with %ecx starting from floor(size/3), but it still measured 2.66 c/l.
  32. C The form used instead can save about 6 cycles by not dividing by 3.
  33. C
  34. C In the code used, putting the "leal"s at the top of the loop is necessary
  35. C for the claimed speed, anywhere else costs an extra cycle per loop.
  36. C Perhaps a tight loop like this needs short decode instructions at the
  37. C branch target, which would explain the leal/loop form above taking 8
  38. C cycles instead of 7 too.
  39. defframe(PARAM_SIZE, 8)
  40. defframe(PARAM_SRC,  4)
  41. dnl  re-use parameter space
  42. define(SAVE_EBX, `PARAM_SIZE')
  43. define(SAVE_ESI, `PARAM_SRC')
  44. TEXT
  45. ALIGN(16)
  46. PROLOGUE(mpn_mod_34lsub1)
  47. deflit(`FRAME',0)
  48. movl PARAM_SIZE, %eax
  49. movl PARAM_SRC, %edx
  50. subl $2, %eax
  51. ja L(three_or_more)
  52. Zdisp( movl, 0,(%edx), %eax) C avoid code cache line boundary
  53. jne L(one)
  54. movl %eax, %ecx
  55. movl 4(%edx), %edx
  56. shrl $24, %eax C src[0] high
  57. andl $0x00FFFFFF, %ecx C src[0] low
  58. addl %ecx, %eax
  59. movl %edx, %ecx
  60. shll $8, %edx
  61. andl $0x00FFFF00, %edx C src[1] high
  62. shrl $16, %ecx C src[1] low
  63. addl %ecx, %eax
  64. addl %edx, %eax
  65. L(one):
  66. ret
  67. L(three_or_more):
  68. C eax size-2
  69. C ebx
  70. C ecx
  71. C edx src
  72. movl %ebx, SAVE_EBX
  73. xorl %ebx, %ebx
  74. movl %esi, SAVE_ESI
  75. pushl %edi FRAME_pushl()
  76. xorl %esi, %esi
  77. xorl %edi, %edi C and clear carry flag
  78. L(top):
  79. C eax counter, limbs
  80. C ebx acc 0mod3
  81. C ecx
  82. C edx src, incrementing
  83. C esi acc 1mod3
  84. C edi acc 2mod3
  85. C ebp
  86. leal -2(%eax), %eax
  87. leal 12(%edx), %edx
  88. adcl -12(%edx), %ebx
  89. adcl -8(%edx), %esi
  90. adcl -4(%edx), %edi
  91. decl %eax
  92. jg L(top)
  93. C ecx is -3, -2 or -1 representing 0, 1 or 2 more limbs, respectively
  94. movb $0, %cl
  95. incl %eax
  96. js L(combine) C 0 more
  97. Zdisp( adcl, 0,(%edx), %ebx) C avoid code cache line crossings
  98. movb $8, %cl
  99. decl %eax
  100. js L(combine) C 1 more
  101. adcl 4(%edx), %esi
  102. movb $16, %cl
  103. L(combine):
  104. sbbl %edx, %edx
  105. shll %cl, %edx C carry
  106. movl %ebx, %eax C 0mod3
  107. shrl $24, %eax C 0mod3 high
  108. andl $0x00FFFFFF, %ebx C 0mod3 low
  109. subl %edx, %eax C apply carry
  110. movl %esi, %ecx C 1mod3
  111. shrl $16, %esi C 1mod3 high
  112. addl %ebx, %eax C apply 0mod3 low
  113. andl $0x0000FFFF, %ecx
  114. addl %esi, %eax C apply 1mod3 high
  115. shll $8, %ecx C 1mod3 low
  116. movl %edi, %edx C 2mod3
  117. shrl $8, %edx C 2mod3 high
  118. addl %ecx, %eax C apply 1mod3 low
  119. addl %edx, %eax C apply 2mod3 high
  120. andl $0x000000FF, %edi
  121. shll $16, %edi C 2mod3 low
  122. movl SAVE_EBX, %ebx
  123. addl %edi, %eax C apply 2mod3 low
  124. movl SAVE_ESI, %esi
  125. popl %edi
  126. ret
  127. EPILOGUE()