2 * Large integer functions
4 * Copyright 2000 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Note: we use LONGLONG instead of LARGE_INTEGER, because
26 * the latter is a structure and the calling convention for
27 * returning a structure would not be binary-compatible.
29 * FIXME: for platforms that don't have a native LONGLONG type,
30 * we should define LONGLONG as a structure similar to LARGE_INTEGER
31 * and do everything by hand. You are welcome to do it...
34 /******************************************************************************
35 * RtlLargeIntegerAdd (NTDLL.@)
37 LONGLONG WINAPI
RtlLargeIntegerAdd( LONGLONG a
, LONGLONG b
)
43 /******************************************************************************
44 * RtlLargeIntegerSubtract (NTDLL.@)
46 LONGLONG WINAPI
RtlLargeIntegerSubtract( LONGLONG a
, LONGLONG b
)
52 /******************************************************************************
53 * RtlLargeIntegerNegate (NTDLL.@)
55 LONGLONG WINAPI
RtlLargeIntegerNegate( LONGLONG a
)
61 /******************************************************************************
62 * RtlLargeIntegerShiftLeft (NTDLL.@)
64 LONGLONG WINAPI
RtlLargeIntegerShiftLeft( LONGLONG a
, INT count
)
70 /******************************************************************************
71 * RtlLargeIntegerShiftRight (NTDLL.@)
73 LONGLONG WINAPI
RtlLargeIntegerShiftRight( LONGLONG a
, INT count
)
75 return (ULONGLONG
)a
>> count
;
79 /******************************************************************************
80 * RtlLargeIntegerArithmeticShift (NTDLL.@)
82 LONGLONG WINAPI
RtlLargeIntegerArithmeticShift( LONGLONG a
, INT count
)
84 /* FIXME: gcc does arithmetic shift here, but it may not be true on all platforms */
89 /******************************************************************************
90 * RtlLargeIntegerDivide (NTDLL.@)
92 * FIXME: should it be signed division instead?
94 ULONGLONG WINAPI
RtlLargeIntegerDivide( ULONGLONG a
, ULONGLONG b
, ULONGLONG
*rem
)
96 ULONGLONG ret
= a
/ b
;
97 if (rem
) *rem
= a
- ret
* b
;
102 /******************************************************************************
103 * RtlConvertLongToLargeInteger (NTDLL.@)
105 LONGLONG WINAPI
RtlConvertLongToLargeInteger( LONG a
)
111 /******************************************************************************
112 * RtlConvertUlongToLargeInteger (NTDLL.@)
114 ULONGLONG WINAPI
RtlConvertUlongToLargeInteger( ULONG a
)
120 /******************************************************************************
121 * RtlEnlargedIntegerMultiply (NTDLL.@)
123 LONGLONG WINAPI
RtlEnlargedIntegerMultiply( INT a
, INT b
)
125 return (LONGLONG
)a
* b
;
129 /******************************************************************************
130 * RtlEnlargedUnsignedMultiply (NTDLL.@)
132 ULONGLONG WINAPI
RtlEnlargedUnsignedMultiply( UINT a
, UINT b
)
134 return (ULONGLONG
)a
* b
;
138 /******************************************************************************
139 * RtlEnlargedUnsignedDivide (NTDLL.@)
141 UINT WINAPI
RtlEnlargedUnsignedDivide( ULONGLONG a
, UINT b
, UINT
*remptr
)
143 #if defined(__i386__) && defined(__GNUC__)
145 __asm__("div %4,%%eax"
146 : "=a" (ret
), "=d" (rem
)
147 : "0" (*(UINT
*)&a
), "1" (*((UINT
*)&a
+1)), "g" (b
) );
148 if (remptr
) *remptr
= rem
;
152 if (remptr
) *remptr
= a
% b
;
158 /******************************************************************************
159 * RtlExtendedLargeIntegerDivide (NTDLL.@)
161 LONGLONG WINAPI
RtlExtendedLargeIntegerDivide( LONGLONG a
, INT b
, INT
*rem
)
163 LONGLONG ret
= a
/ b
;
164 if (rem
) *rem
= a
- b
* ret
;
169 /******************************************************************************
170 * RtlExtendedIntegerMultiply (NTDLL.@)
172 LONGLONG WINAPI
RtlExtendedIntegerMultiply( LONGLONG a
, INT b
)
178 /******************************************************************************
179 * RtlExtendedMagicDivide (NTDLL.@)
181 * This function computes (a * b) >> (64 + shift)
183 * This allows replacing a division by a longlong constant
184 * by a multiplication by the inverse constant.
186 * If 'c' is the constant divisor, the constants 'b' and 'shift'
187 * must be chosen such that b = 2^(64+shift) / c.
188 * Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
190 * I'm too lazy to implement it right now...
192 /* LONGLONG WINAPI RtlExtendedMagicDivide( LONGLONG a, LONGLONG b, INT shift )
199 /******************************************************************************
202 LONGLONG WINAPI
_alldiv( LONGLONG a
, LONGLONG b
)
208 /******************************************************************************
211 LONGLONG WINAPI
_allmul( LONGLONG a
, LONGLONG b
)
217 /******************************************************************************
220 LONGLONG WINAPI
_allrem( LONGLONG a
, LONGLONG b
)
226 /******************************************************************************
229 ULONGLONG WINAPI
_aulldiv( ULONGLONG a
, ULONGLONG b
)
235 /******************************************************************************
238 ULONGLONG WINAPI
_aullrem( ULONGLONG a
, ULONGLONG b
)