blob: 02c9b1d00c65716de2fd1ed5a3cc1bd46f083804 [file] [log] [blame]
Zane Shelley871adec2019-07-30 11:01:39 -05001#pragma once
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -05002
Zane Shelley52cb1a92019-08-21 14:38:31 -05003#include <register/hei_register.hpp>
4
Zane Shelley871adec2019-07-30 11:01:39 -05005namespace libhei
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -05006{
7
Zane Shelleyb0559b92019-12-05 22:18:20 -06008/**
9 * @brief An abstract class for all operator registers.
10 *
11 * Contains member functions and variables that are required for all child
12 * classes.
13 */
14class OperatorRegister : public Register
15{
16 public:
17 /** @brief Pure virtual destructor. */
18 virtual ~OperatorRegister() = 0;
19
20 protected:
21 /**
22 * @brief Constructor from components.
23 * @param i_size Size (in bytes) of this register.
24 */
25 explicit OperatorRegister(size_t i_size) : Register(), iv_result(i_size * 8)
26 {}
27
28 protected: // Instance variables
29 /** When getBitString() is called on an operator, the resulting value of the
30 * operation will be stored in this instance variable. */
31 BitStringBuffer iv_result;
32
33 public:
34 /** @brief Overloaded from parent class. */
35 virtual const BitString* getBitString(const Chip& i_chip) const = 0;
36
37 /** @brief Overloaded from parent class. */
38 size_t getSize() const
39 {
40 return (BitString::getMinBytes(iv_result.getBitLen()));
41 }
42};
43
44// Pure virtual destructor must be defined.
45inline OperatorRegister::~OperatorRegister() {}
46
47class NotRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050048{
49 public:
Zane Shelley48aa8602019-12-05 21:41:21 -060050 /**
51 * @brief Constructor from components.
52 * @param i_arg Target register for operation.
53 */
54 explicit NotRegister(Register& i_arg) :
Zane Shelleyb0559b92019-12-05 22:18:20 -060055 OperatorRegister(i_arg.getSize()), iv_child(&i_arg)
Zane Shelleyd4c0e982019-12-05 21:27:41 -060056 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050057
Zane Shelley48aa8602019-12-05 21:41:21 -060058 /** @brief Default destructor. */
59 ~NotRegister() = default;
60
61 /** @brief Default copy constructor. */
62 NotRegister(const NotRegister&) = default;
63
64 /** @brief Default assignment operator. */
65 NotRegister& operator=(const NotRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050066
Zane Shelleyb0559b92019-12-05 22:18:20 -060067 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -060068 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050069 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -060070 const auto* bs = iv_child->getBitString(i_chip);
71
Zane Shelleyb0559b92019-12-05 22:18:20 -060072 (const_cast<NotRegister*>(this))->iv_result = ~(*bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -060073
Zane Shelleyb0559b92019-12-05 22:18:20 -060074 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050075 }
76
Zane Shelleyec06f822019-12-05 22:23:19 -060077 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -060078 bool operator==(const NotRegister& r) const
79 {
Zane Shelleyec06f822019-12-05 22:23:19 -060080 return iv_child == r.iv_child;
Zane Shelleycaee69f2019-12-05 13:42:58 -060081 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050082
Zane Shelleyec06f822019-12-05 22:23:19 -060083 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -060084 bool operator<(const NotRegister& r) const
85 {
86 return iv_child < r.iv_child;
87 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050088
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050089 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -060090 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050091};
92
Zane Shelleyb0559b92019-12-05 22:18:20 -060093class LeftShiftRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050094{
95 public:
Zane Shelley48aa8602019-12-05 21:41:21 -060096 /**
97 * @brief Constructor from components.
98 * @param i_arg Target register for operation.
99 * @param i_amount The shift value.
100 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600101 LeftShiftRegister(Register& i_arg, uint16_t i_amount) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600102 OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600103 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500104
Zane Shelley48aa8602019-12-05 21:41:21 -0600105 /** @brief Default destructor. */
106 ~LeftShiftRegister() = default;
107
108 /** @brief Default copy constructor. */
109 LeftShiftRegister(const LeftShiftRegister&) = default;
110
111 /** @brief Default assignment operator. */
112 LeftShiftRegister& operator=(const LeftShiftRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500113
Zane Shelleyb0559b92019-12-05 22:18:20 -0600114 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600115 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500116 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600117 const auto* bs = iv_child->getBitString(i_chip);
118
Zane Shelleyb0559b92019-12-05 22:18:20 -0600119 (const_cast<LeftShiftRegister*>(this))->iv_result = (*bs) << iv_amount;
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600120
Zane Shelleyb0559b92019-12-05 22:18:20 -0600121 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500122 }
123
Zane Shelleyec06f822019-12-05 22:23:19 -0600124 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600125 bool operator==(const LeftShiftRegister& r) const
126 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600127 return (iv_child == r.iv_child) && (iv_amount == r.iv_amount);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600128 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500129
Zane Shelleyec06f822019-12-05 22:23:19 -0600130 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600131 bool operator<(const LeftShiftRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500132 {
133 if (iv_child == r.iv_child)
134 return iv_amount < r.iv_amount;
135 return iv_child < r.iv_child;
136 }
137
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500138 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600139 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500140 uint16_t iv_amount;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500141};
142
Zane Shelleyb0559b92019-12-05 22:18:20 -0600143class RightShiftRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500144{
145 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600146 /**
147 * @brief Constructor from components.
148 * @param i_arg Target register for operation.
149 * @param i_amount The shift value.
150 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600151 RightShiftRegister(Register& i_arg, uint16_t i_amount) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600152 OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600153 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500154
Zane Shelley48aa8602019-12-05 21:41:21 -0600155 /** @brief Default destructor. */
156 ~RightShiftRegister() = default;
157
158 /** @brief Default copy constructor. */
159 RightShiftRegister(const RightShiftRegister&) = default;
160
161 /** @brief Default assignment operator. */
162 RightShiftRegister& operator=(const RightShiftRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500163
Zane Shelleyb0559b92019-12-05 22:18:20 -0600164 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600165 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500166 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600167 const auto* bs = iv_child->getBitString(i_chip);
168
Zane Shelleyb0559b92019-12-05 22:18:20 -0600169 (const_cast<RightShiftRegister*>(this))->iv_result = (*bs) >> iv_amount;
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600170
Zane Shelleyb0559b92019-12-05 22:18:20 -0600171 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500172 }
173
Zane Shelleyec06f822019-12-05 22:23:19 -0600174 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600175 bool operator==(const RightShiftRegister& r) const
176 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600177 return (iv_child == r.iv_child) && (iv_amount == r.iv_amount);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600178 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500179
Zane Shelleyec06f822019-12-05 22:23:19 -0600180 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600181 bool operator<(const RightShiftRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500182 {
183 if (iv_child == r.iv_child)
184 return iv_amount < r.iv_amount;
185 return iv_child < r.iv_child;
186 }
187
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500188 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600189 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500190 uint16_t iv_amount;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500191};
192
Zane Shelleyb0559b92019-12-05 22:18:20 -0600193class AndRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500194{
195 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600196 /**
197 * @brief Constructor from components.
198 * @param i_left Target register for operation.
199 * @param i_right Target register for operation.
200 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600201 AndRegister(Register& i_left, Register& i_right) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600202 OperatorRegister(std::min(i_left.getSize(), i_right.getSize())),
203 iv_left(&i_left), iv_right(&i_right)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600204 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500205
Zane Shelley48aa8602019-12-05 21:41:21 -0600206 /** @brief Default destructor. */
207 ~AndRegister() = default;
208
209 /** @brief Default copy constructor. */
210 AndRegister(const AndRegister&) = default;
211
212 /** @brief Default assignment operator. */
213 AndRegister& operator=(const AndRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500214
Zane Shelleyb0559b92019-12-05 22:18:20 -0600215 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600216 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500217 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600218 const auto* l_bs = iv_left->getBitString(i_chip);
219 const auto* r_bs = iv_right->getBitString(i_chip);
220
Zane Shelleyb0559b92019-12-05 22:18:20 -0600221 (const_cast<AndRegister*>(this))->iv_result = (*l_bs) & (*r_bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600222
Zane Shelleyb0559b92019-12-05 22:18:20 -0600223 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500224 }
225
Zane Shelleyec06f822019-12-05 22:23:19 -0600226 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600227 bool operator==(const AndRegister& r) const
228 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600229 return (iv_left == r.iv_left) && (iv_right == r.iv_right);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600230 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500231
Zane Shelleyec06f822019-12-05 22:23:19 -0600232 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600233 bool operator<(const AndRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500234 {
235 if (iv_left == r.iv_left)
236 return iv_right < r.iv_right;
237 return iv_left < r.iv_left;
238 }
239
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500240 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600241 Register* iv_left;
242 Register* iv_right;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500243};
244
Zane Shelleyb0559b92019-12-05 22:18:20 -0600245class OrRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500246{
247 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600248 /**
249 * @brief Constructor from components.
250 * @param i_left Target register for operation.
251 * @param i_right Target register for operation.
252 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600253 OrRegister(Register& i_left, Register& i_right) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600254 OperatorRegister(std::min(i_left.getSize(), i_right.getSize())),
255 iv_left(&i_left), iv_right(&i_right)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600256 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500257
Zane Shelley48aa8602019-12-05 21:41:21 -0600258 /** @brief Default destructor. */
259 ~OrRegister() = default;
260
261 /** @brief Default copy constructor. */
262 OrRegister(const OrRegister&) = default;
263
264 /** @brief Default assignment operator. */
265 OrRegister& operator=(const OrRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500266
Zane Shelleyb0559b92019-12-05 22:18:20 -0600267 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600268 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500269 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600270 const auto* l_bs = iv_left->getBitString(i_chip);
271 const auto* r_bs = iv_right->getBitString(i_chip);
272
Zane Shelleyb0559b92019-12-05 22:18:20 -0600273 (const_cast<OrRegister*>(this))->iv_result = (*l_bs) | (*r_bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600274
Zane Shelleyb0559b92019-12-05 22:18:20 -0600275 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500276 }
277
Zane Shelleyec06f822019-12-05 22:23:19 -0600278 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600279 bool operator==(const OrRegister& r) const
280 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600281 return (iv_left == r.iv_left) && (iv_right == r.iv_right);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600282 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500283
Zane Shelleyec06f822019-12-05 22:23:19 -0600284 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600285 bool operator<(const OrRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500286 {
287 if (iv_left == r.iv_left)
288 return iv_right < r.iv_right;
289 return iv_left < r.iv_left;
290 }
291
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500292 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600293 Register* iv_left;
294 Register* iv_right;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500295};
296
Zane Shelleyb0559b92019-12-05 22:18:20 -0600297class ConstantRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500298{
299 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600300 /**
301 * @brief Constructor from components.
302 * @param i_arg A BitStringBuffer containing the constant value.
303 */
304 explicit ConstantRegister(const BitStringBuffer& i_arg) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600305 OperatorRegister(BitString::getMinBytes(i_arg.getBitLen()))
306 {
307 iv_result = i_arg;
308 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500309
Zane Shelley48aa8602019-12-05 21:41:21 -0600310 /** @brief Default destructor. */
311 ~ConstantRegister() = default;
312
313 /** @brief Default copy constructor. */
314 ConstantRegister(const ConstantRegister&) = default;
315
316 /** @brief Default assignment operator. */
317 ConstantRegister& operator=(const ConstantRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500318
Zane Shelleyb0559b92019-12-05 22:18:20 -0600319 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600320 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500321 {
Zane Shelleyb0559b92019-12-05 22:18:20 -0600322 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500323 }
324
Zane Shelleyec06f822019-12-05 22:23:19 -0600325 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600326 bool operator==(const ConstantRegister& r) const
327 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600328 return iv_result == r.iv_result;
329 }
330
331 /** @brief Less-than operator. */
332 bool operator<(const ConstantRegister& r) const
333 {
334 return iv_result < r.iv_result;
Zane Shelleycaee69f2019-12-05 13:42:58 -0600335 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500336};
337
Zane Shelley871adec2019-07-30 11:01:39 -0500338} // end namespace libhei