//===-- Bit representation of x86 long double numbers -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_UTILS_FPUTIL_LONG_DOUBLE_BITS_X86_H
#define LLVM_LIBC_UTILS_FPUTIL_LONG_DOUBLE_BITS_X86_H

#include "FPBits.h"

#include <stdint.h>

namespace __llvm_libc {
namespace fputil {

template <> struct MantissaWidth<long double> {
  static constexpr unsigned value = 63;
};

template <unsigned Width> struct Padding;

// i386 padding.
template <> struct Padding<4> { static constexpr unsigned value = 16; };

// x86_64 padding.
template <> struct Padding<8> { static constexpr unsigned value = 48; };

template <> struct __attribute__((packed)) FPBits<long double> {
  using UIntType = __uint128_t;

  static constexpr int exponentBias = 0x3FFF;
  static constexpr int maxExponent = 0x7FFF;
  static constexpr UIntType minSubnormal = UIntType(1);
  // Subnormal numbers include the implicit bit in x86 long double formats.
  static constexpr UIntType maxSubnormal =
      (UIntType(1) << (MantissaWidth<long double>::value + 1)) - 1;
  static constexpr UIntType minNormal =
      (UIntType(3) << MantissaWidth<long double>::value);
  static constexpr UIntType maxNormal =
      ((UIntType(maxExponent) - 1) << (MantissaWidth<long double>::value + 1)) |
      (UIntType(1) << MantissaWidth<long double>::value) | maxSubnormal;

  UIntType mantissa : MantissaWidth<long double>::value;
  uint8_t implicitBit : 1;
  uint16_t exponent : ExponentWidth<long double>::value;
  uint8_t sign : 1;
  uint64_t padding : Padding<sizeof(uintptr_t)>::value;

  template <typename XType,
            cpp::EnableIfType<cpp::IsSame<long double, XType>::Value, int> = 0>
  explicit FPBits<long double>(XType x) {
    *this = *reinterpret_cast<FPBits<long double> *>(&x);
  }

  operator long double() { return *reinterpret_cast<long double *>(this); }

  int getExponent() const {
    if (exponent == 0)
      return int(1) - exponentBias;
    return int(exponent) - exponentBias;
  }

  bool isZero() const {
    return exponent == 0 && mantissa == 0 && implicitBit == 0;
  }

  bool isInf() const {
    return exponent == maxExponent && mantissa == 0 && implicitBit == 1;
  }

  bool isNaN() const {
    if (exponent == maxExponent) {
      return (implicitBit == 0) || mantissa != 0;
    } else if (exponent != 0) {
      return implicitBit == 0;
    }
    return false;
  }

  bool isInfOrNaN() const {
    return (exponent == maxExponent) || (exponent != 0 && implicitBit == 0);
  }

  // Methods below this are used by tests.

  template <typename XType,
            cpp::EnableIfType<cpp::IsSame<UIntType, XType>::Value, int> = 0>
  explicit FPBits<long double>(XType x) {
    // The last 4 bytes of v are ignored in case of i386.
    *this = *reinterpret_cast<FPBits<long double> *>(&x);
  }

  UIntType bitsAsUInt() const {
    // We cannot just return the bits as is as it will lead to reading
    // out of bounds in case of i386. So, we first copy the wider value
    // before returning the value. This makes the last 4 bytes are always
    // zero in case i386.
    UIntType result = UIntType(0);
    *reinterpret_cast<FPBits<long double> *>(&result) = *this;

    // Even though we zero out |result| before copying the long double value,
    // there can be garbage bits in the padding. So, we zero the padding bits
    // in |result|.
    static constexpr UIntType mask =
        (UIntType(1) << (sizeof(long double) * 8 -
                         Padding<sizeof(uintptr_t)>::value)) -
        1;
    return result & mask;
  }

  static FPBits<long double> zero() { return FPBits<long double>(0.0l); }

  static FPBits<long double> negZero() {
    FPBits<long double> bits(0.0l);
    bits.sign = 1;
    return bits;
  }

  static FPBits<long double> inf() {
    FPBits<long double> bits(0.0l);
    bits.exponent = maxExponent;
    bits.implicitBit = 1;
    return bits;
  }

  static FPBits<long double> negInf() {
    FPBits<long double> bits(0.0l);
    bits.exponent = maxExponent;
    bits.implicitBit = 1;
    bits.sign = 1;
    return bits;
  }

  static long double buildNaN(UIntType v) {
    FPBits<long double> bits(0.0l);
    bits.exponent = maxExponent;
    bits.implicitBit = 1;
    bits.mantissa = v;
    return bits;
  }
};

static_assert(
    sizeof(FPBits<long double>) == sizeof(long double),
    "Internal long double representation does not match the machine format.");

} // namespace fputil
} // namespace __llvm_libc

#endif // LLVM_LIBC_UTILS_FPUTIL_LONG_DOUBLE_BITS_X86_H
