#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());
}
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::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);
}
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);
}