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