/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
*
* NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
* TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
* SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
* ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
* INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
* EXPOSE YOU TO LIABILITY.
***************************************************************************
*
* giantPorti486.s - i486-specific assembly routines.
*
* Revision History
* ----------------
* 17 Apr 1998 Doug Mitchell at Apple
* Created.
*/
#if defined (i386) || defined(__i386__)
.text
/*
* Multiply a vector a giantDigits, candVector, by a single giantDigit,
* plierDigit, adding results in prodVector.
*
* void VectorMultiply(
* giantDigit plierDigit,
* giantDigit *candVector,
* unsigned candLength,
* giantDigit *prodVector)
*/
.align 2,0x90
.globl _vectorMult_x86
/*
* Stack locations, relative to adjusted bp.
*/
#define LOCAL_SPACE 0x4
#define ARG_START (LOCAL_SPACE + 8) /* rtn ptr plus bp */
#define ARG_PLIER_DIGIT (ARG_START + 0)
#define ARG_CAND_VECTOR (ARG_START + 4) /* cached in ecx */
#define ARG_CAND_LENGTH (ARG_START + 8)
#define ARG_PROD_VECTOR (ARG_START + 12) /* cached in esi */
#define LOCAL_START (0)
#define LOC_CAND_DEX (LOCAL_START + 0) /* index into candVector */
/*
* ebx : lastCarry
* esi : prodVector
* ecx : candVector
*/
_vectorMult_x86:
pushl %ebp
subl $LOCAL_SPACE,%esp
movl %esp,%ebp
pushl %edi
pushl %esi
pushl %ebx
/* esp not used again 'til we pop these off stack */
/* prodVector = %esi */
movl ARG_PROD_VECTOR(%ebp),%esi
/* lastCarry = 0 */
/* 0 --> candDex in 0xf0(%ebp) */
xorl %ebx,%ebx
/* candVector --> %ecx */
movl ARG_CAND_VECTOR(%ebp),%ecx
/* for(candDex=0
/* make sure candLenth > 0 to start...*/
cmpl %ebx,ARG_CAND_LENGTH(%ebp)
jbe _loopEnd
_loopTop:
/* branch back to top of for loop */
/* *candVector--> %eax */
movl (%ecx),%eax
/* candVector++ */
addl $0x04,%ecx
/* plierDigit --> %edx */
movl ARG_PLIER_DIGIT(%ebp),%edx
/* eax = *candVector
* edx = plierDigit
* edx:eax := (plierDigit * *candVector) */
mull %edx
/* from here to end of loop:
prodLo : eax
prodHi : edx */
/* prodLo += *prodVector */
addl (%esi),%eax
/* add carry to hi digit */
adc $0,%edx
/* prodLo += lastCarry */
addl %ebx,%eax
/* add carry to hi digit */
adc $0,%edx
/* *(prodVector++) = prodLo addl $0x04,%esi
/* lastCarry = prodHi */
movl %edx, %ebx
/* candDex++ */
incl LOC_CAND_DEX(%ebp)
/* top of loop if candDex < candLength */
movl ARG_CAND_LENGTH(%ebp),%eax
cmpl %eax,LOC_CAND_DEX(%ebp)
jb _loopTop
_loopEnd:
/* out of for loop */
/* *prodVector += lastCarry addl %ebx,(%esi)
/* return carry from last addition */
xorl %eax,%eax
adc $0,%eax
#else
/* return lastCarry */
movl %ebx,%eax
#endif
popl %ebx
popl %esi
popl %edi
addl $LOCAL_SPACE,%esp
popl %ebp
ret
#endif /* i386 */