]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/RegisterValue.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / RegisterValue.cpp
1 //===-- RegisterValue.cpp ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Core/RegisterValue.h"
11
12 #include "lldb/Core/Scalar.h"
13 #include "lldb/Utility/Args.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "lldb/Utility/Status.h"
16 #include "lldb/Utility/Stream.h"
17 #include "lldb/Utility/StreamString.h"
18 #include "lldb/lldb-defines.h"       // for LLDB_INVALID_ADDRESS
19 #include "lldb/lldb-private-types.h" // for RegisterInfo, type128
20
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/StringRef.h"
23
24 #include <cstdint> // for uint8_t, uint32_t, uint64_t
25 #include <string>  // for string
26 #include <tuple>   // for tie, tuple
27 #include <vector>
28
29 #include <assert.h>   // for assert
30 #include <inttypes.h> // for PRIx64
31 #include <stdio.h>    // for sscanf
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 bool RegisterValue::GetData(DataExtractor &data) const {
37   return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
38 }
39
40 uint32_t RegisterValue::GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
41                                         uint32_t dst_len,
42                                         lldb::ByteOrder dst_byte_order,
43                                         Status &error) const {
44   if (reg_info == nullptr) {
45     error.SetErrorString("invalid register info argument.");
46     return 0;
47   }
48
49   // ReadRegister should have already been called on this object prior to
50   // calling this.
51   if (GetType() == eTypeInvalid) {
52     // No value has been read into this object...
53     error.SetErrorStringWithFormat(
54         "invalid register value type for register %s", reg_info->name);
55     return 0;
56   }
57
58   if (dst_len > kMaxRegisterByteSize) {
59     error.SetErrorString("destination is too big");
60     return 0;
61   }
62
63   const uint32_t src_len = reg_info->byte_size;
64
65   // Extract the register data into a data extractor
66   DataExtractor reg_data;
67   if (!GetData(reg_data)) {
68     error.SetErrorString("invalid register value to copy into");
69     return 0;
70   }
71
72   // Prepare a memory buffer that contains some or all of the register value
73   const uint32_t bytes_copied =
74       reg_data.CopyByteOrderedData(0,               // src offset
75                                    src_len,         // src length
76                                    dst,             // dst buffer
77                                    dst_len,         // dst length
78                                    dst_byte_order); // dst byte order
79   if (bytes_copied == 0)
80     error.SetErrorStringWithFormat(
81         "failed to copy data for register write of %s", reg_info->name);
82
83   return bytes_copied;
84 }
85
86 uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo *reg_info,
87                                           const void *src, uint32_t src_len,
88                                           lldb::ByteOrder src_byte_order,
89                                           Status &error) {
90   if (reg_info == nullptr) {
91     error.SetErrorString("invalid register info argument.");
92     return 0;
93   }
94
95   // Moving from addr into a register
96   //
97   // Case 1: src_len == dst_len
98   //
99   //   |AABBCCDD| Address contents
100   //   |AABBCCDD| Register contents
101   //
102   // Case 2: src_len > dst_len
103   //
104   //   Status!  (The register should always be big enough to hold the data)
105   //
106   // Case 3: src_len < dst_len
107   //
108   //   |AABB| Address contents
109   //   |AABB0000| Register contents [on little-endian hardware]
110   //   |0000AABB| Register contents [on big-endian hardware]
111   if (src_len > kMaxRegisterByteSize) {
112     error.SetErrorStringWithFormat(
113         "register buffer is too small to receive %u bytes of data.", src_len);
114     return 0;
115   }
116
117   const uint32_t dst_len = reg_info->byte_size;
118
119   if (src_len > dst_len) {
120     error.SetErrorStringWithFormat(
121         "%u bytes is too big to store in register %s (%u bytes)", src_len,
122         reg_info->name, dst_len);
123     return 0;
124   }
125
126   // Use a data extractor to correctly copy and pad the bytes read into the
127   // register value
128   DataExtractor src_data(src, src_len, src_byte_order, 4);
129
130   error = SetValueFromData(reg_info, src_data, 0, true);
131   if (error.Fail())
132     return 0;
133
134   // If SetValueFromData succeeded, we must have copied all of src_len
135   return src_len;
136 }
137
138 bool RegisterValue::GetScalarValue(Scalar &scalar) const {
139   switch (m_type) {
140   case eTypeInvalid:
141     break;
142   case eTypeBytes: {
143     switch (buffer.length) {
144     default:
145       break;
146     case 1:
147       scalar = *(const uint8_t *)buffer.bytes;
148       return true;
149     case 2:
150       scalar = *(const uint16_t *)buffer.bytes;
151       return true;
152     case 4:
153       scalar = *(const uint32_t *)buffer.bytes;
154       return true;
155     case 8:
156       scalar = *(const uint64_t *)buffer.bytes;
157       return true;
158     case 16:
159     case 32:
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>((const uint64_t *)buffer.bytes,
166                                                  length_in_uint64));
167         return true;
168       }
169       break;
170     }
171   } break;
172   case eTypeUInt8:
173   case eTypeUInt16:
174   case eTypeUInt32:
175   case eTypeUInt64:
176   case eTypeUInt128:
177   case eTypeFloat:
178   case eTypeDouble:
179   case eTypeLongDouble:
180     scalar = m_scalar;
181     return true;
182   }
183   return false;
184 }
185
186 void RegisterValue::Clear() { m_type = eTypeInvalid; }
187
188 RegisterValue::Type RegisterValue::SetType(const RegisterInfo *reg_info) {
189   // To change the type, we simply copy the data in again, using the new format
190   RegisterValue copy;
191   DataExtractor copy_data;
192   if (copy.CopyValue(*this) && copy.GetData(copy_data))
193     SetValueFromData(reg_info, copy_data, 0, true);
194
195   return m_type;
196 }
197
198 Status RegisterValue::SetValueFromData(const RegisterInfo *reg_info,
199                                        DataExtractor &src,
200                                        lldb::offset_t src_offset,
201                                        bool partial_data_ok) {
202   Status error;
203
204   if (src.GetByteSize() == 0) {
205     error.SetErrorString("empty data.");
206     return error;
207   }
208
209   if (reg_info->byte_size == 0) {
210     error.SetErrorString("invalid register info.");
211     return error;
212   }
213
214   uint32_t src_len = src.GetByteSize() - src_offset;
215
216   if (!partial_data_ok && (src_len < reg_info->byte_size)) {
217     error.SetErrorString("not enough data.");
218     return error;
219   }
220
221   // Cap the data length if there is more than enough bytes for this register
222   // value
223   if (src_len > reg_info->byte_size)
224     src_len = reg_info->byte_size;
225
226   // Zero out the value in case we get partial data...
227   memset(buffer.bytes, 0, sizeof(buffer.bytes));
228
229   type128 int128;
230
231   m_type = eTypeInvalid;
232   switch (reg_info->encoding) {
233   case eEncodingInvalid:
234     break;
235   case eEncodingUint:
236   case eEncodingSint:
237     if (reg_info->byte_size == 1)
238       SetUInt8(src.GetMaxU32(&src_offset, src_len));
239     else if (reg_info->byte_size <= 2)
240       SetUInt16(src.GetMaxU32(&src_offset, src_len));
241     else if (reg_info->byte_size <= 4)
242       SetUInt32(src.GetMaxU32(&src_offset, src_len));
243     else if (reg_info->byte_size <= 8)
244       SetUInt64(src.GetMaxU64(&src_offset, src_len));
245     else if (reg_info->byte_size <= 16) {
246       uint64_t data1 = src.GetU64(&src_offset);
247       uint64_t data2 = src.GetU64(&src_offset);
248       if (src.GetByteSize() == eByteOrderBig) {
249         int128.x[0] = data1;
250         int128.x[1] = data2;
251       } else {
252         int128.x[0] = data2;
253         int128.x[1] = data1;
254       }
255       SetUInt128(llvm::APInt(128, 2, int128.x));
256     }
257     break;
258   case eEncodingIEEE754:
259     if (reg_info->byte_size == sizeof(float))
260       SetFloat(src.GetFloat(&src_offset));
261     else if (reg_info->byte_size == sizeof(double))
262       SetDouble(src.GetDouble(&src_offset));
263     else if (reg_info->byte_size == sizeof(long double))
264       SetLongDouble(src.GetLongDouble(&src_offset));
265     break;
266   case eEncodingVector: {
267     m_type = eTypeBytes;
268     buffer.length = reg_info->byte_size;
269     buffer.byte_order = src.GetByteOrder();
270     assert(buffer.length <= kMaxRegisterByteSize);
271     if (buffer.length > kMaxRegisterByteSize)
272       buffer.length = kMaxRegisterByteSize;
273     if (src.CopyByteOrderedData(
274             src_offset,    // offset within "src" to start extracting data
275             src_len,       // src length
276             buffer.bytes,  // dst buffer
277             buffer.length, // dst length
278             buffer.byte_order) == 0) // dst byte order
279     {
280       error.SetErrorStringWithFormat(
281           "failed to copy data for register write of %s", reg_info->name);
282       return error;
283     }
284   }
285   }
286
287   if (m_type == eTypeInvalid)
288     error.SetErrorStringWithFormat(
289         "invalid register value type for register %s", reg_info->name);
290   return error;
291 }
292
293 // Helper function for RegisterValue::SetValueFromString()
294 static bool ParseVectorEncoding(const RegisterInfo *reg_info,
295                                 llvm::StringRef vector_str,
296                                 const uint32_t byte_size,
297                                 RegisterValue *reg_value) {
298   // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
299   // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
300   vector_str = vector_str.trim();
301   vector_str.consume_front("{");
302   vector_str.consume_back("}");
303   vector_str = vector_str.trim();
304
305   char Sep = ' ';
306
307   // The first split should give us:
308   // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
309   // 0x2a 0x3e').
310   llvm::StringRef car;
311   llvm::StringRef cdr = vector_str;
312   std::tie(car, cdr) = vector_str.split(Sep);
313   std::vector<uint8_t> bytes;
314   unsigned byte = 0;
315
316   // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
317   // vector elements as long as the parsing succeeds and the vector size is <
318   // byte_size.
319   while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
320     bytes.push_back(byte);
321     std::tie(car, cdr) = cdr.split(Sep);
322   }
323
324   // Check for vector of exact byte_size elements.
325   if (bytes.size() != byte_size)
326     return false;
327
328   reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
329   return true;
330 }
331
332 Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info,
333                                          llvm::StringRef value_str) {
334   Status error;
335   if (reg_info == nullptr) {
336     error.SetErrorString("Invalid register info argument.");
337     return error;
338   }
339
340   m_type = eTypeInvalid;
341   if (value_str.empty()) {
342     error.SetErrorString("Invalid c-string value string.");
343     return error;
344   }
345   const uint32_t byte_size = reg_info->byte_size;
346
347   uint64_t uval64;
348   int64_t ival64;
349   float flt_val;
350   double dbl_val;
351   long double ldbl_val;
352   switch (reg_info->encoding) {
353   case eEncodingInvalid:
354     error.SetErrorString("Invalid encoding.");
355     break;
356
357   case eEncodingUint:
358     if (byte_size > sizeof(uint64_t)) {
359       error.SetErrorStringWithFormat(
360           "unsupported unsigned integer byte size: %u", byte_size);
361       break;
362     }
363     if (value_str.getAsInteger(0, uval64)) {
364       error.SetErrorStringWithFormat(
365           "'%s' is not a valid unsigned integer string value",
366           value_str.str().c_str());
367       break;
368     }
369
370     if (!Args::UInt64ValueIsValidForByteSize(uval64, byte_size)) {
371       error.SetErrorStringWithFormat(
372           "value 0x%" PRIx64
373           " is too large to fit in a %u byte unsigned integer value",
374           uval64, byte_size);
375       break;
376     }
377
378     if (!SetUInt(uval64, reg_info->byte_size)) {
379       error.SetErrorStringWithFormat(
380           "unsupported unsigned integer byte size: %u", byte_size);
381       break;
382     }
383     // TODO: Shouldn't we be setting m_type here?
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
414     // TODO: Shouldn't we be setting m_type here?
415     break;
416
417   case eEncodingIEEE754: {
418     std::string value_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 ? false : true;
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 *(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 *(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 *(const uint16_t *)buffer.bytes;
586     case 4:
587       return *(const uint32_t *)buffer.bytes;
588     case 8:
589       return *(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                          ((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     return m_scalar.GetBytes();
706   case eTypeBytes:
707     return buffer.bytes;
708   }
709   return nullptr;
710 }
711
712 uint32_t RegisterValue::GetByteSize() const {
713   switch (m_type) {
714   case eTypeInvalid:
715     break;
716   case eTypeUInt8:
717     return 1;
718   case eTypeUInt16:
719     return 2;
720   case eTypeUInt32:
721   case eTypeUInt64:
722   case eTypeUInt128:
723   case eTypeFloat:
724   case eTypeDouble:
725   case eTypeLongDouble:
726     return m_scalar.GetByteSize();
727   case eTypeBytes:
728     return buffer.length;
729   }
730   return 0;
731 }
732
733 bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
734   if (byte_size == 0) {
735     SetUInt64(uint);
736   } else if (byte_size == 1) {
737     SetUInt8(uint);
738   } else if (byte_size <= 2) {
739     SetUInt16(uint);
740   } else if (byte_size <= 4) {
741     SetUInt32(uint);
742   } else if (byte_size <= 8) {
743     SetUInt64(uint);
744   } else if (byte_size <= 16) {
745     SetUInt128(llvm::APInt(128, uint));
746   } else
747     return false;
748   return true;
749 }
750
751 void RegisterValue::SetBytes(const void *bytes, size_t length,
752                              lldb::ByteOrder byte_order) {
753   // If this assertion fires off we need to increase the size of buffer.bytes,
754   // or make it something that is allocated on the heap. Since the data buffer
755   // is in a union, we can't make it a collection class like SmallVector...
756   if (bytes && length > 0) {
757     assert(length <= sizeof(buffer.bytes) &&
758            "Storing too many bytes in a RegisterValue.");
759     m_type = eTypeBytes;
760     buffer.length = length;
761     memcpy(buffer.bytes, bytes, length);
762     buffer.byte_order = byte_order;
763   } else {
764     m_type = eTypeInvalid;
765     buffer.length = 0;
766   }
767 }
768
769 bool RegisterValue::operator==(const RegisterValue &rhs) const {
770   if (m_type == rhs.m_type) {
771     switch (m_type) {
772     case eTypeInvalid:
773       return true;
774     case eTypeUInt8:
775     case eTypeUInt16:
776     case eTypeUInt32:
777     case eTypeUInt64:
778     case eTypeUInt128:
779     case eTypeFloat:
780     case eTypeDouble:
781     case eTypeLongDouble:
782       return m_scalar == rhs.m_scalar;
783     case eTypeBytes:
784       if (buffer.length != rhs.buffer.length)
785         return false;
786       else {
787         uint8_t length = buffer.length;
788         if (length > kMaxRegisterByteSize)
789           length = kMaxRegisterByteSize;
790         return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0;
791       }
792       break;
793     }
794   }
795   return false;
796 }
797
798 bool RegisterValue::operator!=(const RegisterValue &rhs) const {
799   if (m_type != rhs.m_type)
800     return true;
801   switch (m_type) {
802   case eTypeInvalid:
803     return false;
804   case eTypeUInt8:
805   case eTypeUInt16:
806   case eTypeUInt32:
807   case eTypeUInt64:
808   case eTypeUInt128:
809   case eTypeFloat:
810   case eTypeDouble:
811   case eTypeLongDouble:
812     return m_scalar != rhs.m_scalar;
813   case eTypeBytes:
814     if (buffer.length != rhs.buffer.length) {
815       return true;
816     } else {
817       uint8_t length = buffer.length;
818       if (length > kMaxRegisterByteSize)
819         length = kMaxRegisterByteSize;
820       return memcmp(buffer.bytes, rhs.buffer.bytes, length) != 0;
821     }
822     break;
823   }
824   return true;
825 }
826
827 bool RegisterValue::ClearBit(uint32_t bit) {
828   switch (m_type) {
829   case eTypeInvalid:
830     break;
831
832   case eTypeUInt8:
833   case eTypeUInt16:
834   case eTypeUInt32:
835   case eTypeUInt64:
836   case eTypeUInt128:
837     if (bit < (GetByteSize() * 8)) {
838       return m_scalar.ClearBit(bit);
839     }
840     break;
841
842   case eTypeFloat:
843   case eTypeDouble:
844   case eTypeLongDouble:
845     break;
846
847   case eTypeBytes:
848     if (buffer.byte_order == eByteOrderBig ||
849         buffer.byte_order == eByteOrderLittle) {
850       uint32_t byte_idx;
851       if (buffer.byte_order == eByteOrderBig)
852         byte_idx = buffer.length - (bit / 8) - 1;
853       else
854         byte_idx = bit / 8;
855
856       const uint32_t byte_bit = bit % 8;
857       if (byte_idx < buffer.length) {
858         buffer.bytes[byte_idx] &= ~(1u << byte_bit);
859         return true;
860       }
861     }
862     break;
863   }
864   return false;
865 }
866
867 bool RegisterValue::SetBit(uint32_t bit) {
868   switch (m_type) {
869   case eTypeInvalid:
870     break;
871
872   case eTypeUInt8:
873   case eTypeUInt16:
874   case eTypeUInt32:
875   case eTypeUInt64:
876   case eTypeUInt128:
877     if (bit < (GetByteSize() * 8)) {
878       return m_scalar.SetBit(bit);
879     }
880     break;
881
882   case eTypeFloat:
883   case eTypeDouble:
884   case eTypeLongDouble:
885     break;
886
887   case eTypeBytes:
888     if (buffer.byte_order == eByteOrderBig ||
889         buffer.byte_order == eByteOrderLittle) {
890       uint32_t byte_idx;
891       if (buffer.byte_order == eByteOrderBig)
892         byte_idx = buffer.length - (bit / 8) - 1;
893       else
894         byte_idx = bit / 8;
895
896       const uint32_t byte_bit = bit % 8;
897       if (byte_idx < buffer.length) {
898         buffer.bytes[byte_idx] |= (1u << byte_bit);
899         return true;
900       }
901     }
902     break;
903   }
904   return false;
905 }