Line data Source code
1 : /* cairo - a vector graphics library with display and print output
2 : *
3 : * Copyright © 2004 Keith Packard
4 : *
5 : * This library is free software; you can redistribute it and/or
6 : * modify it either under the terms of the GNU Lesser General Public
7 : * License version 2.1 as published by the Free Software Foundation
8 : * (the "LGPL") or, at your option, under the terms of the Mozilla
9 : * Public License Version 1.1 (the "MPL"). If you do not alter this
10 : * notice, a recipient may use your version of this file under either
11 : * the MPL or the LGPL.
12 : *
13 : * You should have received a copy of the LGPL along with this library
14 : * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 : * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16 : * You should have received a copy of the MPL along with this library
17 : * in the file COPYING-MPL-1.1
18 : *
19 : * The contents of this file are subject to the Mozilla Public License
20 : * Version 1.1 (the "License"); you may not use this file except in
21 : * compliance with the License. You may obtain a copy of the License at
22 : * http://www.mozilla.org/MPL/
23 : *
24 : * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 : * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 : * the specific language governing rights and limitations.
27 : *
28 : * The Original Code is the cairo graphics library.
29 : *
30 : * The Initial Developer of the Original Code is Keith Packard
31 : *
32 : * Contributor(s):
33 : * Keith R. Packard <keithp@keithp.com>
34 : *
35 : */
36 :
37 : #ifndef CAIRO_WIDEINT_H
38 : #define CAIRO_WIDEINT_H
39 :
40 : #include "cairo-wideint-type-private.h"
41 :
42 : #include "cairo-compiler-private.h"
43 :
44 : /*
45 : * 64-bit datatypes. Two separate implementations, one using
46 : * built-in 64-bit signed/unsigned types another implemented
47 : * as a pair of 32-bit ints
48 : */
49 :
50 : #define I cairo_private cairo_const
51 :
52 : #if !HAVE_UINT64_T
53 :
54 : cairo_uquorem64_t I
55 : _cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den);
56 :
57 : cairo_uint64_t I _cairo_uint32_to_uint64 (uint32_t i);
58 : #define _cairo_uint64_to_uint32(a) ((a).lo)
59 : cairo_uint64_t I _cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b);
60 : cairo_uint64_t I _cairo_uint64_sub (cairo_uint64_t a, cairo_uint64_t b);
61 : cairo_uint64_t I _cairo_uint64_mul (cairo_uint64_t a, cairo_uint64_t b);
62 : cairo_uint64_t I _cairo_uint32x32_64_mul (uint32_t a, uint32_t b);
63 : cairo_uint64_t I _cairo_uint64_lsl (cairo_uint64_t a, int shift);
64 : cairo_uint64_t I _cairo_uint64_rsl (cairo_uint64_t a, int shift);
65 : cairo_uint64_t I _cairo_uint64_rsa (cairo_uint64_t a, int shift);
66 : int I _cairo_uint64_lt (cairo_uint64_t a, cairo_uint64_t b);
67 : int I _cairo_uint64_cmp (cairo_uint64_t a, cairo_uint64_t b);
68 : int I _cairo_uint64_eq (cairo_uint64_t a, cairo_uint64_t b);
69 : cairo_uint64_t I _cairo_uint64_negate (cairo_uint64_t a);
70 : #define _cairo_uint64_is_zero(a) ((a).hi == 0 && (a).lo == 0)
71 : #define _cairo_uint64_negative(a) (((int32_t) ((a).hi)) < 0)
72 : cairo_uint64_t I _cairo_uint64_not (cairo_uint64_t a);
73 :
74 : #define _cairo_uint64_to_int64(i) (i)
75 : #define _cairo_int64_to_uint64(i) (i)
76 :
77 : cairo_int64_t I _cairo_int32_to_int64(int32_t i);
78 : #define _cairo_int64_to_int32(a) ((int32_t) _cairo_uint64_to_uint32(a))
79 : #define _cairo_int64_add(a,b) _cairo_uint64_add (a,b)
80 : #define _cairo_int64_sub(a,b) _cairo_uint64_sub (a,b)
81 : #define _cairo_int64_mul(a,b) _cairo_uint64_mul (a,b)
82 : cairo_int64_t I _cairo_int32x32_64_mul (int32_t a, int32_t b);
83 : int I _cairo_int64_lt (cairo_int64_t a, cairo_int64_t b);
84 : int I _cairo_int64_cmp (cairo_int64_t a, cairo_int64_t b);
85 : #define _cairo_int64_is_zero(a) _cairo_uint64_is_zero (a)
86 : #define _cairo_int64_eq(a,b) _cairo_uint64_eq (a,b)
87 : #define _cairo_int64_lsl(a,b) _cairo_uint64_lsl (a,b)
88 : #define _cairo_int64_rsl(a,b) _cairo_uint64_rsl (a,b)
89 : #define _cairo_int64_rsa(a,b) _cairo_uint64_rsa (a,b)
90 : #define _cairo_int64_negate(a) _cairo_uint64_negate(a)
91 : #define _cairo_int64_negative(a) (((int32_t) ((a).hi)) < 0)
92 : #define _cairo_int64_not(a) _cairo_uint64_not(a)
93 :
94 : #else
95 :
96 : static inline cairo_uquorem64_t
97 0 : _cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den)
98 : {
99 : cairo_uquorem64_t qr;
100 :
101 0 : qr.quo = num / den;
102 0 : qr.rem = num % den;
103 0 : return qr;
104 : }
105 :
106 : #define _cairo_uint32_to_uint64(i) ((uint64_t) (i))
107 : #define _cairo_uint64_to_uint32(i) ((uint32_t) (i))
108 : #define _cairo_uint64_add(a,b) ((a) + (b))
109 : #define _cairo_uint64_sub(a,b) ((a) - (b))
110 : #define _cairo_uint64_mul(a,b) ((a) * (b))
111 : #define _cairo_uint32x32_64_mul(a,b) ((uint64_t) (a) * (b))
112 : #define _cairo_uint64_lsl(a,b) ((a) << (b))
113 : #define _cairo_uint64_rsl(a,b) ((uint64_t) (a) >> (b))
114 : #define _cairo_uint64_rsa(a,b) ((uint64_t) ((int64_t) (a) >> (b)))
115 : #define _cairo_uint64_lt(a,b) ((a) < (b))
116 : #define _cairo_uint64_cmp(a,b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1)
117 : #define _cairo_uint64_is_zero(a) ((a) == 0)
118 : #define _cairo_uint64_eq(a,b) ((a) == (b))
119 : #define _cairo_uint64_negate(a) ((uint64_t) -((int64_t) (a)))
120 : #define _cairo_uint64_negative(a) ((int64_t) (a) < 0)
121 : #define _cairo_uint64_not(a) (~(a))
122 :
123 : #define _cairo_uint64_to_int64(i) ((int64_t) (i))
124 : #define _cairo_int64_to_uint64(i) ((uint64_t) (i))
125 :
126 : #define _cairo_int32_to_int64(i) ((int64_t) (i))
127 : #define _cairo_int64_to_int32(i) ((int32_t) (i))
128 : #define _cairo_int64_add(a,b) ((a) + (b))
129 : #define _cairo_int64_sub(a,b) ((a) - (b))
130 : #define _cairo_int64_mul(a,b) ((a) * (b))
131 : #define _cairo_int32x32_64_mul(a,b) ((int64_t) (a) * (b))
132 : #define _cairo_int64_lt(a,b) ((a) < (b))
133 : #define _cairo_int64_cmp(a,b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1)
134 : #define _cairo_int64_is_zero(a) ((a) == 0)
135 : #define _cairo_int64_eq(a,b) ((a) == (b))
136 : #define _cairo_int64_lsl(a,b) ((a) << (b))
137 : #define _cairo_int64_rsl(a,b) ((int64_t) ((uint64_t) (a) >> (b)))
138 : #define _cairo_int64_rsa(a,b) ((int64_t) (a) >> (b))
139 : #define _cairo_int64_negate(a) (-(a))
140 : #define _cairo_int64_negative(a) ((a) < 0)
141 : #define _cairo_int64_not(a) (~(a))
142 :
143 : #endif
144 :
145 : /*
146 : * 64-bit comparisions derived from lt or eq
147 : */
148 : #define _cairo_uint64_le(a,b) (!_cairo_uint64_gt(a,b))
149 : #define _cairo_uint64_ne(a,b) (!_cairo_uint64_eq(a,b))
150 : #define _cairo_uint64_ge(a,b) (!_cairo_uint64_lt(a,b))
151 : #define _cairo_uint64_gt(a,b) _cairo_uint64_lt(b,a)
152 :
153 : #define _cairo_int64_le(a,b) (!_cairo_int64_gt(a,b))
154 : #define _cairo_int64_ne(a,b) (!_cairo_int64_eq(a,b))
155 : #define _cairo_int64_ge(a,b) (!_cairo_int64_lt(a,b))
156 : #define _cairo_int64_gt(a,b) _cairo_int64_lt(b,a)
157 :
158 : /*
159 : * As the C implementation always computes both, create
160 : * a function which returns both for the 'native' type as well
161 : */
162 :
163 : static inline cairo_quorem64_t
164 : _cairo_int64_divrem (cairo_int64_t num, cairo_int64_t den)
165 : {
166 : int num_neg = _cairo_int64_negative (num);
167 : int den_neg = _cairo_int64_negative (den);
168 : cairo_uquorem64_t uqr;
169 : cairo_quorem64_t qr;
170 :
171 : if (num_neg)
172 : num = _cairo_int64_negate (num);
173 : if (den_neg)
174 : den = _cairo_int64_negate (den);
175 : uqr = _cairo_uint64_divrem (num, den);
176 : if (num_neg)
177 : qr.rem = _cairo_int64_negate (uqr.rem);
178 : else
179 : qr.rem = uqr.rem;
180 : if (num_neg != den_neg)
181 : qr.quo = (cairo_int64_t) _cairo_int64_negate (uqr.quo);
182 : else
183 : qr.quo = (cairo_int64_t) uqr.quo;
184 : return qr;
185 : }
186 :
187 : static inline int32_t
188 0 : _cairo_int64_32_div (cairo_int64_t num, int32_t den)
189 : {
190 : #if !HAVE_UINT64_T
191 : return _cairo_int64_to_int32
192 : (_cairo_int64_divrem (num, _cairo_int32_to_int64 (den)).quo);
193 : #else
194 0 : return num / den;
195 : #endif
196 : }
197 :
198 : /*
199 : * 128-bit datatypes. Again, provide two implementations in
200 : * case the machine has a native 128-bit datatype. GCC supports int128_t
201 : * on ia64
202 : */
203 :
204 : #if !HAVE_UINT128_T
205 :
206 : cairo_uint128_t I _cairo_uint32_to_uint128 (uint32_t i);
207 : cairo_uint128_t I _cairo_uint64_to_uint128 (cairo_uint64_t i);
208 : #define _cairo_uint128_to_uint64(a) ((a).lo)
209 : #define _cairo_uint128_to_uint32(a) _cairo_uint64_to_uint32(_cairo_uint128_to_uint64(a))
210 : cairo_uint128_t I _cairo_uint128_add (cairo_uint128_t a, cairo_uint128_t b);
211 : cairo_uint128_t I _cairo_uint128_sub (cairo_uint128_t a, cairo_uint128_t b);
212 : cairo_uint128_t I _cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b);
213 : cairo_uint128_t I _cairo_uint64x64_128_mul (cairo_uint64_t a, cairo_uint64_t b);
214 : cairo_uint128_t I _cairo_uint128_lsl (cairo_uint128_t a, int shift);
215 : cairo_uint128_t I _cairo_uint128_rsl (cairo_uint128_t a, int shift);
216 : cairo_uint128_t I _cairo_uint128_rsa (cairo_uint128_t a, int shift);
217 : int I _cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b);
218 : int I _cairo_uint128_cmp (cairo_uint128_t a, cairo_uint128_t b);
219 : int I _cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b);
220 : #define _cairo_uint128_is_zero(a) (_cairo_uint64_is_zero ((a).hi) && _cairo_uint64_is_zero ((a).lo))
221 : cairo_uint128_t I _cairo_uint128_negate (cairo_uint128_t a);
222 : #define _cairo_uint128_negative(a) (_cairo_uint64_negative(a.hi))
223 : cairo_uint128_t I _cairo_uint128_not (cairo_uint128_t a);
224 :
225 : #define _cairo_uint128_to_int128(i) (i)
226 : #define _cairo_int128_to_uint128(i) (i)
227 :
228 : cairo_int128_t I _cairo_int32_to_int128 (int32_t i);
229 : cairo_int128_t I _cairo_int64_to_int128 (cairo_int64_t i);
230 : #define _cairo_int128_to_int64(a) ((cairo_int64_t) (a).lo)
231 : #define _cairo_int128_to_int32(a) _cairo_int64_to_int32(_cairo_int128_to_int64(a))
232 : #define _cairo_int128_add(a,b) _cairo_uint128_add(a,b)
233 : #define _cairo_int128_sub(a,b) _cairo_uint128_sub(a,b)
234 : #define _cairo_int128_mul(a,b) _cairo_uint128_mul(a,b)
235 : cairo_int128_t I _cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b);
236 : #define _cairo_int64x32_128_mul(a, b) _cairo_int64x64_128_mul(a, _cairo_int32_to_int64(b))
237 : #define _cairo_int128_lsl(a,b) _cairo_uint128_lsl(a,b)
238 : #define _cairo_int128_rsl(a,b) _cairo_uint128_rsl(a,b)
239 : #define _cairo_int128_rsa(a,b) _cairo_uint128_rsa(a,b)
240 : int I _cairo_int128_lt (cairo_int128_t a, cairo_int128_t b);
241 : int I _cairo_int128_cmp (cairo_int128_t a, cairo_int128_t b);
242 : #define _cairo_int128_is_zero(a) _cairo_uint128_is_zero (a)
243 : #define _cairo_int128_eq(a,b) _cairo_uint128_eq (a,b)
244 : #define _cairo_int128_negate(a) _cairo_uint128_negate(a)
245 : #define _cairo_int128_negative(a) (_cairo_uint128_negative(a))
246 : #define _cairo_int128_not(a) _cairo_uint128_not(a)
247 :
248 : #else /* !HAVE_UINT128_T */
249 :
250 : #define _cairo_uint32_to_uint128(i) ((uint128_t) (i))
251 : #define _cairo_uint64_to_uint128(i) ((uint128_t) (i))
252 : #define _cairo_uint128_to_uint64(i) ((uint64_t) (i))
253 : #define _cairo_uint128_to_uint32(i) ((uint32_t) (i))
254 : #define _cairo_uint128_add(a,b) ((a) + (b))
255 : #define _cairo_uint128_sub(a,b) ((a) - (b))
256 : #define _cairo_uint128_mul(a,b) ((a) * (b))
257 : #define _cairo_uint64x64_128_mul(a,b) ((uint128_t) (a) * (b))
258 : #define _cairo_uint128_lsl(a,b) ((a) << (b))
259 : #define _cairo_uint128_rsl(a,b) ((uint128_t) (a) >> (b))
260 : #define _cairo_uint128_rsa(a,b) ((uint128_t) ((int128_t) (a) >> (b)))
261 : #define _cairo_uint128_lt(a,b) ((a) < (b))
262 : #define _cairo_uint128_cmp(a,b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1)
263 : #define _cairo_uint128_is_zero(a) ((a) == 0)
264 : #define _cairo_uint128_eq(a,b) ((a) == (b))
265 : #define _cairo_uint128_negate(a) ((uint128_t) -((int128_t) (a)))
266 : #define _cairo_uint128_negative(a) ((int128_t) (a) < 0)
267 : #define _cairo_uint128_not(a) (~(a))
268 :
269 : #define _cairo_uint128_to_int128(i) ((int128_t) (i))
270 : #define _cairo_int128_to_uint128(i) ((uint128_t) (i))
271 :
272 : #define _cairo_int32_to_int128(i) ((int128_t) (i))
273 : #define _cairo_int64_to_int128(i) ((int128_t) (i))
274 : #define _cairo_int128_to_int64(i) ((int64_t) (i))
275 : #define _cairo_int128_to_int32(i) ((int32_t) (i))
276 : #define _cairo_int128_add(a,b) ((a) + (b))
277 : #define _cairo_int128_sub(a,b) ((a) - (b))
278 : #define _cairo_int128_mul(a,b) ((a) * (b))
279 : #define _cairo_int64x64_128_mul(a,b) ((int128_t) (a) * (b))
280 : #define _cairo_int64x32_128_mul(a, b) _cairo_int64x64_128_mul(a, _cairo_int32_to_int64(b))
281 : #define _cairo_int128_lt(a,b) ((a) < (b))
282 : #define _cairo_int128_cmp(a,b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1)
283 : #define _cairo_int128_is_zero(a) ((a) == 0)
284 : #define _cairo_int128_eq(a,b) ((a) == (b))
285 : #define _cairo_int128_lsl(a,b) ((a) << (b))
286 : #define _cairo_int128_rsl(a,b) ((int128_t) ((uint128_t) (a) >> (b)))
287 : #define _cairo_int128_rsa(a,b) ((int128_t) (a) >> (b))
288 : #define _cairo_int128_negate(a) (-(a))
289 : #define _cairo_int128_negative(a) ((a) < 0)
290 : #define _cairo_int128_not(a) (~(a))
291 :
292 : #endif /* HAVE_UINT128_T */
293 :
294 : cairo_uquorem128_t I
295 : _cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den);
296 :
297 : cairo_quorem128_t I
298 : _cairo_int128_divrem (cairo_int128_t num, cairo_int128_t den);
299 :
300 : cairo_uquorem64_t I
301 : _cairo_uint_96by64_32x64_divrem (cairo_uint128_t num,
302 : cairo_uint64_t den);
303 :
304 : cairo_quorem64_t I
305 : _cairo_int_96by64_32x64_divrem (cairo_int128_t num,
306 : cairo_int64_t den);
307 :
308 : #define _cairo_uint128_le(a,b) (!_cairo_uint128_gt(a,b))
309 : #define _cairo_uint128_ne(a,b) (!_cairo_uint128_eq(a,b))
310 : #define _cairo_uint128_ge(a,b) (!_cairo_uint128_lt(a,b))
311 : #define _cairo_uint128_gt(a,b) _cairo_uint128_lt(b,a)
312 :
313 : #define _cairo_int128_le(a,b) (!_cairo_int128_gt(a,b))
314 : #define _cairo_int128_ne(a,b) (!_cairo_int128_eq(a,b))
315 : #define _cairo_int128_ge(a,b) (!_cairo_int128_lt(a,b))
316 : #define _cairo_int128_gt(a,b) _cairo_int128_lt(b,a)
317 :
318 : #undef I
319 :
320 : #endif /* CAIRO_WIDEINT_H */
|