blob: ce9a869de5dc23bdd265dcd42d0864f37c18b298 [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. */
52 virtual const BitString* getBitString(const Chip& i_chip) const = 0;
53
54 /** @brief Overloaded from parent class. */
55 size_t getSize() const
56 {
57 return (BitString::getMinBytes(iv_result.getBitLen()));
58 }
59};
60
61// Pure virtual destructor must be defined.
62inline OperatorRegister::~OperatorRegister() {}
63
Paul Greenwooddc47e0a2019-11-01 16:22:57 -050064/**
65 * @brief Using getBitString(), performs a bitwise NOT operation on a register.
66 *
67 * Example:
68 * NotRegister reg{someRegister};
69 * result = reg.getBitString(someChip);
70 */
Zane Shelleyb0559b92019-12-05 22:18:20 -060071class NotRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050072{
73 public:
Zane Shelley48aa8602019-12-05 21:41:21 -060074 /**
75 * @brief Constructor from components.
76 * @param i_arg Target register for operation.
77 */
78 explicit NotRegister(Register& i_arg) :
Zane Shelleyb0559b92019-12-05 22:18:20 -060079 OperatorRegister(i_arg.getSize()), iv_child(&i_arg)
Zane Shelleyd4c0e982019-12-05 21:27:41 -060080 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050081
Zane Shelley48aa8602019-12-05 21:41:21 -060082 /** @brief Default destructor. */
83 ~NotRegister() = default;
84
85 /** @brief Default copy constructor. */
86 NotRegister(const NotRegister&) = default;
87
88 /** @brief Default assignment operator. */
89 NotRegister& operator=(const NotRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050090
Zane Shelleyb0559b92019-12-05 22:18:20 -060091 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -060092 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050093 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -060094 const auto* bs = iv_child->getBitString(i_chip);
95
Zane Shelleyb0559b92019-12-05 22:18:20 -060096 (const_cast<NotRegister*>(this))->iv_result = ~(*bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -060097
Zane Shelleyb0559b92019-12-05 22:18:20 -060098 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050099 }
100
Zane Shelleyec06f822019-12-05 22:23:19 -0600101 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600102 bool operator==(const NotRegister& r) const
103 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600104 return iv_child == r.iv_child;
Zane Shelleycaee69f2019-12-05 13:42:58 -0600105 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500106
Zane Shelleyec06f822019-12-05 22:23:19 -0600107 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600108 bool operator<(const NotRegister& r) const
109 {
110 return iv_child < r.iv_child;
111 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500112
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500113 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600114 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500115};
116
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500117/**
118 * @brief Using getBitString(), performs a left shift operation on a register.
119 *
120 * Example:
121 * LeftShiftRegister reg{someRegister1, shiftValue};
122 * result = reg.getBitString(someChip);
123 */
Zane Shelleyb0559b92019-12-05 22:18:20 -0600124class LeftShiftRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500125{
126 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600127 /**
128 * @brief Constructor from components.
129 * @param i_arg Target register for operation.
130 * @param i_amount The shift value.
131 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600132 LeftShiftRegister(Register& i_arg, uint16_t i_amount) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600133 OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600134 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500135
Zane Shelley48aa8602019-12-05 21:41:21 -0600136 /** @brief Default destructor. */
137 ~LeftShiftRegister() = default;
138
139 /** @brief Default copy constructor. */
140 LeftShiftRegister(const LeftShiftRegister&) = default;
141
142 /** @brief Default assignment operator. */
143 LeftShiftRegister& operator=(const LeftShiftRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500144
Zane Shelleyb0559b92019-12-05 22:18:20 -0600145 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600146 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500147 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600148 const auto* bs = iv_child->getBitString(i_chip);
149
Zane Shelleyb0559b92019-12-05 22:18:20 -0600150 (const_cast<LeftShiftRegister*>(this))->iv_result = (*bs) << iv_amount;
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600151
Zane Shelleyb0559b92019-12-05 22:18:20 -0600152 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500153 }
154
Zane Shelleyec06f822019-12-05 22:23:19 -0600155 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600156 bool operator==(const LeftShiftRegister& r) const
157 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600158 return (iv_child == r.iv_child) && (iv_amount == r.iv_amount);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600159 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500160
Zane Shelleyec06f822019-12-05 22:23:19 -0600161 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600162 bool operator<(const LeftShiftRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500163 {
164 if (iv_child == r.iv_child)
165 return iv_amount < r.iv_amount;
166 return iv_child < r.iv_child;
167 }
168
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500169 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600170 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500171 uint16_t iv_amount;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500172};
173
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500174/**
175 * @brief Using getBitString(), performs a right shift operation on a register.
176 *
177 * Example:
178 * RightShiftRegister reg{someRegister1, shiftValue};
179 * result = reg.getBitString(someChip);
180 */
Zane Shelleyb0559b92019-12-05 22:18:20 -0600181class RightShiftRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500182{
183 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600184 /**
185 * @brief Constructor from components.
186 * @param i_arg Target register for operation.
187 * @param i_amount The shift value.
188 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600189 RightShiftRegister(Register& i_arg, uint16_t i_amount) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600190 OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600191 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500192
Zane Shelley48aa8602019-12-05 21:41:21 -0600193 /** @brief Default destructor. */
194 ~RightShiftRegister() = default;
195
196 /** @brief Default copy constructor. */
197 RightShiftRegister(const RightShiftRegister&) = default;
198
199 /** @brief Default assignment operator. */
200 RightShiftRegister& operator=(const RightShiftRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500201
Zane Shelleyb0559b92019-12-05 22:18:20 -0600202 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600203 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500204 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600205 const auto* bs = iv_child->getBitString(i_chip);
206
Zane Shelleyb0559b92019-12-05 22:18:20 -0600207 (const_cast<RightShiftRegister*>(this))->iv_result = (*bs) >> iv_amount;
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600208
Zane Shelleyb0559b92019-12-05 22:18:20 -0600209 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500210 }
211
Zane Shelleyec06f822019-12-05 22:23:19 -0600212 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600213 bool operator==(const RightShiftRegister& r) const
214 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600215 return (iv_child == r.iv_child) && (iv_amount == r.iv_amount);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600216 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500217
Zane Shelleyec06f822019-12-05 22:23:19 -0600218 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600219 bool operator<(const RightShiftRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500220 {
221 if (iv_child == r.iv_child)
222 return iv_amount < r.iv_amount;
223 return iv_child < r.iv_child;
224 }
225
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500226 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600227 Register* iv_child;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500228 uint16_t iv_amount;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500229};
230
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500231/**
232 * @brief Using getBitString(), performs a bitwise AND operation on a pair
233 * of registers.
234 *
235 * Example:
236 * AndRegister reg{someRegister1, someRegister2};
237 * result = reg.getBitString(someChip);
238 */
Zane Shelleyb0559b92019-12-05 22:18:20 -0600239class AndRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500240{
241 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600242 /**
243 * @brief Constructor from components.
244 * @param i_left Target register for operation.
245 * @param i_right Target register for operation.
246 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600247 AndRegister(Register& i_left, Register& i_right) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600248 OperatorRegister(std::min(i_left.getSize(), i_right.getSize())),
249 iv_left(&i_left), iv_right(&i_right)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600250 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500251
Zane Shelley48aa8602019-12-05 21:41:21 -0600252 /** @brief Default destructor. */
253 ~AndRegister() = default;
254
255 /** @brief Default copy constructor. */
256 AndRegister(const AndRegister&) = default;
257
258 /** @brief Default assignment operator. */
259 AndRegister& operator=(const AndRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500260
Zane Shelleyb0559b92019-12-05 22:18:20 -0600261 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600262 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500263 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600264 const auto* l_bs = iv_left->getBitString(i_chip);
265 const auto* r_bs = iv_right->getBitString(i_chip);
266
Zane Shelleyb0559b92019-12-05 22:18:20 -0600267 (const_cast<AndRegister*>(this))->iv_result = (*l_bs) & (*r_bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600268
Zane Shelleyb0559b92019-12-05 22:18:20 -0600269 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500270 }
271
Zane Shelleyec06f822019-12-05 22:23:19 -0600272 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600273 bool operator==(const AndRegister& r) const
274 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600275 return (iv_left == r.iv_left) && (iv_right == r.iv_right);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600276 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500277
Zane Shelleyec06f822019-12-05 22:23:19 -0600278 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600279 bool operator<(const AndRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500280 {
281 if (iv_left == r.iv_left)
282 return iv_right < r.iv_right;
283 return iv_left < r.iv_left;
284 }
285
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500286 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600287 Register* iv_left;
288 Register* iv_right;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500289};
290
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500291/**
292 * @brief Using getBitString(), performs a bitwise OR operation on a pair
293 * of registers.
294 *
295 * Example:
296 * OrRegister reg{someRegister1, someRegister2};
297 * result = reg.getBitString(someChip);
298 */
Zane Shelleyb0559b92019-12-05 22:18:20 -0600299class OrRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500300{
301 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600302 /**
303 * @brief Constructor from components.
304 * @param i_left Target register for operation.
305 * @param i_right Target register for operation.
306 */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600307 OrRegister(Register& i_left, Register& i_right) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600308 OperatorRegister(std::min(i_left.getSize(), i_right.getSize())),
309 iv_left(&i_left), iv_right(&i_right)
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600310 {}
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500311
Zane Shelley48aa8602019-12-05 21:41:21 -0600312 /** @brief Default destructor. */
313 ~OrRegister() = default;
314
315 /** @brief Default copy constructor. */
316 OrRegister(const OrRegister&) = default;
317
318 /** @brief Default assignment operator. */
319 OrRegister& operator=(const OrRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500320
Zane Shelleyb0559b92019-12-05 22:18:20 -0600321 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600322 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500323 {
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600324 const auto* l_bs = iv_left->getBitString(i_chip);
325 const auto* r_bs = iv_right->getBitString(i_chip);
326
Zane Shelleyb0559b92019-12-05 22:18:20 -0600327 (const_cast<OrRegister*>(this))->iv_result = (*l_bs) | (*r_bs);
Zane Shelleyd4c0e982019-12-05 21:27:41 -0600328
Zane Shelleyb0559b92019-12-05 22:18:20 -0600329 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500330 }
331
Zane Shelleyec06f822019-12-05 22:23:19 -0600332 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600333 bool operator==(const OrRegister& r) const
334 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600335 return (iv_left == r.iv_left) && (iv_right == r.iv_right);
Zane Shelleycaee69f2019-12-05 13:42:58 -0600336 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500337
Zane Shelleyec06f822019-12-05 22:23:19 -0600338 /** @brief Less-than operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600339 bool operator<(const OrRegister& r) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500340 {
341 if (iv_left == r.iv_left)
342 return iv_right < r.iv_right;
343 return iv_left < r.iv_left;
344 }
345
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500346 private:
Zane Shelleycaee69f2019-12-05 13:42:58 -0600347 Register* iv_left;
348 Register* iv_right;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500349};
350
Paul Greenwooddc47e0a2019-11-01 16:22:57 -0500351/**
352 * @brief Contains a constant value that can be used within any of the other
353 * register operators. The value can be retrieved using the
354 * getBitString() function.
355 **/
Zane Shelleyb0559b92019-12-05 22:18:20 -0600356class ConstantRegister : public OperatorRegister
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500357{
358 public:
Zane Shelley48aa8602019-12-05 21:41:21 -0600359 /**
360 * @brief Constructor from components.
361 * @param i_arg A BitStringBuffer containing the constant value.
362 */
363 explicit ConstantRegister(const BitStringBuffer& i_arg) :
Zane Shelleyb0559b92019-12-05 22:18:20 -0600364 OperatorRegister(BitString::getMinBytes(i_arg.getBitLen()))
365 {
366 iv_result = i_arg;
367 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500368
Zane Shelley48aa8602019-12-05 21:41:21 -0600369 /** @brief Default destructor. */
370 ~ConstantRegister() = default;
371
372 /** @brief Default copy constructor. */
373 ConstantRegister(const ConstantRegister&) = default;
374
375 /** @brief Default assignment operator. */
376 ConstantRegister& operator=(const ConstantRegister& r) = default;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500377
Zane Shelleyb0559b92019-12-05 22:18:20 -0600378 /** @brief Overloaded from parent class. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600379 const BitString* getBitString(const Chip& i_chip) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500380 {
Zane Shelleyb0559b92019-12-05 22:18:20 -0600381 return &iv_result;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500382 }
383
Zane Shelleyec06f822019-12-05 22:23:19 -0600384 /** @brief Comparison operator. */
Zane Shelleycaee69f2019-12-05 13:42:58 -0600385 bool operator==(const ConstantRegister& r) const
386 {
Zane Shelleyec06f822019-12-05 22:23:19 -0600387 return iv_result == r.iv_result;
388 }
389
390 /** @brief Less-than operator. */
391 bool operator<(const ConstantRegister& r) const
392 {
393 return iv_result < r.iv_result;
Zane Shelleycaee69f2019-12-05 13:42:58 -0600394 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500395};
396
Zane Shelley871adec2019-07-30 11:01:39 -0500397} // end namespace libhei