Blame mpi/i586/mpih-rshift.S

Packit 0680ba
/* i80586   rshift
Packit 0680ba
 *
Packit 0680ba
 *      Copyright (C) 1992, 1994, 1998,
Packit 0680ba
 *                    2001, 2002 Free Software Foundation, Inc.
Packit 0680ba
 *
Packit 0680ba
 * This file is part of Libgcrypt.
Packit 0680ba
 *
Packit 0680ba
 * Libgcrypt is free software; you can redistribute it and/or modify
Packit 0680ba
 * it under the terms of the GNU Lesser General Public License as
Packit 0680ba
 * published by the Free Software Foundation; either version 2.1 of
Packit 0680ba
 * the License, or (at your option) any later version.
Packit 0680ba
 *
Packit 0680ba
 * Libgcrypt is distributed in the hope that it will be useful,
Packit 0680ba
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 0680ba
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 0680ba
 * GNU Lesser General Public License for more details.
Packit 0680ba
 *
Packit 0680ba
 * You should have received a copy of the GNU Lesser General Public
Packit 0680ba
 * License along with this program; if not, write to the Free Software
Packit 0680ba
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Packit 0680ba
 *
Packit 0680ba
 * Note: This code is heavily based on the GNU MP Library.
Packit 0680ba
 *	 Actually it's the same code with only minor changes in the
Packit 0680ba
 *	 way the data is stored; this is to support the abstraction
Packit 0680ba
 *	 of an optional secure memory allocation which may be used
Packit 0680ba
 *	 to avoid revealing of sensitive data due to paging etc.
Packit 0680ba
 */
Packit 0680ba
Packit 0680ba
Packit 0680ba
#include "sysdep.h"
Packit 0680ba
#include "asm-syntax.h"
Packit 0680ba
Packit 0680ba
Packit 0680ba
Packit 0680ba
/*******************
Packit 0680ba
 * mpi_limb_t
Packit 0680ba
 * _gcry_mpih_rshift( mpi_ptr_t wp,	(sp + 4)
Packit 0680ba
 *		   mpi_ptr_t up,	(sp + 8)
Packit 0680ba
 *		   mpi_size_t usize,	(sp + 12)
Packit 0680ba
 *		   unsigned cnt)	(sp + 16)
Packit 0680ba
 */
Packit 0680ba
Packit 0680ba
.text
Packit 0680ba
	ALIGN (3)
Packit 0680ba
	.globl C_SYMBOL_NAME(_gcry_mpih_rshift)
Packit 0680ba
C_SYMBOL_NAME(_gcry_mpih_rshift:)
Packit 0680ba
	pushl	%edi
Packit 0680ba
	pushl	%esi
Packit 0680ba
	pushl	%ebx
Packit 0680ba
	pushl	%ebp
Packit 0680ba
Packit 0680ba
	movl	20(%esp),%edi		/* res_ptr */
Packit 0680ba
	movl	24(%esp),%esi		/* s_ptr */
Packit 0680ba
	movl	28(%esp),%ebp		/* size */
Packit 0680ba
	movl	32(%esp),%ecx		/* cnt */
Packit 0680ba
Packit 0680ba
/* We can use faster code for shift-by-1 under certain conditions.  */
Packit 0680ba
	cmp	$1,%ecx
Packit 0680ba
	jne	Rnormal
Packit 0680ba
	leal	4(%edi),%eax
Packit 0680ba
	cmpl	%esi,%eax
Packit 0680ba
	jnc	Rspecial		/* jump if res_ptr + 1 >= s_ptr */
Packit 0680ba
	leal	(%edi,%ebp,4),%eax
Packit 0680ba
	cmpl	%eax,%esi
Packit 0680ba
	jnc	Rspecial		/* jump if s_ptr >= res_ptr + size */
Packit 0680ba
Packit 0680ba
Rnormal:
Packit 0680ba
	movl	(%esi),%edx
Packit 0680ba
	addl	$4,%esi
Packit 0680ba
	xorl	%eax,%eax
Packit 0680ba
	shrdl	%cl,%edx,%eax		/* compute carry limb */
Packit 0680ba
	pushl	%eax			/* push carry limb onto stack */
Packit 0680ba
Packit 0680ba
	decl	%ebp
Packit 0680ba
	pushl	%ebp
Packit 0680ba
	shrl	$3,%ebp
Packit 0680ba
	jz	Rend
Packit 0680ba
Packit 0680ba
	movl	(%edi),%eax		/* fetch destination cache line */
Packit 0680ba
Packit 0680ba
	ALIGN	(2)
Packit 0680ba
Roop:	movl	28(%edi),%eax		/* fetch destination cache line */
Packit 0680ba
	movl	%edx,%ebx
Packit 0680ba
Packit 0680ba
	movl	(%esi),%eax
Packit 0680ba
	movl	4(%esi),%edx
Packit 0680ba
	shrdl	%cl,%eax,%ebx
Packit 0680ba
	shrdl	%cl,%edx,%eax
Packit 0680ba
	movl	%ebx,(%edi)
Packit 0680ba
	movl	%eax,4(%edi)
Packit 0680ba
Packit 0680ba
	movl	8(%esi),%ebx
Packit 0680ba
	movl	12(%esi),%eax
Packit 0680ba
	shrdl	%cl,%ebx,%edx
Packit 0680ba
	shrdl	%cl,%eax,%ebx
Packit 0680ba
	movl	%edx,8(%edi)
Packit 0680ba
	movl	%ebx,12(%edi)
Packit 0680ba
Packit 0680ba
	movl	16(%esi),%edx
Packit 0680ba
	movl	20(%esi),%ebx
Packit 0680ba
	shrdl	%cl,%edx,%eax
Packit 0680ba
	shrdl	%cl,%ebx,%edx
Packit 0680ba
	movl	%eax,16(%edi)
Packit 0680ba
	movl	%edx,20(%edi)
Packit 0680ba
Packit 0680ba
	movl	24(%esi),%eax
Packit 0680ba
	movl	28(%esi),%edx
Packit 0680ba
	shrdl	%cl,%eax,%ebx
Packit 0680ba
	shrdl	%cl,%edx,%eax
Packit 0680ba
	movl	%ebx,24(%edi)
Packit 0680ba
	movl	%eax,28(%edi)
Packit 0680ba
Packit 0680ba
	addl	$32,%esi
Packit 0680ba
	addl	$32,%edi
Packit 0680ba
	decl	%ebp
Packit 0680ba
	jnz	Roop
Packit 0680ba
Packit 0680ba
Rend:	popl	%ebp
Packit 0680ba
	andl	$7,%ebp
Packit 0680ba
	jz	Rend2
Packit 0680ba
Roop2:	movl	(%esi),%eax
Packit 0680ba
	shrdl	%cl,%eax,%edx		/* compute result limb */
Packit 0680ba
	movl	%edx,(%edi)
Packit 0680ba
	movl	%eax,%edx
Packit 0680ba
	addl	$4,%esi
Packit 0680ba
	addl	$4,%edi
Packit 0680ba
	decl	%ebp
Packit 0680ba
	jnz	Roop2
Packit 0680ba
Packit 0680ba
Rend2:	shrl	%cl,%edx		/* compute most significant limb */
Packit 0680ba
	movl	%edx,(%edi)		/* store it */
Packit 0680ba
Packit 0680ba
	popl	%eax			/* pop carry limb */
Packit 0680ba
Packit 0680ba
	popl	%ebp
Packit 0680ba
	popl	%ebx
Packit 0680ba
	popl	%esi
Packit 0680ba
	popl	%edi
Packit 0680ba
	ret
Packit 0680ba
Packit 0680ba
/* We loop from least significant end of the arrays, which is only
Packit 0680ba
   permissable if the source and destination don't overlap, since the
Packit 0680ba
   function is documented to work for overlapping source and destination.
Packit 0680ba
*/
Packit 0680ba
Packit 0680ba
Rspecial:
Packit 0680ba
	leal	-4(%edi,%ebp,4),%edi
Packit 0680ba
	leal	-4(%esi,%ebp,4),%esi
Packit 0680ba
Packit 0680ba
	movl	(%esi),%edx
Packit 0680ba
	subl	$4,%esi
Packit 0680ba
Packit 0680ba
	decl	%ebp
Packit 0680ba
	pushl	%ebp
Packit 0680ba
	shrl	$3,%ebp
Packit 0680ba
Packit 0680ba
	shrl	$1,%edx
Packit 0680ba
	incl	%ebp
Packit 0680ba
	decl	%ebp
Packit 0680ba
	jz	RLend
Packit 0680ba
Packit 0680ba
	movl	(%edi),%eax		/* fetch destination cache line */
Packit 0680ba
Packit 0680ba
	ALIGN	(2)
Packit 0680ba
RLoop:	movl	-28(%edi),%eax		/* fetch destination cache line */
Packit 0680ba
	movl	%edx,%ebx
Packit 0680ba
Packit 0680ba
	movl	(%esi),%eax
Packit 0680ba
	movl	-4(%esi),%edx
Packit 0680ba
	rcrl	$1,%eax
Packit 0680ba
	movl	%ebx,(%edi)
Packit 0680ba
	rcrl	$1,%edx
Packit 0680ba
	movl	%eax,-4(%edi)
Packit 0680ba
Packit 0680ba
	movl	-8(%esi),%ebx
Packit 0680ba
	movl	-12(%esi),%eax
Packit 0680ba
	rcrl	$1,%ebx
Packit 0680ba
	movl	%edx,-8(%edi)
Packit 0680ba
	rcrl	$1,%eax
Packit 0680ba
	movl	%ebx,-12(%edi)
Packit 0680ba
Packit 0680ba
	movl	-16(%esi),%edx
Packit 0680ba
	movl	-20(%esi),%ebx
Packit 0680ba
	rcrl	$1,%edx
Packit 0680ba
	movl	%eax,-16(%edi)
Packit 0680ba
	rcrl	$1,%ebx
Packit 0680ba
	movl	%edx,-20(%edi)
Packit 0680ba
Packit 0680ba
	movl	-24(%esi),%eax
Packit 0680ba
	movl	-28(%esi),%edx
Packit 0680ba
	rcrl	$1,%eax
Packit 0680ba
	movl	%ebx,-24(%edi)
Packit 0680ba
	rcrl	$1,%edx
Packit 0680ba
	movl	%eax,-28(%edi)
Packit 0680ba
Packit 0680ba
	leal	-32(%esi),%esi		/* use leal not to clobber carry */
Packit 0680ba
	leal	-32(%edi),%edi
Packit 0680ba
	decl	%ebp
Packit 0680ba
	jnz	RLoop
Packit 0680ba
Packit 0680ba
RLend:	popl	%ebp
Packit 0680ba
	sbbl	%eax,%eax		/* save carry in %eax */
Packit 0680ba
	andl	$7,%ebp
Packit 0680ba
	jz	RLend2
Packit 0680ba
	addl	%eax,%eax		/* restore carry from eax */
Packit 0680ba
RLoop2: movl	%edx,%ebx
Packit 0680ba
	movl	(%esi),%edx
Packit 0680ba
	rcrl	$1,%edx
Packit 0680ba
	movl	%ebx,(%edi)
Packit 0680ba
Packit 0680ba
	leal	-4(%esi),%esi		/* use leal not to clobber carry */
Packit 0680ba
	leal	-4(%edi),%edi
Packit 0680ba
	decl	%ebp
Packit 0680ba
	jnz	RLoop2
Packit 0680ba
Packit 0680ba
	jmp	RL1
Packit 0680ba
RLend2: addl	%eax,%eax		/* restore carry from eax */
Packit 0680ba
RL1:	movl	%edx,(%edi)		/* store last limb */
Packit 0680ba
Packit 0680ba
	movl	$0,%eax
Packit 0680ba
	rcrl	$1,%eax
Packit 0680ba
Packit 0680ba
	popl	%ebp
Packit 0680ba
	popl	%ebx
Packit 0680ba
	popl	%esi
Packit 0680ba
	popl	%edi
Packit 0680ba
	ret
Packit 0680ba