2 * Large integer functions
4 * Copyright 2000 Alexandre Julliard
5 * Copyright 2003 Thomas Mertes
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define WIN32_NO_STATUS
33 * Note: we use LONGLONG instead of LARGE_INTEGER, because
34 * the latter is a structure and the calling convention for
35 * returning a structure would not be binary-compatible.
37 * FIXME: for platforms that don't have a native LONGLONG type,
38 * we should define LONGLONG as a structure similar to LARGE_INTEGER
39 * and do everything by hand. You are welcome to do it...
42 /******************************************************************************
43 * RtlLargeIntegerAdd (NTDLL.@)
45 * Add two 64 bit integers.
48 * a [I] Initial number.
49 * b [I] Number to add to a.
54 LONGLONG WINAPI
RtlLargeIntegerAdd( LONGLONG a
, LONGLONG b
)
60 /******************************************************************************
61 * RtlLargeIntegerSubtract (NTDLL.@)
63 * Subtract two 64 bit integers.
66 * a [I] Initial number.
67 * b [I] Number to subtract from a.
70 * The difference of a and b.
72 LONGLONG WINAPI
RtlLargeIntegerSubtract( LONGLONG a
, LONGLONG b
)
78 /******************************************************************************
79 * RtlLargeIntegerNegate (NTDLL.@)
81 * Negate a 64 bit integer.
84 * a [I] Initial number.
87 * The value of a negated.
89 LONGLONG WINAPI
RtlLargeIntegerNegate( LONGLONG a
)
95 /******************************************************************************
96 * RtlLargeIntegerShiftLeft (NTDLL.@)
98 * Perform a shift left on a 64 bit integer.
101 * a [I] Initial number.
102 * count [I] Number of bits to shift by
105 * The value of a following the shift.
107 LONGLONG WINAPI
RtlLargeIntegerShiftLeft( LONGLONG a
, INT count
)
113 /******************************************************************************
114 * RtlLargeIntegerShiftRight (NTDLL.@)
116 * Perform a shift right on a 64 bit integer.
119 * a [I] Initial number.
120 * count [I] Number of bits to shift by
123 * The value of a following the shift.
125 LONGLONG WINAPI
RtlLargeIntegerShiftRight( LONGLONG a
, INT count
)
127 return (ULONGLONG
)a
>> count
;
131 /******************************************************************************
132 * RtlLargeIntegerArithmeticShift (NTDLL.@)
134 * Perform an arithmetic shift right on a 64 bit integer.
137 * a [I] Initial number.
138 * count [I] Number of bits to shift by
141 * The value of a following the shift.
143 LONGLONG WINAPI
RtlLargeIntegerArithmeticShift( LONGLONG a
, INT count
)
145 /* FIXME: gcc does arithmetic shift here, but it may not be true on all platforms */
150 /******************************************************************************
151 * RtlLargeIntegerDivide (NTDLL.@)
153 * Divide one 64 bit unsigned integer by another, with remainder.
156 * a [I] Initial number.
157 * b [I] Number to divide a by
158 * rem [O] Destination for remainder
161 * The dividend of a and b. If rem is non-NULL it is set to the remainder.
164 * Should it be signed division instead?
166 ULONGLONG WINAPI
RtlLargeIntegerDivide( ULONGLONG a
, ULONGLONG b
, ULONGLONG
*rem
)
168 ULONGLONG ret
= a
/ b
;
169 if (rem
) *rem
= a
- ret
* b
;
174 /******************************************************************************
175 * RtlConvertLongToLargeInteger (NTDLL.@)
177 * Convert a 32 bit integer into 64 bits.
180 * a [I] Number to convert
185 LONGLONG WINAPI
RtlConvertLongToLargeInteger( LONG a
)
191 /******************************************************************************
192 * RtlConvertUlongToLargeInteger (NTDLL.@)
194 * Convert a 32 bit unsigned integer into 64 bits.
197 * a [I] Number to convert
202 ULONGLONG WINAPI
RtlConvertUlongToLargeInteger( ULONG a
)
208 /******************************************************************************
209 * RtlEnlargedIntegerMultiply (NTDLL.@)
211 * Multiply two integers giving a 64 bit integer result.
214 * a [I] Initial number.
215 * b [I] Number to multiply a by.
218 * The product of a and b.
220 LONGLONG WINAPI
RtlEnlargedIntegerMultiply( INT a
, INT b
)
222 return (LONGLONG
)a
* b
;
226 /******************************************************************************
227 * RtlEnlargedUnsignedMultiply (NTDLL.@)
229 * Multiply two unsigned integers giving a 64 bit unsigned integer result.
232 * a [I] Initial number.
233 * b [I] Number to multiply a by.
236 * The product of a and b.
238 ULONGLONG WINAPI
RtlEnlargedUnsignedMultiply( UINT a
, UINT b
)
240 return (ULONGLONG
)a
* b
;
244 /******************************************************************************
245 * RtlEnlargedUnsignedDivide (NTDLL.@)
247 * Divide one 64 bit unsigned integer by a 32 bit unsigned integer, with remainder.
250 * a [I] Initial number.
251 * b [I] Number to divide a by
252 * remptr [O] Destination for remainder
255 * The dividend of a and b. If remptr is non-NULL it is set to the remainder.
257 UINT WINAPI
RtlEnlargedUnsignedDivide( ULONGLONG a
, UINT b
, UINT
*remptr
)
259 #if defined(__i386__) && defined(__GNUC__)
263 : "=a" (ret
), "=d" (rem
)
264 : "0" ((UINT
)a
), "1" ((UINT
)(a
>> 32)), "g" (b
) );
265 if (remptr
) *remptr
= rem
;
269 if (remptr
) *remptr
= a
% b
;
275 /******************************************************************************
276 * RtlExtendedLargeIntegerDivide (NTDLL.@)
278 * Divide one 64 bit integer by a 32 bit integer, with remainder.
281 * a [I] Initial number.
282 * b [I] Number to divide a by
283 * rem [O] Destination for remainder
286 * The dividend of a and b. If rem is non-NULL it is set to the remainder.
288 LONGLONG WINAPI
RtlExtendedLargeIntegerDivide( LONGLONG a
, INT b
, INT
*rem
)
290 LONGLONG ret
= a
/ b
;
291 if (rem
) *rem
= a
- b
* ret
;
296 /******************************************************************************
297 * RtlExtendedIntegerMultiply (NTDLL.@)
299 * Multiply one 64 bit integer by another 32 bit integer.
302 * a [I] Initial number.
303 * b [I] Number to multiply a by.
306 * The product of a and b.
308 LONGLONG WINAPI
RtlExtendedIntegerMultiply( LONGLONG a
, INT b
)
314 /******************************************************************************
315 * RtlExtendedMagicDivide (NTDLL.@)
317 * Allows replacing a division by a longlong constant with a multiplication by
318 * the inverse constant.
321 * (dividend * inverse_divisor) >> (64 + shift)
324 * If the divisor of a division is constant, the constants inverse_divisor and
325 * shift must be chosen such that inverse_divisor = 2^(64 + shift) / divisor.
326 * Then we have RtlExtendedMagicDivide(dividend,inverse_divisor,shift) ==
327 * dividend * inverse_divisor / 2^(64 + shift) == dividend / divisor.
329 * The Parameter inverse_divisor although defined as LONGLONG is used as
332 #define LOWER_32(A) ((A) & 0xffffffff)
333 #define UPPER_32(A) ((A) >> 32)
334 LONGLONG WINAPI
RtlExtendedMagicDivide(
335 LONGLONG dividend
, /* [I] Dividend to be divided by the constant divisor */
336 LONGLONG inverse_divisor
, /* [I] Constant computed manually as 2^(64+shift) / divisor */
337 INT shift
) /* [I] Constant shift chosen to make inverse_divisor as big as possible for 64 bits */
339 ULONGLONG dividend_high
;
340 ULONGLONG dividend_low
;
341 ULONGLONG inverse_divisor_high
;
342 ULONGLONG inverse_divisor_low
;
349 dividend_high
= UPPER_32((ULONGLONG
) -dividend
);
350 dividend_low
= LOWER_32((ULONGLONG
) -dividend
);
353 dividend_high
= UPPER_32((ULONGLONG
) dividend
);
354 dividend_low
= LOWER_32((ULONGLONG
) dividend
);
357 inverse_divisor_high
= UPPER_32((ULONGLONG
) inverse_divisor
);
358 inverse_divisor_low
= LOWER_32((ULONGLONG
) inverse_divisor
);
360 ah_bl
= dividend_high
* inverse_divisor_low
;
361 al_bh
= dividend_low
* inverse_divisor_high
;
363 result
= (LONGLONG
) ((dividend_high
* inverse_divisor_high
+
366 UPPER_32(LOWER_32(ah_bl
) + LOWER_32(al_bh
) +
367 UPPER_32(dividend_low
* inverse_divisor_low
))) >> shift
);
377 /*************************************************************************
378 * RtlInterlockedCompareExchange64 (NTDLL.@)
380 LONGLONG WINAPI
RtlInterlockedCompareExchange64( LONGLONG
*dest
, LONGLONG xchg
, LONGLONG compare
)
382 return __sync_val_compare_and_swap( dest
, compare
, xchg
);
387 /******************************************************************************
388 * RtlLargeIntegerToChar [NTDLL.@]
390 * Convert an unsigned large integer to a character string.
393 * Success: STATUS_SUCCESS. str contains the converted number
394 * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
395 * STATUS_BUFFER_OVERFLOW, if str would be larger than length.
396 * STATUS_ACCESS_VIOLATION, if str is NULL.
399 * Instead of base 0 it uses 10 as base.
400 * Writes at most length characters to the string str.
401 * Str is '\0' terminated when length allows it.
402 * When str fits exactly in length characters the '\0' is omitted.
403 * If value_ptr is NULL it crashes, as the native function does.
406 * - Accept base 0 as 10 instead of crashing as native function does.
407 * - The native function does produce garbage or STATUS_BUFFER_OVERFLOW for
408 * base 2, 8 and 16 when the value is larger than 0xFFFFFFFF.
410 NTSTATUS WINAPI
RtlLargeIntegerToChar(
411 const ULONGLONG
*value_ptr
, /* [I] Pointer to the value to be converted */
412 ULONG base
, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
413 ULONG length
, /* [I] Length of the str buffer in bytes */
414 PCHAR str
) /* [O] Destination for the converted value */
416 ULONGLONG value
= *value_ptr
;
424 } else if (base
!= 2 && base
!= 8 && base
!= 10 && base
!= 16) {
425 return STATUS_INVALID_PARAMETER
;
433 digit
= value
% base
;
434 value
= value
/ base
;
438 *pos
= 'A' + digit
- 10;
440 } while (value
!= 0L);
442 len
= &buffer
[64] - pos
;
444 return STATUS_BUFFER_OVERFLOW
;
445 } else if (str
== NULL
) {
446 return STATUS_ACCESS_VIOLATION
;
447 } else if (len
== length
) {
448 memcpy(str
, pos
, len
);
450 memcpy(str
, pos
, len
+ 1);
452 return STATUS_SUCCESS
;
456 /**************************************************************************
457 * RtlInt64ToUnicodeString (NTDLL.@)
459 * Convert a large unsigned integer to a '\0' terminated unicode string.
462 * Success: STATUS_SUCCESS. str contains the converted number
463 * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
464 * STATUS_BUFFER_OVERFLOW, if str is too small to hold the string
465 * (with the '\0' termination). In this case str->Length
466 * is set to the length, the string would have (which can
467 * be larger than the MaximumLength).
470 * Instead of base 0 it uses 10 as base.
471 * If str is NULL it crashes, as the native function does.
474 * - Accept base 0 as 10 instead of crashing as native function does.
475 * - Do not return STATUS_BUFFER_OVERFLOW when the string is long enough.
476 * The native function does this when the string would be longer than 31
477 * characters even when the string parameter is long enough.
478 * - The native function does produce garbage or STATUS_BUFFER_OVERFLOW for
479 * base 2, 8 and 16 when the value is larger than 0xFFFFFFFF.
481 NTSTATUS WINAPI
RtlInt64ToUnicodeString(
482 ULONGLONG value
, /* [I] Value to be converted */
483 ULONG base
, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
484 UNICODE_STRING
*str
) /* [O] Destination for the converted value */
492 } else if (base
!= 2 && base
!= 8 && base
!= 10 && base
!= 16) {
493 return STATUS_INVALID_PARAMETER
;
501 digit
= value
% base
;
502 value
= value
/ base
;
506 *pos
= 'A' + digit
- 10;
508 } while (value
!= 0L);
510 str
->Length
= (&buffer
[64] - pos
) * sizeof(WCHAR
);
511 if (str
->Length
>= str
->MaximumLength
) {
512 return STATUS_BUFFER_OVERFLOW
;
514 memcpy(str
->Buffer
, pos
, str
->Length
+ sizeof(WCHAR
));
516 return STATUS_SUCCESS
;
522 /* those builtin functions use stdcall calling convention, but compilers reference them without stdcall declarations */
523 #if defined(__MINGW32__) || defined(_MSC_VER)
524 LONGLONG WINAPI
_alldiv( LONGLONG a
, LONGLONG b
) asm(__ASM_NAME("_alldiv"));
525 LONGLONG WINAPI
_allmul( LONGLONG a
, LONGLONG b
) asm(__ASM_NAME("_allmul"));
526 LONGLONG WINAPI
_allrem( LONGLONG a
, LONGLONG b
) asm(__ASM_NAME("_allrem"));
527 ULONGLONG WINAPI
_aulldiv( ULONGLONG a
, ULONGLONG b
) asm(__ASM_NAME("_aulldiv"));
528 ULONGLONG WINAPI
_aullrem( ULONGLONG a
, ULONGLONG b
) asm(__ASM_NAME("_aullrem"));
531 static ULONGLONG
udivmod(ULONGLONG a
, ULONGLONG b
, ULONGLONG
*rem
)
533 const ULARGE_INTEGER n
= { .QuadPart
= a
};
534 const ULARGE_INTEGER d
= { .QuadPart
= b
};
535 DWORD sr
, carry
, index
;
538 const unsigned n_uword_bits
= 32;
539 const unsigned n_udword_bits
= 64;
541 /* special cases, X is unknown, K != 0 */
542 if (n
.u
.HighPart
== 0)
544 if (d
.u
.HighPart
== 0)
547 if (rem
) *rem
= n
.u
.LowPart
% d
.u
.LowPart
;
548 return n
.u
.LowPart
/ d
.u
.LowPart
;
551 if (rem
) *rem
= n
.u
.LowPart
;
555 /* n.u.HighPart != 0 */
556 if (d
.u
.LowPart
== 0)
558 if (d
.u
.HighPart
== 0)
561 if (rem
) *rem
= n
.u
.HighPart
% d
.u
.LowPart
;
562 return n
.u
.HighPart
/ d
.u
.LowPart
;
564 /* d.u.HighPart != 0 */
565 if (n
.u
.LowPart
== 0) {
569 r
.u
.HighPart
= n
.u
.HighPart
% d
.u
.HighPart
;
573 return n
.u
.HighPart
/ d
.u
.HighPart
;
576 if ((d
.u
.HighPart
& (d
.u
.HighPart
- 1)) == 0) /* if d is a power of 2 */
580 r
.u
.LowPart
= n
.u
.LowPart
;
581 r
.u
.HighPart
= n
.u
.HighPart
& (d
.u
.HighPart
- 1);
584 BitScanForward(&index
, d
.u
.HighPart
);
585 return n
.u
.HighPart
>> index
;
588 BitScanReverse(&index
, d
.u
.HighPart
);
589 BitScanReverse(&sr
, n
.u
.HighPart
);
591 /* 0 <= sr <= n_uword_bits - 2 or sr large */
592 if (sr
> n_uword_bits
- 2)
594 if (rem
) *rem
= n
.QuadPart
;
598 /* 1 <= sr <= n_uword_bits - 1 */
599 /* q.QuadPart = n.QuadPart << (n_udword_bits - sr); */
601 q
.u
.HighPart
= n
.u
.LowPart
<< (n_uword_bits
- sr
);
602 /* r.QuadPart = n.QuadPart >> sr; */
603 r
.u
.HighPart
= n
.u
.HighPart
>> sr
;
604 r
.u
.LowPart
= (n
.u
.HighPart
<< (n_uword_bits
- sr
)) | (n
.u
.LowPart
>> sr
);
606 else /* d.u.LowPart != 0 */
608 if (d
.u
.HighPart
== 0)
611 if ((d
.u
.LowPart
& (d
.u
.LowPart
- 1)) == 0) /* if d is a power of 2 */
613 if (rem
) *rem
= n
.u
.LowPart
& (d
.u
.LowPart
- 1);
614 if (d
.u
.LowPart
== 1) return n
.QuadPart
;
615 BitScanForward(&sr
, d
.u
.LowPart
);
616 q
.u
.HighPart
= n
.u
.HighPart
>> sr
;
617 q
.u
.LowPart
= (n
.u
.HighPart
<< (n_uword_bits
- sr
)) | (n
.u
.LowPart
>> sr
);
620 BitScanReverse(&index
, d
.u
.LowPart
);
621 BitScanReverse(&sr
, n
.u
.HighPart
);
622 sr
= 1 + n_uword_bits
+ sr
- index
;
623 /* 2 <= sr <= n_udword_bits - 1
624 * q.QuadPart = n.QuadPart << (n_udword_bits - sr);
625 * r.QuadPart = n.QuadPart >> sr; */
626 if (sr
== n_uword_bits
)
629 q
.u
.HighPart
= n
.u
.LowPart
;
631 r
.u
.LowPart
= n
.u
.HighPart
;
633 else if (sr
< n_uword_bits
) /* 2 <= sr <= n_uword_bits - 1 */
636 q
.u
.HighPart
= n
.u
.LowPart
<< (n_uword_bits
- sr
);
637 r
.u
.HighPart
= n
.u
.HighPart
>> sr
;
638 r
.u
.LowPart
= (n
.u
.HighPart
<< (n_uword_bits
- sr
)) | (n
.u
.LowPart
>> sr
);
640 else /* n_uword_bits + 1 <= sr <= n_udword_bits - 1 */
642 q
.u
.LowPart
= n
.u
.LowPart
<< (n_udword_bits
- sr
);
643 q
.u
.HighPart
= (n
.u
.HighPart
<< (n_udword_bits
- sr
)) |
644 (n
.u
.LowPart
>> (sr
- n_uword_bits
));
646 r
.u
.LowPart
= n
.u
.HighPart
>> (sr
- n_uword_bits
);
652 BitScanReverse(&index
, d
.u
.HighPart
);
653 BitScanReverse(&sr
, n
.u
.HighPart
);
655 /* 0 <= sr <= n_uword_bits - 1 or sr large */
656 if (sr
> n_uword_bits
- 1)
658 if (rem
) *rem
= n
.QuadPart
;
662 /* 1 <= sr <= n_uword_bits
663 * q.QuadPart = n.QuadPart << (n_udword_bits - sr); */
665 if (sr
== n_uword_bits
)
667 q
.u
.HighPart
= n
.u
.LowPart
;
669 r
.u
.LowPart
= n
.u
.HighPart
;
673 q
.u
.HighPart
= n
.u
.LowPart
<< (n_uword_bits
- sr
);
674 r
.u
.HighPart
= n
.u
.HighPart
>> sr
;
675 r
.u
.LowPart
= (n
.u
.HighPart
<< (n_uword_bits
- sr
)) | (n
.u
.LowPart
>> sr
);
679 /* Not a special case
680 * q and r are initialized with:
681 * q.QuadPart = n.QuadPart << (n_udword_bits - sr);
682 * r.QuadPart = n.QuadPart >> sr;
683 * 1 <= sr <= n_udword_bits - 1 */
688 /* r:q = ((r:q) << 1) | carry */
689 r
.u
.HighPart
= (r
.u
.HighPart
<< 1) | (r
.u
.LowPart
>> (n_uword_bits
- 1));
690 r
.u
.LowPart
= (r
.u
.LowPart
<< 1) | (q
.u
.HighPart
>> (n_uword_bits
- 1));
691 q
.u
.HighPart
= (q
.u
.HighPart
<< 1) | (q
.u
.LowPart
>> (n_uword_bits
- 1));
692 q
.u
.LowPart
= (q
.u
.LowPart
<< 1) | carry
;
693 /* if (r.QuadPart >= d.QuadPart)
695 * r.QuadPart -= d.QuadPart;
699 s
= (LONGLONG
)(d
.QuadPart
- r
.QuadPart
- 1) >> (n_udword_bits
- 1);
701 r
.QuadPart
-= d
.QuadPart
& s
;
703 q
.QuadPart
= (q
.QuadPart
<< 1) | carry
;
704 if (rem
) *rem
= r
.QuadPart
;
708 /******************************************************************************
711 * Divide two 64 bit unsigned integers.
714 * a [I] Initial number.
715 * b [I] Number to divide a by.
718 * The dividend of a and b.
720 LONGLONG WINAPI
_alldiv( LONGLONG a
, LONGLONG b
)
722 LONGLONG s_a
= a
>> 63; /* s_a = a < 0 ? -1 : 0 */
723 LONGLONG s_b
= b
>> 63; /* s_b = b < 0 ? -1 : 0 */
724 a
= (a
^ s_a
) - s_a
; /* negate if s_a == -1 */
725 b
= (b
^ s_b
) - s_b
; /* negate if s_b == -1 */
726 s_a
^= s_b
; /* sign of quotient */
727 return (udivmod(a
, b
, NULL
) ^ s_a
) - s_a
; /* negate if s_a == -1 */
731 /******************************************************************************
734 * Multiply two 64 bit integers.
737 * a [I] Initial number.
738 * b [I] Number to multiply a by.
741 * The product of a and b.
743 LONGLONG WINAPI
_allmul( LONGLONG a
, LONGLONG b
)
745 LARGE_INTEGER x
= { .QuadPart
= a
};
746 LARGE_INTEGER y
= { .QuadPart
= b
};
750 const int bits_in_word_2
= 16;
751 const unsigned int lower_mask
= ~0u >> bits_in_word_2
;
753 r
.u
.LowPart
= (x
.u
.LowPart
& lower_mask
) * (y
.u
.LowPart
& lower_mask
);
754 t
= r
.u
.LowPart
>> bits_in_word_2
;
755 r
.u
.LowPart
&= lower_mask
;
756 t
+= (x
.u
.LowPart
>> bits_in_word_2
) * (y
.u
.LowPart
& lower_mask
);
757 r
.u
.LowPart
+= (t
& lower_mask
) << bits_in_word_2
;
758 r
.u
.HighPart
= t
>> bits_in_word_2
;
759 t
= r
.u
.LowPart
>> bits_in_word_2
;
760 r
.u
.LowPart
&= lower_mask
;
761 t
+= (y
.u
.LowPart
>> bits_in_word_2
) * (x
.u
.LowPart
& lower_mask
);
762 r
.u
.LowPart
+= (t
& lower_mask
) << bits_in_word_2
;
763 r
.u
.HighPart
+= t
>> bits_in_word_2
;
764 r
.u
.HighPart
+= (x
.u
.LowPart
>> bits_in_word_2
) * (y
.u
.LowPart
>> bits_in_word_2
);
766 r
.u
.HighPart
+= x
.u
.HighPart
* y
.u
.LowPart
+ x
.u
.LowPart
* y
.u
.HighPart
;
771 /******************************************************************************
774 * Calculate the remainder after dividing two 64 bit integers.
777 * a [I] Initial number.
778 * b [I] Number to divide a by.
781 * The remainder of a divided by b.
783 LONGLONG WINAPI
_allrem( LONGLONG a
, LONGLONG b
)
785 LONGLONG s
= b
>> 63; /* s = b < 0 ? -1 : 0 */
787 b
= (b
^ s
) - s
; /* negate if s == -1 */
788 s
= a
>> 63; /* s = a < 0 ? -1 : 0 */
789 a
= (a
^ s
) - s
; /* negate if s == -1 */
791 return ((LONGLONG
)r
^ s
) - s
; /* negate if s == -1 */
795 /******************************************************************************
798 * Divide two 64 bit unsigned integers.
801 * a [I] Initial number.
802 * b [I] Number to divide a by.
805 * The dividend of a and b.
807 ULONGLONG WINAPI
_aulldiv( ULONGLONG a
, ULONGLONG b
)
809 return udivmod(a
, b
, NULL
);
812 /******************************************************************************
815 * Shift a 64 bit integer to the left.
818 * a [I] Initial number.
819 * b [I] Number to shift a by to the left.
822 * The left-shifted value.
824 LONGLONG WINAPI
_allshl( LONGLONG a
, LONG b
)
829 /******************************************************************************
832 * Shift a 64 bit integer to the right.
835 * a [I] Initial number.
836 * b [I] Number to shift a by to the right.
839 * The right-shifted value.
841 LONGLONG WINAPI
_allshr( LONGLONG a
, LONG b
)
846 /******************************************************************************
849 * Divide two 64 bit integers.
852 * a [I] Initial number.
853 * b [I] Number to divide a by.
856 * Returns the quotient of a and b in edx:eax.
857 * Returns the remainder of a and b in ebx:ecx.
859 __ASM_GLOBAL_FUNC( _alldvrm
,
861 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
862 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
864 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
869 "call " __ASM_NAME("_allrem") "\n\t"
876 "call " __ASM_NAME("_alldiv") "\n\t"
879 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
880 __ASM_CFI(".cfi_same_value %ebp\n\t")
883 /******************************************************************************
886 * Calculate the remainder after dividing two 64 bit unsigned integers.
889 * a [I] Initial number.
890 * b [I] Number to divide a by.
893 * The remainder of a divided by b.
895 ULONGLONG WINAPI
_aullrem( ULONGLONG a
, ULONGLONG b
)
902 /******************************************************************************
905 * Shift a 64 bit unsigned integer to the right.
908 * a [I] Initial number.
909 * b [I] Number to shift a by to the right.
912 * The right-shifted value.
914 ULONGLONG WINAPI
_aullshr( ULONGLONG a
, LONG b
)
919 /******************************************************************************
920 * _aulldvrm (NTDLL.@)
922 * Divide two 64 bit unsigned integers.
925 * a [I] Initial number.
926 * b [I] Number to divide a by.
929 * Returns the quotient of a and b in edx:eax.
930 * Returns the remainder of a and b in ebx:ecx.
932 __ASM_GLOBAL_FUNC( _aulldvrm
,
934 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
935 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
937 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
942 "call " __ASM_NAME("_aullrem") "\n\t"
949 "call " __ASM_NAME("_aulldiv") "\n\t"
952 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
953 __ASM_CFI(".cfi_same_value %ebp\n\t")
956 #endif /* __i386__ */