Blame sysdeps/powerpc/powerpc32/sub_n.S

Packit 6c4009
/* Subtract two limb vectors of equal, non-zero length for PowerPC.
Packit 6c4009
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <sysdep.h>
Packit 6c4009
Packit 6c4009
/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
Packit 6c4009
                        mp_size_t size)
Packit 6c4009
   Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1.  */
Packit 6c4009
Packit 6c4009
/* Note on optimisation: This code is optimal for the 601.  Almost every other
Packit 6c4009
   possible 2-unrolled inner loop will not be.  Also, watch out for the
Packit 6c4009
   alignment...  */
Packit 6c4009
Packit 6c4009
EALIGN (__mpn_sub_n, 3, 1)
Packit 6c4009
Packit 6c4009
/* Set up for loop below.  */
Packit 6c4009
	mtcrf 0x01,r6
Packit 6c4009
	srwi. r7,r6,1
Packit 6c4009
	mtctr r7
Packit 6c4009
	bt    31,L(2)
Packit 6c4009
Packit 6c4009
/* Set the carry (clear the borrow).  */
Packit 6c4009
	subfc r0,r0,r0
Packit 6c4009
/* Adjust pointers for loop.  */
Packit 6c4009
	addi  r3,r3,-4
Packit 6c4009
	addi  r4,r4,-4
Packit 6c4009
	addi  r5,r5,-4
Packit 6c4009
	b     L(0)
Packit 6c4009
Packit 6c4009
L(2):	lwz   r7,0(r5)
Packit 6c4009
	lwz   r6,0(r4)
Packit 6c4009
	subfc r6,r7,r6
Packit 6c4009
	stw   r6,0(r3)
Packit 6c4009
        beq   L(1)
Packit 6c4009
Packit 6c4009
/* Align start of loop to an odd word boundary to guarantee that the
Packit 6c4009
   last two words can be fetched in one access (for 601).  This turns
Packit 6c4009
   out to be important.  */
Packit 6c4009
L(0):
Packit 6c4009
	lwz   r9,4(r4)
Packit 6c4009
	lwz   r8,4(r5)
Packit 6c4009
	lwzu  r6,8(r4)
Packit 6c4009
	lwzu  r7,8(r5)
Packit 6c4009
	subfe r8,r8,r9
Packit 6c4009
	stw   r8,4(r3)
Packit 6c4009
	subfe r6,r7,r6
Packit 6c4009
	stwu  r6,8(r3)
Packit 6c4009
	bdnz  L(0)
Packit 6c4009
/* Return the borrow. */
Packit 6c4009
L(1):	subfe r3,r3,r3
Packit 6c4009
	neg   r3,r3
Packit 6c4009
	blr
Packit 6c4009
END (__mpn_sub_n)