LCOV - code coverage report
Current view: directory - gfx/cairo/cairo/src - cairo-wideint.c (source / functions) Found Hit Coverage
Test: app.info Lines: 200 0 0.0 %
Date: 2012-06-02 Functions: 23 0 0.0 %

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

Generated by: LCOV version 1.7