[lldb][dwarf] Compute fully qualified names on simplified template names with DWARFT...
[llvm-project.git] / lldb / source / Utility / RegisterValue.cpp
blob0e99451c3b70071f40ea4acdfd04131e429d0716
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 //===----------------------------------------------------------------------===//
9 #include "lldb/Utility/RegisterValue.h"
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"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringRef.h"
22 #include <cstdint>
23 #include <string>
24 #include <tuple>
25 #include <vector>
27 #include <cassert>
28 #include <cinttypes>
29 #include <cstdio>
31 using namespace lldb;
32 using namespace lldb_private;
34 bool RegisterValue::GetData(DataExtractor &data) const {
35 return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
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 // ReadRegister should have already been called on this object prior to
43 // calling this.
44 if (GetType() == eTypeInvalid) {
45 // No value has been read into this object...
46 error = Status::FromErrorStringWithFormatv(
47 "invalid register value type for register {0}", reg_info.name);
48 return 0;
51 const uint32_t src_len = reg_info.byte_size;
53 // Extract the register data into a data extractor
54 DataExtractor reg_data;
55 if (!GetData(reg_data)) {
56 error = Status::FromErrorString("invalid register value to copy into");
57 return 0;
60 // Prepare a memory buffer that contains some or all of the register value
61 const uint32_t bytes_copied =
62 reg_data.CopyByteOrderedData(0, // src offset
63 src_len, // src length
64 dst, // dst buffer
65 dst_len, // dst length
66 dst_byte_order); // dst byte order
67 if (bytes_copied == 0)
68 error = Status::FromErrorStringWithFormat(
69 "failed to copy data for register write of %s", reg_info.name);
71 return bytes_copied;
74 uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo &reg_info,
75 const void *src, uint32_t src_len,
76 lldb::ByteOrder src_byte_order,
77 Status &error) {
78 // Moving from addr into a register
80 // Case 1: src_len == dst_len
82 // |AABBCCDD| Address contents
83 // |AABBCCDD| Register contents
85 // Case 2: src_len > dst_len
87 // Status! (The register should always be big enough to hold the data)
89 // Case 3: src_len < dst_len
91 // |AABB| Address contents
92 // |AABB0000| Register contents [on little-endian hardware]
93 // |0000AABB| Register contents [on big-endian hardware]
94 const uint32_t dst_len = reg_info.byte_size;
96 if (src_len > dst_len) {
97 error = Status::FromErrorStringWithFormat(
98 "%u bytes is too big to store in register %s (%u bytes)", src_len,
99 reg_info.name, dst_len);
100 return 0;
103 // Use a data extractor to correctly copy and pad the bytes read into the
104 // register value
105 DataExtractor src_data(src, src_len, src_byte_order, 4);
107 error = SetValueFromData(reg_info, src_data, 0, true);
108 if (error.Fail())
109 return 0;
111 // If SetValueFromData succeeded, we must have copied all of src_len
112 return src_len;
115 bool RegisterValue::GetScalarValue(Scalar &scalar) const {
116 switch (m_type) {
117 case eTypeInvalid:
118 break;
119 case eTypeBytes: {
120 DataExtractor data(buffer.bytes.data(), buffer.bytes.size(),
121 buffer.byte_order, 1);
122 if (scalar.SetValueFromData(data, lldb::eEncodingUint, buffer.bytes.size())
123 .Success())
124 return true;
125 } break;
126 case eTypeUInt8:
127 case eTypeUInt16:
128 case eTypeUInt32:
129 case eTypeUInt64:
130 case eTypeUInt128:
131 case eTypeFloat:
132 case eTypeDouble:
133 case eTypeLongDouble:
134 scalar = m_scalar;
135 return true;
137 return false;
140 void RegisterValue::Clear() { m_type = eTypeInvalid; }
142 RegisterValue::Type RegisterValue::SetType(const RegisterInfo &reg_info) {
143 // To change the type, we simply copy the data in again, using the new format
144 RegisterValue copy;
145 DataExtractor copy_data;
146 if (copy.CopyValue(*this) && copy.GetData(copy_data)) {
147 Status error = SetValueFromData(reg_info, copy_data, 0, true);
148 assert(error.Success() && "Expected SetValueFromData to succeed.");
149 UNUSED_IF_ASSERT_DISABLED(error);
152 return m_type;
155 Status RegisterValue::SetValueFromData(const RegisterInfo &reg_info,
156 DataExtractor &src,
157 lldb::offset_t src_offset,
158 bool partial_data_ok) {
159 Status error;
161 if (src.GetByteSize() == 0) {
162 error = Status::FromErrorString("empty data.");
163 return error;
166 if (reg_info.byte_size == 0) {
167 error = Status::FromErrorString("invalid register info.");
168 return error;
171 uint32_t src_len = src.GetByteSize() - src_offset;
173 if (!partial_data_ok && (src_len < reg_info.byte_size)) {
174 error = Status::FromErrorString("not enough data.");
175 return error;
178 // Cap the data length if there is more than enough bytes for this register
179 // value
180 if (src_len > reg_info.byte_size)
181 src_len = reg_info.byte_size;
183 type128 int128;
185 m_type = eTypeInvalid;
186 switch (reg_info.encoding) {
187 case eEncodingInvalid:
188 break;
189 case eEncodingUint:
190 case eEncodingSint:
191 if (reg_info.byte_size == 1)
192 SetUInt8(src.GetMaxU32(&src_offset, src_len));
193 else if (reg_info.byte_size <= 2)
194 SetUInt16(src.GetMaxU32(&src_offset, src_len));
195 else if (reg_info.byte_size <= 4)
196 SetUInt32(src.GetMaxU32(&src_offset, src_len));
197 else if (reg_info.byte_size <= 8)
198 SetUInt64(src.GetMaxU64(&src_offset, src_len));
199 else if (reg_info.byte_size <= 16) {
200 uint64_t data1 = src.GetU64(&src_offset);
201 uint64_t data2 = src.GetU64(&src_offset);
202 if (src.GetByteOrder() == eByteOrderBig) {
203 int128.x[0] = data1;
204 int128.x[1] = data2;
205 } else {
206 int128.x[0] = data2;
207 int128.x[1] = data1;
209 SetUInt128(llvm::APInt(128, 2, int128.x));
211 break;
212 case eEncodingIEEE754:
213 if (reg_info.byte_size == sizeof(float))
214 SetFloat(src.GetFloat(&src_offset));
215 else if (reg_info.byte_size == sizeof(double))
216 SetDouble(src.GetDouble(&src_offset));
217 else if (reg_info.byte_size == sizeof(long double))
218 SetLongDouble(src.GetLongDouble(&src_offset));
219 break;
220 case eEncodingVector: {
221 m_type = eTypeBytes;
222 assert(reg_info.byte_size <= kMaxRegisterByteSize);
223 buffer.bytes.resize(reg_info.byte_size);
224 buffer.byte_order = src.GetByteOrder();
225 if (src.CopyByteOrderedData(
226 src_offset, // offset within "src" to start extracting data
227 src_len, // src length
228 buffer.bytes.data(), // dst buffer
229 buffer.bytes.size(), // dst length
230 buffer.byte_order) == 0) // dst byte order
232 error = Status::FromErrorStringWithFormat(
233 "failed to copy data for register write of %s", reg_info.name);
234 return error;
239 if (m_type == eTypeInvalid)
240 error = Status::FromErrorStringWithFormat(
241 "invalid register value type for register %s", reg_info.name);
242 return error;
245 // Helper function for RegisterValue::SetValueFromString()
246 static bool ParseVectorEncoding(const RegisterInfo *reg_info,
247 llvm::StringRef vector_str,
248 const uint32_t byte_size,
249 RegisterValue *reg_value) {
250 // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
251 // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
252 vector_str = vector_str.trim();
253 vector_str.consume_front("{");
254 vector_str.consume_back("}");
255 vector_str = vector_str.trim();
257 char Sep = ' ';
259 // The first split should give us:
260 // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
261 // 0x2a 0x3e').
262 llvm::StringRef car;
263 llvm::StringRef cdr = vector_str;
264 std::tie(car, cdr) = vector_str.split(Sep);
265 std::vector<uint8_t> bytes;
266 unsigned byte = 0;
268 // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
269 // vector elements as long as the parsing succeeds and the vector size is <
270 // byte_size.
271 while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
272 bytes.push_back(byte);
273 std::tie(car, cdr) = cdr.split(Sep);
276 // Check for vector of exact byte_size elements.
277 if (bytes.size() != byte_size)
278 return false;
280 reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
281 return true;
284 static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
285 size_t total_byte_size) {
286 if (total_byte_size > 8)
287 return false;
289 if (total_byte_size == 8)
290 return true;
292 const uint64_t max =
293 (static_cast<uint64_t>(1) << static_cast<uint64_t>(total_byte_size * 8)) -
295 return uval64 <= max;
298 static bool SInt64ValueIsValidForByteSize(int64_t sval64,
299 size_t total_byte_size) {
300 if (total_byte_size > 8)
301 return false;
303 if (total_byte_size == 8)
304 return true;
306 const int64_t max = (static_cast<int64_t>(1)
307 << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
309 const int64_t min = ~(max);
310 return min <= sval64 && sval64 <= max;
313 Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info,
314 llvm::StringRef value_str) {
315 Status error;
316 if (reg_info == nullptr) {
317 error = Status::FromErrorString("Invalid register info argument.");
318 return error;
321 m_type = eTypeInvalid;
322 if (value_str.empty()) {
323 error = Status::FromErrorString("Invalid c-string value string.");
324 return error;
326 const uint32_t byte_size = reg_info->byte_size;
328 uint64_t uval64;
329 int64_t ival64;
330 float flt_val;
331 double dbl_val;
332 long double ldbl_val;
333 switch (reg_info->encoding) {
334 case eEncodingInvalid:
335 error = Status::FromErrorString("Invalid encoding.");
336 break;
338 case eEncodingUint:
339 if (byte_size > sizeof(uint64_t)) {
340 error = Status::FromErrorStringWithFormat(
341 "unsupported unsigned integer byte size: %u", byte_size);
342 break;
344 if (value_str.getAsInteger(0, uval64)) {
345 error = Status::FromErrorStringWithFormatv(
346 "'{0}' is not a valid unsigned integer string value", value_str);
347 break;
350 if (!UInt64ValueIsValidForByteSize(uval64, byte_size)) {
351 error = Status::FromErrorStringWithFormat(
352 "value 0x%" PRIx64
353 " is too large to fit in a %u byte unsigned integer value",
354 uval64, byte_size);
355 break;
358 if (!SetUInt(uval64, reg_info->byte_size)) {
359 error = Status::FromErrorStringWithFormat(
360 "unsupported unsigned integer byte size: %u", byte_size);
361 break;
363 break;
365 case eEncodingSint:
366 if (byte_size > sizeof(long long)) {
367 error = Status::FromErrorStringWithFormat(
368 "unsupported signed integer byte size: %u", byte_size);
369 break;
372 if (value_str.getAsInteger(0, ival64)) {
373 error = Status::FromErrorStringWithFormatv(
374 "'{0}' is not a valid signed integer string value", value_str);
375 break;
378 if (!SInt64ValueIsValidForByteSize(ival64, byte_size)) {
379 error = Status::FromErrorStringWithFormat(
380 "value 0x%" PRIx64
381 " is too large to fit in a %u byte signed integer value",
382 ival64, byte_size);
383 break;
386 if (!SetUInt(ival64, reg_info->byte_size)) {
387 error = Status::FromErrorStringWithFormat(
388 "unsupported signed integer byte size: %u", byte_size);
389 break;
391 break;
393 case eEncodingIEEE754: {
394 std::string value_string = std::string(value_str);
395 if (byte_size == sizeof(float)) {
396 if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
397 error = Status::FromErrorStringWithFormat(
398 "'%s' is not a valid float string value", value_string.c_str());
399 break;
401 m_scalar = flt_val;
402 m_type = eTypeFloat;
403 } else if (byte_size == sizeof(double)) {
404 if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
405 error = Status::FromErrorStringWithFormat(
406 "'%s' is not a valid float string value", value_string.c_str());
407 break;
409 m_scalar = dbl_val;
410 m_type = eTypeDouble;
411 } else if (byte_size == sizeof(long double)) {
412 if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
413 error = Status::FromErrorStringWithFormat(
414 "'%s' is not a valid float string value", value_string.c_str());
415 break;
417 m_scalar = ldbl_val;
418 m_type = eTypeLongDouble;
419 } else {
420 error = Status::FromErrorStringWithFormat(
421 "unsupported float byte size: %u", byte_size);
422 return error;
424 break;
426 case eEncodingVector:
427 if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
428 error =
429 Status::FromErrorString("unrecognized vector encoding string value.");
430 break;
433 return error;
436 bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
437 switch (m_type) {
438 case eTypeInvalid:
439 break;
441 case eTypeUInt8:
442 case eTypeUInt16:
443 case eTypeUInt32:
444 case eTypeUInt64:
445 case eTypeUInt128:
446 return m_scalar.SignExtend(sign_bitpos);
447 case eTypeFloat:
448 case eTypeDouble:
449 case eTypeLongDouble:
450 case eTypeBytes:
451 break;
453 return false;
456 bool RegisterValue::CopyValue(const RegisterValue &rhs) {
457 if (this == &rhs)
458 return rhs.m_type != eTypeInvalid;
460 m_type = rhs.m_type;
461 switch (m_type) {
462 case eTypeInvalid:
463 return false;
464 case eTypeUInt8:
465 case eTypeUInt16:
466 case eTypeUInt32:
467 case eTypeUInt64:
468 case eTypeUInt128:
469 case eTypeFloat:
470 case eTypeDouble:
471 case eTypeLongDouble:
472 m_scalar = rhs.m_scalar;
473 break;
474 case eTypeBytes:
475 buffer.bytes = rhs.buffer.bytes;
476 buffer.byte_order = rhs.buffer.byte_order;
477 break;
479 return true;
482 uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
483 bool *success_ptr) const {
484 if (success_ptr)
485 *success_ptr = true;
487 switch (m_type) {
488 default:
489 break;
490 case eTypeUInt8:
491 case eTypeUInt16:
492 return m_scalar.UShort(fail_value);
493 case eTypeBytes: {
494 switch (buffer.bytes.size()) {
495 default:
496 break;
497 case 1:
498 case 2:
499 return *reinterpret_cast<const uint16_t *>(buffer.bytes.data());
501 } break;
503 if (success_ptr)
504 *success_ptr = false;
505 return fail_value;
508 uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
509 bool *success_ptr) const {
510 if (success_ptr)
511 *success_ptr = true;
512 switch (m_type) {
513 default:
514 break;
515 case eTypeUInt8:
516 case eTypeUInt16:
517 case eTypeUInt32:
518 case eTypeFloat:
519 case eTypeDouble:
520 case eTypeLongDouble:
521 return m_scalar.UInt(fail_value);
522 case eTypeBytes: {
523 switch (buffer.bytes.size()) {
524 default:
525 break;
526 case 1:
527 case 2:
528 case 4:
529 return *reinterpret_cast<const uint32_t *>(buffer.bytes.data());
531 } break;
533 if (success_ptr)
534 *success_ptr = false;
535 return fail_value;
538 uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
539 bool *success_ptr) const {
540 if (success_ptr)
541 *success_ptr = true;
542 switch (m_type) {
543 default:
544 break;
545 case eTypeUInt8:
546 case eTypeUInt16:
547 case eTypeUInt32:
548 case eTypeUInt64:
549 case eTypeFloat:
550 case eTypeDouble:
551 case eTypeLongDouble:
552 return m_scalar.ULongLong(fail_value);
553 case eTypeBytes: {
554 switch (buffer.bytes.size()) {
555 default:
556 break;
557 case 1:
558 return *(const uint8_t *)buffer.bytes.data();
559 case 2:
560 return *reinterpret_cast<const uint16_t *>(buffer.bytes.data());
561 case 4:
562 return *reinterpret_cast<const uint32_t *>(buffer.bytes.data());
563 case 8:
564 return *reinterpret_cast<const uint64_t *>(buffer.bytes.data());
566 } break;
568 if (success_ptr)
569 *success_ptr = false;
570 return fail_value;
573 llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value,
574 bool *success_ptr) const {
575 if (success_ptr)
576 *success_ptr = true;
577 switch (m_type) {
578 default:
579 break;
580 case eTypeUInt8:
581 case eTypeUInt16:
582 case eTypeUInt32:
583 case eTypeUInt64:
584 case eTypeUInt128:
585 case eTypeFloat:
586 case eTypeDouble:
587 case eTypeLongDouble:
588 return m_scalar.UInt128(fail_value);
589 case eTypeBytes: {
590 switch (buffer.bytes.size()) {
591 default:
592 break;
593 case 1:
594 case 2:
595 case 4:
596 case 8:
597 case 16:
598 return llvm::APInt(
599 BITWIDTH_INT128, NUM_OF_WORDS_INT128,
600 (reinterpret_cast<const type128 *>(buffer.bytes.data()))->x);
602 } break;
604 if (success_ptr)
605 *success_ptr = false;
606 return fail_value;
609 float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
610 if (success_ptr)
611 *success_ptr = true;
612 switch (m_type) {
613 default:
614 break;
615 case eTypeUInt32:
616 case eTypeUInt64:
617 case eTypeUInt128:
618 case eTypeFloat:
619 case eTypeDouble:
620 case eTypeLongDouble:
621 return m_scalar.Float(fail_value);
623 if (success_ptr)
624 *success_ptr = false;
625 return fail_value;
628 double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const {
629 if (success_ptr)
630 *success_ptr = true;
631 switch (m_type) {
632 default:
633 break;
635 case eTypeUInt32:
636 case eTypeUInt64:
637 case eTypeUInt128:
638 case eTypeFloat:
639 case eTypeDouble:
640 case eTypeLongDouble:
641 return m_scalar.Double(fail_value);
643 if (success_ptr)
644 *success_ptr = false;
645 return fail_value;
648 long double RegisterValue::GetAsLongDouble(long double fail_value,
649 bool *success_ptr) const {
650 if (success_ptr)
651 *success_ptr = true;
652 switch (m_type) {
653 default:
654 break;
656 case eTypeUInt32:
657 case eTypeUInt64:
658 case eTypeUInt128:
659 case eTypeFloat:
660 case eTypeDouble:
661 case eTypeLongDouble:
662 return m_scalar.LongDouble();
664 if (success_ptr)
665 *success_ptr = false;
666 return fail_value;
669 const void *RegisterValue::GetBytes() const {
670 switch (m_type) {
671 case eTypeInvalid:
672 break;
673 case eTypeUInt8:
674 case eTypeUInt16:
675 case eTypeUInt32:
676 case eTypeUInt64:
677 case eTypeUInt128:
678 case eTypeFloat:
679 case eTypeDouble:
680 case eTypeLongDouble:
681 m_scalar.GetBytes(buffer.bytes);
682 return buffer.bytes.data();
683 case eTypeBytes:
684 return buffer.bytes.data();
686 return nullptr;
689 uint32_t RegisterValue::GetByteSize() const {
690 switch (m_type) {
691 case eTypeInvalid:
692 break;
693 case eTypeUInt8:
694 return 1;
695 case eTypeUInt16:
696 return 2;
697 case eTypeUInt32:
698 case eTypeUInt64:
699 case eTypeUInt128:
700 case eTypeFloat:
701 case eTypeDouble:
702 case eTypeLongDouble:
703 return m_scalar.GetByteSize();
704 case eTypeBytes:
705 return buffer.bytes.size();
707 return 0;
710 bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
711 if (byte_size == 0) {
712 SetUInt64(uint);
713 } else if (byte_size == 1) {
714 SetUInt8(uint);
715 } else if (byte_size <= 2) {
716 SetUInt16(uint);
717 } else if (byte_size <= 4) {
718 SetUInt32(uint);
719 } else if (byte_size <= 8) {
720 SetUInt64(uint);
721 } else if (byte_size <= 16) {
722 SetUInt128(llvm::APInt(128, uint));
723 } else
724 return false;
725 return true;
728 void RegisterValue::SetBytes(const void *bytes, size_t length,
729 lldb::ByteOrder byte_order) {
730 if (bytes && length > 0) {
731 m_type = eTypeBytes;
732 buffer.bytes.resize(length);
733 memcpy(buffer.bytes.data(), bytes, length);
734 buffer.byte_order = byte_order;
735 } else {
736 m_type = eTypeInvalid;
737 buffer.bytes.resize(0);
741 bool RegisterValue::operator==(const RegisterValue &rhs) const {
742 if (m_type == rhs.m_type) {
743 switch (m_type) {
744 case eTypeInvalid:
745 return true;
746 case eTypeUInt8:
747 case eTypeUInt16:
748 case eTypeUInt32:
749 case eTypeUInt64:
750 case eTypeUInt128:
751 case eTypeFloat:
752 case eTypeDouble:
753 case eTypeLongDouble:
754 return m_scalar == rhs.m_scalar;
755 case eTypeBytes:
756 return buffer.bytes == rhs.buffer.bytes;
759 return false;
762 bool RegisterValue::operator!=(const RegisterValue &rhs) const {
763 return !(*this == rhs);
766 bool RegisterValue::ClearBit(uint32_t bit) {
767 switch (m_type) {
768 case eTypeInvalid:
769 break;
771 case eTypeUInt8:
772 case eTypeUInt16:
773 case eTypeUInt32:
774 case eTypeUInt64:
775 case eTypeUInt128:
776 if (bit < (GetByteSize() * 8)) {
777 return m_scalar.ClearBit(bit);
779 break;
781 case eTypeFloat:
782 case eTypeDouble:
783 case eTypeLongDouble:
784 break;
786 case eTypeBytes:
787 if (buffer.byte_order == eByteOrderBig ||
788 buffer.byte_order == eByteOrderLittle) {
789 uint32_t byte_idx;
790 if (buffer.byte_order == eByteOrderBig)
791 byte_idx = buffer.bytes.size() - (bit / 8) - 1;
792 else
793 byte_idx = bit / 8;
795 const uint32_t byte_bit = bit % 8;
796 if (byte_idx < buffer.bytes.size()) {
797 buffer.bytes[byte_idx] &= ~(1u << byte_bit);
798 return true;
801 break;
803 return false;
806 bool RegisterValue::SetBit(uint32_t bit) {
807 switch (m_type) {
808 case eTypeInvalid:
809 break;
811 case eTypeUInt8:
812 case eTypeUInt16:
813 case eTypeUInt32:
814 case eTypeUInt64:
815 case eTypeUInt128:
816 if (bit < (GetByteSize() * 8)) {
817 return m_scalar.SetBit(bit);
819 break;
821 case eTypeFloat:
822 case eTypeDouble:
823 case eTypeLongDouble:
824 break;
826 case eTypeBytes:
827 if (buffer.byte_order == eByteOrderBig ||
828 buffer.byte_order == eByteOrderLittle) {
829 uint32_t byte_idx;
830 if (buffer.byte_order == eByteOrderBig)
831 byte_idx = buffer.bytes.size() - (bit / 8) - 1;
832 else
833 byte_idx = bit / 8;
835 const uint32_t byte_bit = bit % 8;
836 if (byte_idx < buffer.bytes.size()) {
837 buffer.bytes[byte_idx] |= (1u << byte_bit);
838 return true;
841 break;
843 return false;