Blame sysdeps/powerpc/powerpc32/lshift.S

Packit 6c4009
/* Shift a limb left, low level routine.
Packit 6c4009
   Copyright (C) 1996-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_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
Packit 6c4009
			 unsigned int cnt)  */
Packit 6c4009
Packit 6c4009
EALIGN (__mpn_lshift, 3, 0)
Packit 6c4009
Packit 6c4009
	mtctr	r5		# copy size into CTR
Packit 6c4009
	cmplwi	cr0,r5,16	# is size < 16
Packit 6c4009
	slwi	r0,r5,2
Packit 6c4009
	add	r7,r3,r0	# make r7 point at end of res
Packit 6c4009
	add	r4,r4,r0	# make r4 point at end of s1
Packit 6c4009
	lwzu	r11,-4(r4)	# load first s1 limb
Packit 6c4009
	subfic	r8,r6,32
Packit 6c4009
	srw	r3,r11,r8	# compute function return value
Packit 6c4009
	bge	cr0,L(big)	# branch if size >= 16
Packit 6c4009
Packit 6c4009
	bdz	L(end1)
Packit 6c4009
Packit 6c4009
L(0):	lwzu	r10,-4(r4)
Packit 6c4009
	slw	r9,r11,r6
Packit 6c4009
	srw	r12,r10,r8
Packit 6c4009
	or	r9,r9,r12
Packit 6c4009
	stwu	r9,-4(r7)
Packit 6c4009
	bdz	L(end2)
Packit 6c4009
	lwzu	r11,-4(r4)
Packit 6c4009
	slw	r9,r10,r6
Packit 6c4009
	srw	r12,r11,r8
Packit 6c4009
	or	r9,r9,r12
Packit 6c4009
	stwu	r9,-4(r7)
Packit 6c4009
	bdnz	L(0)
Packit 6c4009
Packit 6c4009
L(end1):slw	r0,r11,r6
Packit 6c4009
	stw	r0,-4(r7)
Packit 6c4009
	blr
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Guaranteed not to succeed.  */
Packit 6c4009
L(boom): tweq    r0,r0
Packit 6c4009
Packit 6c4009
/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
Packit 6c4009
   of size 4*12 bytes.  We have to do this (or something) to make this PIC.  */
Packit 6c4009
L(big):	mflr    r9
Packit 6c4009
	cfi_register(lr,r9)
Packit 6c4009
	bltl-   cr0,L(boom)	# Never taken, only used to set LR.
Packit 6c4009
	slwi    r10,r6,4
Packit 6c4009
	mflr    r12
Packit 6c4009
	add     r10,r12,r10
Packit 6c4009
	slwi	r8,r6,5
Packit 6c4009
	add     r10,r8,r10
Packit 6c4009
	mtctr   r10
Packit 6c4009
	addi	r5,r5,-1
Packit 6c4009
	mtlr	r9
Packit 6c4009
	cfi_same_value (lr)
Packit 6c4009
	bctr
Packit 6c4009
Packit 6c4009
L(end2):slw	r0,r10,r6
Packit 6c4009
	stw	r0,-4(r7)
Packit 6c4009
	blr
Packit 6c4009
Packit 6c4009
#define DO_LSHIFT(n) \
Packit 6c4009
	mtctr	r5;							\
Packit 6c4009
L(n):	lwzu	r10,-4(r4);						\
Packit 6c4009
	slwi	r9,r11,n;						\
Packit 6c4009
	inslwi	r9,r10,n,32-n;					\
Packit 6c4009
	stwu	r9,-4(r7);						\
Packit 6c4009
	bdz-	L(end2);						\
Packit 6c4009
	lwzu	r11,-4(r4);						\
Packit 6c4009
	slwi	r9,r10,n;						\
Packit 6c4009
	inslwi	r9,r11,n,32-n;					\
Packit 6c4009
	stwu	r9,-4(r7);						\
Packit 6c4009
	bdnz	L(n);							\
Packit 6c4009
	b	L(end1)
Packit 6c4009
Packit 6c4009
	DO_LSHIFT(1)
Packit 6c4009
	DO_LSHIFT(2)
Packit 6c4009
	DO_LSHIFT(3)
Packit 6c4009
	DO_LSHIFT(4)
Packit 6c4009
	DO_LSHIFT(5)
Packit 6c4009
	DO_LSHIFT(6)
Packit 6c4009
	DO_LSHIFT(7)
Packit 6c4009
	DO_LSHIFT(8)
Packit 6c4009
	DO_LSHIFT(9)
Packit 6c4009
	DO_LSHIFT(10)
Packit 6c4009
	DO_LSHIFT(11)
Packit 6c4009
	DO_LSHIFT(12)
Packit 6c4009
	DO_LSHIFT(13)
Packit 6c4009
	DO_LSHIFT(14)
Packit 6c4009
	DO_LSHIFT(15)
Packit 6c4009
	DO_LSHIFT(16)
Packit 6c4009
	DO_LSHIFT(17)
Packit 6c4009
	DO_LSHIFT(18)
Packit 6c4009
	DO_LSHIFT(19)
Packit 6c4009
	DO_LSHIFT(20)
Packit 6c4009
	DO_LSHIFT(21)
Packit 6c4009
	DO_LSHIFT(22)
Packit 6c4009
	DO_LSHIFT(23)
Packit 6c4009
	DO_LSHIFT(24)
Packit 6c4009
	DO_LSHIFT(25)
Packit 6c4009
	DO_LSHIFT(26)
Packit 6c4009
	DO_LSHIFT(27)
Packit 6c4009
	DO_LSHIFT(28)
Packit 6c4009
	DO_LSHIFT(29)
Packit 6c4009
	DO_LSHIFT(30)
Packit 6c4009
	DO_LSHIFT(31)
Packit 6c4009
Packit 6c4009
END (__mpn_lshift)