Home | History | Annotate | Line # | Download | only in sparc64
      1      1.1  mrg /* UltraSPARC 64 support macros.
      2      1.1  mrg 
      3      1.1  mrg    THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY.  THEY'RE ALMOST
      4      1.1  mrg    CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
      5      1.1  mrg    FUTURE GNU MP RELEASES.
      6      1.1  mrg 
      7      1.1  mrg Copyright 2003 Free Software Foundation, Inc.
      8      1.1  mrg 
      9      1.1  mrg This file is part of the GNU MP Library.
     10      1.1  mrg 
     11      1.1  mrg The GNU MP Library is free software; you can redistribute it and/or modify
     12  1.1.1.3  mrg it under the terms of either:
     13  1.1.1.3  mrg 
     14  1.1.1.3  mrg   * the GNU Lesser General Public License as published by the Free
     15  1.1.1.3  mrg     Software Foundation; either version 3 of the License, or (at your
     16  1.1.1.3  mrg     option) any later version.
     17  1.1.1.3  mrg 
     18  1.1.1.3  mrg or
     19  1.1.1.3  mrg 
     20  1.1.1.3  mrg   * the GNU General Public License as published by the Free Software
     21  1.1.1.3  mrg     Foundation; either version 2 of the License, or (at your option) any
     22  1.1.1.3  mrg     later version.
     23  1.1.1.3  mrg 
     24  1.1.1.3  mrg or both in parallel, as here.
     25      1.1  mrg 
     26      1.1  mrg The GNU MP Library is distributed in the hope that it will be useful, but
     27      1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     28  1.1.1.3  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     29  1.1.1.3  mrg for more details.
     30      1.1  mrg 
     31  1.1.1.3  mrg You should have received copies of the GNU General Public License and the
     32  1.1.1.3  mrg GNU Lesser General Public License along with the GNU MP Library.  If not,
     33  1.1.1.3  mrg see https://www.gnu.org/licenses/.  */
     34      1.1  mrg 
     35      1.1  mrg 
     36      1.1  mrg #define LOW32(x)   ((x) & 0xFFFFFFFF)
     37      1.1  mrg #define HIGH32(x)  ((x) >> 32)
     38      1.1  mrg 
     39      1.1  mrg 
     40      1.1  mrg /* Halfword number i in src is accessed as src[i+HALF_ENDIAN_ADJ(i)].
     41      1.1  mrg    Plain src[i] would be incorrect in big endian, HALF_ENDIAN_ADJ has the
     42      1.1  mrg    effect of swapping the two halves in this case.  */
     43      1.1  mrg #if HAVE_LIMB_BIG_ENDIAN
     44      1.1  mrg #define HALF_ENDIAN_ADJ(i)  (1 - (((i) & 1) << 1))   /* +1 even, -1 odd */
     45      1.1  mrg #endif
     46      1.1  mrg #if HAVE_LIMB_LITTLE_ENDIAN
     47      1.1  mrg #define HALF_ENDIAN_ADJ(i)  0                        /* no adjust */
     48      1.1  mrg #endif
     49      1.1  mrg #ifndef HALF_ENDIAN_ADJ
     50      1.1  mrg Error, error, unknown limb endianness;
     51      1.1  mrg #endif
     52      1.1  mrg 
     53      1.1  mrg 
     54      1.1  mrg /* umul_ppmm_lowequal sets h to the high limb of q*d, assuming the low limb
     55      1.1  mrg    of that product is equal to l.  dh and dl are the 32-bit halves of d.
     56      1.1  mrg 
     57      1.1  mrg    |-----high----||----low-----|
     58      1.1  mrg    +------+------+
     59      1.1  mrg    |             |                 ph = qh * dh
     60      1.1  mrg    +------+------+
     61      1.1  mrg           +------+------+
     62      1.1  mrg           |             |          pm1 = ql * dh
     63      1.1  mrg           +------+------+
     64      1.1  mrg           +------+------+
     65      1.1  mrg           |             |          pm2 = qh * dl
     66      1.1  mrg           +------+------+
     67      1.1  mrg                  +------+------+
     68      1.1  mrg                  |             |   pl = ql * dl (not calculated)
     69      1.1  mrg                  +------+------+
     70      1.1  mrg 
     71      1.1  mrg    Knowing that the low 64 bits is equal to l means that LOW(pm1) + LOW(pm2)
     72      1.1  mrg    + HIGH(pl) == HIGH(l).  The only thing we need from those product parts
     73      1.1  mrg    is whether they produce a carry into the high.
     74      1.1  mrg 
     75      1.1  mrg    pm_l = LOW(pm1)+LOW(pm2) is done to contribute its carry, then the only
     76      1.1  mrg    time there's a further carry from LOW(pm_l)+HIGH(pl) is if LOW(pm_l) >
     77      1.1  mrg    HIGH(l).  pl is never actually calculated.  */
     78      1.1  mrg 
     79      1.1  mrg #define umul_ppmm_lowequal(h, q, d, dh, dl, l)  \
     80      1.1  mrg   do {                                          \
     81      1.1  mrg     mp_limb_t  ql, qh, ph, pm1, pm2, pm_l;      \
     82      1.1  mrg     ASSERT (dh == HIGH32(d));                   \
     83      1.1  mrg     ASSERT (dl == LOW32(d));                    \
     84      1.1  mrg     ASSERT (q*d == l);                          \
     85      1.1  mrg                                                 \
     86      1.1  mrg     ql = LOW32 (q);                             \
     87      1.1  mrg     qh = HIGH32 (q);                            \
     88      1.1  mrg                                                 \
     89      1.1  mrg     pm1 = ql * dh;                              \
     90      1.1  mrg     pm2 = qh * dl;                              \
     91      1.1  mrg     ph  = qh * dh;                              \
     92      1.1  mrg                                                 \
     93      1.1  mrg     pm_l = LOW32 (pm1) + LOW32 (pm2);           \
     94      1.1  mrg                                                 \
     95      1.1  mrg     (h) = ph + HIGH32 (pm1) + HIGH32 (pm2)      \
     96      1.1  mrg       + HIGH32 (pm_l) + ((pm_l << 32) > l);     \
     97      1.1  mrg                                                 \
     98      1.1  mrg     ASSERT_HIGH_PRODUCT (h, q, d);              \
     99      1.1  mrg   } while (0)
    100      1.1  mrg 
    101      1.1  mrg 
    102      1.1  mrg /* Set h to the high of q*d, assuming the low limb of that product is equal
    103      1.1  mrg    to l, and that d fits in 32-bits.
    104      1.1  mrg 
    105      1.1  mrg    |-----high----||----low-----|
    106      1.1  mrg           +------+------+
    107      1.1  mrg           |             |          pm = qh * dl
    108      1.1  mrg           +------+------+
    109      1.1  mrg                  +------+------+
    110      1.1  mrg                  |             |   pl = ql * dl (not calculated)
    111      1.1  mrg                  +------+------+
    112      1.1  mrg 
    113      1.1  mrg    Knowing that LOW(pm) + HIGH(pl) == HIGH(l) (mod 2^32) means that the only
    114      1.1  mrg    time there's a carry from that sum is when LOW(pm) > HIGH(l).  There's no
    115      1.1  mrg    need to calculate pl to determine this.  */
    116      1.1  mrg 
    117      1.1  mrg #define umul_ppmm_half_lowequal(h, q, d, l)     \
    118      1.1  mrg   do {                                          \
    119      1.1  mrg     mp_limb_t pm;                               \
    120      1.1  mrg     ASSERT (q*d == l);                          \
    121      1.1  mrg     ASSERT (HIGH32(d) == 0);                    \
    122      1.1  mrg                                                 \
    123      1.1  mrg     pm = HIGH32(q) * d;                         \
    124      1.1  mrg     (h) = HIGH32(pm) + ((pm << 32) > l);        \
    125      1.1  mrg     ASSERT_HIGH_PRODUCT (h, q, d);              \
    126      1.1  mrg   } while (0)
    127      1.1  mrg 
    128      1.1  mrg 
    129      1.1  mrg /* check that h is the high limb of x*y */
    130      1.1  mrg #if WANT_ASSERT
    131      1.1  mrg #define ASSERT_HIGH_PRODUCT(h, x, y)    \
    132      1.1  mrg   do {                                  \
    133      1.1  mrg     mp_limb_t  want_h, dummy;           \
    134      1.1  mrg     umul_ppmm (want_h, dummy, x, y);    \
    135      1.1  mrg     ASSERT (h == want_h);               \
    136      1.1  mrg   } while (0)
    137      1.1  mrg #else
    138      1.1  mrg #define ASSERT_HIGH_PRODUCT(h, q, d)    \
    139      1.1  mrg   do { } while (0)
    140      1.1  mrg #endif
    141      1.1  mrg 
    142      1.1  mrg 
    143  1.1.1.2  mrg /* Multiply u anv v, where v < 2^32.  */
    144  1.1.1.2  mrg #define umul_ppmm_s(w1, w0, u, v)					\
    145  1.1.1.2  mrg   do {									\
    146  1.1.1.2  mrg     UWtype __x0, __x2;							\
    147  1.1.1.2  mrg     UWtype __ul, __vl, __uh;						\
    148  1.1.1.2  mrg     UWtype __u = (u), __v = (v);					\
    149  1.1.1.2  mrg 									\
    150  1.1.1.2  mrg     __ul = __ll_lowpart (__u);						\
    151  1.1.1.2  mrg     __uh = __ll_highpart (__u);						\
    152  1.1.1.2  mrg     __vl = __ll_lowpart (__v);						\
    153  1.1.1.2  mrg 									\
    154  1.1.1.2  mrg     __x0 = (UWtype) __ul * __vl;					\
    155  1.1.1.2  mrg     __x2 = (UWtype) __uh * __vl;					\
    156  1.1.1.2  mrg 									\
    157  1.1.1.2  mrg     (w1) = (__x2 + (__x0 >> W_TYPE_SIZE/2)) >> W_TYPE_SIZE/2;		\
    158  1.1.1.2  mrg     (w0) = (__x2 << W_TYPE_SIZE/2) + __x0;				\
    159  1.1.1.2  mrg   } while (0)
    160  1.1.1.2  mrg 
    161      1.1  mrg /* Count the leading zeros on a limb, but assuming it fits in 32 bits.
    162      1.1  mrg    The count returned will be in the range 32 to 63.
    163      1.1  mrg    This is the 32-bit generic C count_leading_zeros from longlong.h. */
    164      1.1  mrg #define count_leading_zeros_32(count, x)                                      \
    165      1.1  mrg   do {                                                                        \
    166      1.1  mrg     mp_limb_t  __xr = (x);                                                    \
    167      1.1  mrg     unsigned   __a;                                                           \
    168      1.1  mrg     ASSERT ((x) != 0);                                                        \
    169      1.1  mrg     ASSERT ((x) <= CNST_LIMB(0xFFFFFFFF));                                    \
    170      1.1  mrg     __a = __xr < ((UWtype) 1 << 16) ? (__xr < ((UWtype) 1 << 8) ? 1 : 8 + 1)  \
    171      1.1  mrg       : (__xr < ((UWtype) 1 << 24)  ? 16 + 1 : 24 + 1);                       \
    172      1.1  mrg                                                                               \
    173      1.1  mrg     (count) = W_TYPE_SIZE + 1 - __a - __clz_tab[__xr >> __a];                 \
    174      1.1  mrg   } while (0)
    175      1.1  mrg 
    176      1.1  mrg 
    177      1.1  mrg /* Set inv to a 32-bit inverse floor((b*(b-d)-1) / d), knowing that d fits
    178      1.1  mrg    32 bits and is normalized (high bit set).  */
    179      1.1  mrg #define invert_half_limb(inv, d)                \
    180      1.1  mrg   do {                                          \
    181      1.1  mrg     mp_limb_t  _n;                              \
    182      1.1  mrg     ASSERT ((d) <= 0xFFFFFFFF);                 \
    183      1.1  mrg     ASSERT ((d) & 0x80000000);                  \
    184      1.1  mrg     _n = (((mp_limb_t) -(d)) << 32) - 1;        \
    185      1.1  mrg     (inv) = (mp_limb_t) (unsigned) (_n / (d));  \
    186      1.1  mrg   } while (0)
    187      1.1  mrg 
    188      1.1  mrg 
    189      1.1  mrg /* Divide nh:nl by d, setting q to the quotient and r to the remainder.
    190      1.1  mrg    q, r, nh and nl are 32-bits each, d_limb is 32-bits but in an mp_limb_t,
    191      1.1  mrg    dinv_limb is similarly a 32-bit inverse but in an mp_limb_t.  */
    192      1.1  mrg 
    193      1.1  mrg #define udiv_qrnnd_half_preinv(q, r, nh, nl, d_limb, dinv_limb)         \
    194      1.1  mrg   do {                                                                  \
    195      1.1  mrg     unsigned   _n2, _n10, _n1, _nadj, _q11n, _xh, _r, _q;               \
    196      1.1  mrg     mp_limb_t  _n, _x;                                                  \
    197      1.1  mrg     ASSERT (d_limb <= 0xFFFFFFFF);                                      \
    198      1.1  mrg     ASSERT (dinv_limb <= 0xFFFFFFFF);                                   \
    199      1.1  mrg     ASSERT (d_limb & 0x80000000);                                       \
    200      1.1  mrg     ASSERT (nh < d_limb);                                               \
    201      1.1  mrg     _n10 = (nl);                                                        \
    202      1.1  mrg     _n2 = (nh);                                                         \
    203      1.1  mrg     _n1 = (int) _n10 >> 31;                                             \
    204      1.1  mrg     _nadj = _n10 + (_n1 & d_limb);                                      \
    205      1.1  mrg     _x = dinv_limb * (_n2 - _n1) + _nadj;                               \
    206      1.1  mrg     _q11n = ~(_n2 + HIGH32 (_x));             /* -q1-1 */               \
    207      1.1  mrg     _n = ((mp_limb_t) _n2 << 32) + _n10;                                \
    208      1.1  mrg     _x = _n + d_limb * _q11n;                 /* n-q1*d-d */            \
    209      1.1  mrg     _xh = HIGH32 (_x) - d_limb;               /* high(n-q1*d-d) */      \
    210      1.1  mrg     ASSERT (_xh == 0 || _xh == ~0);                                     \
    211      1.1  mrg     _r = _x + (d_limb & _xh);                 /* addback */             \
    212      1.1  mrg     _q = _xh - _q11n;                         /* q1+1-addback */        \
    213      1.1  mrg     ASSERT (_r < d_limb);                                               \
    214      1.1  mrg     ASSERT (d_limb * _q + _r == _n);                                    \
    215      1.1  mrg     (r) = _r;                                                           \
    216      1.1  mrg     (q) = _q;                                                           \
    217      1.1  mrg   } while (0)
    218