kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

fp_fixint_impl.inc (2250B)


      1 //===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file implements float to integer conversion for the
     10 // compiler-rt library.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "fp_lib.h"
     15 
     16 #ifndef FP_FIX_SUFFIX
     17 #error "fp_fixint_impl.inc: FP_FIX_SUFFIX must be defined before #include"
     18 #endif
     19 
     20 #ifndef FP_FIX_IMPL_PASTE_
     21 #define FP_FIX_IMPL_PASTE_(a, b) a##_##b
     22 #define FP_FIX_IMPL_PASTE(a, b)  FP_FIX_IMPL_PASTE_(a, b)
     23 #endif
     24 
     25 #ifdef __fixint
     26 #undef __fixint
     27 #endif
     28 #define __fixint FP_FIX_IMPL_PASTE(__fixint, FP_FIX_SUFFIX)
     29 
     30 static inline fixint_t __fixint(fp_t a) {
     31   const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2);
     32   const fixint_t fixint_min = -fixint_max - 1;
     33   // Break a into sign, exponent, significand parts.
     34   const rep_t aRep = toRep(a);
     35   const rep_t aAbs = aRep & absMask;
     36   const fixint_t sign = aRep & signBit ? -1 : 1;
     37   const int exponent = (aAbs >> significandBits) - exponentBias;
     38   const rep_t significand = (aAbs & significandMask) | implicitBit;
     39 
     40   // If exponent is negative, the result is zero.
     41   if (exponent < 0)
     42     return 0;
     43 
     44   // If the value is too large for the integer type, saturate.
     45   if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT)
     46     return sign == 1 ? fixint_max : fixint_min;
     47 
     48   // If 0 <= exponent < significandBits, right shift to get the result.
     49   // Otherwise, shift left.
     50   if (exponent < significandBits)
     51     return sign * (significand >> (significandBits - exponent));
     52   else
     53     return sign * ((fixuint_t)significand << (exponent - significandBits));
     54 }
     55 
     56 // FP_FIX_SUFFIX, fixint_t, fixuint_t intentionally left defined: the
     57 // caller's `return __fixint(a);` line is parsed AFTER this include, and
     58 // the `__fixint` macro re-expands FP_FIX_SUFFIX at that point. The
     59 // caller (per-op .c) is responsible for #undef'ing them at its bottom
     60 // so consolidated builds can stack multiple per-op snippets in one TU.