Home | History | Annotate | Line # | Download | only in libbid
      1  1.12  mrg /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
      2   1.1  mrg 
      3   1.1  mrg This file is part of GCC.
      4   1.1  mrg 
      5   1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      6   1.1  mrg the terms of the GNU General Public License as published by the Free
      7   1.1  mrg Software Foundation; either version 3, or (at your option) any later
      8   1.1  mrg version.
      9   1.1  mrg 
     10   1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     11   1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     12   1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     13   1.1  mrg for more details.
     14   1.1  mrg 
     15   1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     16   1.1  mrg permissions described in the GCC Runtime Library Exception, version
     17   1.1  mrg 3.1, as published by the Free Software Foundation.
     18   1.1  mrg 
     19   1.1  mrg You should have received a copy of the GNU General Public License and
     20   1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     21   1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     22   1.1  mrg <http://www.gnu.org/licenses/>.  */
     23   1.1  mrg 
     24   1.1  mrg /*****************************************************************************
     25   1.1  mrg  *    BID64 divide
     26   1.1  mrg  *****************************************************************************
     27   1.1  mrg  *
     28   1.1  mrg  *  Algorithm description:
     29   1.1  mrg  *
     30   1.1  mrg  *  if(coefficient_x<coefficient_y)
     31   1.1  mrg  *    p = number_digits(coefficient_y) - number_digits(coefficient_x)
     32   1.1  mrg  *    A = coefficient_x*10^p
     33   1.1  mrg  *    B = coefficient_y
     34   1.1  mrg  *    CA= A*10^(15+j), j=0 for A>=B, 1 otherwise
     35   1.1  mrg  *    Q = 0
     36   1.1  mrg  *  else
     37   1.1  mrg  *    get Q=(int)(coefficient_x/coefficient_y)
     38   1.1  mrg  *        (based on double precision divide)
     39   1.1  mrg  *    check for exact divide case
     40   1.1  mrg  *    Let R = coefficient_x - Q*coefficient_y
     41   1.1  mrg  *    Let m=16-number_digits(Q)
     42   1.1  mrg  *    CA=R*10^m, Q=Q*10^m
     43   1.1  mrg  *    B = coefficient_y
     44   1.1  mrg  *  endif
     45   1.1  mrg  *    if (CA<2^64)
     46   1.1  mrg  *      Q += CA/B  (64-bit unsigned divide)
     47   1.1  mrg  *    else
     48   1.1  mrg  *      get final Q using double precision divide, followed by 3 integer
     49   1.1  mrg  *          iterations
     50   1.1  mrg  *    if exact result, eliminate trailing zeros
     51   1.1  mrg  *    check for underflow
     52   1.1  mrg  *    round coefficient to nearest
     53   1.1  mrg  *
     54   1.1  mrg  ****************************************************************************/
     55   1.1  mrg 
     56   1.1  mrg #include "bid_internal.h"
     57   1.1  mrg #include "bid_div_macros.h"
     58   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
     59   1.1  mrg #include <fenv.h>
     60   1.1  mrg 
     61   1.1  mrg #define FE_ALL_FLAGS FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT
     62   1.1  mrg #endif
     63   1.1  mrg 
     64   1.1  mrg extern UINT32 convert_table[5][128][2];
     65   1.1  mrg extern SINT8 factors[][2];
     66   1.1  mrg extern UINT8 packed_10000_zeros[];
     67   1.1  mrg 
     68   1.1  mrg 
     69   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
     70   1.1  mrg 
     71   1.1  mrg void
     72   1.1  mrg bid64_div (UINT64 * pres, UINT64 * px,
     73   1.1  mrg 	   UINT64 *
     74   1.1  mrg 	   py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     75   1.1  mrg 	   _EXC_INFO_PARAM) {
     76   1.1  mrg   UINT64 x, y;
     77   1.1  mrg #else
     78   1.1  mrg 
     79   1.1  mrg UINT64
     80   1.1  mrg bid64_div (UINT64 x,
     81   1.1  mrg 	   UINT64 y _RND_MODE_PARAM _EXC_FLAGS_PARAM
     82   1.1  mrg 	   _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
     83   1.1  mrg #endif
     84   1.1  mrg   UINT128 CA, CT;
     85   1.1  mrg   UINT64 sign_x, sign_y, coefficient_x, coefficient_y, A, B, QX, PD;
     86   1.1  mrg   UINT64 A2, Q, Q2, B2, B4, B5, R, T, DU, res;
     87   1.1  mrg   UINT64 valid_x, valid_y;
     88   1.1  mrg   SINT64 D;
     89   1.1  mrg   int_double t_scale, tempq, temp_b;
     90   1.1  mrg   int_float tempx, tempy;
     91   1.1  mrg   double da, db, dq, da_h, da_l;
     92   1.1  mrg   int exponent_x, exponent_y, bin_expon_cx;
     93   1.1  mrg   int diff_expon, ed1, ed2, bin_index;
     94   1.1  mrg   int rmode, amount;
     95   1.1  mrg   int nzeros, i, j, k, d5;
     96   1.1  mrg   UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
     97   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
     98   1.1  mrg   fexcept_t binaryflags = 0;
     99   1.1  mrg #endif
    100   1.1  mrg 
    101   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    102   1.1  mrg #if !DECIMAL_GLOBAL_ROUNDING
    103   1.1  mrg   _IDEC_round rnd_mode = *prnd_mode;
    104   1.1  mrg #endif
    105   1.1  mrg   x = *px;
    106   1.1  mrg   y = *py;
    107   1.1  mrg #endif
    108   1.1  mrg 
    109   1.1  mrg   valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x);
    110   1.1  mrg   valid_y = unpack_BID64 (&sign_y, &exponent_y, &coefficient_y, y);
    111   1.1  mrg 
    112   1.1  mrg   // unpack arguments, check for NaN or Infinity
    113   1.1  mrg   if (!valid_x) {
    114   1.1  mrg     // x is Inf. or NaN
    115   1.1  mrg #ifdef SET_STATUS_FLAGS
    116   1.1  mrg     if ((y & SNAN_MASK64) == SNAN_MASK64)	// y is sNaN
    117   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
    118   1.1  mrg #endif
    119   1.1  mrg 
    120   1.1  mrg     // test if x is NaN
    121   1.1  mrg     if ((x & NAN_MASK64) == NAN_MASK64) {
    122   1.1  mrg #ifdef SET_STATUS_FLAGS
    123   1.1  mrg       if ((x & SNAN_MASK64) == SNAN_MASK64)	// sNaN
    124   1.1  mrg 	__set_status_flags (pfpsf, INVALID_EXCEPTION);
    125   1.1  mrg #endif
    126   1.1  mrg       BID_RETURN (coefficient_x & QUIET_MASK64);
    127   1.1  mrg     }
    128   1.1  mrg     // x is Infinity?
    129   1.1  mrg     if ((x & INFINITY_MASK64) == INFINITY_MASK64) {
    130   1.1  mrg       // check if y is Inf or NaN
    131   1.1  mrg       if ((y & INFINITY_MASK64) == INFINITY_MASK64) {
    132   1.1  mrg 	// y==Inf, return NaN
    133   1.1  mrg 	if ((y & NAN_MASK64) == INFINITY_MASK64) {	// Inf/Inf
    134   1.1  mrg #ifdef SET_STATUS_FLAGS
    135   1.1  mrg 	  __set_status_flags (pfpsf, INVALID_EXCEPTION);
    136   1.1  mrg #endif
    137   1.1  mrg 	  BID_RETURN (NAN_MASK64);
    138   1.1  mrg 	}
    139   1.1  mrg       } else {
    140   1.1  mrg 	// otherwise return +/-Inf
    141   1.1  mrg 	BID_RETURN (((x ^ y) & 0x8000000000000000ull) |
    142   1.1  mrg 		    INFINITY_MASK64);
    143   1.1  mrg       }
    144   1.1  mrg     }
    145   1.1  mrg     // x==0
    146   1.1  mrg     if (((y & INFINITY_MASK64) != INFINITY_MASK64)
    147   1.1  mrg 	&& !(coefficient_y)) {
    148   1.1  mrg       // y==0 , return NaN
    149   1.1  mrg #ifdef SET_STATUS_FLAGS
    150   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
    151   1.1  mrg #endif
    152   1.1  mrg       BID_RETURN (NAN_MASK64);
    153   1.1  mrg     }
    154   1.1  mrg     if (((y & INFINITY_MASK64) != INFINITY_MASK64)) {
    155   1.1  mrg       if ((y & SPECIAL_ENCODING_MASK64) == SPECIAL_ENCODING_MASK64)
    156   1.1  mrg 	exponent_y = ((UINT32) (y >> 51)) & 0x3ff;
    157   1.1  mrg       else
    158   1.1  mrg 	exponent_y = ((UINT32) (y >> 53)) & 0x3ff;
    159   1.1  mrg       sign_y = y & 0x8000000000000000ull;
    160   1.1  mrg 
    161   1.1  mrg       exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
    162   1.1  mrg       if (exponent_x > DECIMAL_MAX_EXPON_64)
    163   1.1  mrg 	exponent_x = DECIMAL_MAX_EXPON_64;
    164   1.1  mrg       else if (exponent_x < 0)
    165   1.1  mrg 	exponent_x = 0;
    166   1.1  mrg       BID_RETURN ((sign_x ^ sign_y) | (((UINT64) exponent_x) << 53));
    167   1.1  mrg     }
    168   1.1  mrg 
    169   1.1  mrg   }
    170   1.1  mrg   if (!valid_y) {
    171   1.1  mrg     // y is Inf. or NaN
    172   1.1  mrg 
    173   1.1  mrg     // test if y is NaN
    174   1.1  mrg     if ((y & NAN_MASK64) == NAN_MASK64) {
    175   1.1  mrg #ifdef SET_STATUS_FLAGS
    176   1.1  mrg       if ((y & SNAN_MASK64) == SNAN_MASK64)	// sNaN
    177   1.1  mrg 	__set_status_flags (pfpsf, INVALID_EXCEPTION);
    178   1.1  mrg #endif
    179   1.1  mrg       BID_RETURN (coefficient_y & QUIET_MASK64);
    180   1.1  mrg     }
    181   1.1  mrg     // y is Infinity?
    182   1.1  mrg     if ((y & INFINITY_MASK64) == INFINITY_MASK64) {
    183   1.1  mrg       // return +/-0
    184   1.1  mrg       BID_RETURN (((x ^ y) & 0x8000000000000000ull));
    185   1.1  mrg     }
    186   1.1  mrg     // y is 0
    187   1.1  mrg #ifdef SET_STATUS_FLAGS
    188   1.1  mrg     __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
    189   1.1  mrg #endif
    190   1.1  mrg     BID_RETURN ((sign_x ^ sign_y) | INFINITY_MASK64);
    191   1.1  mrg   }
    192   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    193   1.1  mrg   (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
    194   1.1  mrg #endif
    195   1.1  mrg   diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
    196   1.1  mrg 
    197   1.1  mrg   if (coefficient_x < coefficient_y) {
    198   1.1  mrg     // get number of decimal digits for c_x, c_y
    199   1.1  mrg 
    200   1.1  mrg     //--- get number of bits in the coefficients of x and y ---
    201   1.1  mrg     tempx.d = (float) coefficient_x;
    202   1.1  mrg     tempy.d = (float) coefficient_y;
    203   1.1  mrg     bin_index = (tempy.i - tempx.i) >> 23;
    204   1.1  mrg 
    205   1.1  mrg     A = coefficient_x * power10_index_binexp[bin_index];
    206   1.1  mrg     B = coefficient_y;
    207   1.1  mrg 
    208   1.1  mrg     temp_b.d = (double) B;
    209   1.1  mrg 
    210   1.1  mrg     // compare A, B
    211   1.1  mrg     DU = (A - B) >> 63;
    212   1.1  mrg     ed1 = 15 + (int) DU;
    213   1.1  mrg     ed2 = estimate_decimal_digits[bin_index] + ed1;
    214   1.1  mrg     T = power10_table_128[ed1].w[0];
    215   1.1  mrg     __mul_64x64_to_128 (CA, A, T);
    216   1.1  mrg 
    217   1.1  mrg     Q = 0;
    218   1.1  mrg     diff_expon = diff_expon - ed2;
    219   1.1  mrg 
    220   1.1  mrg     // adjust double precision db, to ensure that later A/B - (int)(da/db) > -1
    221   1.1  mrg     if (coefficient_y < 0x0020000000000000ull) {
    222   1.1  mrg       temp_b.i += 1;
    223   1.1  mrg       db = temp_b.d;
    224   1.1  mrg     } else
    225   1.1  mrg       db = (double) (B + 2 + (B & 1));
    226   1.1  mrg 
    227   1.1  mrg   } else {
    228   1.1  mrg     // get c_x/c_y
    229   1.1  mrg 
    230   1.1  mrg     //  set last bit before conversion to DP
    231   1.1  mrg     A2 = coefficient_x | 1;
    232   1.1  mrg     da = (double) A2;
    233   1.1  mrg 
    234   1.1  mrg     db = (double) coefficient_y;
    235   1.1  mrg 
    236   1.1  mrg     tempq.d = da / db;
    237   1.1  mrg     Q = (UINT64) tempq.d;
    238   1.1  mrg 
    239   1.1  mrg     R = coefficient_x - coefficient_y * Q;
    240   1.1  mrg 
    241   1.1  mrg     // will use to get number of dec. digits of Q
    242   1.1  mrg     bin_expon_cx = (tempq.i >> 52) - 0x3ff;
    243   1.1  mrg 
    244   1.1  mrg     // R<0 ?
    245   1.1  mrg     D = ((SINT64) R) >> 63;
    246   1.1  mrg     Q += D;
    247   1.1  mrg     R += (coefficient_y & D);
    248   1.1  mrg 
    249   1.1  mrg     // exact result ?
    250   1.1  mrg     if (((SINT64) R) <= 0) {
    251   1.1  mrg       // can have R==-1 for coeff_y==1
    252   1.1  mrg       res =
    253   1.1  mrg 	get_BID64 (sign_x ^ sign_y, diff_expon, (Q + R), rnd_mode,
    254   1.1  mrg 		   pfpsf);
    255   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    256   1.1  mrg       (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
    257   1.1  mrg #endif
    258   1.1  mrg       BID_RETURN (res);
    259   1.1  mrg     }
    260   1.1  mrg     // get decimal digits of Q
    261   1.1  mrg     DU = power10_index_binexp[bin_expon_cx] - Q - 1;
    262   1.1  mrg     DU >>= 63;
    263   1.1  mrg 
    264   1.1  mrg     ed2 = 16 - estimate_decimal_digits[bin_expon_cx] - (int) DU;
    265   1.1  mrg 
    266   1.1  mrg     T = power10_table_128[ed2].w[0];
    267   1.1  mrg     __mul_64x64_to_128 (CA, R, T);
    268   1.1  mrg     B = coefficient_y;
    269   1.1  mrg 
    270   1.1  mrg     Q *= power10_table_128[ed2].w[0];
    271   1.1  mrg     diff_expon -= ed2;
    272   1.1  mrg 
    273   1.1  mrg   }
    274   1.1  mrg 
    275   1.1  mrg   if (!CA.w[1]) {
    276   1.1  mrg     Q2 = CA.w[0] / B;
    277   1.1  mrg     B2 = B + B;
    278   1.1  mrg     B4 = B2 + B2;
    279   1.1  mrg     R = CA.w[0] - Q2 * B;
    280   1.1  mrg     Q += Q2;
    281   1.1  mrg   } else {
    282   1.1  mrg 
    283   1.1  mrg     // 2^64
    284   1.1  mrg     t_scale.i = 0x43f0000000000000ull;
    285   1.1  mrg     // convert CA to DP
    286   1.1  mrg     da_h = CA.w[1];
    287   1.1  mrg     da_l = CA.w[0];
    288   1.1  mrg     da = da_h * t_scale.d + da_l;
    289   1.1  mrg 
    290   1.1  mrg     // quotient
    291   1.1  mrg     dq = da / db;
    292   1.1  mrg     Q2 = (UINT64) dq;
    293   1.1  mrg 
    294   1.1  mrg     // get w[0] remainder
    295   1.1  mrg     R = CA.w[0] - Q2 * B;
    296   1.1  mrg 
    297   1.1  mrg     // R<0 ?
    298   1.1  mrg     D = ((SINT64) R) >> 63;
    299   1.1  mrg     Q2 += D;
    300   1.1  mrg     R += (B & D);
    301   1.1  mrg 
    302   1.1  mrg     // now R<6*B
    303   1.1  mrg 
    304   1.1  mrg     // quick divide
    305   1.1  mrg 
    306   1.1  mrg     // 4*B
    307   1.1  mrg     B2 = B + B;
    308   1.1  mrg     B4 = B2 + B2;
    309   1.1  mrg 
    310   1.1  mrg     R = R - B4;
    311   1.1  mrg     // R<0 ?
    312   1.1  mrg     D = ((SINT64) R) >> 63;
    313   1.1  mrg     // restore R if negative
    314   1.1  mrg     R += (B4 & D);
    315   1.1  mrg     Q2 += ((~D) & 4);
    316   1.1  mrg 
    317   1.1  mrg     R = R - B2;
    318   1.1  mrg     // R<0 ?
    319   1.1  mrg     D = ((SINT64) R) >> 63;
    320   1.1  mrg     // restore R if negative
    321   1.1  mrg     R += (B2 & D);
    322   1.1  mrg     Q2 += ((~D) & 2);
    323   1.1  mrg 
    324   1.1  mrg     R = R - B;
    325   1.1  mrg     // R<0 ?
    326   1.1  mrg     D = ((SINT64) R) >> 63;
    327   1.1  mrg     // restore R if negative
    328   1.1  mrg     R += (B & D);
    329   1.1  mrg     Q2 += ((~D) & 1);
    330   1.1  mrg 
    331   1.1  mrg     Q += Q2;
    332   1.1  mrg   }
    333   1.1  mrg 
    334   1.1  mrg #ifdef SET_STATUS_FLAGS
    335   1.1  mrg   if (R) {
    336   1.1  mrg     // set status flags
    337   1.1  mrg     __set_status_flags (pfpsf, INEXACT_EXCEPTION);
    338   1.1  mrg   }
    339   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
    340   1.1  mrg   else
    341   1.1  mrg #endif
    342   1.1  mrg #else
    343   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
    344   1.1  mrg   if (!R)
    345   1.1  mrg #endif
    346   1.1  mrg #endif
    347   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
    348   1.1  mrg   {
    349   1.1  mrg     // eliminate trailing zeros
    350   1.1  mrg 
    351   1.1  mrg     // check whether CX, CY are short
    352   1.1  mrg     if ((coefficient_x <= 1024) && (coefficient_y <= 1024)) {
    353   1.1  mrg       i = (int) coefficient_y - 1;
    354   1.1  mrg       j = (int) coefficient_x - 1;
    355   1.1  mrg       // difference in powers of 2 factors for Y and X
    356   1.1  mrg       nzeros = ed2 - factors[i][0] + factors[j][0];
    357   1.1  mrg       // difference in powers of 5 factors
    358   1.1  mrg       d5 = ed2 - factors[i][1] + factors[j][1];
    359   1.1  mrg       if (d5 < nzeros)
    360   1.1  mrg 	nzeros = d5;
    361   1.1  mrg 
    362   1.1  mrg       __mul_64x64_to_128 (CT, Q, reciprocals10_64[nzeros]);
    363   1.1  mrg 
    364   1.1  mrg       // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
    365   1.1  mrg       amount = short_recip_scale[nzeros];
    366   1.1  mrg       Q = CT.w[1] >> amount;
    367   1.1  mrg 
    368   1.1  mrg       diff_expon += nzeros;
    369   1.1  mrg     } else {
    370   1.1  mrg       tdigit[0] = Q & 0x3ffffff;
    371   1.1  mrg       tdigit[1] = 0;
    372   1.1  mrg       QX = Q >> 26;
    373   1.1  mrg       QX32 = QX;
    374   1.1  mrg       nzeros = 0;
    375   1.1  mrg 
    376   1.1  mrg       for (j = 0; QX32; j++, QX32 >>= 7) {
    377   1.1  mrg 	k = (QX32 & 127);
    378   1.1  mrg 	tdigit[0] += convert_table[j][k][0];
    379   1.1  mrg 	tdigit[1] += convert_table[j][k][1];
    380   1.1  mrg 	if (tdigit[0] >= 100000000) {
    381   1.1  mrg 	  tdigit[0] -= 100000000;
    382   1.1  mrg 	  tdigit[1]++;
    383   1.1  mrg 	}
    384   1.1  mrg       }
    385   1.1  mrg 
    386   1.1  mrg       digit = tdigit[0];
    387   1.1  mrg       if (!digit && !tdigit[1])
    388   1.1  mrg 	nzeros += 16;
    389   1.1  mrg       else {
    390   1.1  mrg 	if (!digit) {
    391   1.1  mrg 	  nzeros += 8;
    392   1.1  mrg 	  digit = tdigit[1];
    393   1.1  mrg 	}
    394   1.1  mrg 	// decompose digit
    395   1.1  mrg 	PD = (UINT64) digit *0x068DB8BBull;
    396   1.1  mrg 	digit_h = (UINT32) (PD >> 40);
    397   1.1  mrg 	digit_low = digit - digit_h * 10000;
    398   1.1  mrg 
    399   1.1  mrg 	if (!digit_low)
    400   1.1  mrg 	  nzeros += 4;
    401   1.1  mrg 	else
    402   1.1  mrg 	  digit_h = digit_low;
    403   1.1  mrg 
    404   1.1  mrg 	if (!(digit_h & 1))
    405   1.1  mrg 	  nzeros +=
    406   1.1  mrg 	    3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
    407   1.1  mrg 			  (digit_h & 7));
    408   1.1  mrg       }
    409   1.1  mrg 
    410   1.1  mrg       if (nzeros) {
    411   1.1  mrg 	__mul_64x64_to_128 (CT, Q, reciprocals10_64[nzeros]);
    412   1.1  mrg 
    413   1.1  mrg 	// now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
    414   1.1  mrg 	amount = short_recip_scale[nzeros];
    415   1.1  mrg 	Q = CT.w[1] >> amount;
    416   1.1  mrg       }
    417   1.1  mrg       diff_expon += nzeros;
    418   1.1  mrg 
    419   1.1  mrg     }
    420   1.1  mrg     if (diff_expon >= 0) {
    421   1.1  mrg       res =
    422   1.1  mrg 	fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, Q,
    423   1.1  mrg 				 rnd_mode, pfpsf);
    424   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    425   1.1  mrg       (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
    426   1.1  mrg #endif
    427   1.1  mrg       BID_RETURN (res);
    428   1.1  mrg     }
    429   1.1  mrg   }
    430   1.1  mrg #endif
    431   1.1  mrg 
    432   1.1  mrg   if (diff_expon >= 0) {
    433   1.1  mrg #ifdef IEEE_ROUND_NEAREST
    434   1.1  mrg     // round to nearest code
    435   1.1  mrg     // R*10
    436   1.1  mrg     R += R;
    437   1.1  mrg     R = (R << 2) + R;
    438   1.1  mrg     B5 = B4 + B;
    439   1.1  mrg 
    440   1.1  mrg     // compare 10*R to 5*B
    441   1.1  mrg     R = B5 - R;
    442   1.1  mrg     // correction for (R==0 && (Q&1))
    443   1.1  mrg     R -= (Q & 1);
    444   1.1  mrg     // R<0 ?
    445   1.1  mrg     D = ((UINT64) R) >> 63;
    446   1.1  mrg     Q += D;
    447   1.1  mrg #else
    448   1.1  mrg #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
    449   1.1  mrg     // round to nearest code
    450   1.1  mrg     // R*10
    451   1.1  mrg     R += R;
    452   1.1  mrg     R = (R << 2) + R;
    453   1.1  mrg     B5 = B4 + B;
    454   1.1  mrg 
    455   1.1  mrg     // compare 10*R to 5*B
    456   1.1  mrg     R = B5 - R;
    457   1.1  mrg     // correction for (R==0 && (Q&1))
    458   1.1  mrg     R -= (Q & 1);
    459   1.1  mrg     // R<0 ?
    460   1.1  mrg     D = ((UINT64) R) >> 63;
    461   1.1  mrg     Q += D;
    462   1.1  mrg #else
    463   1.1  mrg     rmode = rnd_mode;
    464   1.1  mrg     if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
    465   1.1  mrg       rmode = 3 - rmode;
    466   1.1  mrg     switch (rmode) {
    467   1.1  mrg     case 0:	// round to nearest code
    468   1.1  mrg     case ROUNDING_TIES_AWAY:
    469   1.1  mrg       // R*10
    470   1.1  mrg       R += R;
    471   1.1  mrg       R = (R << 2) + R;
    472   1.1  mrg       B5 = B4 + B;
    473   1.1  mrg       // compare 10*R to 5*B
    474   1.1  mrg       R = B5 - R;
    475   1.1  mrg       // correction for (R==0 && (Q&1))
    476   1.1  mrg       R -= ((Q | (rmode >> 2)) & 1);
    477   1.1  mrg       // R<0 ?
    478   1.1  mrg       D = ((UINT64) R) >> 63;
    479   1.1  mrg       Q += D;
    480   1.1  mrg       break;
    481   1.1  mrg     case ROUNDING_DOWN:
    482   1.1  mrg     case ROUNDING_TO_ZERO:
    483   1.1  mrg       break;
    484   1.1  mrg     default:	// rounding up
    485   1.1  mrg       Q++;
    486   1.1  mrg       break;
    487   1.1  mrg     }
    488   1.1  mrg #endif
    489   1.1  mrg #endif
    490   1.1  mrg 
    491   1.1  mrg     res =
    492   1.1  mrg       fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, Q, rnd_mode,
    493   1.1  mrg 			       pfpsf);
    494   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    495   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
    496   1.1  mrg #endif
    497   1.1  mrg     BID_RETURN (res);
    498   1.1  mrg   } else {
    499   1.1  mrg     // UF occurs
    500   1.1  mrg 
    501   1.1  mrg #ifdef SET_STATUS_FLAGS
    502   1.1  mrg     if ((diff_expon + 16 < 0)) {
    503   1.1  mrg       // set status flags
    504   1.1  mrg       __set_status_flags (pfpsf, INEXACT_EXCEPTION);
    505   1.1  mrg     }
    506   1.1  mrg #endif
    507   1.1  mrg     rmode = rnd_mode;
    508   1.1  mrg     res =
    509   1.1  mrg       get_BID64_UF (sign_x ^ sign_y, diff_expon, Q, R, rmode, pfpsf);
    510   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    511   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
    512   1.1  mrg #endif
    513   1.1  mrg     BID_RETURN (res);
    514   1.1  mrg 
    515   1.1  mrg   }
    516   1.1  mrg }
    517   1.1  mrg 
    518   1.1  mrg 
    519   1.1  mrg 
    520   1.1  mrg TYPE0_FUNCTION_ARGTYPE1_ARG128 (UINT64, bid64dq_div, UINT64, x, y)
    521   1.1  mrg      UINT256 CA4 =
    522   1.1  mrg        { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
    523   1.5  mrg UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
    524   1.1  mrg UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, valid_y, PD, res;
    525   1.1  mrg int_float fx, fy, f64;
    526   1.1  mrg UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
    527   1.1  mrg int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
    528   1.1  mrg   digits_q, amount;
    529   1.1  mrg int nzeros, i, j, k, d5, done = 0;
    530   1.1  mrg unsigned rmode;
    531   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    532   1.1  mrg fexcept_t binaryflags = 0;
    533   1.1  mrg #endif
    534   1.1  mrg 
    535   1.1  mrg valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y);
    536   1.1  mrg 
    537   1.1  mrg 	// unpack arguments, check for NaN or Infinity
    538   1.1  mrg CX.w[1] = 0;
    539   1.1  mrg if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], (x))) {
    540   1.1  mrg #ifdef SET_STATUS_FLAGS
    541   1.1  mrg     if (((y.w[1] & SNAN_MASK64) == SNAN_MASK64) ||	// y is sNaN
    542   1.1  mrg 		((x & SNAN_MASK64) == SNAN_MASK64))
    543   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
    544   1.1  mrg #endif
    545   1.1  mrg   // test if x is NaN
    546   1.1  mrg   if (((x) & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
    547   1.1  mrg     res = CX.w[0];
    548   1.1  mrg     BID_RETURN (res & QUIET_MASK64);
    549   1.1  mrg   }
    550   1.1  mrg   // x is Infinity?
    551   1.1  mrg   if (((x) & 0x7800000000000000ull) == 0x7800000000000000ull) {
    552   1.1  mrg     // check if y is Inf.
    553   1.1  mrg     if (((y.w[1] & 0x7c00000000000000ull) == 0x7800000000000000ull))
    554   1.1  mrg       // return NaN
    555   1.1  mrg     {
    556   1.1  mrg #ifdef SET_STATUS_FLAGS
    557   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
    558   1.1  mrg #endif
    559   1.1  mrg       res = 0x7c00000000000000ull;
    560   1.1  mrg       BID_RETURN (res);
    561   1.1  mrg     }
    562   1.1  mrg 	if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
    563   1.1  mrg     // otherwise return +/-Inf
    564   1.1  mrg     res =
    565   1.1  mrg       (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
    566   1.1  mrg     BID_RETURN (res);
    567   1.1  mrg 	}
    568   1.1  mrg   }
    569   1.1  mrg   // x is 0
    570   1.1  mrg   if ((y.w[1] & INFINITY_MASK64) != INFINITY_MASK64) {
    571   1.1  mrg     if ((!CY.w[0]) && !(CY.w[1] & 0x0001ffffffffffffull)) {
    572   1.1  mrg #ifdef SET_STATUS_FLAGS
    573   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
    574   1.1  mrg #endif
    575   1.1  mrg       // x=y=0, return NaN
    576   1.1  mrg       res = 0x7c00000000000000ull;
    577   1.1  mrg       BID_RETURN (res);
    578   1.1  mrg     }
    579   1.1  mrg     // return 0
    580   1.1  mrg     res = ((x) ^ y.w[1]) & 0x8000000000000000ull;
    581   1.1  mrg     exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS_128;
    582   1.1  mrg     if (exponent_x > DECIMAL_MAX_EXPON_64)
    583   1.1  mrg       exponent_x = DECIMAL_MAX_EXPON_64;
    584   1.1  mrg     else if (exponent_x < 0)
    585   1.1  mrg       exponent_x = 0;
    586   1.1  mrg     res |= (((UINT64) exponent_x) << 53);
    587   1.1  mrg     BID_RETURN (res);
    588   1.1  mrg   }
    589   1.1  mrg }
    590   1.1  mrg exponent_x += (DECIMAL_EXPONENT_BIAS_128 - DECIMAL_EXPONENT_BIAS);
    591   1.1  mrg if (!valid_y) {
    592   1.1  mrg   // y is Inf. or NaN
    593   1.1  mrg 
    594   1.1  mrg   // test if y is NaN
    595   1.1  mrg   if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
    596   1.1  mrg #ifdef SET_STATUS_FLAGS
    597   1.1  mrg     if ((y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull)	// sNaN
    598   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
    599   1.1  mrg #endif
    600   1.1  mrg     Tmp.w[1] = (CY.w[1] & 0x00003fffffffffffull);
    601   1.1  mrg     Tmp.w[0] = CY.w[0];
    602   1.1  mrg     TP128 = reciprocals10_128[18];
    603   1.5  mrg     __mul_128x128_high (Qh, Tmp, TP128);
    604   1.1  mrg     amount = recip_scale[18];
    605   1.1  mrg     __shr_128 (Tmp, Qh, amount);
    606   1.1  mrg     res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
    607   1.1  mrg     BID_RETURN (res);
    608   1.1  mrg   }
    609   1.1  mrg   // y is Infinity?
    610   1.1  mrg   if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
    611   1.1  mrg     // return +/-0
    612   1.1  mrg     res = sign_x ^ sign_y;
    613   1.1  mrg     BID_RETURN (res);
    614   1.1  mrg   }
    615   1.1  mrg   // y is 0, return +/-Inf
    616   1.1  mrg   res =
    617   1.1  mrg     (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
    618   1.1  mrg #ifdef SET_STATUS_FLAGS
    619   1.1  mrg   __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
    620   1.1  mrg #endif
    621   1.1  mrg   BID_RETURN (res);
    622   1.1  mrg }
    623   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    624   1.1  mrg (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
    625   1.1  mrg #endif
    626   1.1  mrg diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
    627   1.1  mrg 
    628   1.1  mrg if (__unsigned_compare_gt_128 (CY, CX)) {
    629   1.1  mrg   // CX < CY
    630   1.1  mrg 
    631   1.1  mrg   // 2^64
    632   1.1  mrg   f64.i = 0x5f800000;
    633   1.1  mrg 
    634   1.1  mrg   // fx ~ CX,   fy ~ CY
    635   1.1  mrg   fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
    636   1.1  mrg   fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
    637   1.1  mrg   // expon_cy - expon_cx
    638   1.1  mrg   bin_index = (fy.i - fx.i) >> 23;
    639   1.1  mrg 
    640   1.1  mrg   if (CX.w[1]) {
    641   1.1  mrg     T = power10_index_binexp_128[bin_index].w[0];
    642   1.1  mrg     __mul_64x128_short (CA, T, CX);
    643   1.1  mrg   } else {
    644   1.1  mrg     T128 = power10_index_binexp_128[bin_index];
    645   1.1  mrg     __mul_64x128_short (CA, CX.w[0], T128);
    646   1.1  mrg   }
    647   1.1  mrg 
    648   1.1  mrg   ed2 = 15;
    649   1.1  mrg   if (__unsigned_compare_gt_128 (CY, CA))
    650   1.1  mrg     ed2++;
    651   1.1  mrg 
    652   1.1  mrg   T128 = power10_table_128[ed2];
    653   1.1  mrg   __mul_128x128_to_256 (CA4, CA, T128);
    654   1.1  mrg 
    655   1.1  mrg   ed2 += estimate_decimal_digits[bin_index];
    656   1.1  mrg   CQ.w[0] = CQ.w[1] = 0;
    657   1.1  mrg   diff_expon = diff_expon - ed2;
    658   1.1  mrg 
    659   1.1  mrg } else {
    660   1.1  mrg   // get CQ = CX/CY
    661   1.1  mrg   __div_128_by_128 (&CQ, &CR, CX, CY);
    662   1.1  mrg 
    663   1.1  mrg   // get number of decimal digits in CQ
    664   1.1  mrg   // 2^64
    665   1.1  mrg   f64.i = 0x5f800000;
    666   1.1  mrg   fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
    667   1.1  mrg   // binary expon. of CQ
    668   1.1  mrg   bin_expon = (fx.i - 0x3f800000) >> 23;
    669   1.1  mrg 
    670   1.1  mrg   digits_q = estimate_decimal_digits[bin_expon];
    671   1.1  mrg   TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
    672   1.1  mrg   TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
    673   1.1  mrg   if (__unsigned_compare_ge_128 (CQ, TP128))
    674   1.1  mrg     digits_q++;
    675   1.1  mrg 
    676   1.1  mrg   if (digits_q <= 16) {
    677   1.1  mrg     if (!CR.w[1] && !CR.w[0]) {
    678   1.1  mrg       res = get_BID64 (sign_x ^ sign_y, diff_expon,
    679   1.1  mrg 		       CQ.w[0], rnd_mode, pfpsf);
    680   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    681   1.1  mrg       (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
    682   1.1  mrg #endif
    683   1.1  mrg       BID_RETURN (res);
    684   1.1  mrg     }
    685   1.1  mrg 
    686   1.1  mrg     ed2 = 16 - digits_q;
    687   1.1  mrg     T128.w[0] = power10_table_128[ed2].w[0];
    688   1.1  mrg     __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
    689   1.1  mrg     diff_expon = diff_expon - ed2;
    690   1.1  mrg     CQ.w[0] *= T128.w[0];
    691   1.1  mrg   } else {
    692   1.1  mrg     ed2 = digits_q - 16;
    693   1.1  mrg     diff_expon += ed2;
    694   1.1  mrg     T128 = reciprocals10_128[ed2];
    695   1.1  mrg     __mul_128x128_to_256 (P256, CQ, T128);
    696   1.1  mrg     amount = recip_scale[ed2];
    697   1.1  mrg     CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
    698   1.1  mrg     CQ.w[1] = 0;
    699   1.1  mrg 
    700   1.1  mrg     __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
    701   1.1  mrg 
    702   1.1  mrg     __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
    703   1.1  mrg     QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
    704   1.1  mrg 
    705   1.1  mrg     CA4.w[1] = CX.w[1] - QB256.w[1];
    706   1.1  mrg     CA4.w[0] = CX.w[0] - QB256.w[0];
    707   1.1  mrg     if (CX.w[0] < QB256.w[0])
    708   1.1  mrg       CA4.w[1]--;
    709   1.1  mrg     if (CR.w[0] || CR.w[1])
    710   1.1  mrg       CA4.w[0] |= 1;
    711   1.1  mrg     done = 1;
    712   1.1  mrg 
    713   1.1  mrg   }
    714   1.1  mrg 
    715   1.1  mrg }
    716   1.1  mrg if (!done) {
    717   1.1  mrg   __div_256_by_128 (&CQ, &CA4, CY);
    718   1.1  mrg }
    719   1.1  mrg 
    720   1.1  mrg 
    721   1.1  mrg 
    722   1.1  mrg #ifdef SET_STATUS_FLAGS
    723   1.1  mrg   if (CA4.w[0] || CA4.w[1]) {
    724   1.1  mrg     // set status flags
    725   1.1  mrg     __set_status_flags (pfpsf, INEXACT_EXCEPTION);
    726   1.1  mrg   }
    727   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
    728   1.1  mrg   else
    729   1.1  mrg #endif
    730   1.1  mrg #else
    731   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
    732   1.1  mrg   if (!CA4.w[0] && !CA4.w[1])
    733   1.1  mrg #endif
    734   1.1  mrg #endif
    735   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
    736   1.1  mrg     // check whether result is exact
    737   1.1  mrg   {
    738   1.1  mrg     // check whether CX, CY are short
    739   1.1  mrg     if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
    740   1.1  mrg       i = (int) CY.w[0] - 1;
    741   1.1  mrg       j = (int) CX.w[0] - 1;
    742   1.1  mrg       // difference in powers of 2 factors for Y and X
    743   1.1  mrg       nzeros = ed2 - factors[i][0] + factors[j][0];
    744   1.1  mrg       // difference in powers of 5 factors
    745   1.1  mrg       d5 = ed2 - factors[i][1] + factors[j][1];
    746   1.1  mrg       if (d5 < nzeros)
    747   1.1  mrg 	nzeros = d5;
    748   1.1  mrg       // get P*(2^M[extra_digits])/10^extra_digits
    749   1.5  mrg       __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
    750   1.1  mrg 
    751   1.1  mrg       // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
    752   1.1  mrg       amount = recip_scale[nzeros];
    753   1.1  mrg       __shr_128_long (CQ, Qh, amount);
    754   1.1  mrg 
    755   1.1  mrg       diff_expon += nzeros;
    756   1.1  mrg     } else {
    757   1.1  mrg       // decompose Q as Qh*10^17 + Ql
    758   1.1  mrg       Q_low = CQ.w[0];
    759   1.1  mrg 
    760   1.1  mrg       {
    761   1.1  mrg 	tdigit[0] = Q_low & 0x3ffffff;
    762   1.1  mrg 	tdigit[1] = 0;
    763   1.1  mrg 	QX = Q_low >> 26;
    764   1.1  mrg 	QX32 = QX;
    765   1.1  mrg 	nzeros = 0;
    766   1.1  mrg 
    767   1.1  mrg 	for (j = 0; QX32; j++, QX32 >>= 7) {
    768   1.1  mrg 	  k = (QX32 & 127);
    769   1.1  mrg 	  tdigit[0] += convert_table[j][k][0];
    770   1.1  mrg 	  tdigit[1] += convert_table[j][k][1];
    771   1.1  mrg 	  if (tdigit[0] >= 100000000) {
    772   1.1  mrg 	    tdigit[0] -= 100000000;
    773   1.1  mrg 	    tdigit[1]++;
    774   1.1  mrg 	  }
    775   1.1  mrg 	}
    776   1.1  mrg 
    777   1.1  mrg 	if (tdigit[1] >= 100000000) {
    778   1.1  mrg 	  tdigit[1] -= 100000000;
    779   1.1  mrg 	  if (tdigit[1] >= 100000000)
    780   1.1  mrg 	    tdigit[1] -= 100000000;
    781   1.1  mrg 	}
    782   1.1  mrg 
    783   1.1  mrg 	digit = tdigit[0];
    784   1.1  mrg 	if (!digit && !tdigit[1])
    785   1.1  mrg 	  nzeros += 16;
    786   1.1  mrg 	else {
    787   1.1  mrg 	  if (!digit) {
    788   1.1  mrg 	    nzeros += 8;
    789   1.1  mrg 	    digit = tdigit[1];
    790   1.1  mrg 	  }
    791   1.1  mrg 	  // decompose digit
    792   1.1  mrg 	  PD = (UINT64) digit *0x068DB8BBull;
    793   1.1  mrg 	  digit_h = (UINT32) (PD >> 40);
    794   1.1  mrg 	  digit_low = digit - digit_h * 10000;
    795   1.1  mrg 
    796   1.1  mrg 	  if (!digit_low)
    797   1.1  mrg 	    nzeros += 4;
    798   1.1  mrg 	  else
    799   1.1  mrg 	    digit_h = digit_low;
    800   1.1  mrg 
    801   1.1  mrg 	  if (!(digit_h & 1))
    802   1.1  mrg 	    nzeros +=
    803   1.1  mrg 	      3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
    804   1.1  mrg 			    (digit_h & 7));
    805   1.1  mrg 	}
    806   1.1  mrg 
    807   1.1  mrg 	if (nzeros) {
    808   1.1  mrg 	  // get P*(2^M[extra_digits])/10^extra_digits
    809   1.5  mrg 	  __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
    810   1.1  mrg 
    811   1.1  mrg 	  // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
    812   1.1  mrg 	  amount = recip_scale[nzeros];
    813   1.1  mrg 	  __shr_128 (CQ, Qh, amount);
    814   1.1  mrg 	}
    815   1.1  mrg 	diff_expon += nzeros;
    816   1.1  mrg 
    817   1.1  mrg       }
    818   1.1  mrg     }
    819   1.1  mrg 	if(diff_expon>=0){
    820   1.1  mrg     res =
    821   1.1  mrg       fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
    822   1.1  mrg 			       rnd_mode, pfpsf);
    823   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    824   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
    825   1.1  mrg #endif
    826   1.1  mrg     BID_RETURN (res);
    827   1.1  mrg 	}
    828   1.1  mrg   }
    829   1.1  mrg #endif
    830   1.1  mrg 
    831   1.1  mrg   if (diff_expon >= 0) {
    832   1.1  mrg #ifdef IEEE_ROUND_NEAREST
    833   1.1  mrg   // rounding
    834   1.1  mrg   // 2*CA4 - CY
    835   1.1  mrg   CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
    836   1.1  mrg   CA4r.w[0] = CA4.w[0] + CA4.w[0];
    837   1.1  mrg   __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
    838   1.1  mrg   CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
    839   1.1  mrg 
    840   1.1  mrg   D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
    841   1.1  mrg   carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
    842   1.1  mrg 
    843   1.1  mrg   CQ.w[0] += carry64;
    844   1.1  mrg #else
    845   1.1  mrg #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
    846   1.1  mrg   // rounding
    847   1.1  mrg   // 2*CA4 - CY
    848   1.1  mrg   CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
    849   1.1  mrg   CA4r.w[0] = CA4.w[0] + CA4.w[0];
    850   1.1  mrg   __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
    851   1.1  mrg   CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
    852   1.1  mrg 
    853   1.1  mrg   D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
    854   1.1  mrg   carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
    855   1.1  mrg 
    856   1.1  mrg   CQ.w[0] += carry64;
    857   1.1  mrg   if (CQ.w[0] < carry64)
    858   1.1  mrg     CQ.w[1]++;
    859   1.1  mrg #else
    860   1.1  mrg   rmode = rnd_mode;
    861   1.1  mrg   if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
    862   1.1  mrg     rmode = 3 - rmode;
    863   1.1  mrg   switch (rmode) {
    864   1.1  mrg   case ROUNDING_TO_NEAREST:	// round to nearest code
    865   1.1  mrg     // rounding
    866   1.1  mrg     // 2*CA4 - CY
    867   1.1  mrg     CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
    868   1.1  mrg     CA4r.w[0] = CA4.w[0] + CA4.w[0];
    869   1.1  mrg     __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
    870   1.1  mrg     CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
    871   1.1  mrg     D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
    872   1.1  mrg     carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
    873   1.1  mrg     CQ.w[0] += carry64;
    874   1.1  mrg     if (CQ.w[0] < carry64)
    875   1.1  mrg       CQ.w[1]++;
    876   1.1  mrg     break;
    877   1.1  mrg   case ROUNDING_TIES_AWAY:
    878   1.1  mrg     // rounding
    879   1.1  mrg     // 2*CA4 - CY
    880   1.1  mrg     CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
    881   1.1  mrg     CA4r.w[0] = CA4.w[0] + CA4.w[0];
    882   1.1  mrg     __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
    883   1.1  mrg     CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
    884   1.1  mrg     D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
    885   1.1  mrg     carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
    886   1.1  mrg     CQ.w[0] += carry64;
    887   1.1  mrg     if (CQ.w[0] < carry64)
    888   1.1  mrg       CQ.w[1]++;
    889   1.1  mrg     break;
    890   1.1  mrg   case ROUNDING_DOWN:
    891   1.1  mrg   case ROUNDING_TO_ZERO:
    892   1.1  mrg     break;
    893   1.1  mrg   default:	// rounding up
    894   1.1  mrg     CQ.w[0]++;
    895   1.1  mrg     if (!CQ.w[0])
    896   1.1  mrg       CQ.w[1]++;
    897   1.1  mrg     break;
    898   1.1  mrg   }
    899   1.1  mrg #endif
    900   1.1  mrg #endif
    901   1.1  mrg 
    902   1.1  mrg     res =
    903   1.1  mrg       fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
    904   1.1  mrg 			       pfpsf);
    905   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    906   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
    907   1.1  mrg #endif
    908   1.1  mrg     BID_RETURN (res);
    909   1.1  mrg   } else {
    910   1.1  mrg     // UF occurs
    911   1.1  mrg 
    912   1.1  mrg #ifdef SET_STATUS_FLAGS
    913   1.1  mrg     if ((diff_expon + 16 < 0)) {
    914   1.1  mrg       // set status flags
    915   1.1  mrg       __set_status_flags (pfpsf, INEXACT_EXCEPTION);
    916   1.1  mrg     }
    917   1.1  mrg #endif
    918   1.1  mrg     rmode = rnd_mode;
    919   1.1  mrg     res =
    920   1.1  mrg       get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
    921   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    922   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
    923   1.1  mrg #endif
    924   1.1  mrg     BID_RETURN (res);
    925   1.1  mrg 
    926   1.1  mrg   }
    927   1.1  mrg 
    928   1.1  mrg }
    929   1.1  mrg 
    930   1.1  mrg 
    931   1.1  mrg //#define LEAVE_TRAILING_ZEROS
    932   1.1  mrg 
    933   1.1  mrg TYPE0_FUNCTION_ARG128_ARGTYPE2 (UINT64, bid64qd_div, x, UINT64, y)
    934   1.1  mrg 
    935   1.1  mrg      UINT256 CA4 =
    936   1.1  mrg        { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
    937   1.5  mrg UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
    938   1.1  mrg UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, PD, res, valid_y;
    939   1.1  mrg int_float fx, fy, f64;
    940   1.1  mrg UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
    941   1.1  mrg int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
    942   1.1  mrg   digits_q, amount;
    943   1.1  mrg int nzeros, i, j, k, d5, done = 0;
    944   1.1  mrg unsigned rmode;
    945   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
    946   1.1  mrg fexcept_t binaryflags = 0;
    947   1.1  mrg #endif
    948   1.1  mrg 
    949   1.1  mrg valid_y = unpack_BID64 (&sign_y, &exponent_y, &CY.w[0], (y));
    950   1.1  mrg 
    951   1.1  mrg 	// unpack arguments, check for NaN or Infinity
    952   1.1  mrg if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) {
    953   1.1  mrg   // test if x is NaN
    954   1.1  mrg   if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
    955   1.1  mrg #ifdef SET_STATUS_FLAGS
    956   1.1  mrg     if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull ||	// sNaN
    957   1.1  mrg 	(y & 0x7e00000000000000ull) == 0x7e00000000000000ull)
    958   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
    959   1.1  mrg #endif
    960   1.1  mrg       Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull);
    961   1.1  mrg       Tmp.w[0] = CX.w[0];
    962   1.1  mrg       TP128 = reciprocals10_128[18];
    963   1.5  mrg       __mul_128x128_high (Qh, Tmp, TP128);
    964   1.1  mrg       amount = recip_scale[18];
    965   1.1  mrg       __shr_128 (Tmp, Qh, amount);
    966   1.1  mrg       res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
    967   1.1  mrg     BID_RETURN (res);
    968   1.1  mrg   }
    969   1.1  mrg   // x is Infinity?
    970   1.1  mrg   if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
    971   1.1  mrg     // check if y is Inf.
    972   1.1  mrg     if (((y & 0x7c00000000000000ull) == 0x7800000000000000ull))
    973   1.1  mrg       // return NaN
    974   1.1  mrg     {
    975   1.1  mrg #ifdef SET_STATUS_FLAGS
    976   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
    977   1.1  mrg #endif
    978   1.1  mrg       res = 0x7c00000000000000ull;
    979   1.1  mrg       BID_RETURN (res);
    980   1.1  mrg     }
    981   1.1  mrg 	if (((y & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
    982   1.1  mrg     // otherwise return +/-Inf
    983   1.1  mrg     res =
    984   1.1  mrg       ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull;
    985   1.1  mrg     BID_RETURN (res);
    986   1.1  mrg 	}
    987   1.1  mrg   }
    988   1.1  mrg   // x is 0
    989   1.1  mrg   if (((y & INFINITY_MASK64) != INFINITY_MASK64) &&
    990   1.1  mrg       !(CY.w[0])) {
    991   1.1  mrg #ifdef SET_STATUS_FLAGS
    992   1.1  mrg     __set_status_flags (pfpsf, INVALID_EXCEPTION);
    993   1.1  mrg #endif
    994   1.1  mrg     // x=y=0, return NaN
    995   1.1  mrg     res = 0x7c00000000000000ull;
    996   1.1  mrg     BID_RETURN (res);
    997   1.1  mrg   }
    998   1.1  mrg   // return 0
    999   1.1  mrg   if (((y & 0x7800000000000000ull) != 0x7800000000000000ull)) {
   1000   1.1  mrg 	  if (!CY.w[0]) {
   1001   1.1  mrg #ifdef SET_STATUS_FLAGS
   1002   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
   1003   1.1  mrg #endif
   1004   1.1  mrg       res = 0x7c00000000000000ull;
   1005   1.1  mrg       BID_RETURN (res);
   1006   1.1  mrg 	  }
   1007   1.1  mrg     exponent_x =
   1008   1.1  mrg       exponent_x - exponent_y - DECIMAL_EXPONENT_BIAS_128 +
   1009   1.1  mrg       (DECIMAL_EXPONENT_BIAS << 1);
   1010   1.1  mrg     if (exponent_x > DECIMAL_MAX_EXPON_64)
   1011   1.1  mrg       exponent_x = DECIMAL_MAX_EXPON_64;
   1012   1.1  mrg     else if (exponent_x < 0)
   1013   1.1  mrg       exponent_x = 0;
   1014   1.1  mrg     res = (sign_x ^ sign_y) | (((UINT64) exponent_x) << 53);
   1015   1.1  mrg     BID_RETURN (res);
   1016   1.1  mrg   }
   1017   1.1  mrg }
   1018   1.1  mrg CY.w[1] = 0;
   1019   1.1  mrg if (!valid_y) {
   1020   1.1  mrg   // y is Inf. or NaN
   1021   1.1  mrg 
   1022   1.1  mrg   // test if y is NaN
   1023   1.1  mrg   if ((y & NAN_MASK64) == NAN_MASK64) {
   1024   1.1  mrg #ifdef SET_STATUS_FLAGS
   1025   1.1  mrg     if ((y & SNAN_MASK64) == SNAN_MASK64)	// sNaN
   1026   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
   1027   1.1  mrg #endif
   1028   1.1  mrg     BID_RETURN (CY.w[0] & QUIET_MASK64);
   1029   1.1  mrg   }
   1030   1.1  mrg   // y is Infinity?
   1031   1.1  mrg   if (((y) & 0x7800000000000000ull) == 0x7800000000000000ull) {
   1032   1.1  mrg     // return +/-0
   1033   1.1  mrg     res = sign_x ^ sign_y;
   1034   1.1  mrg     BID_RETURN (res);
   1035   1.1  mrg   }
   1036   1.1  mrg   // y is 0, return +/-Inf
   1037   1.1  mrg   res =
   1038   1.1  mrg     ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull;
   1039   1.1  mrg #ifdef SET_STATUS_FLAGS
   1040   1.1  mrg   __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
   1041   1.1  mrg #endif
   1042   1.1  mrg   BID_RETURN (res);
   1043   1.1  mrg }
   1044   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1045   1.1  mrg (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1046   1.1  mrg #endif
   1047   1.1  mrg diff_expon =
   1048   1.1  mrg   exponent_x - exponent_y - DECIMAL_EXPONENT_BIAS_128 +
   1049   1.1  mrg   (DECIMAL_EXPONENT_BIAS << 1);
   1050   1.1  mrg 
   1051   1.1  mrg if (__unsigned_compare_gt_128 (CY, CX)) {
   1052   1.1  mrg   // CX < CY
   1053   1.1  mrg 
   1054   1.1  mrg   // 2^64
   1055   1.1  mrg   f64.i = 0x5f800000;
   1056   1.1  mrg 
   1057   1.1  mrg   // fx ~ CX,   fy ~ CY
   1058   1.1  mrg   fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
   1059   1.1  mrg   fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
   1060   1.1  mrg   // expon_cy - expon_cx
   1061   1.1  mrg   bin_index = (fy.i - fx.i) >> 23;
   1062   1.1  mrg 
   1063   1.1  mrg   if (CX.w[1]) {
   1064   1.1  mrg     T = power10_index_binexp_128[bin_index].w[0];
   1065   1.1  mrg     __mul_64x128_short (CA, T, CX);
   1066   1.1  mrg   } else {
   1067   1.1  mrg     T128 = power10_index_binexp_128[bin_index];
   1068   1.1  mrg     __mul_64x128_short (CA, CX.w[0], T128);
   1069   1.1  mrg   }
   1070   1.1  mrg 
   1071   1.1  mrg   ed2 = 15;
   1072   1.1  mrg   if (__unsigned_compare_gt_128 (CY, CA))
   1073   1.1  mrg     ed2++;
   1074   1.1  mrg 
   1075   1.1  mrg   T128 = power10_table_128[ed2];
   1076   1.1  mrg   __mul_128x128_to_256 (CA4, CA, T128);
   1077   1.1  mrg 
   1078   1.1  mrg   ed2 += estimate_decimal_digits[bin_index];
   1079   1.1  mrg   CQ.w[0] = CQ.w[1] = 0;
   1080   1.1  mrg   diff_expon = diff_expon - ed2;
   1081   1.1  mrg 
   1082   1.1  mrg } else {
   1083   1.1  mrg   // get CQ = CX/CY
   1084   1.1  mrg   __div_128_by_128 (&CQ, &CR, CX, CY);
   1085   1.1  mrg 
   1086   1.1  mrg   // get number of decimal digits in CQ
   1087   1.1  mrg   // 2^64
   1088   1.1  mrg   f64.i = 0x5f800000;
   1089   1.1  mrg   fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
   1090   1.1  mrg   // binary expon. of CQ
   1091   1.1  mrg   bin_expon = (fx.i - 0x3f800000) >> 23;
   1092   1.1  mrg 
   1093   1.1  mrg   digits_q = estimate_decimal_digits[bin_expon];
   1094   1.1  mrg   TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
   1095   1.1  mrg   TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
   1096   1.1  mrg   if (__unsigned_compare_ge_128 (CQ, TP128))
   1097   1.1  mrg     digits_q++;
   1098   1.1  mrg 
   1099   1.1  mrg   if (digits_q <= 16) {
   1100   1.1  mrg     if (!CR.w[1] && !CR.w[0]) {
   1101   1.1  mrg       res = get_BID64 (sign_x ^ sign_y, diff_expon,
   1102   1.1  mrg 		       CQ.w[0], rnd_mode, pfpsf);
   1103   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1104   1.1  mrg       (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1105   1.1  mrg #endif
   1106   1.1  mrg       BID_RETURN (res);
   1107   1.1  mrg     }
   1108   1.1  mrg 
   1109   1.1  mrg     ed2 = 16 - digits_q;
   1110   1.1  mrg     T128.w[0] = power10_table_128[ed2].w[0];
   1111   1.1  mrg     __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
   1112   1.1  mrg     diff_expon = diff_expon - ed2;
   1113   1.1  mrg     CQ.w[0] *= T128.w[0];
   1114   1.1  mrg   } else {
   1115   1.1  mrg     ed2 = digits_q - 16;
   1116   1.1  mrg     diff_expon += ed2;
   1117   1.1  mrg     T128 = reciprocals10_128[ed2];
   1118   1.1  mrg     __mul_128x128_to_256 (P256, CQ, T128);
   1119   1.1  mrg     amount = recip_scale[ed2];
   1120   1.1  mrg     CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
   1121   1.1  mrg     CQ.w[1] = 0;
   1122   1.1  mrg 
   1123   1.1  mrg     __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
   1124   1.1  mrg 
   1125   1.1  mrg     __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
   1126   1.1  mrg     QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
   1127   1.1  mrg 
   1128   1.1  mrg     CA4.w[1] = CX.w[1] - QB256.w[1];
   1129   1.1  mrg     CA4.w[0] = CX.w[0] - QB256.w[0];
   1130   1.1  mrg     if (CX.w[0] < QB256.w[0])
   1131   1.1  mrg       CA4.w[1]--;
   1132   1.1  mrg     if (CR.w[0] || CR.w[1])
   1133   1.1  mrg       CA4.w[0] |= 1;
   1134   1.1  mrg     done = 1;
   1135   1.1  mrg 	if(CA4.w[1]|CA4.w[0]) {
   1136   1.1  mrg     __mul_64x128_low(CY, (power10_table_128[ed2].w[0]),CY);
   1137   1.1  mrg 	}
   1138   1.1  mrg 
   1139   1.1  mrg   }
   1140   1.1  mrg 
   1141   1.1  mrg }
   1142   1.1  mrg 
   1143   1.1  mrg if (!done) {
   1144   1.1  mrg   __div_256_by_128 (&CQ, &CA4, CY);
   1145   1.1  mrg }
   1146   1.1  mrg 
   1147   1.1  mrg #ifdef SET_STATUS_FLAGS
   1148   1.1  mrg   if (CA4.w[0] || CA4.w[1]) {
   1149   1.1  mrg     // set status flags
   1150   1.1  mrg     __set_status_flags (pfpsf, INEXACT_EXCEPTION);
   1151   1.1  mrg   }
   1152   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
   1153   1.1  mrg   else
   1154   1.1  mrg #endif
   1155   1.1  mrg #else
   1156   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
   1157   1.1  mrg   if (!CA4.w[0] && !CA4.w[1])
   1158   1.1  mrg #endif
   1159   1.1  mrg #endif
   1160   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
   1161   1.1  mrg     // check whether result is exact
   1162   1.1  mrg   {
   1163   1.1  mrg 	  if(!done) {
   1164   1.1  mrg     // check whether CX, CY are short
   1165   1.1  mrg     if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
   1166   1.1  mrg       i = (int) CY.w[0] - 1;
   1167   1.1  mrg       j = (int) CX.w[0] - 1;
   1168   1.1  mrg       // difference in powers of 2 factors for Y and X
   1169   1.1  mrg       nzeros = ed2 - factors[i][0] + factors[j][0];
   1170   1.1  mrg       // difference in powers of 5 factors
   1171   1.1  mrg       d5 = ed2 - factors[i][1] + factors[j][1];
   1172   1.1  mrg       if (d5 < nzeros)
   1173   1.1  mrg 		nzeros = d5;
   1174   1.1  mrg       // get P*(2^M[extra_digits])/10^extra_digits
   1175   1.5  mrg       __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
   1176   1.1  mrg       //__mul_128x128_to_256(P256, CQ, reciprocals10_128[nzeros]);Qh.w[1]=P256.w[3];Qh.w[0]=P256.w[2];
   1177   1.1  mrg 
   1178   1.1  mrg       // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
   1179   1.1  mrg       amount = recip_scale[nzeros];
   1180   1.1  mrg       __shr_128_long (CQ, Qh, amount);
   1181   1.1  mrg 
   1182   1.1  mrg       diff_expon += nzeros;
   1183   1.1  mrg     } else {
   1184   1.1  mrg       // decompose Q as Qh*10^17 + Ql
   1185   1.1  mrg       //T128 = reciprocals10_128[17];
   1186   1.1  mrg       Q_low = CQ.w[0];
   1187   1.1  mrg 
   1188   1.1  mrg       {
   1189   1.1  mrg 	tdigit[0] = Q_low & 0x3ffffff;
   1190   1.1  mrg 	tdigit[1] = 0;
   1191   1.1  mrg 	QX = Q_low >> 26;
   1192   1.1  mrg 	QX32 = QX;
   1193   1.1  mrg 	nzeros = 0;
   1194   1.1  mrg 
   1195   1.1  mrg 	for (j = 0; QX32; j++, QX32 >>= 7) {
   1196   1.1  mrg 	  k = (QX32 & 127);
   1197   1.1  mrg 	  tdigit[0] += convert_table[j][k][0];
   1198   1.1  mrg 	  tdigit[1] += convert_table[j][k][1];
   1199   1.1  mrg 	  if (tdigit[0] >= 100000000) {
   1200   1.1  mrg 	    tdigit[0] -= 100000000;
   1201   1.1  mrg 	    tdigit[1]++;
   1202   1.1  mrg 	  }
   1203   1.1  mrg 	}
   1204   1.1  mrg 
   1205   1.1  mrg 	if (tdigit[1] >= 100000000) {
   1206   1.1  mrg 	  tdigit[1] -= 100000000;
   1207   1.1  mrg 	  if (tdigit[1] >= 100000000)
   1208   1.1  mrg 	    tdigit[1] -= 100000000;
   1209   1.1  mrg 	}
   1210   1.1  mrg 
   1211   1.1  mrg 	digit = tdigit[0];
   1212   1.1  mrg 	if (!digit && !tdigit[1])
   1213   1.1  mrg 	  nzeros += 16;
   1214   1.1  mrg 	else {
   1215   1.1  mrg 	  if (!digit) {
   1216   1.1  mrg 	    nzeros += 8;
   1217   1.1  mrg 	    digit = tdigit[1];
   1218   1.1  mrg 	  }
   1219   1.1  mrg 	  // decompose digit
   1220   1.1  mrg 	  PD = (UINT64) digit *0x068DB8BBull;
   1221   1.1  mrg 	  digit_h = (UINT32) (PD >> 40);
   1222   1.1  mrg 	  digit_low = digit - digit_h * 10000;
   1223   1.1  mrg 
   1224   1.1  mrg 	  if (!digit_low)
   1225   1.1  mrg 	    nzeros += 4;
   1226   1.1  mrg 	  else
   1227   1.1  mrg 	    digit_h = digit_low;
   1228   1.1  mrg 
   1229   1.1  mrg 	  if (!(digit_h & 1))
   1230   1.1  mrg 	    nzeros +=
   1231   1.1  mrg 	      3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
   1232   1.1  mrg 			    (digit_h & 7));
   1233   1.1  mrg 	}
   1234   1.1  mrg 
   1235   1.1  mrg 	if (nzeros) {
   1236   1.1  mrg 	  // get P*(2^M[extra_digits])/10^extra_digits
   1237   1.5  mrg 	  __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
   1238   1.1  mrg 
   1239   1.1  mrg 	  // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
   1240   1.1  mrg 	  amount = recip_scale[nzeros];
   1241   1.1  mrg 	  __shr_128 (CQ, Qh, amount);
   1242   1.1  mrg 	}
   1243   1.1  mrg 	diff_expon += nzeros;
   1244   1.1  mrg 
   1245   1.1  mrg       }
   1246   1.1  mrg     }
   1247   1.1  mrg 	  }
   1248   1.1  mrg 	if(diff_expon>=0){
   1249   1.1  mrg     res =
   1250   1.1  mrg       fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
   1251   1.1  mrg 			       rnd_mode, pfpsf);
   1252   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1253   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1254   1.1  mrg #endif
   1255   1.1  mrg     BID_RETURN (res);
   1256   1.1  mrg 	}
   1257   1.1  mrg   }
   1258   1.1  mrg #endif
   1259   1.1  mrg 
   1260   1.1  mrg   if (diff_expon >= 0) {
   1261   1.1  mrg #ifdef IEEE_ROUND_NEAREST
   1262   1.1  mrg   // rounding
   1263   1.1  mrg   // 2*CA4 - CY
   1264   1.1  mrg   CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
   1265   1.1  mrg   CA4r.w[0] = CA4.w[0] + CA4.w[0];
   1266   1.1  mrg   __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
   1267   1.1  mrg   CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
   1268   1.1  mrg 
   1269   1.1  mrg   D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
   1270   1.1  mrg   carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
   1271   1.1  mrg 
   1272   1.1  mrg   CQ.w[0] += carry64;
   1273   1.1  mrg   //if(CQ.w[0]<carry64)
   1274   1.1  mrg   //CQ.w[1] ++;
   1275   1.1  mrg #else
   1276   1.1  mrg #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
   1277   1.1  mrg   // rounding
   1278   1.1  mrg   // 2*CA4 - CY
   1279   1.1  mrg   CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
   1280   1.1  mrg   CA4r.w[0] = CA4.w[0] + CA4.w[0];
   1281   1.1  mrg   __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
   1282   1.1  mrg   CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
   1283   1.1  mrg 
   1284   1.1  mrg   D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
   1285   1.1  mrg   carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
   1286   1.1  mrg 
   1287   1.1  mrg   CQ.w[0] += carry64;
   1288   1.1  mrg   if (CQ.w[0] < carry64)
   1289   1.1  mrg     CQ.w[1]++;
   1290   1.1  mrg #else
   1291   1.1  mrg   rmode = rnd_mode;
   1292   1.1  mrg   if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
   1293   1.1  mrg     rmode = 3 - rmode;
   1294   1.1  mrg   switch (rmode) {
   1295   1.1  mrg   case ROUNDING_TO_NEAREST:	// round to nearest code
   1296   1.1  mrg     // rounding
   1297   1.1  mrg     // 2*CA4 - CY
   1298   1.1  mrg     CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
   1299   1.1  mrg     CA4r.w[0] = CA4.w[0] + CA4.w[0];
   1300   1.1  mrg     __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
   1301   1.1  mrg     CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
   1302   1.1  mrg     D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
   1303   1.1  mrg     carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
   1304   1.1  mrg     CQ.w[0] += carry64;
   1305   1.1  mrg     if (CQ.w[0] < carry64)
   1306   1.1  mrg       CQ.w[1]++;
   1307   1.1  mrg     break;
   1308   1.1  mrg   case ROUNDING_TIES_AWAY:
   1309   1.1  mrg     // rounding
   1310   1.1  mrg     // 2*CA4 - CY
   1311   1.1  mrg     CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
   1312   1.1  mrg     CA4r.w[0] = CA4.w[0] + CA4.w[0];
   1313   1.1  mrg     __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
   1314   1.1  mrg     CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
   1315   1.1  mrg     D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
   1316   1.1  mrg     carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
   1317   1.1  mrg     CQ.w[0] += carry64;
   1318   1.1  mrg     if (CQ.w[0] < carry64)
   1319   1.1  mrg       CQ.w[1]++;
   1320   1.1  mrg     break;
   1321   1.1  mrg   case ROUNDING_DOWN:
   1322   1.1  mrg   case ROUNDING_TO_ZERO:
   1323   1.1  mrg     break;
   1324   1.1  mrg   default:	// rounding up
   1325   1.1  mrg     CQ.w[0]++;
   1326   1.1  mrg     if (!CQ.w[0])
   1327   1.1  mrg       CQ.w[1]++;
   1328   1.1  mrg     break;
   1329   1.1  mrg   }
   1330   1.1  mrg #endif
   1331   1.1  mrg #endif
   1332   1.1  mrg 
   1333   1.1  mrg 
   1334   1.1  mrg     res =
   1335   1.1  mrg       fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
   1336   1.1  mrg 			       pfpsf);
   1337   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1338   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1339   1.1  mrg #endif
   1340   1.1  mrg     BID_RETURN (res);
   1341   1.1  mrg   } else {
   1342   1.1  mrg     // UF occurs
   1343   1.1  mrg 
   1344   1.1  mrg #ifdef SET_STATUS_FLAGS
   1345   1.1  mrg     if ((diff_expon + 16 < 0)) {
   1346   1.1  mrg       // set status flags
   1347   1.1  mrg       __set_status_flags (pfpsf, INEXACT_EXCEPTION);
   1348   1.1  mrg     }
   1349   1.1  mrg #endif
   1350   1.1  mrg     rmode = rnd_mode;
   1351   1.1  mrg     res =
   1352   1.1  mrg       get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
   1353   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1354   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1355   1.1  mrg #endif
   1356   1.1  mrg     BID_RETURN (res);
   1357   1.1  mrg 
   1358   1.1  mrg   }
   1359   1.1  mrg 
   1360   1.1  mrg }
   1361   1.1  mrg 
   1362   1.1  mrg //#define LEAVE_TRAILING_ZEROS
   1363   1.1  mrg 
   1364   1.1  mrg extern UINT32 convert_table[5][128][2];
   1365   1.1  mrg extern SINT8 factors[][2];
   1366   1.1  mrg extern UINT8 packed_10000_zeros[];
   1367   1.1  mrg 
   1368   1.1  mrg 
   1369   1.1  mrg //UINT64* bid64_div128x128(UINT64 res, UINT128 *px, UINT128 *py, unsigned rnd_mode, unsigned *pfpsf)
   1370   1.1  mrg 
   1371   1.1  mrg TYPE0_FUNCTION_ARG128_ARG128 (UINT64, bid64qq_div, x, y)
   1372   1.1  mrg      UINT256 CA4 =
   1373   1.1  mrg        { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
   1374   1.5  mrg UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
   1375   1.1  mrg UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, valid_y, PD, res;
   1376   1.1  mrg int_float fx, fy, f64;
   1377   1.1  mrg UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
   1378   1.1  mrg int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
   1379   1.1  mrg   digits_q, amount;
   1380   1.1  mrg int nzeros, i, j, k, d5, done = 0;
   1381   1.1  mrg unsigned rmode;
   1382   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1383   1.1  mrg fexcept_t binaryflags = 0;
   1384   1.1  mrg #endif
   1385   1.1  mrg 
   1386   1.1  mrg valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y);
   1387   1.1  mrg 
   1388   1.1  mrg 	// unpack arguments, check for NaN or Infinity
   1389   1.1  mrg if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) {
   1390   1.1  mrg   // test if x is NaN
   1391   1.1  mrg   if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
   1392   1.1  mrg #ifdef SET_STATUS_FLAGS
   1393   1.1  mrg     if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull ||	// sNaN
   1394   1.1  mrg 	(y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull)
   1395   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
   1396   1.1  mrg #endif
   1397   1.1  mrg       Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull);
   1398   1.1  mrg       Tmp.w[0] = CX.w[0];
   1399   1.1  mrg       TP128 = reciprocals10_128[18];
   1400   1.5  mrg       __mul_128x128_high (Qh, Tmp, TP128);
   1401   1.1  mrg       amount = recip_scale[18];
   1402   1.1  mrg       __shr_128 (Tmp, Qh, amount);
   1403   1.1  mrg       res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
   1404   1.1  mrg     BID_RETURN (res);
   1405   1.1  mrg   }
   1406   1.1  mrg   // x is Infinity?
   1407   1.1  mrg   if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
   1408   1.1  mrg     // check if y is Inf.
   1409   1.1  mrg     if (((y.w[1] & 0x7c00000000000000ull) == 0x7800000000000000ull))
   1410   1.1  mrg       // return NaN
   1411   1.1  mrg     {
   1412   1.1  mrg #ifdef SET_STATUS_FLAGS
   1413   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
   1414   1.1  mrg #endif
   1415   1.1  mrg       res = 0x7c00000000000000ull;
   1416   1.1  mrg       BID_RETURN (res);
   1417   1.1  mrg     }
   1418   1.1  mrg 	if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
   1419   1.1  mrg     // otherwise return +/-Inf
   1420   1.1  mrg     res =
   1421   1.1  mrg       ((x.w[1] ^ y.
   1422   1.1  mrg 	w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
   1423   1.1  mrg     BID_RETURN (res);
   1424   1.1  mrg 	}
   1425   1.1  mrg   }
   1426   1.1  mrg   // x is 0
   1427   1.1  mrg   if (((y.w[1] & 0x7800000000000000ull) != 0x7800000000000000ull)) {
   1428   1.1  mrg   if ((!CY.w[0]) && !(CY.w[1] & 0x0001ffffffffffffull)) {
   1429   1.1  mrg #ifdef SET_STATUS_FLAGS
   1430   1.1  mrg     __set_status_flags (pfpsf, INVALID_EXCEPTION);
   1431   1.1  mrg #endif
   1432   1.1  mrg     // x=y=0, return NaN
   1433   1.1  mrg     res = 0x7c00000000000000ull;
   1434   1.1  mrg     BID_RETURN (res);
   1435   1.1  mrg   }
   1436   1.1  mrg   // return 0
   1437   1.1  mrg   res = (x.w[1] ^ y.w[1]) & 0x8000000000000000ull;
   1438   1.1  mrg   exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
   1439   1.1  mrg   if (exponent_x > DECIMAL_MAX_EXPON_64)
   1440   1.1  mrg     exponent_x = DECIMAL_MAX_EXPON_64;
   1441   1.1  mrg   else if (exponent_x < 0)
   1442   1.1  mrg     exponent_x = 0;
   1443   1.1  mrg   res |= (((UINT64) exponent_x) << 53);
   1444   1.1  mrg   BID_RETURN (res);
   1445   1.1  mrg   }
   1446   1.1  mrg }
   1447   1.1  mrg if (!valid_y) {
   1448   1.1  mrg   // y is Inf. or NaN
   1449   1.1  mrg 
   1450   1.1  mrg   // test if y is NaN
   1451   1.1  mrg   if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
   1452   1.1  mrg #ifdef SET_STATUS_FLAGS
   1453   1.1  mrg     if ((y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull)	// sNaN
   1454   1.1  mrg       __set_status_flags (pfpsf, INVALID_EXCEPTION);
   1455   1.1  mrg #endif
   1456   1.1  mrg       Tmp.w[1] = (CY.w[1] & 0x00003fffffffffffull);
   1457   1.1  mrg       Tmp.w[0] = CY.w[0];
   1458   1.1  mrg       TP128 = reciprocals10_128[18];
   1459   1.5  mrg       __mul_128x128_high (Qh, Tmp, TP128);
   1460   1.1  mrg       amount = recip_scale[18];
   1461   1.1  mrg       __shr_128 (Tmp, Qh, amount);
   1462   1.1  mrg       res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
   1463   1.1  mrg     BID_RETURN (res);
   1464   1.1  mrg   }
   1465   1.1  mrg   // y is Infinity?
   1466   1.1  mrg   if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
   1467   1.1  mrg     // return +/-0
   1468   1.1  mrg     res = sign_x ^ sign_y;
   1469   1.1  mrg     BID_RETURN (res);
   1470   1.1  mrg   }
   1471   1.1  mrg   // y is 0, return +/-Inf
   1472   1.1  mrg   res =
   1473   1.1  mrg     ((x.w[1] ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
   1474   1.1  mrg #ifdef SET_STATUS_FLAGS
   1475   1.1  mrg   __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
   1476   1.1  mrg #endif
   1477   1.1  mrg   BID_RETURN (res);
   1478   1.1  mrg }
   1479   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1480   1.1  mrg (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1481   1.1  mrg #endif
   1482   1.1  mrg diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
   1483   1.1  mrg 
   1484   1.1  mrg if (__unsigned_compare_gt_128 (CY, CX)) {
   1485   1.1  mrg   // CX < CY
   1486   1.1  mrg 
   1487   1.1  mrg   // 2^64
   1488   1.1  mrg   f64.i = 0x5f800000;
   1489   1.1  mrg 
   1490   1.1  mrg   // fx ~ CX,   fy ~ CY
   1491   1.1  mrg   fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
   1492   1.1  mrg   fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
   1493   1.1  mrg   // expon_cy - expon_cx
   1494   1.1  mrg   bin_index = (fy.i - fx.i) >> 23;
   1495   1.1  mrg 
   1496   1.1  mrg   if (CX.w[1]) {
   1497   1.1  mrg     T = power10_index_binexp_128[bin_index].w[0];
   1498   1.1  mrg     __mul_64x128_short (CA, T, CX);
   1499   1.1  mrg   } else {
   1500   1.1  mrg     T128 = power10_index_binexp_128[bin_index];
   1501   1.1  mrg     __mul_64x128_short (CA, CX.w[0], T128);
   1502   1.1  mrg   }
   1503   1.1  mrg 
   1504   1.1  mrg   ed2 = 15;
   1505   1.1  mrg   if (__unsigned_compare_gt_128 (CY, CA))
   1506   1.1  mrg     ed2++;
   1507   1.1  mrg 
   1508   1.1  mrg   T128 = power10_table_128[ed2];
   1509   1.1  mrg   __mul_128x128_to_256 (CA4, CA, T128);
   1510   1.1  mrg 
   1511   1.1  mrg   ed2 += estimate_decimal_digits[bin_index];
   1512   1.1  mrg   CQ.w[0] = CQ.w[1] = 0;
   1513   1.1  mrg   diff_expon = diff_expon - ed2;
   1514   1.1  mrg 
   1515   1.1  mrg } else {
   1516   1.1  mrg   // get CQ = CX/CY
   1517   1.1  mrg   __div_128_by_128 (&CQ, &CR, CX, CY);
   1518   1.1  mrg 
   1519   1.1  mrg   // get number of decimal digits in CQ
   1520   1.1  mrg   // 2^64
   1521   1.1  mrg   f64.i = 0x5f800000;
   1522   1.1  mrg   fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
   1523   1.1  mrg   // binary expon. of CQ
   1524   1.1  mrg   bin_expon = (fx.i - 0x3f800000) >> 23;
   1525   1.1  mrg 
   1526   1.1  mrg   digits_q = estimate_decimal_digits[bin_expon];
   1527   1.1  mrg   TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
   1528   1.1  mrg   TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
   1529   1.1  mrg   if (__unsigned_compare_ge_128 (CQ, TP128))
   1530   1.1  mrg     digits_q++;
   1531   1.1  mrg 
   1532   1.1  mrg   if (digits_q <= 16) {
   1533   1.1  mrg     if (!CR.w[1] && !CR.w[0]) {
   1534   1.1  mrg       res = get_BID64 (sign_x ^ sign_y, diff_expon,
   1535   1.1  mrg 		       CQ.w[0], rnd_mode, pfpsf);
   1536   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1537   1.1  mrg       (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1538   1.1  mrg #endif
   1539   1.1  mrg       BID_RETURN (res);
   1540   1.1  mrg     }
   1541   1.1  mrg 
   1542   1.1  mrg     ed2 = 16 - digits_q;
   1543   1.1  mrg     T128.w[0] = power10_table_128[ed2].w[0];
   1544   1.1  mrg     __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
   1545   1.1  mrg     diff_expon = diff_expon - ed2;
   1546   1.1  mrg     CQ.w[0] *= T128.w[0];
   1547   1.1  mrg   } else {
   1548   1.1  mrg     ed2 = digits_q - 16;
   1549   1.1  mrg     diff_expon += ed2;
   1550   1.1  mrg     T128 = reciprocals10_128[ed2];
   1551   1.1  mrg     __mul_128x128_to_256 (P256, CQ, T128);
   1552   1.1  mrg     amount = recip_scale[ed2];
   1553   1.1  mrg     CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
   1554   1.1  mrg     CQ.w[1] = 0;
   1555   1.1  mrg 
   1556   1.1  mrg     __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
   1557   1.1  mrg 
   1558   1.1  mrg     __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
   1559   1.1  mrg     QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
   1560   1.1  mrg 
   1561   1.1  mrg     CA4.w[1] = CX.w[1] - QB256.w[1];
   1562   1.1  mrg     CA4.w[0] = CX.w[0] - QB256.w[0];
   1563   1.1  mrg     if (CX.w[0] < QB256.w[0])
   1564   1.1  mrg       CA4.w[1]--;
   1565   1.1  mrg     if (CR.w[0] || CR.w[1])
   1566   1.1  mrg       CA4.w[0] |= 1;
   1567   1.1  mrg     done = 1;
   1568   1.1  mrg 	if(CA4.w[1]|CA4.w[0]) {
   1569   1.1  mrg     __mul_64x128_low(CY, (power10_table_128[ed2].w[0]),CY);
   1570   1.1  mrg 	}
   1571   1.1  mrg   }
   1572   1.1  mrg 
   1573   1.1  mrg }
   1574   1.1  mrg 
   1575   1.1  mrg if (!done) {
   1576   1.1  mrg   __div_256_by_128 (&CQ, &CA4, CY);
   1577   1.1  mrg }
   1578   1.1  mrg 
   1579   1.1  mrg 
   1580   1.1  mrg 
   1581   1.1  mrg #ifdef SET_STATUS_FLAGS
   1582   1.1  mrg   if (CA4.w[0] || CA4.w[1]) {
   1583   1.1  mrg     // set status flags
   1584   1.1  mrg     __set_status_flags (pfpsf, INEXACT_EXCEPTION);
   1585   1.1  mrg   }
   1586   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
   1587   1.1  mrg   else
   1588   1.1  mrg #endif
   1589   1.1  mrg #else
   1590   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
   1591   1.1  mrg   if (!CA4.w[0] && !CA4.w[1])
   1592   1.1  mrg #endif
   1593   1.1  mrg #endif
   1594   1.1  mrg #ifndef LEAVE_TRAILING_ZEROS
   1595   1.1  mrg     // check whether result is exact
   1596   1.1  mrg   {
   1597   1.1  mrg 	  if(!done) {
   1598   1.1  mrg     // check whether CX, CY are short
   1599   1.1  mrg     if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
   1600   1.1  mrg       i = (int) CY.w[0] - 1;
   1601   1.1  mrg       j = (int) CX.w[0] - 1;
   1602   1.1  mrg       // difference in powers of 2 factors for Y and X
   1603   1.1  mrg       nzeros = ed2 - factors[i][0] + factors[j][0];
   1604   1.1  mrg       // difference in powers of 5 factors
   1605   1.1  mrg       d5 = ed2 - factors[i][1] + factors[j][1];
   1606   1.1  mrg       if (d5 < nzeros)
   1607   1.1  mrg 	nzeros = d5;
   1608   1.1  mrg       // get P*(2^M[extra_digits])/10^extra_digits
   1609   1.5  mrg       __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
   1610   1.1  mrg       //__mul_128x128_to_256(P256, CQ, reciprocals10_128[nzeros]);Qh.w[1]=P256.w[3];Qh.w[0]=P256.w[2];
   1611   1.1  mrg 
   1612   1.1  mrg       // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
   1613   1.1  mrg       amount = recip_scale[nzeros];
   1614   1.1  mrg       __shr_128_long (CQ, Qh, amount);
   1615   1.1  mrg 
   1616   1.1  mrg       diff_expon += nzeros;
   1617   1.1  mrg     } else {
   1618   1.1  mrg       // decompose Q as Qh*10^17 + Ql
   1619   1.1  mrg       //T128 = reciprocals10_128[17];
   1620   1.1  mrg       Q_low = CQ.w[0];
   1621   1.1  mrg 
   1622   1.1  mrg       {
   1623   1.1  mrg 	tdigit[0] = Q_low & 0x3ffffff;
   1624   1.1  mrg 	tdigit[1] = 0;
   1625   1.1  mrg 	QX = Q_low >> 26;
   1626   1.1  mrg 	QX32 = QX;
   1627   1.1  mrg 	nzeros = 0;
   1628   1.1  mrg 
   1629   1.1  mrg 	for (j = 0; QX32; j++, QX32 >>= 7) {
   1630   1.1  mrg 	  k = (QX32 & 127);
   1631   1.1  mrg 	  tdigit[0] += convert_table[j][k][0];
   1632   1.1  mrg 	  tdigit[1] += convert_table[j][k][1];
   1633   1.1  mrg 	  if (tdigit[0] >= 100000000) {
   1634   1.1  mrg 	    tdigit[0] -= 100000000;
   1635   1.1  mrg 	    tdigit[1]++;
   1636   1.1  mrg 	  }
   1637   1.1  mrg 	}
   1638   1.1  mrg 
   1639   1.1  mrg 	if (tdigit[1] >= 100000000) {
   1640   1.1  mrg 	  tdigit[1] -= 100000000;
   1641   1.1  mrg 	  if (tdigit[1] >= 100000000)
   1642   1.1  mrg 	    tdigit[1] -= 100000000;
   1643   1.1  mrg 	}
   1644   1.1  mrg 
   1645   1.1  mrg 	digit = tdigit[0];
   1646   1.1  mrg 	if (!digit && !tdigit[1])
   1647   1.1  mrg 	  nzeros += 16;
   1648   1.1  mrg 	else {
   1649   1.1  mrg 	  if (!digit) {
   1650   1.1  mrg 	    nzeros += 8;
   1651   1.1  mrg 	    digit = tdigit[1];
   1652   1.1  mrg 	  }
   1653   1.1  mrg 	  // decompose digit
   1654   1.1  mrg 	  PD = (UINT64) digit *0x068DB8BBull;
   1655   1.1  mrg 	  digit_h = (UINT32) (PD >> 40);
   1656   1.1  mrg 	  digit_low = digit - digit_h * 10000;
   1657   1.1  mrg 
   1658   1.1  mrg 	  if (!digit_low)
   1659   1.1  mrg 	    nzeros += 4;
   1660   1.1  mrg 	  else
   1661   1.1  mrg 	    digit_h = digit_low;
   1662   1.1  mrg 
   1663   1.1  mrg 	  if (!(digit_h & 1))
   1664   1.1  mrg 	    nzeros +=
   1665   1.1  mrg 	      3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
   1666   1.1  mrg 			    (digit_h & 7));
   1667   1.1  mrg 	}
   1668   1.1  mrg 
   1669   1.1  mrg 	if (nzeros) {
   1670   1.1  mrg 	  // get P*(2^M[extra_digits])/10^extra_digits
   1671   1.5  mrg 	  __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
   1672   1.1  mrg 
   1673   1.1  mrg 	  // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
   1674   1.1  mrg 	  amount = recip_scale[nzeros];
   1675   1.1  mrg 	  __shr_128 (CQ, Qh, amount);
   1676   1.1  mrg 	}
   1677   1.1  mrg 	diff_expon += nzeros;
   1678   1.1  mrg 
   1679   1.1  mrg       }
   1680   1.1  mrg     }
   1681   1.1  mrg 	  }
   1682   1.1  mrg 	if(diff_expon>=0){
   1683   1.1  mrg     res =
   1684   1.1  mrg       fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
   1685   1.1  mrg 			       rnd_mode, pfpsf);
   1686   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1687   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1688   1.1  mrg #endif
   1689   1.1  mrg     BID_RETURN (res);
   1690   1.1  mrg 	}
   1691   1.1  mrg   }
   1692   1.1  mrg #endif
   1693   1.1  mrg 
   1694   1.1  mrg   if(diff_expon>=0) {
   1695   1.1  mrg 
   1696   1.1  mrg #ifdef IEEE_ROUND_NEAREST
   1697   1.1  mrg   // rounding
   1698   1.1  mrg   // 2*CA4 - CY
   1699   1.1  mrg   CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
   1700   1.1  mrg   CA4r.w[0] = CA4.w[0] + CA4.w[0];
   1701   1.1  mrg   __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
   1702   1.1  mrg   CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
   1703   1.1  mrg 
   1704   1.1  mrg   D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
   1705   1.1  mrg   carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
   1706   1.1  mrg 
   1707   1.1  mrg   CQ.w[0] += carry64;
   1708   1.1  mrg   //if(CQ.w[0]<carry64)
   1709   1.1  mrg   //CQ.w[1] ++;
   1710   1.1  mrg #else
   1711   1.1  mrg #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
   1712   1.1  mrg   // rounding
   1713   1.1  mrg   // 2*CA4 - CY
   1714   1.1  mrg   CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
   1715   1.1  mrg   CA4r.w[0] = CA4.w[0] + CA4.w[0];
   1716   1.1  mrg   __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
   1717   1.1  mrg   CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
   1718   1.1  mrg 
   1719   1.1  mrg   D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
   1720   1.1  mrg   carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
   1721   1.1  mrg 
   1722   1.1  mrg   CQ.w[0] += carry64;
   1723   1.1  mrg   if (CQ.w[0] < carry64)
   1724   1.1  mrg     CQ.w[1]++;
   1725   1.1  mrg #else
   1726   1.1  mrg   rmode = rnd_mode;
   1727   1.1  mrg   if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
   1728   1.1  mrg     rmode = 3 - rmode;
   1729   1.1  mrg   switch (rmode) {
   1730   1.1  mrg   case ROUNDING_TO_NEAREST:	// round to nearest code
   1731   1.1  mrg     // rounding
   1732   1.1  mrg     // 2*CA4 - CY
   1733   1.1  mrg     CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
   1734   1.1  mrg     CA4r.w[0] = CA4.w[0] + CA4.w[0];
   1735   1.1  mrg     __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
   1736   1.1  mrg     CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
   1737   1.1  mrg     D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
   1738   1.1  mrg     carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
   1739   1.1  mrg     CQ.w[0] += carry64;
   1740   1.1  mrg     if (CQ.w[0] < carry64)
   1741   1.1  mrg       CQ.w[1]++;
   1742   1.1  mrg     break;
   1743   1.1  mrg   case ROUNDING_TIES_AWAY:
   1744   1.1  mrg     // rounding
   1745   1.1  mrg     // 2*CA4 - CY
   1746   1.1  mrg     CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
   1747   1.1  mrg     CA4r.w[0] = CA4.w[0] + CA4.w[0];
   1748   1.1  mrg     __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
   1749   1.1  mrg     CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
   1750   1.1  mrg     D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
   1751   1.1  mrg     carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
   1752   1.1  mrg     CQ.w[0] += carry64;
   1753   1.1  mrg     if (CQ.w[0] < carry64)
   1754   1.1  mrg       CQ.w[1]++;
   1755   1.1  mrg     break;
   1756   1.1  mrg   case ROUNDING_DOWN:
   1757   1.1  mrg   case ROUNDING_TO_ZERO:
   1758   1.1  mrg     break;
   1759   1.1  mrg   default:	// rounding up
   1760   1.1  mrg     CQ.w[0]++;
   1761   1.1  mrg     if (!CQ.w[0])
   1762   1.1  mrg       CQ.w[1]++;
   1763   1.1  mrg     break;
   1764   1.1  mrg   }
   1765   1.1  mrg #endif
   1766   1.1  mrg #endif
   1767   1.1  mrg 
   1768   1.1  mrg 
   1769   1.1  mrg     res =
   1770   1.1  mrg       fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
   1771   1.1  mrg 			       pfpsf);
   1772   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1773   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1774   1.1  mrg #endif
   1775   1.1  mrg     BID_RETURN (res);
   1776   1.1  mrg   } else {
   1777   1.1  mrg     // UF occurs
   1778   1.1  mrg 
   1779   1.1  mrg #ifdef SET_STATUS_FLAGS
   1780   1.1  mrg     if ((diff_expon + 16 < 0)) {
   1781   1.1  mrg       // set status flags
   1782   1.1  mrg       __set_status_flags (pfpsf, INEXACT_EXCEPTION);
   1783   1.1  mrg     }
   1784   1.1  mrg #endif
   1785   1.1  mrg     rmode = rnd_mode;
   1786   1.1  mrg     res =
   1787   1.1  mrg       get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
   1788   1.1  mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS
   1789   1.1  mrg     (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
   1790   1.1  mrg #endif
   1791   1.1  mrg     BID_RETURN (res);
   1792   1.1  mrg 
   1793   1.1  mrg   }
   1794   1.1  mrg 
   1795   1.1  mrg }
   1796