1 /* This file is part of the dynarmic project. 2 * Copyright (c) 2018 MerryMage 3 * SPDX-License-Identifier: 0BSD 4 */ 5 6 #pragma once 7 8 #include "common/bit_util.h" 9 #include "common/common_types.h" 10 11 namespace Dynarmic::FP { 12 13 /** 14 * Representation of the Floating-Point Status Register. 15 */ 16 class FPSR final { 17 public: 18 FPSR() = default; 19 FPSR(const FPSR&) = default; 20 FPSR(FPSR&&) = default; FPSR(u32 data)21 explicit FPSR(u32 data) : value{data & mask} {} 22 23 FPSR& operator=(const FPSR&) = default; 24 FPSR& operator=(FPSR&&) = default; 25 FPSR& operator=(u32 data) { 26 value = data & mask; 27 return *this; 28 } 29 30 /// Get negative condition flag N()31 bool N() const { 32 return Common::Bit<31>(value); 33 } 34 35 /// Set negative condition flag N(bool N_)36 void N(bool N_) { 37 value = Common::ModifyBit<31>(value, N_); 38 } 39 40 /// Get zero condition flag Z()41 bool Z() const { 42 return Common::Bit<30>(value); 43 } 44 45 /// Set zero condition flag Z(bool Z_)46 void Z(bool Z_) { 47 value = Common::ModifyBit<30>(value, Z_); 48 } 49 50 /// Get carry condition flag C()51 bool C() const { 52 return Common::Bit<29>(value); 53 } 54 55 /// Set carry condition flag C(bool C_)56 void C(bool C_) { 57 value = Common::ModifyBit<29>(value, C_); 58 } 59 60 /// Get overflow condition flag V()61 bool V() const { 62 return Common::Bit<28>(value); 63 } 64 65 /// Set overflow condition flag V(bool V_)66 void V(bool V_) { 67 value = Common::ModifyBit<28>(value, V_); 68 } 69 70 /// Get cumulative saturation bit QC()71 bool QC() const { 72 return Common::Bit<27>(value); 73 } 74 75 /// Set cumulative saturation bit QC(bool QC_)76 void QC(bool QC_) { 77 value = Common::ModifyBit<27>(value, QC_); 78 } 79 80 /// Get input denormal floating-point exception bit IDC()81 bool IDC() const { 82 return Common::Bit<7>(value); 83 } 84 85 /// Set input denormal floating-point exception bit IDC(bool IDC_)86 void IDC(bool IDC_) { 87 value = Common::ModifyBit<7>(value, IDC_); 88 } 89 90 /// Get inexact cumulative floating-point exception bit IXC()91 bool IXC() const { 92 return Common::Bit<4>(value); 93 } 94 95 /// Set inexact cumulative floating-point exception bit IXC(bool IXC_)96 void IXC(bool IXC_) { 97 value = Common::ModifyBit<4>(value, IXC_); 98 } 99 100 /// Get underflow cumulative floating-point exception bit UFC()101 bool UFC() const { 102 return Common::Bit<3>(value); 103 } 104 105 /// Set underflow cumulative floating-point exception bit UFC(bool UFC_)106 void UFC(bool UFC_) { 107 value = Common::ModifyBit<3>(value, UFC_); 108 } 109 110 /// Get overflow cumulative floating-point exception bit OFC()111 bool OFC() const { 112 return Common::Bit<2>(value); 113 } 114 115 /// Set overflow cumulative floating-point exception bit OFC(bool OFC_)116 void OFC(bool OFC_) { 117 value = Common::ModifyBit<2>(value, OFC_); 118 } 119 120 /// Get divide by zero cumulative floating-point exception bit DZC()121 bool DZC() const { 122 return Common::Bit<1>(value); 123 } 124 125 /// Set divide by zero cumulative floating-point exception bit DZC(bool DZC_)126 void DZC(bool DZC_) { 127 value = Common::ModifyBit<1>(value, DZC_); 128 } 129 130 /// Get invalid operation cumulative floating-point exception bit IOC()131 bool IOC() const { 132 return Common::Bit<0>(value); 133 } 134 135 /// Set invalid operation cumulative floating-point exception bit IOC(bool IOC_)136 void IOC(bool IOC_) { 137 value = Common::ModifyBit<0>(value, IOC_); 138 } 139 140 /// Gets the underlying raw value within the FPSR. Value()141 u32 Value() const { 142 return value; 143 } 144 145 private: 146 // Bits 5-6 and 8-26 are reserved. 147 static constexpr u32 mask = 0xF800009F; 148 u32 value = 0; 149 }; 150 151 inline bool operator==(FPSR lhs, FPSR rhs) { 152 return lhs.Value() == rhs.Value(); 153 } 154 155 inline bool operator!=(FPSR lhs, FPSR rhs) { 156 return !operator==(lhs, rhs); 157 } 158 159 } // namespace Dynarmic::FP 160