Blame sysdeps/sparc/sparc32/add_n.S

Packit Service 82fcde
! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
Packit Service 82fcde
! sum in a third limb vector.
Packit Service 82fcde
!
Packit Service 82fcde
! Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit Service 82fcde
!
Packit Service 82fcde
! This file is part of the GNU MP Library.
Packit Service 82fcde
!
Packit Service 82fcde
! The GNU MP Library is free software; you can redistribute it and/or modify
Packit Service 82fcde
! it under the terms of the GNU Lesser General Public License as published by
Packit Service 82fcde
! the Free Software Foundation; either version 2.1 of the License, or (at your
Packit Service 82fcde
! option) any later version.
Packit Service 82fcde
!
Packit Service 82fcde
! The GNU MP Library is distributed in the hope that it will be useful, but
Packit Service 82fcde
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit Service 82fcde
! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
Packit Service 82fcde
! License for more details.
Packit Service 82fcde
!
Packit Service 82fcde
! You should have received a copy of the GNU Lesser General Public License
Packit Service 82fcde
! along with the GNU MP Library; see the file COPYING.LIB.  If not,
Packit Service 82fcde
! see <http://www.gnu.org/licenses/>.
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
! INPUT PARAMETERS
Packit Service 82fcde
#define RES_PTR	%o0
Packit Service 82fcde
#define S1_PTR	%o1
Packit Service 82fcde
#define S2_PTR	%o2
Packit Service 82fcde
#define SIZE	%o3
Packit Service 82fcde
Packit Service 82fcde
#include <sysdep.h>
Packit Service 82fcde
Packit Service 82fcde
ENTRY(__mpn_add_n)
Packit Service 82fcde
	xor	S2_PTR,RES_PTR,%g1
Packit Service 82fcde
	andcc	%g1,4,%g0
Packit Service 82fcde
	bne	LOC(1)			! branch if alignment differs
Packit Service 82fcde
	 nop
Packit Service 82fcde
! **  V1a  **
Packit Service 82fcde
LOC(0):	andcc	RES_PTR,4,%g0		! RES_PTR unaligned? Side effect: cy=0
Packit Service 82fcde
	be	LOC(v1)			! if no, branch
Packit Service 82fcde
	 nop
Packit Service 82fcde
/* Add least significant limb separately to align RES_PTR and S2_PTR */
Packit Service 82fcde
	ld	[S1_PTR],%g4
Packit Service 82fcde
	add	S1_PTR,4,S1_PTR
Packit Service 82fcde
	ld	[S2_PTR],%g2
Packit Service 82fcde
	add	S2_PTR,4,S2_PTR
Packit Service 82fcde
	add	SIZE,-1,SIZE
Packit Service 82fcde
	addcc	%g4,%g2,%o4
Packit Service 82fcde
	st	%o4,[RES_PTR]
Packit Service 82fcde
	add	RES_PTR,4,RES_PTR
Packit Service 82fcde
LOC(v1):
Packit Service 82fcde
	addx	%g0,%g0,%o4		! save cy in register
Packit Service 82fcde
	cmp	SIZE,2			! if SIZE < 2 ...
Packit Service 82fcde
	bl	LOC(end2)		! ... branch to tail code
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
Packit Service 82fcde
	ld	[S1_PTR+0],%g4
Packit Service 82fcde
	addcc	SIZE,-10,SIZE
Packit Service 82fcde
	ld	[S1_PTR+4],%g1
Packit Service 82fcde
	ldd	[S2_PTR+0],%g2
Packit Service 82fcde
	blt	LOC(fin1)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
/* Add blocks of 8 limbs until less than 8 limbs remain */
Packit Service 82fcde
LOC(loop1):
Packit Service 82fcde
	addxcc	%g4,%g2,%o4
Packit Service 82fcde
	ld	[S1_PTR+8],%g4
Packit Service 82fcde
	addxcc	%g1,%g3,%o5
Packit Service 82fcde
	ld	[S1_PTR+12],%g1
Packit Service 82fcde
	ldd	[S2_PTR+8],%g2
Packit Service 82fcde
	std	%o4,[RES_PTR+0]
Packit Service 82fcde
	addxcc	%g4,%g2,%o4
Packit Service 82fcde
	ld	[S1_PTR+16],%g4
Packit Service 82fcde
	addxcc	%g1,%g3,%o5
Packit Service 82fcde
	ld	[S1_PTR+20],%g1
Packit Service 82fcde
	ldd	[S2_PTR+16],%g2
Packit Service 82fcde
	std	%o4,[RES_PTR+8]
Packit Service 82fcde
	addxcc	%g4,%g2,%o4
Packit Service 82fcde
	ld	[S1_PTR+24],%g4
Packit Service 82fcde
	addxcc	%g1,%g3,%o5
Packit Service 82fcde
	ld	[S1_PTR+28],%g1
Packit Service 82fcde
	ldd	[S2_PTR+24],%g2
Packit Service 82fcde
	std	%o4,[RES_PTR+16]
Packit Service 82fcde
	addxcc	%g4,%g2,%o4
Packit Service 82fcde
	ld	[S1_PTR+32],%g4
Packit Service 82fcde
	addxcc	%g1,%g3,%o5
Packit Service 82fcde
	ld	[S1_PTR+36],%g1
Packit Service 82fcde
	ldd	[S2_PTR+32],%g2
Packit Service 82fcde
	std	%o4,[RES_PTR+24]
Packit Service 82fcde
	addx	%g0,%g0,%o4		! save cy in register
Packit Service 82fcde
	addcc	SIZE,-8,SIZE
Packit Service 82fcde
	add	S1_PTR,32,S1_PTR
Packit Service 82fcde
	add	S2_PTR,32,S2_PTR
Packit Service 82fcde
	add	RES_PTR,32,RES_PTR
Packit Service 82fcde
	bge	LOC(loop1)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
Packit Service 82fcde
LOC(fin1):
Packit Service 82fcde
	addcc	SIZE,8-2,SIZE
Packit Service 82fcde
	blt	LOC(end1)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
/* Add blocks of 2 limbs until less than 2 limbs remain */
Packit Service 82fcde
LOC(loope1):
Packit Service 82fcde
	addxcc	%g4,%g2,%o4
Packit Service 82fcde
	ld	[S1_PTR+8],%g4
Packit Service 82fcde
	addxcc	%g1,%g3,%o5
Packit Service 82fcde
	ld	[S1_PTR+12],%g1
Packit Service 82fcde
	ldd	[S2_PTR+8],%g2
Packit Service 82fcde
	std	%o4,[RES_PTR+0]
Packit Service 82fcde
	addx	%g0,%g0,%o4		! save cy in register
Packit Service 82fcde
	addcc	SIZE,-2,SIZE
Packit Service 82fcde
	add	S1_PTR,8,S1_PTR
Packit Service 82fcde
	add	S2_PTR,8,S2_PTR
Packit Service 82fcde
	add	RES_PTR,8,RES_PTR
Packit Service 82fcde
	bge	LOC(loope1)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
LOC(end1):
Packit Service 82fcde
	addxcc	%g4,%g2,%o4
Packit Service 82fcde
	addxcc	%g1,%g3,%o5
Packit Service 82fcde
	std	%o4,[RES_PTR+0]
Packit Service 82fcde
	addx	%g0,%g0,%o4		! save cy in register
Packit Service 82fcde
Packit Service 82fcde
	andcc	SIZE,1,%g0
Packit Service 82fcde
	be	LOC(ret1)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
/* Add last limb */
Packit Service 82fcde
	ld	[S1_PTR+8],%g4
Packit Service 82fcde
	ld	[S2_PTR+8],%g2
Packit Service 82fcde
	addxcc	%g4,%g2,%o4
Packit Service 82fcde
	st	%o4,[RES_PTR+8]
Packit Service 82fcde
Packit Service 82fcde
LOC(ret1):
Packit Service 82fcde
	retl
Packit Service 82fcde
	addx	%g0,%g0,%o0	! return carry-out from most sign. limb
Packit Service 82fcde
Packit Service 82fcde
LOC(1):	xor	S1_PTR,RES_PTR,%g1
Packit Service 82fcde
	andcc	%g1,4,%g0
Packit Service 82fcde
	bne	LOC(2)
Packit Service 82fcde
	nop
Packit Service 82fcde
! **  V1b  **
Packit Service 82fcde
	mov	S2_PTR,%g1
Packit Service 82fcde
	mov	S1_PTR,S2_PTR
Packit Service 82fcde
	b	LOC(0)
Packit Service 82fcde
	mov	%g1,S1_PTR
Packit Service 82fcde
Packit Service 82fcde
! **  V2  **
Packit Service 82fcde
/* If we come here, the alignment of S1_PTR and RES_PTR as well as the
Packit Service 82fcde
   alignment of S2_PTR and RES_PTR differ.  Since there are only two ways
Packit Service 82fcde
   things can be aligned (that we care about) we now know that the alignment
Packit Service 82fcde
   of S1_PTR and S2_PTR are the same.  */
Packit Service 82fcde
Packit Service 82fcde
LOC(2):	cmp	SIZE,1
Packit Service 82fcde
	be	LOC(jone)
Packit Service 82fcde
	nop
Packit Service 82fcde
	andcc	S1_PTR,4,%g0		! S1_PTR unaligned? Side effect: cy=0
Packit Service 82fcde
	be	LOC(v2)			! if no, branch
Packit Service 82fcde
	nop
Packit Service 82fcde
/* Add least significant limb separately to align S1_PTR and S2_PTR */
Packit Service 82fcde
	ld	[S1_PTR],%g4
Packit Service 82fcde
	add	S1_PTR,4,S1_PTR
Packit Service 82fcde
	ld	[S2_PTR],%g2
Packit Service 82fcde
	add	S2_PTR,4,S2_PTR
Packit Service 82fcde
	add	SIZE,-1,SIZE
Packit Service 82fcde
	addcc	%g4,%g2,%o4
Packit Service 82fcde
	st	%o4,[RES_PTR]
Packit Service 82fcde
	add	RES_PTR,4,RES_PTR
Packit Service 82fcde
Packit Service 82fcde
LOC(v2):
Packit Service 82fcde
	addx	%g0,%g0,%o4		! save cy in register
Packit Service 82fcde
	addcc	SIZE,-8,SIZE
Packit Service 82fcde
	blt	LOC(fin2)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
/* Add blocks of 8 limbs until less than 8 limbs remain */
Packit Service 82fcde
LOC(loop2):
Packit Service 82fcde
	ldd	[S1_PTR+0],%g2
Packit Service 82fcde
	ldd	[S2_PTR+0],%o4
Packit Service 82fcde
	addxcc	%g2,%o4,%g2
Packit Service 82fcde
	st	%g2,[RES_PTR+0]
Packit Service 82fcde
	addxcc	%g3,%o5,%g3
Packit Service 82fcde
	st	%g3,[RES_PTR+4]
Packit Service 82fcde
	ldd	[S1_PTR+8],%g2
Packit Service 82fcde
	ldd	[S2_PTR+8],%o4
Packit Service 82fcde
	addxcc	%g2,%o4,%g2
Packit Service 82fcde
	st	%g2,[RES_PTR+8]
Packit Service 82fcde
	addxcc	%g3,%o5,%g3
Packit Service 82fcde
	st	%g3,[RES_PTR+12]
Packit Service 82fcde
	ldd	[S1_PTR+16],%g2
Packit Service 82fcde
	ldd	[S2_PTR+16],%o4
Packit Service 82fcde
	addxcc	%g2,%o4,%g2
Packit Service 82fcde
	st	%g2,[RES_PTR+16]
Packit Service 82fcde
	addxcc	%g3,%o5,%g3
Packit Service 82fcde
	st	%g3,[RES_PTR+20]
Packit Service 82fcde
	ldd	[S1_PTR+24],%g2
Packit Service 82fcde
	ldd	[S2_PTR+24],%o4
Packit Service 82fcde
	addxcc	%g2,%o4,%g2
Packit Service 82fcde
	st	%g2,[RES_PTR+24]
Packit Service 82fcde
	addxcc	%g3,%o5,%g3
Packit Service 82fcde
	st	%g3,[RES_PTR+28]
Packit Service 82fcde
	addx	%g0,%g0,%o4		! save cy in register
Packit Service 82fcde
	addcc	SIZE,-8,SIZE
Packit Service 82fcde
	add	S1_PTR,32,S1_PTR
Packit Service 82fcde
	add	S2_PTR,32,S2_PTR
Packit Service 82fcde
	add	RES_PTR,32,RES_PTR
Packit Service 82fcde
	bge	LOC(loop2)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
Packit Service 82fcde
LOC(fin2):
Packit Service 82fcde
	addcc	SIZE,8-2,SIZE
Packit Service 82fcde
	blt	LOC(end2)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
LOC(loope2):
Packit Service 82fcde
	ldd	[S1_PTR+0],%g2
Packit Service 82fcde
	ldd	[S2_PTR+0],%o4
Packit Service 82fcde
	addxcc	%g2,%o4,%g2
Packit Service 82fcde
	st	%g2,[RES_PTR+0]
Packit Service 82fcde
	addxcc	%g3,%o5,%g3
Packit Service 82fcde
	st	%g3,[RES_PTR+4]
Packit Service 82fcde
	addx	%g0,%g0,%o4		! save cy in register
Packit Service 82fcde
	addcc	SIZE,-2,SIZE
Packit Service 82fcde
	add	S1_PTR,8,S1_PTR
Packit Service 82fcde
	add	S2_PTR,8,S2_PTR
Packit Service 82fcde
	add	RES_PTR,8,RES_PTR
Packit Service 82fcde
	bge	LOC(loope2)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
LOC(end2):
Packit Service 82fcde
	andcc	SIZE,1,%g0
Packit Service 82fcde
	be	LOC(ret2)
Packit Service 82fcde
	subcc	%g0,%o4,%g0		! restore cy
Packit Service 82fcde
/* Add last limb */
Packit Service 82fcde
LOC(jone):
Packit Service 82fcde
	ld	[S1_PTR],%g4
Packit Service 82fcde
	ld	[S2_PTR],%g2
Packit Service 82fcde
	addxcc	%g4,%g2,%o4
Packit Service 82fcde
	st	%o4,[RES_PTR]
Packit Service 82fcde
Packit Service 82fcde
LOC(ret2):
Packit Service 82fcde
	retl
Packit Service 82fcde
	addx	%g0,%g0,%o0	! return carry-out from most sign. limb
Packit Service 82fcde
Packit Service 82fcde
END(__mpn_add_n)