23 #ifndef BM_BM_SIM_DATA_H_
24 #define BM_BM_SIM_DATA_H_
28 #include <type_traits>
65 typename std::enable_if<std::is_integral<T>::value,
int>::type = 0>
70 Data(
const char *bytes,
int nbytes) {
71 bignum::import_bytes(&value, bytes, nbytes);
76 static char char2digit(
char c) {
77 if (c >=
'0' && c <=
'9')
79 if (c >=
'A' && c <=
'F')
80 return (c -
'A' + 10);
81 if (c >=
'a' && c <=
'f')
82 return (c -
'a' + 10);
91 explicit Data(
const std::string &hexstring) {
95 virtual void export_bytes() {}
99 int sign()
const {
return value.sign(); }
104 typename std::enable_if<std::is_integral<T>::value,
int>::type = 0>
112 typename std::enable_if<std::is_enum<T>::value,
int>::type = 0>
114 value =
static_cast<int>(i);
119 void set(
const char *bytes,
int nbytes) {
120 bignum::import_bytes(&value, bytes, nbytes);
125 void set(
const Data &data) {
130 void set(Data &&data) {
131 value = std::move(data.value);
135 void set(
const ByteContainer &bc) {
136 bignum::import_bytes(&value, bc.data(), bc.size());
143 #if __GNUC__ == 5 && __GNUC_MINOR__ <= 2
150 __attribute__((optimize(
"O0")))
152 set(
const std::string &hexstring) {
153 std::vector<char> bytes;
157 if (hexstring[idx] ==
'-') {
161 if (hexstring[idx] ==
'0' && hexstring[idx + 1] ==
'x') {
164 size_t size = hexstring.
size();
165 assert((size - idx) > 0);
167 if ((size - idx) % 2 != 0) {
168 char c = char2digit(hexstring[idx++]);
172 for (; idx < size; ) {
173 char c = char2digit(hexstring[idx++]) << 4;
174 c += char2digit(hexstring[idx++]);
178 bignum::import_bytes(&value, bytes.data(), bytes.size());
179 if (neg) value = -value;
185 typename std::enable_if<std::is_integral<T>::value,
int>::type = 0>
188 return value.convert_to<
typename std::remove_const<T>::type>();
192 unsigned int get_uint()
const {
194 return value.convert_to<
unsigned int>();
198 uint64_t get_uint64()
const {
200 return value.convert_to<uint64_t>();
204 int get_int()
const {
206 return value.convert_to<
int>();
211 std::string get_string()
const {
213 const size_t export_size = bignum::export_size_in_bytes(value);
214 std::string s(export_size,
'\x00');
216 bignum::export_bytes(&s[0], export_size, value);
220 std::string get_string_repr()
const {
222 return value.convert_to<std::string>();
225 bool get_arith()
const {
return arith; }
230 void add(
const Data &src1,
const Data &src2) {
231 assert(src1.arith && src2.arith);
232 value = src1.value + src2.value;
237 void sub(
const Data &src1,
const Data &src2) {
238 assert(src1.arith && src2.arith);
239 value = src1.value - src2.value;
245 void mod(
const Data &src1,
const Data &src2) {
246 assert(src1.arith && src2.arith);
247 assert(src1.value >= 0 && src2.value > 0);
248 value = src1.value % src2.value;
254 void divide(
const Data &src1,
const Data &src2) {
255 assert(src1.arith && src2.arith);
256 assert(src1.value >= 0 && src2.value > 0);
257 value = src1.value / src2.value;
262 void multiply(
const Data &src1,
const Data &src2) {
263 assert(src1.arith && src2.arith);
264 value = src1.value * src2.value;
269 void shift_left(
const Data &src1,
const Data &src2) {
270 assert(src1.arith && src2.arith);
271 assert(src2.value >= 0);
272 value = src1.value << (src2.get_uint());
277 void shift_right(
const Data &src1,
const Data &src2) {
278 assert(src1.arith && src2.arith);
279 assert(src2.value >= 0);
280 value = src1.value >> (src2.get_uint());
285 void shift_left(
const Data &src1,
unsigned int src2) {
287 value = src1.value << src2;
292 void shift_right(
const Data &src1,
unsigned int src2) {
294 value = src1.value >> src2;
299 void bit_and(
const Data &src1,
const Data &src2) {
300 assert(src1.arith && src2.arith);
301 value = src1.value & src2.value;
306 void bit_or(
const Data &src1,
const Data &src2) {
307 assert(src1.arith && src2.arith);
308 value = src1.value | src2.value;
313 void bit_xor(
const Data &src1,
const Data &src2) {
314 assert(src1.arith && src2.arith);
315 value = src1.value ^ src2.value;
320 void bit_neg(
const Data &src) {
328 void two_comp_mod(
const Data &src,
const Data &width) {
329 static const Bignum one(1);
330 unsigned int uwidth = width.get_uint();
331 Bignum mask = (one << uwidth) - 1;
332 Bignum max = (one << (uwidth - 1)) - 1;
333 Bignum min = -(one << (uwidth - 1));
334 if (src.value < min || src.value > max) {
335 value = src.value & mask;
337 value -= (one << uwidth);
347 void usat_cast(
const Data &src,
const Data &width) {
348 static const Bignum one(1);
349 unsigned int uwidth = width.get_uint();
350 Bignum max = (one << uwidth) - 1;
353 else if (src.value < 0)
363 void sat_cast(
const Data &src,
const Data &width) {
364 static const Bignum one(1);
365 unsigned int uwidth = width.get_uint();
366 Bignum max = (one << (uwidth - 1)) - 1;
367 Bignum min = -(one << (uwidth - 1));
370 else if (src.value < min)
379 typename std::enable_if<std::is_integral<T>::value,
int>::type = 0>
380 bool test_eq(T i)
const {
385 friend bool operator==(
const Data &lhs,
const Data &rhs) {
386 assert(lhs.arith && rhs.arith);
387 return lhs.value == rhs.value;
391 friend bool operator!=(
const Data &lhs,
const Data &rhs) {
392 assert(lhs.arith && rhs.arith);
393 return !(lhs == rhs);
397 friend bool operator>(
const Data &lhs,
const Data &rhs) {
398 assert(lhs.arith && rhs.arith);
399 return lhs.value > rhs.value;
403 friend bool operator>=(
const Data &lhs,
const Data &rhs) {
404 assert(lhs.arith && rhs.arith);
405 return lhs.value >= rhs.value;
409 friend bool operator<(
const Data &lhs,
const Data &rhs) {
410 assert(lhs.arith && rhs.arith);
411 return lhs.value < rhs.value;
415 friend bool operator<=(
const Data &lhs,
const Data &rhs) {
416 assert(lhs.arith && rhs.arith);
417 return lhs.value <= rhs.value;
421 friend std::ostream& operator<<(std::ostream &out,
const Data &d) {
429 Data(
const Data &other)
430 : arith(other.arith) {
431 if (other.arith) value = other.value;
436 Data &operator=(
const Data &other) {
438 *
this = std::move(tmp);
443 Data(Data &&other) =
default;
446 Data &operator=(Data &&other) =
default;
455 #endif // BM_BM_SIM_DATA_H_