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