/work/workdir/UnpackedTarball/cairo/src/cairo-wideint.c
Line | Count | Source (jump to first uncovered line) |
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 | | #include "cairoint.h" |
37 | | |
38 | | #if HAVE_UINT64_T |
39 | | |
40 | | #define uint64_lo32(i) ((i) & 0xffffffff) |
41 | 0 | #define uint64_hi32(i) ((i) >> 32) |
42 | | #define uint64_lo(i) ((i) & 0xffffffff) |
43 | | #define uint64_hi(i) ((i) >> 32) |
44 | | #define uint64_shift32(i) ((i) << 32) |
45 | | #define uint64_carry32 (((uint64_t) 1) << 32) |
46 | | |
47 | 0 | #define _cairo_uint32s_to_uint64(h,l) ((uint64_t) (h) << 32 | (l)) |
48 | | |
49 | | #else |
50 | | |
51 | | #define uint64_lo32(i) ((i).lo) |
52 | | #define uint64_hi32(i) ((i).hi) |
53 | | |
54 | | static cairo_uint64_t |
55 | | uint64_lo (cairo_uint64_t i) |
56 | | { |
57 | | cairo_uint64_t s; |
58 | | |
59 | | s.lo = i.lo; |
60 | | s.hi = 0; |
61 | | return s; |
62 | | } |
63 | | |
64 | | static cairo_uint64_t |
65 | | uint64_hi (cairo_uint64_t i) |
66 | | { |
67 | | cairo_uint64_t s; |
68 | | |
69 | | s.lo = i.hi; |
70 | | s.hi = 0; |
71 | | return s; |
72 | | } |
73 | | |
74 | | static cairo_uint64_t |
75 | | uint64_shift32 (cairo_uint64_t i) |
76 | | { |
77 | | cairo_uint64_t s; |
78 | | |
79 | | s.lo = 0; |
80 | | s.hi = i.lo; |
81 | | return s; |
82 | | } |
83 | | |
84 | | static const cairo_uint64_t uint64_carry32 = { 0, 1 }; |
85 | | |
86 | | cairo_uint64_t |
87 | | _cairo_double_to_uint64 (double i) |
88 | | { |
89 | | cairo_uint64_t q; |
90 | | |
91 | | q.hi = i * (1. / 4294967296.); |
92 | | q.lo = i - q.hi * 4294967296.; |
93 | | return q; |
94 | | } |
95 | | |
96 | | double |
97 | | _cairo_uint64_to_double (cairo_uint64_t i) |
98 | | { |
99 | | return i.hi * 4294967296. + i.lo; |
100 | | } |
101 | | |
102 | | cairo_int64_t |
103 | | _cairo_double_to_int64 (double i) |
104 | | { |
105 | | cairo_uint64_t q; |
106 | | |
107 | | q.hi = i * (1. / INT32_MAX); |
108 | | q.lo = i - q.hi * (double)INT32_MAX; |
109 | | return q; |
110 | | } |
111 | | |
112 | | double |
113 | | _cairo_int64_to_double (cairo_int64_t i) |
114 | | { |
115 | | return i.hi * INT32_MAX + i.lo; |
116 | | } |
117 | | |
118 | | cairo_uint64_t |
119 | | _cairo_uint32_to_uint64 (uint32_t i) |
120 | | { |
121 | | cairo_uint64_t q; |
122 | | |
123 | | q.lo = i; |
124 | | q.hi = 0; |
125 | | return q; |
126 | | } |
127 | | |
128 | | cairo_int64_t |
129 | | _cairo_int32_to_int64 (int32_t i) |
130 | | { |
131 | | cairo_uint64_t q; |
132 | | |
133 | | q.lo = i; |
134 | | q.hi = i < 0 ? -1 : 0; |
135 | | return q; |
136 | | } |
137 | | |
138 | | static cairo_uint64_t |
139 | | _cairo_uint32s_to_uint64 (uint32_t h, uint32_t l) |
140 | | { |
141 | | cairo_uint64_t q; |
142 | | |
143 | | q.lo = l; |
144 | | q.hi = h; |
145 | | return q; |
146 | | } |
147 | | |
148 | | cairo_uint64_t |
149 | | _cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b) |
150 | | { |
151 | | cairo_uint64_t s; |
152 | | |
153 | | s.hi = a.hi + b.hi; |
154 | | s.lo = a.lo + b.lo; |
155 | | if (s.lo < a.lo) |
156 | | s.hi++; |
157 | | return s; |
158 | | } |
159 | | |
160 | | cairo_uint64_t |
161 | | _cairo_uint64_sub (cairo_uint64_t a, cairo_uint64_t b) |
162 | | { |
163 | | cairo_uint64_t s; |
164 | | |
165 | | s.hi = a.hi - b.hi; |
166 | | s.lo = a.lo - b.lo; |
167 | | if (s.lo > a.lo) |
168 | | s.hi--; |
169 | | return s; |
170 | | } |
171 | | |
172 | | #define uint32_lo(i) ((i) & 0xffff) |
173 | | #define uint32_hi(i) ((i) >> 16) |
174 | | #define uint32_carry16 ((1) << 16) |
175 | | |
176 | | cairo_uint64_t |
177 | | _cairo_uint32x32_64_mul (uint32_t a, uint32_t b) |
178 | | { |
179 | | cairo_uint64_t s; |
180 | | |
181 | | uint16_t ah, al, bh, bl; |
182 | | uint32_t r0, r1, r2, r3; |
183 | | |
184 | | al = uint32_lo (a); |
185 | | ah = uint32_hi (a); |
186 | | bl = uint32_lo (b); |
187 | | bh = uint32_hi (b); |
188 | | |
189 | | r0 = (uint32_t) al * bl; |
190 | | r1 = (uint32_t) al * bh; |
191 | | r2 = (uint32_t) ah * bl; |
192 | | r3 = (uint32_t) ah * bh; |
193 | | |
194 | | r1 += uint32_hi(r0); /* no carry possible */ |
195 | | r1 += r2; /* but this can carry */ |
196 | | if (r1 < r2) /* check */ |
197 | | r3 += uint32_carry16; |
198 | | |
199 | | s.hi = r3 + uint32_hi(r1); |
200 | | s.lo = (uint32_lo (r1) << 16) + uint32_lo (r0); |
201 | | return s; |
202 | | } |
203 | | |
204 | | cairo_int64_t |
205 | | _cairo_int32x32_64_mul (int32_t a, int32_t b) |
206 | | { |
207 | | cairo_int64_t s; |
208 | | s = _cairo_uint32x32_64_mul ((uint32_t) a, (uint32_t) b); |
209 | | if (a < 0) |
210 | | s.hi -= b; |
211 | | if (b < 0) |
212 | | s.hi -= a; |
213 | | return s; |
214 | | } |
215 | | |
216 | | cairo_uint64_t |
217 | | _cairo_uint64_mul (cairo_uint64_t a, cairo_uint64_t b) |
218 | | { |
219 | | cairo_uint64_t s; |
220 | | |
221 | | s = _cairo_uint32x32_64_mul (a.lo, b.lo); |
222 | | s.hi += a.lo * b.hi + a.hi * b.lo; |
223 | | return s; |
224 | | } |
225 | | |
226 | | cairo_uint64_t |
227 | | _cairo_uint64_lsl (cairo_uint64_t a, int shift) |
228 | | { |
229 | | if (shift >= 32) |
230 | | { |
231 | | a.hi = a.lo; |
232 | | a.lo = 0; |
233 | | shift -= 32; |
234 | | } |
235 | | if (shift) |
236 | | { |
237 | | a.hi = a.hi << shift | a.lo >> (32 - shift); |
238 | | a.lo = a.lo << shift; |
239 | | } |
240 | | return a; |
241 | | } |
242 | | |
243 | | cairo_uint64_t |
244 | | _cairo_uint64_rsl (cairo_uint64_t a, int shift) |
245 | | { |
246 | | if (shift >= 32) |
247 | | { |
248 | | a.lo = a.hi; |
249 | | a.hi = 0; |
250 | | shift -= 32; |
251 | | } |
252 | | if (shift) |
253 | | { |
254 | | a.lo = a.lo >> shift | a.hi << (32 - shift); |
255 | | a.hi = a.hi >> shift; |
256 | | } |
257 | | return a; |
258 | | } |
259 | | |
260 | | #define _cairo_uint32_rsa(a,n) ((uint32_t) (((int32_t) (a)) >> (n))) |
261 | | |
262 | | cairo_int64_t |
263 | | _cairo_uint64_rsa (cairo_int64_t a, int shift) |
264 | | { |
265 | | if (shift >= 32) |
266 | | { |
267 | | a.lo = a.hi; |
268 | | a.hi = _cairo_uint32_rsa (a.hi, 31); |
269 | | shift -= 32; |
270 | | } |
271 | | if (shift) |
272 | | { |
273 | | a.lo = a.lo >> shift | a.hi << (32 - shift); |
274 | | a.hi = _cairo_uint32_rsa (a.hi, shift); |
275 | | } |
276 | | return a; |
277 | | } |
278 | | |
279 | | int |
280 | | _cairo_uint64_lt (cairo_uint64_t a, cairo_uint64_t b) |
281 | | { |
282 | | return (a.hi < b.hi || |
283 | | (a.hi == b.hi && a.lo < b.lo)); |
284 | | } |
285 | | |
286 | | int |
287 | | _cairo_uint64_eq (cairo_uint64_t a, cairo_uint64_t b) |
288 | | { |
289 | | return a.hi == b.hi && a.lo == b.lo; |
290 | | } |
291 | | |
292 | | int |
293 | | _cairo_int64_lt (cairo_int64_t a, cairo_int64_t b) |
294 | | { |
295 | | if (_cairo_int64_negative (a) && !_cairo_int64_negative (b)) |
296 | | return 1; |
297 | | if (!_cairo_int64_negative (a) && _cairo_int64_negative (b)) |
298 | | return 0; |
299 | | return _cairo_uint64_lt (a, b); |
300 | | } |
301 | | |
302 | | int |
303 | | _cairo_uint64_cmp (cairo_uint64_t a, cairo_uint64_t b) |
304 | | { |
305 | | if (a.hi < b.hi) |
306 | | return -1; |
307 | | else if (a.hi > b.hi) |
308 | | return 1; |
309 | | else if (a.lo < b.lo) |
310 | | return -1; |
311 | | else if (a.lo > b.lo) |
312 | | return 1; |
313 | | else |
314 | | return 0; |
315 | | } |
316 | | |
317 | | int |
318 | | _cairo_int64_cmp (cairo_int64_t a, cairo_int64_t b) |
319 | | { |
320 | | if (_cairo_int64_negative (a) && !_cairo_int64_negative (b)) |
321 | | return -1; |
322 | | if (!_cairo_int64_negative (a) && _cairo_int64_negative (b)) |
323 | | return 1; |
324 | | |
325 | | return _cairo_uint64_cmp (a, b); |
326 | | } |
327 | | |
328 | | cairo_uint64_t |
329 | | _cairo_uint64_not (cairo_uint64_t a) |
330 | | { |
331 | | a.lo = ~a.lo; |
332 | | a.hi = ~a.hi; |
333 | | return a; |
334 | | } |
335 | | |
336 | | cairo_uint64_t |
337 | | _cairo_uint64_negate (cairo_uint64_t a) |
338 | | { |
339 | | a.lo = ~a.lo; |
340 | | a.hi = ~a.hi; |
341 | | if (++a.lo == 0) |
342 | | ++a.hi; |
343 | | return a; |
344 | | } |
345 | | |
346 | | /* |
347 | | * Simple bit-at-a-time divide. |
348 | | */ |
349 | | cairo_uquorem64_t |
350 | | _cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den) |
351 | | { |
352 | | cairo_uquorem64_t qr; |
353 | | cairo_uint64_t bit; |
354 | | cairo_uint64_t quo; |
355 | | |
356 | | bit = _cairo_uint32_to_uint64 (1); |
357 | | |
358 | | /* normalize to make den >= num, but not overflow */ |
359 | | while (_cairo_uint64_lt (den, num) && (den.hi & 0x80000000) == 0) |
360 | | { |
361 | | bit = _cairo_uint64_lsl (bit, 1); |
362 | | den = _cairo_uint64_lsl (den, 1); |
363 | | } |
364 | | quo = _cairo_uint32_to_uint64 (0); |
365 | | |
366 | | /* generate quotient, one bit at a time */ |
367 | | while (bit.hi | bit.lo) |
368 | | { |
369 | | if (_cairo_uint64_le (den, num)) |
370 | | { |
371 | | num = _cairo_uint64_sub (num, den); |
372 | | quo = _cairo_uint64_add (quo, bit); |
373 | | } |
374 | | bit = _cairo_uint64_rsl (bit, 1); |
375 | | den = _cairo_uint64_rsl (den, 1); |
376 | | } |
377 | | qr.quo = quo; |
378 | | qr.rem = num; |
379 | | return qr; |
380 | | } |
381 | | |
382 | | #endif /* !HAVE_UINT64_T */ |
383 | | |
384 | | #if HAVE_UINT128_T |
385 | | cairo_uquorem128_t |
386 | | _cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den) |
387 | 0 | { |
388 | 0 | cairo_uquorem128_t qr; |
389 | |
|
390 | 0 | qr.quo = num / den; |
391 | 0 | qr.rem = num % den; |
392 | 0 | return qr; |
393 | 0 | } |
394 | | |
395 | | #else |
396 | | |
397 | | cairo_uint128_t |
398 | | _cairo_uint32_to_uint128 (uint32_t i) |
399 | | { |
400 | | cairo_uint128_t q; |
401 | | |
402 | | q.lo = _cairo_uint32_to_uint64 (i); |
403 | | q.hi = _cairo_uint32_to_uint64 (0); |
404 | | return q; |
405 | | } |
406 | | |
407 | | cairo_int128_t |
408 | | _cairo_int32_to_int128 (int32_t i) |
409 | | { |
410 | | cairo_int128_t q; |
411 | | |
412 | | q.lo = _cairo_int32_to_int64 (i); |
413 | | q.hi = _cairo_int32_to_int64 (i < 0 ? -1 : 0); |
414 | | return q; |
415 | | } |
416 | | |
417 | | cairo_uint128_t |
418 | | _cairo_uint64_to_uint128 (cairo_uint64_t i) |
419 | | { |
420 | | cairo_uint128_t q; |
421 | | |
422 | | q.lo = i; |
423 | | q.hi = _cairo_uint32_to_uint64 (0); |
424 | | return q; |
425 | | } |
426 | | |
427 | | cairo_int128_t |
428 | | _cairo_int64_to_int128 (cairo_int64_t i) |
429 | | { |
430 | | cairo_int128_t q; |
431 | | |
432 | | q.lo = i; |
433 | | q.hi = _cairo_int32_to_int64 (_cairo_int64_negative(i) ? -1 : 0); |
434 | | return q; |
435 | | } |
436 | | |
437 | | cairo_uint128_t |
438 | | _cairo_uint128_add (cairo_uint128_t a, cairo_uint128_t b) |
439 | | { |
440 | | cairo_uint128_t s; |
441 | | |
442 | | s.hi = _cairo_uint64_add (a.hi, b.hi); |
443 | | s.lo = _cairo_uint64_add (a.lo, b.lo); |
444 | | if (_cairo_uint64_lt (s.lo, a.lo)) |
445 | | s.hi = _cairo_uint64_add (s.hi, _cairo_uint32_to_uint64 (1)); |
446 | | return s; |
447 | | } |
448 | | |
449 | | cairo_uint128_t |
450 | | _cairo_uint128_sub (cairo_uint128_t a, cairo_uint128_t b) |
451 | | { |
452 | | cairo_uint128_t s; |
453 | | |
454 | | s.hi = _cairo_uint64_sub (a.hi, b.hi); |
455 | | s.lo = _cairo_uint64_sub (a.lo, b.lo); |
456 | | if (_cairo_uint64_gt (s.lo, a.lo)) |
457 | | s.hi = _cairo_uint64_sub (s.hi, _cairo_uint32_to_uint64(1)); |
458 | | return s; |
459 | | } |
460 | | |
461 | | cairo_uint128_t |
462 | | _cairo_uint64x64_128_mul (cairo_uint64_t a, cairo_uint64_t b) |
463 | | { |
464 | | cairo_uint128_t s; |
465 | | uint32_t ah, al, bh, bl; |
466 | | cairo_uint64_t r0, r1, r2, r3; |
467 | | |
468 | | al = uint64_lo32 (a); |
469 | | ah = uint64_hi32 (a); |
470 | | bl = uint64_lo32 (b); |
471 | | bh = uint64_hi32 (b); |
472 | | |
473 | | r0 = _cairo_uint32x32_64_mul (al, bl); |
474 | | r1 = _cairo_uint32x32_64_mul (al, bh); |
475 | | r2 = _cairo_uint32x32_64_mul (ah, bl); |
476 | | r3 = _cairo_uint32x32_64_mul (ah, bh); |
477 | | |
478 | | r1 = _cairo_uint64_add (r1, uint64_hi (r0)); /* no carry possible */ |
479 | | r1 = _cairo_uint64_add (r1, r2); /* but this can carry */ |
480 | | if (_cairo_uint64_lt (r1, r2)) /* check */ |
481 | | r3 = _cairo_uint64_add (r3, uint64_carry32); |
482 | | |
483 | | s.hi = _cairo_uint64_add (r3, uint64_hi(r1)); |
484 | | s.lo = _cairo_uint64_add (uint64_shift32 (r1), |
485 | | uint64_lo (r0)); |
486 | | return s; |
487 | | } |
488 | | |
489 | | cairo_int128_t |
490 | | _cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b) |
491 | | { |
492 | | cairo_int128_t s; |
493 | | s = _cairo_uint64x64_128_mul (_cairo_int64_to_uint64(a), |
494 | | _cairo_int64_to_uint64(b)); |
495 | | if (_cairo_int64_negative (a)) |
496 | | s.hi = _cairo_uint64_sub (s.hi, |
497 | | _cairo_int64_to_uint64 (b)); |
498 | | if (_cairo_int64_negative (b)) |
499 | | s.hi = _cairo_uint64_sub (s.hi, |
500 | | _cairo_int64_to_uint64 (a)); |
501 | | return s; |
502 | | } |
503 | | |
504 | | cairo_uint128_t |
505 | | _cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b) |
506 | | { |
507 | | cairo_uint128_t s; |
508 | | |
509 | | s = _cairo_uint64x64_128_mul (a.lo, b.lo); |
510 | | s.hi = _cairo_uint64_add (s.hi, |
511 | | _cairo_uint64_mul (a.lo, b.hi)); |
512 | | s.hi = _cairo_uint64_add (s.hi, |
513 | | _cairo_uint64_mul (a.hi, b.lo)); |
514 | | return s; |
515 | | } |
516 | | |
517 | | cairo_uint128_t |
518 | | _cairo_uint128_lsl (cairo_uint128_t a, int shift) |
519 | | { |
520 | | if (shift >= 64) |
521 | | { |
522 | | a.hi = a.lo; |
523 | | a.lo = _cairo_uint32_to_uint64 (0); |
524 | | shift -= 64; |
525 | | } |
526 | | if (shift) |
527 | | { |
528 | | a.hi = _cairo_uint64_add (_cairo_uint64_lsl (a.hi, shift), |
529 | | _cairo_uint64_rsl (a.lo, (64 - shift))); |
530 | | a.lo = _cairo_uint64_lsl (a.lo, shift); |
531 | | } |
532 | | return a; |
533 | | } |
534 | | |
535 | | cairo_uint128_t |
536 | | _cairo_uint128_rsl (cairo_uint128_t a, int shift) |
537 | | { |
538 | | if (shift >= 64) |
539 | | { |
540 | | a.lo = a.hi; |
541 | | a.hi = _cairo_uint32_to_uint64 (0); |
542 | | shift -= 64; |
543 | | } |
544 | | if (shift) |
545 | | { |
546 | | a.lo = _cairo_uint64_add (_cairo_uint64_rsl (a.lo, shift), |
547 | | _cairo_uint64_lsl (a.hi, (64 - shift))); |
548 | | a.hi = _cairo_uint64_rsl (a.hi, shift); |
549 | | } |
550 | | return a; |
551 | | } |
552 | | |
553 | | cairo_uint128_t |
554 | | _cairo_uint128_rsa (cairo_int128_t a, int shift) |
555 | | { |
556 | | if (shift >= 64) |
557 | | { |
558 | | a.lo = a.hi; |
559 | | a.hi = _cairo_uint64_rsa (a.hi, 64-1); |
560 | | shift -= 64; |
561 | | } |
562 | | if (shift) |
563 | | { |
564 | | a.lo = _cairo_uint64_add (_cairo_uint64_rsl (a.lo, shift), |
565 | | _cairo_uint64_lsl (a.hi, (64 - shift))); |
566 | | a.hi = _cairo_uint64_rsa (a.hi, shift); |
567 | | } |
568 | | return a; |
569 | | } |
570 | | |
571 | | int |
572 | | _cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b) |
573 | | { |
574 | | return (_cairo_uint64_lt (a.hi, b.hi) || |
575 | | (_cairo_uint64_eq (a.hi, b.hi) && |
576 | | _cairo_uint64_lt (a.lo, b.lo))); |
577 | | } |
578 | | |
579 | | int |
580 | | _cairo_int128_lt (cairo_int128_t a, cairo_int128_t b) |
581 | | { |
582 | | if (_cairo_int128_negative (a) && !_cairo_int128_negative (b)) |
583 | | return 1; |
584 | | if (!_cairo_int128_negative (a) && _cairo_int128_negative (b)) |
585 | | return 0; |
586 | | return _cairo_uint128_lt (a, b); |
587 | | } |
588 | | |
589 | | int |
590 | | _cairo_uint128_cmp (cairo_uint128_t a, cairo_uint128_t b) |
591 | | { |
592 | | int cmp; |
593 | | |
594 | | cmp = _cairo_uint64_cmp (a.hi, b.hi); |
595 | | if (cmp) |
596 | | return cmp; |
597 | | return _cairo_uint64_cmp (a.lo, b.lo); |
598 | | } |
599 | | |
600 | | int |
601 | | _cairo_int128_cmp (cairo_int128_t a, cairo_int128_t b) |
602 | | { |
603 | | if (_cairo_int128_negative (a) && !_cairo_int128_negative (b)) |
604 | | return -1; |
605 | | if (!_cairo_int128_negative (a) && _cairo_int128_negative (b)) |
606 | | return 1; |
607 | | |
608 | | return _cairo_uint128_cmp (a, b); |
609 | | } |
610 | | |
611 | | int |
612 | | _cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b) |
613 | | { |
614 | | return (_cairo_uint64_eq (a.hi, b.hi) && |
615 | | _cairo_uint64_eq (a.lo, b.lo)); |
616 | | } |
617 | | |
618 | | #if HAVE_UINT64_T |
619 | | #define _cairo_msbset64(q) (q & ((uint64_t) 1 << 63)) |
620 | | #else |
621 | | #define _cairo_msbset64(q) (q.hi & ((uint32_t) 1 << 31)) |
622 | | #endif |
623 | | |
624 | | cairo_uquorem128_t |
625 | | _cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den) |
626 | | { |
627 | | cairo_uquorem128_t qr; |
628 | | cairo_uint128_t bit; |
629 | | cairo_uint128_t quo; |
630 | | |
631 | | bit = _cairo_uint32_to_uint128 (1); |
632 | | |
633 | | /* normalize to make den >= num, but not overflow */ |
634 | | while (_cairo_uint128_lt (den, num) && !_cairo_msbset64(den.hi)) |
635 | | { |
636 | | bit = _cairo_uint128_lsl (bit, 1); |
637 | | den = _cairo_uint128_lsl (den, 1); |
638 | | } |
639 | | quo = _cairo_uint32_to_uint128 (0); |
640 | | |
641 | | /* generate quotient, one bit at a time */ |
642 | | while (_cairo_uint128_ne (bit, _cairo_uint32_to_uint128(0))) |
643 | | { |
644 | | if (_cairo_uint128_le (den, num)) |
645 | | { |
646 | | num = _cairo_uint128_sub (num, den); |
647 | | quo = _cairo_uint128_add (quo, bit); |
648 | | } |
649 | | bit = _cairo_uint128_rsl (bit, 1); |
650 | | den = _cairo_uint128_rsl (den, 1); |
651 | | } |
652 | | qr.quo = quo; |
653 | | qr.rem = num; |
654 | | return qr; |
655 | | } |
656 | | |
657 | | cairo_uint128_t |
658 | | _cairo_uint128_negate (cairo_uint128_t a) |
659 | | { |
660 | | a.lo = _cairo_uint64_not (a.lo); |
661 | | a.hi = _cairo_uint64_not (a.hi); |
662 | | return _cairo_uint128_add (a, _cairo_uint32_to_uint128 (1)); |
663 | | } |
664 | | |
665 | | cairo_uint128_t |
666 | | _cairo_uint128_not (cairo_uint128_t a) |
667 | | { |
668 | | a.lo = _cairo_uint64_not (a.lo); |
669 | | a.hi = _cairo_uint64_not (a.hi); |
670 | | return a; |
671 | | } |
672 | | |
673 | | #endif /* !HAVE_UINT128_T */ |
674 | | |
675 | | cairo_quorem128_t |
676 | | _cairo_int128_divrem (cairo_int128_t num, cairo_int128_t den) |
677 | 0 | { |
678 | 0 | int num_neg = _cairo_int128_negative (num); |
679 | 0 | int den_neg = _cairo_int128_negative (den); |
680 | 0 | cairo_uquorem128_t uqr; |
681 | 0 | cairo_quorem128_t qr; |
682 | |
|
683 | 0 | if (num_neg) |
684 | 0 | num = _cairo_int128_negate (num); |
685 | 0 | if (den_neg) |
686 | 0 | den = _cairo_int128_negate (den); |
687 | 0 | uqr = _cairo_uint128_divrem (num, den); |
688 | 0 | if (num_neg) |
689 | 0 | qr.rem = _cairo_int128_negate (uqr.rem); |
690 | 0 | else |
691 | 0 | qr.rem = uqr.rem; |
692 | 0 | if (num_neg != den_neg) |
693 | 0 | qr.quo = _cairo_int128_negate (uqr.quo); |
694 | 0 | else |
695 | 0 | qr.quo = uqr.quo; |
696 | 0 | return qr; |
697 | 0 | } |
698 | | |
699 | | /** |
700 | | * _cairo_uint_96by64_32x64_divrem: |
701 | | * |
702 | | * Compute a 32 bit quotient and 64 bit remainder of a 96 bit unsigned |
703 | | * dividend and 64 bit divisor. If the quotient doesn't fit into 32 |
704 | | * bits then the returned remainder is equal to the divisor, and the |
705 | | * quotient is the largest representable 64 bit integer. It is an |
706 | | * error to call this function with the high 32 bits of @num being |
707 | | * non-zero. |
708 | | **/ |
709 | | cairo_uquorem64_t |
710 | | _cairo_uint_96by64_32x64_divrem (cairo_uint128_t num, |
711 | | cairo_uint64_t den) |
712 | 0 | { |
713 | 0 | cairo_uquorem64_t result; |
714 | 0 | cairo_uint64_t B = _cairo_uint32s_to_uint64 (1, 0); |
715 | | |
716 | | /* These are the high 64 bits of the *96* bit numerator. We're |
717 | | * going to represent the numerator as xB + y, where x is a 64, |
718 | | * and y is a 32 bit number. */ |
719 | 0 | cairo_uint64_t x = _cairo_uint128_to_uint64 (_cairo_uint128_rsl(num, 32)); |
720 | | |
721 | | /* Initialise the result to indicate overflow. */ |
722 | 0 | result.quo = _cairo_uint32s_to_uint64 (-1U, -1U); |
723 | 0 | result.rem = den; |
724 | | |
725 | | /* Don't bother if the quotient is going to overflow. */ |
726 | 0 | if (_cairo_uint64_ge (x, den)) { |
727 | 0 | return /* overflow */ result; |
728 | 0 | } |
729 | | |
730 | 0 | if (_cairo_uint64_lt (x, B)) { |
731 | | /* When the final quotient is known to fit in 32 bits, then |
732 | | * num < 2^64 if and only if den < 2^32. */ |
733 | 0 | return _cairo_uint64_divrem (_cairo_uint128_to_uint64 (num), den); |
734 | 0 | } |
735 | 0 | else { |
736 | | /* Denominator is >= 2^32. the numerator is >= 2^64, and the |
737 | | * division won't overflow: need two divrems. Write the |
738 | | * numerator and denominator as |
739 | | * |
740 | | * num = xB + y x : 64 bits, y : 32 bits |
741 | | * den = uB + v u, v : 32 bits |
742 | | */ |
743 | 0 | uint32_t y = _cairo_uint128_to_uint32 (num); |
744 | 0 | uint32_t u = uint64_hi32 (den); |
745 | 0 | uint32_t v = _cairo_uint64_to_uint32 (den); |
746 | | |
747 | | /* Compute a lower bound approximate quotient of num/den |
748 | | * from x/(u+1). Then we have |
749 | | * |
750 | | * x = q(u+1) + r ; q : 32 bits, r <= u : 32 bits. |
751 | | * |
752 | | * xB + y = q(u+1)B + (rB+y) |
753 | | * = q(uB + B + v - v) + (rB+y) |
754 | | * = q(uB + v) + qB - qv + (rB+y) |
755 | | * = q(uB + v) + q(B-v) + (rB+y) |
756 | | * |
757 | | * The true quotient of num/den then is q plus the |
758 | | * contribution of q(B-v) + (rB+y). The main contribution |
759 | | * comes from the term q(B-v), with the term (rB+y) only |
760 | | * contributing at most one part. |
761 | | * |
762 | | * The term q(B-v) must fit into 64 bits, since q fits into 32 |
763 | | * bits on account of being a lower bound to the true |
764 | | * quotient, and as B-v <= 2^32, we may safely use a single |
765 | | * 64/64 bit division to find its contribution. */ |
766 | |
|
767 | 0 | cairo_uquorem64_t quorem; |
768 | 0 | cairo_uint64_t remainder; /* will contain final remainder */ |
769 | 0 | uint32_t quotient; /* will contain final quotient. */ |
770 | 0 | uint32_t q; |
771 | 0 | uint32_t r; |
772 | | |
773 | | /* Approximate quotient by dividing the high 64 bits of num by |
774 | | * u+1. Watch out for overflow of u+1. */ |
775 | 0 | if (u+1) { |
776 | 0 | quorem = _cairo_uint64_divrem (x, _cairo_uint32_to_uint64 (u+1)); |
777 | 0 | q = _cairo_uint64_to_uint32 (quorem.quo); |
778 | 0 | r = _cairo_uint64_to_uint32 (quorem.rem); |
779 | 0 | } |
780 | 0 | else { |
781 | 0 | q = uint64_hi32 (x); |
782 | 0 | r = _cairo_uint64_to_uint32 (x); |
783 | 0 | } |
784 | 0 | quotient = q; |
785 | | |
786 | | /* Add the main term's contribution to quotient. Note B-v = |
787 | | * -v as an uint32 (unless v = 0) */ |
788 | 0 | if (v) |
789 | 0 | quorem = _cairo_uint64_divrem (_cairo_uint32x32_64_mul (q, -v), den); |
790 | 0 | else |
791 | 0 | quorem = _cairo_uint64_divrem (_cairo_uint32s_to_uint64 (q, 0), den); |
792 | 0 | quotient += _cairo_uint64_to_uint32 (quorem.quo); |
793 | | |
794 | | /* Add the contribution of the subterm and start computing the |
795 | | * true remainder. */ |
796 | 0 | remainder = _cairo_uint32s_to_uint64 (r, y); |
797 | 0 | if (_cairo_uint64_ge (remainder, den)) { |
798 | 0 | remainder = _cairo_uint64_sub (remainder, den); |
799 | 0 | quotient++; |
800 | 0 | } |
801 | | |
802 | | /* Add the contribution of the main term's remainder. The |
803 | | * funky test here checks that remainder + main_rem >= den, |
804 | | * taking into account overflow of the addition. */ |
805 | 0 | remainder = _cairo_uint64_add (remainder, quorem.rem); |
806 | 0 | if (_cairo_uint64_ge (remainder, den) || |
807 | 0 | _cairo_uint64_lt (remainder, quorem.rem)) |
808 | 0 | { |
809 | 0 | remainder = _cairo_uint64_sub (remainder, den); |
810 | 0 | quotient++; |
811 | 0 | } |
812 | |
|
813 | 0 | result.quo = _cairo_uint32_to_uint64 (quotient); |
814 | 0 | result.rem = remainder; |
815 | 0 | } |
816 | 0 | return result; |
817 | 0 | } |
818 | | |
819 | | cairo_quorem64_t |
820 | | _cairo_int_96by64_32x64_divrem (cairo_int128_t num, cairo_int64_t den) |
821 | 0 | { |
822 | 0 | int num_neg = _cairo_int128_negative (num); |
823 | 0 | int den_neg = _cairo_int64_negative (den); |
824 | 0 | cairo_uint64_t nonneg_den; |
825 | 0 | cairo_uquorem64_t uqr; |
826 | 0 | cairo_quorem64_t qr; |
827 | |
|
828 | 0 | if (num_neg) |
829 | 0 | num = _cairo_int128_negate (num); |
830 | 0 | if (den_neg) |
831 | 0 | nonneg_den = _cairo_int64_negate (den); |
832 | 0 | else |
833 | 0 | nonneg_den = den; |
834 | |
|
835 | 0 | uqr = _cairo_uint_96by64_32x64_divrem (num, nonneg_den); |
836 | 0 | if (_cairo_uint64_eq (uqr.rem, nonneg_den)) { |
837 | | /* bail on overflow. */ |
838 | 0 | qr.quo = _cairo_uint32s_to_uint64 (0x7FFFFFFF, -1U); |
839 | 0 | qr.rem = den; |
840 | 0 | return qr; |
841 | 0 | } |
842 | | |
843 | 0 | if (num_neg) |
844 | 0 | qr.rem = _cairo_int64_negate (uqr.rem); |
845 | 0 | else |
846 | 0 | qr.rem = uqr.rem; |
847 | 0 | if (num_neg != den_neg) |
848 | 0 | qr.quo = _cairo_int64_negate (uqr.quo); |
849 | 0 | else |
850 | 0 | qr.quo = uqr.quo; |
851 | 0 | return qr; |
852 | 0 | } |