head 1.1; branch 1.1.1; access; symbols netbsd-11-0-RELEASE:1.1.1.3 netbsd-11-0-RC7:1.1.1.3 netbsd-11-0-RC6:1.1.1.3 netbsd-11-0-RC5:1.1.1.3 netbsd-11-0-RC4:1.1.1.3 netbsd-11-0-RC3:1.1.1.3 netbsd-11-0-RC2:1.1.1.3 netbsd-11-0-RC1:1.1.1.3 perseant-exfatfs-base-20250801:1.1.1.3 netbsd-11:1.1.1.3.0.18 netbsd-11-base:1.1.1.3 netbsd-10-1-RELEASE:1.1.1.3 perseant-exfatfs-base-20240630:1.1.1.3 perseant-exfatfs:1.1.1.3.0.16 perseant-exfatfs-base:1.1.1.3 netbsd-8-3-RELEASE:1.1.1.2 netbsd-9-4-RELEASE:1.1.1.3 netbsd-10-0-RELEASE:1.1.1.3 netbsd-10-0-RC6:1.1.1.3 netbsd-10-0-RC5:1.1.1.3 netbsd-10-0-RC4:1.1.1.3 netbsd-10-0-RC3:1.1.1.3 netbsd-10-0-RC2:1.1.1.3 netbsd-10-0-RC1:1.1.1.3 netbsd-10:1.1.1.3.0.14 netbsd-10-base:1.1.1.3 netbsd-9-3-RELEASE:1.1.1.3 gmp-6-2-1:1.1.1.3 cjep_sun2x-base1:1.1.1.3 cjep_sun2x:1.1.1.3.0.12 cjep_sun2x-base:1.1.1.3 cjep_staticlib_x-base1:1.1.1.3 netbsd-9-2-RELEASE:1.1.1.3 cjep_staticlib_x:1.1.1.3.0.10 cjep_staticlib_x-base:1.1.1.3 netbsd-9-1-RELEASE:1.1.1.3 gmp-6-2-0:1.1.1.3 phil-wifi-20200421:1.1.1.3 phil-wifi-20200411:1.1.1.3 is-mlppp:1.1.1.3.0.8 is-mlppp-base:1.1.1.3 phil-wifi-20200406:1.1.1.3 netbsd-8-2-RELEASE:1.1.1.2 netbsd-9-0-RELEASE:1.1.1.3 netbsd-9-0-RC2:1.1.1.3 netbsd-9-0-RC1:1.1.1.3 phil-wifi-20191119:1.1.1.3 netbsd-9:1.1.1.3.0.6 netbsd-9-base:1.1.1.3 phil-wifi-20190609:1.1.1.3 netbsd-8-1-RELEASE:1.1.1.2 netbsd-8-1-RC1:1.1.1.2 pgoyette-compat-merge-20190127:1.1.1.3 pgoyette-compat-20190127:1.1.1.3 pgoyette-compat-20190118:1.1.1.3 pgoyette-compat-1226:1.1.1.3 pgoyette-compat-1126:1.1.1.3 pgoyette-compat-1020:1.1.1.3 pgoyette-compat-0930:1.1.1.3 pgoyette-compat-0906:1.1.1.3 netbsd-7-2-RELEASE:1.1.1.2 pgoyette-compat-0728:1.1.1.3 netbsd-8-0-RELEASE:1.1.1.2 phil-wifi:1.1.1.3.0.4 phil-wifi-base:1.1.1.3 pgoyette-compat-0625:1.1.1.3 netbsd-8-0-RC2:1.1.1.2 pgoyette-compat-0521:1.1.1.3 pgoyette-compat-0502:1.1.1.3 pgoyette-compat-0422:1.1.1.3 netbsd-8-0-RC1:1.1.1.2 pgoyette-compat-0415:1.1.1.3 pgoyette-compat-0407:1.1.1.3 pgoyette-compat-0330:1.1.1.3 pgoyette-compat-0322:1.1.1.3 pgoyette-compat-0315:1.1.1.3 netbsd-7-1-2-RELEASE:1.1.1.2 pgoyette-compat:1.1.1.3.0.2 pgoyette-compat-base:1.1.1.3 netbsd-7-1-1-RELEASE:1.1.1.2 matt-nb8-mediatek:1.1.1.2.0.22 matt-nb8-mediatek-base:1.1.1.2 gmp-6-1-2:1.1.1.3 perseant-stdc-iso10646:1.1.1.2.0.20 perseant-stdc-iso10646-base:1.1.1.2 netbsd-8:1.1.1.2.0.18 netbsd-8-base:1.1.1.2 prg-localcount2-base3:1.1.1.2 prg-localcount2-base2:1.1.1.2 prg-localcount2-base1:1.1.1.2 prg-localcount2:1.1.1.2.0.16 prg-localcount2-base:1.1.1.2 pgoyette-localcount-20170426:1.1.1.2 bouyer-socketcan-base1:1.1.1.2 pgoyette-localcount-20170320:1.1.1.2 netbsd-7-1:1.1.1.2.0.14 netbsd-7-1-RELEASE:1.1.1.2 netbsd-7-1-RC2:1.1.1.2 netbsd-7-nhusb-base-20170116:1.1.1.2 bouyer-socketcan:1.1.1.2.0.12 bouyer-socketcan-base:1.1.1.2 pgoyette-localcount-20170107:1.1.1.2 netbsd-7-1-RC1:1.1.1.2 pgoyette-localcount-20161104:1.1.1.2 netbsd-7-0-2-RELEASE:1.1.1.2 localcount-20160914:1.1.1.2 netbsd-7-nhusb:1.1.1.2.0.10 netbsd-7-nhusb-base:1.1.1.2 pgoyette-localcount-20160806:1.1.1.2 pgoyette-localcount-20160726:1.1.1.2 pgoyette-localcount:1.1.1.2.0.8 pgoyette-localcount-base:1.1.1.2 netbsd-7-0-1-RELEASE:1.1.1.2 netbsd-7-0:1.1.1.2.0.6 netbsd-7-0-RELEASE:1.1.1.2 netbsd-7-0-RC3:1.1.1.2 netbsd-7-0-RC2:1.1.1.2 netbsd-7-0-RC1:1.1.1.2 netbsd-6-0-6-RELEASE:1.1.1.1 netbsd-6-1-5-RELEASE:1.1.1.1 netbsd-7:1.1.1.2.0.4 netbsd-7-base:1.1.1.2 yamt-pagecache-base9:1.1.1.2 yamt-pagecache-tag8:1.1.1.1 netbsd-6-1-4-RELEASE:1.1.1.1 netbsd-6-0-5-RELEASE:1.1.1.1 tls-earlyentropy:1.1.1.2.0.2 tls-earlyentropy-base:1.1.1.2 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.1.1.2 riastradh-drm2-base3:1.1.1.2 netbsd-6-1-3-RELEASE:1.1.1.1 netbsd-6-0-4-RELEASE:1.1.1.1 gmp-5-1-3:1.1.1.2 netbsd-6-1-2-RELEASE:1.1.1.1 netbsd-6-0-3-RELEASE:1.1.1.1 netbsd-6-1-1-RELEASE:1.1.1.1 riastradh-drm2-base2:1.1.1.1 riastradh-drm2-base1:1.1.1.1 riastradh-drm2:1.1.1.1.0.12 riastradh-drm2-base:1.1.1.1 netbsd-6-1:1.1.1.1.0.16 netbsd-6-0-2-RELEASE:1.1.1.1 netbsd-6-1-RELEASE:1.1.1.1 netbsd-6-1-RC4:1.1.1.1 netbsd-6-1-RC3:1.1.1.1 agc-symver:1.1.1.1.0.14 agc-symver-base:1.1.1.1 netbsd-6-1-RC2:1.1.1.1 netbsd-6-1-RC1:1.1.1.1 yamt-pagecache-base8:1.1.1.1 netbsd-6-0-1-RELEASE:1.1.1.1 yamt-pagecache-base7:1.1.1.1 matt-nb6-plus-nbase:1.1.1.1 yamt-pagecache-base6:1.1.1.1 netbsd-6-0:1.1.1.1.0.10 netbsd-6-0-RELEASE:1.1.1.1 netbsd-6-0-RC2:1.1.1.1 tls-maxphys:1.1.1.1.0.8 tls-maxphys-base:1.1.1.2 matt-nb6-plus:1.1.1.1.0.6 matt-nb6-plus-base:1.1.1.1 netbsd-6-0-RC1:1.1.1.1 yamt-pagecache-base5:1.1.1.1 yamt-pagecache-base4:1.1.1.1 netbsd-6:1.1.1.1.0.4 netbsd-6-base:1.1.1.1 yamt-pagecache-base3:1.1.1.1 yamt-pagecache-base2:1.1.1.1 yamt-pagecache:1.1.1.1.0.2 yamt-pagecache-base:1.1.1.1 gmp-5-0-2:1.1.1.1 gmp:1.1.1; locks; strict; comment @;; @; 1.1 date 2011.06.20.05.54.39; author mrg; state Exp; branches 1.1.1.1; next ; 1.1.1.1 date 2011.06.20.05.54.39; author mrg; state Exp; branches 1.1.1.1.2.1 1.1.1.1.8.1; next 1.1.1.2; 1.1.1.2 date 2013.11.29.07.49.48; author mrg; state Exp; branches; next 1.1.1.3; commitid L2Av4PuGmdoL39fx; 1.1.1.3 date 2017.08.22.09.40.49; author mrg; state Exp; branches; next ; commitid W5kmAIk8hwVpSb4A; 1.1.1.1.2.1 date 2014.05.22.14.09.01; author yamt; state Exp; branches; next ; commitid nx2BSsHy0NPeAxBx; 1.1.1.1.8.1 date 2014.08.19.23.59.50; author tls; state Exp; branches; next ; commitid jTnpym9Qu0o4R1Nx; desc @@ 1.1 log @Initial revision @ text @dnl IA-64 mpn_divrem_2 -- Divide an n-limb number by a 2-limb number. dnl Copyright 2004, 2005 Free Software Foundation, Inc. dnl This file is part of the GNU MP Library. dnl The GNU MP Library is free software; you can redistribute it and/or modify dnl it under the terms of the GNU Lesser General Public License as published dnl by the Free Software Foundation; either version 3 of the License, or (at dnl your option) any later version. dnl The GNU MP Library is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public dnl License for more details. dnl You should have received a copy of the GNU Lesser General Public License dnl along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. include(`../config.m4') C cycles/limb C Itanium: 63 C Itanium 2: 46 C TODO C * Further optimize the loop. We could probably do some more trickery with C arithmetic in the FPU, or perhaps use a non-zero addend of xma in more C places. C * Software pipeline for perhaps 5 saved cycles, around the end and start of C the loop. C * Schedule code outside of loop better. C * Update the comments. They are now using the same name for the same C logical quantity. C * Handle conditional zeroing of r31 in loop more cleanly. C * Inline mpn_invert_limb and schedule its insns across the entire init code. C * Ultimately, use 2-limb, or perhaps 3-limb or 4-limb inverse. define(`qp',`r32') define(`qxn',`r33') define(`np',`r34') define(`nn',`r35') define(`dp',`r36') define(`fnh',`f11') define(`fminus1',`f10') define(`fd0',`f13') define(`fd1',`f14') define(`d0',`r39') define(`d1',`r36') define(`fnl',`f32') define(`fdinv',`f12') define(`R1',`r38') define(`R0',`r37') define(`P1',`r28') define(`P0',`r27') ASM_START() C HP's assembler requires these declarations for importing mpn_invert_limb .global mpn_invert_limb .type mpn_invert_limb,@@function PROLOGUE(mpn_divrem_2) .prologue .save ar.pfs, r42 .save ar.lc, r44 .save rp, r41 ifdef(`HAVE_ABI_32', ` addp4 qp = 0, qp C M I addp4 np = 0, np C M I addp4 dp = 0, dp C M I zxt4 nn = nn C I zxt4 qxn = qxn C I ;; ') alloc r42 = ar.pfs, 5,8,1,0 C M2 ld8 d0 = [dp], 8 C M0M1 d0 mov r44 = ar.lc C I0 shladd np = nn, 3, np C M I ;; ld8 d1 = [dp] C M0M1 d1 mov r41 = b0 C I0 add r15 = -8, np C M I add np = -16, np C M I mov r40 = r0 C M I ;; ld8 R1 = [r15] C M0M1 n1 ld8 R0 = [r34], -8 C M0M1 n0 ;; cmp.ltu p6, p0 = d1, R1 C M I cmp.eq p8, p0 = d1, R1 C M I ;; (p8) cmp.leu p6, p0 = d0, R0 cmp.ltu p8, p9 = R0, d0 (p6) br.cond.dpnt .L_high_limb_1 C FIXME: inline! .L8: mov r45 = d1 br.call.sptk.many b0 = mpn_invert_limb C FIXME: inline+schedule ;; setf.sig fd1 = d1 C d1 setf.sig fd0 = d0 C d0 add r14 = r33, r35 C nn + qxn ;; setf.sig fdinv = r8 C dinv mov r9 = -1 add r35 = -3, r14 ;; setf.sig fminus1 = r9 cmp.gt p6, p0 = r0, r35 shladd qp = r35, 3, qp mov ar.lc = r35 mov r31 = 0 C n0 (p6) br.cond.dpnt .Ldone ;; ALIGN(16) C *** MAIN LOOP START *** .Loop: C 00 mov r15 = R0 C nadj = n10 cmp.le p14, p15 = 0, R0 C check high bit of R0 cmp.le p8, p0 = r33, r35 C dividend limbs remaining? ;; C 01 .pred.rel "mutex", p14, p15 (p8) ld8 r31 = [r34], -8 C n0 (p15) add r15 = d1, R0 C nadj = n10 + d1 (p15) add r14 = 1, R1 C nh + (nl:63) (p14) mov r14 = R1 C nh cmp.eq p6, p0 = d1, R1 C nh == d1 (p6) br.cond.spnt .L_R1_eq_d1 ;; C 02 setf.sig f8 = r14 C n2 + (nl:63) setf.sig f15 = r15 C nadj sub r23 = -1, R1 C r23 = ~nh ;; C 03 setf.sig fnh = r23 setf.sig fnl = R0 ;; C 08 xma.hu f7 = fdinv, f8, f15 C xh = HI(dinv*(nh-nmask)+nadj) ;; C 12 xma.l f7 = f7, fminus1, fnh C nh + xh ;; C 16 getf.sig r14 = f7 xma.hu f9 = f7, fd1, fnl C xh = HI(q1*d1+nl) xma.l f33 = f7, fd1, fnl C xh = LO(q1*d1+nl) ;; C 20 getf.sig r16 = f9 sub r24 = d1, R1 C 21 getf.sig r17 = f33 ;; C 25 cmp.eq p6, p7 = r16, r24 ;; C 26 .pred.rel "mutex", p6, p7 (p6) xma.l f8 = f7, fminus1, f0 C f8 = -f7 (p7) xma.l f8 = f7,fminus1,fminus1 C f8 = -f7-1 ;; C 27 .pred.rel "mutex", p6, p7 (p6) sub r18 = 0, r14 C q = -q1 (p7) sub r18 = -1, r14 C q = -q1-1 (p6) add r14 = 0, r17 C n1 = xl (p7) add r14 = d1, r17 C n1 = xl + d1 ;; C 30 xma.hu f9 = fd0, f8, f0 C d0*(-f7-1) = -d0*f7-d0 xma.l f35 = fd0, f8, f0 ;; C 34 getf.sig P1 = f9 C P1 C 35 getf.sig P0 = f35 C P0 ;; .L_adj: C 40 cmp.ltu p8, p0 = r31, P0 C p8 = cy from low limb cmp.ltu p6, p0 = r14, P1 C p6 = prel cy from high limb sub R0 = r31, P0 sub R1 = r14, P1 ;; C 41 (p8) cmp.eq.or p6, p0 = 0, R1 C p6 = final cy from high limb (p8) add R1 = -1, R1 cmp.ne p10, p0 = r0, r0 C clear p10 FIXME: use unc below! cmp.ne p13, p0 = r0, r0 C clear p13 FIXME: use unc below! ;; C 42 (p6) add R0 = R0, d0 (p6) add R1 = R1, d1 (p6) add r18 = -1, r18 C q-- ;; C 43 (p6) cmp.ltu p10, p0 = R0, d0 (p6) cmp.ltu p0, p13 = R1, d1 ;; C 44 (p10) cmp.ne.and p0, p13 = -1, R1 C p13 = !cy (p10) add R1 = 1, R1 (p13) br.cond.spnt .L_two_too_big C jump if not cy ;; C 45 st8 [qp] = r18, -8 add r35 = -1, r35 mov r31 = 0 C n0, next iteration br.cloop.sptk .Loop C *** MAIN LOOP END *** ;; .Ldone: mov r8 = r40 mov b0 = r41 add r21 = 8, r34 add r22 = 16, r34 ;; st8 [r21] = R0 st8 [r22] = R1 mov ar.pfs = r42 mov ar.lc = r44 br.ret.sptk.many b0 .L_high_limb_1: .pred.rel "mutex", p8, p9 sub R0 = R0, d0 (p8) sub R1 = R1, d1, 1 (p9) sub R1 = R1, d1 mov r40 = 1 br.sptk .L8 ;; .L_two_too_big: add R0 = R0, d0 add R1 = R1, d1 ;; add r18 = -1, r18 C q-- cmp.ltu p10, p0 = R0, d0 ;; (p10) add R1 = 1, R1 st8 [qp] = r18, -8 add r35 = -1, r35 mov r31 = 0 C n0, next iteration br.cloop.sptk .Loop br.sptk .Ldone .L_R1_eq_d1: add r14 = R0, d1 C r = R0 + d1 mov r18 = -1 C q = -1 ;; cmp.leu p6, p0 = R0, r14 (p6) br.cond.spnt .L20 C jump unless cy ;; sub P1 = r14, d0 add R0 = r31, d0 ;; cmp.ltu p8, p9 = R0, r31 ;; .pred.rel "mutex", p8, p9 st8 [qp] = r18, -8 (p8) add R1 = r0, P1, 1 C R1 = n1 - P1 - cy (p9) add R1 = r0, P1 C R1 = n1 - P1 add r35 = -1, r35 mov r31 = 0 C n0, next iteration br.cloop.sptk .Loop br.sptk .Ldone ;; .L20: cmp.ne p6, p7 = 0, d0 ;; .pred.rel "mutex", p6, p7 (p6) add P1 = -1, d0 (p7) mov P1 = d0 sub P0 = r0, d0 br.sptk .L_adj EPILOGUE() ASM_END() @ 1.1.1.1 log @initial import of GMP 5.0.2. GNU MP is a library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers. It has a rich set of functions, and the functions have a regular interface. GMP is necessary for GCC >= 4.2. @ text @@ 1.1.1.1.8.1 log @Rebase to HEAD as of a few days ago. @ text @d1 1 a1 1 dnl IA-64 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number. d3 1 a3 1 dnl Copyright 2010, 2013 Free Software Foundation, Inc. d9 1 a9 1 dnl by the Free Software Foundation; either version 2.1 of the License, or (at d18 1 a18 3 dnl along with the GNU MP Library; see the file COPYING.LIB. If not, write dnl to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, dnl Boston, MA 02110-1301, USA. d22 3 a24 3 C norm frac C itanium 1 C itanium 2 29 29 d28 26 a53 3 C * Inline and interleave limb inversion code with loop setup code. C * We should use explicit bundling in much of the code, since it typically C cuts some cycles with the GNU assembler. d55 2 a63 10 C INPUT PARAMETERS C qp = r32 C fn = r33 C np = r34 C nn = r35 C dp = r36 define(`f0x1', `f15') ASM_START() d66 3 d70 5 a74 5 ` addp4 r32 = 0, r32 C M I addp4 r34 = 0, r34 C M I addp4 r36 = 0, r36 C M I zxt4 r35 = r35 C I zxt4 r33 = r33 C I d77 25 a101 13 .save ar.pfs, r42 alloc r42 = ar.pfs, 5, 9, 1, 0 shladd r34 = r35, 3, r34 adds r14 = 8, r36 mov r43 = r1 ;; adds r15 = -8, r34 ld8 r39 = [r14] .save ar.lc, r45 mov r45 = ar.lc adds r14 = -16, r34 mov r40 = r0 adds r34 = -24, r34 d103 14 a116 6 ld8 r38 = [r15] .save rp, r41 mov r41 = b0 .body ld8 r36 = [r36] ld8 r37 = [r14] d118 120 a237 2 cmp.gtu p6, p7 = r39, r38 (p6) br.cond.dptk .L8 d239 2 a240 2 cmp.leu p8, p9 = r36, r37 cmp.geu p6, p7 = r39, r38 d242 2 a243 7 (p8) cmp4.ne.and.orcm p6, p7 = 0, r0 (p7) br.cond.dptk .L51 .L8: add r14 = r33, r35 // un + fn mov r46 = r39 // argument to mpn_invert_limb ;; adds r35 = -3, r14 d245 1 a245 87 cmp.gt p12, p0 = r0, r35 (p12) br.cond.dpnt L(end) br.call.sptk.many b0 = mpn_invert_limb ;; setf.sig f11 = r8 // di (non-final) setf.sig f34 = r39 // d1 setf.sig f33 = r36 // d0 mov r1 = r43 ;; mov r17 = 1 setf.sig f9 = r38 // n2 xma.l f6 = f11, f34, f0 // t0 = LO(di * d1) ;; setf.sig f10 = r37 // n1 setf.sig f15 = r17 // 1 xma.hu f8 = f11, f33, f0 // s0 = HI(di * d0) ;; getf.sig r17 = f6 getf.sig r16 = f8 mov ar.lc = r35 ;; sub r18 = r0, r39 // -d1 add r14 = r17, r36 ;; setf.sig f14 = r18 // -d1 cmp.leu p8, p9 = r17, r14 add r16 = r14, r16 ;; (p9) adds r19 = 0, r0 (p8) adds r19 = -1, r0 cmp.gtu p6, p7 = r14, r16 ;; (p6) adds r19 = 1, r19 ;; ifelse(1,1,` cmp.gt p7, p6 = r0, r19 ;; (p6) adds r8 = -1, r8 // di-- (p6) sub r14 = r16, r39 // t0 -= d1 (p6) cmp.ltu p6, p7 = r16, r39 // cy for: t0 - d1 ;; (p6) cmp.gt p9, p8 = 1, r19 (p7) cmp.gt p9, p8 = 0, r19 (p6) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p8) adds r8 = -1, r8 // di-- (p8) sub r14 = r16, r39 // t0 -= d1 (p8) cmp.ltu p8, p9 = r16, r39 // cy for: t0 - d1 ;; (p8) cmp.gt p7, p6 = 1, r19 (p9) cmp.gt p7, p6 = 0, r19 (p8) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p6) adds r8 = -1, r8 // di-- (p6) sub r14 = r16, r39 // t0 -= d1 (p6) cmp.ltu p6, p7 = r16, r39 // cy for: t0 - d1 ;; (p6) cmp.gt p9, p8 = 1, r19 (p7) cmp.gt p9, p8 = 0, r19 (p6) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p8) adds r8 = -1, r8 // di-- (p8) sub r14 = r16, r39 // t0 -= d1 (p8) cmp.ltu p8, p9 = r16, r39 // cy for: t0 - d1 ;; (p8) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ',` cmp.gt p8, p9 = r0, r19 (p8) br.cond.dpnt .L46 .L52: cmp.leu p6, p7 = r39, r16 sub r14 = r16, r39 adds r8 = -1, r8 ;; (p7) adds r19 = -1, r19 mov r16 = r14 ;; (p7) cmp.gt p8, p9 = r0, r19 (p9) br.cond.dptk .L52 .L46: ') setf.sig f32 = r8 // di shladd r32 = r35, 3, r32 a246 63 ALIGN(16) L(top): nop 0 nop 0 cmp.gt p8, p9 = r33, r35 ;; (p8) mov r37 = r0 (p9) ld8 r37 = [r34], -8 xma.hu f8 = f9, f32, f10 // 0,29 xma.l f12 = f9, f32, f10 // 0 ;; getf.sig r20 = f12 // q0 4 xma.l f13 = f15, f8, f9 // q += n2 4 sub r8 = -1, r36 // bitnot d0 ;; getf.sig r18 = f13 // 8 xma.l f7 = f14, f13, f10 // 8 xma.l f6 = f33, f13, f33 // t0 = LO(d0*q+d0) 8 xma.hu f9 = f33, f13, f33 // t1 = HI(d0*q+d0) 9 ;; getf.sig r38 = f7 // n1 12 getf.sig r16 = f6 // 13 getf.sig r19 = f9 // 14 ;; sub r38 = r38, r39 // n1 -= d1 17 ;; cmp.ne p9, p0 = r0, r0 // clear p9 cmp.leu p10, p11 = r16, r37 // cy for: n0 - t0 18 ;; sub r37 = r37, r16 // n0 -= t0 19 (p11) sub r38 = r38, r19, 1 // n1 -= t1 - cy 19 (p10) sub r38 = r38, r19 // n1 -= t1 19 ;; cmp.gtu p6, p7 = r20, r38 // n1 >= q0 20 ;; (p7) cmp.ltu p9, p0 = r8, r37 // 21 (p6) add r18 = 1, r18 // (p7) add r37 = r37, r36 // 21 (p7) add r38 = r38, r39 // 21 ;; setf.sig f10 = r37 // n1 22 (p9) add r38 = 1, r38 // 22 ;; setf.sig f9 = r38 // n2 23 cmp.gtu p6, p7 = r39, r38 // 23 (p7) br.cond.spnt L(fix) L(bck): st8 [r32] = r18, -8 adds r35 = -1, r35 br.cloop.sptk.few L(top) ;; L(end): add r14 = 8, r34 add r15 = 16, r34 mov b0 = r41 ;; st8 [r14] = r37 st8 [r15] = r38 mov ar.pfs = r42 mov r8 = r40 mov ar.lc = r45 br.ret.sptk.many b0 ;; .L51: d248 15 a262 21 sub r37 = r37, r36 (p9) sub r38 = r38, r39, 1 (p8) sub r38 = r38, r39 adds r40 = 1, r0 br .L8 ;; L(fix): cmp.geu p6, p7 = r39, r38 cmp.leu p8, p9 = r36, r37 ;; (p8) cmp4.ne.and.orcm p6, p7 = 0, r0 (p6) br.cond.dptk L(bck) sub r37 = r37, r36 (p9) sub r38 = r38, r39, 1 (p8) sub r38 = r38, r39 adds r18 = 1, r18 ;; setf.sig f9 = r38 // n2 setf.sig f10 = r37 // n1 br L(bck) @ 1.1.1.1.2.1 log @sync with head. for a reference, the tree before this commit was tagged as yamt-pagecache-tag8. this commit was splitted into small chunks to avoid a limitation of cvs. ("Protocol error: too many arguments") @ text @d1 1 a1 1 dnl IA-64 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number. d3 1 a3 1 dnl Copyright 2010, 2013 Free Software Foundation, Inc. d9 1 a9 1 dnl by the Free Software Foundation; either version 2.1 of the License, or (at d18 1 a18 3 dnl along with the GNU MP Library; see the file COPYING.LIB. If not, write dnl to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, dnl Boston, MA 02110-1301, USA. d22 3 a24 3 C norm frac C itanium 1 C itanium 2 29 29 d28 26 a53 3 C * Inline and interleave limb inversion code with loop setup code. C * We should use explicit bundling in much of the code, since it typically C cuts some cycles with the GNU assembler. d55 2 a63 10 C INPUT PARAMETERS C qp = r32 C fn = r33 C np = r34 C nn = r35 C dp = r36 define(`f0x1', `f15') ASM_START() d66 3 d70 5 a74 5 ` addp4 r32 = 0, r32 C M I addp4 r34 = 0, r34 C M I addp4 r36 = 0, r36 C M I zxt4 r35 = r35 C I zxt4 r33 = r33 C I d77 25 a101 13 .save ar.pfs, r42 alloc r42 = ar.pfs, 5, 9, 1, 0 shladd r34 = r35, 3, r34 adds r14 = 8, r36 mov r43 = r1 ;; adds r15 = -8, r34 ld8 r39 = [r14] .save ar.lc, r45 mov r45 = ar.lc adds r14 = -16, r34 mov r40 = r0 adds r34 = -24, r34 d103 14 a116 6 ld8 r38 = [r15] .save rp, r41 mov r41 = b0 .body ld8 r36 = [r36] ld8 r37 = [r14] d118 120 a237 2 cmp.gtu p6, p7 = r39, r38 (p6) br.cond.dptk .L8 d239 2 a240 2 cmp.leu p8, p9 = r36, r37 cmp.geu p6, p7 = r39, r38 d242 2 a243 7 (p8) cmp4.ne.and.orcm p6, p7 = 0, r0 (p7) br.cond.dptk .L51 .L8: add r14 = r33, r35 // un + fn mov r46 = r39 // argument to mpn_invert_limb ;; adds r35 = -3, r14 d245 1 a245 87 cmp.gt p12, p0 = r0, r35 (p12) br.cond.dpnt L(end) br.call.sptk.many b0 = mpn_invert_limb ;; setf.sig f11 = r8 // di (non-final) setf.sig f34 = r39 // d1 setf.sig f33 = r36 // d0 mov r1 = r43 ;; mov r17 = 1 setf.sig f9 = r38 // n2 xma.l f6 = f11, f34, f0 // t0 = LO(di * d1) ;; setf.sig f10 = r37 // n1 setf.sig f15 = r17 // 1 xma.hu f8 = f11, f33, f0 // s0 = HI(di * d0) ;; getf.sig r17 = f6 getf.sig r16 = f8 mov ar.lc = r35 ;; sub r18 = r0, r39 // -d1 add r14 = r17, r36 ;; setf.sig f14 = r18 // -d1 cmp.leu p8, p9 = r17, r14 add r16 = r14, r16 ;; (p9) adds r19 = 0, r0 (p8) adds r19 = -1, r0 cmp.gtu p6, p7 = r14, r16 ;; (p6) adds r19 = 1, r19 ;; ifelse(1,1,` cmp.gt p7, p6 = r0, r19 ;; (p6) adds r8 = -1, r8 // di-- (p6) sub r14 = r16, r39 // t0 -= d1 (p6) cmp.ltu p6, p7 = r16, r39 // cy for: t0 - d1 ;; (p6) cmp.gt p9, p8 = 1, r19 (p7) cmp.gt p9, p8 = 0, r19 (p6) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p8) adds r8 = -1, r8 // di-- (p8) sub r14 = r16, r39 // t0 -= d1 (p8) cmp.ltu p8, p9 = r16, r39 // cy for: t0 - d1 ;; (p8) cmp.gt p7, p6 = 1, r19 (p9) cmp.gt p7, p6 = 0, r19 (p8) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p6) adds r8 = -1, r8 // di-- (p6) sub r14 = r16, r39 // t0 -= d1 (p6) cmp.ltu p6, p7 = r16, r39 // cy for: t0 - d1 ;; (p6) cmp.gt p9, p8 = 1, r19 (p7) cmp.gt p9, p8 = 0, r19 (p6) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p8) adds r8 = -1, r8 // di-- (p8) sub r14 = r16, r39 // t0 -= d1 (p8) cmp.ltu p8, p9 = r16, r39 // cy for: t0 - d1 ;; (p8) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ',` cmp.gt p8, p9 = r0, r19 (p8) br.cond.dpnt .L46 .L52: cmp.leu p6, p7 = r39, r16 sub r14 = r16, r39 adds r8 = -1, r8 ;; (p7) adds r19 = -1, r19 mov r16 = r14 ;; (p7) cmp.gt p8, p9 = r0, r19 (p9) br.cond.dptk .L52 .L46: ') setf.sig f32 = r8 // di shladd r32 = r35, 3, r32 a246 63 ALIGN(16) L(top): nop 0 nop 0 cmp.gt p8, p9 = r33, r35 ;; (p8) mov r37 = r0 (p9) ld8 r37 = [r34], -8 xma.hu f8 = f9, f32, f10 // 0,29 xma.l f12 = f9, f32, f10 // 0 ;; getf.sig r20 = f12 // q0 4 xma.l f13 = f15, f8, f9 // q += n2 4 sub r8 = -1, r36 // bitnot d0 ;; getf.sig r18 = f13 // 8 xma.l f7 = f14, f13, f10 // 8 xma.l f6 = f33, f13, f33 // t0 = LO(d0*q+d0) 8 xma.hu f9 = f33, f13, f33 // t1 = HI(d0*q+d0) 9 ;; getf.sig r38 = f7 // n1 12 getf.sig r16 = f6 // 13 getf.sig r19 = f9 // 14 ;; sub r38 = r38, r39 // n1 -= d1 17 ;; cmp.ne p9, p0 = r0, r0 // clear p9 cmp.leu p10, p11 = r16, r37 // cy for: n0 - t0 18 ;; sub r37 = r37, r16 // n0 -= t0 19 (p11) sub r38 = r38, r19, 1 // n1 -= t1 - cy 19 (p10) sub r38 = r38, r19 // n1 -= t1 19 ;; cmp.gtu p6, p7 = r20, r38 // n1 >= q0 20 ;; (p7) cmp.ltu p9, p0 = r8, r37 // 21 (p6) add r18 = 1, r18 // (p7) add r37 = r37, r36 // 21 (p7) add r38 = r38, r39 // 21 ;; setf.sig f10 = r37 // n1 22 (p9) add r38 = 1, r38 // 22 ;; setf.sig f9 = r38 // n2 23 cmp.gtu p6, p7 = r39, r38 // 23 (p7) br.cond.spnt L(fix) L(bck): st8 [r32] = r18, -8 adds r35 = -1, r35 br.cloop.sptk.few L(top) ;; L(end): add r14 = 8, r34 add r15 = 16, r34 mov b0 = r41 ;; st8 [r14] = r37 st8 [r15] = r38 mov ar.pfs = r42 mov r8 = r40 mov ar.lc = r45 br.ret.sptk.many b0 ;; .L51: d248 15 a262 21 sub r37 = r37, r36 (p9) sub r38 = r38, r39, 1 (p8) sub r38 = r38, r39 adds r40 = 1, r0 br .L8 ;; L(fix): cmp.geu p6, p7 = r39, r38 cmp.leu p8, p9 = r36, r37 ;; (p8) cmp4.ne.and.orcm p6, p7 = 0, r0 (p6) br.cond.dptk L(bck) sub r37 = r37, r36 (p9) sub r38 = r38, r39, 1 (p8) sub r38 = r38, r39 adds r18 = 1, r18 ;; setf.sig f9 = r38 // n2 setf.sig f10 = r37 // n1 br L(bck) @ 1.1.1.2 log @initial import GMP 5.1.3 sources. changes include: fixes for: - mpn_sbpi1_div_qr_sec and mpn_sbpi1_div_r_sec - mpz_powm_ui - AMD family 11h - mpz_powm_sec and mpn_powm_sec - ASSERT() fixes - gcd, gcdext, and invert function fixes - some PPC division operations @ text @d1 1 a1 1 dnl IA-64 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number. d3 1 a3 1 dnl Copyright 2010, 2013 Free Software Foundation, Inc. d9 1 a9 1 dnl by the Free Software Foundation; either version 2.1 of the License, or (at d18 1 a18 3 dnl along with the GNU MP Library; see the file COPYING.LIB. If not, write dnl to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, dnl Boston, MA 02110-1301, USA. d22 3 a24 3 C norm frac C itanium 1 C itanium 2 29 29 d28 26 a53 3 C * Inline and interleave limb inversion code with loop setup code. C * We should use explicit bundling in much of the code, since it typically C cuts some cycles with the GNU assembler. d55 2 a63 10 C INPUT PARAMETERS C qp = r32 C fn = r33 C np = r34 C nn = r35 C dp = r36 define(`f0x1', `f15') ASM_START() d66 3 d70 5 a74 5 ` addp4 r32 = 0, r32 C M I addp4 r34 = 0, r34 C M I addp4 r36 = 0, r36 C M I zxt4 r35 = r35 C I zxt4 r33 = r33 C I d77 25 a101 13 .save ar.pfs, r42 alloc r42 = ar.pfs, 5, 9, 1, 0 shladd r34 = r35, 3, r34 adds r14 = 8, r36 mov r43 = r1 ;; adds r15 = -8, r34 ld8 r39 = [r14] .save ar.lc, r45 mov r45 = ar.lc adds r14 = -16, r34 mov r40 = r0 adds r34 = -24, r34 d103 14 a116 6 ld8 r38 = [r15] .save rp, r41 mov r41 = b0 .body ld8 r36 = [r36] ld8 r37 = [r14] d118 120 a237 2 cmp.gtu p6, p7 = r39, r38 (p6) br.cond.dptk .L8 d239 2 a240 2 cmp.leu p8, p9 = r36, r37 cmp.geu p6, p7 = r39, r38 d242 2 a243 7 (p8) cmp4.ne.and.orcm p6, p7 = 0, r0 (p7) br.cond.dptk .L51 .L8: add r14 = r33, r35 // un + fn mov r46 = r39 // argument to mpn_invert_limb ;; adds r35 = -3, r14 d245 1 a245 87 cmp.gt p12, p0 = r0, r35 (p12) br.cond.dpnt L(end) br.call.sptk.many b0 = mpn_invert_limb ;; setf.sig f11 = r8 // di (non-final) setf.sig f34 = r39 // d1 setf.sig f33 = r36 // d0 mov r1 = r43 ;; mov r17 = 1 setf.sig f9 = r38 // n2 xma.l f6 = f11, f34, f0 // t0 = LO(di * d1) ;; setf.sig f10 = r37 // n1 setf.sig f15 = r17 // 1 xma.hu f8 = f11, f33, f0 // s0 = HI(di * d0) ;; getf.sig r17 = f6 getf.sig r16 = f8 mov ar.lc = r35 ;; sub r18 = r0, r39 // -d1 add r14 = r17, r36 ;; setf.sig f14 = r18 // -d1 cmp.leu p8, p9 = r17, r14 add r16 = r14, r16 ;; (p9) adds r19 = 0, r0 (p8) adds r19 = -1, r0 cmp.gtu p6, p7 = r14, r16 ;; (p6) adds r19 = 1, r19 ;; ifelse(1,1,` cmp.gt p7, p6 = r0, r19 ;; (p6) adds r8 = -1, r8 // di-- (p6) sub r14 = r16, r39 // t0 -= d1 (p6) cmp.ltu p6, p7 = r16, r39 // cy for: t0 - d1 ;; (p6) cmp.gt p9, p8 = 1, r19 (p7) cmp.gt p9, p8 = 0, r19 (p6) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p8) adds r8 = -1, r8 // di-- (p8) sub r14 = r16, r39 // t0 -= d1 (p8) cmp.ltu p8, p9 = r16, r39 // cy for: t0 - d1 ;; (p8) cmp.gt p7, p6 = 1, r19 (p9) cmp.gt p7, p6 = 0, r19 (p8) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p6) adds r8 = -1, r8 // di-- (p6) sub r14 = r16, r39 // t0 -= d1 (p6) cmp.ltu p6, p7 = r16, r39 // cy for: t0 - d1 ;; (p6) cmp.gt p9, p8 = 1, r19 (p7) cmp.gt p9, p8 = 0, r19 (p6) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ;; (p8) adds r8 = -1, r8 // di-- (p8) sub r14 = r16, r39 // t0 -= d1 (p8) cmp.ltu p8, p9 = r16, r39 // cy for: t0 - d1 ;; (p8) adds r19 = -1, r19 // t1 -= cy mov r16 = r14 ',` cmp.gt p8, p9 = r0, r19 (p8) br.cond.dpnt .L46 .L52: cmp.leu p6, p7 = r39, r16 sub r14 = r16, r39 adds r8 = -1, r8 ;; (p7) adds r19 = -1, r19 mov r16 = r14 ;; (p7) cmp.gt p8, p9 = r0, r19 (p9) br.cond.dptk .L52 .L46: ') setf.sig f32 = r8 // di shladd r32 = r35, 3, r32 a246 63 ALIGN(16) L(top): nop 0 nop 0 cmp.gt p8, p9 = r33, r35 ;; (p8) mov r37 = r0 (p9) ld8 r37 = [r34], -8 xma.hu f8 = f9, f32, f10 // 0,29 xma.l f12 = f9, f32, f10 // 0 ;; getf.sig r20 = f12 // q0 4 xma.l f13 = f15, f8, f9 // q += n2 4 sub r8 = -1, r36 // bitnot d0 ;; getf.sig r18 = f13 // 8 xma.l f7 = f14, f13, f10 // 8 xma.l f6 = f33, f13, f33 // t0 = LO(d0*q+d0) 8 xma.hu f9 = f33, f13, f33 // t1 = HI(d0*q+d0) 9 ;; getf.sig r38 = f7 // n1 12 getf.sig r16 = f6 // 13 getf.sig r19 = f9 // 14 ;; sub r38 = r38, r39 // n1 -= d1 17 ;; cmp.ne p9, p0 = r0, r0 // clear p9 cmp.leu p10, p11 = r16, r37 // cy for: n0 - t0 18 ;; sub r37 = r37, r16 // n0 -= t0 19 (p11) sub r38 = r38, r19, 1 // n1 -= t1 - cy 19 (p10) sub r38 = r38, r19 // n1 -= t1 19 ;; cmp.gtu p6, p7 = r20, r38 // n1 >= q0 20 ;; (p7) cmp.ltu p9, p0 = r8, r37 // 21 (p6) add r18 = 1, r18 // (p7) add r37 = r37, r36 // 21 (p7) add r38 = r38, r39 // 21 ;; setf.sig f10 = r37 // n1 22 (p9) add r38 = 1, r38 // 22 ;; setf.sig f9 = r38 // n2 23 cmp.gtu p6, p7 = r39, r38 // 23 (p7) br.cond.spnt L(fix) L(bck): st8 [r32] = r18, -8 adds r35 = -1, r35 br.cloop.sptk.few L(top) ;; L(end): add r14 = 8, r34 add r15 = 16, r34 mov b0 = r41 ;; st8 [r14] = r37 st8 [r15] = r38 mov ar.pfs = r42 mov r8 = r40 mov ar.lc = r45 br.ret.sptk.many b0 ;; .L51: d248 15 a262 21 sub r37 = r37, r36 (p9) sub r38 = r38, r39, 1 (p8) sub r38 = r38, r39 adds r40 = 1, r0 br .L8 ;; L(fix): cmp.geu p6, p7 = r39, r38 cmp.leu p8, p9 = r36, r37 ;; (p8) cmp4.ne.and.orcm p6, p7 = 0, r0 (p6) br.cond.dptk L(bck) sub r37 = r37, r36 (p9) sub r38 = r38, r39, 1 (p8) sub r38 = r38, r39 adds r18 = 1, r18 ;; setf.sig f9 = r38 // n2 setf.sig f10 = r37 // n1 br L(bck) @ 1.1.1.3 log @initial import of GMP 6.1.2. main changes from 5.1.3 below. notes: - support for thumb-less ARM chips was in our port of 5.1.3, but a similar method has been provided upstream now - someone should look at the AVX failure reports, and fix them Changes between GMP version 6.1.0 and 6.1.1 FEATURES * Work around faulty cpuid on some recent Intel chips (this allows GMP to run on Skylake Pentiums). * Support thumb-less ARM chips. Changes between GMP version 6.0.* and 6.1.0 BUGS FIXED * The public function mpn_com is now correctly declared in gmp.h. * Healed possible failures of mpn_sec_sqr for non-cryptographic sizes for some obsolete CPUs. * Various problems related to precision for mpf have been fixed. * Fixed ABI incompatible stack alignment in calls from assembly code. * Fixed PIC bug in popcount affecting Intel processors using the 32-bit ABI. SPEEDUPS * Speedup for Intel Broadwell and Skylake through assembly code making use of new ADX instructions. * Square root is now faster when the remainder is not needed. Also the speed to compute the k-th root improved, for small sizes. FEATURES * New C++ functions gcd and lcm for mpz_class. * New public mpn functions mpn_divexact_1, mpn_zero_p, and mpn_cnd_swap. * New public mpq_cmp_z function, to efficiently compare rationals with integers. * Support for more 32-bit arm processors. * Support for AVX-less modern x86 CPUs. (Such support might be missing either because the CPU vendor chose to disable AVX, or because the running kernel lacks AVX context switch support.) * Support for NetBSD under Xen; we switch off AVX unconditionally under NetBSD since a bug in NetBSD makes AVX fail under Xen. MISC * Tuned values for FFT multiplications are provided for larger number on many platforms. Changes between GMP version 5.1.* and 6.0.0 BUGS FIXED * The function mpz_invert now considers any number invertible in Z/1Z. * The mpn multiply code now handles operands of more than 2^31 limbs correctly. (Note however that the mpz code is limited to 2^32 bits on 32-bit hosts and 2^37 bits on 64-bit hosts.) SPEEDUPS * Plain division of large operands is faster and more monotonous in operand size. * Major speedup for ARM, in particular ARM Cortex-A15, thanks to improved assembly. * Speedup for Intel Sandy Bridge, Ivy Bridge, Haswell, thanks to rewritten and vastly expanded assembly support. Speedup also for the older Core 2 and Nehalem. * Faster mixed arithmetic between mpq_class and double. FEATURES * Support for new Intel and AMD CPUs. * New public functions mpn_sec_mul and mpn_sec_sqr, implementing side-channel silent multiplication and squaring. * New public functions mpn_sec_div_qr and mpn_sec_div_r, implementing side-channel silent division. * New public functions mpn_cnd_add_n and mpn_cnd_sub_n. Side-channel silent conditional addition and subtraction. * New public function mpn_sec_powm, implementing side-channel silent modexp. * New public function mpn_sec_invert, implementing side-channel silent modular inversion. * Better support for applications which use the mpz_t type, but nevertheless need to call some of the lower-level mpn functions. See the documentation for mpz_limbs_read and related functions. @ text @d6 1 a6 1 dnl d8 4 a11 14 dnl it under the terms of either: dnl dnl * the GNU Lesser General Public License as published by the Free dnl Software Foundation; either version 3 of the License, or (at your dnl option) any later version. dnl dnl or dnl dnl * the GNU General Public License as published by the Free Software dnl Foundation; either version 2 of the License, or (at your option) any dnl later version. dnl dnl or both in parallel, as here. dnl d14 7 a20 6 dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License dnl for more details. dnl dnl You should have received copies of the GNU General Public License and the dnl GNU Lesser General Public License along with the GNU MP Library. If not, dnl see https://www.gnu.org/licenses/. d56 1 a57 2 addp4 r36 = 0, r36 C M I nop.m 0 @