kernel/eka/nkern/nklib.cpp
changeset 201 43365a9b78a3
equal deleted inserted replaced
200:73ea206103e6 201:43365a9b78a3
       
     1 // Copyright (c) 2010-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\nkern\nklib.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <e32atomics.h>
       
    19 #include <nklib.h>
       
    20 
       
    21 #ifndef __SRATIO_MACHINE_CODED__
       
    22 void SRatio::Set(TUint32 aInt, TInt aDivisorExp)
       
    23 	{
       
    24 	iSpare1 = 0;
       
    25 	iSpare2 = 0;
       
    26 	iM = aInt;
       
    27 	if (iM)
       
    28 		{
       
    29 		TInt ms1 = __e32_find_ms1_32(iM);
       
    30 		TInt shift = 31 - ms1;
       
    31 		iM <<= shift;
       
    32 		iX = (TInt16)(-shift - aDivisorExp);
       
    33 		}
       
    34 	else
       
    35 		iX = 0;
       
    36 	}
       
    37 
       
    38 TInt SRatio::Reciprocal()
       
    39 	{
       
    40 	if (iM==0)
       
    41 		return KErrDivideByZero;
       
    42 	// Calculate 2^32/iM
       
    43 	TInt exp=0;
       
    44 	if (iM == 0x80000000u)
       
    45 		{
       
    46 		// ratio = 2^(31+iX) so reciprocal = 2^(-31-iX) = 2^(31 + (-62-iX))
       
    47 		exp = -62-iX;
       
    48 		}
       
    49 	else
       
    50 		{
       
    51 		// 2^32/iM = 1.xxx
       
    52 		TUint64 r64 = MAKE_TUINT64(0u-iM,0);
       
    53 		TUint32 q32 = (TUint32)(r64/TUint64(iM));	// next 32 bits of result
       
    54 		iM = 0x80000000u | (q32>>1);
       
    55 		exp = -63-iX;
       
    56 		if (q32 & 1)
       
    57 			{
       
    58 			if (++iM==0)
       
    59 				iM=0x80000000u, ++exp;
       
    60 			}
       
    61 		}
       
    62 	if (exp < -32768)
       
    63 		{
       
    64 		iM = 0;
       
    65 		iX = 0;
       
    66 		return KErrUnderflow;
       
    67 		}
       
    68 	if (exp > 32767)
       
    69 		{
       
    70 		iM = 0xffffffffu;
       
    71 		iX = 32767;
       
    72 		return KErrOverflow;
       
    73 		}
       
    74 	iX = (TInt16)exp;
       
    75 	return KErrNone;
       
    76 	}
       
    77 
       
    78 TInt SRatio::Mult(TUint32& aInt32)
       
    79 	{
       
    80 	TUint64 x = aInt32;
       
    81 	x *= TUint64(iM);
       
    82 	if (x==0)
       
    83 		{
       
    84 		aInt32 = 0;
       
    85 		return KErrNone;
       
    86 		}
       
    87 	TInt ms1 = __e32_find_ms1_64(x);
       
    88 	TInt ms1b = ms1 + iX;
       
    89 	if (ms1b>=32)
       
    90 		{
       
    91 		aInt32 = ~0u;
       
    92 		return KErrOverflow;
       
    93 		}
       
    94 	if (ms1b<-1)
       
    95 		{
       
    96 		aInt32 = 0;
       
    97 		return KErrUnderflow;
       
    98 		}
       
    99 	TInt shift = ms1b - ms1 + 31;
       
   100 	if (shift > 0)
       
   101 		x <<= shift;
       
   102 	else if (shift < 0)
       
   103 		x >>= (-shift);
       
   104 	x += MAKE_TUINT64(0,0x40000000u);
       
   105 	if (x >> 63)
       
   106 		{
       
   107 		aInt32 = ~0u;
       
   108 		return KErrOverflow;
       
   109 		}
       
   110 	aInt32 = (TUint32)(x>>31);
       
   111 	return aInt32 ? KErrNone : KErrUnderflow;
       
   112 	}
       
   113 
       
   114 //TInt SRatio::Mult(TUint64& aInt64)
       
   115 //	{
       
   116 //	}
       
   117 #endif
       
   118 
       
   119 void SRatioInv::Set(const SRatio* a)
       
   120 	{
       
   121 	if (a)
       
   122 		{
       
   123 		iR = *a;
       
   124 		iI = iR;
       
   125 		iI.Reciprocal();
       
   126 		}
       
   127 	else
       
   128 		{
       
   129 		iR.Set(1);
       
   130 		iI.Set(1);
       
   131 		}
       
   132 	}
       
   133 
       
   134 
       
   135