blob: 6bfaca9c2abc4a26a140d6e98ca43093202b7ccd [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
Paul Greenwooddc47e0a2019-11-01 16:22:57 -05005/**
6 * @file hei_operator_register.hpp
7 *
8 * A library of useful classes used to perform logical or bitwise math on or
9 * between other registers. The classes implemented here include NotRegister,
10 * LeftShiftRegister, RightShiftRegister, AndRegister, OrRegister, and
11 * ConstantRegister.
12 *
13 * Accompanied with other Register classes and the getBitString() function, it
14 * is possible to perform operations like:
15 *
16 * AndRegister reg{<register1>,<register2>};
17 * result = reg.getBitString(<someChip>);
18 *
19 * This example will return a BitString containing the result of the bitwise
20 * AND operation applied to register1 and register2.
21 */
Zane Shelley871adec2019-07-30 11:01:39 -050022namespace libhei
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050023{
24
Zane Shelleyb0559b92019-12-05 22:18:20 -060025/**
26 * @brief An abstract class for all operator registers.
27 *
28 * Contains member functions and variables that are required for all child
29 * classes.
30 */
31class OperatorRegister : public Register
32{
33 public:
34 /** @brief Pure virtual destructor. */
35 virtual ~OperatorRegister() = 0;
36
37 protected:
38 /**
39 * @brief Constructor from components.
40 * @param i_size Size (in bytes) of this register.
41 */
42 explicit OperatorRegister(size_t i_size) : Register(), iv_result(i_size * 8)
43 {}
44
45 protected: // Instance variables
46 /** When getBitString() is called on an operator, the resulting value of the
47 * operation will be stored in this instance variable. */
48 BitStringBuffer iv_result;
49
50 public:
51 /** @brief Overloaded from parent class. */
Zane Shelleyd0659242020-05-15 23:02:29 -050052 size_t getSize() const override
Zane Shelleyb0559b92019-12-05 22:18:20 -060053 {
54 return (BitString::getMinBytes(iv_result.getBitLen()));
55 }
56};
57
58// Pure virtual destructor must be defined.
59inline OperatorRegister::~OperatorRegister() {}
60
Paul Greenwooddc47e0a2019-11-01 16:22:57 -050061/**
62 * @brief Using getBitString(), performs a bitwise NOT operation on a register.
63 *
64 * Example:
65 * NotRegister reg{someRegister};
66 * result = reg.getBitString(someChip);
67 */
Zane Shelleyb0559b92019-12-05 22:18:20 -060068class NotRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050069{
70 public:
Zane Shelley48aa8602019-12-05 21:41:21 -060071 /**
72 * @brief Constructor from components.
73 * @param i_arg Target register for operation.
74 */
75 explicit NotRegister(Register& i_arg) :
Zane Shelleyb0559b92019-12-05 22:18:20 -060076 OperatorRegister(i_arg.getSize()), iv_child(&i_arg)
Zane Shelleyd4c0e982019-12-05 21:27:41 -060077 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050078
Zane Shelley48aa8602019-12-05 21:41:21 -060079 /** @brief Default destructor. */
80 ~NotRegister() = default;
81
82 /** @brief Default copy constructor. */
83 NotRegister(const NotRegister&) = default;
84
85 /** @brief Default assignment operator. */
86 NotRegister& operator=(const NotRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050087
Zane Shelleyb0559b92019-12-05 22:18:20 -060088 /** @brief Overloaded from parent class. */
Zane Shelleyd0659242020-05-15 23:02:29 -050089 const BitString* getBitString(const Chip& i_chip) const override
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050090 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -060091 const auto* bs = iv_child->getBitString(i_chip);
92
Zane Shelleyb0559b92019-12-05 22:18:20 -060093 (const_cast<NotRegister*>(this))->iv_result = ~(*bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -060094
Zane Shelleyb0559b92019-12-05 22:18:20 -060095 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050096 }
97
Zane Shelleyec06f822019-12-05 22:23:19 -060098 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -060099 bool operator==(const NotRegister& r) const
100 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600101 return iv_child == r.iv_child;
Zane Shelleycaee69f2019-12-05 13:42:58 -0600102 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500103
Zane Shelleyec06f822019-12-05 22:23:19 -0600104 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600105 bool operator<(const NotRegister& r) const
106 {
107 return iv_child < r.iv_child;
108 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500109
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500110 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600111 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500112};
113
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500114/**
115 * @brief Using getBitString(), performs a left shift operation on a register.
116 *
117 * Example:
118 * LeftShiftRegister reg{someRegister1, shiftValue};
119 * result = reg.getBitString(someChip);
120 */
Zane Shelleyb0559b92019-12-05 22:18:20 -0600121class LeftShiftRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500122{
123 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600124 /**
125 * @brief Constructor from components.
126 * @param i_arg Target register for operation.
127 * @param i_amount The shift value.
128 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600129 LeftShiftRegister(Register& i_arg, uint16_t i_amount) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600130 OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600131 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500132
Zane Shelley48aa8602019-12-05 21:41:21 -0600133 /** @brief Default destructor. */
134 ~LeftShiftRegister() = default;
135
136 /** @brief Default copy constructor. */
137 LeftShiftRegister(const LeftShiftRegister&) = default;
138
139 /** @brief Default assignment operator. */
140 LeftShiftRegister& operator=(const LeftShiftRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500141
Zane Shelleyb0559b92019-12-05 22:18:20 -0600142 /** @brief Overloaded from parent class. */
Zane Shelleyd0659242020-05-15 23:02:29 -0500143 const BitString* getBitString(const Chip& i_chip) const override
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500144 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600145 const auto* bs = iv_child->getBitString(i_chip);
146
Zane Shelleyb0559b92019-12-05 22:18:20 -0600147 (const_cast<LeftShiftRegister*>(this))->iv_result = (*bs) << iv_amount;
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600148
Zane Shelleyb0559b92019-12-05 22:18:20 -0600149 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500150 }
151
Zane Shelleyec06f822019-12-05 22:23:19 -0600152 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600153 bool operator==(const LeftShiftRegister& r) const
154 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600155 return (iv_child == r.iv_child) && (iv_amount == r.iv_amount);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600156 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500157
Zane Shelleyec06f822019-12-05 22:23:19 -0600158 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600159 bool operator<(const LeftShiftRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500160 {
161 if (iv_child == r.iv_child)
162 return iv_amount < r.iv_amount;
163 return iv_child < r.iv_child;
164 }
165
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500166 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600167 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500168 uint16_t iv_amount;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500169};
170
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500171/**
172 * @brief Using getBitString(), performs a right shift operation on a register.
173 *
174 * Example:
175 * RightShiftRegister reg{someRegister1, shiftValue};
176 * result = reg.getBitString(someChip);
177 */
Zane Shelleyb0559b92019-12-05 22:18:20 -0600178class RightShiftRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500179{
180 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600181 /**
182 * @brief Constructor from components.
183 * @param i_arg Target register for operation.
184 * @param i_amount The shift value.
185 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600186 RightShiftRegister(Register& i_arg, uint16_t i_amount) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600187 OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600188 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500189
Zane Shelley48aa8602019-12-05 21:41:21 -0600190 /** @brief Default destructor. */
191 ~RightShiftRegister() = default;
192
193 /** @brief Default copy constructor. */
194 RightShiftRegister(const RightShiftRegister&) = default;
195
196 /** @brief Default assignment operator. */
197 RightShiftRegister& operator=(const RightShiftRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500198
Zane Shelleyb0559b92019-12-05 22:18:20 -0600199 /** @brief Overloaded from parent class. */
Zane Shelleyd0659242020-05-15 23:02:29 -0500200 const BitString* getBitString(const Chip& i_chip) const override
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500201 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600202 const auto* bs = iv_child->getBitString(i_chip);
203
Zane Shelleyb0559b92019-12-05 22:18:20 -0600204 (const_cast<RightShiftRegister*>(this))->iv_result = (*bs) >> iv_amount;
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600205
Zane Shelleyb0559b92019-12-05 22:18:20 -0600206 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500207 }
208
Zane Shelleyec06f822019-12-05 22:23:19 -0600209 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600210 bool operator==(const RightShiftRegister& r) const
211 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600212 return (iv_child == r.iv_child) && (iv_amount == r.iv_amount);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600213 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500214
Zane Shelleyec06f822019-12-05 22:23:19 -0600215 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600216 bool operator<(const RightShiftRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500217 {
218 if (iv_child == r.iv_child)
219 return iv_amount < r.iv_amount;
220 return iv_child < r.iv_child;
221 }
222
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500223 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600224 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500225 uint16_t iv_amount;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500226};
227
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500228/**
229 * @brief Using getBitString(), performs a bitwise AND operation on a pair
230 * of registers.
231 *
232 * Example:
233 * AndRegister reg{someRegister1, someRegister2};
234 * result = reg.getBitString(someChip);
235 */
Zane Shelleyb0559b92019-12-05 22:18:20 -0600236class AndRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500237{
238 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600239 /**
240 * @brief Constructor from components.
241 * @param i_left Target register for operation.
242 * @param i_right Target register for operation.
243 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600244 AndRegister(Register& i_left, Register& i_right) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600245 OperatorRegister(std::min(i_left.getSize(), i_right.getSize())),
246 iv_left(&i_left), iv_right(&i_right)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600247 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500248
Zane Shelley48aa8602019-12-05 21:41:21 -0600249 /** @brief Default destructor. */
250 ~AndRegister() = default;
251
252 /** @brief Default copy constructor. */
253 AndRegister(const AndRegister&) = default;
254
255 /** @brief Default assignment operator. */
256 AndRegister& operator=(const AndRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500257
Zane Shelleyb0559b92019-12-05 22:18:20 -0600258 /** @brief Overloaded from parent class. */
Zane Shelleyd0659242020-05-15 23:02:29 -0500259 const BitString* getBitString(const Chip& i_chip) const override
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500260 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600261 const auto* l_bs = iv_left->getBitString(i_chip);
262 const auto* r_bs = iv_right->getBitString(i_chip);
263
Zane Shelleyb0559b92019-12-05 22:18:20 -0600264 (const_cast<AndRegister*>(this))->iv_result = (*l_bs) & (*r_bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600265
Zane Shelleyb0559b92019-12-05 22:18:20 -0600266 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500267 }
268
Zane Shelleyec06f822019-12-05 22:23:19 -0600269 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600270 bool operator==(const AndRegister& r) const
271 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600272 return (iv_left == r.iv_left) && (iv_right == r.iv_right);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600273 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500274
Zane Shelleyec06f822019-12-05 22:23:19 -0600275 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600276 bool operator<(const AndRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500277 {
278 if (iv_left == r.iv_left)
279 return iv_right < r.iv_right;
280 return iv_left < r.iv_left;
281 }
282
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500283 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600284 Register* iv_left;
285 Register* iv_right;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500286};
287
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500288/**
289 * @brief Using getBitString(), performs a bitwise OR operation on a pair
290 * of registers.
291 *
292 * Example:
293 * OrRegister reg{someRegister1, someRegister2};
294 * result = reg.getBitString(someChip);
295 */
Zane Shelleyb0559b92019-12-05 22:18:20 -0600296class OrRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500297{
298 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600299 /**
300 * @brief Constructor from components.
301 * @param i_left Target register for operation.
302 * @param i_right Target register for operation.
303 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600304 OrRegister(Register& i_left, Register& i_right) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600305 OperatorRegister(std::min(i_left.getSize(), i_right.getSize())),
306 iv_left(&i_left), iv_right(&i_right)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600307 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500308
Zane Shelley48aa8602019-12-05 21:41:21 -0600309 /** @brief Default destructor. */
310 ~OrRegister() = default;
311
312 /** @brief Default copy constructor. */
313 OrRegister(const OrRegister&) = default;
314
315 /** @brief Default assignment operator. */
316 OrRegister& operator=(const OrRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500317
Zane Shelleyb0559b92019-12-05 22:18:20 -0600318 /** @brief Overloaded from parent class. */
Zane Shelleyd0659242020-05-15 23:02:29 -0500319 const BitString* getBitString(const Chip& i_chip) const override
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500320 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600321 const auto* l_bs = iv_left->getBitString(i_chip);
322 const auto* r_bs = iv_right->getBitString(i_chip);
323
Zane Shelleyb0559b92019-12-05 22:18:20 -0600324 (const_cast<OrRegister*>(this))->iv_result = (*l_bs) | (*r_bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600325
Zane Shelleyb0559b92019-12-05 22:18:20 -0600326 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500327 }
328
Zane Shelleyec06f822019-12-05 22:23:19 -0600329 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600330 bool operator==(const OrRegister& r) const
331 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600332 return (iv_left == r.iv_left) && (iv_right == r.iv_right);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600333 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500334
Zane Shelleyec06f822019-12-05 22:23:19 -0600335 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600336 bool operator<(const OrRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500337 {
338 if (iv_left == r.iv_left)
339 return iv_right < r.iv_right;
340 return iv_left < r.iv_left;
341 }
342
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500343 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600344 Register* iv_left;
345 Register* iv_right;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500346};
347
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500348/**
349 * @brief Contains a constant value that can be used within any of the other
350 * register operators. The value can be retrieved using the
351 * getBitString() function.
352 **/
Zane Shelleyb0559b92019-12-05 22:18:20 -0600353class ConstantRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500354{
355 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600356 /**
357 * @brief Constructor from components.
358 * @param i_arg A BitStringBuffer containing the constant value.
359 */
360 explicit ConstantRegister(const BitStringBuffer& i_arg) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600361 OperatorRegister(BitString::getMinBytes(i_arg.getBitLen()))
362 {
363 iv_result = i_arg;
364 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500365
Zane Shelley48aa8602019-12-05 21:41:21 -0600366 /** @brief Default destructor. */
367 ~ConstantRegister() = default;
368
369 /** @brief Default copy constructor. */
370 ConstantRegister(const ConstantRegister&) = default;
371
372 /** @brief Default assignment operator. */
373 ConstantRegister& operator=(const ConstantRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500374
Zane Shelleyb0559b92019-12-05 22:18:20 -0600375 /** @brief Overloaded from parent class. */
Zane Shelleyd0659242020-05-15 23:02:29 -0500376 const BitString* getBitString(const Chip& i_chip) const override
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500377 {
Zane Shelleyb0559b92019-12-05 22:18:20 -0600378 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500379 }
380
Zane Shelleyec06f822019-12-05 22:23:19 -0600381 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600382 bool operator==(const ConstantRegister& r) const
383 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600384 return iv_result == r.iv_result;
385 }
386
387 /** @brief Less-than operator. */
388 bool operator<(const ConstantRegister& r) const
389 {
390 return iv_result < r.iv_result;
Zane Shelleycaee69f2019-12-05 13:42:58 -0600391 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500392};
393
Zane Shelley871adec2019-07-30 11:01:39 -0500394} // end namespace libhei