fp: Add FPSR

This commit is contained in:
MerryMage 2018-06-26 20:51:25 +01:00
parent 66381352f3
commit c41a38b13e
2 changed files with 163 additions and 0 deletions

View file

@ -17,6 +17,7 @@ add_library(dynarmic
common/crc32.cpp common/crc32.cpp
common/crc32.h common/crc32.h
common/fp_util.h common/fp_util.h
common/fp/fpsr.h
common/fp/info.h common/fp/info.h
common/fp/rounding_mode.h common/fp/rounding_mode.h
common/intrusive_list.h common/intrusive_list.h

162
src/common/fp/fpsr.h Normal file
View file

@ -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 <boost/optional.hpp>
#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