(root)/
gcc-13.2.0/
libgcc/
config/
libbid/
bid128_sqrt.c
       1  /* Copyright (C) 2007-2023 Free Software Foundation, Inc.
       2  
       3  This file is part of GCC.
       4  
       5  GCC is free software; you can redistribute it and/or modify it under
       6  the terms of the GNU General Public License as published by the Free
       7  Software Foundation; either version 3, or (at your option) any later
       8  version.
       9  
      10  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11  WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13  for more details.
      14  
      15  Under Section 7 of GPL version 3, you are granted additional
      16  permissions described in the GCC Runtime Library Exception, version
      17  3.1, as published by the Free Software Foundation.
      18  
      19  You should have received a copy of the GNU General Public License and
      20  a copy of the GCC Runtime Library Exception along with this program;
      21  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      22  <http://www.gnu.org/licenses/>.  */
      23  
      24  #define BID_128RES
      25  #include "bid_internal.h"
      26  #include "bid_sqrt_macros.h"
      27  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
      28  #include <fenv.h>
      29  
      30  #define FE_ALL_FLAGS FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT
      31  #endif
      32  
      33  BID128_FUNCTION_ARG1 (bid128_sqrt, x)
      34  
      35       UINT256 M256, C256, C4, C8;
      36       UINT128 CX, CX1, CX2, A10, S2, T128, TP128, CS, CSM, res;
      37       UINT64 sign_x, Carry;
      38       SINT64 D;
      39       int_float fx, f64;
      40       int exponent_x, bin_expon_cx;
      41       int digits, scale, exponent_q;
      42  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
      43       fexcept_t binaryflags = 0;
      44  #endif
      45  
      46    // unpack arguments, check for NaN or Infinity
      47  if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) {
      48  res.w[1] = CX.w[1];
      49  res.w[0] = CX.w[0];
      50      // NaN ?
      51  if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
      52  #ifdef SET_STATUS_FLAGS
      53    if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull)	// sNaN
      54      __set_status_flags (pfpsf, INVALID_EXCEPTION);
      55  #endif
      56    res.w[1] = CX.w[1] & QUIET_MASK64;
      57    BID_RETURN (res);
      58  }
      59      // x is Infinity?
      60  if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
      61    res.w[1] = CX.w[1];
      62    if (sign_x) {
      63      // -Inf, return NaN
      64      res.w[1] = 0x7c00000000000000ull;
      65  #ifdef SET_STATUS_FLAGS
      66      __set_status_flags (pfpsf, INVALID_EXCEPTION);
      67  #endif
      68    }
      69    BID_RETURN (res);
      70  }
      71      // x is 0 otherwise
      72  
      73  res.w[1] =
      74    sign_x |
      75    ((((UINT64) (exponent_x + DECIMAL_EXPONENT_BIAS_128)) >> 1) << 49);
      76  res.w[0] = 0;
      77  BID_RETURN (res);
      78  }
      79  if (sign_x) {
      80    res.w[1] = 0x7c00000000000000ull;
      81    res.w[0] = 0;
      82  #ifdef SET_STATUS_FLAGS
      83    __set_status_flags (pfpsf, INVALID_EXCEPTION);
      84  #endif
      85    BID_RETURN (res);
      86  }
      87  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
      88  (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
      89  #endif
      90    // 2^64
      91  f64.i = 0x5f800000;
      92  
      93    // fx ~ CX
      94  fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
      95  bin_expon_cx = ((fx.i >> 23) & 0xff) - 0x7f;
      96  digits = estimate_decimal_digits[bin_expon_cx];
      97  
      98  A10 = CX;
      99  if (exponent_x & 1) {
     100    A10.w[1] = (CX.w[1] << 3) | (CX.w[0] >> 61);
     101    A10.w[0] = CX.w[0] << 3;
     102    CX2.w[1] = (CX.w[1] << 1) | (CX.w[0] >> 63);
     103    CX2.w[0] = CX.w[0] << 1;
     104    __add_128_128 (A10, A10, CX2);
     105  }
     106  
     107  CS.w[0] = short_sqrt128 (A10);
     108  CS.w[1] = 0;
     109    // check for exact result
     110  if (CS.w[0] * CS.w[0] == A10.w[0]) {
     111    __mul_64x64_to_128_fast (S2, CS.w[0], CS.w[0]);
     112    if (S2.w[1] == A10.w[1])	// && S2.w[0]==A10.w[0])
     113    {
     114      get_BID128_very_fast (&res, 0,
     115  			  (exponent_x +
     116  			   DECIMAL_EXPONENT_BIAS_128) >> 1, CS);
     117  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
     118      (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
     119  #endif
     120      BID_RETURN (res);
     121    }
     122  }
     123    // get number of digits in CX
     124  D = CX.w[1] - power10_index_binexp_128[bin_expon_cx].w[1];
     125  if (D > 0
     126      || (!D && CX.w[0] >= power10_index_binexp_128[bin_expon_cx].w[0]))
     127    digits++;
     128  
     129    // if exponent is odd, scale coefficient by 10
     130  scale = 67 - digits;
     131  exponent_q = exponent_x - scale;
     132  scale += (exponent_q & 1);	// exp. bias is even
     133  
     134  if (scale > 38) {
     135    T128 = power10_table_128[scale - 37];
     136    __mul_128x128_low (CX1, CX, T128);
     137  
     138    TP128 = power10_table_128[37];
     139    __mul_128x128_to_256 (C256, CX1, TP128);
     140  } else {
     141    T128 = power10_table_128[scale];
     142    __mul_128x128_to_256 (C256, CX, T128);
     143  }
     144  
     145  
     146    // 4*C256
     147  C4.w[3] = (C256.w[3] << 2) | (C256.w[2] >> 62);
     148  C4.w[2] = (C256.w[2] << 2) | (C256.w[1] >> 62);
     149  C4.w[1] = (C256.w[1] << 2) | (C256.w[0] >> 62);
     150  C4.w[0] = C256.w[0] << 2;
     151  
     152  long_sqrt128 (&CS, C256);
     153  
     154  #ifndef IEEE_ROUND_NEAREST
     155  #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
     156  if (!((rnd_mode) & 3)) {
     157  #endif
     158  #endif
     159    // compare to midpoints
     160    CSM.w[1] = (CS.w[1] << 1) | (CS.w[0] >> 63);
     161    CSM.w[0] = (CS.w[0] + CS.w[0]) | 1;
     162    // CSM^2
     163    //__mul_128x128_to_256(M256, CSM, CSM);
     164    __sqr128_to_256 (M256, CSM);
     165  
     166    if (C4.w[3] > M256.w[3]
     167        || (C4.w[3] == M256.w[3]
     168  	  && (C4.w[2] > M256.w[2]
     169  	      || (C4.w[2] == M256.w[2]
     170  		  && (C4.w[1] > M256.w[1]
     171  		      || (C4.w[1] == M256.w[1]
     172  			  && C4.w[0] > M256.w[0])))))) {
     173      // round up
     174      CS.w[0]++;
     175      if (!CS.w[0])
     176        CS.w[1]++;
     177    } else {
     178      C8.w[1] = (CS.w[1] << 3) | (CS.w[0] >> 61);
     179      C8.w[0] = CS.w[0] << 3;
     180      // M256 - 8*CSM
     181      __sub_borrow_out (M256.w[0], Carry, M256.w[0], C8.w[0]);
     182      __sub_borrow_in_out (M256.w[1], Carry, M256.w[1], C8.w[1], Carry);
     183      __sub_borrow_in_out (M256.w[2], Carry, M256.w[2], 0, Carry);
     184      M256.w[3] = M256.w[3] - Carry;
     185  
     186      // if CSM' > C256, round up
     187      if (M256.w[3] > C4.w[3]
     188  	|| (M256.w[3] == C4.w[3]
     189  	    && (M256.w[2] > C4.w[2]
     190  		|| (M256.w[2] == C4.w[2]
     191  		    && (M256.w[1] > C4.w[1]
     192  			|| (M256.w[1] == C4.w[1]
     193  			    && M256.w[0] > C4.w[0])))))) {
     194        // round down
     195        if (!CS.w[0])
     196  	CS.w[1]--;
     197        CS.w[0]--;
     198      }
     199    }
     200  #ifndef IEEE_ROUND_NEAREST
     201  #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
     202  } else {
     203    __sqr128_to_256 (M256, CS);
     204    C8.w[1] = (CS.w[1] << 1) | (CS.w[0] >> 63);
     205    C8.w[0] = CS.w[0] << 1;
     206    if (M256.w[3] > C256.w[3]
     207        || (M256.w[3] == C256.w[3]
     208  	  && (M256.w[2] > C256.w[2]
     209  	      || (M256.w[2] == C256.w[2]
     210  		  && (M256.w[1] > C256.w[1]
     211  		      || (M256.w[1] == C256.w[1]
     212  			  && M256.w[0] > C256.w[0])))))) {
     213      __sub_borrow_out (M256.w[0], Carry, M256.w[0], C8.w[0]);
     214      __sub_borrow_in_out (M256.w[1], Carry, M256.w[1], C8.w[1], Carry);
     215      __sub_borrow_in_out (M256.w[2], Carry, M256.w[2], 0, Carry);
     216      M256.w[3] = M256.w[3] - Carry;
     217      M256.w[0]++;
     218      if (!M256.w[0]) {
     219        M256.w[1]++;
     220        if (!M256.w[1]) {
     221  	M256.w[2]++;
     222  	if (!M256.w[2])
     223  	  M256.w[3]++;
     224        }
     225      }
     226  
     227      if (!CS.w[0])
     228        CS.w[1]--;
     229      CS.w[0]--;
     230  
     231      if (M256.w[3] > C256.w[3]
     232  	|| (M256.w[3] == C256.w[3]
     233  	    && (M256.w[2] > C256.w[2]
     234  		|| (M256.w[2] == C256.w[2]
     235  		    && (M256.w[1] > C256.w[1]
     236  			|| (M256.w[1] == C256.w[1]
     237  			    && M256.w[0] > C256.w[0])))))) {
     238  
     239        if (!CS.w[0])
     240  	CS.w[1]--;
     241        CS.w[0]--;
     242      }
     243    }
     244  
     245    else {
     246      __add_carry_out (M256.w[0], Carry, M256.w[0], C8.w[0]);
     247      __add_carry_in_out (M256.w[1], Carry, M256.w[1], C8.w[1], Carry);
     248      __add_carry_in_out (M256.w[2], Carry, M256.w[2], 0, Carry);
     249      M256.w[3] = M256.w[3] + Carry;
     250      M256.w[0]++;
     251      if (!M256.w[0]) {
     252        M256.w[1]++;
     253        if (!M256.w[1]) {
     254  	M256.w[2]++;
     255  	if (!M256.w[2])
     256  	  M256.w[3]++;
     257        }
     258      }
     259      if (M256.w[3] < C256.w[3]
     260  	|| (M256.w[3] == C256.w[3]
     261  	    && (M256.w[2] < C256.w[2]
     262  		|| (M256.w[2] == C256.w[2]
     263  		    && (M256.w[1] < C256.w[1]
     264  			|| (M256.w[1] == C256.w[1]
     265  			    && M256.w[0] <= C256.w[0])))))) {
     266  
     267        CS.w[0]++;
     268        if (!CS.w[0])
     269  	CS.w[1]++;
     270      }
     271    }
     272    // RU?
     273    if ((rnd_mode) == ROUNDING_UP) {
     274      CS.w[0]++;
     275      if (!CS.w[0])
     276        CS.w[1]++;
     277    }
     278  
     279  }
     280  #endif
     281  #endif
     282  
     283  #ifdef SET_STATUS_FLAGS
     284  __set_status_flags (pfpsf, INEXACT_EXCEPTION);
     285  #endif
     286  get_BID128_fast (&res, 0,
     287  		 (exponent_q + DECIMAL_EXPONENT_BIAS_128) >> 1, CS);
     288  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
     289  (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
     290  #endif
     291  BID_RETURN (res);
     292  }
     293  
     294  
     295  
     296  BID128_FUNCTION_ARGTYPE1 (bid128d_sqrt, UINT64, x)
     297  
     298       UINT256 M256, C256, C4, C8;
     299       UINT128 CX, CX1, CX2, A10, S2, T128, TP128, CS, CSM, res;
     300       UINT64 sign_x, Carry;
     301       SINT64 D;
     302       int_float fx, f64;
     303       int exponent_x, bin_expon_cx;
     304       int digits, scale, exponent_q;
     305  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
     306       fexcept_t binaryflags = 0;
     307  #endif
     308  
     309  	// unpack arguments, check for NaN or Infinity
     310     // unpack arguments, check for NaN or Infinity
     311  CX.w[1] = 0;
     312  if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], x)) {
     313  res.w[1] = CX.w[0];
     314  res.w[0] = 0;
     315  	   // NaN ?
     316  if ((x & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
     317  #ifdef SET_STATUS_FLAGS
     318    if ((x & SNAN_MASK64) == SNAN_MASK64)	// sNaN
     319      __set_status_flags (pfpsf, INVALID_EXCEPTION);
     320  #endif
     321    res.w[0] = (CX.w[0] & 0x0003ffffffffffffull);
     322    __mul_64x64_to_128 (res, res.w[0], power10_table_128[18].w[0]);
     323    res.w[1] |= ((CX.w[0]) & 0xfc00000000000000ull);
     324    BID_RETURN (res);
     325  }
     326  	   // x is Infinity?
     327  if ((x & 0x7800000000000000ull) == 0x7800000000000000ull) {
     328    if (sign_x) {
     329      // -Inf, return NaN
     330      res.w[1] = 0x7c00000000000000ull;
     331  #ifdef SET_STATUS_FLAGS
     332      __set_status_flags (pfpsf, INVALID_EXCEPTION);
     333  #endif
     334    }
     335    BID_RETURN (res);
     336  }
     337  	   // x is 0 otherwise
     338  
     339  exponent_x =
     340    exponent_x - DECIMAL_EXPONENT_BIAS + DECIMAL_EXPONENT_BIAS_128;
     341  res.w[1] =
     342    sign_x | ((((UINT64) (exponent_x + DECIMAL_EXPONENT_BIAS_128)) >> 1)
     343  	    << 49);
     344  res.w[0] = 0;
     345  BID_RETURN (res);
     346  }
     347  if (sign_x) {
     348    res.w[1] = 0x7c00000000000000ull;
     349    res.w[0] = 0;
     350  #ifdef SET_STATUS_FLAGS
     351    __set_status_flags (pfpsf, INVALID_EXCEPTION);
     352  #endif
     353    BID_RETURN (res);
     354  }
     355  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
     356  (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
     357  #endif
     358  exponent_x =
     359    exponent_x - DECIMAL_EXPONENT_BIAS + DECIMAL_EXPONENT_BIAS_128;
     360  
     361  	   // 2^64
     362  f64.i = 0x5f800000;
     363  
     364  	   // fx ~ CX
     365  fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
     366  bin_expon_cx = ((fx.i >> 23) & 0xff) - 0x7f;
     367  digits = estimate_decimal_digits[bin_expon_cx];
     368  
     369  A10 = CX;
     370  if (exponent_x & 1) {
     371    A10.w[1] = (CX.w[1] << 3) | (CX.w[0] >> 61);
     372    A10.w[0] = CX.w[0] << 3;
     373    CX2.w[1] = (CX.w[1] << 1) | (CX.w[0] >> 63);
     374    CX2.w[0] = CX.w[0] << 1;
     375    __add_128_128 (A10, A10, CX2);
     376  }
     377  
     378  CS.w[0] = short_sqrt128 (A10);
     379  CS.w[1] = 0;
     380  	   // check for exact result
     381  if (CS.w[0] * CS.w[0] == A10.w[0]) {
     382    __mul_64x64_to_128_fast (S2, CS.w[0], CS.w[0]);
     383    if (S2.w[1] == A10.w[1]) {
     384      get_BID128_very_fast (&res, 0,
     385  			  (exponent_x + DECIMAL_EXPONENT_BIAS_128) >> 1,
     386  			  CS);
     387  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
     388      (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
     389  #endif
     390      BID_RETURN (res);
     391    }
     392  }
     393  	   // get number of digits in CX
     394  D = CX.w[1] - power10_index_binexp_128[bin_expon_cx].w[1];
     395  if (D > 0
     396      || (!D && CX.w[0] >= power10_index_binexp_128[bin_expon_cx].w[0]))
     397    digits++;
     398  
     399  		// if exponent is odd, scale coefficient by 10
     400  scale = 67 - digits;
     401  exponent_q = exponent_x - scale;
     402  scale += (exponent_q & 1);	// exp. bias is even
     403  
     404  if (scale > 38) {
     405    T128 = power10_table_128[scale - 37];
     406    __mul_128x128_low (CX1, CX, T128);
     407  
     408    TP128 = power10_table_128[37];
     409    __mul_128x128_to_256 (C256, CX1, TP128);
     410  } else {
     411    T128 = power10_table_128[scale];
     412    __mul_128x128_to_256 (C256, CX, T128);
     413  }
     414  
     415  
     416  	   // 4*C256
     417  C4.w[3] = (C256.w[3] << 2) | (C256.w[2] >> 62);
     418  C4.w[2] = (C256.w[2] << 2) | (C256.w[1] >> 62);
     419  C4.w[1] = (C256.w[1] << 2) | (C256.w[0] >> 62);
     420  C4.w[0] = C256.w[0] << 2;
     421  
     422  long_sqrt128 (&CS, C256);
     423  
     424  #ifndef IEEE_ROUND_NEAREST
     425  #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
     426  if (!((rnd_mode) & 3)) {
     427  #endif
     428  #endif
     429    // compare to midpoints
     430    CSM.w[1] = (CS.w[1] << 1) | (CS.w[0] >> 63);
     431    CSM.w[0] = (CS.w[0] + CS.w[0]) | 1;
     432    // CSM^2
     433    //__mul_128x128_to_256(M256, CSM, CSM);
     434    __sqr128_to_256 (M256, CSM);
     435  
     436    if (C4.w[3] > M256.w[3]
     437        || (C4.w[3] == M256.w[3]
     438  	  && (C4.w[2] > M256.w[2]
     439  	      || (C4.w[2] == M256.w[2]
     440  		  && (C4.w[1] > M256.w[1]
     441  		      || (C4.w[1] == M256.w[1]
     442  			  && C4.w[0] > M256.w[0])))))) {
     443      // round up
     444      CS.w[0]++;
     445      if (!CS.w[0])
     446        CS.w[1]++;
     447    } else {
     448      C8.w[1] = (CS.w[1] << 3) | (CS.w[0] >> 61);
     449      C8.w[0] = CS.w[0] << 3;
     450      // M256 - 8*CSM
     451      __sub_borrow_out (M256.w[0], Carry, M256.w[0], C8.w[0]);
     452      __sub_borrow_in_out (M256.w[1], Carry, M256.w[1], C8.w[1], Carry);
     453      __sub_borrow_in_out (M256.w[2], Carry, M256.w[2], 0, Carry);
     454      M256.w[3] = M256.w[3] - Carry;
     455  
     456      // if CSM' > C256, round up
     457      if (M256.w[3] > C4.w[3]
     458  	|| (M256.w[3] == C4.w[3]
     459  	    && (M256.w[2] > C4.w[2]
     460  		|| (M256.w[2] == C4.w[2]
     461  		    && (M256.w[1] > C4.w[1]
     462  			|| (M256.w[1] == C4.w[1]
     463  			    && M256.w[0] > C4.w[0])))))) {
     464        // round down
     465        if (!CS.w[0])
     466  	CS.w[1]--;
     467        CS.w[0]--;
     468      }
     469    }
     470  #ifndef IEEE_ROUND_NEAREST
     471  #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
     472  } else {
     473    __sqr128_to_256 (M256, CS);
     474    C8.w[1] = (CS.w[1] << 1) | (CS.w[0] >> 63);
     475    C8.w[0] = CS.w[0] << 1;
     476    if (M256.w[3] > C256.w[3]
     477        || (M256.w[3] == C256.w[3]
     478  	  && (M256.w[2] > C256.w[2]
     479  	      || (M256.w[2] == C256.w[2]
     480  		  && (M256.w[1] > C256.w[1]
     481  		      || (M256.w[1] == C256.w[1]
     482  			  && M256.w[0] > C256.w[0])))))) {
     483      __sub_borrow_out (M256.w[0], Carry, M256.w[0], C8.w[0]);
     484      __sub_borrow_in_out (M256.w[1], Carry, M256.w[1], C8.w[1], Carry);
     485      __sub_borrow_in_out (M256.w[2], Carry, M256.w[2], 0, Carry);
     486      M256.w[3] = M256.w[3] - Carry;
     487      M256.w[0]++;
     488      if (!M256.w[0]) {
     489        M256.w[1]++;
     490        if (!M256.w[1]) {
     491  	M256.w[2]++;
     492  	if (!M256.w[2])
     493  	  M256.w[3]++;
     494        }
     495      }
     496  
     497      if (!CS.w[0])
     498        CS.w[1]--;
     499      CS.w[0]--;
     500  
     501      if (M256.w[3] > C256.w[3]
     502  	|| (M256.w[3] == C256.w[3]
     503  	    && (M256.w[2] > C256.w[2]
     504  		|| (M256.w[2] == C256.w[2]
     505  		    && (M256.w[1] > C256.w[1]
     506  			|| (M256.w[1] == C256.w[1]
     507  			    && M256.w[0] > C256.w[0])))))) {
     508  
     509        if (!CS.w[0])
     510  	CS.w[1]--;
     511        CS.w[0]--;
     512      }
     513    }
     514  
     515    else {
     516      __add_carry_out (M256.w[0], Carry, M256.w[0], C8.w[0]);
     517      __add_carry_in_out (M256.w[1], Carry, M256.w[1], C8.w[1], Carry);
     518      __add_carry_in_out (M256.w[2], Carry, M256.w[2], 0, Carry);
     519      M256.w[3] = M256.w[3] + Carry;
     520      M256.w[0]++;
     521      if (!M256.w[0]) {
     522        M256.w[1]++;
     523        if (!M256.w[1]) {
     524  	M256.w[2]++;
     525  	if (!M256.w[2])
     526  	  M256.w[3]++;
     527        }
     528      }
     529      if (M256.w[3] < C256.w[3]
     530  	|| (M256.w[3] == C256.w[3]
     531  	    && (M256.w[2] < C256.w[2]
     532  		|| (M256.w[2] == C256.w[2]
     533  		    && (M256.w[1] < C256.w[1]
     534  			|| (M256.w[1] == C256.w[1]
     535  			    && M256.w[0] <= C256.w[0])))))) {
     536  
     537        CS.w[0]++;
     538        if (!CS.w[0])
     539  	CS.w[1]++;
     540      }
     541    }
     542    // RU?
     543    if ((rnd_mode) == ROUNDING_UP) {
     544      CS.w[0]++;
     545      if (!CS.w[0])
     546        CS.w[1]++;
     547    }
     548  
     549  }
     550  #endif
     551  #endif
     552  
     553  #ifdef SET_STATUS_FLAGS
     554  __set_status_flags (pfpsf, INEXACT_EXCEPTION);
     555  #endif
     556  get_BID128_fast (&res, 0, (exponent_q + DECIMAL_EXPONENT_BIAS_128) >> 1,
     557  		 CS);
     558  #ifdef UNCHANGED_BINARY_STATUS_FLAGS
     559  (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
     560  #endif
     561  BID_RETURN (res);
     562  
     563  
     564  }