ChampSim
fwcounter.h
Go to the documentation of this file.
1 /*
2  * Copyright 2023 The ChampSim Contributors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef FWCOUNTER_HPP
18 #define FWCOUNTER_HPP
19 
20 #include <algorithm>
21 #include <cstdlib>
22 
23 namespace champsim::msl
24 {
25 template <typename val_type, val_type MAXVAL, val_type MINVAL>
27 {
28 protected:
29  val_type _value{};
30 
31  static val_type clamp(val_type val) { return std::clamp(val, MINVAL, MAXVAL); }
32 
33 public:
34  constexpr static val_type minimum = MINVAL;
35  constexpr static val_type maximum = MAXVAL;
36 
38  explicit base_fwcounter(val_type value) : _value(std::move(value)) {}
39 
40  template <typename Numeric>
42 
47 
52 
53  template <typename Numeric>
55 
56  template <typename Numeric>
58 
59  template <typename Numeric>
61 
62  template <typename Numeric>
64 
65  bool is_max() const { return _value == maximum; }
66  bool is_min() const { return _value == minimum; }
67 
68  // operator val_type const ();
69  val_type value() const { return _value; }
70 };
71 
72 /*
73  * Unsigned template specialization
74  */
75 template <std::size_t WIDTH>
76 using fwcounter = base_fwcounter<signed long long int, (1 << WIDTH) - 1, 0>;
77 
78 /*
79  * Signed template specialization
80  */
81 template <std::size_t WIDTH>
82 using sfwcounter = base_fwcounter<signed long long int, (1 << (WIDTH - 1)) - 1, -(1 << (WIDTH - 1))>;
83 
84 /*
85  * Fundamental operations
86  */
87 template <typename val_type, val_type MAXVAL, val_type MINVAL>
88 template <typename Numeric>
90 {
91  _value = clamp(rhs);
92  return *this;
93 }
94 
95 template <typename val_type, val_type MAXVAL, val_type MINVAL>
96 template <typename Numeric>
98 {
99  _value = clamp(_value + rhs);
100  return *this;
101 }
102 
103 template <typename val_type, val_type MAXVAL, val_type MINVAL>
104 template <typename Numeric>
106 {
107  _value = clamp(_value - rhs);
108  return *this;
109 }
110 
111 template <typename val_type, val_type MAXVAL, val_type MINVAL>
112 template <typename Numeric>
114 {
115  _value = clamp(_value * rhs);
116  return *this;
117 }
118 
119 template <typename val_type, val_type MAXVAL, val_type MINVAL>
120 template <typename Numeric>
122 {
123  _value = clamp(_value / rhs);
124  return *this;
125 }
126 
127 /*
128  * Prefix unary operators forward to the binary assignment operator with value one
129  */
130 
131 template <typename val_type, val_type MAXVAL, val_type MINVAL>
133 {
134  return (*this += 1);
135 }
136 
137 template <typename val_type, val_type MAXVAL, val_type MINVAL>
139 {
140  return (*this += 1);
141 }
142 
143 /*
144  * Postfix unary operators forwward to the prefix unary operator of the same type
145  */
146 template <typename val_type, val_type MAXVAL, val_type MINVAL>
148 {
150  operator++();
151  return result;
152 }
153 
154 template <typename val_type, val_type MAXVAL, val_type MINVAL>
156 {
158  operator--();
159  return result;
160 }
161 
162 /*
163  * Binary arithmetic operators forward to the assignment operators of the same type
164  */
165 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
167 {
168  lhs += rhs;
169  return lhs;
170 }
171 
172 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
174 {
175  lhs -= rhs;
176  return lhs;
177 }
178 
179 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
181 {
182  lhs *= rhs;
183  return lhs;
184 }
185 
186 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
188 {
189  lhs /= rhs;
190  return lhs;
191 }
192 
193 /*
194  * Base comparators
195  */
196 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
197 bool operator<(const base_fwcounter<vt, mxvl, mnvl>& lhs, Numeric rhs)
198 {
199  return lhs.value() < rhs;
200 }
201 
202 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
203 bool operator==(const base_fwcounter<vt, mxvl, mnvl>& lhs, Numeric rhs)
204 {
205  return lhs.value() == rhs;
206 }
207 
208 /*
209  * Other comparators forward to the bases
210  */
211 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
212 bool operator>(const base_fwcounter<vt, mxvl, mnvl>& lhs, Numeric rhs)
213 {
214  return !(lhs == rhs || lhs < rhs);
215 }
216 
217 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
218 bool operator>=(const base_fwcounter<vt, mxvl, mnvl>& lhs, Numeric rhs)
219 {
220  return !(lhs < rhs);
221 }
222 
223 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
224 bool operator<=(const base_fwcounter<vt, mxvl, mnvl>& lhs, Numeric rhs)
225 {
226  return !(lhs > rhs);
227 }
228 
229 template <typename vt, vt mxvl, vt mnvl, typename Numeric>
230 bool operator!=(const base_fwcounter<vt, mxvl, mnvl>& lhs, Numeric rhs)
231 {
232  return !(lhs == rhs);
233 }
234 
235 /*
236  * Arithmentic operators for two fwcounters forward to the value operators
237  */
238 
239 template <typename val_type, val_type MAXVAL, val_type MINVAL>
241 {
242  return (*this += rhs._value);
243 }
244 
245 template <typename val_type, val_type MAXVAL, val_type MINVAL>
247 {
248  return (*this -= rhs._value);
249 }
250 
251 template <typename vt, vt mxvl, vt mnvl>
253 {
254  return lhs + rhs.value();
255 }
256 
257 template <typename vt, vt mxvl, vt mnvl>
259 {
260  return lhs - rhs.value();
261 }
262 
263 /*
264  * Comparison operators for two fwcounters forward to the value comparators
265  */
266 template <typename vt, vt mxvl, vt mnvl>
268 {
269  return lhs < rhs.value();
270 }
271 
272 template <typename vt, vt mxvl, vt mnvl>
274 {
275  return lhs > rhs.value();
276 }
277 
278 template <typename vt, vt mxvl, vt mnvl>
280 {
281  return lhs <= rhs.value();
282 }
283 
284 template <typename vt, vt mxvl, vt mnvl>
286 {
287  return lhs >= rhs.value();
288 }
289 
290 template <typename vt, vt mxvl, vt mnvl>
292 {
293  return lhs == rhs.value();
294 }
295 
296 template <typename vt, vt mxvl, vt mnvl>
298 {
299  return lhs != rhs.value();
300 }
301 } // namespace champsim::msl
302 
303 #endif
Definition: fwcounter.h:27
base_fwcounter< val_type, MAXVAL, MINVAL > & operator*=(base_fwcounter< val_type, MAXVAL, MINVAL >)
base_fwcounter()
Definition: fwcounter.h:37
base_fwcounter< val_type, MAXVAL, MINVAL > & operator--()
Definition: fwcounter.h:138
base_fwcounter< val_type, MAXVAL, MINVAL > & operator+=(base_fwcounter< val_type, MAXVAL, MINVAL >)
Definition: fwcounter.h:240
base_fwcounter< val_type, MAXVAL, MINVAL > & operator=(Numeric)
Definition: fwcounter.h:89
base_fwcounter< val_type, MAXVAL, MINVAL > & operator++()
Definition: fwcounter.h:132
static val_type clamp(val_type val)
Definition: fwcounter.h:31
base_fwcounter< val_type, MAXVAL, MINVAL > & operator/=(base_fwcounter< val_type, MAXVAL, MINVAL >)
val_type _value
Definition: fwcounter.h:29
val_type value() const
Definition: fwcounter.h:69
constexpr static val_type maximum
Definition: fwcounter.h:35
bool is_max() const
Definition: fwcounter.h:65
constexpr static val_type minimum
Definition: fwcounter.h:34
base_fwcounter< val_type, MAXVAL, MINVAL > & operator-=(base_fwcounter< val_type, MAXVAL, MINVAL >)
Definition: fwcounter.h:246
bool is_min() const
Definition: fwcounter.h:66
base_fwcounter(val_type value)
Definition: fwcounter.h:38
Definition: bits.h:24
bool operator>(const base_fwcounter< vt, mxvl, mnvl > &lhs, Numeric rhs)
Definition: fwcounter.h:212
bool operator>=(const base_fwcounter< vt, mxvl, mnvl > &lhs, Numeric rhs)
Definition: fwcounter.h:218
bool operator!=(const base_fwcounter< vt, mxvl, mnvl > &lhs, Numeric rhs)
Definition: fwcounter.h:230
base_fwcounter< vt, mxvl, mnvl > operator*(base_fwcounter< vt, mxvl, mnvl > lhs, Numeric rhs)
Definition: fwcounter.h:180
bool operator<(const base_fwcounter< vt, mxvl, mnvl > &lhs, Numeric rhs)
Definition: fwcounter.h:197
base_fwcounter< vt, mxvl, mnvl > operator/(base_fwcounter< vt, mxvl, mnvl > lhs, Numeric rhs)
Definition: fwcounter.h:187
bool operator<=(const base_fwcounter< vt, mxvl, mnvl > &lhs, Numeric rhs)
Definition: fwcounter.h:224
base_fwcounter< vt, mxvl, mnvl > operator+(base_fwcounter< vt, mxvl, mnvl > lhs, Numeric rhs)
Definition: fwcounter.h:166
bool operator==(const base_fwcounter< vt, mxvl, mnvl > &lhs, Numeric rhs)
Definition: fwcounter.h:203
base_fwcounter< vt, mxvl, mnvl > operator-(base_fwcounter< vt, mxvl, mnvl > lhs, Numeric rhs)
Definition: fwcounter.h:173