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

数学计算

开发平台:

Unix_Linux

  1. dnl  PowerPC-32/VMX and PowerPC-64/VMX mpn_copyd.
  2. dnl  Copyright 2006 Free Software Foundation, Inc.
  3. dnl  This file is part of the GNU MP Library.
  4. dnl  The GNU MP Library is free software; you can redistribute it and/or modify
  5. dnl  it under the terms of the GNU Lesser General Public License as published
  6. dnl  by the Free Software Foundation; either version 3 of the License, or (at
  7. dnl  your option) any later version.
  8. dnl  The GNU MP Library is distributed in the hope that it will be useful, but
  9. dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  11. dnl  License for more details.
  12. dnl  You should have received a copy of the GNU Lesser General Public License
  13. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  14. include(`../config.m4')
  15. C                16-byte coaligned      unaligned
  16. C                   cycles/limb        cycles/limb
  17. C 7400,7410 (G4):       0.5                0.64
  18. C 744x,745x (G4+):      0.75               0.82
  19. C 970 (G5):             0.78               1.02 (64-bit limbs)
  20. C STATUS
  21. C  * Works for all sizes and alignments.
  22. C TODO
  23. C  * Optimize unaligned case.  Some basic tests with 2-way and 4-way unrolling
  24. C    indicate that we can reach 0.56 c/l for 7400, 0.75 c/l for 745x, and 0.80
  25. C    c/l for 970.
  26. C  * Consider using VMX instructions also for head and tail, by using some
  27. C    read-modify-write tricks.
  28. C  * The VMX code is used from the smallest sizes it handles, but measurements
  29. C    show a large speed bump at the cutoff points.  Small copying (perhaps
  30. C    using some read-modify-write technique) should be optimized.
  31. C  * Make a mpn_com based on this code.
  32. define(`GMP_LIMB_BYTES', eval(GMP_LIMB_BITS/8))
  33. define(`LIMBS_PER_VR',  eval(16/GMP_LIMB_BYTES))
  34. define(`LIMBS_PER_2VR', eval(32/GMP_LIMB_BYTES))
  35. ifelse(GMP_LIMB_BITS,32,`
  36. define(`LIMB32',` $1')
  37. define(`LIMB64',`')
  38. ',`
  39. define(`LIMB32',`')
  40. define(`LIMB64',` $1')
  41. ')
  42. C INPUT PARAMETERS
  43. define(`rp', `r3')
  44. define(`up', `r4')
  45. define(`n', `r5')
  46. define(`us', `v4')
  47. ASM_START()
  48. PROLOGUE(mpn_copyd)
  49. LIMB32(`slwi. r0, n, 2 ')
  50. LIMB64(`sldi. r0, n, 3 ')
  51. add rp, rp, r0
  52. add up, up, r0
  53. LIMB32(`cmpi cr7, n, 11 ')
  54. LIMB64(`cmpdi cr7, n, 5 ')
  55. bge cr7, L(big)
  56. beqlr cr0
  57. C Handle small cases with plain operations
  58. mtctr n
  59. L(topS):
  60. LIMB32(`lwz r0, -4(up) ')
  61. LIMB64(`ld r0, -8(up) ')
  62. addi up, up, -GMP_LIMB_BYTES
  63. LIMB32(`stw r0, -4(rp) ')
  64. LIMB64(`std r0, -8(rp) ')
  65. addi rp, rp, -GMP_LIMB_BYTES
  66. bdnz L(topS)
  67. blr
  68. C Handle large cases with VMX operations
  69. L(big):
  70. addi rp, rp, -16
  71. addi up, up, -16
  72. mfspr r12, 256
  73. oris r0, r12, 0xf800 C Set VRSAVE bit 0-4
  74. mtspr 256, r0
  75. LIMB32(`rlwinm. r7, rp, 30,30,31') C (rp >> 2) mod 4
  76. LIMB64(`rlwinm. r7, rp, 29,31,31') C (rp >> 3) mod 2
  77. beq L(rp_aligned)
  78. subf n, r7, n
  79. L(top0):
  80. LIMB32(`lwz r0, 12(up) ')
  81. LIMB64(`ld r0, 8(up) ')
  82. addi up, up, -GMP_LIMB_BYTES
  83. LIMB32(`addic. r7, r7, -1 ')
  84. LIMB32(`stw r0, 12(rp) ')
  85. LIMB64(`std r0, 8(rp) ')
  86. addi rp, rp, -GMP_LIMB_BYTES
  87. LIMB32(`bne L(top0) ')
  88. L(rp_aligned):
  89. LIMB32(`rlwinm. r0, up, 30,30,31') C (up >> 2) mod 4
  90. LIMB64(`rlwinm. r0, up, 29,31,31') C (up >> 3) mod 2
  91. LIMB64(`srdi r7, n, 2 ') C loop count corresponding to n
  92. LIMB32(`srwi r7, n, 3 ') C loop count corresponding to n
  93. mtctr r7 C copy n to count register
  94. li r10, -16
  95. beq L(up_aligned)
  96. lvsl us, 0, up
  97. addi up, up, 16
  98. LIMB32(`andi. r0, n, 0x4 ')
  99. LIMB64(`andi. r0, n, 0x2 ')
  100. beq L(1)
  101. lvx v0, 0, up
  102. lvx v2, r10, up
  103. vperm v3, v2, v0, us
  104. stvx v3, 0, rp
  105. addi up, up, -32
  106. addi rp, rp, -16
  107. b L(lpu)
  108. L(1): lvx v2, 0, up
  109. addi up, up, -16
  110. b L(lpu)
  111. ALIGN(32)
  112. L(lpu): lvx v0, 0, up
  113. vperm v3, v0, v2, us
  114. stvx v3, 0, rp
  115. lvx v2, r10, up
  116. addi up, up, -32
  117. vperm v3, v2, v0, us
  118. stvx v3, r10, rp
  119. addi rp, rp, -32
  120. bdnz L(lpu)
  121. b L(tail)
  122. L(up_aligned):
  123. LIMB32(`andi. r0, n, 0x4 ')
  124. LIMB64(`andi. r0, n, 0x2 ')
  125. beq L(lpa)
  126. lvx v0, 0,   up
  127. stvx v0, 0,   rp
  128. addi up, up, -16
  129. addi rp, rp, -16
  130. b L(lpa)
  131. ALIGN(32)
  132. L(lpa): lvx v0, 0,   up
  133. lvx v1, r10, up
  134. addi up, up, -32
  135. nop
  136. stvx v0, 0,   rp
  137. stvx v1, r10, rp
  138. addi rp, rp, -32
  139. bdnz L(lpa)
  140. L(tail):
  141. LIMB32(`rlwinm. r7, n, 0,30,31 ') C r7 = n mod 4
  142. LIMB64(`rlwinm. r7, n, 0,31,31 ') C r7 = n mod 2
  143. beq L(ret)
  144. LIMB32(`li r10, 12 ')
  145. L(top2):
  146. LIMB32(`lwzx r0, r10, up ')
  147. LIMB64(`ld r0, 8(up) ')
  148. LIMB32(`addic. r7, r7, -1 ')
  149. LIMB32(`stwx r0, r10, rp ')
  150. LIMB64(`std r0, 8(rp) ')
  151. LIMB32(`addi r10, r10, -GMP_LIMB_BYTES')
  152. LIMB32(`bne L(top2) ')
  153. L(ret): mtspr 256, r12
  154. blr
  155. EPILOGUE()