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