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