2 * Large integer functions
4 * Copyright 2000 Alexandre Julliard
11 * Note: we use LONGLONG instead of LARGE_INTEGER, because
12 * the latter is a structure and the calling convention for
13 * returning a structure would not be binary-compatible.
15 * FIXME: for platforms that don't have a native LONGLONG type,
16 * we should define LONGLONG as a structure similar to LARGE_INTEGER
17 * and do everything by hand. You are welcome to do it...
20 /******************************************************************************
21 * RtlLargeIntegerAdd (NTDLL.@)
23 LONGLONG WINAPI
RtlLargeIntegerAdd( LONGLONG a
, LONGLONG b
)
29 /******************************************************************************
30 * RtlLargeIntegerSubtract (NTDLL.@)
32 LONGLONG WINAPI
RtlLargeIntegerSubtract( LONGLONG a
, LONGLONG b
)
38 /******************************************************************************
39 * RtlLargeIntegerNegate (NTDLL.@)
41 LONGLONG WINAPI
RtlLargeIntegerNegate( LONGLONG a
)
47 /******************************************************************************
48 * RtlLargeIntegerShiftLeft (NTDLL.@)
50 LONGLONG WINAPI
RtlLargeIntegerShiftLeft( LONGLONG a
, INT count
)
56 /******************************************************************************
57 * RtlLargeIntegerShiftRight (NTDLL.@)
59 LONGLONG WINAPI
RtlLargeIntegerShiftRight( LONGLONG a
, INT count
)
61 return (ULONGLONG
)a
>> count
;
65 /******************************************************************************
66 * RtlLargeIntegerArithmeticShift (NTDLL.@)
68 LONGLONG WINAPI
RtlLargeIntegerArithmeticShift( LONGLONG a
, INT count
)
70 /* FIXME: gcc does arithmetic shift here, but it may not be true on all platforms */
75 /******************************************************************************
76 * RtlLargeIntegerDivide (NTDLL.@)
78 * FIXME: should it be signed division instead?
80 ULONGLONG WINAPI
RtlLargeIntegerDivide( ULONGLONG a
, ULONGLONG b
, ULONGLONG
*rem
)
82 ULONGLONG ret
= a
/ b
;
83 if (rem
) *rem
= a
- ret
* b
;
88 /******************************************************************************
89 * RtlConvertLongToLargeInteger (NTDLL.@)
91 LONGLONG WINAPI
RtlConvertLongToLargeInteger( LONG a
)
97 /******************************************************************************
98 * RtlConvertUlongToLargeInteger (NTDLL.@)
100 ULONGLONG WINAPI
RtlConvertUlongToLargeInteger( ULONG a
)
106 /******************************************************************************
107 * RtlEnlargedIntegerMultiply (NTDLL.@)
109 LONGLONG WINAPI
RtlEnlargedIntegerMultiply( INT a
, INT b
)
111 return (LONGLONG
)a
* b
;
115 /******************************************************************************
116 * RtlEnlargedUnsignedMultiply (NTDLL.@)
118 ULONGLONG WINAPI
RtlEnlargedUnsignedMultiply( UINT a
, UINT b
)
120 return (ULONGLONG
)a
* b
;
124 /******************************************************************************
125 * RtlEnlargedUnsignedDivide (NTDLL.@)
127 UINT WINAPI
RtlEnlargedUnsignedDivide( ULONGLONG a
, UINT b
, UINT
*remptr
)
129 #if defined(__i386__) && defined(__GNUC__)
131 __asm__("div %4,%%eax"
132 : "=a" (ret
), "=d" (rem
)
133 : "0" (*(UINT
*)&a
), "1" (*((UINT
*)&a
+1)), "g" (b
) );
134 if (remptr
) *remptr
= rem
;
138 if (remptr
) *remptr
= a
% b
;
144 /******************************************************************************
145 * RtlExtendedLargeIntegerDivide (NTDLL.@)
147 LONGLONG WINAPI
RtlExtendedLargeIntegerDivide( LONGLONG a
, INT b
, INT
*rem
)
149 LONGLONG ret
= a
/ b
;
150 if (rem
) *rem
= a
- b
* ret
;
155 /******************************************************************************
156 * RtlExtendedIntegerMultiply (NTDLL.@)
158 LONGLONG WINAPI
RtlExtendedIntegerMultiply( LONGLONG a
, INT b
)
164 /******************************************************************************
165 * RtlExtendedMagicDivide (NTDLL.@)
167 * This function computes (a * b) >> (64 + shift)
169 * This allows replacing a division by a longlong constant
170 * by a multiplication by the inverse constant.
172 * If 'c' is the constant divisor, the constants 'b' and 'shift'
173 * must be chosen such that b = 2^(64+shift) / c.
174 * Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
176 * I'm too lazy to implement it right now...
178 /* LONGLONG WINAPI RtlExtendedMagicDivide( LONGLONG a, LONGLONG b, INT shift )
185 /******************************************************************************
188 LONGLONG WINAPI
_alldiv( LONGLONG a
, LONGLONG b
)
194 /******************************************************************************
197 LONGLONG WINAPI
_allmul( LONGLONG a
, LONGLONG b
)
203 /******************************************************************************
206 LONGLONG WINAPI
_allrem( LONGLONG a
, LONGLONG b
)
212 /******************************************************************************
215 ULONGLONG WINAPI
_aulldiv( ULONGLONG a
, ULONGLONG b
)
221 /******************************************************************************
224 ULONGLONG WINAPI
_aullrem( ULONGLONG a
, ULONGLONG b
)