629 lines
17 KiB
C
629 lines
17 KiB
C
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
|
||
|
File: octapi_largmath.h
|
||
|
|
||
|
Copyright (c) 2001-2007 Octasic Inc.
|
||
|
|
||
|
Description:
|
||
|
|
||
|
Library used to perform arithmetic on integer values of an integer multiple
|
||
|
of 32-bits.
|
||
|
|
||
|
This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is
|
||
|
free software; you can redistribute it and/or modify it under the terms of
|
||
|
the GNU General Public License as published by the Free Software Foundation;
|
||
|
either version 2 of the License, or (at your option) any later version.
|
||
|
|
||
|
The OCT6100 GPL API is distributed in the hope that it will be useful, but
|
||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||
|
for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with the OCT6100 GPL API; if not, write to the Free Software
|
||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
|
||
|
$Octasic_Release: OCT612xAPI-01.00-PR49 $
|
||
|
|
||
|
$Octasic_Revision: 10 $
|
||
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#include "apilib/octapi_largmath.h"
|
||
|
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
| API UTILITIES
|
||
|
|
|
||
|
| Function: OctApiLmAdd.
|
||
|
|
|
||
|
| Description: This function adds 2 numbers, a and b. Number a is
|
||
|
| (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The
|
||
|
| result is (zlen + 1) * 32 bits long. It the function succeeds it returns
|
||
|
| GENERIC_OK, else GENERIC_ERROR.
|
||
|
|
|
||
|
| -----------------------------------------------------------------------
|
||
|
| | Variable | Type | Description
|
||
|
| -----------------------------------------------------------------------
|
||
|
| *a UINT32 The array containing the first number.
|
||
|
| alen USHORT The length of array a, minus 1 (0 - 99).
|
||
|
| *b UINT32 The array containing the second number.
|
||
|
| blen USHORT The length of array b, minus 1 (0 - 99).
|
||
|
| *z UINT32 The array containing the resulting number.
|
||
|
| zlen USHORT The length of array z, minus 1 (0 - 99).
|
||
|
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_OctApiLmAdd
|
||
|
UINT32 OctApiLmAdd(UINT32 * a,USHORT alen,UINT32 * b,USHORT blen,UINT32 * z, USHORT zlen)
|
||
|
{
|
||
|
USHORT i;
|
||
|
UINT32 temp;
|
||
|
UINT32 carry=0;
|
||
|
UINT32 aprim;
|
||
|
UINT32 bprim;
|
||
|
|
||
|
/* Check for array lengths.*/
|
||
|
if (alen > zlen || blen > zlen) return(OCTAPI_LM_ARRAY_SIZE_MISMATCH);
|
||
|
|
||
|
for(i=0;i<=zlen;i++)
|
||
|
{
|
||
|
if (i <= alen) aprim = *(a+i); else aprim = 0;
|
||
|
if (i <= blen) bprim = *(b+i); else bprim = 0;
|
||
|
temp = aprim + bprim + carry;
|
||
|
|
||
|
/* Calculate carry for next time.*/
|
||
|
if (carry == 0)
|
||
|
if (temp < aprim) carry = 1; else carry = 0;
|
||
|
else
|
||
|
if (temp <= aprim) carry = 1; else carry = 0;
|
||
|
|
||
|
/* Write new value.*/
|
||
|
*(z+i) = temp;
|
||
|
}
|
||
|
|
||
|
/* Check for overflow.*/
|
||
|
if (carry == 1) return(OCTAPI_LM_OVERFLOW);
|
||
|
|
||
|
/* All is well.*/
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
| API UTILITIES
|
||
|
|
|
||
|
| Function: OctApiLmSubtract.
|
||
|
|
|
||
|
| Description: This function subtracts 2 numbers, a and b. Number a is
|
||
|
| (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The result
|
||
|
| is (zlen + 1) * 32 bits long. It the function succeeds it returns
|
||
|
| GENERIC_OK, else GENERIC_ERROR.
|
||
|
|
|
||
|
| -----------------------------------------------------------------------
|
||
|
| | Variable | Type | Description
|
||
|
| -----------------------------------------------------------------------
|
||
|
| *a UINT32 The array containing the first number.
|
||
|
| alen USHORT The length of array a, minus 1 (0 - 99).
|
||
|
| *bneg UINT32 The array containing the second number.
|
||
|
| blen USHORT The length of array b, minus 1 (0 - 99).
|
||
|
| *z UINT32 The array containing the resulting number.
|
||
|
| zlen USHORT The length of array z, minus 1 (0 - 99).
|
||
|
| *neg USHORT Indicates if the result is negative
|
||
|
| (TRUE/FALSE).
|
||
|
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_OctApiLmSubtract
|
||
|
UINT32 OctApiLmSubtract(UINT32 * a,USHORT alen,UINT32 * bneg,USHORT blen,UINT32 * z,USHORT zlen,USHORT * neg)
|
||
|
{
|
||
|
USHORT i;
|
||
|
UINT32 temp;
|
||
|
UINT32 carry=1;
|
||
|
UINT32 aprim;
|
||
|
UINT32 bprim;
|
||
|
|
||
|
/* Check for array lengths.*/
|
||
|
if (alen > zlen || blen > zlen) return(OCTAPI_LM_ARRAY_SIZE_MISMATCH);
|
||
|
|
||
|
for(i=0;i<=zlen;i++)
|
||
|
{
|
||
|
if (i <= alen) aprim = *(a+i); else aprim = 0;
|
||
|
if (i <= blen) bprim = ~(*(bneg+i)); else bprim = 0xFFFFFFFF;
|
||
|
temp = aprim + bprim + carry;
|
||
|
|
||
|
/* Calculate carry for next time.*/
|
||
|
if (carry == 0)
|
||
|
if (temp < aprim) carry = 1; else carry = 0;
|
||
|
else
|
||
|
if (temp <= aprim) carry = 1; else carry = 0;
|
||
|
|
||
|
/* Write new value.*/
|
||
|
*(z+i) = temp;
|
||
|
}
|
||
|
|
||
|
/* Check for overflow, which means negative number!*/
|
||
|
if (carry == 0)
|
||
|
{
|
||
|
/* Number is not of right neg. Invert and add one to correct neg.*/
|
||
|
for(i=0;i<=zlen;i++)
|
||
|
*(z+i) = ~(*(z+i));
|
||
|
|
||
|
temp = 1;
|
||
|
OctApiLmAdd(&temp,0,z,zlen,z,zlen);
|
||
|
|
||
|
*neg = TRUE;
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
|
||
|
/* Result is positive.*/
|
||
|
*neg = FALSE;
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
| API UTILITIES
|
||
|
|
|
||
|
| Function: OctApiLmCompare.
|
||
|
|
|
||
|
| Description: This function compares two numbers (arrays) of equal lengths.
|
||
|
| Number a is (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The result
|
||
|
|
|
||
|
| -----------------------------------------------------------------------
|
||
|
| | Variable | Type | Description
|
||
|
| -----------------------------------------------------------------------
|
||
|
| *a UINT32 The array containing the first number.
|
||
|
| alen USHORT The length of array a, minus 1 (0 - 99).
|
||
|
| *b UINT32 The array containing the second number.
|
||
|
| blen USHORT The length of array b, minus 1 (0 - 99).
|
||
|
| *neg USHORT Result of compare.
|
||
|
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_OctApiLmCompare
|
||
|
UINT32 OctApiLmCompare(UINT32 * a,USHORT alen,UINT32 * bneg,USHORT blen,USHORT * neg)
|
||
|
{
|
||
|
USHORT i;
|
||
|
UINT32 temp;
|
||
|
UINT32 carry=1;
|
||
|
UINT32 aprim;
|
||
|
UINT32 bprim;
|
||
|
UINT32 zlen;
|
||
|
|
||
|
/* Set zlen to alen or blen (which ever is longer)*/
|
||
|
if (alen < blen)
|
||
|
zlen = blen;
|
||
|
else
|
||
|
zlen = alen;
|
||
|
|
||
|
for(i=0;i<=zlen;i++)
|
||
|
{
|
||
|
if (i <= alen) aprim = *(a+i); else aprim = 0;
|
||
|
if (i <= blen) bprim = ~(*(bneg+i)); else bprim = 0xFFFFFFFF;
|
||
|
temp = aprim + bprim + carry;
|
||
|
|
||
|
/* Calculate carry for next time.*/
|
||
|
if (carry == 0)
|
||
|
if (temp < aprim) carry = 1; else carry = 0;
|
||
|
else
|
||
|
if (temp <= aprim) carry = 1; else carry = 0;
|
||
|
}
|
||
|
|
||
|
/* Check for overflow, which means negative number!*/
|
||
|
if (carry == 0)
|
||
|
{
|
||
|
*neg = TRUE;
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
|
||
|
/* Result is positive.*/
|
||
|
*neg = FALSE;
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
| API UTILITIES
|
||
|
|
|
||
|
| Function: OctApiLmSubtract.
|
||
|
|
|
||
|
| Description: This function multiplies 2 numbers, a and b. Number a and
|
||
|
| b are both (ablen + 1) * 32 bits long. The result is twice as
|
||
|
| long. If the functions succeeds if returns GENERIC_OK,
|
||
|
| else GENERIC_ERROR.
|
||
|
|
|
||
|
| -----------------------------------------------------------------------
|
||
|
| | Variable | Type | Description
|
||
|
| -----------------------------------------------------------------------
|
||
|
| *a UINT32 The array containing the first number.
|
||
|
| *b UINT32 The array containing the second number.
|
||
|
| ablen USHORT The length of arrays a and b, minus 1 (0 - 99).
|
||
|
| *z UINT32 The array containing the resulting number.
|
||
|
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_OctApiLmMultiply
|
||
|
UINT32 OctApiLmMultiply(UINT32 * a,UINT32 * b,USHORT ablen,UINT32 * z)
|
||
|
{
|
||
|
USHORT i,j,k;
|
||
|
USHORT nos;
|
||
|
UINT32 lownum;
|
||
|
UINT32 highnum;
|
||
|
USHORT longnumi;
|
||
|
USHORT longnumj;
|
||
|
USHORT indentw,indentl;
|
||
|
|
||
|
|
||
|
/* Caculate number of shorts in a and b.*/
|
||
|
nos = (USHORT)((ablen+1) * 2);
|
||
|
|
||
|
/* Clear answer word.*/
|
||
|
for(i=0;i<nos;i++)
|
||
|
*(z+i) = 0;
|
||
|
|
||
|
{
|
||
|
USHORT optimizea, optimizeb;
|
||
|
USHORT l;
|
||
|
optimizea = TRUE;
|
||
|
optimizeb = TRUE;
|
||
|
for(l = 1; l < ablen+1; l++)
|
||
|
{
|
||
|
if(*(a+l) != 0)
|
||
|
optimizea = FALSE;
|
||
|
if(*(b+l) != 0)
|
||
|
optimizeb = FALSE;
|
||
|
}
|
||
|
if(*a > OCTAPI_LM_MAX_OPTIMIZE_MUL)
|
||
|
optimizea = FALSE;
|
||
|
if(*b > OCTAPI_LM_MAX_OPTIMIZE_MUL)
|
||
|
optimizeb = FALSE;
|
||
|
|
||
|
if(optimizea == TRUE)
|
||
|
{
|
||
|
for(l = 0; l < *a; l++)
|
||
|
OctApiLmAdd(z, (USHORT)(nos-1), b, ablen, z, (USHORT)(nos-1));
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
|
||
|
if(optimizeb == TRUE)
|
||
|
{
|
||
|
for(l = 0; l < *b; l++)
|
||
|
OctApiLmAdd(z, (USHORT)(nos-1), a, ablen, z, (USHORT)(nos-1));
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for(i=0;i<nos;i++)
|
||
|
{
|
||
|
longnumi = (USHORT)( i/2 );
|
||
|
/* One iteration per short in a.*/
|
||
|
if ((i%2) == 0)
|
||
|
lownum = *(a+longnumi) & 0xFFFF; /* Even word. Lower part of long.*/
|
||
|
else
|
||
|
lownum = *(a+longnumi)>>16; /* Odd word. Upper part of long.*/
|
||
|
|
||
|
for(j=0;j<nos;j++)
|
||
|
{
|
||
|
UINT32 product;
|
||
|
|
||
|
longnumj = (USHORT)( j/2 );
|
||
|
/* One iteration per short in a.*/
|
||
|
if ((j%2) == 0)
|
||
|
highnum = *(b+longnumj) & 0xFFFF; /* Even word. Lower part of long.*/
|
||
|
else
|
||
|
highnum = *(b+longnumj)>>16; /* Odd word. Upper part of long.*/
|
||
|
|
||
|
/* Find the word indent of the answer. 0 = no indent. 1 = one word indent.*/
|
||
|
indentw = (USHORT)( j+i );
|
||
|
indentl = (USHORT)( indentw / 2 );
|
||
|
|
||
|
/* Multiply both numbers.*/
|
||
|
product = highnum * lownum;
|
||
|
|
||
|
/* After multiplying both numbers, add result to end result.*/
|
||
|
if ((indentw % 2) == 0) /* Even word boundary, addition in one shot!*/
|
||
|
{
|
||
|
UINT32 carry=0;
|
||
|
UINT32 temp;
|
||
|
UINT32 addme;
|
||
|
|
||
|
for(k=indentl;k<nos;k++)
|
||
|
{
|
||
|
if (k==indentl) addme = product; else addme = 0;
|
||
|
|
||
|
temp = *(z+k) + addme + carry;
|
||
|
|
||
|
/* Calculate carry for next time.*/
|
||
|
if (carry == 0)
|
||
|
if (temp < addme) carry = 1; else carry = 0;
|
||
|
else
|
||
|
if (temp <= addme) carry = 1; else carry = 0;
|
||
|
|
||
|
/* Set value.*/
|
||
|
*(z+k) = temp;
|
||
|
}
|
||
|
|
||
|
/* Carry should always be 0.*/
|
||
|
if (carry == 1) return(GENERIC_ERROR);
|
||
|
}
|
||
|
else /* Odd word boundary, addition in two shots.*/
|
||
|
{
|
||
|
UINT32 carry=0;
|
||
|
UINT32 temp;
|
||
|
UINT32 addme;
|
||
|
|
||
|
for(k=indentl;k<nos;k++)
|
||
|
{
|
||
|
if (k==indentl) addme = product<<16;
|
||
|
else if (k==(indentl+1)) addme = product>>16;
|
||
|
else addme = 0;
|
||
|
|
||
|
temp = *(z+k) + addme + carry;
|
||
|
|
||
|
/* Calculate carry for next time.*/
|
||
|
if (carry == 0)
|
||
|
if (temp < addme) carry = 1; else carry = 0;
|
||
|
else
|
||
|
if (temp <= addme) carry = 1; else carry = 0;
|
||
|
|
||
|
/* Set value.*/
|
||
|
*(z+k) = temp;
|
||
|
}
|
||
|
|
||
|
/* Carry should always be 0.*/
|
||
|
if (carry == 1) return(GENERIC_ERROR);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
| API UTILITIES
|
||
|
|
|
||
|
| Function: OctApiLmDivide.
|
||
|
|
|
||
|
| Description: This function divides the number n by the number d. The
|
||
|
| quotient is placed in q and the remainder in r. The arrays
|
||
|
| n, d, q and r are all of the same length, namely (ndqrlen + 1).
|
||
|
| If the functions succeeds if returns GENERIC_OK, else
|
||
|
| GENERIC_ERROR.
|
||
|
|
|
||
|
| -----------------------------------------------------------------------
|
||
|
| | Variable | Type | Description
|
||
|
| -----------------------------------------------------------------------
|
||
|
| *a UINT32 The array containing the first number.
|
||
|
| *b UINT32 The array containing the second number.
|
||
|
| ablen USHORT The length of arrays a and b, minus 1 (0 - 99).
|
||
|
| *z UINT32 The array containing the resulting number.
|
||
|
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_OctApiLmDivide
|
||
|
UINT32 OctApiLmDivide(UINT32 * n,UINT32 * d,UINT32 * q,UINT32 * r,USHORT ndqrlen)
|
||
|
{
|
||
|
/* Proceedure for division:*/
|
||
|
/* r = n*/
|
||
|
/* q = 0*/
|
||
|
/* shift = initial_denominator_shift (for upper '1's to be in same bit position).*/
|
||
|
/* d <<= shift;*/
|
||
|
/* Start loop:*/
|
||
|
/* compare r and d*/
|
||
|
/* if r > d then*/
|
||
|
/* r -= d;*/
|
||
|
/* write a '1' to bit "shift" of array q.*/
|
||
|
/* end if;*/
|
||
|
/* if shift == 0 then*/
|
||
|
/* return;*/
|
||
|
/* else*/
|
||
|
/* shift--;*/
|
||
|
/* d>>=1;*/
|
||
|
/* goto "Start loop:"*/
|
||
|
/* end if;*/
|
||
|
|
||
|
UINT32 i;
|
||
|
UINT32 result;
|
||
|
USHORT shift,n_msb,d_msb;
|
||
|
USHORT neg;
|
||
|
USHORT ConditionFlag = TRUE;
|
||
|
|
||
|
/* r = n*/
|
||
|
for(i=0;i<=ndqrlen;i++)
|
||
|
*(r+i) = *(n+i);
|
||
|
|
||
|
/* q = 0*/
|
||
|
for(i=0;i<=ndqrlen;i++)
|
||
|
*(q+i) = 0;
|
||
|
|
||
|
/* shift = initial_denominator_shift (for upper '1's to be in same bit position).*/
|
||
|
result = OctApiLmGetMsb(d,ndqrlen,&d_msb);
|
||
|
if (result != GENERIC_OK) return(result);
|
||
|
|
||
|
result = OctApiLmGetMsb(n,ndqrlen,&n_msb);
|
||
|
if (result != GENERIC_OK) return(result);
|
||
|
|
||
|
if (d_msb == 0xFFFF) /* Division by 0.*/
|
||
|
return(OCTAPI_LM_DIVISION_BY_ZERO);
|
||
|
|
||
|
if (n_msb == 0xFFFF) /* 0/n, returns 0 R 0.*/
|
||
|
return(GENERIC_OK);
|
||
|
|
||
|
if (n_msb < d_msb) /* x/y, where x is smaller than y, returns 0 R x.*/
|
||
|
return(GENERIC_OK);
|
||
|
|
||
|
shift = (USHORT)( n_msb - d_msb );
|
||
|
|
||
|
/* Shift d to match n highest bit position.*/
|
||
|
result = OctApiLmShiftn(d,ndqrlen,TRUE,shift);
|
||
|
if (result != GENERIC_OK) return(result);
|
||
|
|
||
|
/* Start loop:*/
|
||
|
while( ConditionFlag == TRUE )
|
||
|
{
|
||
|
/* compare r and d*/
|
||
|
result = OctApiLmCompare(r,ndqrlen,d,ndqrlen,&neg);
|
||
|
if (result != GENERIC_OK) return(result);
|
||
|
|
||
|
if (neg == FALSE) /* Subtraction can be done(do it).*/
|
||
|
{
|
||
|
/* r -= d;*/
|
||
|
result = OctApiLmSubtract(r,ndqrlen,d,ndqrlen,r,ndqrlen,&neg);
|
||
|
if (result != GENERIC_OK) return(result);
|
||
|
|
||
|
/* write a '1' to bit "shift" of array q.*/
|
||
|
*(q+(shift/32)) |= (UINT32)0x1 << (shift%32);
|
||
|
}
|
||
|
|
||
|
/* if shift == 0 then*/
|
||
|
/* return;*/
|
||
|
if (shift == 0) return(GENERIC_OK);
|
||
|
|
||
|
/* shift--;*/
|
||
|
/* d>>=1;*/
|
||
|
/* goto "Start loop:"*/
|
||
|
shift--;
|
||
|
OctApiLmShiftRight1(d,ndqrlen);
|
||
|
}
|
||
|
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
| API UTILITIES
|
||
|
|
|
||
|
| Function: octapi_lm_shifright1.
|
||
|
|
|
||
|
| Description: The function is for internal use only.
|
||
|
|
|
||
|
| -----------------------------------------------------------------------
|
||
|
| | Variable | Type | Description
|
||
|
| -----------------------------------------------------------------------
|
||
|
| N/A.
|
||
|
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_OctApiLmShiftRight1
|
||
|
UINT32 OctApiLmShiftRight1(UINT32 * a,USHORT alen)
|
||
|
{
|
||
|
UINT32 i;
|
||
|
|
||
|
/* Start with lower long and move up by one long each time,*/
|
||
|
/* shifting each long to the right by one bit. The upper bit*/
|
||
|
/* of the next long will have to be concatenated each time a*/
|
||
|
/* loop is executed. For the last long, leave the highest bit*/
|
||
|
/* intact.*/
|
||
|
for(i=0;i<alen;i++)
|
||
|
{
|
||
|
*(a+i)>>=1; /* Shift long by one to the right.*/
|
||
|
*(a+i)|=*(a+i+1)<<31;
|
||
|
}
|
||
|
*(a+alen)>>=1; /* Shift last long, leaving it's highest bit at 0.*/
|
||
|
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
| API UTILITIES
|
||
|
|
|
||
|
| Function: OctApiLmShiftn.
|
||
|
|
|
||
|
| Description: The function is for internal use only.
|
||
|
|
|
||
|
| -----------------------------------------------------------------------
|
||
|
| | Variable | Type | Description
|
||
|
| -----------------------------------------------------------------------
|
||
|
| N/A.
|
||
|
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_OctApiLmShiftn
|
||
|
UINT32 OctApiLmShiftn(UINT32 * a,USHORT alen,USHORT shiftleft,USHORT shiftn)
|
||
|
{
|
||
|
UINT32 i;
|
||
|
USHORT long_offset;
|
||
|
USHORT bit_offset;
|
||
|
|
||
|
long_offset = (USHORT)( shiftn / 32 );
|
||
|
bit_offset = (USHORT)( shiftn % 32 );
|
||
|
|
||
|
if (shiftleft == TRUE) /* Shift left.*/
|
||
|
{
|
||
|
for(i=alen;i<=alen;i--)
|
||
|
{
|
||
|
/* Fill upper bits of long.*/
|
||
|
if (i >= long_offset)
|
||
|
*(a+i) = *(a+i-long_offset) << bit_offset;
|
||
|
else
|
||
|
*(a+i) = 0;
|
||
|
|
||
|
/* Fill lower bits of long.*/
|
||
|
if (i > long_offset && bit_offset != 0)
|
||
|
*(a+i) |= *(a+i-long_offset-1) >> (32-bit_offset);
|
||
|
}
|
||
|
}
|
||
|
else /* Shift right.*/
|
||
|
{
|
||
|
for(i=0;i<=alen;i++)
|
||
|
{
|
||
|
/* Fill lower bits of long.*/
|
||
|
if ((alen-i) >= long_offset)
|
||
|
*(a+i) = *(a+i+long_offset) >> bit_offset;
|
||
|
else
|
||
|
*(a+i) = 0;
|
||
|
|
||
|
/* Fill upper bits of long.*/
|
||
|
if ((alen-i) > long_offset && bit_offset != 0)
|
||
|
*(a+i) |= *(a+i+long_offset+1) << (32-bit_offset);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
| API UTILITIES
|
||
|
|
|
||
|
| Function: OctApiLmGetMsb.
|
||
|
|
|
||
|
| Description: The function is for internal use only.
|
||
|
|
|
||
|
| -----------------------------------------------------------------------
|
||
|
| | Variable | Type | Description
|
||
|
| -----------------------------------------------------------------------
|
||
|
| N/A.
|
||
|
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_OctApiLmGetMsb
|
||
|
UINT32 OctApiLmGetMsb(UINT32 * a,USHORT alen,USHORT * msb_pos)
|
||
|
{
|
||
|
UINT32 i,j;
|
||
|
UINT32 x;
|
||
|
|
||
|
for(i=alen;i<=alen;i--)
|
||
|
{
|
||
|
if (*(a+i) == 0) continue;
|
||
|
|
||
|
x = *(a+i);
|
||
|
for(j=31;j<=31;j--)
|
||
|
{
|
||
|
/* Test for bit being '1'.*/
|
||
|
if ((x & 0x80000000) != 0)
|
||
|
{
|
||
|
*msb_pos=(USHORT)(j+(32*i));
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
|
||
|
/* Shift bit one bit position, and try again.*/
|
||
|
x<<=1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* MSB not found.*/
|
||
|
*msb_pos = 0xFFFF;
|
||
|
|
||
|
return(GENERIC_OK);
|
||
|
}
|
||
|
#endif
|