OpenASIP  2.0
SimValue.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2015 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file SimValue.cc
26  *
27  * Non-inline definitions of SimValue class.
28  *
29  * @author Pekka Jääskeläinen 2004,2014-2015 (pjaaskel-no.spam-cs.tut.fi)
30  * @author Mikko Jarvela 2013, 2014 (mikko.jarvela-no.spam-.tut.fi)
31  * @note This file is used in compiled simulation. Keep dependencies *clean*
32  * @note rating: red
33  */
34 
35 #include "SimValue.hh"
36 #include "MathTools.hh"
37 #include "Conversion.hh"
38 #include "TCEString.hh"
39 #include "Exception.hh"
40 
41 /**
42  * Default constructor.
43  *
44  * To allow creation of SimValue arrays. Constructs a SimValue with
45  * width of SIMULATOR_MAX_INTWORD_BITWIDTH bits.
46  */
48  mask_(~ULongWord(0)) {
49 
51 }
52 
53 /**
54  * Constructor.
55  *
56  * @param width The bit width of the created SimValue.
57  */
58 SimValue::SimValue(int width) :
59  mask_(~ULongWord(0)) {
60 
62 }
63 
64 
65 /**
66  * Constructor.
67  *
68  * @param value The numeric value of this SimValue (in host endianness).
69  * @param width The bit width of the created SimValue.
70  */
71 SimValue::SimValue(SLongWord value, int width) :
72  mask_(~ULongWord(0)) {
73 
75 
76  // Don't memcpy more than 8 bytes
77  const int BYTE_COUNT =
78  width < 64 ? (width + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH : 8;
79 
80 #if HOST_BIGENDIAN == 1
81  swapByteOrder(((const Byte*)&value), BYTE_COUNT, rawData_);
82 #else
83  memcpy(rawData_, &value, BYTE_COUNT);
84 #endif
85 }
86 
87 
88 /**
89  * Copy constructor.
90  *
91  * @param source The source object from which to copy data.
92  */
93 SimValue::SimValue(const SimValue& source) {
94  deepCopy(source);
95 }
96 
97 /**
98  * Returns the bit width of the SimValue.
99  *
100  * @return The bit width.
101  */
102 int
104  return bitWidth_;
105 }
106 
107 /**
108  * Sets SimValue's bitwidth and clears bytes to 0 for the whole width.
109  *
110  * @param width The new bit width.
111  */
112 void
115 
116  bitWidth_ = width;
117  if (BYTE_BITWIDTH * sizeof(mask_) > static_cast<size_t>(width)) {
118  mask_ = ~((~ULongWord(0)) << bitWidth_);
119  }
120 
121  const int BYTE_COUNT = (width + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH;
122 
123  if (static_cast<size_t>(BYTE_COUNT) > sizeof(DoubleWord)) {
125  } else {
127  }
128 }
129 
130 
131 /**
132  * Assignment operator for source value of type SIntWord.
133  *
134  * @param source The source value.
135  * @return Reference to itself.
136  */
137 SimValue&
139 
140  const size_t BYTE_COUNT = sizeof(SIntWord);
141 
142 #if HOST_BIGENDIAN == 1
143  swapByteOrder((const Byte*)&source, BYTE_COUNT, rawData_);
144 #else
145  memcpy(rawData_, &source, BYTE_COUNT);
146 #endif
147  return (*this);
148 }
149 
150 /**
151  * Assignment operator for source value of type UIntWord.
152  *
153  * @param source The source value.
154  * @return Reference to itself.
155  */
156 SimValue&
158 
159  const size_t BYTE_COUNT = sizeof(UIntWord);
160 
161 #if HOST_BIGENDIAN == 1
162  swapByteOrder((const Byte*)&source, BYTE_COUNT, rawData_);
163 #else
164  memcpy(rawData_, &source, BYTE_COUNT);
165 #endif
166  return (*this);
167 }
168 
169 /**
170  * Assignment operator for source value of type SLongWord.
171  *
172  * @param source The source value.
173  * @return Reference to itself.
174  */
175 SimValue&
177 
178  const size_t BYTE_COUNT = sizeof(SLongWord);
179 
180 #if HOST_BIGENDIAN == 1
181  swapByteOrder((const Byte*)&source, BYTE_COUNT, rawData_);
182 #else
183  memcpy(rawData_, &source, BYTE_COUNT);
184 #endif
185  return (*this);
186 }
187 
188 /**
189  * Assignment operator for source value of type ULongWord.
190  *
191  * @param source The source value.
192  * @return Reference to itself.
193  */
194 SimValue&
196 
197  const size_t BYTE_COUNT = sizeof(ULongWord);
198 
199 #if HOST_BIGENDIAN == 1
200  swapByteOrder((const Byte*)&source, BYTE_COUNT, rawData_);
201 #else
202  memcpy(rawData_, &source, BYTE_COUNT);
203 #endif
204  return (*this);
205 }
206 
207 
208 /**
209  * Assignment operator for source value of type HalfFloatWord.
210  *
211  * @param source The source value.
212  * @return Reference to itself.
213  */
214 SimValue&
216 
217  const size_t BYTE_COUNT = sizeof(uint16_t);
218  uint16_t data = source.getBinaryRep();
219 
220  setBitWidth(BYTE_COUNT * BYTE_BITWIDTH);
221 
222 #if HOST_BIGENDIAN == 1
223  swapByteOrder((const Byte*)&data, BYTE_COUNT, rawData_);
224 #else
225  memcpy(rawData_, &data, BYTE_COUNT);
226 #endif
227  return (*this);
228 }
229 
230 /**
231  * Assignment operator for source value of type FloatWord.
232  *
233  * @param source The source value.
234  * @return Reference to itself.
235  */
236 SimValue&
238 
239  const size_t BYTE_COUNT = sizeof(FloatWord);
240 
241  setBitWidth(BYTE_COUNT * BYTE_BITWIDTH);
242 
243 #if HOST_BIGENDIAN == 1
244  swapByteOrder((const Byte*)&source, BYTE_COUNT, rawData_);
245 #else
246  memcpy(rawData_, &source, BYTE_COUNT);
247 #endif
248  return (*this);
249 }
250 
251 /**
252  * Assignment operator for source value of type DoubleWord.
253  *
254  * @param source The source value.
255  * @return Reference to itself.
256  */
257 SimValue&
259 
260  const size_t BYTE_COUNT = sizeof(DoubleWord);
261 
262  setBitWidth(BYTE_COUNT * BYTE_BITWIDTH);
263 
264 #if HOST_BIGENDIAN == 1
265  swapByteOrder((const Byte*)&source, BYTE_COUNT, rawData_);
266 #else
267  memcpy(rawData_, &source, BYTE_COUNT);
268 #endif
269  return (*this);
270 }
271 
272 /**
273  * Assignment operator for source value of type SimValue.
274  *
275  * @note No sign extension is done in case
276  * the destination width differs from the source width.
277  *
278  * @param source The source value.
279  * @return Reference to itself.
280  */
281 SimValue&
283 
284  const size_t DST_BYTE_COUNT =
286  const size_t SRC_BYTE_COUNT =
287  (source.bitWidth_ + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH;
288 
289  memcpy(rawData_, source.rawData_, SRC_BYTE_COUNT);
290  if (SRC_BYTE_COUNT < DST_BYTE_COUNT) {
291  memset(rawData_+SRC_BYTE_COUNT, 0, DST_BYTE_COUNT-SRC_BYTE_COUNT);
292  } else if (bitWidth_ % BYTE_BITWIDTH) {
293  const unsigned bitsInMSB = bitWidth_ % BYTE_BITWIDTH;
294  const Byte msbBitMask = static_cast<Byte>((1 << bitsInMSB) - 1);
295  rawData_[DST_BYTE_COUNT-1] &= msbBitMask;
296  }
297 
298  return (*this);
299 }
300 
301 /**
302  * Copies the source SimValue completely.
303  *
304  * @param source The source value.
305  */
306 void
307 SimValue::deepCopy(const SimValue& source) {
308 
309  const size_t BYTE_COUNT =
310  (source.bitWidth_ + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH;
311 
312  memcpy(rawData_, source.rawData_, BYTE_COUNT);
313  bitWidth_ = source.bitWidth_;
314  mask_ = source.mask_;
315 }
316 
317 /**
318  * Explicit addition operator to SIntWord type.
319  *
320  * These operators are defined to avoid ambiguous overload because of built-in
321  * operators.
322  *
323  * @param rightHand The right hand side of the addition.
324  * @return The SimValue with the result of the operation.
325  */
326 const SimValue
327 SimValue::operator+(const SIntWord& rightHand) {
328  SimValue copy(*this);
329  copy = sIntWordValue() + rightHand;
330  return copy;
331 }
332 
333 /**
334  * Explicit addition operator to UIntWord type.
335  *
336  * These operators are defined to avoid ambiguous overload because of built-in
337  * operators.
338  *
339  * @param rightHand The right hand side of the addition.
340  * @return The SimValue with the result of the operation.
341  */
342 const SimValue
343 SimValue::operator+(const UIntWord& rightHand) {
344  SimValue copy(*this);
345  copy = uIntWordValue() + rightHand;
346  return copy;
347 }
348 
349 /**
350  * Explicit addition operator to SlongWord type.
351  *
352  * These operators are defined to avoid ambiguous overload because of built-in
353  * operators.
354  *
355  * @param rightHand The right hand side of the addition.
356  * @return The SimValue with the result of the operation.
357  */
358 const SimValue
359 SimValue::operator+(const SLongWord& rightHand) {
360  SimValue copy(*this);
361  copy = sLongWordValue() + rightHand;
362  return copy;
363 }
364 
365 /**
366  * Explicit addition operator to ULongWord type.
367  *
368  * These operators are defined to avoid ambiguous overload because of built-in
369  * operators.
370  *
371  * @param rightHand The right hand side of the addition.
372  * @return The SimValue with the result of the operation.
373  */
374 const SimValue
375 SimValue::operator+(const ULongWord& rightHand) {
376  SimValue copy(*this);
377  copy = uLongWordValue() + rightHand;
378  return copy;
379 }
380 
381 /**
382  * Explicit addition operator to HalfFloatWord type.
383  *
384  * These operators are defined to avoid ambiguous overload because of built-in
385  * operators.
386  *
387  * @param rightHand The right hand side of the addition.
388  * @return The SimValue with the result of the operation.
389  */
390 const SimValue
392  SimValue copy(*this);
393  copy = halfFloatWordValue() + rightHand;
394  return copy;
395 }
396 
397 /**
398  * Explicit addition operator to FloatWord type.
399  *
400  * These operators are defined to avoid ambiguous overload because of built-in
401  * operators.
402  *
403  * @param rightHand The right hand side of the addition.
404  * @return The SimValue with the result of the operation.
405  */
406 const SimValue
407 SimValue::operator+(const FloatWord& rightHand) {
408  SimValue copy(*this);
409  copy = floatWordValue() + rightHand;
410  return copy;
411 }
412 
413 /**
414  * Explicit addition operator to DoubleWord type.
415  *
416  * These operators are defined to avoid ambiguous overload because of built-in
417  * operators.
418  *
419  * @param rightHand The right hand side of the addition.
420  * @return The SimValue with the result of the operation.
421  */
422 const SimValue
423 SimValue::operator+(const DoubleWord& rightHand) {
424  SimValue copy(*this);
425  copy = doubleWordValue() + rightHand;
426  return copy;
427 }
428 
429 
430 /**
431  * Explicit subtraction operator to HalfFloatWord type.
432  *
433  * These operators are defined to avoid ambiguous overload because of built-in
434  * operators.
435  *
436  * @param rightHand The right hand side of the addition.
437  * @return The SimValue with the result of the operation.
438  */
439 const SimValue
441  SimValue copy(*this);
442  copy = halfFloatWordValue() - rightHand;
443  return copy;
444 }
445 
446 /**
447  * Explicit subtraction operator to SIntWord type.
448  *
449  * These operators are defined to avoid ambiguous overload because of built-in
450  * operators.
451  *
452  * @param rightHand The right hand side of the addition.
453  * @return The SimValue with the result of the operation.
454  */
455 const SimValue
456 SimValue::operator-(const SIntWord& rightHand) {
457  SimValue copy(*this);
458  copy = sIntWordValue() - rightHand;
459  return copy;
460 }
461 
462 /**
463  * Explicit subtraction operator to UIntWord type.
464  *
465  * These operators are defined to avoid ambiguous overload because of built-in
466  * operators.
467  *
468  * @param rightHand The right hand side of the addition.
469  * @return The SimValue with the result of the operation.
470  */
471 const SimValue
472 SimValue::operator-(const UIntWord& rightHand) {
473  SimValue copy(*this);
474  copy = uIntWordValue() - rightHand;
475  return copy;
476 }
477 
478 /**
479  * Explicit subtraction operator to SLongWord type.
480  *
481  * These operators are defined to avoid ambiguous overload because of built-in
482  * operators.
483  *
484  * @param rightHand The right hand side of the addition.
485  * @return The SimValue with the result of the operation.
486  */
487 const SimValue
488 SimValue::operator-(const SLongWord& rightHand) {
489  SimValue copy(*this);
490  copy = sLongWordValue() - rightHand;
491  return copy;
492 }
493 
494 /**
495  * Explicit subtraction operator to ULongWord type.
496  *
497  * These operators are defined to avoid ambiguous overload because of built-in
498  * operators.
499  *
500  * @param rightHand The right hand side of the addition.
501  * @return The SimValue with the result of the operation.
502  */
503 const SimValue
504 SimValue::operator-(const ULongWord& rightHand) {
505  SimValue copy(*this);
506  copy = uLongWordValue() - rightHand;
507  return copy;
508 }
509 
510 /**
511  * Explicit subtraction operator to FloatWord type.
512  *
513  * These operators are defined to avoid ambiguous overload because of built-in
514  * operators.
515  *
516  * @param rightHand The right hand side of the addition.
517  * @return The SimValue with the result of the operation.
518  */
519 const SimValue
520 SimValue::operator-(const FloatWord& rightHand) {
521  SimValue copy(*this);
522  copy = floatWordValue() - rightHand;
523  return copy;
524 }
525 
526 /**
527  * Explicit subtraction operator to DoubleWord type.
528  *
529  * These operators are defined to avoid ambiguous overload because of built-in
530  * operators.
531  *
532  * @param rightHand The right hand side of the addition.
533  * @return The SimValue with the result of the operation.
534  */
535 const SimValue
536 SimValue::operator-(const DoubleWord& rightHand) {
537  SimValue copy(*this);
538  copy = doubleWordValue() - rightHand;
539  return copy;
540 }
541 
542 /**
543  * Explicit division operator to HalfFloatWord type.
544  *
545  * These operators are defined to avoid ambiguous overload because of built-in
546  * operators.
547  *
548  * @param rightHand The right hand side of the addition.
549  * @return The SimValue with the result of the operation.
550  */
551 const SimValue
553  SimValue copy(*this);
554  copy = halfFloatWordValue() / rightHand;
555  return copy;
556 }
557 
558 /**
559  * Explicit division operator to SIntWord type.
560  *
561  * These operators are defined to avoid ambiguous overload because of built-in
562  * operators.
563  *
564  * @param rightHand The right hand side of the addition.
565  * @return The SimValue with the result of the operation.
566  */
567 const SimValue
568 SimValue::operator/(const SIntWord& rightHand) {
569  SimValue copy(*this);
570  copy = sIntWordValue() / rightHand;
571  return copy;
572 }
573 
574 /**
575  * Explicit division operator to UIntWord type.
576  *
577  * These operators are defined to avoid ambiguous overload because of built-in
578  * operators.
579  *
580  * @param rightHand The right hand side of the addition.
581  * @return The SimValue with the result of the operation.
582  */
583 const SimValue
584 SimValue::operator/(const UIntWord& rightHand) {
585  SimValue copy(*this);
586  copy = uIntWordValue() / rightHand;
587  return copy;
588 }
589 
590 /**
591  * Explicit division operator to SLongWord type.
592  *
593  * These operators are defined to avoid ambiguous overload because of built-in
594  * operators.
595  *
596  * @param rightHand The right hand side of the addition.
597  * @return The SimValue with the result of the operation.
598  */
599 const SimValue
600 SimValue::operator/(const SLongWord& rightHand) {
601  SimValue copy(*this);
602  copy = sLongWordValue() / rightHand;
603  return copy;
604 }
605 
606 /**
607  * Explicit division operator to UIntWord type.
608  *
609  * These operators are defined to avoid ambiguous overload because of built-in
610  * operators.
611  *
612  * @param rightHand The right hand side of the addition.
613  * @return The SimValue with the result of the operation.
614  */
615 const SimValue
616 SimValue::operator/(const ULongWord& rightHand) {
617  SimValue copy(*this);
618  copy = uLongWordValue() / rightHand;
619  return copy;
620 }
621 
622 /**
623  * Explicit division operator to FloatWord type.
624  *
625  * These operators are defined to avoid ambiguous overload because of built-in
626  * operators.
627  *
628  * @param rightHand The right hand side of the addition.
629  * @return The SimValue with the result of the operation.
630  */
631 const SimValue
632 SimValue::operator/(const FloatWord& rightHand) {
633  SimValue copy(*this);
634  copy = floatWordValue() / rightHand;
635  return copy;
636 }
637 
638 /**
639  * Explicit division operator to DoubleWord type.
640  *
641  * These operators are defined to avoid ambiguous overload because of built-in
642  * operators.
643  *
644  * @param rightHand The right hand side of the addition.
645  * @return The SimValue with the result of the operation.
646  */
647 const SimValue
648 SimValue::operator/(const DoubleWord& rightHand) {
649  SimValue copy(*this);
650  copy = doubleWordValue() / rightHand;
651  return copy;
652 }
653 
654 /**
655  * Explicit multiply operator to HalfFloatWord type.
656  *
657  * These operators are defined to avoid ambiguous overload because of built-in
658  * operators.
659  *
660  * @param rightHand The right hand side of the addition.
661  * @return The SimValue with the result of the operation.
662  */
663 const SimValue
665  SimValue copy(*this);
666  copy = halfFloatWordValue() * rightHand;
667  return copy;
668 }
669 
670 /**
671  * Explicit multiplication operator to SIntWord type.
672  *
673  * These operators are defined to avoid ambiguous overload because of built-in
674  * operators.
675  *
676  * @param rightHand The right hand side of the addition.
677  * @return The SimValue with the result of the operation.
678  */
679 const SimValue
680 SimValue::operator*(const SIntWord& rightHand) {
681  SimValue copy(*this);
682  copy = sIntWordValue() * rightHand;
683  return copy;
684 }
685 
686 /**
687  * Explicit multiplication operator to UIntWord type.
688  *
689  * These operators are defined to avoid ambiguous overload because of built-in
690  * operators.
691  *
692  * @param rightHand The right hand side of the addition.
693  * @return The SimValue with the result of the operation.
694  */
695 const SimValue
696 SimValue::operator*(const UIntWord& rightHand) {
697  SimValue copy(*this);
698  copy = uIntWordValue() * rightHand;
699  return copy;
700 }
701 
702 /**
703  * Explicit multiplication operator to SLongWord type.
704  *
705  * These operators are defined to avoid ambiguous overload because of built-in
706  * operators.
707  *
708  * @param rightHand The right hand side of the addition.
709  * @return The SimValue with the result of the operation.
710  */
711 const SimValue
712 SimValue::operator*(const SLongWord& rightHand) {
713  SimValue copy(*this);
714  copy = sLongWordValue() * rightHand;
715  return copy;
716 }
717 
718 /**
719  * Explicit multiplication operator to UIntWord type.
720  *
721  * These operators are defined to avoid ambiguous overload because of built-in
722  * operators.
723  *
724  * @param rightHand The right hand side of the addition.
725  * @return The SimValue with the result of the operation.
726  */
727 const SimValue
728 SimValue::operator*(const ULongWord& rightHand) {
729  SimValue copy(*this);
730  copy = uLongWordValue() * rightHand;
731  return copy;
732 }
733 
734 /**
735  * Explicit multiplication operator to FloatWord type.
736  *
737  * These operators are defined to avoid ambiguous overload because of built-in
738  * operators.
739  *
740  * @param rightHand The right hand side of the addition.
741  * @return The SimValue with the result of the operation.
742  */
743 const SimValue
744 SimValue::operator*(const FloatWord& rightHand) {
745  SimValue copy(*this);
746  copy = floatWordValue() * rightHand;
747  return copy;
748 }
749 
750 /**
751  * Explicit multiplication operator to DoubleWord type.
752  *
753  * These operators are defined to avoid ambiguous overload because of built-in
754  * operators.
755  *
756  * @param rightHand The right hand side of the addition.
757  * @return The SimValue with the result of the operation.
758  */
759 const SimValue
760 SimValue::operator*(const DoubleWord& rightHand) {
761  SimValue copy(*this);
762  copy = doubleWordValue() * rightHand;
763  return copy;
764 }
765 
766 /**
767  * Explicit equality operator for SimValue type.
768  *
769  * These operators are defined to avoid ambiguous overload because of built-in
770  * operators.
771  *
772  * @note This compares only the first value as a 32bit uintword, thus
773  * does not work for vectors that exceed that width.
774  *
775  * @param rightHand The right hand side of the comparison.
776  * @return Reference to itself.
777  *
778  */
779 int
780 SimValue::operator==(const SimValue& rightHand) const {
781  /// @todo Should this be changed to comparison between bytes from the
782  /// whole bitwidth?
783  return uIntWordValue() == rightHand.uIntWordValue();
784 }
785 
786 /**
787  * Explicit equality operator for SIntWord type.
788  *
789  * These operators are defined to avoid ambiguous overload because of built-in
790  * operators.
791  *
792  * @param rightHand The right hand side of the comparison.
793  * @return Reference to itself.
794  *
795  */
796 int
797 SimValue::operator==(const SIntWord& rightHand) const {
798  return sIntWordValue() == rightHand;
799 }
800 
801 /**
802  * Explicit equality operator for UIntWord type.
803  *
804  * These operators are defined to avoid ambiguous overload because of built-in
805  * operators.
806  *
807  * @param rightHand The right hand side of the comparison.
808  * @return Reference to itself.
809  *
810  */
811 int
812 SimValue::operator==(const UIntWord& rightHand) const {
813  return uIntWordValue() == rightHand;
814 }
815 
816 /**
817  * Explicit equality operator for SLongWord type.
818  *
819  * These operators are defined to avoid ambiguous overload because of built-in
820  * operators.
821  *
822  * @param rightHand The right hand side of the comparison.
823  * @return Reference to itself.
824  *
825  */
826 int
827 SimValue::operator==(const SLongWord& rightHand) const {
828  return sLongWordValue() == rightHand;
829 }
830 
831 /**
832  * Explicit equality operator for ULongWord type.
833  *
834  * These operators are defined to avoid ambiguous overload because of built-in
835  * operators.
836  *
837  * @param rightHand The right hand side of the comparison.
838  * @return Reference to itself.
839  *
840  */
841 int
842 SimValue::operator==(const ULongWord& rightHand) const {
843  return uLongWordValue() == rightHand;
844 }
845 
846 /**
847  * Explicit equality operator for HalfFloatWord type.
848  *
849  * These operators are defined to avoid ambiguous overload because of built-in
850  * operators.
851  *
852  * @param rightHand The right hand side of the comparison.
853  * @return Reference to itself.
854  *
855  */
856 int
857 SimValue::operator==(const HalfFloatWord& rightHand) const {
858  return halfFloatWordValue().getBinaryRep() == rightHand.getBinaryRep();
859 }
860 
861 /**
862  * Explicit equality operator for FloatWord type.
863  *
864  * These operators are defined to avoid ambiguous overload because of built-in
865  * operators.
866  *
867  * @param rightHand The right hand side of the comparison.
868  * @return Reference to itself.
869  *
870  */
871 int
872 SimValue::operator==(const FloatWord& rightHand) const {
873  return floatWordValue() == rightHand;
874 }
875 
876 /**
877  * Explicit equality operator for DoubleWord type.
878  *
879  * These operators are defined to avoid ambiguous overload because of built-in
880  * operators.
881  *
882  * @param rightHand The right hand side of the comparison.
883  * @return Reference to itself.
884  *
885  */
886 int
887 SimValue::operator==(const DoubleWord& rightHand) const {
888  return doubleWordValue() == rightHand;
889 }
890 
891 /**
892  * Returns SimValue as a sign extended host integer.
893  */
894 int
896 
897  const size_t BYTE_COUNT = sizeof(int);
898 
899  union CastUnion {
900  Byte bytes[BYTE_COUNT];
901  int value;
902  };
903 
904  CastUnion cast;
905 
906 #if HOST_BIGENDIAN == 1
907  swapByteOrder(rawData_ , BYTE_COUNT, cast.bytes);
908 #else
909  memcpy(cast.bytes, rawData_, BYTE_COUNT);
910 #endif
911  int bitWidth = (bitWidth_ > 32) ? 32 : bitWidth_;
912  return MathTools::fastSignExtendTo(cast.value, bitWidth);
913 }
914 
915 /**
916  * Returns SimValue as a zero extended unsigned host integer.
917  */
918 unsigned int
920 
921  const size_t BYTE_COUNT = sizeof(unsigned int);
922 
923  union CastUnion {
924  Byte bytes[BYTE_COUNT];
925  unsigned int value;
926  };
927 
928  CastUnion cast;
929 
930 #if HOST_BIGENDIAN == 1
931  swapByteOrder(rawData_, BYTE_COUNT, cast.bytes);
932 #else
933  memcpy(cast.bytes, rawData_, BYTE_COUNT);
934 #endif
935 
936  int bitWidth = (bitWidth_ > 32) ? 32 : bitWidth_;
937  return MathTools::fastZeroExtendTo(cast.value, bitWidth);
938 }
939 
940 /**
941  * Returns the SimValue as SIntWord value.
942  */
943 SIntWord
945 
946  const size_t BYTE_COUNT = sizeof(SIntWord);
947 
948  union CastUnion {
949  Byte bytes[BYTE_COUNT];
950  SIntWord value;
951  };
952 
953  CastUnion cast;
954 
955 #if HOST_BIGENDIAN == 1
956  swapByteOrder(rawData_, BYTE_COUNT, cast.bytes);
957 #else
958  memcpy(cast.bytes, rawData_, BYTE_COUNT);
959 #endif
960 
961  if ((unsigned)bitWidth_ >= sizeof(SIntWord) * BYTE_BITWIDTH) {
962  return cast.value;
963  } else {
964  return MathTools::fastSignExtendTo(cast.value, bitWidth_);
965  }
966 }
967 
968 /**
969  * Returns the SimValue as host endian UIntWord value.
970  */
971 UIntWord
973 
974  const size_t BYTE_COUNT = sizeof(UIntWord);
975 
976  union CastUnion {
977  Byte bytes[BYTE_COUNT];
978  UIntWord value;
979  };
980 
981  CastUnion cast;
982 
983 #if HOST_BIGENDIAN == 1
984  swapByteOrder(rawData_, BYTE_COUNT, cast.bytes);
985 #else
986  memcpy(cast.bytes, rawData_, BYTE_COUNT);
987 #endif
988  return cast.value & mask_;
989 }
990 
991 /**
992  * Returns the SimValue as SIntWord value.
993  *
994  * @return SIntWord value.
995  */
996 SLongWord
998 
999  const size_t BYTE_COUNT = sizeof(SLongWord);
1000 
1001  union CastUnion {
1002  Byte bytes[BYTE_COUNT];
1003  SLongWord value;
1004  };
1005 
1006  CastUnion cast;
1007 
1008 #if HOST_BIGENDIAN == 1
1009  swapByteOrder(rawData_, BYTE_COUNT, cast.bytes);
1010 #else
1011  memcpy(cast.bytes, rawData_, BYTE_COUNT);
1012 #endif
1013 
1014  if ((unsigned)bitWidth_ >= sizeof(SLongWord) * BYTE_BITWIDTH) {
1015  return cast.value;
1016  } else {
1017  return MathTools::fastSignExtendTo(cast.value, bitWidth_);
1018  }
1019 }
1020 
1021 /**
1022  * Returns the SimValue as an ULongWord.
1023  *
1024  * @return UIntWord value.
1025  */
1026 ULongWord
1028 
1029  const size_t BYTE_COUNT = sizeof(ULongWord);
1030 
1031  union CastUnion {
1032  Byte bytes[BYTE_COUNT];
1033  ULongWord value;
1034  };
1035 
1036  CastUnion cast;
1037 
1038 #if HOST_BIGENDIAN == 1
1039  swapByteOrder(rawData_, BYTE_COUNT, cast.bytes);
1040 #else
1041  memcpy(cast.bytes, rawData_, BYTE_COUNT);
1042 #endif
1043  return cast.value & mask_;
1044 }
1045 
1046 /**
1047  * Returns the SimValue as a host endian DoubleWord value.
1048  *
1049  * @return DoubleWord value.
1050  */
1051 DoubleWord
1053 
1054  const size_t BYTE_COUNT = sizeof(DoubleWord);
1055 
1056  union CastUnion {
1057  Byte bytes[BYTE_COUNT];
1058  DoubleWord value;
1059  };
1060 
1061  CastUnion cast;
1062 
1063 #if HOST_BIGENDIAN == 1
1064  swapByteOrder(rawData_, BYTE_COUNT, cast.bytes);
1065 #else
1066  memcpy(cast.bytes, rawData_, BYTE_COUNT);
1067 #endif
1068  return cast.value;
1069 }
1070 
1071 /**
1072  * Returns the SimValue as a host endian FloatWord value.
1073  */
1074 FloatWord
1076 
1077  const size_t BYTE_COUNT = sizeof(FloatWord);
1078 
1079  union CastUnion {
1080  Byte bytes[BYTE_COUNT];
1081  FloatWord value;
1082  };
1083 
1084  CastUnion cast;
1085 
1086 #if HOST_BIGENDIAN == 1
1087  swapByteOrder(rawData_, BYTE_COUNT, cast.bytes);
1088 #else
1089  memcpy(cast.bytes, rawData_, BYTE_COUNT);
1090 #endif
1091  return cast.value;
1092 }
1093 
1094 /**
1095  * Returns the SimValue as a host endian HalfFloatWord value.
1096  */
1099 
1100  const size_t BYTE_COUNT = sizeof(uint16_t);
1101 
1102  union CastUnion {
1103  Byte bytes[BYTE_COUNT];
1104  uint16_t value;
1105  };
1106 
1107  CastUnion cast;
1108 
1109 #if HOST_BIGENDIAN == 1
1110  swapByteOrder(rawData_, BYTE_COUNT, cast.bytes);
1111 #else
1112  memcpy(cast.bytes, rawData_, BYTE_COUNT);
1113 #endif
1114  return HalfFloatWord(cast.value);
1115 }
1116 
1117 /**
1118  * Returns the value as a 2's complement (MSB left) binary string in ascii.
1119  */
1120 TCEString
1122 
1123  const size_t BYTE_COUNT = bitWidth_ / BYTE_BITWIDTH;
1124 
1125  int remainBits = bitWidth_ % BYTE_BITWIDTH;
1126  TCEString binaryStr = "";
1127 
1128  if (remainBits > 0) {
1129  binaryStr += Conversion::toBinary(
1130  static_cast<unsigned int>(rawData_[BYTE_COUNT]),
1131  remainBits);
1132  }
1133 
1134  for (int i = BYTE_COUNT - 1; i >= 0; --i) {
1135  binaryStr += Conversion::toBinary(
1136  static_cast<unsigned int>(rawData_[i]), 8);
1137  }
1138 
1139  return binaryStr;
1140 }
1141 
1142 /**
1143  * Returns the value as a big endian ordered (C-literal style) hex
1144  * ascii string.
1145  *
1146  * @param noHexIdentifier Leaves "0x" prefix out if set to true.
1147  * @return SimValue bytes in hex format.
1148  */
1149 TCEString
1150 SimValue::hexValue(bool noHexIdentifier) const {
1151  size_t hexNumbers = (bitWidth_ + 3) / 4;
1152  if (bitWidth_ <= 32) {
1153  if (noHexIdentifier) {
1154  return Conversion::toHexString(
1155  uIntWordValue(), hexNumbers).substr(2);
1156  } else {
1157  // TODO: what about SIMD? this only prints one word?
1158  return Conversion::toHexString(uLongWordValue(), hexNumbers);
1159  }
1160  }
1161 
1162  const size_t BYTE_COUNT =
1164  const unsigned MSB_MASK = ~(0xfffffffffffffffful << (8-(BYTE_COUNT*8-bitWidth_)));
1165 
1166  TCEString hexStr;
1167  // Convert the raw data buffer to hex string values one byte at a time.
1168  // Also, remove "0x" from the front of the hex string for each hex value.
1169  for (int i = BYTE_COUNT - 1; i >= 0; --i) {
1170  unsigned int value = static_cast<unsigned int>(rawData_[i]);
1171  if (i == static_cast<int>(BYTE_COUNT - 1)) {
1172  value &= MSB_MASK;
1173  }
1174  hexStr += Conversion::toHexString(value, 2).substr(2);
1175  }
1176 
1177  // Remove extraneous zero digit from the front.
1178  hexStr = hexStr.substr(hexStr.size() - hexNumbers);
1179 
1180  if (!noHexIdentifier) hexStr.insert(0, "0x");
1181 
1182  return hexStr;
1183 }
1184 
1185 template <typename T>
1186 T
1187 SimValue::vectorElement(size_t elementIndex) const {
1188  const size_t BYTE_COUNT = sizeof(T);
1189  const size_t OFFSET = elementIndex * BYTE_COUNT;
1190 
1191  // Element index must not cross SimValue's bitwidth.
1192  assert((elementIndex+1) <= (SIMVALUE_MAX_BYTE_SIZE / BYTE_COUNT));
1193 
1194  union CastUnion {
1195  Byte bytes[sizeof(T)];
1196  T value;
1197  };
1198 
1199  CastUnion cast;
1200 
1201 #if HOST_BIGENDIAN == 1
1202  swapByteOrder(rawData_ + OFFSET, BYTE_COUNT, cast.bytes);
1203 #else
1204  memcpy(cast.bytes, rawData_ + OFFSET, BYTE_COUNT);
1205 #endif
1206  return cast.value;
1207 }
1208 
1209 /**
1210  * Returns the desired 32-bit word element in host endianness.
1211  *
1212  * The element ordering of SimValue storage is always the memory order,
1213  * first vector elements in the first locations.
1214  *
1215  * @param elementIndex Index of the element (from 0 upwards).
1216  * @return Word element.
1217  */
1218 Word
1219 SimValue::wordElement(size_t elementIndex) const {
1220  return vectorElement<Word>(elementIndex);
1221 }
1222 
1223 /**
1224  * Returns desired element at given index as signed integer.
1225  */
1226 SIntWord
1227 SimValue::sIntWordElement(size_t elementIndex) const {
1228  union CastUnion {
1229  Word uWord;
1230  SIntWord sWord;
1231  } cast;
1232  cast.uWord = wordElement(elementIndex);
1233  return cast.sWord;
1234 }
1235 
1236 /**
1237  * Returns desired element at given index as unsigned integer.
1238  */
1239 UIntWord
1240 SimValue::uIntWordElement(size_t elementIndex) const {
1241  return wordElement(elementIndex);
1242 }
1243 
1244 
1245 /**
1246  * Returns desired 16-bit short integer word element in host endianness.
1247  */
1248 HalfWord
1249 SimValue::halfWordElement(size_t elementIndex) const {
1250  return vectorElement<HalfWord>(elementIndex);
1251 }
1252 
1254 SimValue::halfFloatElement(size_t elementIndex) const {
1255  // Uses the same implementation as the integer version as
1256  // there is no native 'half' in C/C++.
1257  return HalfFloatWord(vectorElement<HalfWord>(elementIndex));
1258 }
1259 
1260 FloatWord
1261 SimValue::floatElement(size_t elementIndex) const {
1262  return vectorElement<FloatWord>(elementIndex);
1263 }
1264 
1266 SimValue::doubleFloatElement(size_t elementIndex) const {
1267  return vectorElement<DoubleWord>(elementIndex);
1268 }
1269 
1270 /**
1271  * Returns desired 8-bit byte element.
1272  */
1273 Byte
1274 SimValue::byteElement(size_t elementIndex) const {
1275  const size_t BYTE_COUNT = sizeof(Byte);
1276  const size_t OFFSET = elementIndex * BYTE_COUNT;
1277 
1278  // Element index must not cross SimValue's bitwidth.
1279  assert((elementIndex+1) <= (SIMVALUE_MAX_BYTE_SIZE / BYTE_COUNT));
1280 
1281  return rawData_[OFFSET];
1282 }
1283 
1284 /**
1285  * Returns desired 1-bit bit element.
1286  */
1287 UIntWord
1288 SimValue::bitElement(size_t elementIndex) const {
1289  // Element index must not cross SimValue's bitwidth.
1290  assert((elementIndex+1) <= SIMD_WORD_WIDTH);
1291 
1292  const size_t OFFSET = elementIndex / BYTE_BITWIDTH;
1293  const size_t LEFT_SHIFTS = elementIndex % BYTE_BITWIDTH;
1294 
1295  Byte data = rawData_[OFFSET];
1296 
1297  if (data & (1 << LEFT_SHIFTS)) {
1298  return 1;
1299  } else {
1300  return 0;
1301  }
1302 }
1303 
1304 /**
1305  * Get element function for arbitrary element width.
1306  *
1307  * Values by width are stored in power of 2 byte boundaries (1, 2 or 4).
1308  * elementWidth must be in range of (0, 32].
1309  */
1310 Word
1311 SimValue::element(size_t elementIndex, size_t elementWidth) const {
1312  // TODO: support 64-bit elements!
1313 
1314  assert(elementWidth != 0);
1315  assert(elementWidth <= 32);
1316 
1317  if (elementWidth == 1) {
1318  return bitElement(elementIndex);
1319  } else {
1320  const size_t BYTE_COUNT = elementWidth >= 8u ?
1321  MathTools::roundUpToPowerTwo((unsigned int)elementWidth)/8 : 1;
1322  const size_t OFFSET = elementIndex * BYTE_COUNT;
1323  const Word BITMASK =
1324  elementWidth < 32 ? ~(~Word(0) << elementWidth) : ~(Word(0));
1325  Word tmp;
1326 
1327 #if HOST_BIGENDIAN == 1
1328  swapByteOrder(rawData_ + OFFSET, BYTE_COUNT, &tmp);
1329 #else
1330  memcpy(&tmp, rawData_ + OFFSET, BYTE_COUNT);
1331 #endif
1332  tmp &= BITMASK;
1333  return tmp;
1334  }
1335 }
1336 
1337 template <typename T>
1338 void
1339 SimValue::setVectorElement(size_t elementIndex, T data) {
1340  const size_t BYTE_COUNT = sizeof(T);
1341  const size_t OFFSET = elementIndex * BYTE_COUNT;
1342 
1343  // Element index must not cross SimValue's bitwidth.
1344  assert((elementIndex+1) <= (SIMVALUE_MAX_BYTE_SIZE / BYTE_COUNT));
1345 
1346 #if HOST_BIGENDIAN == 1
1347  swapByteOrder((Byte*)&data, BYTE_COUNT, rawData_ + OFFSET);
1348 #else
1349  memcpy(rawData_ + OFFSET, &data, BYTE_COUNT);
1350 #endif
1351 }
1352 
1353 void
1354 SimValue::setWordElement(size_t elementIndex, Word data) {
1355  setVectorElement(elementIndex, data);
1356 }
1357 
1358 /**
1359  * Sets half word (a.k.a. short 16-bit integer) element at a certain index to
1360  * given value.
1361  *
1362  * @param elementIndex Half word element index.
1363  * @param data Half word element data.
1364  */
1365 void
1366 SimValue::setHalfWordElement(size_t elementIndex, HalfWord data) {
1367  setVectorElement(elementIndex, data);
1368 }
1369 
1370 void
1371 SimValue::setHalfFloatElement(size_t elementIndex, HalfFloatWord data) {
1372  setVectorElement(elementIndex, data);
1373 }
1374 
1375 void
1376 SimValue::setFloatElement(size_t elementIndex, FloatWord data) {
1377  setVectorElement(elementIndex, data);
1378 }
1379 
1380 void
1382  setVectorElement(elementIndex, data);
1383 }
1384 
1385 void
1386 SimValue::setByteElement(size_t elementIndex, Byte data) {
1387  setVectorElement(elementIndex, data);
1388 }
1389 
1390 /**
1391  * Sets bit element at a certain index to given value.
1392  *
1393  * @param elementIndex Bit element index.
1394  * @param data Bit element data.
1395  */
1396 void
1397 SimValue::setBitElement(size_t elementIndex, UIntWord data) {
1398  // Element index must not cross SimValue's bitwidth.
1399  assert((elementIndex+1) <= SIMD_WORD_WIDTH);
1400 
1401  const size_t OFFSET = elementIndex / BYTE_BITWIDTH;
1402  const size_t LEFT_SHIFTS = elementIndex % BYTE_BITWIDTH;
1403 
1404  Byte byte = rawData_[OFFSET];
1405 
1406  if (data == 0) {
1407  byte = byte & (~(1 << LEFT_SHIFTS));
1408  } else {
1409  byte = byte | (1 << LEFT_SHIFTS);
1410  }
1411 
1412  rawData_[OFFSET] = byte;
1413 }
1414 
1415 /**
1416  * Set element function for arbitrary element width.
1417  *
1418  * Values by width are stored in power of 2 byte boundaries (1, 2 or 4).
1419  * elementWidth must be in range of (0, 32].
1420  */
1421 void
1422 SimValue::setElement(size_t elementIndex, size_t elementWidth, Word data) {
1423  assert(elementWidth != 0);
1424  if (elementWidth == 1) {
1425  setBitElement(elementIndex, data);
1426  } else {
1427  const size_t BYTE_COUNT =
1428  elementWidth >= 8u ?
1429  MathTools::roundUpToPowerTwo((unsigned int)elementWidth)/8 : 1;
1430  const size_t OFFSET = elementIndex * BYTE_COUNT;
1431 
1432  // Element index must not cross SimValue's bitwidth.
1433  assert((elementIndex+1) <= (SIMVALUE_MAX_BYTE_SIZE / BYTE_COUNT));
1434  // Cut excess bits from data
1435  Word BITMASK = ~Word(0);
1436  if (elementWidth < sizeof(Word)*8) {
1437  BITMASK = ~(~Word(0) << elementWidth);
1438  }
1439 
1440  Word tmp_data = data & BITMASK;
1441 #if HOST_BIGENDIAN == 1
1442  swapByteOrder((Byte*)&tmp_data, BYTE_COUNT, rawData_ + OFFSET);
1443 #else
1444  memcpy(rawData_ + OFFSET, &tmp_data, BYTE_COUNT);
1445 #endif
1446  }
1447 }
1448 
1449 /**
1450  * Sets SimValue to correspond the hex value.
1451  *
1452  * Given hex string must be in big-endian order when it is given. For
1453  * instance, if the user wants to set integer value 5 through this function,
1454  * the function should be called "setValue("0x00000005");". Add leading
1455  * zeroes if you want to clear bytes before the byte that has value 5.
1456  *
1457  * @param hexValue New value in hex format.
1458  */
1459 void
1461  if (hexValue.size() > 2 && hexValue[0] == '0' && hexValue[1] == 'x') {
1462  hexValue = hexValue.substr(2); // Remove "0x."
1463  }
1464 
1465  const size_t VALUE_BITWIDTH = hexValue.size() * 4;
1466 
1467  // stretch the SimValue to the hex value bit width in case
1468  // this is an initialization
1469  if (bitWidth_ == 0) bitWidth_ = VALUE_BITWIDTH;
1470 
1471  size_t paddingBytes = 0;
1472  // Check the hex string value is legal.
1473  if (VALUE_BITWIDTH > SIMD_WORD_WIDTH) {
1474  throw NumberFormatException(
1475  __FILE__, __LINE__, __func__, "Too wide value.");
1476  } else if (VALUE_BITWIDTH == 0) {
1477  throw NumberFormatException(
1478  __FILE__, __LINE__, __func__, "Input value is empty.");
1479  } else if (VALUE_BITWIDTH > (size_t)bitWidth_) {
1480  // Add padding zero bytes in case the hexValue defines less
1481  // bytes than the width of the value.
1482  paddingBytes = (VALUE_BITWIDTH - bitWidth_) / 8;
1483  for (size_t i = 0; i < paddingBytes; ++i)
1484  rawData_[VALUE_BITWIDTH / 8 + i] = 0;
1485  }
1486  Byte bigEndianData[SIMVALUE_MAX_BYTE_SIZE];
1487  Conversion::toRawData(hexValue, bigEndianData);
1488 
1489  // because the hexValues are 4bits each they might not fill exact
1490  // bytes, thus we need to round up to consume an extra byte for
1491  // remaining 4bits
1492  int byteWidth = VALUE_BITWIDTH / 8;
1493  if (VALUE_BITWIDTH % 8 != 0) ++byteWidth;
1494 
1495  swapByteOrder(bigEndianData, byteWidth, rawData_);
1496 }
1497 
1498 /**
1499  * Sets SimValue bytes to 0 for the given bitwidth.
1500  *
1501  * @param bitWidth The width that is to be nullified.
1502  */
1503 void
1504 SimValue::clearToZero(int bitWidth) {
1505  assert(bitWidth <= SIMD_WORD_WIDTH);
1506 
1507  const size_t BYTE_COUNT = (bitWidth + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH;
1508 
1509  memset(rawData_, 0, BYTE_COUNT);
1510 }
1511 
1512 /**
1513  * Sets all SimValue bytes to 0.
1514  */
1515 void
1518 }
1519 
1520 /**
1521  * Overwrites all bits that do not fit in the given bit width with the sign
1522  * bit (the bit at position width - 1).
1523  *
1524  * This operation corresponds to reinterpreting the value as a signed
1525  * word of given bit width.
1526  *
1527  * @param bitWidth Number of meaningful bits in the given integer.
1528  * @exception OutOfRange If width > value size
1529  */
1530 void
1531 SimValue::signExtendTo(int bitWidth) {
1532  if (bitWidth > SIMD_WORD_WIDTH) {
1533  throw OutOfRange(__FILE__, __LINE__, __func__);
1534  }
1535 
1536  if (bitWidth <= 0) {
1537  clearToZero();
1538  return;
1539  }
1540 
1541  const size_t FIRST_BYTE = (bitWidth + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH;
1542  const size_t BYTE_COUNT = (bitWidth_ + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH;
1543 
1544  rawData_[FIRST_BYTE-1] = MathTools::fastSignExtendTo(
1545  static_cast<int>(rawData_[FIRST_BYTE-1]),
1546  ((bitWidth-1)%BYTE_BITWIDTH)+1);
1547 
1548  if (BYTE_COUNT > FIRST_BYTE) { // Fill remaining bytes with sign bit
1549  if (bitElement(bitWidth-1) == 0) {
1550  memset(rawData_+FIRST_BYTE, 0, BYTE_COUNT-FIRST_BYTE);
1551  } else {
1552  memset(rawData_+FIRST_BYTE, -1, BYTE_COUNT-FIRST_BYTE);
1553  }
1554  }
1555 }
1556 
1557 /**
1558  * Overwrites all bits that do not fit in the given bit width with 0
1559  *
1560  * This operation corresponds to reinterpreting the value as an unsigned
1561  * word of given bit width.
1562  *
1563  * @param bitWidth Number of meaningful bits in the given integer.
1564  * @exception OutOfRange If width > value size
1565  */
1566 void
1567 SimValue::zeroExtendTo(int bitWidth) {
1568  if (bitWidth > SIMD_WORD_WIDTH) {
1569  throw OutOfRange(__FILE__, __LINE__, __func__);
1570  }
1571 
1572  if (bitWidth <= 0) {
1573  clearToZero();
1574  return;
1575  }
1576 
1577  const size_t FIRST_BYTE = (bitWidth + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH;
1578  const size_t BYTE_COUNT = (bitWidth_ + (BYTE_BITWIDTH - 1)) / BYTE_BITWIDTH;
1579 
1580  rawData_[FIRST_BYTE-1] = MathTools::fastZeroExtendTo(
1581  static_cast<int>(rawData_[FIRST_BYTE-1]),
1582  ((bitWidth-1)%BYTE_BITWIDTH)+1);
1583 
1584  if (BYTE_COUNT > FIRST_BYTE) { // Fill remaining bytes with 0
1585  memset(rawData_+FIRST_BYTE, 0, BYTE_COUNT-FIRST_BYTE);
1586  }
1587 }
1588 
1589 /**
1590  * Dumps raw data encoded in the SimValue in hexadecimal format.
1591  */
1592 TCEString
1594  TCEString result = "width=";
1595  result += Conversion::toString(width());
1596  result += " mask=";
1597  result += Conversion::toBinary(mask_, 64);
1598  result += " data=0x";
1599 
1600  // Convert the raw data buffer to hex string values one byte at a time.
1601  // Also, remove "0x" from the front of the hex string for each hex value.
1602  for (int i = SIMVALUE_MAX_BYTE_SIZE - 1; i >= 0; --i) {
1603  unsigned int value =
1604  static_cast<unsigned int>(rawData_[i]);
1605  result += Conversion::toHexString(value, 2).substr(2);
1606  }
1607 
1608  return result;
1609 }
1610 
1611 /**
1612  * Copies the byte order from source array in opposite order to target array.
1613  *
1614  * @note Caller is responsible for making sure both input pointers have
1615  * enough allocated memory.
1616  * @param from Array from which the bytes are copied.
1617  * @param byteCount How many bytes are copied.
1618  * @param to Array to which the bytes are copied in opposite order.
1619  */
1620 void
1622  const Byte* from, size_t byteCount, Byte* to) const {
1623 
1624  assert (from != to);
1625  for (size_t i = 0; i < byteCount; ++i) {
1626  to[byteCount - 1 - i] = from[i];
1627  }
1628 }
1629 
1630 //////////////////////////////////////////////////////////////////////////////
1631 // NullSimValue
1632 //////////////////////////////////////////////////////////////////////////////
1633 
1635 
1636 /**
1637  * Returns an instance of NullSimValue class (singleton).
1638  *
1639  * @return Singleton instance of NullSimValue class.
1640  */
1641 SimValue&
1643  return instance_;
1644 }
SimValue::sIntWordElement
SIntWord sIntWordElement(size_t elementIndex) const
Definition: SimValue.cc:1227
SimValue::setElement
void setElement(size_t elementIndex, size_t elementWidth, Word data)
Definition: SimValue.cc:1422
SimValue::intValue
int intValue() const
Definition: SimValue.cc:895
UIntWord
Word UIntWord
Definition: BaseType.hh:144
SimValue::setBitWidth
void setBitWidth(int width)
Definition: SimValue.cc:113
SimValue::element
Word element(size_t elementIndex, size_t elementWidth) const
Definition: SimValue.cc:1311
NumberFormatException
Definition: Exception.hh:421
SimValue::doubleWordValue
DoubleWord doubleWordValue() const
Definition: SimValue.cc:1052
SimValue::sLongWordValue
SLongWord sLongWordValue() const
Definition: SimValue.cc:997
SimValue::DoubleFloatWord
DoubleWord DoubleFloatWord
Definition: SimValue.hh:99
SimValue::SimValue
SimValue()
Definition: SimValue.cc:47
Exception.hh
SimValue::setFloatElement
void setFloatElement(size_t elementIndex, FloatWord data)
Definition: SimValue.cc:1376
SimValue::bitElement
UIntWord bitElement(size_t elementIndex) const
Definition: SimValue.cc:1288
SimValue::operator/
const SimValue operator/(const SIntWord &rightHand)
Definition: SimValue.cc:568
SimValue::setWordElement
void setWordElement(size_t elementIndex, Word data)
Definition: SimValue.cc:1354
OutOfRange
Definition: Exception.hh:320
NullSimValue::instance
static SimValue & instance()
Definition: SimValue.cc:1642
SimValue::setVectorElement
void setVectorElement(size_t elementIndex, T data)
Definition: SimValue.cc:1339
SimValue::floatElement
FloatWord floatElement(size_t elementIndex) const
Definition: SimValue.cc:1261
SimValue::operator=
SimValue & operator=(const SIntWord &source)
Definition: SimValue.cc:138
HalfFloatWord
Definition: HalfFloatWord.hh:41
MathTools::fastSignExtendTo
static SLongWord fastSignExtendTo(SLongWord value, int width)
Byte
unsigned char Byte
Definition: BaseType.hh:116
SimValue::uIntWordValue
UIntWord uIntWordValue() const
Definition: SimValue.cc:972
SimValue::wordElement
Word wordElement(size_t elementIndex) const
Definition: SimValue.cc:1219
Conversion::toString
static std::string toString(const T &source)
SimValue::vectorElement
T vectorElement(size_t elementIndex) const
Definition: SimValue.cc:1187
SimValue
Definition: SimValue.hh:96
TCEString.hh
assert
#define assert(condition)
Definition: Application.hh:86
Conversion::toBinary
static std::string toBinary(unsigned int source, unsigned int stringWidth=0)
Definition: Conversion.cc:155
SimValue::zeroExtendTo
void zeroExtendTo(int bitWidth)
Definition: SimValue.cc:1567
SIMVALUE_MAX_BYTE_SIZE
#define SIMVALUE_MAX_BYTE_SIZE
Definition: SimValue.hh:43
SimValue::dump
TCEString dump() const
Definition: SimValue.cc:1593
HalfFloatWord::getBinaryRep
uint16_t getBinaryRep() const
Definition: HalfFloatWord.hh:60
SimValue::rawData_
Byte rawData_[SIMVALUE_MAX_BYTE_SIZE]
Array that contains SimValue's underlaying bytes in little endian.
Definition: SimValue.hh:202
MathTools::fastZeroExtendTo
static ULongWord fastZeroExtendTo(ULongWord value, int width)
Conversion.hh
NullSimValue::instance_
static SimValue instance_
Definition: SimValue.hh:244
SimValue::mask_
ULongWord mask_
Mask for masking extra bits when returning unsigned value.
Definition: SimValue.hh:223
SimValue::swapByteOrder
void swapByteOrder(const Byte *from, size_t byteCount, Byte *to) const
Definition: SimValue.cc:1621
FloatWord
float FloatWord
Definition: BaseType.hh:160
SimValue::floatWordValue
FloatWord floatWordValue() const
Definition: SimValue.cc:1075
__func__
#define __func__
Definition: Application.hh:67
SimValue::setHalfFloatElement
void setHalfFloatElement(size_t elementIndex, HalfFloatWord data)
Definition: SimValue.cc:1371
SimValue::setBitElement
void setBitElement(size_t elementIndex, UIntWord data)
Definition: SimValue.cc:1397
SimValue::uLongWordValue
ULongWord uLongWordValue() const
Definition: SimValue.cc:1027
SIntWord
SignedWord SIntWord
Definition: BaseType.hh:149
SimValue::clearToZero
void clearToZero()
Definition: SimValue.cc:1516
SimValue::setDoubleFloatElement
void setDoubleFloatElement(size_t elementIndex, DoubleFloatWord data)
Definition: SimValue.cc:1381
SimValue::uIntWordElement
UIntWord uIntWordElement(size_t elementIndex) const
Definition: SimValue.cc:1240
DoubleWord
double DoubleWord
Definition: BaseType.hh:166
SimValue::byteElement
Byte byteElement(size_t elementIndex) const
Definition: SimValue.cc:1274
SimValue::operator*
const SimValue operator*(const SIntWord &rightHand)
Definition: SimValue.cc:680
SimValue::operator==
int operator==(const SimValue &rightHand) const
Definition: SimValue.cc:780
SimValue::setHalfWordElement
void setHalfWordElement(size_t elementIndex, HalfWord data)
Definition: SimValue.cc:1366
Conversion::toRawData
static void toRawData(const std::string &hexSource, unsigned char *target)
Definition: Conversion.cc:201
SimValue::doubleFloatElement
DoubleFloatWord doubleFloatElement(size_t elementIndex) const
Definition: SimValue.cc:1266
Conversion::toHexString
static std::string toHexString(T source, std::size_t digits=0, bool include0x=true)
SimValue::hexValue
TCEString hexValue(bool noHexIdentifier=false) const
Definition: SimValue.cc:1150
SimValue::operator+
const SimValue operator+(const SIntWord &rightHand)
Definition: SimValue.cc:327
SimValue::unsignedValue
unsigned int unsignedValue() const
Definition: SimValue.cc:919
SimValue::sIntWordValue
SIntWord sIntWordValue() const
Definition: SimValue.cc:944
SimValue::signExtendTo
void signExtendTo(int bitWidth)
Definition: SimValue.cc:1531
SimValue::width
int width() const
Definition: SimValue.cc:103
BYTE_BITWIDTH
const Byte BYTE_BITWIDTH
Definition: BaseType.hh:136
SimValue::halfWordElement
HalfWord halfWordElement(size_t elementIndex) const
Definition: SimValue.cc:1249
SimValue::binaryValue
TCEString binaryValue() const
Definition: SimValue.cc:1121
SimValue.hh
TCEString
Definition: TCEString.hh:53
SIMULATOR_MAX_LONGWORD_BITWIDTH
#define SIMULATOR_MAX_LONGWORD_BITWIDTH
Definition: SimValue.hh:249
ULongWord
unsigned long ULongWord
Definition: BaseType.hh:51
MathTools::roundUpToPowerTwo
static unsigned int roundUpToPowerTwo(unsigned int number)
MathTools.hh
SimValue::setValue
void setValue(TCEString hexValue)
Definition: SimValue.cc:1460
SimValue::setByteElement
void setByteElement(size_t elementIndex, Byte data)
Definition: SimValue.cc:1386
SimValue::bitWidth_
int bitWidth_
The bitwidth of the value.
Definition: SimValue.hh:205
SimValue::operator-
const SimValue operator-(const SIntWord &rightHand)
Definition: SimValue.cc:456
SIMD_WORD_WIDTH
#define SIMD_WORD_WIDTH
Definition: SimValue.hh:42
SLongWord
long SLongWord
Definition: BaseType.hh:52
SimValue::halfFloatWordValue
HalfFloatWord halfFloatWordValue() const
Definition: SimValue.cc:1098
SimValue::halfFloatElement
HalfFloatWord halfFloatElement(size_t elementIndex) const
Definition: SimValue.cc:1254
SimValue::deepCopy
void deepCopy(const SimValue &source)
Definition: SimValue.cc:307