diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f3c59dfa..30028224 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,6 +17,7 @@ add_library(dynarmic common/crc32.cpp common/crc32.h common/fp_util.h + common/fp/fpsr.h common/fp/info.h common/fp/rounding_mode.h common/intrusive_list.h diff --git a/src/common/fp/fpsr.h b/src/common/fp/fpsr.h new file mode 100644 index 00000000..3b8ae7e0 --- /dev/null +++ b/src/common/fp/fpsr.h @@ -0,0 +1,162 @@ +/* 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/bit_util.h" +#include "common/common_types.h" + +namespace Dynarmic::FP { + +/** + * Representation of the Floating-Point Status Register. + */ +class FPSR final { +public: + FPSR() = default; + FPSR(const FPSR&) = default; + FPSR(FPSR&&) = default; + explicit FPSR(u32 data) : value{data & mask} {} + + FPSR& operator=(const FPSR&) = default; + FPSR& operator=(FPSR&&) = default; + FPSR& operator=(u32 data) { + value = data & mask; + return *this; + } + + /// Get negative condition flag + bool N() const { + return Common::Bit<31>(value); + } + + /// Set negative condition flag + void N(bool N_) { + value = Common::ModifyBit<31>(value, N_); + } + + /// Get zero condition flag + bool Z() const { + return Common::Bit<30>(value); + } + + /// Set zero condition flag + void Z(bool Z_) { + value = Common::ModifyBit<30>(value, Z_); + } + + /// Get carry condition flag + bool C() const { + return Common::Bit<29>(value); + } + + /// Set carry condition flag + void C(bool C_) { + value = Common::ModifyBit<29>(value, C_); + } + + /// Get overflow condition flag + bool V() const { + return Common::Bit<28>(value); + } + + /// Set overflow condition flag + void V(bool V_) { + value = Common::ModifyBit<28>(value, V_); + } + + /// Get cumulative saturation bit + bool QC() const { + return Common::Bit<27>(value); + } + + /// Set cumulative saturation bit + void QC(bool QC_) { + value = Common::ModifyBit<27>(value, QC_); + } + + /// Get input denormal floating-point exception bit + bool IDC() const { + return Common::Bit<7>(value); + } + + /// Set input denormal floating-point exception bit + void IDC(bool IDC_) { + value = Common::ModifyBit<7>(value, IDC_); + } + + /// Get inexact cumulative floating-point exception bit + bool IXC() const { + return Common::Bit<4>(value); + } + + /// Set inexact cumulative floating-point exception bit + void IXC(bool IXC_) { + value = Common::ModifyBit<4>(value, IXC_); + } + + /// Get underflow cumulative floating-point exception bit + bool UFC() const { + return Common::Bit<3>(value); + } + + /// Set underflow cumulative floating-point exception bit + void UFC(bool UFC_) { + value = Common::ModifyBit<3>(value, UFC_); + } + + /// Get overflow cumulative floating-point exception bit + bool OFC() const { + return Common::Bit<2>(value); + } + + /// Set overflow cumulative floating-point exception bit + void OFC(bool OFC_) { + value = Common::ModifyBit<2>(value, OFC_); + } + + /// Get divide by zero cumulative floating-point exception bit + bool DZC() const { + return Common::Bit<1>(value); + } + + /// Set divide by zero cumulative floating-point exception bit + void DZC(bool DZC_) { + value = Common::ModifyBit<1>(value, DZC_); + } + + /// Get invalid operation cumulative floating-point exception bit + bool IOC() const { + return Common::Bit<0>(value); + } + + /// Set invalid operation cumulative floating-point exception bit + void IOC(bool IOC_) { + value = Common::ModifyBit<0>(value, IOC_); + } + + /// Gets the underlying raw value within the FPSR. + u32 Value() const { + return value; + } + +private: + // Bits 5-6 and 8-26 are reserved. + static constexpr u32 mask = 0xF800009F; + u32 value = 0; +}; + +inline bool operator==(FPSR lhs, FPSR rhs) { + return lhs.Value() == rhs.Value(); +} + +inline bool operator!=(FPSR lhs, FPSR rhs) { + return !operator==(lhs, rhs); +} + +} // namespace Dynarmic::FP