brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 51f76fd Raw
73 lines · plain
1//===-- int_to_fp_impl.inc - integer to floating point conversion ---------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// Thsi file implements a generic conversion from an integer type to an10// IEEE-754 floating point type, allowing a common implementation to be hsared11// without copy and paste.12//13//===----------------------------------------------------------------------===//14 15#include "int_to_fp.h"16 17static __inline dst_t __floatXiYf__(src_t a) {18  if (a == 0)19    return 0.0;20 21  enum {22    dstMantDig = dstSigBits + 1,23    srcBits = sizeof(src_t) * CHAR_BIT,24    srcIsSigned = ((src_t)-1) < 0,25  };26 27  const src_t s = srcIsSigned ? a >> (srcBits - 1) : 0;28 29  a = (usrc_t)(a ^ s) - s;30  int sd = srcBits - clzSrcT(a);         // number of significant digits31  int e = sd - 1;                        // exponent32  if (sd > dstMantDig) {33    //  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx34    //  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR35    //                                                1234567890123456789012345636    //  1 = msb 1 bit37    //  P = bit dstMantDig-1 bits to the right of 138    //  Q = bit dstMantDig bits to the right of 139    //  R = "or" of all bits to the right of Q40    if (sd == dstMantDig + 1) {41      a <<= 1;42    } else if (sd == dstMantDig + 2) {43      // Do nothing.44    } else {45      a = ((usrc_t)a >> (sd - (dstMantDig + 2))) |46          ((a & ((usrc_t)(-1) >> ((srcBits + dstMantDig + 2) - sd))) != 0);47    }48    // finish:49    a |= (a & 4) != 0; // Or P into R50    ++a;               // round - this step may add a significant bit51    a >>= 2;           // dump Q and R52    // a is now rounded to dstMantDig or dstMantDig+1 bits53    if (a & ((usrc_t)1 << dstMantDig)) {54      a >>= 1;55      ++e;56    }57    // a is now rounded to dstMantDig bits58  } else {59    a <<= (dstMantDig - sd);60    // a is now rounded to dstMantDig bits61  }62  const int dstBits = sizeof(dst_t) * CHAR_BIT;63  const dst_rep_t dstSignMask = DST_REP_C(1) << (dstBits - 1);64  const int dstExpBits = dstBits - dstSigBits - 1;65  const int dstExpBias = (1 << (dstExpBits - 1)) - 1;66  const dst_rep_t dstSignificandMask = (DST_REP_C(1) << dstSigBits) - 1;67  // Combine sign, exponent, and mantissa.68  const dst_rep_t result = ((dst_rep_t)s & dstSignMask) |69                           ((dst_rep_t)(e + dstExpBias) << dstSigBits) |70                           ((dst_rep_t)(a) & dstSignificandMask);71  return dstFromRep(result);72}73