/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cassert>
#include <cmath>
#include <limits>

#include "support/safe_integer.h"

using namespace wasm;

bool wasm::isInteger(double x) { return trunc(x) == x && !std::isinf(x); }

bool wasm::isUInteger32(double x) {
  return !std::signbit(x) && isInteger(x) &&
         x <= std::numeric_limits<uint32_t>::max();
}

bool wasm::isSInteger32(double x) {
  return isInteger(x) && x >= std::numeric_limits<int32_t>::min() &&
         x <= std::numeric_limits<int32_t>::max();
}

uint32_t wasm::toUInteger32(double x) {
  return std::signbit(x) ? 0
                         : (x < std::numeric_limits<uint32_t>::max()
                              ? (uint32_t)x
                              : std::numeric_limits<uint32_t>::max());
}

int32_t wasm::toSInteger32(double x) {
  return (x > std::numeric_limits<int32_t>::min() &&
          x < std::numeric_limits<int32_t>::max())
           ? (int32_t)x
           : (std::signbit(x) ? std::numeric_limits<int32_t>::min()
                              : std::numeric_limits<int32_t>::max());
}

bool wasm::isUInteger64(double x) {
  return !std::signbit(x) && isInteger(x) &&
         x <= static_cast<double>(std::numeric_limits<uint64_t>::max());
}

bool wasm::isSInteger64(double x) {
  return isInteger(x) && x >= std::numeric_limits<int64_t>::min() &&
         x <= static_cast<double>(std::numeric_limits<int64_t>::max());
}

uint64_t wasm::toUInteger64(double x) {
  return std::signbit(x) ? 0
                         : (x < (double)std::numeric_limits<uint64_t>::max()
                              ? (uint64_t)x
                              : std::numeric_limits<uint64_t>::max());
}

int64_t wasm::toSInteger64(double x) {
  return (x > (double)std::numeric_limits<int64_t>::min() &&
          x < (double)std::numeric_limits<int64_t>::max())
           ? (int64_t)x
           : (std::signbit(x) ? std::numeric_limits<int64_t>::min()
                              : std::numeric_limits<int64_t>::max());
}

/* 3 32222222 222...00
 * 1 09876543 210...10
 * -------------------
 * 0 00000000 000...00 => 0x00000000 => 0
 * 0 10011101 111...11 => 0x4effffff => 2147483520                  (~INT32_MAX)
 * 0 10011110 000...00 => 0x4f000000 => 2147483648
 * 0 10011110 111...11 => 0x4f7fffff => 4294967040                 (~UINT32_MAX)
 * 0 10111110 111...11 => 0x5effffff => 9223371487098961920         (~INT64_MAX)
 * 0 10111110 000...00 => 0x5f000000 => 9223372036854775808
 * 0 10111111 111...11 => 0x5f7fffff => 18446742974197923840       (~UINT64_MAX)
 * 0 10111111 000...00 => 0x5f800000 => 18446744073709551616
 * 0 11111111 000...00 => 0x7f800000 => inf
 * 0 11111111 000...01 => 0x7f800001 => nan(0x1)
 * 0 11111111 111...11 => 0x7fffffff => nan(0x7fffff)
 * 1 00000000 000...00 => 0x80000000 => -0
 * 1 01111110 111...11 => 0xbf7fffff => -1 + ulp      (~UINT32_MIN, ~UINT64_MIN)
 * 1 01111111 000...00 => 0xbf800000 => -1
 * 1 10011110 000...00 => 0xcf000000 => -2147483648                  (INT32_MIN)
 * 1 10111110 000...00 => 0xdf000000 => -9223372036854775808         (INT64_MIN)
 * 1 11111111 000...00 => 0xff800000 => -inf
 * 1 11111111 000...01 => 0xff800001 => -nan(0x1)
 * 1 11111111 111...11 => 0xffffffff => -nan(0x7fffff)
 */

bool wasm::isInRangeI16TruncS(int32_t i) {
  uint32_t u = i;
  return (u < 0x47000000U) || (u >= 0x80000000U && u <= 0xc7000000U);
}

bool wasm::isInRangeI32TruncS(int32_t i) {
  uint32_t u = i;
  return (u < 0x4f000000U) || (u >= 0x80000000U && u <= 0xcf000000U);
}

bool wasm::isInRangeI64TruncS(int32_t i) {
  uint32_t u = i;
  return (u < 0x5f000000U) || (u >= 0x80000000U && u <= 0xdf000000U);
}

bool wasm::isInRangeI16TruncU(int32_t i) {
  uint32_t u = i;
  return (u < 0x47800000) || (u >= 0x80000000U && u < 0xbf800000U);
}

bool wasm::isInRangeI32TruncU(int32_t i) {
  uint32_t u = i;
  return (u < 0x4f800000U) || (u >= 0x80000000U && u < 0xbf800000U);
}

bool wasm::isInRangeI64TruncU(int32_t i) {
  uint32_t u = i;
  return (u < 0x5f800000U) || (u >= 0x80000000U && u < 0xbf800000U);
}

/* clang-format off */
/*
 * 6 66655555555 5544...222221...000
 * 3 21098765432 1098...432109...210
 * ---------------------------------
 * 0 00000000000 0000...000000...000 0x0000000000000000 => 0
 * 0 10000011101 1111...111000...111 0x41dfffffffffffff => 2147483647.9999998     (rounds down to INT32_MAX)
 * 0 10000011110 1111...111111...111 0x41efffffffffffff => 4294967295.9999995     (rounds down to UINT32_MAX)
 * 0 10000111101 1111...111111...111 0x43dfffffffffffff => 9223372036854774784     (~INT64_MAX)
 * 0 10000111110 0000...000000...000 0x43e0000000000000 => 9223372036854775808
 * 0 10000111110 1111...111111...111 0x43efffffffffffff => 18446744073709549568   (~UINT64_MAX)
 * 0 10000111111 0000...000000...000 0x43f0000000000000 => 18446744073709551616
 * 0 11111111111 0000...000000...000 0x7ff0000000000000 => inf
 * 0 11111111111 0000...000000...001 0x7ff0000000000001 => nan(0x1)
 * 0 11111111111 1111...111111...111 0x7fffffffffffffff => nan(0xfff...)
 * 1 00000000000 0000...000000...000 0x8000000000000000 => -0
 * 1 01111111110 1111...111111...111 0xbfefffffffffffff => -1 + ulp  (~UINT32_MIN, ~UINT64_MIN)
 * 1 01111111111 0000...000000...000 0xbff0000000000000 => -1
 * 1 10000011110 0000...000000...111 0xc1e00000001fffff => -2147483648.9999995    (rounds up to INT32_MIN)
 * 1 10000111110 0000...000000...000 0xc3e0000000000000 => -9223372036854775808     (INT64_MIN)
 * 1 11111111111 0000...000000...000 0xfff0000000000000 => -inf
 * 1 11111111111 0000...000000...001 0xfff0000000000001 => -nan(0x1)
 * 1 11111111111 1111...111111...111 0xffffffffffffffff => -nan(0xfff...)
 */
/* clang-format on */

bool wasm::isInRangeI32TruncS(int64_t i) {
  uint64_t u = i;
  return (u <= 0x41dfffffffffffffULL) ||
         (u >= 0x8000000000000000ULL && u <= 0xc1e00000001fffffULL);
}

bool wasm::isInRangeI32TruncU(int64_t i) {
  uint64_t u = i;
  return (u <= 0x41efffffffffffffULL) ||
         (u >= 0x8000000000000000ULL && u <= 0xbfefffffffffffffULL);
}

bool wasm::isInRangeI64TruncS(int64_t i) {
  uint64_t u = i;
  return (u < 0x43e0000000000000ULL) ||
         (u >= 0x8000000000000000ULL && u <= 0xc3e0000000000000ULL);
}

bool wasm::isInRangeI64TruncU(int64_t i) {
  uint64_t u = i;
  return (u < 0x43f0000000000000ULL) ||
         (u >= 0x8000000000000000ULL && u <= 0xbfefffffffffffffULL);
}
