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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K6-2 mpn_and_n, mpn_andn_n, mpn_nand_n, mpn_ior_n, mpn_iorn_n,
  2. dnl  mpn_nior_n, mpn_xor_n, mpn_xnor_n -- mpn bitwise logical operations.
  3. dnl  Copyright 1999, 2000, 2001, 2002 Free Software 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. NAILS_SUPPORT(0-31)
  21. C         alignment dst/src1/src2, A=0mod8, N=4mod8
  22. C      A/A/A A/A/N A/N/A A/N/N N/A/A N/A/N N/N/A N/N/N
  23. C
  24. C K6-2  1.2   1.5   1.5   1.2   1.2   1.5   1.5   1.2   and,andn,ior,xor
  25. C K6-2  1.5   1.75  2.0   1.75  1.75  2.0   1.75  1.5   iorn,xnor
  26. C K6-2  1.75  2.0   2.0   2.0   2.0   2.0   2.0   1.75  nand,nior
  27. C
  28. C K6    1.5   1.68  1.75  1.2   1.75  1.75  1.68  1.5   and,andn,ior,xor
  29. C K6    2.0   2.0   2.25  2.25  2.25  2.25  2.0   2.0   iorn,xnor
  30. C K6    2.0   2.25  2.25  2.25  2.25  2.25  2.25  2.0   nand,nior
  31. dnl  M4_p and M4_i are the MMX and integer instructions
  32. dnl  M4_*_neg_dst means whether to negate the final result before writing
  33. dnl  M4_*_neg_src2 means whether to negate the src2 values before using them
  34. define(M4_choose_op,
  35. m4_assert_numargs(7)
  36. `ifdef(`OPERATION_$1',`
  37. define(`M4_function',  `mpn_$1')
  38. define(`M4_operation', `$1')
  39. define(`M4_p',         `$2')
  40. define(`M4_p_neg_dst', `$3')
  41. define(`M4_p_neg_src2',`$4')
  42. define(`M4_i',         `$5')
  43. define(`M4_i_neg_dst', `$6')
  44. define(`M4_i_neg_src2',`$7')
  45. ')')
  46. dnl  xnor is done in "iorn" style because it's a touch faster than "nior"
  47. dnl  style (the two are equivalent for xor).
  48. dnl
  49. dnl  pandn can't be used with nails.
  50. M4_choose_op( and_n,  pand,0,0,  andl,0,0)
  51. ifelse(GMP_NAIL_BITS,0,
  52. `M4_choose_op(andn_n, pandn,0,0, andl,0,1)',
  53. `M4_choose_op(andn_n, pand,0,1,  andl,0,1)')
  54. M4_choose_op( nand_n, pand,1,0,  andl,1,0)
  55. M4_choose_op( ior_n,  por,0,0,   orl,0,0)
  56. M4_choose_op( iorn_n, por,0,1,   orl,0,1)
  57. M4_choose_op( nior_n, por,1,0,   orl,1,0)
  58. M4_choose_op( xor_n,  pxor,0,0,  xorl,0,0)
  59. M4_choose_op( xnor_n, pxor,0,1,  xorl,0,1)
  60. ifdef(`M4_function',,
  61. `m4_error(`Unrecognised or undefined OPERATION symbol
  62. ')')
  63. MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
  64. C void M4_function (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
  65. C                   mp_size_t size);
  66. C
  67. C Do src1,size M4_operation src2,size, storing the result in dst,size.
  68. C
  69. C Unaligned movq loads and stores are a bit slower than aligned ones.  The
  70. C test at the start of the routine checks the alignment of src1 and if
  71. C necessary processes one limb separately at the low end to make it aligned.
  72. C
  73. C The raw speeds without this alignment switch are as follows.
  74. C
  75. C           alignment dst/src1/src2, A=0mod8, N=4mod8
  76. C     A/A/A  A/A/N  A/N/A  A/N/N  N/A/A  N/A/N  N/N/A  N/N/N
  77. C
  78. C K6                 1.5    2.0                 1.5    2.0    and,andn,ior,xor
  79. C K6                 1.75   2.2                 2.0    2.28   iorn,xnor
  80. C K6                 2.0    2.25                2.35   2.28   nand,nior
  81. C
  82. C
  83. C Future:
  84. C
  85. C K6 can do one 64-bit load per cycle so each of these routines should be
  86. C able to approach 1.0 c/l, if aligned.  The basic and/andn/ior/xor might be
  87. C able to get 1.0 with just a 4 limb loop, being 3 instructions per 2 limbs.
  88. C The others are 4 instructions per 2 limbs, and so can only approach 1.0
  89. C because there's nowhere to hide some loop control.
  90. defframe(PARAM_SIZE,16)
  91. defframe(PARAM_SRC2,12)
  92. defframe(PARAM_SRC1,8)
  93. defframe(PARAM_DST, 4)
  94. deflit(`FRAME',0)
  95. TEXT
  96. ALIGN(32)
  97. PROLOGUE(M4_function)
  98. movl PARAM_SIZE, %ecx
  99. pushl %ebx FRAME_pushl()
  100. movl PARAM_SRC1, %eax
  101. movl PARAM_SRC2, %ebx
  102. cmpl $1, %ecx
  103. movl PARAM_DST, %edx
  104. ja L(two_or_more)
  105. movl (%ebx), %ecx
  106. popl %ebx
  107. ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ecx)')
  108. M4_i (%eax), %ecx
  109. ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ecx)')
  110. movl %ecx, (%edx)
  111. ret
  112. L(two_or_more):
  113. C eax src1
  114. C ebx src2
  115. C ecx size
  116. C edx dst
  117. C esi
  118. C edi
  119. C ebp
  120. pushl %esi FRAME_pushl()
  121. testl $4, %eax
  122. jz L(alignment_ok)
  123. movl (%ebx), %esi
  124. addl $4, %ebx
  125. ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %esi)')
  126. M4_i (%eax), %esi
  127. addl $4, %eax
  128. ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %esi)')
  129. movl %esi, (%edx)
  130. addl $4, %edx
  131. decl %ecx
  132. L(alignment_ok):
  133. movl %ecx, %esi
  134. shrl %ecx
  135. jnz L(still_two_or_more)
  136. movl (%ebx), %ecx
  137. popl %esi
  138. ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ecx)')
  139. M4_i (%eax), %ecx
  140. ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ecx)')
  141. popl %ebx
  142. movl %ecx, (%edx)
  143. ret
  144. L(still_two_or_more):
  145. ifelse(eval(M4_p_neg_src2 || M4_p_neg_dst),1,`
  146. pcmpeqd %mm7, %mm7 C all ones
  147. ifelse(GMP_NAIL_BITS,0,,`psrld $GMP_NAIL_BITS, %mm7') C clear nails
  148. ')
  149. ALIGN(16)
  150. L(top):
  151. C eax src1
  152. C ebx src2
  153. C ecx counter
  154. C edx dst
  155. C esi
  156. C edi
  157. C ebp
  158. C
  159. C carry bit is low of size
  160. movq -8(%ebx,%ecx,8), %mm0
  161. ifelse(M4_p_neg_src2,1,`pxor %mm7, %mm0')
  162. M4_p -8(%eax,%ecx,8), %mm0
  163. ifelse(M4_p_neg_dst,1,` pxor %mm7, %mm0')
  164. movq %mm0, -8(%edx,%ecx,8)
  165. loop L(top)
  166. jnc L(no_extra)
  167. movl -4(%ebx,%esi,4), %ebx
  168. ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ebx)')
  169. M4_i -4(%eax,%esi,4), %ebx
  170. ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ebx)')
  171. movl %ebx, -4(%edx,%esi,4)
  172. L(no_extra):
  173. popl %esi
  174. popl %ebx
  175. emms_or_femms
  176. ret
  177. EPILOGUE()