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__)
144 UINT ret, rem, p1, p2;
147 p2 = a & 0xffffffffLL;
149 __asm__("div %4,%%eax"
150 : "=a" (ret), "=d" (rem)
151 : "0" (p2), "1" (p1), "g" (b) );
152 if (remptr) *remptr = rem;
156 if (remptr) *remptr = a % b;
162 /******************************************************************************
163 * RtlExtendedLargeIntegerDivide (NTDLL.@)
165 LONGLONG WINAPI RtlExtendedLargeIntegerDivide( LONGLONG a, INT b, INT *rem )
167 LONGLONG ret = a / b;
168 if (rem) *rem = a - b * ret;
173 /******************************************************************************
174 * RtlExtendedIntegerMultiply (NTDLL.@)
176 LONGLONG WINAPI RtlExtendedIntegerMultiply( LONGLONG a, INT b )
182 /******************************************************************************
183 * RtlExtendedMagicDivide (NTDLL.@)
185 * This function computes (a * b) >> (64 + shift)
187 * This allows replacing a division by a longlong constant
188 * by a multiplication by the inverse constant.
190 * If 'c' is the constant divisor, the constants 'b' and 'shift'
191 * must be chosen such that b = 2^(64+shift) / c.
192 * Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
194 * I'm too lazy to implement it right now...
196 /* LONGLONG WINAPI RtlExtendedMagicDivide( LONGLONG a, LONGLONG b, INT shift )
203 /******************************************************************************
206 LONGLONG WINAPI _alldiv( LONGLONG a, LONGLONG b )
212 /******************************************************************************
215 LONGLONG WINAPI _allmul( LONGLONG a, LONGLONG b )
221 /******************************************************************************
224 LONGLONG WINAPI _allrem( LONGLONG a, LONGLONG b )
230 /******************************************************************************
233 ULONGLONG WINAPI _aulldiv( ULONGLONG a, ULONGLONG b )
239 /******************************************************************************
242 ULONGLONG WINAPI _aullrem( ULONGLONG a, ULONGLONG b )