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_double_to_uint64 (double i);
58
double	       I	_cairo_uint64_to_double (cairo_uint64_t i);
59
cairo_int64_t  I	_cairo_double_to_int64 (double i);
60
double	       I	_cairo_int64_to_double (cairo_uint64_t i);
61

            
62
cairo_uint64_t I	_cairo_uint32_to_uint64 (uint32_t i);
63
#define			_cairo_uint64_to_uint32(a)  ((a).lo)
64
cairo_uint64_t I	_cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b);
65
cairo_uint64_t I	_cairo_uint64_sub (cairo_uint64_t a, cairo_uint64_t b);
66
cairo_uint64_t I	_cairo_uint64_mul (cairo_uint64_t a, cairo_uint64_t b);
67
cairo_uint64_t I	_cairo_uint32x32_64_mul (uint32_t a, uint32_t b);
68
cairo_uint64_t I	_cairo_uint64_lsl (cairo_uint64_t a, int shift);
69
cairo_uint64_t I	_cairo_uint64_rsl (cairo_uint64_t a, int shift);
70
cairo_uint64_t I	_cairo_uint64_rsa (cairo_uint64_t a, int shift);
71
int	       I	_cairo_uint64_lt (cairo_uint64_t a, cairo_uint64_t b);
72
int	       I	_cairo_uint64_cmp (cairo_uint64_t a, cairo_uint64_t b);
73
int	       I	_cairo_uint64_eq (cairo_uint64_t a, cairo_uint64_t b);
74
cairo_uint64_t I	_cairo_uint64_negate (cairo_uint64_t a);
75
#define			_cairo_uint64_is_zero(a) ((a).hi == 0 && (a).lo == 0)
76
#define			_cairo_uint64_negative(a)   (((int32_t) ((a).hi)) < 0)
77
cairo_uint64_t I	_cairo_uint64_not (cairo_uint64_t a);
78

            
79
#define			_cairo_uint64_to_int64(i)   (i)
80
#define			_cairo_int64_to_uint64(i)   (i)
81

            
82
cairo_int64_t  I	_cairo_int32_to_int64(int32_t i);
83
#define			_cairo_int64_to_int32(a)    ((int32_t) _cairo_uint64_to_uint32(a))
84
#define			_cairo_int64_add(a,b)	    _cairo_uint64_add (a,b)
85
#define			_cairo_int64_sub(a,b)	    _cairo_uint64_sub (a,b)
86
#define			_cairo_int64_mul(a,b)	    _cairo_uint64_mul (a,b)
87
cairo_int64_t  I	_cairo_int32x32_64_mul (int32_t a, int32_t b);
88
int	       I	_cairo_int64_lt (cairo_int64_t a, cairo_int64_t b);
89
int	       I	_cairo_int64_cmp (cairo_int64_t a, cairo_int64_t b);
90
#define			_cairo_int64_is_zero(a)	    _cairo_uint64_is_zero (a)
91
#define			_cairo_int64_eq(a,b)	    _cairo_uint64_eq (a,b)
92
#define			_cairo_int64_lsl(a,b)	    _cairo_uint64_lsl (a,b)
93
#define			_cairo_int64_rsl(a,b)	    _cairo_uint64_rsl (a,b)
94
#define			_cairo_int64_rsa(a,b)	    _cairo_uint64_rsa (a,b)
95
#define			_cairo_int64_negate(a)	    _cairo_uint64_negate(a)
96
#define			_cairo_int64_negative(a)    (((int32_t) ((a).hi)) < 0)
97
#define			_cairo_int64_not(a)	    _cairo_uint64_not(a)
98

            
99
#else
100

            
101
static inline cairo_uquorem64_t
102
657198
_cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den)
103
{
104
    cairo_uquorem64_t	qr;
105

            
106
657198
    qr.quo = num / den;
107
657198
    qr.rem = num % den;
108
657198
    return qr;
109
}
110

            
111
/*
112
 * These need to be functions or gcc will complain when used on the
113
 * result of a function:
114
 *
115
 * warning: cast from function call of type ‘#cairo_uint64_t’ to
116
 * non-matching type ‘double’
117
 */
118
static cairo_always_inline cairo_const cairo_uint64_t _cairo_double_to_uint64 (double i) { return i; }
119
static cairo_always_inline cairo_const double _cairo_uint64_to_double (cairo_uint64_t i) { return i; }
120

            
121
static cairo_always_inline cairo_int64_t I _cairo_double_to_int64 (double i) { return i; }
122
static cairo_always_inline double I _cairo_int64_to_double (cairo_int64_t i) { return i; }
123

            
124
#define			_cairo_uint32_to_uint64(i)  ((uint64_t) (i))
125
#define			_cairo_uint64_to_uint32(i)  ((uint32_t) (i))
126
#define			_cairo_uint64_add(a,b)	    ((a) + (b))
127
#define			_cairo_uint64_sub(a,b)	    ((a) - (b))
128
#define			_cairo_uint64_mul(a,b)	    ((a) * (b))
129
#define			_cairo_uint32x32_64_mul(a,b)	((uint64_t) (a) * (b))
130
#define			_cairo_uint64_lsl(a,b)	    ((a) << (b))
131
#define			_cairo_uint64_rsl(a,b)	    ((uint64_t) (a) >> (b))
132
#define			_cairo_uint64_rsa(a,b)	    ((uint64_t) ((int64_t) (a) >> (b)))
133
#define			_cairo_uint64_lt(a,b)	    ((a) < (b))
134
#define                 _cairo_uint64_cmp(a,b)       ((a) == (b) ? 0 : (a) < (b) ? -1 : 1)
135
#define			_cairo_uint64_is_zero(a)    ((a) == 0)
136
#define			_cairo_uint64_eq(a,b)	    ((a) == (b))
137
#define			_cairo_uint64_negate(a)	    ((uint64_t) -((int64_t) (a)))
138
#define			_cairo_uint64_negative(a)   ((int64_t) (a) < 0)
139
#define			_cairo_uint64_not(a)	    (~(a))
140

            
141
#define			_cairo_uint64_to_int64(i)   ((int64_t) (i))
142
#define			_cairo_int64_to_uint64(i)   ((uint64_t) (i))
143

            
144
#define			_cairo_int32_to_int64(i)    ((int64_t) (i))
145
#define			_cairo_int64_to_int32(i)    ((int32_t) (i))
146
#define			_cairo_int64_add(a,b)	    ((a) + (b))
147
#define			_cairo_int64_sub(a,b)	    ((a) - (b))
148
#define			_cairo_int64_mul(a,b)	    ((a) * (b))
149
#define			_cairo_int32x32_64_mul(a,b) ((int64_t) (a) * (b))
150
#define			_cairo_int64_lt(a,b)	    ((a) < (b))
151
#define                 _cairo_int64_cmp(a,b)       ((a) == (b) ? 0 : (a) < (b) ? -1 : 1)
152
#define			_cairo_int64_is_zero(a)     ((a) == 0)
153
#define			_cairo_int64_eq(a,b)	    ((a) == (b))
154
#define			_cairo_int64_lsl(a,b)	    ((a) << (b))
155
#define			_cairo_int64_rsl(a,b)	    ((int64_t) ((uint64_t) (a) >> (b)))
156
#define			_cairo_int64_rsa(a,b)	    ((int64_t) (a) >> (b))
157
#define			_cairo_int64_negate(a)	    (-(a))
158
#define			_cairo_int64_negative(a)    ((a) < 0)
159
#define			_cairo_int64_not(a)	    (~(a))
160

            
161
#endif
162

            
163
/*
164
 * 64-bit comparisons derived from lt or eq
165
 */
166
#define			_cairo_uint64_le(a,b)	    (!_cairo_uint64_gt(a,b))
167
#define			_cairo_uint64_ne(a,b)	    (!_cairo_uint64_eq(a,b))
168
#define			_cairo_uint64_ge(a,b)	    (!_cairo_uint64_lt(a,b))
169
#define			_cairo_uint64_gt(a,b)	    _cairo_uint64_lt(b,a)
170

            
171
#define			_cairo_int64_le(a,b)	    (!_cairo_int64_gt(a,b))
172
#define			_cairo_int64_ne(a,b)	    (!_cairo_int64_eq(a,b))
173
#define			_cairo_int64_ge(a,b)	    (!_cairo_int64_lt(a,b))
174
#define			_cairo_int64_gt(a,b)	    _cairo_int64_lt(b,a)
175

            
176
/*
177
 * As the C implementation always computes both, create
178
 * a function which returns both for the 'native' type as well
179
 */
180

            
181
static inline cairo_quorem64_t
182
_cairo_int64_divrem (cairo_int64_t num, cairo_int64_t den)
183
{
184
    int			num_neg = _cairo_int64_negative (num);
185
    int			den_neg = _cairo_int64_negative (den);
186
    cairo_uquorem64_t	uqr;
187
    cairo_quorem64_t	qr;
188

            
189
    if (num_neg)
190
	num = _cairo_int64_negate (num);
191
    if (den_neg)
192
	den = _cairo_int64_negate (den);
193
    uqr = _cairo_uint64_divrem (num, den);
194
    if (num_neg)
195
	qr.rem = _cairo_int64_negate (uqr.rem);
196
    else
197
	qr.rem = uqr.rem;
198
    if (num_neg != den_neg)
199
	qr.quo = (cairo_int64_t) _cairo_int64_negate (uqr.quo);
200
    else
201
	qr.quo = (cairo_int64_t) uqr.quo;
202
    return qr;
203
}
204

            
205
static inline int32_t
206
716663
_cairo_int64_32_div (cairo_int64_t num, int32_t den)
207
{
208
#if !HAVE_UINT64_T
209
    return _cairo_int64_to_int32
210
	(_cairo_int64_divrem (num, _cairo_int32_to_int64 (den)).quo);
211
#else
212
716663
    return num / den;
213
#endif
214
}
215

            
216
/*
217
 * 128-bit datatypes.  Again, provide two implementations in
218
 * case the machine has a native 128-bit datatype.  GCC supports int128_t
219
 * on ia64
220
 */
221

            
222
#if !HAVE_UINT128_T
223

            
224
cairo_uint128_t I	_cairo_uint32_to_uint128 (uint32_t i);
225
cairo_uint128_t I	_cairo_uint64_to_uint128 (cairo_uint64_t i);
226
#define			_cairo_uint128_to_uint64(a)	((a).lo)
227
#define			_cairo_uint128_to_uint32(a)	_cairo_uint64_to_uint32(_cairo_uint128_to_uint64(a))
228
cairo_uint128_t I	_cairo_uint128_add (cairo_uint128_t a, cairo_uint128_t b);
229
cairo_uint128_t I	_cairo_uint128_sub (cairo_uint128_t a, cairo_uint128_t b);
230
cairo_uint128_t I	_cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b);
231
cairo_uint128_t I	_cairo_uint64x64_128_mul (cairo_uint64_t a, cairo_uint64_t b);
232
cairo_uint128_t I	_cairo_uint128_lsl (cairo_uint128_t a, int shift);
233
cairo_uint128_t I	_cairo_uint128_rsl (cairo_uint128_t a, int shift);
234
cairo_uint128_t I	_cairo_uint128_rsa (cairo_uint128_t a, int shift);
235
int	        I	_cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b);
236
int	        I	_cairo_uint128_cmp (cairo_uint128_t a, cairo_uint128_t b);
237
int	        I	_cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b);
238
#define			_cairo_uint128_is_zero(a) (_cairo_uint64_is_zero ((a).hi) && _cairo_uint64_is_zero ((a).lo))
239
cairo_uint128_t I	_cairo_uint128_negate (cairo_uint128_t a);
240
#define			_cairo_uint128_negative(a)  (_cairo_uint64_negative(a.hi))
241
cairo_uint128_t I	_cairo_uint128_not (cairo_uint128_t a);
242

            
243
#define			_cairo_uint128_to_int128(i)	(i)
244
#define			_cairo_int128_to_uint128(i)	(i)
245

            
246
cairo_int128_t  I	_cairo_int32_to_int128 (int32_t i);
247
cairo_int128_t  I	_cairo_int64_to_int128 (cairo_int64_t i);
248
#define			_cairo_int128_to_int64(a)   ((cairo_int64_t) (a).lo)
249
#define			_cairo_int128_to_int32(a)   _cairo_int64_to_int32(_cairo_int128_to_int64(a))
250
#define			_cairo_int128_add(a,b)	    _cairo_uint128_add(a,b)
251
#define			_cairo_int128_sub(a,b)	    _cairo_uint128_sub(a,b)
252
#define			_cairo_int128_mul(a,b)	    _cairo_uint128_mul(a,b)
253
cairo_int128_t I _cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b);
254
#define                 _cairo_int64x32_128_mul(a, b) _cairo_int64x64_128_mul(a, _cairo_int32_to_int64(b))
255
#define			_cairo_int128_lsl(a,b)	    _cairo_uint128_lsl(a,b)
256
#define			_cairo_int128_rsl(a,b)	    _cairo_uint128_rsl(a,b)
257
#define			_cairo_int128_rsa(a,b)	    _cairo_uint128_rsa(a,b)
258
int 	        I	_cairo_int128_lt (cairo_int128_t a, cairo_int128_t b);
259
int	        I	_cairo_int128_cmp (cairo_int128_t a, cairo_int128_t b);
260
#define			_cairo_int128_is_zero(a)    _cairo_uint128_is_zero (a)
261
#define			_cairo_int128_eq(a,b)	    _cairo_uint128_eq (a,b)
262
#define			_cairo_int128_negate(a)	    _cairo_uint128_negate(a)
263
#define			_cairo_int128_negative(a)   (_cairo_uint128_negative(a))
264
#define			_cairo_int128_not(a)	    _cairo_uint128_not(a)
265

            
266
#else	/* !HAVE_UINT128_T */
267

            
268
#define			_cairo_uint32_to_uint128(i) ((uint128_t) (i))
269
#define			_cairo_uint64_to_uint128(i) ((uint128_t) (i))
270
#define			_cairo_uint128_to_uint64(i) ((uint64_t) (i))
271
#define			_cairo_uint128_to_uint32(i) ((uint32_t) (i))
272
#define			_cairo_uint128_add(a,b)	    ((a) + (b))
273
#define			_cairo_uint128_sub(a,b)	    ((a) - (b))
274
#define			_cairo_uint128_mul(a,b)	    ((a) * (b))
275
#define			_cairo_uint64x64_128_mul(a,b)	((uint128_t) (a) * (b))
276
#define			_cairo_uint128_lsl(a,b)	    ((a) << (b))
277
#define			_cairo_uint128_rsl(a,b)	    ((uint128_t) (a) >> (b))
278
#define			_cairo_uint128_rsa(a,b)	    ((uint128_t) ((int128_t) (a) >> (b)))
279
#define			_cairo_uint128_lt(a,b)	    ((a) < (b))
280
#define			_cairo_uint128_cmp(a,b)	    ((a) == (b) ? 0 : (a) < (b) ? -1 : 1)
281
#define			_cairo_uint128_is_zero(a)   ((a) == 0)
282
#define			_cairo_uint128_eq(a,b)	    ((a) == (b))
283
#define			_cairo_uint128_negate(a)    ((uint128_t) -((int128_t) (a)))
284
#define			_cairo_uint128_negative(a)  ((int128_t) (a) < 0)
285
#define			_cairo_uint128_not(a)	    (~(a))
286

            
287
#define			_cairo_uint128_to_int128(i) ((int128_t) (i))
288
#define			_cairo_int128_to_uint128(i) ((uint128_t) (i))
289

            
290
#define			_cairo_int32_to_int128(i)   ((int128_t) (i))
291
#define			_cairo_int64_to_int128(i)   ((int128_t) (i))
292
#define			_cairo_int128_to_int64(i)   ((int64_t) (i))
293
#define			_cairo_int128_to_int32(i)   ((int32_t) (i))
294
#define			_cairo_int128_add(a,b)	    ((a) + (b))
295
#define			_cairo_int128_sub(a,b)	    ((a) - (b))
296
#define			_cairo_int128_mul(a,b)	    ((a) * (b))
297
#define			_cairo_int64x64_128_mul(a,b) ((int128_t) (a) * (b))
298
#define                 _cairo_int64x32_128_mul(a, b) _cairo_int64x64_128_mul(a, _cairo_int32_to_int64(b))
299
#define			_cairo_int128_lt(a,b)	    ((a) < (b))
300
#define			_cairo_int128_cmp(a,b)	    ((a) == (b) ? 0 : (a) < (b) ? -1 : 1)
301
#define			_cairo_int128_is_zero(a)    ((a) == 0)
302
#define			_cairo_int128_eq(a,b)	    ((a) == (b))
303
#define			_cairo_int128_lsl(a,b)	    ((a) << (b))
304
#define			_cairo_int128_rsl(a,b)	    ((int128_t) ((uint128_t) (a) >> (b)))
305
#define			_cairo_int128_rsa(a,b)	    ((int128_t) (a) >> (b))
306
#define			_cairo_int128_negate(a)	    (-(a))
307
#define			_cairo_int128_negative(a)   ((a) < 0)
308
#define			_cairo_int128_not(a)	    (~(a))
309

            
310
#endif	/* HAVE_UINT128_T */
311

            
312
cairo_uquorem128_t I
313
_cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den);
314

            
315
cairo_quorem128_t I
316
_cairo_int128_divrem (cairo_int128_t num, cairo_int128_t den);
317

            
318
cairo_uquorem64_t I
319
_cairo_uint_96by64_32x64_divrem (cairo_uint128_t num,
320
				 cairo_uint64_t  den);
321

            
322
cairo_quorem64_t I
323
_cairo_int_96by64_32x64_divrem (cairo_int128_t num,
324
				cairo_int64_t  den);
325

            
326
#define			_cairo_uint128_le(a,b)	    (!_cairo_uint128_gt(a,b))
327
#define			_cairo_uint128_ne(a,b)	    (!_cairo_uint128_eq(a,b))
328
#define			_cairo_uint128_ge(a,b)	    (!_cairo_uint128_lt(a,b))
329
#define			_cairo_uint128_gt(a,b)	    _cairo_uint128_lt(b,a)
330

            
331
#define			_cairo_int128_le(a,b)	    (!_cairo_int128_gt(a,b))
332
#define			_cairo_int128_ne(a,b)	    (!_cairo_int128_eq(a,b))
333
#define			_cairo_int128_ge(a,b)	    (!_cairo_int128_lt(a,b))
334
#define			_cairo_int128_gt(a,b)	    _cairo_int128_lt(b,a)
335

            
336
#undef I
337

            
338
#endif /* CAIRO_WIDEINT_H */