A Discrete-Event Network Simulator
API
cairo-wideint.c
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /* cairo - a vector graphics library with display and print output
3  *
4  * Copyright © 2004 Keith Packard
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * The original code as contributed to the cairo library under
20  * the dual license MPL+LGPL. We used the LGPL relicensing clause to
21  * get a GPL version of this code which now lives here. This header is
22  * unmodified other than the licensing clause.
23  *
24  * The Original Code is the cairo graphics library.
25  *
26  * The Initial Developer of the Original Code is Keith Packard
27  *
28  * Contributor(s):
29  * Keith R. Packard <keithp@keithp.com>
30  */
31 
32 #include "cairo-wideint-private.h"
33 
40 #if HAVE_UINT64_T
41 
42 const char * cairo_impl64 = "uint64_t";
43 
44 #define _cairo_uint32s_to_uint64(h,l) ((uint64_t) (h) << 32 | (l))
45 
48 {
50 
51  qr.quo = num / den;
52  qr.rem = num % den;
53  return qr;
54 }
55 
56 #else
57 
58 const char * cairo_impl64 = "uint32_t";
59 
61 _cairo_uint32_to_uint64 (uint32_t i)
62 {
64 
65  q.lo = i;
66  q.hi = 0;
67  return q;
68 }
69 
71 _cairo_int32_to_int64 (int32_t i)
72 {
74 
75  q.lo = i;
76  q.hi = i < 0 ? -1 : 0;
77  return q;
78 }
79 
80 static cairo_uint64_t
81 _cairo_uint32s_to_uint64 (uint32_t h, uint32_t l)
82 {
84 
85  q.lo = l;
86  q.hi = h;
87  return q;
88 }
89 
92 {
94 
95  s.hi = a.hi + b.hi;
96  s.lo = a.lo + b.lo;
97  if (s.lo < a.lo)
98  s.hi++;
99  return s;
100 }
101 
104 {
105  cairo_uint64_t s;
106 
107  s.hi = a.hi - b.hi;
108  s.lo = a.lo - b.lo;
109  if (s.lo > a.lo)
110  s.hi--;
111  return s;
112 }
113 
114 #define uint32_lo(i) ((i) & 0xffff)
115 #define uint32_hi(i) ((i) >> 16)
116 #define uint32_carry16 ((1) << 16)
117 
119 _cairo_uint32x32_64_mul (uint32_t a, uint32_t b)
120 {
121  cairo_uint64_t s;
122 
123  uint16_t ah, al, bh, bl;
124  uint32_t r0, r1, r2, r3;
125 
126  al = uint32_lo (a);
127  ah = uint32_hi (a);
128  bl = uint32_lo (b);
129  bh = uint32_hi (b);
130 
131  r0 = (uint32_t) al * bl;
132  r1 = (uint32_t) al * bh;
133  r2 = (uint32_t) ah * bl;
134  r3 = (uint32_t) ah * bh;
135 
136  r1 += uint32_hi(r0); /* no carry possible */
137  r1 += r2; /* but this can carry */
138  if (r1 < r2) /* check */
139  r3 += uint32_carry16;
140 
141  s.hi = r3 + uint32_hi(r1);
142  s.lo = (uint32_lo (r1) << 16) + uint32_lo (r0);
143  return s;
144 }
145 
147 _cairo_int32x32_64_mul (int32_t a, int32_t b)
148 {
149  cairo_int64_t s;
150  s = _cairo_uint32x32_64_mul ((uint32_t) a, (uint32_t) b);
151  if (a < 0)
152  s.hi -= b;
153  if (b < 0)
154  s.hi -= a;
155  return s;
156 }
157 
160 {
161  cairo_uint64_t s;
162 
163  s = _cairo_uint32x32_64_mul (a.lo, b.lo);
164  s.hi += a.lo * b.hi + a.hi * b.lo;
165  return s;
166 }
167 
169 _cairo_uint64_lsl (cairo_uint64_t a, int shift)
170 {
171  if (shift >= 32)
172  {
173  a.hi = a.lo;
174  a.lo = 0;
175  shift -= 32;
176  }
177  if (shift)
178  {
179  a.hi = a.hi << shift | a.lo >> (32 - shift);
180  a.lo = a.lo << shift;
181  }
182  return a;
183 }
184 
186 _cairo_uint64_rsl (cairo_uint64_t a, int shift)
187 {
188  if (shift >= 32)
189  {
190  a.lo = a.hi;
191  a.hi = 0;
192  shift -= 32;
193  }
194  if (shift)
195  {
196  a.lo = a.lo >> shift | a.hi << (32 - shift);
197  a.hi = a.hi >> shift;
198  }
199  return a;
200 }
201 
202 #define _cairo_uint32_rsa(a,n) ((uint32_t) (((int32_t) (a)) >> (n)))
203 
205 _cairo_uint64_rsa (cairo_int64_t a, int shift)
206 {
207  if (shift >= 32)
208  {
209  a.lo = a.hi;
210  a.hi = _cairo_uint32_rsa (a.hi, 31);
211  shift -= 32;
212  }
213  if (shift)
214  {
215  a.lo = a.lo >> shift | a.hi << (32 - shift);
216  a.hi = _cairo_uint32_rsa (a.hi, shift);
217  }
218  return a;
219 }
220 
221 int
223 {
224  return (a.hi < b.hi ||
225  (a.hi == b.hi && a.lo < b.lo));
226 }
227 
228 int
230 {
231  return a.hi == b.hi && a.lo == b.lo;
232 }
233 
234 int
236 {
238  return 1;
240  return 0;
241  return _cairo_uint64_lt (a, b);
242 }
243 
246 {
247  a.lo = ~a.lo;
248  a.hi = ~a.hi;
249  return a;
250 }
251 
254 {
255  a.lo = ~a.lo;
256  a.hi = ~a.hi;
257  if (++a.lo == 0)
258  ++a.hi;
259  return a;
260 }
261 
262 /*
263  * Simple bit-at-a-time divide.
264  */
267 {
269  cairo_uint64_t bit;
270  cairo_uint64_t quo;
271 
272  bit = _cairo_uint32_to_uint64 (1);
273 
274  /* normalize to make den >= num, but not overflow */
275  while (_cairo_uint64_lt (den, num) && (den.hi & 0x80000000) == 0)
276  {
277  bit = _cairo_uint64_lsl (bit, 1);
278  den = _cairo_uint64_lsl (den, 1);
279  }
280  quo = _cairo_uint32_to_uint64 (0);
281 
282  /* generate quotient, one bit at a time */
283  while (bit.hi | bit.lo)
284  {
285  if (_cairo_uint64_le (den, num))
286  {
287  num = _cairo_uint64_sub (num, den);
288  quo = _cairo_uint64_add (quo, bit);
289  }
290  bit = _cairo_uint64_rsl (bit, 1);
291  den = _cairo_uint64_rsl (den, 1);
292  }
293  qr.quo = quo;
294  qr.rem = num;
295  return qr;
296 }
297 
298 #endif /* !HAVE_UINT64_T */
299 
302 {
303  int num_neg = _cairo_int64_negative (num);
304  int den_neg = _cairo_int64_negative (den);
305  cairo_uquorem64_t uqr;
306  cairo_quorem64_t qr;
307 
308  if (num_neg)
309  num = _cairo_int64_negate (num);
310  if (den_neg)
311  den = _cairo_int64_negate (den);
312  uqr = _cairo_uint64_divrem (num, den);
313  if (num_neg)
314  qr.rem = _cairo_int64_negate (uqr.rem);
315  else
316  qr.rem = uqr.rem;
317  if (num_neg != den_neg)
319  else
320  qr.quo = (cairo_int64_t) uqr.quo;
321  return qr;
322 }
323 
324 #if HAVE_UINT128_T
325 
326 const char * cairo_impl128 = "uint128_t";
327 
329 _cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den)
330 {
332 
333  qr.quo = num / den;
334  qr.rem = num % den;
335  return qr;
336 }
337 
338 #else
339 
340 const char * cairo_impl128 = "cairo_uint64_t";
341 
342 cairo_uint128_t
344 {
345  cairo_uint128_t q;
346 
347  q.lo = _cairo_uint32_to_uint64 (i);
348  q.hi = _cairo_uint32_to_uint64 (0);
349  return q;
350 }
351 
354 {
355  cairo_int128_t q;
356 
357  q.lo = _cairo_int32_to_int64 (i);
358  q.hi = _cairo_int32_to_int64 (i < 0 ? -1 : 0);
359  return q;
360 }
361 
362 cairo_uint128_t
364 {
365  cairo_uint128_t q;
366 
367  q.lo = i;
368  q.hi = _cairo_uint32_to_uint64 (0);
369  return q;
370 }
371 
374 {
375  cairo_int128_t q;
376 
377  q.lo = i;
379  return q;
380 }
381 
382 cairo_uint128_t
383 _cairo_uint128_add (cairo_uint128_t a, cairo_uint128_t b)
384 {
385  cairo_uint128_t s;
386 
387  s.hi = _cairo_uint64_add (a.hi, b.hi);
388  s.lo = _cairo_uint64_add (a.lo, b.lo);
389  if (_cairo_uint64_lt (s.lo, a.lo))
390  s.hi = _cairo_uint64_add (s.hi, _cairo_uint32_to_uint64 (1));
391  return s;
392 }
393 
394 cairo_uint128_t
395 _cairo_uint128_sub (cairo_uint128_t a, cairo_uint128_t b)
396 {
397  cairo_uint128_t s;
398 
399  s.hi = _cairo_uint64_sub (a.hi, b.hi);
400  s.lo = _cairo_uint64_sub (a.lo, b.lo);
401  if (_cairo_uint64_gt (s.lo, a.lo))
402  s.hi = _cairo_uint64_sub (s.hi, _cairo_uint32_to_uint64(1));
403  return s;
404 }
405 
406 #if HAVE_UINT64_T
407 
408 #define uint64_lo32(i) ((i) & 0xffffffff)
409 #define uint64_hi32(i) ((i) >> 32)
410 #define uint64_lo(i) ((i) & 0xffffffff)
411 #define uint64_hi(i) ((i) >> 32)
412 #define uint64_shift32(i) ((i) << 32)
413 #define uint64_carry32 (((uint64_t) 1) << 32)
414 
415 #else
416 
417 #define uint64_lo32(i) ((i).lo)
418 #define uint64_hi32(i) ((i).hi)
419 
420 static cairo_uint64_t
422 {
423  cairo_uint64_t s;
424 
425  s.lo = i.lo;
426  s.hi = 0;
427  return s;
428 }
429 
430 static cairo_uint64_t
432 {
433  cairo_uint64_t s;
434 
435  s.lo = i.hi;
436  s.hi = 0;
437  return s;
438 }
439 
440 static cairo_uint64_t
442 {
443  cairo_uint64_t s;
444 
445  s.lo = 0;
446  s.hi = i.lo;
447  return s;
448 }
449 
450 static const cairo_uint64_t uint64_carry32 = { 0, 1 };
451 
452 #endif
453 
454 cairo_uint128_t
456 {
457  cairo_uint128_t s;
458  uint32_t ah, al, bh, bl;
459  cairo_uint64_t r0, r1, r2, r3;
460 
461  al = uint64_lo32 (a);
462  ah = uint64_hi32 (a);
463  bl = uint64_lo32 (b);
464  bh = uint64_hi32 (b);
465 
466  r0 = _cairo_uint32x32_64_mul (al, bl);
467  r1 = _cairo_uint32x32_64_mul (al, bh);
468  r2 = _cairo_uint32x32_64_mul (ah, bl);
469  r3 = _cairo_uint32x32_64_mul (ah, bh);
470 
471  r1 = _cairo_uint64_add (r1, uint64_hi (r0)); /* no carry possible */
472  r1 = _cairo_uint64_add (r1, r2); /* but this can carry */
473  if (_cairo_uint64_lt (r1, r2)) /* check */
474  r3 = _cairo_uint64_add (r3, uint64_carry32);
475 
476  s.hi = _cairo_uint64_add (r3, uint64_hi(r1));
477  s.lo = _cairo_uint64_add (uint64_shift32 (r1),
478  uint64_lo (r0));
479  return s;
480 }
481 
484 {
485  cairo_int128_t s;
488  if (_cairo_int64_negative (a))
489  s.hi = _cairo_uint64_sub (s.hi,
491  if (_cairo_int64_negative (b))
492  s.hi = _cairo_uint64_sub (s.hi,
494  return s;
495 }
496 
497 cairo_uint128_t
498 _cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b)
499 {
500  cairo_uint128_t s;
501 
502  s = _cairo_uint64x64_128_mul (a.lo, b.lo);
503  s.hi = _cairo_uint64_add (s.hi,
504  _cairo_uint64_mul (a.lo, b.hi));
505  s.hi = _cairo_uint64_add (s.hi,
506  _cairo_uint64_mul (a.hi, b.lo));
507  return s;
508 }
509 
510 cairo_uint128_t
511 _cairo_uint128_lsl (cairo_uint128_t a, int shift)
512 {
513  if (shift >= 64)
514  {
515  a.hi = a.lo;
516  a.lo = _cairo_uint32_to_uint64 (0);
517  shift -= 64;
518  }
519  if (shift)
520  {
521  a.hi = _cairo_uint64_add (_cairo_uint64_lsl (a.hi, shift),
522  _cairo_uint64_rsl (a.lo, (64 - shift)));
523  a.lo = _cairo_uint64_lsl (a.lo, shift);
524  }
525  return a;
526 }
527 
528 cairo_uint128_t
529 _cairo_uint128_rsl (cairo_uint128_t a, int shift)
530 {
531  if (shift >= 64)
532  {
533  a.lo = a.hi;
534  a.hi = _cairo_uint32_to_uint64 (0);
535  shift -= 64;
536  }
537  if (shift)
538  {
539  a.lo = _cairo_uint64_add (_cairo_uint64_rsl (a.lo, shift),
540  _cairo_uint64_lsl (a.hi, (64 - shift)));
541  a.hi = _cairo_uint64_rsl (a.hi, shift);
542  }
543  return a;
544 }
545 
546 cairo_uint128_t
548 {
549  if (shift >= 64)
550  {
551  a.lo = a.hi;
552  a.hi = _cairo_uint64_rsa (a.hi, 64-1);
553  shift -= 64;
554  }
555  if (shift)
556  {
557  a.lo = _cairo_uint64_add (_cairo_uint64_rsl (a.lo, shift),
558  _cairo_uint64_lsl (a.hi, (64 - shift)));
559  a.hi = _cairo_uint64_rsa (a.hi, shift);
560  }
561  return a;
562 }
563 
564 int
565 _cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b)
566 {
567  return (_cairo_uint64_lt (a.hi, b.hi) ||
568  (_cairo_uint64_eq (a.hi, b.hi) &&
569  _cairo_uint64_lt (a.lo, b.lo)));
570 }
571 
572 int
574 {
576  return 1;
578  return 0;
579  return _cairo_uint128_lt (a, b);
580 }
581 
582 int
583 _cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b)
584 {
585  return (_cairo_uint64_eq (a.hi, b.hi) &&
586  _cairo_uint64_eq (a.lo, b.lo));
587 }
588 
589 #if HAVE_UINT64_T
590 #define _cairo_msbset64(q) (q & ((uint64_t) 1 << 63))
591 #else
592 #define _cairo_msbset64(q) (q.hi & ((uint32_t) 1 << 31))
593 #endif
594 
596 _cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den)
597 {
599  cairo_uint128_t bit;
600  cairo_uint128_t quo;
601 
602  bit = _cairo_uint32_to_uint128 (1);
603 
604  /* normalize to make den >= num, but not overflow */
605  while (_cairo_uint128_lt (den, num) && !_cairo_msbset64(den.hi))
606  {
607  bit = _cairo_uint128_lsl (bit, 1);
608  den = _cairo_uint128_lsl (den, 1);
609  }
610  quo = _cairo_uint32_to_uint128 (0);
611 
612  /* generate quotient, one bit at a time */
614  {
615  if (_cairo_uint128_le (den, num))
616  {
617  num = _cairo_uint128_sub (num, den);
618  quo = _cairo_uint128_add (quo, bit);
619  }
620  bit = _cairo_uint128_rsl (bit, 1);
621  den = _cairo_uint128_rsl (den, 1);
622  }
623  qr.quo = quo;
624  qr.rem = num;
625  return qr;
626 }
627 
628 cairo_uint128_t
629 _cairo_uint128_negate (cairo_uint128_t a)
630 {
631  a.lo = _cairo_uint64_not (a.lo);
632  a.hi = _cairo_uint64_not (a.hi);
634 }
635 
636 cairo_uint128_t
637 _cairo_uint128_not (cairo_uint128_t a)
638 {
639  a.lo = _cairo_uint64_not (a.lo);
640  a.hi = _cairo_uint64_not (a.hi);
641  return a;
642 }
643 
644 #endif /* !HAVE_UINT128_T */
645 
648 {
649  int num_neg = _cairo_int128_negative (num);
650  int den_neg = _cairo_int128_negative (den);
651  cairo_uquorem128_t uqr;
653 
654  if (num_neg)
655  num = _cairo_int128_negate (num);
656  if (den_neg)
657  den = _cairo_int128_negate (den);
658  uqr = _cairo_uint128_divrem (num, den);
659  if (num_neg)
660  qr.rem = _cairo_int128_negate (uqr.rem);
661  else
662  qr.rem = uqr.rem;
663  if (num_neg != den_neg)
664  qr.quo = _cairo_int128_negate (uqr.quo);
665  else
666  qr.quo = uqr.quo;
667  return qr;
668 }
669 
680 _cairo_uint_96by64_32x64_divrem (cairo_uint128_t num,
681  cairo_uint64_t den)
682 {
683  cairo_uquorem64_t result;
685 
686  /* These are the high 64 bits of the *96* bit numerator. We're
687  * going to represent the numerator as xB + y, where x is a 64,
688  * and y is a 32 bit number. */
690 
691  /* Initialise the result to indicate overflow. */
692  result.quo = _cairo_uint32s_to_uint64 (-1U, -1U);
693  result.rem = den;
694 
695  /* Don't bother if the quotient is going to overflow. */
696  if (_cairo_uint64_ge (x, den)) {
697  return /* overflow */ result;
698  }
699 
700  if (_cairo_uint64_lt (x, B)) {
701  /* When the final quotient is known to fit in 32 bits, then
702  * num < 2^64 if and only if den < 2^32. */
704  }
705  else {
706  /* Denominator is >= 2^32. the numerator is >= 2^64, and the
707  * division won't overflow: need two divrems. Write the
708  * numerator and denominator as
709  *
710  * num = xB + y x : 64 bits, y : 32 bits
711  * den = uB + v u, v : 32 bits
712  */
713  uint32_t y = _cairo_uint128_to_uint32 (num);
714  uint32_t u = uint64_hi32 (den);
715  uint32_t v = _cairo_uint64_to_uint32 (den);
716 
717  /* Compute a lower bound approximate quotient of num/den
718  * from x/(u+1). Then we have
719  *
720  * x = q(u+1) + r ; q : 32 bits, r <= u : 32 bits.
721  *
722  * xB + y = q(u+1)B + (rB+y)
723  * = q(uB + B + v - v) + (rB+y)
724  * = q(uB + v) + qB - qv + (rB+y)
725  * = q(uB + v) + q(B-v) + (rB+y)
726  *
727  * The true quotient of num/den then is q plus the
728  * contribution of q(B-v) + (rB+y). The main contribution
729  * comes from the term q(B-v), with the term (rB+y) only
730  * contributing at most one part.
731  *
732  * The term q(B-v) must fit into 64 bits, since q fits into 32
733  * bits on account of being a lower bound to the true
734  * quotient, and as B-v <= 2^32, we may safely use a single
735  * 64/64 bit division to find its contribution. */
736 
737  cairo_uquorem64_t quorem;
738  cairo_uint64_t remainder; /* will contain final remainder */
739  uint32_t quotient; /* will contain final quotient. */
740  uint32_t q;
741  uint32_t r;
742 
743  /* Approximate quotient by dividing the high 64 bits of num by
744  * u+1. Watch out for overflow of u+1. */
745  if (u+1) {
746  quorem = _cairo_uint64_divrem (x, _cairo_uint32_to_uint64 (u+1));
747  q = _cairo_uint64_to_uint32 (quorem.quo);
748  r = _cairo_uint64_to_uint32 (quorem.rem);
749  }
750  else {
751  q = uint64_hi32 (x);
752  r = _cairo_uint64_to_uint32 (x);
753  }
754  quotient = q;
755 
756  /* Add the main term's contribution to quotient. Note B-v =
757  * -v as an uint32 (unless v = 0) */
758  if (v)
759  quorem = _cairo_uint64_divrem (_cairo_uint32x32_64_mul (q, -v), den);
760  else
761  quorem = _cairo_uint64_divrem (_cairo_uint32s_to_uint64 (q, 0), den);
762  quotient += _cairo_uint64_to_uint32 (quorem.quo);
763 
764  /* Add the contribution of the subterm and start computing the
765  * true remainder. */
766  remainder = _cairo_uint32s_to_uint64 (r, y);
767  if (_cairo_uint64_ge (remainder, den)) {
768  remainder = _cairo_uint64_sub (remainder, den);
769  quotient++;
770  }
771 
772  /* Add the contribution of the main term's remainder. The
773  * funky test here checks that remainder + main_rem >= den,
774  * taking into account overflow of the addition. */
775  remainder = _cairo_uint64_add (remainder, quorem.rem);
776  if (_cairo_uint64_ge (remainder, den) ||
777  _cairo_uint64_lt (remainder, quorem.rem))
778  {
779  remainder = _cairo_uint64_sub (remainder, den);
780  quotient++;
781  }
782 
783  result.quo = _cairo_uint32_to_uint64 (quotient);
784  result.rem = remainder;
785  }
786  return result;
787 }
788 
791 {
792  int num_neg = _cairo_int128_negative (num);
793  int den_neg = _cairo_int64_negative (den);
794  cairo_uint64_t nonneg_den;
795  cairo_uquorem64_t uqr;
796  cairo_quorem64_t qr;
797 
798  if (num_neg)
799  num = _cairo_int128_negate (num);
800  if (den_neg)
801  nonneg_den = _cairo_int64_negate (den);
802  else
803  nonneg_den = den;
804 
805  uqr = _cairo_uint_96by64_32x64_divrem (num, nonneg_den);
806  if (_cairo_uint64_eq (uqr.rem, _cairo_int64_to_uint64 (nonneg_den))) {
807  /* bail on overflow. */
808  qr.quo = _cairo_uint32s_to_uint64 (0x7FFFFFFF, -1U);;
809  qr.rem = den;
810  return qr;
811  }
812 
813  if (num_neg)
814  qr.rem = _cairo_int64_negate (uqr.rem);
815  else
816  qr.rem = uqr.rem;
817  if (num_neg != den_neg)
818  qr.quo = _cairo_int64_negate (uqr.quo);
819  else
820  qr.quo = uqr.quo;
821  return qr;
822 }
const char * cairo_impl64
Definition: cairo-wideint.c:42
#define _cairo_int64_to_uint64(i)
#define _cairo_uint64_le(a, b)
int _cairo_uint128_lt(cairo_uint128_t a, cairo_uint128_t b)
cairo_uint128_t _cairo_uint32_to_uint128(uint32_t i)
cairo_uint128_t _cairo_uint128_not(cairo_uint128_t a)
#define _cairo_uint64_rsa(a, b)
cairo_uint128_t _cairo_uint128_negate(cairo_uint128_t a)
#define _cairo_uint32x32_64_mul(a, b)
#define _cairo_uint64_not(a)
int64_t cairo_int64_t
#define _cairo_uint128_to_uint64(a)
#define _cairo_msbset64(q)
int _cairo_uint128_eq(cairo_uint128_t a, cairo_uint128_t b)
cairo_int128_t _cairo_int64x64_128_mul(cairo_int64_t a, cairo_int64_t b)
#define _cairo_uint64_lsl(a, b)
#define uint64_lo(i)
#define uint64_hi32(i)
cairo_uint128_t _cairo_uint128_mul(cairo_uint128_t a, cairo_uint128_t b)
cairo_uquorem64_t _cairo_uint_96by64_32x64_divrem(cairo_uint128_t num, cairo_uint64_t den)
_cairo_uint_96by64_32x64_divrem:
cairo_uint128_t _cairo_uint64_to_uint128(cairo_uint64_t i)
#define _cairo_uint64_gt(a, b)
#define _cairo_uint32s_to_uint64(h, l)
Definition: cairo-wideint.c:44
#define _cairo_uint128_to_uint32(a)
#define _cairo_uint64_to_uint32(i)
#define _cairo_uint64_mul(a, b)
#define _cairo_uint64_rsl(a, b)
cairo_uquorem128_t _cairo_uint128_divrem(cairo_uint128_t num, cairo_uint128_t den)
cairo_uint128_t _cairo_uint128_sub(cairo_uint128_t a, cairo_uint128_t b)
#define _cairo_int64_negative(a)
#define _cairo_uint32_to_uint64(i)
#define _cairo_int32x32_64_mul(a, b)
cairo_uquorem64_t _cairo_uint64_divrem(cairo_uint64_t num, cairo_uint64_t den)
Definition: cairo-wideint.c:47
#define uint64_hi(i)
#define uint64_shift32(i)
#define _cairo_int64_negate(a)
cairo_uint128_t _cairo_uint128_lsl(cairo_uint128_t a, int shift)
#define _cairo_int128_negative(a)
cairo_uint128_t _cairo_uint128_rsa(cairo_int128_t a, int shift)
cairo_quorem64_t _cairo_int64_divrem(cairo_int64_t num, cairo_int64_t den)
uint64_t cairo_uint64_t
const char * cairo_impl128
cairo_quorem64_t _cairo_int_96by64_32x64_divrem(cairo_int128_t num, cairo_int64_t den)
#define _cairo_uint64_add(a, b)
#define _cairo_uint128_le(a, b)
Declaration of the cairo_x functions which implement high precision arithmetic.
#define uint64_lo32(i)
cairo_uint128_t _cairo_uint64x64_128_mul(cairo_uint64_t a, cairo_uint64_t b)
#define _cairo_uint64_negate(a)
cairo_int128_t _cairo_int32_to_int128(int32_t i)
#define _cairo_int128_negate(a)
#define _cairo_uint64_lt(a, b)
int _cairo_int128_lt(cairo_int128_t a, cairo_int128_t b)
#define _cairo_uint64_ge(a, b)
#define _cairo_uint128_ne(a, b)
#define _cairo_int32_to_int64(i)
cairo_uint128_t _cairo_uint128_rsl(cairo_uint128_t a, int shift)
cairo_uint128_t _cairo_uint128_add(cairo_uint128_t a, cairo_uint128_t b)
#define _cairo_uint64_sub(a, b)
#define uint64_carry32
#define _cairo_int64_lt(a, b)
#define _cairo_uint64_eq(a, b)
cairo_int128_t _cairo_int64_to_int128(cairo_int64_t i)
cairo_quorem128_t _cairo_int128_divrem(cairo_int128_t num, cairo_int128_t den)