[Gmp-commit] /home/hgfiles/gmp: {add, sub}lsh1_n.asm for k7 and Atom.

mercurial at gmplib.org mercurial at gmplib.org
Sun Feb 6 20:27:31 CET 2011


details:   /home/hgfiles/gmp/rev/a375236a1e6b
changeset: 13833:a375236a1e6b
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Sun Feb 06 20:27:28 2011 +0100
description:
{add,sub}lsh1_n.asm for k7 and Atom.

diffstat:

 ChangeLog                  |    7 +
 mpn/x86/atom/addlsh1_n.asm |   23 +++
 mpn/x86/atom/sublsh1_n.asm |   23 +++
 mpn/x86/k7/addlsh1_n.asm   |  197 +++++++++++++++++++++++++++++++++
 mpn/x86/k7/sublsh1_n.asm   |  264 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 514 insertions(+), 0 deletions(-)

diffs (truncated from 537 to 300 lines):

diff -r 1712752e4f47 -r a375236a1e6b ChangeLog
--- a/ChangeLog	Sat Feb 05 20:22:41 2011 +0100
+++ b/ChangeLog	Sun Feb 06 20:27:28 2011 +0100
@@ -1,3 +1,10 @@
+2011-02-06 Marco Bodrato <bodrato at mail.dm.unipi.it>
+
+	* mpn/x86/k7/addlsh1_n.asm: New file.
+	* mpn/x86/k7/sublsh1_n.asm: New file.
+	* mpn/x86/atom/addlsh1_n.asm: Grab k7/addlsh1_n.asm.
+	* mpn/x86/atom/sublsh1_n.asm: Grab k7/sublsh1_n.asm.
+
 2011-02-05  Torbjorn Granlund  <tege at gmplib.org>
 
 	* gmp-impl.h (mpn_addlsh1_nc, mpn_addlsh2_nc, mpn_sublsh1_nc,
diff -r 1712752e4f47 -r a375236a1e6b mpn/x86/atom/addlsh1_n.asm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpn/x86/atom/addlsh1_n.asm	Sun Feb 06 20:27:28 2011 +0100
@@ -0,0 +1,23 @@
+dnl  Intel Atom mpn_addlsh1_n -- rp[] = up[] + (vp[] << 1)
+
+dnl  Copyright 2011 Free Software Foundation, Inc.
+dnl
+dnl  This file is part of the GNU MP Library.
+dnl
+dnl  The GNU MP Library is free software; you can redistribute it and/or
+dnl  modify it under the terms of the GNU Lesser General Public License as
+dnl  published by the Free Software Foundation; either version 3 of the
+dnl  License, or (at your option) any later version.
+dnl
+dnl  The GNU MP Library is distributed in the hope that it will be useful,
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl  Lesser General Public License for more details.
+dnl
+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')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n)
+include_mpn(`x86/k7/addlsh1_n.asm')
diff -r 1712752e4f47 -r a375236a1e6b mpn/x86/atom/sublsh1_n.asm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpn/x86/atom/sublsh1_n.asm	Sun Feb 06 20:27:28 2011 +0100
@@ -0,0 +1,23 @@
+dnl  Intel Atom mpn_sublsh1_n -- rp[] = up[] - (vp[] << 1)
+
+dnl  Copyright 2011 Free Software Foundation, Inc.
+dnl
+dnl  This file is part of the GNU MP Library.
+dnl
+dnl  The GNU MP Library is free software; you can redistribute it and/or
+dnl  modify it under the terms of the GNU Lesser General Public License as
+dnl  published by the Free Software Foundation; either version 3 of the
+dnl  License, or (at your option) any later version.
+dnl
+dnl  The GNU MP Library is distributed in the hope that it will be useful,
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl  Lesser General Public License for more details.
+dnl
+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')
+
+MULFUNC_PROLOGUE(mpn_sublsh1_n)
+include_mpn(`x86/k7/sublsh1_n.asm')
diff -r 1712752e4f47 -r a375236a1e6b mpn/x86/k7/addlsh1_n.asm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpn/x86/k7/addlsh1_n.asm	Sun Feb 06 20:27:28 2011 +0100
@@ -0,0 +1,197 @@
+dnl  AMD K7 mpn_addlsh1_n -- rp[] = up[] + (vp[] << 1)
+
+dnl  Copyright 2011 Free Software Foundation, Inc.
+
+dnl  Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+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 This is an attempt at a addlsh1_n for x86-32, not relying on sse2 insns.  The
+C innerloop is 2*3-way unrolled, which is best we can do with the available
+C registers.  It seems tricky to use the same structure for rsblsh1_n, since we
+C cannot feed carry between operations there.
+
+C                           cycles/limb
+C P5
+C P6 model 0-8,10-12)
+C P6 model 9  (Banias)
+C P6 model 13 (Dothan)           5.4	(worse than add_n + lshift)
+C P4 model 0  (Willamette)
+C P4 model 1  (?)
+C P4 model 2  (Northwood)
+C P4 model 3  (Prescott)
+C P4 model 4  (Nocona)
+C Intel Atom			 6
+C AMD K6                         ?
+C AMD K7                         2.5
+C AMD K8
+
+C This is a basic addlsh1_n for k7, atom, and perhaps some other x86-32
+C processors.  It uses 2*3-way unrolling, for good reasons.  Unfortunately,
+C that means we need an initial magic multiply.
+C 
+C It is not clear how to do sublsh1_n or rsblsh1_n using the same pattern.  We
+C cannot do rsblsh1_n since we feed carry from the shift blocks to the
+C add/subtract blocks, which is right for addition but reversed for
+C subtraction.  We could perhaps do sublsh1_n, with some extra move insns,
+C without losing any time, since we're not issue limited but carry recurrency
+C latency.
+C 
+C Breaking carry recurrency might be a good idea.  We would then need separate
+C registers for the shift carry and add/subtract carry, which in turn would
+C force is to 2*2-way unrolling.
+
+defframe(PARAM_SIZE,	16)
+defframe(PARAM_DBLD,	12)
+defframe(PARAM_SRC,	 8)
+defframe(PARAM_DST,	 4)
+
+dnl  re-use parameter space
+define(VAR_COUNT,`PARAM_DST')
+define(VAR_TMP,`PARAM_DBLD')
+
+ASM_START()
+	TEXT
+	ALIGN(8)
+PROLOGUE(mpn_addlsh1_n)
+deflit(`FRAME',0)
+
+define(`rp',  `%edi')
+define(`up',  `%esi')
+define(`vp',  `%ebp')
+
+	mov	$0x20000000, %eax
+
+	push	%ebx			FRAME_pushl()
+	movl	PARAM_SIZE, %ebx	C size
+
+	push	rp			FRAME_pushl()
+	movl	PARAM_DST, rp
+
+	mull	%ebx
+
+	push	up			FRAME_pushl()
+	movl	PARAM_SRC, up
+
+	not	%edx			C count = -(size\8)-1
+	mov	%edx, VAR_COUNT
+
+	push	vp			FRAME_pushl()
+	movl	PARAM_DBLD, vp
+
+	leal	4(,%edx,4), %ecx	C count*4+4 = -(size\8)*4
+	xorl	%edx, %edx
+	leal	(%ebx,%ecx,2), %ebx	C size + (count*4+4)*2 = size % 8
+	orl	%ebx, %ebx
+	jz	L(exact)
+
+L(oop):
+ifdef(`CPU_P6',`
+	shr	%edx ')			C restore 2nd saved carry bit
+	mov	(vp), %eax
+	adc	%eax, %eax
+	rcr	%edx			C restore 1st saved carry bit
+	adc	(up), %eax
+	mov	%eax, (rp)
+	adc	%edx, %edx		C save a carry bit in edx
+	lea	4(rp), rp
+	lea	4(up), up
+	lea	4(vp), vp
+ifdef(`CPU_P6',`
+	adc	%edx, %edx ')		C save another carry bit in edx
+	decl	%ebx
+	jnz	L(oop)
+	movl	vp, VAR_TMP
+L(exact):
+	incl	VAR_COUNT
+	jz	L(end)
+	
+	ALIGN(16)
+L(top):
+ifdef(`CPU_P6',`
+	shr	%edx ')			C restore 2nd saved carry bit
+	mov	(vp), %eax
+	adc	%eax, %eax
+	mov	4(vp), %ebx
+	adc	%ebx, %ebx
+	mov	8(vp), %ecx
+	adc	%ecx, %ecx
+	mov	12(vp), vp
+	adc	vp, vp
+
+	rcr	%edx			C restore 1st saved carry bit
+
+	adc	(up), %eax
+	mov	%eax, (rp)
+	adc	4(up), %ebx
+	mov	%ebx, 4(rp)
+	adc	8(up), %ecx
+	mov	%ecx, 8(rp)
+	adc	12(up), vp
+	mov	vp, 12(rp)
+
+	movl	VAR_TMP, vp
+
+	mov	16(vp), %eax
+	adc	%eax, %eax
+	mov	20(vp), %ebx
+	adc	%ebx, %ebx
+	mov	24(vp), %ecx
+	adc	%ecx, %ecx
+	mov	28(vp), vp
+	adc	vp, vp
+
+	adc	%edx, %edx		C save a carry bit in edx
+
+	adc	16(up), %eax
+	mov	%eax, 16(rp)
+	adc	20(up), %ebx
+	mov	%ebx, 20(rp)
+	adc	24(up), %ecx
+	mov	%ecx, 24(rp)
+	adc	28(up), vp
+	mov	vp, 28(rp)
+
+	movl	VAR_TMP, vp
+	lea	32(rp), rp
+	lea	32(up), up
+	lea	32(vp), vp
+
+ifdef(`CPU_P6',`
+	adc	%edx, %edx ')		C save another carry bit in edx
+	incl	VAR_COUNT
+	movl	vp, VAR_TMP
+	jne	L(top)
+
+L(end):
+	pop	vp			FRAME_popl()
+	pop	up			FRAME_popl()
+
+ifdef(`CPU_P6',`
+	xor	%eax, %eax
+	shr	$1, %edx
+	adc	%edx, %eax
+',`
+	adc	$0, %edx
+	mov	%edx, %eax
+')
+	pop	rp			FRAME_popl()
+	pop	%ebx			FRAME_popl()
+	ret
+EPILOGUE()
+ASM_END()
diff -r 1712752e4f47 -r a375236a1e6b mpn/x86/k7/sublsh1_n.asm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpn/x86/k7/sublsh1_n.asm	Sun Feb 06 20:27:28 2011 +0100
@@ -0,0 +1,264 @@
+dnl  AMD K7 mpn_sublsh1_n -- rp[] = up[] - (vp[] << 1)
+
+dnl  Copyright 2011 Free Software Foundation, Inc.
+
+dnl  Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+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 This is an attempt at a sublsh1_n for x86-32, not relying on sse2 insns.  The
+C innerloop is 2*3-way unrolled, which is best we can do with the available
+C registers.  It seems tricky to use the same structure for rsblsh1_n, since we
+C cannot feed carry between operations there.


More information about the gmp-commit mailing list