/* FUNCTIONS *****************************************************************/
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlConvertLongToLargeInteger (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlConvertUlongToLargeInteger (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlEnlargedIntegerMultiply (
return RC;
}
+/*
+ * @implemented
+ */
ULONG
STDCALL
RtlEnlargedUnsignedDivide (
return (ULONG)(Dividend.QuadPart / Divisor);
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlEnlargedUnsignedMultiply (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlExtendedIntegerMultiply (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlExtendedLargeIntegerDivide (
return RC;
}
-LARGE_INTEGER
-STDCALL
-RtlExtendedMagicDivide (LARGE_INTEGER Dividend,
- LARGE_INTEGER MagicDivisor,
- CCHAR ShiftCount)
-{
- LARGE_INTEGER Result;
- Result.QuadPart = (Dividend.QuadPart * MagicDivisor.QuadPart) >> ShiftCount;
- return(Result);
+/******************************************************************************
+ * 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)
+{
+ 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 (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlLargeIntegerArithmeticShift (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlLargeIntegerDivide (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlLargeIntegerNegate (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlLargeIntegerShiftLeft (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlLargeIntegerShiftRight (
return RC;
}
+/*
+ * @implemented
+ */
LARGE_INTEGER
STDCALL
RtlLargeIntegerSubtract (