(root)/
glibc-2.38/
sysdeps/
ieee754/
ldbl-128/
s_getpayloadl.c
       1  /* Get NaN payload.  ldbl-128 version.
       2     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <math.h>
      20  #include <math_private.h>
      21  #include <libm-alias-ldouble.h>
      22  #include <stdint.h>
      23  
      24  _Float128
      25  __getpayloadl (const _Float128 *x)
      26  {
      27    uint64_t hx, lx;
      28    GET_LDOUBLE_WORDS64 (hx, lx, *x);
      29    if ((hx & 0x7fff000000000000ULL) != 0x7fff000000000000ULL
      30        || ((hx & 0xffffffffffffULL) | lx) == 0)
      31      return -1;
      32    hx &= 0x7fffffffffffULL;
      33    /* Construct the representation of the return value directly, since
      34       128-bit integers may not be available.  */
      35    int lz;
      36    if (hx == 0)
      37      {
      38        if (lx == 0)
      39  	return 0.0L;
      40        else
      41  	lz = __builtin_clzll (lx) + 64;
      42      }
      43    else
      44      lz = __builtin_clzll (hx);
      45    int shift = lz - 15;
      46    if (shift >= 64)
      47      {
      48        hx = lx << (shift - 64);
      49        lx = 0;
      50      }
      51    else
      52      {
      53        /* 2 <= SHIFT <= 63.  */
      54        hx = (hx << shift) | (lx >> (64 - shift));
      55        lx <<= shift;
      56      }
      57    hx = (hx & 0xffffffffffffULL) | ((0x3fffULL + 127 - lz) << 48);
      58    _Float128 ret;
      59    SET_LDOUBLE_WORDS64 (ret, hx, lx);
      60    return ret;
      61  }
      62  libm_alias_ldouble (__getpayload, getpayload)