Blame sysdeps/m68k/m680x0/lshift.S

Packit Service 82fcde
/* mc68020 __mpn_lshift -- Shift left a low-level natural-number integer.
Packit Service 82fcde
Packit Service 82fcde
Copyright (C) 1996-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.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
  INPUT PARAMETERS
Packit Service 82fcde
  res_ptr	(sp + 4)
Packit Service 82fcde
  s_ptr		(sp + 8)
Packit Service 82fcde
  s_size	(sp + 16)
Packit Service 82fcde
  cnt		(sp + 12)
Packit Service 82fcde
*/
Packit Service 82fcde
Packit Service 82fcde
#include "sysdep.h"
Packit Service 82fcde
#include "asm-syntax.h"
Packit Service 82fcde
Packit Service 82fcde
#define res_ptr a1
Packit Service 82fcde
#define s_ptr a0
Packit Service 82fcde
#define s_size d6
Packit Service 82fcde
#define cnt d4
Packit Service 82fcde
Packit Service 82fcde
	TEXT
Packit Service 82fcde
ENTRY(__mpn_lshift)
Packit Service 82fcde
Packit Service 82fcde
/* Save used registers on the stack.  */
Packit Service 82fcde
	moveml	R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
Packit Service 82fcde
	cfi_adjust_cfa_offset (6*4)
Packit Service 82fcde
	cfi_rel_offset (R(d2), 0)
Packit Service 82fcde
	cfi_rel_offset (R(d3), 4)
Packit Service 82fcde
	cfi_rel_offset (R(d4), 8)
Packit Service 82fcde
	cfi_rel_offset (R(d5), 12)
Packit Service 82fcde
	cfi_rel_offset (R(d6), 16)
Packit Service 82fcde
	cfi_rel_offset (R(a2), 20)
Packit Service 82fcde
Packit Service 82fcde
/* Copy the arguments to registers.  */
Packit Service 82fcde
	movel	MEM_DISP(sp,28),R(res_ptr)
Packit Service 82fcde
	movel	MEM_DISP(sp,32),R(s_ptr)
Packit Service 82fcde
	movel	MEM_DISP(sp,36),R(s_size)
Packit Service 82fcde
	movel	MEM_DISP(sp,40),R(cnt)
Packit Service 82fcde
Packit Service 82fcde
	moveql	#1,R(d5)
Packit Service 82fcde
	cmpl	R(d5),R(cnt)
Packit Service 82fcde
	bne	L(Lnormal)
Packit Service 82fcde
	cmpl	R(s_ptr),R(res_ptr)
Packit Service 82fcde
	bls	L(Lspecial)		/* jump if s_ptr >= res_ptr */
Packit Service 82fcde
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
Packit Service 82fcde
	lea	MEM_INDX1(s_ptr,s_size,l,4),R(a2)
Packit Service 82fcde
#else /* not mc68020 */
Packit Service 82fcde
	movel	R(s_size),R(d0)
Packit Service 82fcde
	asll	#2,R(d0)
Packit Service 82fcde
	lea	MEM_INDX(s_ptr,d0,l),R(a2)
Packit Service 82fcde
#endif
Packit Service 82fcde
	cmpl	R(res_ptr),R(a2)
Packit Service 82fcde
	bls	L(Lspecial)		/* jump if res_ptr >= s_ptr + s_size */
Packit Service 82fcde
Packit Service 82fcde
L(Lnormal:)
Packit Service 82fcde
	moveql	#32,R(d5)
Packit Service 82fcde
	subl	R(cnt),R(d5)
Packit Service 82fcde
Packit Service 82fcde
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
Packit Service 82fcde
	lea	MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
Packit Service 82fcde
	lea	MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
Packit Service 82fcde
#else /* not mc68000 */
Packit Service 82fcde
	movel	R(s_size),R(d0)
Packit Service 82fcde
	asll	#2,R(d0)
Packit Service 82fcde
	addl	R(s_size),R(s_ptr)
Packit Service 82fcde
	addl	R(s_size),R(res_ptr)
Packit Service 82fcde
#endif
Packit Service 82fcde
	movel	MEM_PREDEC(s_ptr),R(d2)
Packit Service 82fcde
	movel	R(d2),R(d0)
Packit Service 82fcde
	lsrl	R(d5),R(d0)		/* compute carry limb */
Packit Service 82fcde
Packit Service 82fcde
	lsll	R(cnt),R(d2)
Packit Service 82fcde
	movel	R(d2),R(d1)
Packit Service 82fcde
	subql	#1,R(s_size)
Packit Service 82fcde
	beq	L(Lend)
Packit Service 82fcde
	lsrl	#1,R(s_size)
Packit Service 82fcde
	bcs	L(L1)
Packit Service 82fcde
	subql	#1,R(s_size)
Packit Service 82fcde
Packit Service 82fcde
L(Loop:)
Packit Service 82fcde
	movel	MEM_PREDEC(s_ptr),R(d2)
Packit Service 82fcde
	movel	R(d2),R(d3)
Packit Service 82fcde
	lsrl	R(d5),R(d3)
Packit Service 82fcde
	orl	R(d3),R(d1)
Packit Service 82fcde
	movel	R(d1),MEM_PREDEC(res_ptr)
Packit Service 82fcde
	lsll	R(cnt),R(d2)
Packit Service 82fcde
L(L1:)
Packit Service 82fcde
	movel	MEM_PREDEC(s_ptr),R(d1)
Packit Service 82fcde
	movel	R(d1),R(d3)
Packit Service 82fcde
	lsrl	R(d5),R(d3)
Packit Service 82fcde
	orl	R(d3),R(d2)
Packit Service 82fcde
	movel	R(d2),MEM_PREDEC(res_ptr)
Packit Service 82fcde
	lsll	R(cnt),R(d1)
Packit Service 82fcde
Packit Service 82fcde
	dbf	R(s_size),L(Loop)
Packit Service 82fcde
	subl	#0x10000,R(s_size)
Packit Service 82fcde
	bcc	L(Loop)
Packit Service 82fcde
Packit Service 82fcde
L(Lend:)
Packit Service 82fcde
	movel	R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */
Packit Service 82fcde
Packit Service 82fcde
/* Restore used registers from stack frame.  */
Packit Service 82fcde
	moveml	MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
Packit Service 82fcde
	cfi_remember_state
Packit Service 82fcde
	cfi_adjust_cfa_offset (-6*4)
Packit Service 82fcde
	cfi_restore (R(d2))
Packit Service 82fcde
	cfi_restore (R(d3))
Packit Service 82fcde
	cfi_restore (R(d4))
Packit Service 82fcde
	cfi_restore (R(d5))
Packit Service 82fcde
	cfi_restore (R(d6))
Packit Service 82fcde
	cfi_restore (R(a2))
Packit Service 82fcde
	rts
Packit Service 82fcde
Packit Service 82fcde
/* We loop from least significant end of the arrays, which is only
Packit Service 82fcde
   permissible if the source and destination don't overlap, since the
Packit Service 82fcde
   function is documented to work for overlapping source and destination.  */
Packit Service 82fcde
Packit Service 82fcde
	cfi_restore_state
Packit Service 82fcde
L(Lspecial:)
Packit Service 82fcde
	clrl	R(d0)			/* initialize carry */
Packit Service 82fcde
	eorw	#1,R(s_size)
Packit Service 82fcde
	lsrl	#1,R(s_size)
Packit Service 82fcde
	bcc	L(LL1)
Packit Service 82fcde
	subql	#1,R(s_size)
Packit Service 82fcde
Packit Service 82fcde
L(LLoop:)
Packit Service 82fcde
	movel	MEM_POSTINC(s_ptr),R(d2)
Packit Service 82fcde
	addxl	R(d2),R(d2)
Packit Service 82fcde
	movel	R(d2),MEM_POSTINC(res_ptr)
Packit Service 82fcde
L(LL1:)
Packit Service 82fcde
	movel	MEM_POSTINC(s_ptr),R(d2)
Packit Service 82fcde
	addxl	R(d2),R(d2)
Packit Service 82fcde
	movel	R(d2),MEM_POSTINC(res_ptr)
Packit Service 82fcde
Packit Service 82fcde
	dbf	R(s_size),L(LLoop)
Packit Service 82fcde
	addxl	R(d0),R(d0)		/* save cy in lsb */
Packit Service 82fcde
	subl	#0x10000,R(s_size)
Packit Service 82fcde
	bcs	L(LLend)
Packit Service 82fcde
	lsrl	#1,R(d0)		/* restore cy */
Packit Service 82fcde
	bra	L(LLoop)
Packit Service 82fcde
Packit Service 82fcde
L(LLend:)
Packit Service 82fcde
/* Restore used registers from stack frame.  */
Packit Service 82fcde
	moveml	MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
Packit Service 82fcde
	cfi_adjust_cfa_offset (-6*4)
Packit Service 82fcde
	cfi_restore (R(d2))
Packit Service 82fcde
	cfi_restore (R(d3))
Packit Service 82fcde
	cfi_restore (R(d4))
Packit Service 82fcde
	cfi_restore (R(d5))
Packit Service 82fcde
	cfi_restore (R(d6))
Packit Service 82fcde
	cfi_restore (R(a2))
Packit Service 82fcde
	rts
Packit Service 82fcde
END(__mpn_lshift)