head	1.2;
access;
symbols
	perseant-exfatfs-base-20250801:1.2
	perseant-exfatfs-base-20240630:1.2
	perseant-exfatfs:1.2.0.2
	perseant-exfatfs-base:1.2
	netbsd-8-3-RELEASE:1.1.1.2
	netbsd-9-4-RELEASE:1.1.1.3
	netbsd-9-3-RELEASE: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.2
date	2021.07.11.21.15.46;	author mrg;	state dead;
branches;
next	1.1;
commitid	UkDd4YZ64jVf9C0D;

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.2
log
@merge GMP 6.2.1.
@
text
@dnl  Itanium-2 mpn_gcd_1 -- mpn by 1 gcd.

dnl  Copyright 2002, 2003, 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/bitpair (1x1 gcd)
C Itanium:      14 (approx)
C Itanium 2:     6.3


C mpn_gcd_1 (mp_srcptr xp, mp_size_t xsize, mp_limb_t y);
C
C The entry sequence is designed to expect xsize>1 and hence a modexact
C call.  This ought to be more common than a 1x1 operation.  Our critical
C path is thus stripping factors of 2 from y, calling modexact, then
C stripping factors of 2 from the x remainder returned.
C
C The common factors of 2 between x and y must be determined using the
C original x, not the remainder from the modexact.  This is done with
C x_orig which is xp[0].  There's plenty of time to do this while the rest
C of the modexact etc is happening.
C
C It's possible xp[0] is zero.  In this case the trailing zeros calculation
C popc((x-1)&~x) gives 63, and that's clearly no less than what y will
C have, making min(x_twos,y_twos) == y_twos.
C
C The main loop consists of transforming x,y to abs(x-y),min(x,y), and then
C stripping factors of 2 from abs(x-y).  Those factors of two are
C determined from just y-x, without the abs(), since there's the same
C number of trailing zeros on n or -n in twos complement.  That makes the
C dependent chain
C
C	cycles
C	  1    sub     x-y and x-y-1
C	  3    andcm   (x-y-1)&~(x-y)
C	  2    popcnt  trailing zeros
C	  3    shr.u   strip abs(x-y)
C	 ---
C	  9
C
C The selection of x-y versus y-x for abs(x-y), and the selection of the
C minimum of x and y, is done in parallel with the above.
C
C The algorithm takes about 0.68 iterations per bit (two N bit operands) on
C average, hence the final 6.3 cycles/bitpair.
C
C The loop is not as fast as one might hope, since there's extra latency
C from andcm going across to the `multimedia' popcnt, and vice versa from
C multimedia shr.u back to the integer sub.
C
C The loop branch is .sptk.clr since we usually expect a good number of
C iterations, and the iterations are data dependent so it's unlikely past
C results will predict anything much about the future.
C
C Not done:
C
C An alternate algorithm which didn't strip all twos, but instead applied
C tbit and predicated extr on x, and then y, was attempted.  The loop was 6
C cycles, but the algorithm is an average 1.25 iterations per bitpair for a
C total 7.25 c/bp, which is slower than the current approach.
C
C Alternatives:
C
C Perhaps we could do something tricky by extracting a few high bits and a
C few low bits from the operands, and looking up a table which would give a
C set of predicates to control some shifts or subtracts or whatever.  That
C could knock off multiple bits per iteration.
C
C The right shifts are a bit of a bottleneck (shr at 2 or 3 cycles, or extr
C only going down I0), perhaps it'd be possible to shift left instead,
C using add.  That would mean keeping track of the lowest not-yet-zeroed
C bit, using some sort of mask.
C
C Itanium-1:
C
C This code is not designed for itanium-1 and in fact doesn't run well on
C that chip.  The loop seems to be about 21 cycles, probably because we end
C up with a 10 cycle replay for not forcibly scheduling the shr.u latency.
C Lack of branch hints might introduce a couple of bubbles too.
C

ASM_START()
	.explicit				C What does this mean?

C HP's assembler requires these declarations for importing mpn_modexact_1c_odd
	.global	mpn_modexact_1c_odd
	.type	mpn_modexact_1c_odd,@@function

PROLOGUE(mpn_gcd_1)

		C r32	xp
		C r33	xsize
		C r34	y

define(x,           r8)
define(xp_orig,     r32)
define(xsize,       r33)
define(y,           r34)  define(inputs, 3)
define(save_rp,     r35)
define(save_pfs,    r36)
define(x_orig,      r37)
define(x_orig_one,  r38)
define(y_twos,      r39)  define(locals, 5)
define(out_xp,      r40)
define(out_xsize,   r41)
define(out_divisor, r42)
define(out_carry,   r43)  define(outputs, 4)

	.prologue
{ .mmi;
ifdef(`HAVE_ABI_32',
`		addp4	r9 = 0, xp_orig   define(xp,r9)',	C M0
`					  define(xp,xp_orig)')
	.save ar.pfs, save_pfs
		alloc	save_pfs = ar.pfs, inputs, locals, outputs, 0 C M2
	.save rp, save_rp
		mov	save_rp = b0		C I0
}{	.body
		add	r10 = -1, y		C M3  y-1
}		;;

{ .mmi;		ld8	x = [xp]		C M0  x = xp[0] if no modexact
		ld8	x_orig = [xp]		C M1  orig x for common twos
		cmp.ne	p6,p0 = 1, xsize	C I0
}{ .mmi;	andcm	y_twos = r10, y		C M2  (y-1)&~y
		mov	out_xp = xp_orig	C M3
		mov	out_xsize = xsize	C I1
}		;;

		mov	out_carry = 0

		C

		popcnt	y_twos = y_twos		C I0  y twos
		;;

		C

{ .mmi;		add	x_orig_one = -1, x_orig	C M0  orig x-1
		shr.u	out_divisor = y, y_twos	C I0  y without twos
}{		shr.u	y = y, y_twos		C I1  y without twos
	(p6)	br.call.sptk.many b0 = mpn_modexact_1c_odd  C if xsize>1
}		;;

		C modexact can leave x==0
{ .mmi;		cmp.eq	p6,p0 = 0, x		C M0  if {xp,xsize} % y == 0
		andcm	x_orig = x_orig_one, x_orig	C M1  orig (x-1)&~x
		add	r9 = -1, x		C I0  x-1
}		;;

{ .mmi;		andcm	r9 = r9, x		C M0  (x-1)&~x
		mov	b0 = save_rp		C I0
}		;;

		C

		popcnt	x_orig = x_orig		C I0  orig x twos

		popcnt	r9 = r9			C I0  x twos
		;;

		C

{		cmp.lt	p7,p0 = x_orig, y_twos	C M0  orig x_twos < y_twos
		shr.u	x = x, r9		C I0  x odd
}		;;

{	(p7)	mov	y_twos = x_orig		C M0  common twos
		add	r10 = -1, y		C I0  y-1
	(p6)	br.dpnt.few .Ldone_y		C B0  x%y==0 then result y
}		;;

		C


		C No noticable difference in speed for the loop aligned to
		C 32 or just 16.
.Ltop:
		C r8	x
		C r10  y-1
		C r34	y
		C r38	common twos, for use at end

{  .mmi;	cmp.gtu	p8,p9 = x, y	C M0  x>y
		cmp.ne	p10,p0 = x, y	C M1  x==y
		sub	r9 = y, x	C I0  d = y - x
}{ .mmi;	sub	r10 = r10, x	C M2  d-1 = y - x - 1
}		;;

{ .mmi;	.pred.rel "mutex", p8, p9
	(p8)	sub	x = x, y	C M0  x>y  use x=x-y, y unchanged
	(p9)	mov	y = x		C M1  y>=x use y=x
	(p9)	mov	x = r9		C I0  y>=x use x=y-x
}{ .mmi;	andcm	r9 = r10, r9	C M2  (d-1)&~d
		;;

		add	r10 = -1, y	C M0  new y-1
		popcnt	r9 = r9		C I0  twos on x-y
}		;;

{		shr.u	x = x, r9	C I0   new x without twos
	(p10)	br.sptk.few.clr .Ltop
}		;;



		C result is y
.Ldone_y:
		shl	r8 = y, y_twos		C I   common factors of 2
		;;
		mov	ar.pfs = save_pfs	C I0
		br.ret.sptk.many b0

EPILOGUE()
@


1.1
log
@Initial revision
@
text
@@


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
@d3 1
a3 4
dnl  Contributed to the GNU project by Kevin Ryde, innerloop by Torbjorn
dnl  Granlund.

dnl  Copyright 2002, 2003, 2004, 2005, 2012 Free Software Foundation, Inc.
d24 2
a25 2
C Itanium:       ?
C Itanium 2:     5.8  (trimmable to 5.64 with huge ctz_table)
d48 9
a56 1
C dependent chain 8 cycles deep.
d59 1
a59 1
C minimum of x and y, is done in parallel with the critical path.
d62 9
a70 1
C average, hence the final 5.8 cycles/bitpair.
d91 7
a97 4
C TODO:
C  * Once mod_1_N exists in assembly for Itanium, add conditional calls.
C  * Call bmod_1 even for n=1 when up[0] >> v0 (like other gcd_1 impls).
C  * Probably avoid popcnt also outside of loop, instead use ctz_table.
a105 12
C ctz_table[n] is the number of trailing zeros on n, or MAXSHIFT if n==0.

deflit(MAXSHIFT, 7)
deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))

	.section	".rodata"
ctz_table:
	.byte	MAXSHIFT
forloop(i,1,MASK,
`	.byte	m4_count_trailing_zeros(i)
')

d149 2
d154 2
d172 2
d175 1
d179 2
d187 1
a187 1
	(p6)	br.dpnt.few L(done_y)		C B0  x%y==0 then result y
d190 22
a211 1
		addl	r22 = @@ltoffx(ctz_table#), r1
a212 2
		ld8.mov r22 = [r22], ctz_table#
		br	L(ent)
d214 7
a221 26
		ALIGN(32)
L(top):		.pred.rel "mutex", p6,p7
.mmi;		and	r20 = MASK, r19
	(p7)	mov	y = x
	(p6)	sub	x = x, y
.mmi;	(p7)	mov	x = r19
		nop	0
		nop	0
		;;
L(mid):
.mmb;		add	r21 = r22, r20
		cmp.eq	p10,p0 = 0, r20
	(p10)	br.spnt.few.clr	 L(shift_alot)
		;;
.mmi;		ld1	r16 = [r21]
		;;
		nop	0
		shr.u	x = x, r16
		;;
L(ent):
.mmi;		sub	r19 = y, x
		cmp.gtu	p6,p7 = x, y
		cmp.ne	p8,p0 = x, y
.mmb;		nop	0
		nop	0
	(p8)	br.sptk.few.clr L(top)
d225 3
a227 1
L(done_y):
a228 1
		shl	r8 = y, y_twos		C I   common factors of 2
a230 4
L(shift_alot):
		extr.u	r20 = x, MAXSHIFT, MAXSHIFT
		shr.u	x = x, MAXSHIFT
		br	L(mid)
@


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
@d3 1
a3 4
dnl  Contributed to the GNU project by Kevin Ryde, innerloop by Torbjorn
dnl  Granlund.

dnl  Copyright 2002, 2003, 2004, 2005, 2012 Free Software Foundation, Inc.
d24 2
a25 2
C Itanium:       ?
C Itanium 2:     5.8  (trimmable to 5.64 with huge ctz_table)
d48 9
a56 1
C dependent chain 8 cycles deep.
d59 1
a59 1
C minimum of x and y, is done in parallel with the critical path.
d62 9
a70 1
C average, hence the final 5.8 cycles/bitpair.
d91 7
a97 4
C TODO:
C  * Once mod_1_N exists in assembly for Itanium, add conditional calls.
C  * Call bmod_1 even for n=1 when up[0] >> v0 (like other gcd_1 impls).
C  * Probably avoid popcnt also outside of loop, instead use ctz_table.
a105 12
C ctz_table[n] is the number of trailing zeros on n, or MAXSHIFT if n==0.

deflit(MAXSHIFT, 7)
deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))

	.section	".rodata"
ctz_table:
	.byte	MAXSHIFT
forloop(i,1,MASK,
`	.byte	m4_count_trailing_zeros(i)
')

d149 2
d154 2
d172 2
d175 1
d179 2
d187 1
a187 1
	(p6)	br.dpnt.few L(done_y)		C B0  x%y==0 then result y
d190 22
a211 1
		addl	r22 = @@ltoffx(ctz_table#), r1
a212 2
		ld8.mov r22 = [r22], ctz_table#
		br	L(ent)
d214 7
a221 26
		ALIGN(32)
L(top):		.pred.rel "mutex", p6,p7
.mmi;		and	r20 = MASK, r19
	(p7)	mov	y = x
	(p6)	sub	x = x, y
.mmi;	(p7)	mov	x = r19
		nop	0
		nop	0
		;;
L(mid):
.mmb;		add	r21 = r22, r20
		cmp.eq	p10,p0 = 0, r20
	(p10)	br.spnt.few.clr	 L(shift_alot)
		;;
.mmi;		ld1	r16 = [r21]
		;;
		nop	0
		shr.u	x = x, r16
		;;
L(ent):
.mmi;		sub	r19 = y, x
		cmp.gtu	p6,p7 = x, y
		cmp.ne	p8,p0 = x, y
.mmb;		nop	0
		nop	0
	(p8)	br.sptk.few.clr L(top)
d225 3
a227 1
L(done_y):
a228 1
		shl	r8 = y, y_twos		C I   common factors of 2
a230 4
L(shift_alot):
		extr.u	r20 = x, MAXSHIFT, MAXSHIFT
		shr.u	x = x, MAXSHIFT
		br	L(mid)
@


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
@d3 1
a3 4
dnl  Contributed to the GNU project by Kevin Ryde, innerloop by Torbjorn
dnl  Granlund.

dnl  Copyright 2002, 2003, 2004, 2005, 2012 Free Software Foundation, Inc.
d24 2
a25 2
C Itanium:       ?
C Itanium 2:     5.8  (trimmable to 5.64 with huge ctz_table)
d48 9
a56 1
C dependent chain 8 cycles deep.
d59 1
a59 1
C minimum of x and y, is done in parallel with the critical path.
d62 9
a70 1
C average, hence the final 5.8 cycles/bitpair.
d91 7
a97 4
C TODO:
C  * Once mod_1_N exists in assembly for Itanium, add conditional calls.
C  * Call bmod_1 even for n=1 when up[0] >> v0 (like other gcd_1 impls).
C  * Probably avoid popcnt also outside of loop, instead use ctz_table.
a105 12
C ctz_table[n] is the number of trailing zeros on n, or MAXSHIFT if n==0.

deflit(MAXSHIFT, 7)
deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))

	.section	".rodata"
ctz_table:
	.byte	MAXSHIFT
forloop(i,1,MASK,
`	.byte	m4_count_trailing_zeros(i)
')

d149 2
d154 2
d172 2
d175 1
d179 2
d187 1
a187 1
	(p6)	br.dpnt.few L(done_y)		C B0  x%y==0 then result y
d190 22
a211 1
		addl	r22 = @@ltoffx(ctz_table#), r1
a212 2
		ld8.mov r22 = [r22], ctz_table#
		br	L(ent)
d214 7
a221 26
		ALIGN(32)
L(top):		.pred.rel "mutex", p6,p7
.mmi;		and	r20 = MASK, r19
	(p7)	mov	y = x
	(p6)	sub	x = x, y
.mmi;	(p7)	mov	x = r19
		nop	0
		nop	0
		;;
L(mid):
.mmb;		add	r21 = r22, r20
		cmp.eq	p10,p0 = 0, r20
	(p10)	br.spnt.few.clr	 L(shift_alot)
		;;
.mmi;		ld1	r16 = [r21]
		;;
		nop	0
		shr.u	x = x, r16
		;;
L(ent):
.mmi;		sub	r19 = y, x
		cmp.gtu	p6,p7 = x, y
		cmp.ne	p8,p0 = x, y
.mmb;		nop	0
		nop	0
	(p8)	br.sptk.few.clr L(top)
d225 3
a227 1
L(done_y):
a228 1
		shl	r8 = y, y_twos		C I   common factors of 2
a230 4
L(shift_alot):
		extr.u	r20 = x, MAXSHIFT, MAXSHIFT
		shr.u	x = x, MAXSHIFT
		br	L(mid)
@


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  Copyright 2002-2005, 2012, 2013, 2015 Free Software Foundation, Inc.
d9 1
a9 1
dnl
d11 4
a14 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
d17 5
a21 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/.
d28 1
a28 1
C Itanium 2:     5.1
d95 1
a95 3
C	.section	".rodata"
	.rodata
	ALIGN(m4_lshift(1,MAXSHIFT))	C align table to allow using dep
d97 1
a97 1
	data1	MAXSHIFT
d99 1
a99 1
`	data1	m4_count_trailing_zeros(i)
d123 1
a123 1
 {.mmi;
d130 21
a150 23
		mov	save_rp = b0			C I0
}{.mbb;	.body
		add	r10 = -1, y			C M3  y-1
		nop.b	0				C B0
		nop.b	0				C B1
	;;

}{.mmi;		ld8	x = [xp]			C M0  x = xp[0] if no modexact
		ld8	x_orig = [xp]			C M1  orig x for common twos
		cmp.ne	p6,p0 = 1, xsize		C I0
}{.mmi;		andcm	y_twos = r10, y			C M2  (y-1)&~y
		mov	out_xp = xp_orig		C M3
		mov	out_xsize = xsize		C I1
	;;
}{.mmi;		mov	out_carry = 0			C M0
		nop.m	0				C M1
		popcnt	y_twos = y_twos			C I0  y twos
	;;
}{.mmi;		add	x_orig_one = -1, x_orig		C M0  orig x-1
		nop.m	0				C M1
		shr.u	out_divisor = y, y_twos		C I0  y without twos
}{.mib;		nop.m	0				C M2
		shr.u	y = y, y_twos			C I1  y without twos
d152 4
a155 4
	;;
}
	C modexact can leave x==0
 {.mmi;		cmp.eq	p6,p0 = 0, x			C M0  if {xp,xsize} % y == 0
d157 16
a172 16
		add	r9 = -1, x			C I0  x-1
	;;
}{.mmi;		andcm	r9 = r9, x			C M0  (x-1)&~x
		nop.m	0				C M1
		mov	b0 = save_rp			C I0
	;;
}{.mii;		nop.m	0				C M0
		popcnt	x_orig = x_orig			C I0  orig x twos
		popcnt	r9 = r9				C I0  x twos
	;;
}{.mmi;		cmp.lt	p7,p0 = x_orig, y_twos		C M0  orig x_twos < y_twos
		addl	r22 = @@ltoff(ctz_table), r1
		shr.u	x = x, r9			C I0  x odd
	;;
}{.mib;
	(p7)	mov	y_twos = x_orig		C M0  common twos
d175 5
a179 4
	;;
}
		mov	r25 = m4_lshift(MASK, MAXSHIFT)
		ld8	r22 = [r22]
a180 1
	;;
d182 5
a186 4
	ALIGN(32)
L(top):
	.pred.rel "mutex", p6,p7
 {.mmi;	(p7)	mov	y = x
d188 1
a188 3
		dep	r21 = r19, r22, 0, MAXSHIFT	C concat(table,lowbits)
}{.mmi;		and	r20 = MASK, r19
	(p7)	mov	x = r19
d190 2
a191 2
	;;
}
d193 1
a193 1
{.mmb;		ld1	r16 = [r21]
d196 3
a198 2
	;;
}{.mmi;		nop	0
d201 1
a201 2
	;;
}
d203 1
a203 1
 {.mmi;		sub	r19 = y, x
d206 1
a206 1
}{.mmb;		nop	0
a208 1
}
d210 3
a212 1
L(done_y):	C result is y
d218 1
a218 1
		and	r20 = x, r25
a219 2
	;;
		dep	r21 = x, r22, 0, MAXSHIFT
@


