/* This file is part of the dynarmic project. * Copyright (c) 2018 MerryMage * This software may be used and distributed according to the terms of the GNU * General Public License version 2 or any later version. */ #pragma once #include #include "common/common_types.h" #include "common/fp/fpcr.h" namespace Dynarmic::FP { class FPSR; enum class RoundingMode; enum class FPType { Nonzero, Zero, Infinity, QNaN, SNaN, }; constexpr size_t normalized_point_position = 62; /// value = (sign ? -1 : +1) * mantissa/(2^62) * 2^exponent /// 63rd bit of mantissa is always set (unless value is zero) struct FPUnpacked { bool sign; int exponent; u64 mantissa; }; inline bool operator==(const FPUnpacked& a, const FPUnpacked& b) { return std::tie(a.sign, a.exponent, a.mantissa) == std::tie(b.sign, b.exponent, b.mantissa); } /// return value = (sign ? -1 : +1) * value * 2^exponent constexpr FPUnpacked ToNormalized(bool sign, int exponent, u64 value) { if (value == 0) { return {sign, 0, 0}; } const int highest_bit = Common::HighestSetBit(value); const int offset = static_cast(normalized_point_position) - highest_bit; value <<= offset; exponent -= offset - normalized_point_position; return {sign, exponent, value}; } template std::tuple FPUnpackBase(FPT op, FPCR fpcr, FPSR& fpsr); template std::tuple FPUnpack(FPT op, FPCR fpcr, FPSR& fpsr) { fpcr.AHP(false); return FPUnpackBase(op, fpcr, fpsr); } template std::tuple FPUnpackCV(FPT op, FPCR fpcr, FPSR& fpsr) { fpcr.FZ16(false); return FPUnpackBase(op, fpcr, fpsr); } template FPT FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr); template FPT FPRound(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr) { fpcr.AHP(false); return FPRoundBase(op, fpcr, rounding, fpsr); } template FPT FPRoundCV(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr) { fpcr.FZ16(false); return FPRoundBase(op, fpcr, rounding, fpsr); } template FPT FPRound(FPUnpacked op, FPCR fpcr, FPSR& fpsr) { return FPRound(op, fpcr, fpcr.RMode(), fpsr); } } // namespace Dynarmic::FP