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

数学计算

开发平台:

Unix_Linux

  1. dnl  SPARC mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
  2. dnl  store difference in a third limb vector.
  3. dnl  Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
  4. dnl  This file is part of the GNU MP Library.
  5. dnl  The GNU MP Library is free software; you can redistribute it and/or modify
  6. dnl  it under the terms of the GNU Lesser General Public License as published
  7. dnl  by the Free Software Foundation; either version 3 of the License, or (at
  8. dnl  your option) any later version.
  9. dnl  The GNU MP Library is distributed in the hope that it will be useful, but
  10. dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  12. dnl  License for more details.
  13. dnl  You should have received a copy of the GNU Lesser General Public License
  14. dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
  15. include(`../config.m4')
  16. C INPUT PARAMETERS
  17. define(res_ptr,%o0)
  18. define(s1_ptr,%o1)
  19. define(s2_ptr,%o2)
  20. define(n,%o3)
  21. ASM_START()
  22. PROLOGUE(mpn_sub_n)
  23. xor s2_ptr,res_ptr,%g1
  24. andcc %g1,4,%g0
  25. bne L(1) C branch if alignment differs
  26. nop
  27. C **  V1a  **
  28. andcc res_ptr,4,%g0 C res_ptr unaligned? Side effect: cy=0
  29. be L(v1) C if no, branch
  30. nop
  31. C Add least significant limb separately to align res_ptr and s2_ptr
  32. ld [s1_ptr],%g4
  33. add s1_ptr,4,s1_ptr
  34. ld [s2_ptr],%g2
  35. add s2_ptr,4,s2_ptr
  36. add n,-1,n
  37. subcc %g4,%g2,%o4
  38. st %o4,[res_ptr]
  39. add res_ptr,4,res_ptr
  40. L(v1): addx %g0,%g0,%o4 C save cy in register
  41. cmp n,2 C if n < 2 ...
  42. bl L(end2) C ... branch to tail code
  43. subcc %g0,%o4,%g0 C restore cy
  44. ld [s1_ptr+0],%g4
  45. addcc n,-10,n
  46. ld [s1_ptr+4],%g1
  47. ldd [s2_ptr+0],%g2
  48. blt L(fin1)
  49. subcc %g0,%o4,%g0 C restore cy
  50. C Add blocks of 8 limbs until less than 8 limbs remain
  51. L(loop1):
  52. subxcc %g4,%g2,%o4
  53. ld [s1_ptr+8],%g4
  54. subxcc %g1,%g3,%o5
  55. ld [s1_ptr+12],%g1
  56. ldd [s2_ptr+8],%g2
  57. std %o4,[res_ptr+0]
  58. subxcc %g4,%g2,%o4
  59. ld [s1_ptr+16],%g4
  60. subxcc %g1,%g3,%o5
  61. ld [s1_ptr+20],%g1
  62. ldd [s2_ptr+16],%g2
  63. std %o4,[res_ptr+8]
  64. subxcc %g4,%g2,%o4
  65. ld [s1_ptr+24],%g4
  66. subxcc %g1,%g3,%o5
  67. ld [s1_ptr+28],%g1
  68. ldd [s2_ptr+24],%g2
  69. std %o4,[res_ptr+16]
  70. subxcc %g4,%g2,%o4
  71. ld [s1_ptr+32],%g4
  72. subxcc %g1,%g3,%o5
  73. ld [s1_ptr+36],%g1
  74. ldd [s2_ptr+32],%g2
  75. std %o4,[res_ptr+24]
  76. addx %g0,%g0,%o4 C save cy in register
  77. addcc n,-8,n
  78. add s1_ptr,32,s1_ptr
  79. add s2_ptr,32,s2_ptr
  80. add res_ptr,32,res_ptr
  81. bge L(loop1)
  82. subcc %g0,%o4,%g0 C restore cy
  83. L(fin1):
  84. addcc n,8-2,n
  85. blt L(end1)
  86. subcc %g0,%o4,%g0 C restore cy
  87. C Add blocks of 2 limbs until less than 2 limbs remain
  88. L(loope1):
  89. subxcc %g4,%g2,%o4
  90. ld [s1_ptr+8],%g4
  91. subxcc %g1,%g3,%o5
  92. ld [s1_ptr+12],%g1
  93. ldd [s2_ptr+8],%g2
  94. std %o4,[res_ptr+0]
  95. addx %g0,%g0,%o4 C save cy in register
  96. addcc n,-2,n
  97. add s1_ptr,8,s1_ptr
  98. add s2_ptr,8,s2_ptr
  99. add res_ptr,8,res_ptr
  100. bge L(loope1)
  101. subcc %g0,%o4,%g0 C restore cy
  102. L(end1):
  103. subxcc %g4,%g2,%o4
  104. subxcc %g1,%g3,%o5
  105. std %o4,[res_ptr+0]
  106. addx %g0,%g0,%o4 C save cy in register
  107. andcc n,1,%g0
  108. be L(ret1)
  109. subcc %g0,%o4,%g0 C restore cy
  110. C Add last limb
  111. ld [s1_ptr+8],%g4
  112. ld [s2_ptr+8],%g2
  113. subxcc %g4,%g2,%o4
  114. st %o4,[res_ptr+8]
  115. L(ret1):
  116. retl
  117. addx %g0,%g0,%o0 C return carry-out from most sign. limb
  118. L(1): xor s1_ptr,res_ptr,%g1
  119. andcc %g1,4,%g0
  120. bne L(2)
  121. nop
  122. C **  V1b  **
  123. andcc res_ptr,4,%g0 C res_ptr unaligned? Side effect: cy=0
  124. be L(v1b) C if no, branch
  125. nop
  126. C Add least significant limb separately to align res_ptr and s1_ptr
  127. ld [s2_ptr],%g4
  128. add s2_ptr,4,s2_ptr
  129. ld [s1_ptr],%g2
  130. add s1_ptr,4,s1_ptr
  131. add n,-1,n
  132. subcc %g2,%g4,%o4
  133. st %o4,[res_ptr]
  134. add res_ptr,4,res_ptr
  135. L(v1b): addx %g0,%g0,%o4 C save cy in register
  136. cmp n,2 C if n < 2 ...
  137. bl L(end2) C ... branch to tail code
  138. subcc %g0,%o4,%g0 C restore cy
  139. ld [s2_ptr+0],%g4
  140. addcc n,-10,n
  141. ld [s2_ptr+4],%g1
  142. ldd [s1_ptr+0],%g2
  143. blt L(fin1b)
  144. subcc %g0,%o4,%g0 C restore cy
  145. C Add blocks of 8 limbs until less than 8 limbs remain
  146. L(loop1b):
  147. subxcc %g2,%g4,%o4
  148. ld [s2_ptr+8],%g4
  149. subxcc %g3,%g1,%o5
  150. ld [s2_ptr+12],%g1
  151. ldd [s1_ptr+8],%g2
  152. std %o4,[res_ptr+0]
  153. subxcc %g2,%g4,%o4
  154. ld [s2_ptr+16],%g4
  155. subxcc %g3,%g1,%o5
  156. ld [s2_ptr+20],%g1
  157. ldd [s1_ptr+16],%g2
  158. std %o4,[res_ptr+8]
  159. subxcc %g2,%g4,%o4
  160. ld [s2_ptr+24],%g4
  161. subxcc %g3,%g1,%o5
  162. ld [s2_ptr+28],%g1
  163. ldd [s1_ptr+24],%g2
  164. std %o4,[res_ptr+16]
  165. subxcc %g2,%g4,%o4
  166. ld [s2_ptr+32],%g4
  167. subxcc %g3,%g1,%o5
  168. ld [s2_ptr+36],%g1
  169. ldd [s1_ptr+32],%g2
  170. std %o4,[res_ptr+24]
  171. addx %g0,%g0,%o4 C save cy in register
  172. addcc n,-8,n
  173. add s1_ptr,32,s1_ptr
  174. add s2_ptr,32,s2_ptr
  175. add res_ptr,32,res_ptr
  176. bge L(loop1b)
  177. subcc %g0,%o4,%g0 C restore cy
  178. L(fin1b):
  179. addcc n,8-2,n
  180. blt L(end1b)
  181. subcc %g0,%o4,%g0 C restore cy
  182. C Add blocks of 2 limbs until less than 2 limbs remain
  183. L(loope1b):
  184. subxcc %g2,%g4,%o4
  185. ld [s2_ptr+8],%g4
  186. subxcc %g3,%g1,%o5
  187. ld [s2_ptr+12],%g1
  188. ldd [s1_ptr+8],%g2
  189. std %o4,[res_ptr+0]
  190. addx %g0,%g0,%o4 C save cy in register
  191. addcc n,-2,n
  192. add s1_ptr,8,s1_ptr
  193. add s2_ptr,8,s2_ptr
  194. add res_ptr,8,res_ptr
  195. bge L(loope1b)
  196. subcc %g0,%o4,%g0 C restore cy
  197. L(end1b):
  198. subxcc %g2,%g4,%o4
  199. subxcc %g3,%g1,%o5
  200. std %o4,[res_ptr+0]
  201. addx %g0,%g0,%o4 C save cy in register
  202. andcc n,1,%g0
  203. be L(ret1b)
  204. subcc %g0,%o4,%g0 C restore cy
  205. C Add last limb
  206. ld [s2_ptr+8],%g4
  207. ld [s1_ptr+8],%g2
  208. subxcc %g2,%g4,%o4
  209. st %o4,[res_ptr+8]
  210. L(ret1b):
  211. retl
  212. addx %g0,%g0,%o0 C return carry-out from most sign. limb
  213. C **  V2  **
  214. C If we come here, the alignment of s1_ptr and res_ptr as well as the
  215. C alignment of s2_ptr and res_ptr differ.  Since there are only two ways
  216. C things can be aligned (that we care about) we now know that the alignment
  217. C of s1_ptr and s2_ptr are the same.
  218. L(2): cmp n,1
  219. be L(jone)
  220. nop
  221. andcc s1_ptr,4,%g0 C s1_ptr unaligned? Side effect: cy=0
  222. be L(v2) C if no, branch
  223. nop
  224. C Add least significant limb separately to align s1_ptr and s2_ptr
  225. ld [s1_ptr],%g4
  226. add s1_ptr,4,s1_ptr
  227. ld [s2_ptr],%g2
  228. add s2_ptr,4,s2_ptr
  229. add n,-1,n
  230. subcc %g4,%g2,%o4
  231. st %o4,[res_ptr]
  232. add res_ptr,4,res_ptr
  233. L(v2): addx %g0,%g0,%o4 C save cy in register
  234. addcc n,-8,n
  235. blt L(fin2)
  236. subcc %g0,%o4,%g0 C restore cy
  237. C Add blocks of 8 limbs until less than 8 limbs remain
  238. L(loop2):
  239. ldd [s1_ptr+0],%g2
  240. ldd [s2_ptr+0],%o4
  241. subxcc %g2,%o4,%g2
  242. st %g2,[res_ptr+0]
  243. subxcc %g3,%o5,%g3
  244. st %g3,[res_ptr+4]
  245. ldd [s1_ptr+8],%g2
  246. ldd [s2_ptr+8],%o4
  247. subxcc %g2,%o4,%g2
  248. st %g2,[res_ptr+8]
  249. subxcc %g3,%o5,%g3
  250. st %g3,[res_ptr+12]
  251. ldd [s1_ptr+16],%g2
  252. ldd [s2_ptr+16],%o4
  253. subxcc %g2,%o4,%g2
  254. st %g2,[res_ptr+16]
  255. subxcc %g3,%o5,%g3
  256. st %g3,[res_ptr+20]
  257. ldd [s1_ptr+24],%g2
  258. ldd [s2_ptr+24],%o4
  259. subxcc %g2,%o4,%g2
  260. st %g2,[res_ptr+24]
  261. subxcc %g3,%o5,%g3
  262. st %g3,[res_ptr+28]
  263. addx %g0,%g0,%o4 C save cy in register
  264. addcc n,-8,n
  265. add s1_ptr,32,s1_ptr
  266. add s2_ptr,32,s2_ptr
  267. add res_ptr,32,res_ptr
  268. bge L(loop2)
  269. subcc %g0,%o4,%g0 C restore cy
  270. L(fin2):
  271. addcc n,8-2,n
  272. blt L(end2)
  273. subcc %g0,%o4,%g0 C restore cy
  274. L(loope2):
  275. ldd [s1_ptr+0],%g2
  276. ldd [s2_ptr+0],%o4
  277. subxcc %g2,%o4,%g2
  278. st %g2,[res_ptr+0]
  279. subxcc %g3,%o5,%g3
  280. st %g3,[res_ptr+4]
  281. addx %g0,%g0,%o4 C save cy in register
  282. addcc n,-2,n
  283. add s1_ptr,8,s1_ptr
  284. add s2_ptr,8,s2_ptr
  285. add res_ptr,8,res_ptr
  286. bge L(loope2)
  287. subcc %g0,%o4,%g0 C restore cy
  288. L(end2):
  289. andcc n,1,%g0
  290. be L(ret2)
  291. subcc %g0,%o4,%g0 C restore cy
  292. C Add last limb
  293. L(jone):
  294. ld [s1_ptr],%g4
  295. ld [s2_ptr],%g2
  296. subxcc %g4,%g2,%o4
  297. st %o4,[res_ptr]
  298. L(ret2):
  299. retl
  300. addx %g0,%g0,%o0 C return carry-out from most sign. limb
  301. EPILOGUE(mpn_sub_n)