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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K6 mpn_add/sub_n -- mpn addition or subtraction.
  2. dnl  Copyright 1999, 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: normal 3.25 cycles/limb, in-place 2.75 cycles/limb.
  20. ifdef(`OPERATION_add_n', `
  21. define(M4_inst,        adcl)
  22. define(M4_function_n,  mpn_add_n)
  23. define(M4_function_nc, mpn_add_nc)
  24. define(M4_description, add)
  25. ',`ifdef(`OPERATION_sub_n', `
  26. define(M4_inst,        sbbl)
  27. define(M4_function_n,  mpn_sub_n)
  28. define(M4_function_nc, mpn_sub_nc)
  29. define(M4_description, subtract)
  30. ',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
  31. ')')')
  32. MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
  33. C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
  34. C                          mp_size_t size);
  35. C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
  36. C                       mp_size_t size, mp_limb_t carry);
  37. C
  38. C Calculate src1,size M4_description src2,size, and store the result in
  39. C dst,size.  The return value is the carry bit from the top of the result
  40. C (1 or 0).
  41. C
  42. C The _nc version accepts 1 or 0 for an initial carry into the low limb of
  43. C the calculation.  Note values other than 1 or 0 here will lead to garbage
  44. C results.
  45. C
  46. C Instruction decoding limits a normal dst=src1+src2 operation to 3 c/l, and
  47. C an in-place dst+=src to 2.5 c/l.  The unrolled loops have 1 cycle/loop of
  48. C loop control, which with 4 limbs/loop means an extra 0.25 c/l.
  49. define(PARAM_CARRY, `FRAME+20(%esp)')
  50. define(PARAM_SIZE,  `FRAME+16(%esp)')
  51. define(PARAM_SRC2,  `FRAME+12(%esp)')
  52. define(PARAM_SRC1,  `FRAME+8(%esp)')
  53. define(PARAM_DST,   `FRAME+4(%esp)')
  54. deflit(`FRAME',0)
  55. dnl  minimum 5 because the unrolled code can't handle less
  56. deflit(UNROLL_THRESHOLD, 5)
  57. TEXT
  58. ALIGN(32)
  59. PROLOGUE(M4_function_nc)
  60. movl PARAM_CARRY, %eax
  61. jmp L(start)
  62. EPILOGUE()
  63. PROLOGUE(M4_function_n)
  64. xorl %eax, %eax
  65. L(start):
  66. movl PARAM_SIZE, %ecx
  67. pushl %ebx
  68. FRAME_pushl()
  69. movl PARAM_SRC1, %ebx
  70. pushl %edi
  71. FRAME_pushl()
  72. movl PARAM_SRC2, %edx
  73. cmpl $UNROLL_THRESHOLD, %ecx
  74. movl PARAM_DST, %edi
  75. jae L(unroll)
  76. shrl %eax C initial carry flag
  77. C offset 0x21 here, close enough to aligned
  78. L(simple):
  79. C eax scratch
  80. C ebx src1
  81. C ecx counter
  82. C edx src2
  83. C esi
  84. C edi dst
  85. C ebp
  86. C
  87. C The store to (%edi) could be done with a stosl; it'd be smaller
  88. C code, but there's no speed gain and a cld would have to be added
  89. C (per mpn/x86/README).
  90. movl (%ebx), %eax
  91. leal 4(%ebx), %ebx
  92. M4_inst (%edx), %eax
  93. movl %eax, (%edi)
  94. leal 4(%edi), %edi
  95. leal 4(%edx), %edx
  96. loop L(simple)
  97. movl $0, %eax
  98. popl %edi
  99. setc %al
  100. popl %ebx
  101. ret
  102. C -----------------------------------------------------------------------------
  103. L(unroll):
  104. C eax carry
  105. C ebx src1
  106. C ecx counter
  107. C edx src2
  108. C esi
  109. C edi dst
  110. C ebp
  111. cmpl %edi, %ebx
  112. pushl %esi
  113. je L(inplace)
  114. ifdef(`OPERATION_add_n',`
  115. cmpl %edi, %edx
  116. je L(inplace_reverse)
  117. ')
  118. movl %ecx, %esi
  119. andl $-4, %ecx
  120. andl $3, %esi
  121. leal (%ebx,%ecx,4), %ebx
  122. leal (%edx,%ecx,4), %edx
  123. leal (%edi,%ecx,4), %edi
  124. negl %ecx
  125. shrl %eax
  126. ALIGN(32)
  127. L(normal_top):
  128. C eax counter, qwords, negative
  129. C ebx src1
  130. C ecx scratch
  131. C edx src2
  132. C esi
  133. C edi dst
  134. C ebp
  135. movl (%ebx,%ecx,4), %eax
  136. leal 5(%ecx), %ecx
  137. M4_inst -20(%edx,%ecx,4), %eax
  138. movl %eax, -20(%edi,%ecx,4)
  139. movl 4-20(%ebx,%ecx,4), %eax
  140. M4_inst 4-20(%edx,%ecx,4), %eax
  141. movl %eax, 4-20(%edi,%ecx,4)
  142. movl 8-20(%ebx,%ecx,4), %eax
  143. M4_inst 8-20(%edx,%ecx,4), %eax
  144. movl %eax, 8-20(%edi,%ecx,4)
  145. movl 12-20(%ebx,%ecx,4), %eax
  146. M4_inst 12-20(%edx,%ecx,4), %eax
  147. movl %eax, 12-20(%edi,%ecx,4)
  148. loop L(normal_top)
  149. decl %esi
  150. jz L(normal_finish_one)
  151. js L(normal_done)
  152. C two or three more limbs
  153. movl (%ebx), %eax
  154. M4_inst (%edx), %eax
  155. movl %eax, (%edi)
  156. movl 4(%ebx), %eax
  157. M4_inst 4(%edx), %eax
  158. decl %esi
  159. movl %eax, 4(%edi)
  160. jz L(normal_done)
  161. movl $2, %ecx
  162. L(normal_finish_one):
  163. movl (%ebx,%ecx,4), %eax
  164. M4_inst (%edx,%ecx,4), %eax
  165. movl %eax, (%edi,%ecx,4)
  166. L(normal_done):
  167. popl %esi
  168. popl %edi
  169. movl $0, %eax
  170. popl %ebx
  171. setc %al
  172. ret
  173. C -----------------------------------------------------------------------------
  174. ifdef(`OPERATION_add_n',`
  175. L(inplace_reverse):
  176. C dst==src2
  177. movl %ebx, %edx
  178. ')
  179. L(inplace):
  180. C eax initial carry
  181. C ebx
  182. C ecx size
  183. C edx src
  184. C esi
  185. C edi dst
  186. C ebp
  187. leal -1(%ecx), %esi
  188. decl %ecx
  189. andl $-4, %ecx
  190. andl $3, %esi
  191. movl (%edx), %ebx C src low limb
  192. leal (%edx,%ecx,4), %edx
  193. leal (%edi,%ecx,4), %edi
  194. negl %ecx
  195. shrl %eax
  196. ALIGN(32)
  197. L(inplace_top):
  198. C eax
  199. C ebx next src limb
  200. C ecx size
  201. C edx src
  202. C esi
  203. C edi dst
  204. C ebp
  205. M4_inst %ebx, (%edi,%ecx,4)
  206. movl 4(%edx,%ecx,4), %eax
  207. leal 5(%ecx), %ecx
  208. M4_inst %eax, 4-20(%edi,%ecx,4)
  209. movl 8-20(%edx,%ecx,4), %eax
  210. movl 12-20(%edx,%ecx,4), %ebx
  211. M4_inst %eax, 8-20(%edi,%ecx,4)
  212. M4_inst %ebx, 12-20(%edi,%ecx,4)
  213. movl 16-20(%edx,%ecx,4), %ebx
  214. loop L(inplace_top)
  215. C now %esi is 0 to 3 representing respectively 1 to 4 limbs more
  216. M4_inst %ebx, (%edi)
  217. decl %esi
  218. jz L(inplace_finish_one)
  219. js L(inplace_done)
  220. C two or three more limbs
  221. movl 4(%edx), %eax
  222. movl 8(%edx), %ebx
  223. M4_inst %eax, 4(%edi)
  224. M4_inst %ebx, 8(%edi)
  225. decl %esi
  226. movl $2, %ecx
  227. jz L(normal_done)
  228. L(inplace_finish_one):
  229. movl 4(%edx,%ecx,4), %eax
  230. M4_inst %eax, 4(%edi,%ecx,4)
  231. L(inplace_done):
  232. popl %esi
  233. popl %edi
  234. movl $0, %eax
  235. popl %ebx
  236. setc %al
  237. ret
  238. EPILOGUE()