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

数学计算

开发平台:

Unix_Linux

  1. dnl  AMD64 mpn_sqr_basecase.
  2. dnl  Contributed to the GNU project by Torbjorn Granlund.
  3. dnl  Copyright 2008, 2009 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 The inner loops of this code are the result of running a code generation and
  17. C optimization tool suite written by David Harvey and Torbjorn Granlund.
  18. C NOTES
  19. C   * This code only handles operands up to SQR_TOOM2_THRESHOLD_MAX.  That
  20. C     means we can safely use 32-bit operations for all sizes, unlike in e.g.,
  21. C     mpn_addmul_1.
  22. C   * The jump table could probably be optimized, at least for non-pic.
  23. C   * The special code for n=1,2,3 was quickly written.  It is probably too
  24. C     large and unnecessarily slow.
  25. C   * Consider combining small cases code so that the n=k-1 code jumps into
  26. C     the middle of the n=k code.
  27. C   * Avoid saving registers for small cases code.
  28. C   * Needed variables:
  29. C    n   r11  input size
  30. C    i   r8   work left, initially n
  31. C    j   r9   inner loop count
  32. C        r15  unused
  33. C    v0  r13
  34. C    v1  r14
  35. C    rp  rdi
  36. C    up  rsi
  37. C    w0  rbx
  38. C    w1  rcx
  39. C    w2  rbp
  40. C    w3  r10
  41. C    tp  r12
  42. C    lo  rax
  43. C    hi  rdx
  44. C        rsp
  45. C INPUT PARAMETERS
  46. define(`rp',   `%rdi')
  47. define(`up',   `%rsi')
  48. define(`n_param', `%rdx')
  49. C We should really trim this, for better spatial locality.  Alternatively,
  50. C we could grab the upper part of the stack area, leaving the lower part
  51. C instead of the upper part unused.
  52. deflit(SQR_TOOM2_THRESHOLD_MAX, 80)
  53. define(`STACK_ALLOC', eval(8*2*SQR_TOOM2_THRESHOLD_MAX))
  54. define(`n', `%r11')
  55. define(`tp', `%r12')
  56. define(`i', `%r8')
  57. define(`j', `%r9')
  58. define(`v0', `%r13')
  59. define(`v1', `%r14')
  60. define(`w0', `%rbx')
  61. define(`w1', `%rcx')
  62. define(`w2', `%rbp')
  63. define(`w3', `%r10')
  64. ASM_START()
  65. TEXT
  66. ALIGN(16)
  67. PROLOGUE(mpn_sqr_basecase)
  68. add $-48, %rsp
  69. mov %rbx, 40(%rsp)
  70. mov %rbp, 32(%rsp)
  71. mov %r12, 24(%rsp)
  72. mov %r13, 16(%rsp)
  73. mov %r14, 8(%rsp)
  74. mov R32(n_param), R32(n) C free original n register (rdx)
  75. mov R32(n_param), R32(%rcx)
  76. and $3, R32(%rcx)
  77. lea 4(%rcx), %rbx
  78. cmp $4, R32(n_param)
  79. cmovg %rbx, %rcx
  80. lea L(jmptab)(%rip), %rax
  81. jmp *(%rax,%rcx,8)
  82. JUMPTABSECT
  83. ALIGN(8)
  84. L(jmptab):
  85. .quad L(4)
  86. .quad L(1)
  87. .quad L(2)
  88. .quad L(3)
  89. .quad L(0m4)
  90. .quad L(1m4)
  91. .quad L(2m4)
  92. .quad L(3m4)
  93. TEXT
  94. L(1): mov (up), %rax
  95. mul %rax
  96. mov %rax, (rp)
  97. mov %rdx, 8(rp)
  98. add $40, %rsp
  99. pop %rbx
  100. ret
  101. L(2): mov (up), %rax
  102. mul %rax
  103. mov %rax, (rp)
  104. mov %rdx, %r9
  105. mov 8(up), %rax
  106. mul %rax
  107. mov %rax, %r10
  108. mov %rdx, %r11
  109. mov 8(up), %rax
  110. mov (up), %rbx
  111. mul %rbx
  112. add %rax, %r9
  113. adc %rdx, %r10
  114. adc $0, %r11
  115. add %rax, %r9
  116. mov %r9, 8(rp)
  117. adc %rdx, %r10
  118. mov %r10, 16(rp)
  119. adc $0, %r11
  120. mov %r11, 24(rp)
  121. add $40, %rsp
  122. pop %rbx
  123. ret
  124. L(3): mov (up), %rax
  125. mul %rax
  126. mov %rax, (rp)
  127. mov %rdx, 8(rp)
  128. mov 8(up), %rax
  129. mul %rax
  130. mov %rax, 16(rp)
  131. mov %rdx, 24(rp)
  132. mov 16(up), %rax
  133. mul %rax
  134. mov %rax, 32(rp)
  135. mov %rdx, 40(rp)
  136. mov (up), %rbx
  137. mov 8(up), %rax
  138. mul %rbx
  139. mov %rax, %r8
  140. mov %rdx, %r9
  141. mov 16(up), %rax
  142. mul %rbx
  143. xor R32(%r10), R32(%r10)
  144. add %rax, %r9
  145. adc %rdx, %r10
  146. mov 8(up), %rbx
  147. mov 16(up), %rax
  148. mul %rbx
  149. xor R32(%r11), R32(%r11)
  150. add %rax, %r10
  151. adc %rdx, %r11
  152. add %r8, %r8
  153. adc %r9, %r9
  154. adc %r10, %r10
  155. adc %r11, %r11
  156. mov $0, R32(%rbx)
  157. adc %rbx, %rbx
  158. add %r8, 8(rp)
  159. adc %r9, 16(rp)
  160. adc %r10, 24(rp)
  161. adc %r11, 32(rp)
  162. adc %rbx, 40(rp)
  163. add $40, %rsp
  164. pop %rbx
  165. ret
  166. L(4): mov (up), %rax
  167. mul %rax
  168. mov %rax, (rp)
  169. mov %rdx, 8(rp)
  170. mov 8(up), %rax
  171. mul %rax
  172. mov %rax, 16(rp)
  173. mov %rdx, 24(rp)
  174. mov 16(up), %rax
  175. mul %rax
  176. mov %rax, 32(rp)
  177. mov %rdx, 40(rp)
  178. mov 24(up), %rax
  179. mul %rax
  180. mov %rax, 48(rp)
  181. mov %rdx, 56(rp)
  182. mov (up), %rbx
  183. mov 8(up), %rax
  184. mul %rbx
  185. mov %rax, %r8
  186. mov %rdx, %r9
  187. mov 16(up), %rax
  188. mul %rbx
  189. xor R32(%r10), R32(%r10)
  190. add %rax, %r9
  191. adc %rdx, %r10
  192. mov 24(up), %rax
  193. mul %rbx
  194. xor R32(%r11), R32(%r11)
  195. add %rax, %r10
  196. adc %rdx, %r11
  197. mov 8(up), %rbx
  198. mov 16(up), %rax
  199. mul %rbx
  200. xor R32(%r12), R32(%r12)
  201. add %rax, %r10
  202. adc %rdx, %r11
  203. adc $0, %r12
  204. mov 24(up), %rax
  205. mul %rbx
  206. add %rax, %r11
  207. adc %rdx, %r12
  208. mov 16(up), %rbx
  209. mov 24(up), %rax
  210. mul %rbx
  211. xor R32(%rbp), R32(%rbp)
  212. add %rax, %r12
  213. adc %rdx, %rbp
  214. add %r8, %r8
  215. adc %r9, %r9
  216. adc %r10, %r10
  217. adc %r11, %r11
  218. adc %r12, %r12
  219. mov $0, R32(%rbx)
  220. adc %rbp, %rbp
  221. adc %rbx, %rbx
  222. add %r8, 8(rp)
  223. adc %r9, 16(rp)
  224. adc %r10, 24(rp)
  225. adc %r11, 32(rp)
  226. adc %r12, 40(rp)
  227. adc %rbp, 48(rp)
  228. adc %rbx, 56(rp)
  229. add $24, %rsp
  230. pop %r12
  231. pop %rbp
  232. pop %rbx
  233. ret
  234. L(0m4): add $-STACK_ALLOC, %rsp
  235. lea -24(%rsp,n,8), tp C point tp in middle of result operand
  236. mov (up), v0
  237. mov 8(up), %rax
  238. lea (up,n,8), up C point up at end of input operand
  239. lea -4(n), i
  240. C Function mpn_mul_1_m3(tp, up - i, i, up[-i - 1])
  241. xor R32(j), R32(j)
  242. sub n, j
  243. mul v0
  244. xor R32(w2), R32(w2)
  245. mov %rax, w0
  246. mov 16(up,j,8), %rax
  247. mov %rdx, w3
  248. jmp L(L3)
  249. ALIGN(16)
  250. L(mul_1_m3_top):
  251. add %rax, w2
  252. mov w3, (tp,j,8)
  253. mov (up,j,8), %rax
  254. adc %rdx, w1
  255. xor R32(w0), R32(w0)
  256. mul v0
  257. xor R32(w3), R32(w3)
  258. mov w2, 8(tp,j,8)
  259. add %rax, w1
  260. adc %rdx, w0
  261. mov 8(up,j,8), %rax
  262. mov w1, 16(tp,j,8)
  263. xor R32(w2), R32(w2)
  264. mul v0
  265. add %rax, w0
  266. mov 16(up,j,8), %rax
  267. adc %rdx, w3
  268. L(L3): xor R32(w1), R32(w1)
  269. mul v0
  270. add %rax, w3
  271. mov 24(up,j,8), %rax
  272. adc %rdx, w2
  273. mov w0, 24(tp,j,8)
  274. mul v0
  275. add $4, j
  276. js L(mul_1_m3_top)
  277. add %rax, w2
  278. mov w3, (tp)
  279. adc %rdx, w1
  280. mov w2, 8(tp)
  281. mov w1, 16(tp)
  282. lea eval(2*8)(tp), tp C tp += 2
  283. lea -8(up), up
  284. jmp L(dowhile)
  285. L(1m4): add $-STACK_ALLOC, %rsp
  286. lea (%rsp,n,8), tp C point tp in middle of result operand
  287. mov (up), v0 C u0
  288. mov 8(up), %rax C u1
  289. lea 8(up,n,8), up C point up at end of input operand
  290. lea -3(n), i
  291. C Function mpn_mul_2s_m0(tp, up - i, i, up - i - 1)
  292. lea -3(n), j
  293. neg j
  294. mov %rax, v1 C u1
  295. mul v0 C u0 * u1
  296. mov %rdx, w1
  297. xor R32(w2), R32(w2)
  298. mov %rax, (%rsp)
  299. jmp L(m0)
  300. ALIGN(16)
  301. L(mul_2_m0_top):
  302. mul v1
  303. add %rax, w0
  304. adc %rdx, w1
  305. mov -24(up,j,8), %rax
  306. mov $0, R32(w2)
  307. mul v0
  308. add %rax, w0
  309. mov -24(up,j,8), %rax
  310. adc %rdx, w1
  311. adc $0, R32(w2)
  312. mul v1 C v1 * u0
  313. add %rax, w1
  314. mov w0, -24(tp,j,8)
  315. adc %rdx, w2
  316. L(m0): mov -16(up,j,8), %rax C u2, u6 ...
  317. mul v0 C u0 * u2
  318. mov $0, R32(w3)
  319. add %rax, w1
  320. adc %rdx, w2
  321. mov -16(up,j,8), %rax
  322. adc $0, R32(w3)
  323. mov $0, R32(w0)
  324. mov w1, -16(tp,j,8)
  325. mul v1
  326. add %rax, w2
  327. mov -8(up,j,8), %rax
  328. adc %rdx, w3
  329. mov $0, R32(w1)
  330. mul v0
  331. add %rax, w2
  332. mov -8(up,j,8), %rax
  333. adc %rdx, w3
  334. adc $0, R32(w0)
  335. mul v1
  336. add %rax, w3
  337. mov w2, -8(tp,j,8)
  338. adc %rdx, w0
  339. L(m2x): mov (up,j,8), %rax
  340. mul v0
  341. add %rax, w3
  342. adc %rdx, w0
  343. adc $0, R32(w1)
  344. add $4, j
  345. mov -32(up,j,8), %rax
  346. mov w3, -32(tp,j,8)
  347. js L(mul_2_m0_top)
  348. mul v1
  349. add %rax, w0
  350. adc %rdx, w1
  351. mov w0, -8(tp)
  352. mov w1, (tp)
  353. lea -16(up), up
  354. lea eval(3*8-24)(tp), tp C tp += 3
  355. jmp L(dowhile_end)
  356. L(2m4): add $-STACK_ALLOC, %rsp
  357. lea -24(%rsp,n,8), tp C point tp in middle of result operand
  358. mov (up), v0
  359. mov 8(up), %rax
  360. lea (up,n,8), up C point up at end of input operand
  361. lea -4(n), i
  362. C Function mpn_mul_1_m1(tp, up - (i - 1), i - 1, up[-i])
  363. lea -2(n), j
  364. neg j
  365. mul v0
  366. mov %rax, w2
  367. mov (up,j,8), %rax
  368. mov %rdx, w1
  369. jmp L(L1)
  370. ALIGN(16)
  371. L(mul_1_m1_top):
  372. add %rax, w2
  373. mov w3, (tp,j,8)
  374. mov (up,j,8), %rax
  375. adc %rdx, w1
  376. L(L1): xor R32(w0), R32(w0)
  377. mul v0
  378. xor R32(w3), R32(w3)
  379. mov w2, 8(tp,j,8)
  380. add %rax, w1
  381. adc %rdx, w0
  382. mov 8(up,j,8), %rax
  383. mov w1, 16(tp,j,8)
  384. xor R32(w2), R32(w2)
  385. mul v0
  386. add %rax, w0
  387. mov 16(up,j,8), %rax
  388. adc %rdx, w3
  389. xor R32(w1), R32(w1)
  390. mul v0
  391. add %rax, w3
  392. mov 24(up,j,8), %rax
  393. adc %rdx, w2
  394. mov w0, 24(tp,j,8)
  395. mul v0
  396. add $4, j
  397. js L(mul_1_m1_top)
  398. add %rax, w2
  399. mov w3, (tp)
  400. adc %rdx, w1
  401. mov w2, 8(tp)
  402. mov w1, 16(tp)
  403. lea eval(2*8)(tp), tp C tp += 2
  404. lea -8(up), up
  405. jmp L(dowhile_mid)
  406. L(3m4): add $-STACK_ALLOC, %rsp
  407. lea (%rsp,n,8), tp C point tp in middle of result operand
  408. mov (up), v0 C u0
  409. mov 8(up), %rax C u1
  410. lea 8(up,n,8), up C point up at end of input operand
  411. lea -5(n), i
  412. C Function mpn_mul_2s_m2(tp, up - i + 1, i - 1, up - i)
  413. lea -1(n), j
  414. neg j
  415. mov %rax, v1 C u1
  416. mul v0 C u0 * u1
  417. mov %rdx, w3
  418. xor R32(w0), R32(w0)
  419. xor R32(w1), R32(w1)
  420. mov %rax, (%rsp)
  421. jmp L(m2)
  422. ALIGN(16)
  423. L(mul_2_m2_top):
  424. mul v1
  425. add %rax, w0
  426. adc %rdx, w1
  427. mov -24(up,j,8), %rax
  428. mov $0, R32(w2)
  429. mul v0
  430. add %rax, w0
  431. mov -24(up,j,8), %rax
  432. adc %rdx, w1
  433. adc $0, R32(w2)
  434. mul v1 C v1 * u0
  435. add %rax, w1
  436. mov w0, -24(tp,j,8)
  437. adc %rdx, w2
  438. mov -16(up,j,8), %rax
  439. mul v0
  440. mov $0, R32(w3)
  441. add %rax, w1
  442. adc %rdx, w2
  443. mov -16(up,j,8), %rax
  444. adc $0, R32(w3)
  445. mov $0, R32(w0)
  446. mov w1, -16(tp,j,8)
  447. mul v1
  448. add %rax, w2
  449. mov -8(up,j,8), %rax
  450. adc %rdx, w3
  451. mov $0, R32(w1)
  452. mul v0
  453. add %rax, w2
  454. mov -8(up,j,8), %rax
  455. adc %rdx, w3
  456. adc $0, R32(w0)
  457. mul v1
  458. add %rax, w3
  459. mov w2, -8(tp,j,8)
  460. adc %rdx, w0
  461. L(m2): mov (up,j,8), %rax
  462. mul v0
  463. add %rax, w3
  464. adc %rdx, w0
  465. adc $0, R32(w1)
  466. add $4, j
  467. mov -32(up,j,8), %rax
  468. mov w3, -32(tp,j,8)
  469. js L(mul_2_m2_top)
  470. mul v1
  471. add %rax, w0
  472. adc %rdx, w1
  473. mov w0, -8(tp)
  474. mov w1, (tp)
  475. lea -16(up), up
  476. jmp L(dowhile_mid)
  477. L(dowhile):
  478. C Function mpn_addmul_2s_m2(tp, up - (i - 1), i - 1, up - i)
  479. lea 4(i), j
  480. neg j
  481. mov 16(up,j,8), v0
  482. mov 24(up,j,8), v1
  483. mov 24(up,j,8), %rax
  484. mul v0
  485. xor R32(w3), R32(w3)
  486. add %rax, 24(tp,j,8)
  487. adc %rdx, w3
  488. xor R32(w0), R32(w0)
  489. xor R32(w1), R32(w1)
  490. jmp L(am2)
  491. ALIGN(16)
  492. L(addmul_2_m2_top):
  493. add w3, (tp,j,8)
  494. adc %rax, w0
  495. mov 8(up,j,8), %rax
  496. adc %rdx, w1
  497. mov $0, R32(w2)
  498. mul v0
  499. add %rax, w0
  500. mov 8(up,j,8), %rax
  501. adc %rdx, w1
  502. adc $0, R32(w2)
  503. mul v1 C v1 * u0
  504. add w0, 8(tp,j,8)
  505. adc %rax, w1
  506. adc %rdx, w2
  507. mov 16(up,j,8), %rax
  508. mov $0, R32(w3)
  509. mul v0 C v0 * u1
  510. add %rax, w1
  511. mov 16(up,j,8), %rax
  512. adc %rdx, w2
  513. adc $0, R32(w3)
  514. mul v1 C v1 * u1
  515. add w1, 16(tp,j,8)
  516. adc %rax, w2
  517. mov 24(up,j,8), %rax
  518. adc %rdx, w3
  519. mul v0
  520. mov $0, R32(w0)
  521. add %rax, w2
  522. adc %rdx, w3
  523. mov $0, R32(w1)
  524. mov 24(up,j,8), %rax
  525. adc $0, R32(w0)
  526. mul v1
  527. add w2, 24(tp,j,8)
  528. adc %rax, w3
  529. adc %rdx, w0
  530. L(am2): mov 32(up,j,8), %rax
  531. mul v0
  532. add %rax, w3
  533. mov 32(up,j,8), %rax
  534. adc %rdx, w0
  535. adc $0, R32(w1)
  536. mul v1
  537. add $4, j
  538. js L(addmul_2_m2_top)
  539. add w3, (tp)
  540. adc %rax, w0
  541. adc %rdx, w1
  542. mov w0, 8(tp)
  543. mov w1, 16(tp)
  544. lea eval(2*8)(tp), tp C tp += 2
  545. add $-2, R32(i) C i -= 2
  546. L(dowhile_mid):
  547. C Function mpn_addmul_2s_m0(tp, up - (i - 1), i - 1, up - i)
  548. lea 2(i), j
  549. neg j
  550. mov (up,j,8), v0
  551. mov 8(up,j,8), v1
  552. mov 8(up,j,8), %rax
  553. mul v0
  554. xor R32(w1), R32(w1)
  555. add %rax, 8(tp,j,8)
  556. adc %rdx, w1
  557. xor R32(w2), R32(w2)
  558. jmp L(20)
  559. ALIGN(16)
  560. L(addmul_2_m0_top):
  561. add w3, (tp,j,8)
  562. adc %rax, w0
  563. mov 8(up,j,8), %rax
  564. adc %rdx, w1
  565. mov $0, R32(w2)
  566. mul v0
  567. add %rax, w0
  568. mov 8(up,j,8), %rax
  569. adc %rdx, w1
  570. adc $0, R32(w2)
  571. mul v1 C v1 * u0
  572. add w0, 8(tp,j,8)
  573. adc %rax, w1
  574. adc %rdx, w2
  575. L(20): mov 16(up,j,8), %rax
  576. mov $0, R32(w3)
  577. mul v0 C v0 * u1
  578. add %rax, w1
  579. mov 16(up,j,8), %rax
  580. adc %rdx, w2
  581. adc $0, R32(w3)
  582. mul v1 C v1 * u1
  583. add w1, 16(tp,j,8)
  584. adc %rax, w2
  585. mov 24(up,j,8), %rax
  586. adc %rdx, w3
  587. mul v0
  588. mov $0, R32(w0)
  589. add %rax, w2
  590. adc %rdx, w3
  591. mov $0, R32(w1)
  592. mov 24(up,j,8), %rax
  593. adc $0, R32(w0)
  594. mul v1
  595. add w2, 24(tp,j,8)
  596. adc %rax, w3
  597. adc %rdx, w0
  598. mov 32(up,j,8), %rax
  599. mul v0
  600. add %rax, w3
  601. mov 32(up,j,8), %rax
  602. adc %rdx, w0
  603. adc $0, R32(w1)
  604. mul v1
  605. add $4, j
  606. js L(addmul_2_m0_top)
  607. add w3, (tp)
  608. adc %rax, w0
  609. adc %rdx, w1
  610. mov w0, 8(tp)
  611. mov w1, 16(tp)
  612. lea eval(2*8)(tp), tp C tp += 2
  613. L(dowhile_end):
  614. add $-2, R32(i) C i -= 2
  615. jne L(dowhile)
  616. C Function mpn_addmul_2s_2
  617. mov -16(up), v0
  618. mov -8(up), v1
  619. mov -8(up), %rax
  620. mul v0
  621. xor R32(w3), R32(w3)
  622. add %rax, -8(tp)
  623. adc %rdx, w3
  624. xor R32(w0), R32(w0)
  625. xor R32(w1), R32(w1)
  626. mov (up), %rax
  627. mul v0
  628. add %rax, w3
  629. mov (up), %rax
  630. adc %rdx, w0
  631. mul v1
  632. add w3, (tp)
  633. adc %rax, w0
  634. adc %rdx, w1
  635. mov w0, 8(tp)
  636. mov w1, 16(tp)
  637. C Function mpn_sqr_diag_addlsh1
  638. lea -4(n,n), j
  639. mov (%rsp), %r11
  640. lea (rp,j,8), rp
  641. lea -8(up), up
  642. lea 8(%rsp,j,8), tp
  643. neg j
  644. mov (up,j,4), %rax
  645. mul %rax
  646. test $2, R8(j)
  647. jnz L(odd)
  648. L(evn): add %r11, %r11
  649. sbb R32(%rbx), R32(%rbx) C save CF
  650. add %rdx, %r11
  651. mov %rax, (rp,j,8)
  652. jmp L(d0)
  653. L(odd): add %r11, %r11
  654. sbb R32(%rbp), R32(%rbp) C save CF
  655. add %rdx, %r11
  656. mov %rax, (rp,j,8)
  657. lea -2(j), j
  658. jmp L(d1)
  659. ALIGN(16)
  660. L(top): mov (up,j,4), %rax
  661. mul %rax
  662. add R32(%rbp), R32(%rbp) C restore carry
  663. adc %rax, %r10
  664. adc %rdx, %r11
  665. mov %r10, (rp,j,8)
  666. L(d0): mov %r11, 8(rp,j,8)
  667. mov (tp,j,8), %r10
  668. adc %r10, %r10
  669. mov 8(tp,j,8), %r11
  670. adc %r11, %r11
  671. nop
  672. sbb R32(%rbp), R32(%rbp) C save CF
  673. mov 8(up,j,4), %rax
  674. mul %rax
  675. add R32(%rbx), R32(%rbx) C restore carry
  676. adc %rax, %r10
  677. adc %rdx, %r11
  678. mov %r10, 16(rp,j,8)
  679. L(d1): mov %r11, 24(rp,j,8)
  680. mov 16(tp,j,8), %r10
  681. adc %r10, %r10
  682. mov 24(tp,j,8), %r11
  683. adc %r11, %r11
  684. sbb R32(%rbx), R32(%rbx) C save CF
  685. add $4, j
  686. js L(top)
  687. mov (up), %rax
  688. mul %rax
  689. add R32(%rbp), R32(%rbp) C restore carry
  690. adc %rax, %r10
  691. adc %rdx, %r11
  692. mov %r10, (rp)
  693. mov %r11, 8(rp)
  694. mov (tp), %r10
  695. adc %r10, %r10
  696. sbb R32(%rbp), R32(%rbp) C save CF
  697. neg R32(%rbp)
  698. mov 8(up), %rax
  699. mul %rax
  700. add R32(%rbx), R32(%rbx) C restore carry
  701. adc %rax, %r10
  702. adc %rbp, %rdx
  703. mov %r10, 16(rp)
  704. mov %rdx, 24(rp)
  705. add $eval(8+STACK_ALLOC), %rsp
  706. pop %r14
  707. pop %r13
  708. pop %r12
  709. pop %rbp
  710. pop %rbx
  711. ret
  712. EPILOGUE()