bf3fe05dfb
This needs some more testing before it's on by default. If the card is otherwise functioning, these messages may be confusing to the user. If the card is not functioning, the driver can be reloaded with debug to check for this condition. Signed-off-by: Shaun Ruffell <sruffell@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9205 a0bf4364-ded3-4de4-8d8a-66a801d63aff
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
|