More comcat.dll implementation, swprintf fix, winerror.h additions.
[wine] / dlls / ntdll / large_int.c
1 /*
2  * Large integer functions
3  *
4  * Copyright 2000 Alexandre Julliard
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "winnt.h"
22 #include "ntddk.h"
23
24 /*
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.
28  *
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...
32  */
33
34 /******************************************************************************
35  *        RtlLargeIntegerAdd   (NTDLL.@)
36  */
37 LONGLONG WINAPI RtlLargeIntegerAdd( LONGLONG a, LONGLONG b )
38 {
39     return a + b;
40 }
41
42
43 /******************************************************************************
44  *        RtlLargeIntegerSubtract   (NTDLL.@)
45  */
46 LONGLONG WINAPI RtlLargeIntegerSubtract( LONGLONG a, LONGLONG b )
47 {
48     return a - b;
49 }
50
51
52 /******************************************************************************
53  *        RtlLargeIntegerNegate   (NTDLL.@)
54  */
55 LONGLONG WINAPI RtlLargeIntegerNegate( LONGLONG a )
56 {
57     return -a;
58 }
59
60
61 /******************************************************************************
62  *        RtlLargeIntegerShiftLeft   (NTDLL.@)
63  */
64 LONGLONG WINAPI RtlLargeIntegerShiftLeft( LONGLONG a, INT count )
65 {
66     return a << count;
67 }
68
69
70 /******************************************************************************
71  *        RtlLargeIntegerShiftRight   (NTDLL.@)
72  */
73 LONGLONG WINAPI RtlLargeIntegerShiftRight( LONGLONG a, INT count )
74 {
75     return (ULONGLONG)a >> count;
76 }
77
78
79 /******************************************************************************
80  *        RtlLargeIntegerArithmeticShift   (NTDLL.@)
81  */
82 LONGLONG WINAPI RtlLargeIntegerArithmeticShift( LONGLONG a, INT count )
83 {
84     /* FIXME: gcc does arithmetic shift here, but it may not be true on all platforms */
85     return a >> count;
86 }
87
88
89 /******************************************************************************
90  *        RtlLargeIntegerDivide   (NTDLL.@)
91  *
92  * FIXME: should it be signed division instead?
93  */
94 ULONGLONG WINAPI RtlLargeIntegerDivide( ULONGLONG a, ULONGLONG b, ULONGLONG *rem )
95 {
96     ULONGLONG ret = a / b;
97     if (rem) *rem = a - ret * b;
98     return ret;
99 }
100
101
102 /******************************************************************************
103  *        RtlConvertLongToLargeInteger   (NTDLL.@)
104  */
105 LONGLONG WINAPI RtlConvertLongToLargeInteger( LONG a )
106 {
107     return a;
108 }
109
110
111 /******************************************************************************
112  *        RtlConvertUlongToLargeInteger   (NTDLL.@)
113  */
114 ULONGLONG WINAPI RtlConvertUlongToLargeInteger( ULONG a )
115 {
116     return a;
117 }
118
119
120 /******************************************************************************
121  *        RtlEnlargedIntegerMultiply   (NTDLL.@)
122  */
123 LONGLONG WINAPI RtlEnlargedIntegerMultiply( INT a, INT b )
124 {
125     return (LONGLONG)a * b;
126 }
127
128
129 /******************************************************************************
130  *        RtlEnlargedUnsignedMultiply   (NTDLL.@)
131  */
132 ULONGLONG WINAPI RtlEnlargedUnsignedMultiply( UINT a, UINT b )
133 {
134     return (ULONGLONG)a * b;
135 }
136
137
138 /******************************************************************************
139  *        RtlEnlargedUnsignedDivide   (NTDLL.@)
140  */
141 UINT WINAPI RtlEnlargedUnsignedDivide( ULONGLONG a, UINT b, UINT *remptr )
142 {
143 #if defined(__i386__) && defined(__GNUC__)
144     UINT ret, rem;
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;
149     return ret;
150 #else
151     UINT ret = a / b;
152     if (remptr) *remptr = a % b;
153     return ret;
154 #endif
155 }
156
157
158 /******************************************************************************
159  *        RtlExtendedLargeIntegerDivide   (NTDLL.@)
160  */
161 LONGLONG WINAPI RtlExtendedLargeIntegerDivide( LONGLONG a, INT b, INT *rem )
162 {
163     LONGLONG ret = a / b;
164     if (rem) *rem = a - b * ret;
165     return ret;
166 }
167
168
169 /******************************************************************************
170  *        RtlExtendedIntegerMultiply   (NTDLL.@)
171  */
172 LONGLONG WINAPI RtlExtendedIntegerMultiply( LONGLONG a, INT b )
173 {
174     return a * b;
175 }
176
177
178 /******************************************************************************
179  *        RtlExtendedMagicDivide   (NTDLL.@)
180  *
181  * This function computes (a * b) >> (64 + shift)
182  *
183  * This allows replacing a division by a longlong constant
184  * by a multiplication by the inverse constant.
185  *
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.
189  *
190  * I'm too lazy to implement it right now...
191  */
192 /* LONGLONG WINAPI RtlExtendedMagicDivide( LONGLONG a, LONGLONG b, INT shift )
193  * {
194  *     return 0;
195  * }
196  */
197
198
199 /******************************************************************************
200  *        _alldiv   (NTDLL.@)
201  */
202 LONGLONG WINAPI _alldiv( LONGLONG a, LONGLONG b )
203 {
204     return a / b;
205 }
206
207
208 /******************************************************************************
209  *        _allmul   (NTDLL.@)
210  */
211 LONGLONG WINAPI _allmul( LONGLONG a, LONGLONG b )
212 {
213     return a * b;
214 }
215
216
217 /******************************************************************************
218  *        _allrem   (NTDLL.@)
219  */
220 LONGLONG WINAPI _allrem( LONGLONG a, LONGLONG b )
221 {
222     return a % b;
223 }
224
225
226 /******************************************************************************
227  *        _aulldiv   (NTDLL.@)
228  */
229 ULONGLONG WINAPI _aulldiv( ULONGLONG a, ULONGLONG b )
230 {
231     return a / b;
232 }
233
234
235 /******************************************************************************
236  *        _aullrem   (NTDLL.@)
237  */
238 ULONGLONG WINAPI _aullrem( ULONGLONG a, ULONGLONG b )
239 {
240     return a % b;
241 }