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