2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: kernel/rtl/largeint.c
5 * PURPOSE: Large integer operations
8 * 08/30/98 RJJ Implemented several functions
11 /* INCLUDES *****************************************************************/
13 #include <internal/ke.h>
14 #include <internal/linkage.h>
15 #include <ddk/ntddk.h>
18 #include <internal/debug.h>
20 typedef long long int LLI
, *PLLI
;
21 typedef unsigned long long int ULLI
, *PULLI
;
23 #define LIFromLLI(X) (*(PLARGE_INTEGER)&(X))
24 #define LLIFromLI(X) (*(PLLI)&(X))
25 #define ULIFromULLI(X) (*(PULARGE_INTEGER)&(X))
27 /* FUNCTIONS *****************************************************************/
30 RtlConvertLongToLargeInteger(LONG SignedInteger
)
34 RC
.QuadPart
= SignedInteger
;
40 RtlConvertUlongToLargeInteger(ULONG UnsignedInteger
)
44 RC
.QuadPart
= UnsignedInteger
;
50 RtlEnlargedIntegerMultiply(LONG Multiplicand
,
55 RC
.QuadPart
= (LONGLONG
) Multiplicand
* Multiplier
;
60 ULONG
RtlEnlargedUnsignedDivide(ULARGE_INTEGER Dividend
,
67 LARGE_INTEGER
RtlEnlargedUnsignedMultiply(ULONG Multiplicand
,
72 RC
.QuadPart
= (ULONGLONG
) Multiplicand
* Multiplier
;
78 RtlExtendedIntegerMultiply(LARGE_INTEGER Multiplicand
,
83 RC
.QuadPart
= Multiplicand
.QuadPart
* Multiplier
;
88 LARGE_INTEGER
RtlExtendedLargeIntegerDivide(LARGE_INTEGER Dividend
,
95 LARGE_INTEGER
RtlExtendedMagicDivide(LARGE_INTEGER Dividend
,
96 LARGE_INTEGER MagicDivisor
,
102 LARGE_INTEGER
ExInterlockedAddLargeInteger(PLARGE_INTEGER Addend
,
103 LARGE_INTEGER Increment
,
110 RtlLargeIntegerAdd(LARGE_INTEGER Addend1
,
111 LARGE_INTEGER Addend2
)
115 RC
.QuadPart
= Addend1
.QuadPart
+ Addend2
.QuadPart
;
120 VOID
RtlLargeIntegerAnd(PLARGE_INTEGER Result
,
121 LARGE_INTEGER Source
,
124 Result
->QuadPart
= Source
.QuadPart
& Mask
.QuadPart
;
127 LARGE_INTEGER
RtlLargeIntegerArithmeticShift(LARGE_INTEGER LargeInteger
,
135 RC
.QuadPart
= LargeInteger
.QuadPart
>> ShiftCount
;
136 asm ("movb %2, %%cl\n\t"
137 "andb $0x3f, %%cl\n\t"
140 "shrdl %%cl, %%edx, %%eax\n\t"
141 "sarl %%cl, %%edx\n\t"
144 : "=m" (LargeInteger
.LowPart
),
145 "=m" (LargeInteger
.HighPart
)
147 "0" (LargeInteger
.LowPart
),
148 "1" (LargeInteger
.HighPart
)
149 : "eax", "ecx", "edx"
156 LARGE_INTEGER
RtlLargeIntegerDivide(LARGE_INTEGER Dividend
,
157 LARGE_INTEGER Divisor
,
158 PLARGE_INTEGER Remainder
)
164 RtlLargeIntegerEqualTo(LARGE_INTEGER Operand1
,
165 LARGE_INTEGER Operand2
)
167 return Operand1
.QuadPart
== Operand2
.QuadPart
;
169 return Operand1
.HighPart
== Operand2
.HighPart
&&
170 Operand1
.LowPart
== Operand2
.LowPart
;
175 RtlLargeIntegerEqualToZero(LARGE_INTEGER Operand
)
177 return Operand
.QuadPart
== 0 ;
181 RtlLargeIntegerGreaterThan(LARGE_INTEGER Operand1
,
182 LARGE_INTEGER Operand2
)
184 return Operand1
.QuadPart
> Operand2
.QuadPart
;
186 return Operand1
.HighPart
> Operand2
.HighPart
||
187 (Operand1
.HighPart
== Operand2
.HighPart
&&
188 Operand1
.LowPart
> Operand2
.LowPart
);
193 RtlLargeIntegerGreaterThanOrEqualTo(LARGE_INTEGER Operand1
,
194 LARGE_INTEGER Operand2
)
196 return Operand1
.QuadPart
>= Operand2
.QuadPart
;
198 return Operand1
.HighPart
> Operand2
.HighPart
||
199 (Operand1
.HighPart
== Operand2
.HighPart
&&
200 Operand1
.LowPart
>= Operand2
.LowPart
);
205 RtlLargeIntegerGreaterThanOrEqualToZero(LARGE_INTEGER Operand1
)
207 return Operand1
.QuadPart
>= 0;
209 return Operand1
.HighPart
>= 0;
214 RtlLargeIntegerGreaterThanZero(LARGE_INTEGER Operand1
)
216 return Operand1
.QuadPart
> 0;
218 return Operand1
.HighPart
> 0 ||
219 (Operand1
.HighPart
== 0 && Operand1
.LowPart
> 0);
224 RtlLargeIntegerLessThan(LARGE_INTEGER Operand1
,
225 LARGE_INTEGER Operand2
)
227 return Operand1
.QuadPart
< Operand2
.QuadPart
;
229 return Operand1
.HighPart
< Operand2
.HighPart
||
230 (Operand1
.HighPart
== Operand2
.HighPart
&&
231 Operand1
.LowPart
< Operand2
.LowPart
);
236 RtlLargeIntegerLessThanOrEqualTo(LARGE_INTEGER Operand1
,
237 LARGE_INTEGER Operand2
)
239 return Operand1
.QuadPart
<= Operand2
.QuadPart
;
241 return Operand1
.HighPart
< Operand2
.HighPart
||
242 (Operand1
.HighPart
== Operand2
.HighPart
&&
243 Operand1
.LowPart
<= Operand2
.LowPart
);
248 RtlLargeIntegerLessThanOrEqualToZero(LARGE_INTEGER Operand
)
250 return Operand
.QuadPart
<= 0;
252 return Operand
.HighPart
< 0 ||
253 (Operand
.HighPart
== 0 && Operand
.LowPart
== 0);
258 RtlLargeIntegerLessThanZero(LARGE_INTEGER Operand
)
260 return Operand
.QuadPart
< 0;
262 return Operand
.HighPart
< 0;
266 LARGE_INTEGER
RtlLargeIntegerNegate(LARGE_INTEGER Subtrahend
)
270 RC
.QuadPart
= - Subtrahend
.QuadPart
;
276 RtlLargeIntegerNotEqualTo(LARGE_INTEGER Operand1
,
277 LARGE_INTEGER Operand2
)
279 return Operand1
.QuadPart
!= Operand2
.QuadPart
;
283 RtlLargeIntegerNotEqualToZero(LARGE_INTEGER Operand
)
285 return Operand
.QuadPart
!= 0;
288 LARGE_INTEGER
RtlLargeIntegerShiftLeft(LARGE_INTEGER LargeInteger
,
293 RC
.QuadPart
= LargeInteger
.QuadPart
<< ShiftCount
;
298 LARGE_INTEGER
RtlLargeIntegerShiftRight(LARGE_INTEGER LargeInteger
,
303 RC
.QuadPart
= LargeInteger
.QuadPart
>> ShiftCount
;
308 LARGE_INTEGER
RtlLargeIntegerSubtract(LARGE_INTEGER Minuend
,
309 LARGE_INTEGER Subtrahend
)
313 RC
.QuadPart
= Minuend
.QuadPart
- Subtrahend
.QuadPart
;