- beginning of vertex matrix blending using extensions (currently
[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 "windef.h"
22 #include "winternl.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, p1, p2;
145
146     p1 = a >> 32;
147     p2 = a &  0xffffffffLL;
148
149     __asm__("div %4,%%eax"
150             : "=a" (ret), "=d" (rem)
151             : "0" (p2), "1" (p1), "g" (b) );
152     if (remptr) *remptr = rem;
153     return ret;
154 #else
155     UINT ret = a / b;
156     if (remptr) *remptr = a % b;
157     return ret;
158 #endif
159 }
160
161
162 /******************************************************************************
163  *        RtlExtendedLargeIntegerDivide   (NTDLL.@)
164  */
165 LONGLONG WINAPI RtlExtendedLargeIntegerDivide( LONGLONG a, INT b, INT *rem )
166 {
167     LONGLONG ret = a / b;
168     if (rem) *rem = a - b * ret;
169     return ret;
170 }
171
172
173 /******************************************************************************
174  *        RtlExtendedIntegerMultiply   (NTDLL.@)
175  */
176 LONGLONG WINAPI RtlExtendedIntegerMultiply( LONGLONG a, INT b )
177 {
178     return a * b;
179 }
180
181
182 /******************************************************************************
183  *        RtlExtendedMagicDivide   (NTDLL.@)
184  *
185  * This function computes (a * b) >> (64 + shift)
186  *
187  * This allows replacing a division by a longlong constant
188  * by a multiplication by the inverse constant.
189  *
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.
193  *
194  * I'm too lazy to implement it right now...
195  */
196 /* LONGLONG WINAPI RtlExtendedMagicDivide( LONGLONG a, LONGLONG b, INT shift )
197  * {
198  *     return 0;
199  * }
200  */
201
202
203 /******************************************************************************
204  *        _alldiv   (NTDLL.@)
205  */
206 LONGLONG WINAPI _alldiv( LONGLONG a, LONGLONG b )
207 {
208     return a / b;
209 }
210
211
212 /******************************************************************************
213  *        _allmul   (NTDLL.@)
214  */
215 LONGLONG WINAPI _allmul( LONGLONG a, LONGLONG b )
216 {
217     return a * b;
218 }
219
220
221 /******************************************************************************
222  *        _allrem   (NTDLL.@)
223  */
224 LONGLONG WINAPI _allrem( LONGLONG a, LONGLONG b )
225 {
226     return a % b;
227 }
228
229
230 /******************************************************************************
231  *        _aulldiv   (NTDLL.@)
232  */
233 ULONGLONG WINAPI _aulldiv( ULONGLONG a, ULONGLONG b )
234 {
235     return a / b;
236 }
237
238
239 /******************************************************************************
240  *        _aullrem   (NTDLL.@)
241  */
242 ULONGLONG WINAPI _aullrem( ULONGLONG a, ULONGLONG b )
243 {
244     return a % b;
245 }