mirror of
https://github.com/azahar-emu/dynarmic
synced 2025-11-08 16:10:05 +01:00
Removes unnecessary header dependencies that have accumulated over time as changes have been made. Lessens the amount of files that need to be rebuilt when the headers change.
101 lines
2.9 KiB
C++
101 lines
2.9 KiB
C++
/* 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 <optional>
|
|
|
|
#include "common/fp/fpcr.h"
|
|
#include "common/fp/info.h"
|
|
|
|
namespace Dynarmic::FP {
|
|
|
|
/// Is floating point value a zero?
|
|
template<typename FPT>
|
|
inline bool IsZero(FPT value, FPCR fpcr) {
|
|
if (fpcr.FZ()) {
|
|
return (value & FPInfo<FPT>::exponent_mask) == 0;
|
|
}
|
|
return (value & ~FPInfo<FPT>::sign_mask) == 0;
|
|
}
|
|
|
|
/// Is floating point value an infinity?
|
|
template<typename FPT>
|
|
constexpr bool IsInf(FPT value) {
|
|
return (value & ~FPInfo<FPT>::sign_mask) == FPInfo<FPT>::Infinity(false);
|
|
}
|
|
|
|
/// Is floating point value a QNaN?
|
|
template<typename FPT>
|
|
constexpr bool IsQNaN(FPT value) {
|
|
constexpr FPT qnan_bits = FPInfo<FPT>::exponent_mask | FPInfo<FPT>::mantissa_msb;
|
|
return (value & qnan_bits) == qnan_bits;
|
|
}
|
|
|
|
/// Is floating point value a SNaN?
|
|
template<typename FPT>
|
|
constexpr bool IsSNaN(FPT value) {
|
|
constexpr FPT qnan_bits = FPInfo<FPT>::exponent_mask | FPInfo<FPT>::mantissa_msb;
|
|
constexpr FPT snan_bits = FPInfo<FPT>::exponent_mask;
|
|
return (value & qnan_bits) == snan_bits && (value & FPInfo<FPT>::mantissa_mask) != 0;
|
|
}
|
|
|
|
/// Is floating point value a NaN?
|
|
template<typename FPT>
|
|
constexpr bool IsNaN(FPT value) {
|
|
return IsQNaN(value) || IsSNaN(value);
|
|
}
|
|
|
|
/// Given a single argument, return the NaN value which would be returned by an ARM processor.
|
|
/// If the argument isn't a NaN, returns std::nullopt.
|
|
template<typename FPT>
|
|
constexpr std::optional<FPT> ProcessNaNs(FPT a) {
|
|
if (IsSNaN(a)) {
|
|
return a | FPInfo<FPT>::mantissa_msb;
|
|
} else if (IsQNaN(a)) {
|
|
return a;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
/// Given a pair of arguments, return the NaN value which would be returned by an ARM processor.
|
|
/// If neither argument is a NaN, returns std::nullopt.
|
|
template<typename FPT>
|
|
constexpr std::optional<FPT> ProcessNaNs(FPT a, FPT b) {
|
|
if (IsSNaN(a)) {
|
|
return a | FPInfo<FPT>::mantissa_msb;
|
|
} else if (IsSNaN(b)) {
|
|
return b | FPInfo<FPT>::mantissa_msb;
|
|
} else if (IsQNaN(a)) {
|
|
return a;
|
|
} else if (IsQNaN(b)) {
|
|
return b;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
/// Given three arguments, return the NaN value which would be returned by an ARM processor.
|
|
/// If none of the arguments is a NaN, returns std::nullopt.
|
|
template<typename FPT>
|
|
constexpr std::optional<FPT> ProcessNaNs(FPT a, FPT b, FPT c) {
|
|
if (IsSNaN(a)) {
|
|
return a | FPInfo<FPT>::mantissa_msb;
|
|
} else if (IsSNaN(b)) {
|
|
return b | FPInfo<FPT>::mantissa_msb;
|
|
} else if (IsSNaN(c)) {
|
|
return c | FPInfo<FPT>::mantissa_msb;
|
|
} else if (IsQNaN(a)) {
|
|
return a;
|
|
} else if (IsQNaN(b)) {
|
|
return b;
|
|
} else if (IsQNaN(c)) {
|
|
return c;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
} // namespace Dynarmic::FP
|