X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=ntoskrnl%2Frtl%2Flargeint.c;h=b62213b5a21007998eb02ab71a8bd51b4fea6cd3;hb=HEAD;hp=d45df8642d64e9f36944941281cad562cbf83e29;hpb=1334f77b1ecef00ac31076ce6bf22bdfeb82d347;p=reactos.git diff --git a/ntoskrnl/rtl/largeint.c b/ntoskrnl/rtl/largeint.c index d45df86..b62213b 100644 --- a/ntoskrnl/rtl/largeint.c +++ b/ntoskrnl/rtl/largeint.c @@ -19,6 +19,9 @@ /* FUNCTIONS *****************************************************************/ +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlConvertLongToLargeInteger ( @@ -32,6 +35,9 @@ RtlConvertLongToLargeInteger ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlConvertUlongToLargeInteger ( @@ -45,6 +51,9 @@ RtlConvertUlongToLargeInteger ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlEnlargedIntegerMultiply ( @@ -59,6 +68,9 @@ RtlEnlargedIntegerMultiply ( return RC; } +/* + * @implemented + */ ULONG STDCALL RtlEnlargedUnsignedDivide ( @@ -73,6 +85,9 @@ RtlEnlargedUnsignedDivide ( return (ULONG)(Dividend.QuadPart / Divisor); } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlEnlargedUnsignedMultiply ( @@ -87,6 +102,9 @@ RtlEnlargedUnsignedMultiply ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlExtendedIntegerMultiply ( @@ -101,6 +119,9 @@ RtlExtendedIntegerMultiply ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlExtendedLargeIntegerDivide ( @@ -119,17 +140,84 @@ RtlExtendedLargeIntegerDivide ( return RC; } + +/****************************************************************************** + * RtlExtendedMagicDivide + * + * Allows replacing a division by a longlong constant with a multiplication by + * the inverse constant. + * + * RETURNS + * (Dividend * MagicDivisor) >> (64 + ShiftCount) + * + * NOTES + * If the divisor of a division is constant, the constants MagicDivisor and + * shift must be chosen such that + * MagicDivisor = 2^(64 + ShiftCount) / Divisor. + * + * Then we have RtlExtendedMagicDivide(Dividend,MagicDivisor,ShiftCount) == + * Dividend * MagicDivisor / 2^(64 + ShiftCount) == Dividend / Divisor. + * + * The Parameter MagicDivisor although defined as LONGLONG is used as + * ULONGLONG. + */ + +#define LOWER_32(A) ((A) & 0xffffffff) +#define UPPER_32(A) ((A) >> 32) + +/* + * @implemented + */ LARGE_INTEGER STDCALL -RtlExtendedMagicDivide (LARGE_INTEGER Dividend, - LARGE_INTEGER MagicDivisor, - CCHAR ShiftCount) +RtlExtendedMagicDivide (LARGE_INTEGER Dividend, + LARGE_INTEGER MagicDivisor, + CCHAR ShiftCount) { - LARGE_INTEGER Result; - - Result.QuadPart = (Dividend.QuadPart * MagicDivisor.QuadPart) >> ShiftCount; - return(Result); + ULONGLONG dividend_high; + ULONGLONG dividend_low; + ULONGLONG inverse_divisor_high; + ULONGLONG inverse_divisor_low; + ULONGLONG ah_bl; + ULONGLONG al_bh; + LARGE_INTEGER result; + BOOLEAN positive; + + if (Dividend.QuadPart < 0) + { + dividend_high = UPPER_32((ULONGLONG) -Dividend.QuadPart); + dividend_low = LOWER_32((ULONGLONG) -Dividend.QuadPart); + positive = FALSE; + } + else + { + dividend_high = UPPER_32((ULONGLONG) Dividend.QuadPart); + dividend_low = LOWER_32((ULONGLONG) Dividend.QuadPart); + positive = TRUE; + } + inverse_divisor_high = UPPER_32((ULONGLONG) MagicDivisor.QuadPart); + inverse_divisor_low = LOWER_32((ULONGLONG) MagicDivisor.QuadPart); + + ah_bl = dividend_high * inverse_divisor_low; + al_bh = dividend_low * inverse_divisor_high; + + result.QuadPart = + (LONGLONG) ((dividend_high * inverse_divisor_high + + UPPER_32(ah_bl) + + UPPER_32(al_bh) + + UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) + + UPPER_32(dividend_low * inverse_divisor_low))) >> ShiftCount); + if (!positive) + { + result.QuadPart = -result.QuadPart; + } + + return result; } + +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlLargeIntegerAdd ( @@ -144,6 +232,9 @@ RtlLargeIntegerAdd ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlLargeIntegerArithmeticShift ( @@ -170,6 +261,9 @@ RtlLargeIntegerArithmeticShift ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlLargeIntegerDivide ( @@ -188,6 +282,9 @@ RtlLargeIntegerDivide ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlLargeIntegerNegate ( @@ -201,6 +298,9 @@ RtlLargeIntegerNegate ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlLargeIntegerShiftLeft ( @@ -217,6 +317,9 @@ RtlLargeIntegerShiftLeft ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlLargeIntegerShiftRight ( @@ -233,6 +336,9 @@ RtlLargeIntegerShiftRight ( return RC; } +/* + * @implemented + */ LARGE_INTEGER STDCALL RtlLargeIntegerSubtract (