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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K7 mpn_add_n/mpn_sub_n -- mpn add or subtract.
  2. dnl  Copyright 1999, 2000, 2001, 2002, 2003 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 K7: 1.64 cycles/limb (at 16 limbs/loop).
  20. dnl  K7: UNROLL_COUNT cycles/limb
  21. dnl           8           1.9
  22. dnl          16           1.64
  23. dnl          32           1.7
  24. dnl          64           2.0
  25. dnl  Maximum possible with the current code is 64.
  26. deflit(UNROLL_COUNT, 16)
  27. ifdef(`OPERATION_add_n', `
  28. define(M4_inst,        adcl)
  29. define(M4_function_n,  mpn_add_n)
  30. define(M4_function_nc, mpn_add_nc)
  31. define(M4_description, add)
  32. ',`ifdef(`OPERATION_sub_n', `
  33. define(M4_inst,        sbbl)
  34. define(M4_function_n,  mpn_sub_n)
  35. define(M4_function_nc, mpn_sub_nc)
  36. define(M4_description, subtract)
  37. ',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
  38. ')')')
  39. MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
  40. C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
  41. C                         mp_size_t size);
  42. C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
  43. C                    mp_size_t size, mp_limb_t carry);
  44. C
  45. C Calculate src1,size M4_description src2,size, and store the result in
  46. C dst,size.  The return value is the carry bit from the top of the result (1
  47. C or 0).
  48. C
  49. C The _nc version accepts 1 or 0 for an initial carry into the low limb of
  50. C the calculation.  Note values other than 1 or 0 here will lead to garbage
  51. C results.
  52. C
  53. C This code runs at 1.64 cycles/limb, which might be the best possible with
  54. C plain integer operations.  Each limb is 2 loads and 1 store, any 2 of
  55. C which can be done each cycle, leading to 1.5 c/l.
  56. dnl  Must have UNROLL_THRESHOLD >= 2, since the unrolled loop can't handle 1.
  57. ifdef(`PIC',`
  58. deflit(UNROLL_THRESHOLD, 8)
  59. ',`
  60. deflit(UNROLL_THRESHOLD, 8)
  61. ')
  62. defframe(PARAM_CARRY,20)
  63. defframe(PARAM_SIZE, 16)
  64. defframe(PARAM_SRC2, 12)
  65. defframe(PARAM_SRC1, 8)
  66. defframe(PARAM_DST,  4)
  67. defframe(SAVE_EBP, -4)
  68. defframe(SAVE_ESI, -8)
  69. defframe(SAVE_EBX, -12)
  70. defframe(SAVE_EDI, -16)
  71. deflit(STACK_SPACE, 16)
  72. TEXT
  73. ALIGN(32)
  74. deflit(`FRAME',0)
  75. PROLOGUE(M4_function_nc)
  76. movl PARAM_CARRY, %eax
  77. jmp L(start)
  78. EPILOGUE()
  79. PROLOGUE(M4_function_n)
  80. xorl %eax, %eax C carry
  81. L(start):
  82. movl PARAM_SIZE, %ecx
  83. subl $STACK_SPACE, %esp
  84. deflit(`FRAME',STACK_SPACE)
  85. movl %edi, SAVE_EDI
  86. movl %ebx, SAVE_EBX
  87. cmpl $UNROLL_THRESHOLD, %ecx
  88. movl PARAM_SRC2, %edx
  89. movl PARAM_SRC1, %ebx
  90. jae L(unroll)
  91. movl PARAM_DST, %edi
  92. leal (%ebx,%ecx,4), %ebx
  93. leal (%edx,%ecx,4), %edx
  94. leal (%edi,%ecx,4), %edi
  95. negl %ecx
  96. shrl %eax
  97. C This loop in in a single 16 byte code block already, so no
  98. C alignment necessary.
  99. L(simple):
  100. C eax scratch
  101. C ebx src1
  102. C ecx counter
  103. C edx src2
  104. C esi
  105. C edi dst
  106. C ebp
  107. movl (%ebx,%ecx,4), %eax
  108. M4_inst (%edx,%ecx,4), %eax
  109. movl %eax, (%edi,%ecx,4)
  110. incl %ecx
  111. jnz L(simple)
  112. movl $0, %eax
  113. movl SAVE_EDI, %edi
  114. movl SAVE_EBX, %ebx
  115. setc %al
  116. addl $STACK_SPACE, %esp
  117. ret
  118. C -----------------------------------------------------------------------------
  119. C This is at 0x55, close enough to aligned.
  120. L(unroll):
  121. deflit(`FRAME',STACK_SPACE)
  122. movl %ebp, SAVE_EBP
  123. andl $-2, %ecx C size low bit masked out
  124. andl $1, PARAM_SIZE C size low bit kept
  125. movl %ecx, %edi
  126. decl %ecx
  127. movl PARAM_DST, %ebp
  128. shrl $UNROLL_LOG2, %ecx
  129. negl %edi
  130. movl %esi, SAVE_ESI
  131. andl $UNROLL_MASK, %edi
  132. ifdef(`PIC',`
  133. call L(pic_calc)
  134. L(here):
  135. ',`
  136. leal L(entry) (%edi,%edi,8), %esi C 9 bytes per
  137. ')
  138. negl %edi
  139. shrl %eax
  140. leal ifelse(UNROLL_BYTES,256,128) (%ebx,%edi,4), %ebx
  141. leal ifelse(UNROLL_BYTES,256,128) (%edx,%edi,4), %edx
  142. leal ifelse(UNROLL_BYTES,256,128) (%ebp,%edi,4), %edi
  143. jmp *%esi
  144. ifdef(`PIC',`
  145. L(pic_calc):
  146. C See mpn/x86/README about old gas bugs
  147. leal (%edi,%edi,8), %esi
  148. addl $L(entry)-L(here), %esi
  149. addl (%esp), %esi
  150. ret_internal
  151. ')
  152. C -----------------------------------------------------------------------------
  153. ALIGN(32)
  154. L(top):
  155. C eax zero
  156. C ebx src1
  157. C ecx counter
  158. C edx src2
  159. C esi scratch (was computed jump)
  160. C edi dst
  161. C ebp scratch
  162. leal UNROLL_BYTES(%edx), %edx
  163. L(entry):
  164. deflit(CHUNK_COUNT, 2)
  165. forloop(i, 0, UNROLL_COUNT/CHUNK_COUNT-1, `
  166. deflit(`disp0', eval(i*CHUNK_COUNT*4 ifelse(UNROLL_BYTES,256,-128)))
  167. deflit(`disp1', eval(disp0 + 4))
  168. Zdisp( movl, disp0,(%ebx), %esi)
  169. movl disp1(%ebx), %ebp
  170. Zdisp( M4_inst,disp0,(%edx), %esi)
  171. Zdisp( movl, %esi, disp0,(%edi))
  172. M4_inst disp1(%edx), %ebp
  173. movl %ebp, disp1(%edi)
  174. ')
  175. decl %ecx
  176. leal UNROLL_BYTES(%ebx), %ebx
  177. leal UNROLL_BYTES(%edi), %edi
  178. jns L(top)
  179. mov PARAM_SIZE, %esi
  180. movl SAVE_EBP, %ebp
  181. movl $0, %eax
  182. decl %esi
  183. js L(even)
  184. movl (%ebx), %ecx
  185. M4_inst UNROLL_BYTES(%edx), %ecx
  186. movl %ecx, (%edi)
  187. L(even):
  188. movl SAVE_EDI, %edi
  189. movl SAVE_EBX, %ebx
  190. setc %al
  191. movl SAVE_ESI, %esi
  192. addl $STACK_SPACE, %esp
  193. ret
  194. EPILOGUE()