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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD K7 mpn_copyi -- copy limb vector, incrementing.
  2. dnl  Copyright 1999, 2000, 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    alignment dst/src, A=0mod8 N=4mod8
  20. C       A/A   A/N   N/A   N/N
  21. C K7    0.75  1.0   1.0   0.75
  22. C void mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t size);
  23. C
  24. C Copy src,size to dst,size.
  25. C
  26. C This code at 0.75 or 1.0 c/l is always faster than a plain rep movsl at
  27. C 1.33 c/l.
  28. C
  29. C The K7 can do a 64-bit load and 64-bit store in one cycle (optimization
  30. C guile 22007 appendix B), so 0.5 c/l should be possible, however nothing
  31. C under 0.7 c/l is known.  Apparently only two 32-bit stores can be done in
  32. C one cycle, so perhaps some scheduling is needed to ensure it's a
  33. C load+store in each cycle, not store+store.
  34. C
  35. C If both source and destination are unaligned then one limb is processed at
  36. C the start to make them aligned and so get 0.75 c/l, whereas if they'd been
  37. C used unaligned it would be 1.5 c/l.
  38. defframe(PARAM_SIZE,12)
  39. defframe(PARAM_SRC, 8)
  40. defframe(PARAM_DST, 4)
  41. dnl  parameter space reused
  42. define(SAVE_EBX,`PARAM_SIZE')
  43. dnl  minimum 5 since the unrolled code can't handle less than 5
  44. deflit(UNROLL_THRESHOLD, 5)
  45. TEXT
  46. ALIGN(32)
  47. PROLOGUE(mpn_copyi)
  48. deflit(`FRAME',0)
  49. movl PARAM_SIZE, %ecx
  50. movl %ebx, SAVE_EBX
  51. movl PARAM_SRC, %eax
  52. movl PARAM_DST, %edx
  53. cmpl $UNROLL_THRESHOLD, %ecx
  54. jae L(unroll)
  55. orl %ecx, %ecx
  56. jz L(simple_done)
  57. L(simple):
  58. C eax src, incrementing
  59. C ebx scratch
  60. C ecx counter
  61. C edx dst, incrementing
  62. C
  63. C this loop is 2 cycles/limb
  64. movl (%eax), %ebx
  65. movl %ebx, (%edx)
  66. decl %ecx
  67. leal 4(%eax), %eax
  68. leal 4(%edx), %edx
  69. jnz L(simple)
  70. L(simple_done):
  71. movl SAVE_EBX, %ebx
  72. ret
  73. L(unroll):
  74. movl %eax, %ebx
  75. leal -12(%eax,%ecx,4), %eax C src end - 12
  76. subl $3, %ecx C size-3
  77. andl %edx, %ebx
  78. leal (%edx,%ecx,4), %edx C dst end - 12
  79. negl %ecx
  80. testl $4, %ebx   C testl to pad code closer to 16 bytes for L(top)
  81. jz L(aligned)
  82. C both src and dst unaligned, process one limb to align them
  83. movl (%eax,%ecx,4), %ebx
  84. movl %ebx, (%edx,%ecx,4)
  85. incl %ecx
  86. L(aligned):
  87. ALIGN(16)
  88. L(top):
  89. C eax src end - 12
  90. C ebx
  91. C ecx counter, negative, limbs
  92. C edx dst end - 12
  93. movq (%eax,%ecx,4), %mm0
  94. movq 8(%eax,%ecx,4), %mm1
  95. addl $4, %ecx
  96. movq %mm0, -16(%edx,%ecx,4)
  97. movq %mm1, -16+8(%edx,%ecx,4)
  98. ja L(top) C jump no carry and not zero
  99. C now %ecx is 0 to 3 representing respectively 3 to 0 limbs remaining
  100. testb $2, %cl
  101. jnz L(finish_not_two)
  102. movq (%eax,%ecx,4), %mm0
  103. movq %mm0, (%edx,%ecx,4)
  104. L(finish_not_two):
  105. testb $1, %cl
  106. jnz L(done)
  107. movl 8(%eax), %ebx
  108. movl %ebx, 8(%edx)
  109. L(done):
  110. movl SAVE_EBX, %ebx
  111. emms
  112. ret
  113. EPILOGUE()