1 //===-- RegisterValue.cpp -------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Utility/RegisterValue.h"
10 
11 #include "lldb/Utility/DataExtractor.h"
12 #include "lldb/Utility/Scalar.h"
13 #include "lldb/Utility/Status.h"
14 #include "lldb/Utility/Stream.h"
15 #include "lldb/Utility/StreamString.h"
16 #include "lldb/lldb-defines.h"
17 #include "lldb/lldb-private-types.h"
18 
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringRef.h"
21 
22 #include <cstdint>
23 #include <string>
24 #include <tuple>
25 #include <vector>
26 
27 #include <assert.h>
28 #include <inttypes.h>
29 #include <stdio.h>
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 bool RegisterValue::GetData(DataExtractor &data) const {
35   return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
36 }
37 
38 uint32_t RegisterValue::GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
39                                         uint32_t dst_len,
40                                         lldb::ByteOrder dst_byte_order,
41                                         Status &error) const {
42   if (reg_info == nullptr) {
43     error.SetErrorString("invalid register info argument.");
44     return 0;
45   }
46 
47   // ReadRegister should have already been called on this object prior to
48   // calling this.
49   if (GetType() == eTypeInvalid) {
50     // No value has been read into this object...
51     error.SetErrorStringWithFormat(
52         "invalid register value type for register %s", reg_info->name);
53     return 0;
54   }
55 
56   if (dst_len > kMaxRegisterByteSize) {
57     error.SetErrorString("destination is too big");
58     return 0;
59   }
60 
61   const uint32_t src_len = reg_info->byte_size;
62 
63   // Extract the register data into a data extractor
64   DataExtractor reg_data;
65   if (!GetData(reg_data)) {
66     error.SetErrorString("invalid register value to copy into");
67     return 0;
68   }
69 
70   // Prepare a memory buffer that contains some or all of the register value
71   const uint32_t bytes_copied =
72       reg_data.CopyByteOrderedData(0,               // src offset
73                                    src_len,         // src length
74                                    dst,             // dst buffer
75                                    dst_len,         // dst length
76                                    dst_byte_order); // dst byte order
77   if (bytes_copied == 0)
78     error.SetErrorStringWithFormat(
79         "failed to copy data for register write of %s", reg_info->name);
80 
81   return bytes_copied;
82 }
83 
84 uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo *reg_info,
85                                           const void *src, uint32_t src_len,
86                                           lldb::ByteOrder src_byte_order,
87                                           Status &error) {
88   if (reg_info == nullptr) {
89     error.SetErrorString("invalid register info argument.");
90     return 0;
91   }
92 
93   // Moving from addr into a register
94   //
95   // Case 1: src_len == dst_len
96   //
97   //   |AABBCCDD| Address contents
98   //   |AABBCCDD| Register contents
99   //
100   // Case 2: src_len > dst_len
101   //
102   //   Status!  (The register should always be big enough to hold the data)
103   //
104   // Case 3: src_len < dst_len
105   //
106   //   |AABB| Address contents
107   //   |AABB0000| Register contents [on little-endian hardware]
108   //   |0000AABB| Register contents [on big-endian hardware]
109   if (src_len > kMaxRegisterByteSize) {
110     error.SetErrorStringWithFormat(
111         "register buffer is too small to receive %u bytes of data.", src_len);
112     return 0;
113   }
114 
115   const uint32_t dst_len = reg_info->byte_size;
116 
117   if (src_len > dst_len) {
118     error.SetErrorStringWithFormat(
119         "%u bytes is too big to store in register %s (%u bytes)", src_len,
120         reg_info->name, dst_len);
121     return 0;
122   }
123 
124   // Use a data extractor to correctly copy and pad the bytes read into the
125   // register value
126   DataExtractor src_data(src, src_len, src_byte_order, 4);
127 
128   error = SetValueFromData(reg_info, src_data, 0, true);
129   if (error.Fail())
130     return 0;
131 
132   // If SetValueFromData succeeded, we must have copied all of src_len
133   return src_len;
134 }
135 
136 bool RegisterValue::GetScalarValue(Scalar &scalar) const {
137   switch (m_type) {
138   case eTypeInvalid:
139     break;
140   case eTypeBytes: {
141     DataExtractor data(buffer.bytes, buffer.length, buffer.byte_order, 1);
142     if (scalar.SetValueFromData(data, lldb::eEncodingUint,
143 	  buffer.length).Success())
144       return true;
145   } break;
146   case eTypeUInt8:
147   case eTypeUInt16:
148   case eTypeUInt32:
149   case eTypeUInt64:
150   case eTypeUInt128:
151   case eTypeFloat:
152   case eTypeDouble:
153   case eTypeLongDouble:
154     scalar = m_scalar;
155     return true;
156   }
157   return false;
158 }
159 
160 void RegisterValue::Clear() { m_type = eTypeInvalid; }
161 
162 RegisterValue::Type RegisterValue::SetType(const RegisterInfo *reg_info) {
163   // To change the type, we simply copy the data in again, using the new format
164   RegisterValue copy;
165   DataExtractor copy_data;
166   if (copy.CopyValue(*this) && copy.GetData(copy_data))
167     SetValueFromData(reg_info, copy_data, 0, true);
168 
169   return m_type;
170 }
171 
172 Status RegisterValue::SetValueFromData(const RegisterInfo *reg_info,
173                                        DataExtractor &src,
174                                        lldb::offset_t src_offset,
175                                        bool partial_data_ok) {
176   Status error;
177 
178   if (src.GetByteSize() == 0) {
179     error.SetErrorString("empty data.");
180     return error;
181   }
182 
183   if (reg_info->byte_size == 0) {
184     error.SetErrorString("invalid register info.");
185     return error;
186   }
187 
188   uint32_t src_len = src.GetByteSize() - src_offset;
189 
190   if (!partial_data_ok && (src_len < reg_info->byte_size)) {
191     error.SetErrorString("not enough data.");
192     return error;
193   }
194 
195   // Cap the data length if there is more than enough bytes for this register
196   // value
197   if (src_len > reg_info->byte_size)
198     src_len = reg_info->byte_size;
199 
200   // Zero out the value in case we get partial data...
201   memset(buffer.bytes, 0, sizeof(buffer.bytes));
202 
203   type128 int128;
204 
205   m_type = eTypeInvalid;
206   switch (reg_info->encoding) {
207   case eEncodingInvalid:
208     break;
209   case eEncodingUint:
210   case eEncodingSint:
211     if (reg_info->byte_size == 1)
212       SetUInt8(src.GetMaxU32(&src_offset, src_len));
213     else if (reg_info->byte_size <= 2)
214       SetUInt16(src.GetMaxU32(&src_offset, src_len));
215     else if (reg_info->byte_size <= 4)
216       SetUInt32(src.GetMaxU32(&src_offset, src_len));
217     else if (reg_info->byte_size <= 8)
218       SetUInt64(src.GetMaxU64(&src_offset, src_len));
219     else if (reg_info->byte_size <= 16) {
220       uint64_t data1 = src.GetU64(&src_offset);
221       uint64_t data2 = src.GetU64(&src_offset);
222       if (src.GetByteSize() == eByteOrderBig) {
223         int128.x[0] = data1;
224         int128.x[1] = data2;
225       } else {
226         int128.x[0] = data2;
227         int128.x[1] = data1;
228       }
229       SetUInt128(llvm::APInt(128, 2, int128.x));
230     }
231     break;
232   case eEncodingIEEE754:
233     if (reg_info->byte_size == sizeof(float))
234       SetFloat(src.GetFloat(&src_offset));
235     else if (reg_info->byte_size == sizeof(double))
236       SetDouble(src.GetDouble(&src_offset));
237     else if (reg_info->byte_size == sizeof(long double))
238       SetLongDouble(src.GetLongDouble(&src_offset));
239     break;
240   case eEncodingVector: {
241     m_type = eTypeBytes;
242     buffer.length = reg_info->byte_size;
243     buffer.byte_order = src.GetByteOrder();
244     assert(buffer.length <= kMaxRegisterByteSize);
245     if (buffer.length > kMaxRegisterByteSize)
246       buffer.length = kMaxRegisterByteSize;
247     if (src.CopyByteOrderedData(
248             src_offset,    // offset within "src" to start extracting data
249             src_len,       // src length
250             buffer.bytes,  // dst buffer
251             buffer.length, // dst length
252             buffer.byte_order) == 0) // dst byte order
253     {
254       error.SetErrorStringWithFormat(
255           "failed to copy data for register write of %s", reg_info->name);
256       return error;
257     }
258   }
259   }
260 
261   if (m_type == eTypeInvalid)
262     error.SetErrorStringWithFormat(
263         "invalid register value type for register %s", reg_info->name);
264   return error;
265 }
266 
267 // Helper function for RegisterValue::SetValueFromString()
268 static bool ParseVectorEncoding(const RegisterInfo *reg_info,
269                                 llvm::StringRef vector_str,
270                                 const uint32_t byte_size,
271                                 RegisterValue *reg_value) {
272   // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
273   // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
274   vector_str = vector_str.trim();
275   vector_str.consume_front("{");
276   vector_str.consume_back("}");
277   vector_str = vector_str.trim();
278 
279   char Sep = ' ';
280 
281   // The first split should give us:
282   // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
283   // 0x2a 0x3e').
284   llvm::StringRef car;
285   llvm::StringRef cdr = vector_str;
286   std::tie(car, cdr) = vector_str.split(Sep);
287   std::vector<uint8_t> bytes;
288   unsigned byte = 0;
289 
290   // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
291   // vector elements as long as the parsing succeeds and the vector size is <
292   // byte_size.
293   while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
294     bytes.push_back(byte);
295     std::tie(car, cdr) = cdr.split(Sep);
296   }
297 
298   // Check for vector of exact byte_size elements.
299   if (bytes.size() != byte_size)
300     return false;
301 
302   reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
303   return true;
304 }
305 
306 static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
307                                           size_t total_byte_size) {
308   if (total_byte_size > 8)
309     return false;
310 
311   if (total_byte_size == 8)
312     return true;
313 
314   const uint64_t max =
315       (static_cast<uint64_t>(1) << static_cast<uint64_t>(total_byte_size * 8)) -
316       1;
317   return uval64 <= max;
318 }
319 
320 static bool SInt64ValueIsValidForByteSize(int64_t sval64,
321                                           size_t total_byte_size) {
322   if (total_byte_size > 8)
323     return false;
324 
325   if (total_byte_size == 8)
326     return true;
327 
328   const int64_t max = (static_cast<int64_t>(1)
329                        << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
330                       1;
331   const int64_t min = ~(max);
332   return min <= sval64 && sval64 <= max;
333 }
334 
335 Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info,
336                                          llvm::StringRef value_str) {
337   Status error;
338   if (reg_info == nullptr) {
339     error.SetErrorString("Invalid register info argument.");
340     return error;
341   }
342 
343   m_type = eTypeInvalid;
344   if (value_str.empty()) {
345     error.SetErrorString("Invalid c-string value string.");
346     return error;
347   }
348   const uint32_t byte_size = reg_info->byte_size;
349 
350   uint64_t uval64;
351   int64_t ival64;
352   float flt_val;
353   double dbl_val;
354   long double ldbl_val;
355   switch (reg_info->encoding) {
356   case eEncodingInvalid:
357     error.SetErrorString("Invalid encoding.");
358     break;
359 
360   case eEncodingUint:
361     if (byte_size > sizeof(uint64_t)) {
362       error.SetErrorStringWithFormat(
363           "unsupported unsigned integer byte size: %u", byte_size);
364       break;
365     }
366     if (value_str.getAsInteger(0, uval64)) {
367       error.SetErrorStringWithFormat(
368           "'%s' is not a valid unsigned integer string value",
369           value_str.str().c_str());
370       break;
371     }
372 
373     if (!UInt64ValueIsValidForByteSize(uval64, byte_size)) {
374       error.SetErrorStringWithFormat(
375           "value 0x%" PRIx64
376           " is too large to fit in a %u byte unsigned integer value",
377           uval64, byte_size);
378       break;
379     }
380 
381     if (!SetUInt(uval64, reg_info->byte_size)) {
382       error.SetErrorStringWithFormat(
383           "unsupported unsigned integer byte size: %u", byte_size);
384       break;
385     }
386     break;
387 
388   case eEncodingSint:
389     if (byte_size > sizeof(long long)) {
390       error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
391                                      byte_size);
392       break;
393     }
394 
395     if (value_str.getAsInteger(0, ival64)) {
396       error.SetErrorStringWithFormat(
397           "'%s' is not a valid signed integer string value",
398           value_str.str().c_str());
399       break;
400     }
401 
402     if (!SInt64ValueIsValidForByteSize(ival64, byte_size)) {
403       error.SetErrorStringWithFormat(
404           "value 0x%" PRIx64
405           " is too large to fit in a %u byte signed integer value",
406           ival64, byte_size);
407       break;
408     }
409 
410     if (!SetUInt(ival64, reg_info->byte_size)) {
411       error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
412                                      byte_size);
413       break;
414     }
415     break;
416 
417   case eEncodingIEEE754: {
418     std::string value_string = std::string(value_str);
419     if (byte_size == sizeof(float)) {
420       if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
421         error.SetErrorStringWithFormat("'%s' is not a valid float string value",
422                                        value_string.c_str());
423         break;
424       }
425       m_scalar = flt_val;
426       m_type = eTypeFloat;
427     } else if (byte_size == sizeof(double)) {
428       if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
429         error.SetErrorStringWithFormat("'%s' is not a valid float string value",
430                                        value_string.c_str());
431         break;
432       }
433       m_scalar = dbl_val;
434       m_type = eTypeDouble;
435     } else if (byte_size == sizeof(long double)) {
436       if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
437         error.SetErrorStringWithFormat("'%s' is not a valid float string value",
438                                        value_string.c_str());
439         break;
440       }
441       m_scalar = ldbl_val;
442       m_type = eTypeLongDouble;
443     } else {
444       error.SetErrorStringWithFormat("unsupported float byte size: %u",
445                                      byte_size);
446       return error;
447     }
448     break;
449   }
450   case eEncodingVector:
451     if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
452       error.SetErrorString("unrecognized vector encoding string value.");
453     break;
454   }
455 
456   return error;
457 }
458 
459 bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
460   switch (m_type) {
461   case eTypeInvalid:
462     break;
463 
464   case eTypeUInt8:
465   case eTypeUInt16:
466   case eTypeUInt32:
467   case eTypeUInt64:
468   case eTypeUInt128:
469     return m_scalar.SignExtend(sign_bitpos);
470   case eTypeFloat:
471   case eTypeDouble:
472   case eTypeLongDouble:
473   case eTypeBytes:
474     break;
475   }
476   return false;
477 }
478 
479 bool RegisterValue::CopyValue(const RegisterValue &rhs) {
480   if (this == &rhs)
481     return rhs.m_type != eTypeInvalid;
482 
483   m_type = rhs.m_type;
484   switch (m_type) {
485   case eTypeInvalid:
486     return false;
487   case eTypeUInt8:
488   case eTypeUInt16:
489   case eTypeUInt32:
490   case eTypeUInt64:
491   case eTypeUInt128:
492   case eTypeFloat:
493   case eTypeDouble:
494   case eTypeLongDouble:
495     m_scalar = rhs.m_scalar;
496     break;
497   case eTypeBytes:
498     assert(rhs.buffer.length <= kMaxRegisterByteSize);
499     ::memcpy(buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize);
500     buffer.length = rhs.buffer.length;
501     buffer.byte_order = rhs.buffer.byte_order;
502     break;
503   }
504   return true;
505 }
506 
507 uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
508                                     bool *success_ptr) const {
509   if (success_ptr)
510     *success_ptr = true;
511 
512   switch (m_type) {
513   default:
514     break;
515   case eTypeUInt8:
516   case eTypeUInt16:
517     return m_scalar.UShort(fail_value);
518   case eTypeBytes: {
519     switch (buffer.length) {
520     default:
521       break;
522     case 1:
523     case 2:
524       return *reinterpret_cast<const uint16_t *>(buffer.bytes);
525     }
526   } break;
527   }
528   if (success_ptr)
529     *success_ptr = false;
530   return fail_value;
531 }
532 
533 uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
534                                     bool *success_ptr) const {
535   if (success_ptr)
536     *success_ptr = true;
537   switch (m_type) {
538   default:
539     break;
540   case eTypeUInt8:
541   case eTypeUInt16:
542   case eTypeUInt32:
543   case eTypeFloat:
544   case eTypeDouble:
545   case eTypeLongDouble:
546     return m_scalar.UInt(fail_value);
547   case eTypeBytes: {
548     switch (buffer.length) {
549     default:
550       break;
551     case 1:
552     case 2:
553     case 4:
554       return *reinterpret_cast<const uint32_t *>(buffer.bytes);
555     }
556   } break;
557   }
558   if (success_ptr)
559     *success_ptr = false;
560   return fail_value;
561 }
562 
563 uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
564                                     bool *success_ptr) const {
565   if (success_ptr)
566     *success_ptr = true;
567   switch (m_type) {
568   default:
569     break;
570   case eTypeUInt8:
571   case eTypeUInt16:
572   case eTypeUInt32:
573   case eTypeUInt64:
574   case eTypeFloat:
575   case eTypeDouble:
576   case eTypeLongDouble:
577     return m_scalar.ULongLong(fail_value);
578   case eTypeBytes: {
579     switch (buffer.length) {
580     default:
581       break;
582     case 1:
583       return *(const uint8_t *)buffer.bytes;
584     case 2:
585       return *reinterpret_cast<const uint16_t *>(buffer.bytes);
586     case 4:
587       return *reinterpret_cast<const uint32_t *>(buffer.bytes);
588     case 8:
589       return *reinterpret_cast<const uint64_t *>(buffer.bytes);
590     }
591   } break;
592   }
593   if (success_ptr)
594     *success_ptr = false;
595   return fail_value;
596 }
597 
598 llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value,
599                                         bool *success_ptr) const {
600   if (success_ptr)
601     *success_ptr = true;
602   switch (m_type) {
603   default:
604     break;
605   case eTypeUInt8:
606   case eTypeUInt16:
607   case eTypeUInt32:
608   case eTypeUInt64:
609   case eTypeUInt128:
610   case eTypeFloat:
611   case eTypeDouble:
612   case eTypeLongDouble:
613     return m_scalar.UInt128(fail_value);
614   case eTypeBytes: {
615     switch (buffer.length) {
616     default:
617       break;
618     case 1:
619     case 2:
620     case 4:
621     case 8:
622     case 16:
623       return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
624                          (reinterpret_cast<const type128 *>(buffer.bytes))->x);
625     }
626   } break;
627   }
628   if (success_ptr)
629     *success_ptr = false;
630   return fail_value;
631 }
632 
633 float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
634   if (success_ptr)
635     *success_ptr = true;
636   switch (m_type) {
637   default:
638     break;
639   case eTypeUInt32:
640   case eTypeUInt64:
641   case eTypeUInt128:
642   case eTypeFloat:
643   case eTypeDouble:
644   case eTypeLongDouble:
645     return m_scalar.Float(fail_value);
646   }
647   if (success_ptr)
648     *success_ptr = false;
649   return fail_value;
650 }
651 
652 double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const {
653   if (success_ptr)
654     *success_ptr = true;
655   switch (m_type) {
656   default:
657     break;
658 
659   case eTypeUInt32:
660   case eTypeUInt64:
661   case eTypeUInt128:
662   case eTypeFloat:
663   case eTypeDouble:
664   case eTypeLongDouble:
665     return m_scalar.Double(fail_value);
666   }
667   if (success_ptr)
668     *success_ptr = false;
669   return fail_value;
670 }
671 
672 long double RegisterValue::GetAsLongDouble(long double fail_value,
673                                            bool *success_ptr) const {
674   if (success_ptr)
675     *success_ptr = true;
676   switch (m_type) {
677   default:
678     break;
679 
680   case eTypeUInt32:
681   case eTypeUInt64:
682   case eTypeUInt128:
683   case eTypeFloat:
684   case eTypeDouble:
685   case eTypeLongDouble:
686     return m_scalar.LongDouble();
687   }
688   if (success_ptr)
689     *success_ptr = false;
690   return fail_value;
691 }
692 
693 const void *RegisterValue::GetBytes() const {
694   switch (m_type) {
695   case eTypeInvalid:
696     break;
697   case eTypeUInt8:
698   case eTypeUInt16:
699   case eTypeUInt32:
700   case eTypeUInt64:
701   case eTypeUInt128:
702   case eTypeFloat:
703   case eTypeDouble:
704   case eTypeLongDouble:
705     m_scalar.GetBytes(buffer.bytes);
706     return buffer.bytes;
707   case eTypeBytes:
708     return buffer.bytes;
709   }
710   return nullptr;
711 }
712 
713 uint32_t RegisterValue::GetByteSize() const {
714   switch (m_type) {
715   case eTypeInvalid:
716     break;
717   case eTypeUInt8:
718     return 1;
719   case eTypeUInt16:
720     return 2;
721   case eTypeUInt32:
722   case eTypeUInt64:
723   case eTypeUInt128:
724   case eTypeFloat:
725   case eTypeDouble:
726   case eTypeLongDouble:
727     return m_scalar.GetByteSize();
728   case eTypeBytes:
729     return buffer.length;
730   }
731   return 0;
732 }
733 
734 bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
735   if (byte_size == 0) {
736     SetUInt64(uint);
737   } else if (byte_size == 1) {
738     SetUInt8(uint);
739   } else if (byte_size <= 2) {
740     SetUInt16(uint);
741   } else if (byte_size <= 4) {
742     SetUInt32(uint);
743   } else if (byte_size <= 8) {
744     SetUInt64(uint);
745   } else if (byte_size <= 16) {
746     SetUInt128(llvm::APInt(128, uint));
747   } else
748     return false;
749   return true;
750 }
751 
752 void RegisterValue::SetBytes(const void *bytes, size_t length,
753                              lldb::ByteOrder byte_order) {
754   // If this assertion fires off we need to increase the size of buffer.bytes,
755   // or make it something that is allocated on the heap. Since the data buffer
756   // is in a union, we can't make it a collection class like SmallVector...
757   if (bytes && length > 0) {
758     assert(length <= sizeof(buffer.bytes) &&
759            "Storing too many bytes in a RegisterValue.");
760     m_type = eTypeBytes;
761     buffer.length = length;
762     memcpy(buffer.bytes, bytes, length);
763     buffer.byte_order = byte_order;
764   } else {
765     m_type = eTypeInvalid;
766     buffer.length = 0;
767   }
768 }
769 
770 bool RegisterValue::operator==(const RegisterValue &rhs) const {
771   if (m_type == rhs.m_type) {
772     switch (m_type) {
773     case eTypeInvalid:
774       return true;
775     case eTypeUInt8:
776     case eTypeUInt16:
777     case eTypeUInt32:
778     case eTypeUInt64:
779     case eTypeUInt128:
780     case eTypeFloat:
781     case eTypeDouble:
782     case eTypeLongDouble:
783       return m_scalar == rhs.m_scalar;
784     case eTypeBytes:
785       if (buffer.length != rhs.buffer.length)
786         return false;
787       else {
788         uint16_t length = buffer.length;
789         if (length > kMaxRegisterByteSize)
790           length = kMaxRegisterByteSize;
791         return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0;
792       }
793       break;
794     }
795   }
796   return false;
797 }
798 
799 bool RegisterValue::operator!=(const RegisterValue &rhs) const {
800   return !(*this == rhs);
801 }
802 
803 bool RegisterValue::ClearBit(uint32_t bit) {
804   switch (m_type) {
805   case eTypeInvalid:
806     break;
807 
808   case eTypeUInt8:
809   case eTypeUInt16:
810   case eTypeUInt32:
811   case eTypeUInt64:
812   case eTypeUInt128:
813     if (bit < (GetByteSize() * 8)) {
814       return m_scalar.ClearBit(bit);
815     }
816     break;
817 
818   case eTypeFloat:
819   case eTypeDouble:
820   case eTypeLongDouble:
821     break;
822 
823   case eTypeBytes:
824     if (buffer.byte_order == eByteOrderBig ||
825         buffer.byte_order == eByteOrderLittle) {
826       uint32_t byte_idx;
827       if (buffer.byte_order == eByteOrderBig)
828         byte_idx = buffer.length - (bit / 8) - 1;
829       else
830         byte_idx = bit / 8;
831 
832       const uint32_t byte_bit = bit % 8;
833       if (byte_idx < buffer.length) {
834         buffer.bytes[byte_idx] &= ~(1u << byte_bit);
835         return true;
836       }
837     }
838     break;
839   }
840   return false;
841 }
842 
843 bool RegisterValue::SetBit(uint32_t bit) {
844   switch (m_type) {
845   case eTypeInvalid:
846     break;
847 
848   case eTypeUInt8:
849   case eTypeUInt16:
850   case eTypeUInt32:
851   case eTypeUInt64:
852   case eTypeUInt128:
853     if (bit < (GetByteSize() * 8)) {
854       return m_scalar.SetBit(bit);
855     }
856     break;
857 
858   case eTypeFloat:
859   case eTypeDouble:
860   case eTypeLongDouble:
861     break;
862 
863   case eTypeBytes:
864     if (buffer.byte_order == eByteOrderBig ||
865         buffer.byte_order == eByteOrderLittle) {
866       uint32_t byte_idx;
867       if (buffer.byte_order == eByteOrderBig)
868         byte_idx = buffer.length - (bit / 8) - 1;
869       else
870         byte_idx = bit / 8;
871 
872       const uint32_t byte_bit = bit % 8;
873       if (byte_idx < buffer.length) {
874         buffer.bytes[byte_idx] |= (1u << byte_bit);
875         return true;
876       }
877     }
878     break;
879   }
880   return false;
881 }
882