finished applying @implemented and @unimplemented comments and remove the comments...
[reactos.git] / reactos / ntoskrnl / rtl / largeint.c
1 /* $Id: largeint.c,v 1.15 2003/07/11 01:23:15 royce Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: kernel/rtl/largeint.c
6 * PURPOSE: Large integer operations
7 * UPDATE HISTORY:
8 * Created 22/05/98
9 * 08/30/98 RJJ Implemented several functions
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15
16 #define NDEBUG
17 #include <internal/debug.h>
18
19
20 /* FUNCTIONS *****************************************************************/
21
22 /*
23 * @implemented
24 */
25 LARGE_INTEGER
26 STDCALL
27 RtlConvertLongToLargeInteger (
28 LONG SignedInteger
29 )
30 {
31 LARGE_INTEGER RC;
32
33 RC.QuadPart = SignedInteger;
34
35 return RC;
36 }
37
38 /*
39 * @implemented
40 */
41 LARGE_INTEGER
42 STDCALL
43 RtlConvertUlongToLargeInteger (
44 ULONG UnsignedInteger
45 )
46 {
47 LARGE_INTEGER RC;
48
49 RC.QuadPart = UnsignedInteger;
50
51 return RC;
52 }
53
54 /*
55 * @implemented
56 */
57 LARGE_INTEGER
58 STDCALL
59 RtlEnlargedIntegerMultiply (
60 LONG Multiplicand,
61 LONG Multiplier
62 )
63 {
64 LARGE_INTEGER RC;
65
66 RC.QuadPart = (LONGLONG) Multiplicand * Multiplier;
67
68 return RC;
69 }
70
71 /*
72 * @implemented
73 */
74 ULONG
75 STDCALL
76 RtlEnlargedUnsignedDivide (
77 ULARGE_INTEGER Dividend,
78 ULONG Divisor,
79 PULONG Remainder
80 )
81 {
82 if (Remainder)
83 *Remainder = Dividend.QuadPart % Divisor;
84
85 return (ULONG)(Dividend.QuadPart / Divisor);
86 }
87
88 /*
89 * @implemented
90 */
91 LARGE_INTEGER
92 STDCALL
93 RtlEnlargedUnsignedMultiply (
94 ULONG Multiplicand,
95 ULONG Multiplier
96 )
97 {
98 LARGE_INTEGER RC;
99
100 RC.QuadPart = (ULONGLONG) Multiplicand * Multiplier;
101
102 return RC;
103 }
104
105 /*
106 * @implemented
107 */
108 LARGE_INTEGER
109 STDCALL
110 RtlExtendedIntegerMultiply (
111 LARGE_INTEGER Multiplicand,
112 LONG Multiplier
113 )
114 {
115 LARGE_INTEGER RC;
116
117 RC.QuadPart = Multiplicand.QuadPart * Multiplier;
118
119 return RC;
120 }
121
122 /*
123 * @implemented
124 */
125 LARGE_INTEGER
126 STDCALL
127 RtlExtendedLargeIntegerDivide (
128 LARGE_INTEGER Dividend,
129 ULONG Divisor,
130 PULONG Remainder
131 )
132 {
133 LARGE_INTEGER RC;
134
135 if (Remainder)
136 *Remainder = Dividend.QuadPart % Divisor;
137
138 RC.QuadPart = Dividend.QuadPart / Divisor;
139
140 return RC;
141 }
142
143
144 /******************************************************************************
145 * RtlExtendedMagicDivide
146 *
147 * Allows replacing a division by a longlong constant with a multiplication by
148 * the inverse constant.
149 *
150 * RETURNS
151 * (Dividend * MagicDivisor) >> (64 + ShiftCount)
152 *
153 * NOTES
154 * If the divisor of a division is constant, the constants MagicDivisor and
155 * shift must be chosen such that
156 * MagicDivisor = 2^(64 + ShiftCount) / Divisor.
157 *
158 * Then we have RtlExtendedMagicDivide(Dividend,MagicDivisor,ShiftCount) ==
159 * Dividend * MagicDivisor / 2^(64 + ShiftCount) == Dividend / Divisor.
160 *
161 * The Parameter MagicDivisor although defined as LONGLONG is used as
162 * ULONGLONG.
163 */
164
165 #define LOWER_32(A) ((A) & 0xffffffff)
166 #define UPPER_32(A) ((A) >> 32)
167
168 /*
169 * @implemented
170 */
171 LARGE_INTEGER STDCALL
172 RtlExtendedMagicDivide (LARGE_INTEGER Dividend,
173 LARGE_INTEGER MagicDivisor,
174 CCHAR ShiftCount)
175 {
176 ULONGLONG dividend_high;
177 ULONGLONG dividend_low;
178 ULONGLONG inverse_divisor_high;
179 ULONGLONG inverse_divisor_low;
180 ULONGLONG ah_bl;
181 ULONGLONG al_bh;
182 LARGE_INTEGER result;
183 BOOLEAN positive;
184
185 if (Dividend.QuadPart < 0)
186 {
187 dividend_high = UPPER_32((ULONGLONG) -Dividend.QuadPart);
188 dividend_low = LOWER_32((ULONGLONG) -Dividend.QuadPart);
189 positive = FALSE;
190 }
191 else
192 {
193 dividend_high = UPPER_32((ULONGLONG) Dividend.QuadPart);
194 dividend_low = LOWER_32((ULONGLONG) Dividend.QuadPart);
195 positive = TRUE;
196 }
197 inverse_divisor_high = UPPER_32((ULONGLONG) MagicDivisor.QuadPart);
198 inverse_divisor_low = LOWER_32((ULONGLONG) MagicDivisor.QuadPart);
199
200 ah_bl = dividend_high * inverse_divisor_low;
201 al_bh = dividend_low * inverse_divisor_high;
202
203 result.QuadPart =
204 (LONGLONG) ((dividend_high * inverse_divisor_high +
205 UPPER_32(ah_bl) +
206 UPPER_32(al_bh) +
207 UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) +
208 UPPER_32(dividend_low * inverse_divisor_low))) >> ShiftCount);
209 if (!positive)
210 {
211 result.QuadPart = -result.QuadPart;
212 }
213
214 return result;
215 }
216
217
218 /*
219 * @implemented
220 */
221 LARGE_INTEGER
222 STDCALL
223 RtlLargeIntegerAdd (
224 LARGE_INTEGER Addend1,
225 LARGE_INTEGER Addend2
226 )
227 {
228 LARGE_INTEGER RC;
229
230 RC.QuadPart = Addend1.QuadPart + Addend2.QuadPart;
231
232 return RC;
233 }
234
235 /*
236 * @implemented
237 */
238 LARGE_INTEGER
239 STDCALL
240 RtlLargeIntegerArithmeticShift (
241 LARGE_INTEGER LargeInteger,
242 CCHAR ShiftCount
243 )
244 {
245 LARGE_INTEGER RC;
246 CHAR Shift;
247
248 Shift = ShiftCount % 64;
249
250 if (Shift < 32)
251 {
252 RC.QuadPart = LargeInteger.QuadPart >> Shift;
253 }
254 else
255 {
256 /* copy the sign bit */
257 RC.u.HighPart |= (LargeInteger.u.HighPart & 0x80000000);
258 RC.u.LowPart = LargeInteger.u.HighPart >> Shift;
259 }
260
261 return RC;
262 }
263
264 /*
265 * @implemented
266 */
267 LARGE_INTEGER
268 STDCALL
269 RtlLargeIntegerDivide (
270 LARGE_INTEGER Dividend,
271 LARGE_INTEGER Divisor,
272 PLARGE_INTEGER Remainder
273 )
274 {
275 LARGE_INTEGER RC;
276
277 if (Remainder)
278 Remainder->QuadPart = Dividend.QuadPart % Divisor.QuadPart;
279
280 RC.QuadPart = Dividend.QuadPart / Divisor.QuadPart;
281
282 return RC;
283 }
284
285 /*
286 * @implemented
287 */
288 LARGE_INTEGER
289 STDCALL
290 RtlLargeIntegerNegate (
291 LARGE_INTEGER Subtrahend
292 )
293 {
294 LARGE_INTEGER RC;
295
296 RC.QuadPart = - Subtrahend.QuadPart;
297
298 return RC;
299 }
300
301 /*
302 * @implemented
303 */
304 LARGE_INTEGER
305 STDCALL
306 RtlLargeIntegerShiftLeft (
307 LARGE_INTEGER LargeInteger,
308 CCHAR ShiftCount
309 )
310 {
311 LARGE_INTEGER RC;
312 CHAR Shift;
313
314 Shift = ShiftCount % 64;
315 RC.QuadPart = LargeInteger.QuadPart << Shift;
316
317 return RC;
318 }
319
320 /*
321 * @implemented
322 */
323 LARGE_INTEGER
324 STDCALL
325 RtlLargeIntegerShiftRight (
326 LARGE_INTEGER LargeInteger,
327 CCHAR ShiftCount
328 )
329 {
330 LARGE_INTEGER RC;
331 CHAR Shift;
332
333 Shift = ShiftCount % 64;
334 RC.QuadPart = LargeInteger.QuadPart >> ShiftCount;
335
336 return RC;
337 }
338
339 /*
340 * @implemented
341 */
342 LARGE_INTEGER
343 STDCALL
344 RtlLargeIntegerSubtract (
345 LARGE_INTEGER Minuend,
346 LARGE_INTEGER Subtrahend
347 )
348 {
349 LARGE_INTEGER RC;
350
351 RC.QuadPart = Minuend.QuadPart - Subtrahend.QuadPart;
352
353 return RC;
354 }
355
356 /* EOF */