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

数学计算

开发平台:

Unix_Linux

  1. dnl  Intel Pentium-4 mpn_rsh1add_n -- mpn (x+y)/2
  2. dnl  Copyright 2001, 2002, 2003, 2004 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        cycles/limb (approx)
  20. C      dst!=src1,2  dst==src1  dst==src2
  21. C P4:      4.5         6.5        6.5
  22. C mp_limb_t mpn_rsh1add_n (mp_ptr wp, mp_srcptr xp, mp_srcptr yp,
  23. C                          mp_size_t size);
  24. C
  25. C The slightly strange combination of indexing and pointer incrementing
  26. C that's used seems to work best.  Not sure why, but for instance leal
  27. C incrementing on %esi is a 1 or 2 cycle slowdown.
  28. C
  29. C The dependent chain is paddq combining the carry and next (shifted) part,
  30. C plus psrlq to move the new carry down.  That, and just 4 mmx instructions
  31. C in total, makes 4 c/l the target speed, which is almost achieved for
  32. C separate src/dst but when src==dst the write combining anomalies slow it
  33. C down.
  34. defframe(PARAM_SIZE, 16)
  35. defframe(PARAM_YP,   12)
  36. defframe(PARAM_XP,   8)
  37. defframe(PARAM_WP,   4)
  38. dnl  re-use parameter space
  39. define(SAVE_EBX,`PARAM_XP')
  40. define(SAVE_ESI,`PARAM_YP')
  41. TEXT
  42. ALIGN(8)
  43. PROLOGUE(mpn_rsh1add_n)
  44. deflit(`FRAME',0)
  45. movl PARAM_XP, %edx
  46. movl %ebx, SAVE_EBX
  47. movl PARAM_YP, %ebx
  48. movl %esi, SAVE_ESI
  49. movl PARAM_WP, %esi
  50. movd (%edx), %mm0 C xp[0]
  51. movd (%ebx), %mm1 C yp[0]
  52. movl PARAM_SIZE, %ecx
  53. movl (%edx), %eax C xp[0]
  54. addl (%ebx), %eax C xp[0]+yp[0]
  55. paddq %mm1, %mm0 C xp[0]+yp[0]
  56. leal (%esi,%ecx,4), %esi C wp end
  57. negl %ecx C -size
  58. psrlq $1, %mm0 C (xp[0]+yp[0])/2
  59. and $1, %eax C return value, rsh1 bit of xp[0]+yp[0]
  60. addl $1, %ecx C -(size-1)
  61. jz L(done)
  62. L(top):
  63. C eax return value
  64. C ebx yp end
  65. C ecx counter, limbs, -(size-1) to -1 inclusive
  66. C edx xp end
  67. C esi wp end
  68. C mm0 carry (32 bits)
  69. movd 4(%edx), %mm1 C xp[i+1]
  70. movd 4(%ebx), %mm2 C yp[i+1]
  71. leal 4(%edx), %edx
  72. leal 4(%ebx), %ebx
  73. paddq %mm2, %mm1 C xp[i+1]+yp[i+1]
  74. psllq $31, %mm1 C low bit at 31, further 32 above
  75. paddq %mm1, %mm0 C 31 and carry from prev add
  76. movd %mm0, -4(%esi,%ecx,4) C low ready to store dst[i]
  77. psrlq $32, %mm0 C high becomes new carry
  78. addl $1, %ecx
  79. jnz L(top)
  80. L(done):
  81. movd %mm0, -4(%esi) C dst[size-1]
  82. movl SAVE_EBX, %ebx
  83. movl SAVE_ESI, %esi
  84. emms
  85. ret
  86. EPILOGUE()