/* 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. */ #include "common/fp/info.h" #include "common/fp/process_exception.h" #include "common/fp/unpacked.h" namespace Dynarmic::FP { template std::tuple> FPUnpack(FPT op, FPCR fpcr, FPSR& fpsr) { constexpr size_t sign_bit = FPInfo::exponent_width + FPInfo::explicit_mantissa_width; constexpr size_t exponent_high_bit = FPInfo::exponent_width + FPInfo::explicit_mantissa_width - 1; constexpr size_t exponent_low_bit = FPInfo::explicit_mantissa_width; constexpr size_t mantissa_high_bit = FPInfo::explicit_mantissa_width - 1; constexpr size_t mantissa_low_bit = 0; constexpr int denormal_exponent = FPInfo::exponent_min - int(FPInfo::explicit_mantissa_width); const bool sign = Common::Bit(op); const FPT exp_raw = Common::Bits(op); const FPT frac_raw = Common::Bits(op); if (exp_raw == 0) { if (frac_raw == 0 || fpcr.FZ()) { if (frac_raw != 0) { FPProcessException(FPExc::InputDenorm, fpcr, fpsr); } return {FPType::Zero, sign, {sign, 0, 0}}; } return {FPType::Nonzero, sign, {sign, denormal_exponent, frac_raw}}; } if (exp_raw == Common::Ones(FPInfo::exponent_width)) { if (frac_raw == 0) { return {FPType::Infinity, sign, {sign, 1000000, 1}}; } const bool is_quiet = Common::Bit(frac_raw); return {is_quiet ? FPType::QNaN : FPType::SNaN, sign, {sign, 0, 0}}; } const int exp = static_cast(exp_raw) - FPInfo::exponent_bias - FPInfo::explicit_mantissa_width; const u64 frac = frac_raw | FPInfo::implicit_leading_bit; return {FPType::Nonzero, sign, {sign, exp, frac}}; } template std::tuple> FPUnpack(u32 op, FPCR fpcr, FPSR& fpsr); template std::tuple> FPUnpack(u64 op, FPCR fpcr, FPSR& fpsr); } // namespace Dynarmic::FP