summary refs log tree commit diff
path: root/sysdeps/sparc
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-03-01 18:45:35 +0000
committerRoland McGrath <roland@gnu.org>1996-03-01 18:45:35 +0000
commit6b628d3634559ddd84148ed860a0e1e967b5d59c (patch)
tree59e9370cd3fdf04ebe25ce605465f9057e24e081 /sysdeps/sparc
parentbc47d7a85be6334801853aaee489c875646ecb00 (diff)
downloadglibc-6b628d3634559ddd84148ed860a0e1e967b5d59c.tar.gz
glibc-6b628d3634559ddd84148ed860a0e1e967b5d59c.tar.xz
glibc-6b628d3634559ddd84148ed860a0e1e967b5d59c.zip
* stdlib/Makefile (mpn-stuff): New target.
	(copy-mpn): Use it.

	* Code copied from GMP updated to 1.937 version.
	* stdlib/strtod.c (HAVE_ALLOCA): Define this for gmp headers.
Diffstat (limited to 'sysdeps/sparc')
-rw-r--r--sysdeps/sparc/add_n.S42
-rw-r--r--sysdeps/sparc/lshift.S6
-rw-r--r--sysdeps/sparc/rshift.S6
-rw-r--r--sysdeps/sparc/sparc64/add_n.s57
-rw-r--r--sysdeps/sparc/sparc64/addmul_1.s88
-rw-r--r--sysdeps/sparc/sparc64/gmp-mparam.h26
-rw-r--r--sysdeps/sparc/sparc64/lshift.s95
-rw-r--r--sysdeps/sparc/sparc64/mul_1.s85
-rw-r--r--sysdeps/sparc/sparc64/rshift.s92
-rw-r--r--sysdeps/sparc/sparc64/sub_n.s57
-rw-r--r--sysdeps/sparc/sparc64/submul_1.s88
-rw-r--r--sysdeps/sparc/sparc8/addmul_1.S2
-rw-r--r--sysdeps/sparc/sparc8/mul_1.S2
-rw-r--r--sysdeps/sparc/sub_n.S12
14 files changed, 624 insertions, 34 deletions
diff --git a/sysdeps/sparc/add_n.S b/sysdeps/sparc/add_n.S
index 80c3b99640..49b31fc660 100644
--- a/sysdeps/sparc/add_n.S
+++ b/sysdeps/sparc/add_n.S
@@ -1,7 +1,7 @@
-! sparc __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
 ! sum in a third limb vector.
 
-! Copyright (C) 1995 Free Software Foundation, Inc.
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 
 ! This file is part of the GNU MP Library.
 
@@ -32,18 +32,14 @@
 	.align	4
 	.global	C_SYMBOL_NAME(__mpn_add_n)
 C_SYMBOL_NAME(__mpn_add_n):
-	cmp	size,8
-	mov	0,%o4			! clear cy-save register
-	blt,a	Ltriv
-	addcc	size,-2,size
 	xor	s2_ptr,res_ptr,%g1
 	andcc	%g1,4,%g0
 	bne	L1			! branch if alignment differs
 	nop
+! **  V1a  **
 L0:	andcc	res_ptr,4,%g0		! res_ptr unaligned? Side effect: cy=0
-	beq	L_v1			! if no, branch
+	be	L_v1			! if no, branch
 	nop
-! **  V1a  **
 /* Add least significant limb separately to align res_ptr and s2_ptr */
 	ld	[s1_ptr],%g4
 	add	s1_ptr,4,s1_ptr
@@ -53,12 +49,15 @@ L0:	andcc	res_ptr,4,%g0		! res_ptr unaligned? Side effect: cy=0
 	addcc	%g4,%g2,%o4
 	st	%o4,[res_ptr]
 	add	res_ptr,4,res_ptr
+L_v1:	addx	%g0,%g0,%o4		! save cy in register
+	cmp	size,2			! if size < 2 ...
+	bl	Lend2			! ... branch to tail code
+	subcc	%g0,%o4,%g0		! restore cy
 
-L_v1:	ld	[s1_ptr+0],%g4
+	ld	[s1_ptr+0],%g4
+	addcc	size,-10,size
 	ld	[s1_ptr+4],%g1
 	ldd	[s2_ptr+0],%g2
-	addx	%g0,%g0,%o4		! save cy in register
-	addcc	size,-10,size
 	blt	Lfin1
 	subcc	%g0,%o4,%g0		! restore cy
 /* Add blocks of 8 limbs until less than 8 limbs remain */
@@ -98,7 +97,7 @@ Lfin1:	addcc	size,8-2,size
 	blt	Lend1
 	subcc	%g0,%o4,%g0		! restore cy
 /* Add blocks of 2 limbs until less than 2 limbs remain */
-Loop1b:	addxcc	%g4,%g2,%o4
+Loope1:	addxcc	%g4,%g2,%o4
 	ld	[s1_ptr+8],%g4
 	addxcc	%g1,%g3,%o5
 	ld	[s1_ptr+12],%g1
@@ -109,7 +108,7 @@ Loop1b:	addxcc	%g4,%g2,%o4
 	add	s1_ptr,8,s1_ptr
 	add	s2_ptr,8,s2_ptr
 	add	res_ptr,8,res_ptr
-	bge	Loop1b
+	bge	Loope1
 	subcc	%g0,%o4,%g0		! restore cy
 Lend1:	addxcc	%g4,%g2,%o4
 	addxcc	%g1,%g3,%o5
@@ -144,10 +143,13 @@ L1:	xor	s1_ptr,res_ptr,%g1
    things can be aligned (that we care about) we now know that the alignment
    of s1_ptr and s2_ptr are the same.  */
 
-L2:	andcc	s1_ptr,4,%g0		! s1_ptr unaligned? Side effect: cy=0
-	beq	L_v2			! if no, branch
+L2:	cmp	size,1
+	be	Ljone
 	nop
-/* Add least significant limb separately to align res_ptr and s2_ptr */
+	andcc	s1_ptr,4,%g0		! s1_ptr unaligned? Side effect: cy=0
+	be	L_v2			! if no, branch
+	nop
+/* Add least significant limb separately to align s1_ptr and s2_ptr */
 	ld	[s1_ptr],%g4
 	add	s1_ptr,4,s1_ptr
 	ld	[s2_ptr],%g2
@@ -195,9 +197,9 @@ Loop2:	ldd	[s1_ptr+0],%g2
 	subcc	%g0,%o4,%g0		! restore cy
 
 Lfin2:	addcc	size,8-2,size
-Ltriv:	blt	Lend2
+	blt	Lend2
 	subcc	%g0,%o4,%g0		! restore cy
-Loop2b:	ldd	[s1_ptr+0],%g2
+Loope2:	ldd	[s1_ptr+0],%g2
 	ldd	[s2_ptr+0],%o4
 	addxcc	%g2,%o4,%g2
 	st	%g2,[res_ptr+0]
@@ -208,13 +210,13 @@ Loop2b:	ldd	[s1_ptr+0],%g2
 	add	s1_ptr,8,s1_ptr
 	add	s2_ptr,8,s2_ptr
 	add	res_ptr,8,res_ptr
-	bge	Loop2b
+	bge	Loope2
 	subcc	%g0,%o4,%g0		! restore cy
 Lend2:	andcc	size,1,%g0
 	be	Lret2
 	subcc	%g0,%o4,%g0		! restore cy
 /* Add last limb */
-	ld	[s1_ptr],%g4
+Ljone:	ld	[s1_ptr],%g4
 	ld	[s2_ptr],%g2
 	addxcc	%g4,%g2,%o4
 	st	%o4,[res_ptr]
diff --git a/sysdeps/sparc/lshift.S b/sysdeps/sparc/lshift.S
index 497272af0f..6844fa2475 100644
--- a/sysdeps/sparc/lshift.S
+++ b/sysdeps/sparc/lshift.S
@@ -1,6 +1,6 @@
 ! sparc __mpn_lshift --
 
-! Copyright (C) 1995 Free Software Foundation, Inc.
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 
 ! This file is part of the GNU MP Library.
 
@@ -39,7 +39,7 @@ C_SYMBOL_NAME(__mpn_lshift):
 	add	%o2,-1,%o2
 	andcc	%o2,4-1,%g4	! number of limbs in first loop
 	srl	%g2,%o5,%g1	! compute function result
-	beq	L0		! if multiple of 4 limbs, skip first loop
+	be	L0		! if multiple of 4 limbs, skip first loop
 	st	%g1,[%sp+80]
 
 	sub	%o2,%g4,%o2	! adjust count for main loop
@@ -56,7 +56,7 @@ Loop0:	ld	[%o1-8],%g3
 	 st	%o4,[%o0+0]
 
 L0:	tst	%o2
-	beq	Lend
+	be	Lend
 	 nop
 
 Loop:	ld	[%o1-8],%g3
diff --git a/sysdeps/sparc/rshift.S b/sysdeps/sparc/rshift.S
index 3428cfe9a4..5a47926302 100644
--- a/sysdeps/sparc/rshift.S
+++ b/sysdeps/sparc/rshift.S
@@ -1,6 +1,6 @@
 ! sparc __mpn_rshift --
 
-! Copyright (C) 1995 Free Software Foundation, Inc.
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 
 ! This file is part of the GNU MP Library.
 
@@ -36,7 +36,7 @@ C_SYMBOL_NAME(__mpn_rshift):
 	add	%o2,-1,%o2
 	andcc	%o2,4-1,%g4	! number of limbs in first loop
 	sll	%g2,%o5,%g1	! compute function result
-	beq	L0		! if multiple of 4 limbs, skip first loop
+	be	L0		! if multiple of 4 limbs, skip first loop
 	st	%g1,[%sp+80]
 
 	sub	%o2,%g4,%o2	! adjust count for main loop
@@ -53,7 +53,7 @@ Loop0:	ld	[%o1+4],%g3
 	 st	%o4,[%o0-4]
 
 L0:	tst	%o2
-	beq	Lend
+	be	Lend
 	 nop
 
 Loop:	ld	[%o1+4],%g3
diff --git a/sysdeps/sparc/sparc64/add_n.s b/sysdeps/sparc/sparc64/add_n.s
new file mode 100644
index 0000000000..104a89e78c
--- /dev/null
+++ b/sysdeps/sparc/sparc64/add_n.s
@@ -0,0 +1,57 @@
+! SPARC v9 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+! sum in a third limb vector.
+
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr	%o0
+! s1_ptr	%o1
+! s2_ptr	%o2
+! size		%o3
+
+.section	".text"
+	.align 4
+	.global __mpn_add_n
+	.type	 __mpn_add_n,#function
+	.proc	04
+__mpn_add_n:
+	sub %g0,%o3,%g3
+	sllx %o3,3,%g1
+	add %o1,%g1,%o1			! make s1_ptr point at end
+	add %o2,%g1,%o2			! make s2_ptr point at end
+	add %o0,%g1,%o0			! make res_ptr point at end
+	mov 0,%o4			! clear carry variable
+	sllx %g3,3,%o5			! compute initial address index
+
+.Loop:	ldx [%o2+%o5],%g1		! load s2 limb
+	add %g3,1,%g3			! increment loop count
+	ldx [%o1+%o5],%g2		! load s1 limb
+	addcc %g1,%o4,%g1		! add s2 limb and carry variable
+	movcc %xcc,0,%o4		! if carry-out, o4 was 1; clear it
+	addcc %g1,%g2,%g1		! add s1 limb to sum
+	stx %g1,[%o0+%o5]		! store result
+	add %o5,8,%o5			! increment address index
+	brnz,pt %g3,.Loop
+	movcs %xcc,1,%o4		! if s1 add gave carry, record it
+
+	retl
+	mov %o4,%o0
+.LLfe1:
+	.size	 __mpn_add_n,.LLfe1-__mpn_add_n
diff --git a/sysdeps/sparc/sparc64/addmul_1.s b/sysdeps/sparc/sparc64/addmul_1.s
new file mode 100644
index 0000000000..ef013eeb91
--- /dev/null
+++ b/sysdeps/sparc/sparc64/addmul_1.s
@@ -0,0 +1,88 @@
+! SPARC v9 __mpn_addmul_1 -- Multiply a limb vector with a single limb and
+! add the product to a second limb vector.
+
+! Copyright (C) 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr	o0
+! s1_ptr	o1
+! size		o2
+! s2_limb	o3
+
+.section	".text"
+	.align 4
+	.global __mpn_addmul_1
+	.type	 __mpn_addmul_1,#function
+	.proc	016
+__mpn_addmul_1:
+	!#PROLOGUE#	0
+	save	%sp,-160,%sp
+	!#PROLOGUE#	1
+	sub	%g0,%i2,%o7
+	sllx	%o7,3,%g5
+	sub	%i1,%g5,%o3
+	sub	%i0,%g5,%o4
+	mov	0,%o0			! zero cy_limb
+
+	srl	%i3,0,%o1		! extract low 32 bits of s2_limb
+	srlx	%i3,32,%i3		! extract high 32 bits of s2_limb
+	mov	1,%o2
+	sllx	%o2,32,%o2		! o2 = 0x100000000
+
+	!   hi   !
+             !  mid-1 !
+             !  mid-2 !
+		 !   lo   !
+.Loop:
+	sllx	%o7,3,%g1
+	ldx	[%o3+%g1],%g5
+	srl	%g5,0,%i0		! zero hi bits
+	srlx	%g5,32,%g5
+	mulx	%o1,%i0,%i4		! lo product
+	mulx	%i3,%i0,%i1		! mid-1 product
+	mulx	%o1,%g5,%l2		! mid-2 product
+	mulx	%i3,%g5,%i5		! hi product
+	srlx	%i4,32,%i0		! extract high 32 bits of lo product...
+	add	%i1,%i0,%i1		! ...and add it to the mid-1 product
+	addcc	%i1,%l2,%i1		! add mid products
+	mov	0,%l0			! we need the carry from that add...
+	movcs	%xcc,%o2,%l0		! ...compute it and...
+	add	%i5,%l0,%i5		! ...add to bit 32 of the hi product
+	sllx	%i1,32,%i0		! align low bits of mid product
+	srl	%i4,0,%g5		! zero high 32 bits of lo product
+	add	%i0,%g5,%i0		! combine into low 64 bits of result
+	srlx	%i1,32,%i1		! extract high bits of mid product...
+	add	%i5,%i1,%i1		! ...and add them to the high result
+	addcc	%i0,%o0,%i0		! add cy_limb to low 64 bits of result
+	mov	0,%g5
+	movcs	%xcc,1,%g5
+	add	%o7,1,%o7
+	ldx	[%o4+%g1],%l1
+	addcc	%l1,%i0,%i0
+	movcs	%xcc,1,%g5
+	stx	%i0,[%o4+%g1]
+	brnz	%o7,.Loop
+	add	%i1,%g5,%o0		! compute new cy_limb
+
+	mov	%o0,%i0
+	ret
+	restore
+.LLfe1:
+	.size  __mpn_addmul_1,.LLfe1-__mpn_addmul_1
diff --git a/sysdeps/sparc/sparc64/gmp-mparam.h b/sysdeps/sparc/sparc64/gmp-mparam.h
new file mode 100644
index 0000000000..05c893f790
--- /dev/null
+++ b/sysdeps/sparc/sparc64/gmp-mparam.h
@@ -0,0 +1,26 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#define BITS_PER_MP_LIMB 64
+#define BYTES_PER_MP_LIMB 8
+#define BITS_PER_LONGINT 64
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
diff --git a/sysdeps/sparc/sparc64/lshift.s b/sysdeps/sparc/sparc64/lshift.s
new file mode 100644
index 0000000000..bd7fa0111f
--- /dev/null
+++ b/sysdeps/sparc/sparc64/lshift.s
@@ -0,0 +1,95 @@
+! SPARC v9 __mpn_lshift --
+
+! Copyright (C) 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr	%o0
+! src_ptr	%o1
+! size		%o2
+! cnt		%o3
+
+.section	".text"
+	.align 4
+	.global __mpn_lshift
+	.type	 __mpn_lshift,#function
+	.proc	04
+__mpn_lshift:
+	sllx	%o2,3,%g1
+	add	%o1,%g1,%o1	! make %o1 point at end of src
+	ldx	[%o1-8],%g2	! load first limb
+	sub	%g0,%o3,%o5	! negate shift count
+	add	%o0,%g1,%o0	! make %o0 point at end of res
+	add	%o2,-1,%o2
+	and	%o2,4-1,%g4	! number of limbs in first loop
+	srlx	%g2,%o5,%g1	! compute function result
+	brz,pn	%g4,.L0		! if multiple of 4 limbs, skip first loop
+	stx	%g1,[%sp+80]
+
+	sub	%o2,%g4,%o2	! adjust count for main loop
+
+.Loop0:	ldx	[%o1-16],%g3
+	add	%o0,-8,%o0
+	add	%o1,-8,%o1
+	add	%g4,-1,%g4
+	sllx	%g2,%o3,%o4
+	srlx	%g3,%o5,%g1
+	mov	%g3,%g2
+	or	%o4,%g1,%o4
+	brnz,pt	%g4,.Loop0
+	 stx	%o4,[%o0+0]
+
+.L0:	brz,pn	%o2,.Lend
+	 nop
+
+.Loop:	ldx	[%o1-16],%g3
+	add	%o0,-32,%o0
+	add	%o2,-4,%o2
+	sllx	%g2,%o3,%o4
+	srlx	%g3,%o5,%g1
+
+	ldx	[%o1-24],%g2
+	sllx	%g3,%o3,%g4
+	or	%o4,%g1,%o4
+	stx	%o4,[%o0+24]
+	srlx	%g2,%o5,%g1
+
+	ldx	[%o1-32],%g3
+	sllx	%g2,%o3,%o4
+	or	%g4,%g1,%g4
+	stx	%g4,[%o0+16]
+	srlx	%g3,%o5,%g1
+
+	ldx	[%o1-40],%g2
+	sllx	%g3,%o3,%g4
+	or	%o4,%g1,%o4
+	stx	%o4,[%o0+8]
+	srlx	%g2,%o5,%g1
+
+	add	%o1,-32,%o1
+	or	%g4,%g1,%g4
+	brnz,pt	%o2,.Loop
+	 stx	%g4,[%o0+0]
+
+.Lend:	sllx	%g2,%o3,%g2
+	stx	%g2,[%o0-8]
+	retl
+	ldx	[%sp+80],%o0
+.LLfe1:
+	.size	 __mpn_lshift,.LLfe1-__mpn_lshift
diff --git a/sysdeps/sparc/sparc64/mul_1.s b/sysdeps/sparc/sparc64/mul_1.s
new file mode 100644
index 0000000000..41be3705a8
--- /dev/null
+++ b/sysdeps/sparc/sparc64/mul_1.s
@@ -0,0 +1,85 @@
+! SPARC v9 __mpn_mul_1 -- Multiply a limb vector with a single limb and
+! store the product in a second limb vector.
+
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr	o0
+! s1_ptr	o1
+! size		o2
+! s2_limb	o3
+
+.section	".text"
+	.align 4
+	.global __mpn_mul_1
+	.type	 __mpn_mul_1,#function
+	.proc	016
+__mpn_mul_1:
+	!#PROLOGUE#	0
+	save	%sp,-160,%sp
+	!#PROLOGUE#	1
+	sub	%g0,%i2,%o7
+	sllx	%o7,3,%g5
+	sub	%i1,%g5,%o3
+	sub	%i0,%g5,%o4
+	mov	0,%o0			! zero cy_limb
+
+	srl	%i3,0,%o1		! extract low 32 bits of s2_limb
+	srlx	%i3,32,%i3		! extract high 32 bits of s2_limb
+	mov	1,%o2
+	sllx	%o2,32,%o2		! o2 = 0x100000000
+
+	!   hi   !
+             !  mid-1 !
+             !  mid-2 !
+		 !   lo   !
+.Loop:
+	sllx	%o7,3,%g1
+	ldx	[%o3+%g1],%g5
+	srl	%g5,0,%i0		! zero hi bits
+	srlx	%g5,32,%g5
+	mulx	%o1,%i0,%i4		! lo product
+	mulx	%i3,%i0,%i1		! mid-1 product
+	mulx	%o1,%g5,%l2		! mid-2 product
+	mulx	%i3,%g5,%i5		! hi product
+	srlx	%i4,32,%i0		! extract high 32 bits of lo product...
+	add	%i1,%i0,%i1		! ...and add it to the mid-1 product
+	addcc	%i1,%l2,%i1		! add mid products
+	mov	0,%l0			! we need the carry from that add...
+	movcs	%xcc,%o2,%l0		! ...compute it and...
+	add	%i5,%l0,%i5		! ...add to bit 32 of the hi product
+	sllx	%i1,32,%i0		! align low bits of mid product
+	srl	%i4,0,%g5		! zero high 32 bits of lo product
+	add	%i0,%g5,%i0		! combine into low 64 bits of result
+	srlx	%i1,32,%i1		! extract high bits of mid product...
+	add	%i5,%i1,%i1		! ...and add them to the high result
+	addcc	%i0,%o0,%i0		! add cy_limb to low 64 bits of result
+	mov	0,%g5
+	movcs	%xcc,1,%g5
+	add	%o7,1,%o7
+	stx	%i0,[%o4+%g1]
+	brnz	%o7,.Loop
+	add	%i1,%g5,%o0		! compute new cy_limb
+
+	mov	%o0,%i0
+	ret
+	restore
+.LLfe1:
+	.size  __mpn_mul_1,.LLfe1-__mpn_mul_1
diff --git a/sysdeps/sparc/sparc64/rshift.s b/sysdeps/sparc/sparc64/rshift.s
new file mode 100644
index 0000000000..971deec2a4
--- /dev/null
+++ b/sysdeps/sparc/sparc64/rshift.s
@@ -0,0 +1,92 @@
+! SPARC v9 __mpn_rshift --
+
+! Copyright (C) 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr	%o0
+! src_ptr	%o1
+! size		%o2
+! cnt		%o3
+
+.section	".text"
+	.align	4
+	.global	__mpn_rshift
+	.type	__mpn_rshift,#function
+	.proc	04
+__mpn_rshift:
+	ldx	[%o1],%g2	! load first limb
+	sub	%g0,%o3,%o5	! negate shift count
+	add	%o2,-1,%o2
+	and	%o2,4-1,%g4	! number of limbs in first loop
+	sllx	%g2,%o5,%g1	! compute function result
+	brz,pn	%g4,.L0		! if multiple of 4 limbs, skip first loop
+	stx	%g1,[%sp+80]
+
+	sub	%o2,%g4,%o2	! adjust count for main loop
+
+.Loop0:	ldx	[%o1+8],%g3
+	add	%o0,8,%o0
+	add	%o1,8,%o1
+	add	%g4,-1,%g4
+	srlx	%g2,%o3,%o4
+	sllx	%g3,%o5,%g1
+	mov	%g3,%g2
+	or	%o4,%g1,%o4
+	brnz,pt	%g4,.Loop0
+	 stx	%o4,[%o0-8]
+
+.L0:	brz,pn	%o2,.Lend
+	 nop
+
+.Loop:	ldx	[%o1+8],%g3
+	add	%o0,32,%o0
+	add	%o2,-4,%o2
+	srlx	%g2,%o3,%o4
+	sllx	%g3,%o5,%g1
+
+	ldx	[%o1+16],%g2
+	srlx	%g3,%o3,%g4
+	or	%o4,%g1,%o4
+	stx	%o4,[%o0-32]
+	sllx	%g2,%o5,%g1
+
+	ldx	[%o1+24],%g3
+	srlx	%g2,%o3,%o4
+	or	%g4,%g1,%g4
+	stx	%g4,[%o0-24]
+	sllx	%g3,%o5,%g1
+
+	ldx	[%o1+32],%g2
+	srlx	%g3,%o3,%g4
+	or	%o4,%g1,%o4
+	stx	%o4,[%o0-16]
+	sllx	%g2,%o5,%g1
+
+	add	%o1,32,%o1
+	or	%g4,%g1,%g4
+	brnz	%o2,.Loop
+	 stx	%g4,[%o0-8]
+
+.Lend:	srlx	%g2,%o3,%g2
+	stx	%g2,[%o0-0]
+	retl
+	ldx	[%sp+80],%o0
+.LLfe1:
+	.size	__mpn_rshift,.LLfe1-__mpn_rshift
diff --git a/sysdeps/sparc/sparc64/sub_n.s b/sysdeps/sparc/sparc64/sub_n.s
new file mode 100644
index 0000000000..7099bf43e9
--- /dev/null
+++ b/sysdeps/sparc/sparc64/sub_n.s
@@ -0,0 +1,57 @@
+! SPARC v9 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+! store difference in a third limb vector.
+
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr	%o0
+! s1_ptr	%o1
+! s2_ptr	%o2
+! size		%o3
+
+.section	".text"
+	.align 4
+	.global __mpn_sub_n
+	.type	 __mpn_sub_n,#function
+	.proc	04
+__mpn_sub_n:
+	sub %g0,%o3,%g3
+	sllx %o3,3,%g1
+	add %o1,%g1,%o1			! make s1_ptr point at end
+	add %o2,%g1,%o2			! make s2_ptr point at end
+	add %o0,%g1,%o0			! make res_ptr point at end
+	mov 0,%o4			! clear carry variable
+	sllx %g3,3,%o5			! compute initial address index
+
+.Loop:	ldx [%o2+%o5],%g1		! load s2 limb
+	add %g3,1,%g3			! increment loop count
+	ldx [%o1+%o5],%g2		! load s1 limb
+	addcc %g1,%o4,%g1		! add s2 limb and carry variable
+	movcc %xcc,0,%o4		! if carry-out, o4 was 1; clear it
+	subcc %g1,%g2,%g1		! subtract s1 limb from sum
+	stx %g1,[%o0+%o5]		! store result
+	add %o5,8,%o5			! increment address index
+	brnz,pt %g3,.Loop
+	movcs %xcc,1,%o4		! if s1 subtract gave carry, record it
+
+	retl
+	mov %o4,%o0
+.LLfe1:
+	.size	 __mpn_sub_n,.LLfe1-__mpn_sub_n
diff --git a/sysdeps/sparc/sparc64/submul_1.s b/sysdeps/sparc/sparc64/submul_1.s
new file mode 100644
index 0000000000..f0df38c3bc
--- /dev/null
+++ b/sysdeps/sparc/sparc64/submul_1.s
@@ -0,0 +1,88 @@
+! SPARC v9 __mpn_submul_1 -- Multiply a limb vector with a single limb and
+! subtract the product from a second limb vector.
+
+! Copyright (C) 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr	o0
+! s1_ptr	o1
+! size		o2
+! s2_limb	o3
+
+.section	".text"
+	.align 4
+	.global __mpn_submul_1
+	.type	 __mpn_submul_1,#function
+	.proc	016
+__mpn_submul_1:
+	!#PROLOGUE#	0
+	save	%sp,-160,%sp
+	!#PROLOGUE#	1
+	sub	%g0,%i2,%o7
+	sllx	%o7,3,%g5
+	sub	%i1,%g5,%o3
+	sub	%i0,%g5,%o4
+	mov	0,%o0			! zero cy_limb
+
+	srl	%i3,0,%o1		! extract low 32 bits of s2_limb
+	srlx	%i3,32,%i3		! extract high 32 bits of s2_limb
+	mov	1,%o2
+	sllx	%o2,32,%o2		! o2 = 0x100000000
+
+	!   hi   !
+             !  mid-1 !
+             !  mid-2 !
+		 !   lo   !
+.Loop:
+	sllx	%o7,3,%g1
+	ldx	[%o3+%g1],%g5
+	srl	%g5,0,%i0		! zero hi bits
+	srlx	%g5,32,%g5
+	mulx	%o1,%i0,%i4		! lo product
+	mulx	%i3,%i0,%i1		! mid-1 product
+	mulx	%o1,%g5,%l2		! mid-2 product
+	mulx	%i3,%g5,%i5		! hi product
+	srlx	%i4,32,%i0		! extract high 32 bits of lo product...
+	add	%i1,%i0,%i1		! ...and add it to the mid-1 product
+	addcc	%i1,%l2,%i1		! add mid products
+	mov	0,%l0			! we need the carry from that add...
+	movcs	%xcc,%o2,%l0		! ...compute it and...
+	add	%i5,%l0,%i5		! ...add to bit 32 of the hi product
+	sllx	%i1,32,%i0		! align low bits of mid product
+	srl	%i4,0,%g5		! zero high 32 bits of lo product
+	add	%i0,%g5,%i0		! combine into low 64 bits of result
+	srlx	%i1,32,%i1		! extract high bits of mid product...
+	add	%i5,%i1,%i1		! ...and add them to the high result
+	addcc	%i0,%o0,%i0		! add cy_limb to low 64 bits of result
+	mov	0,%g5
+	movcs	%xcc,1,%g5
+	add	%o7,1,%o7
+	ldx	[%o4+%g1],%l1
+	subcc	%l1,%i0,%i0
+	movcs	%xcc,1,%g5
+	stx	%i0,[%o4+%g1]
+	brnz	%o7,.Loop
+	add	%i1,%g5,%o0		! compute new cy_limb
+
+	mov	%o0,%i0
+	ret
+	restore
+.LLfe1:
+	.size  __mpn_submul_1,.LLfe1-__mpn_submul_1
diff --git a/sysdeps/sparc/sparc8/addmul_1.S b/sysdeps/sparc/sparc8/addmul_1.S
index d1de0c3649..1cf5128ee5 100644
--- a/sysdeps/sparc/sparc8/addmul_1.S
+++ b/sysdeps/sparc/sparc8/addmul_1.S
@@ -1,7 +1,7 @@
 ! SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and
 ! add the result to a second limb vector.
 
-! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+! Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
 
 ! This file is part of the GNU MP Library.
 
diff --git a/sysdeps/sparc/sparc8/mul_1.S b/sysdeps/sparc/sparc8/mul_1.S
index 42717be33b..d56394e135 100644
--- a/sysdeps/sparc/sparc8/mul_1.S
+++ b/sysdeps/sparc/sparc8/mul_1.S
@@ -1,7 +1,7 @@
 ! SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and
 ! store the product in a second limb vector.
 
-! Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+! Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
 
 ! This file is part of the GNU MP Library.
 
diff --git a/sysdeps/sparc/sub_n.S b/sysdeps/sparc/sub_n.S
index 2e217ed679..9ff5b7b863 100644
--- a/sysdeps/sparc/sub_n.S
+++ b/sysdeps/sparc/sub_n.S
@@ -1,7 +1,7 @@
-! sparc __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
 ! store difference in a third limb vector.
 
-! Copyright (C) 1995 Free Software Foundation, Inc.
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 
 ! This file is part of the GNU MP Library.
 
@@ -38,7 +38,7 @@ C_SYMBOL_NAME(__mpn_sub_n):
 	nop
 ! **  V1a  **
 	andcc	res_ptr,4,%g0		! res_ptr unaligned? Side effect: cy=0
-	beq	L_v1			! if no, branch
+	be	L_v1			! if no, branch
 	nop
 /* Add least significant limb separately to align res_ptr and s2_ptr */
 	ld	[s1_ptr],%g4
@@ -133,9 +133,9 @@ L1:	xor	s1_ptr,res_ptr,%g1
 	nop
 ! **  V1b  **
 	andcc	res_ptr,4,%g0		! res_ptr unaligned? Side effect: cy=0
-	beq	L_v1b			! if no, branch
+	be	L_v1b			! if no, branch
 	nop
-/* Add least significant limb separately to align res_ptr and s2_ptr */
+/* Add least significant limb separately to align res_ptr and s1_ptr */
 	ld	[s2_ptr],%g4
 	add	s2_ptr,4,s2_ptr
 	ld	[s1_ptr],%g2
@@ -232,7 +232,7 @@ L2:	cmp	size,1
 	be	Ljone
 	nop
 	andcc	s1_ptr,4,%g0		! s1_ptr unaligned? Side effect: cy=0
-	beq	L_v2			! if no, branch
+	be	L_v2			! if no, branch
 	nop
 /* Add least significant limb separately to align s1_ptr and s2_ptr */
 	ld	[s1_ptr],%g4