1 //===-- Scalar.cpp --------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Utility/Scalar.h" 10 #include "lldb/Utility/DataBufferHeap.h" 11 #include "lldb/Utility/DataExtractor.h" 12 #include "lldb/Utility/Endian.h" 13 #include "lldb/Utility/Status.h" 14 #include "lldb/Utility/Stream.h" 15 #include "lldb/Utility/StreamString.h" 16 #include "lldb/lldb-types.h" 17 #include "llvm/ADT/APSInt.h" 18 #include "llvm/ADT/SmallString.h" 19 #include "llvm/ADT/StringExtras.h" 20 21 #include <cinttypes> 22 #include <cstdio> 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 using llvm::APFloat; 28 using llvm::APInt; 29 using llvm::APSInt; 30 31 Scalar::PromotionKey Scalar::GetPromoKey() const { 32 switch (m_type) { 33 case e_void: 34 return PromotionKey{e_void, 0, false}; 35 case e_int: 36 return PromotionKey{e_int, m_integer.getBitWidth(), m_integer.isUnsigned()}; 37 case e_float: 38 return GetFloatPromoKey(m_float.getSemantics()); 39 } 40 llvm_unreachable("Unhandled category!"); 41 } 42 43 Scalar::PromotionKey Scalar::GetFloatPromoKey(const llvm::fltSemantics &sem) { 44 static const llvm::fltSemantics *const order[] = { 45 &APFloat::IEEEsingle(), &APFloat::IEEEdouble(), 46 &APFloat::x87DoubleExtended()}; 47 for (const auto &entry : llvm::enumerate(order)) { 48 if (entry.value() == &sem) 49 return PromotionKey{e_float, entry.index(), false}; 50 } 51 llvm_unreachable("Unsupported semantics!"); 52 } 53 54 // Promote to max type currently follows the ANSI C rule for type promotion in 55 // expressions. 56 Scalar::Type Scalar::PromoteToMaxType(Scalar &lhs, Scalar &rhs) { 57 const auto &Promote = [](Scalar &a, const Scalar &b) { 58 switch (b.GetType()) { 59 case e_void: 60 break; 61 case e_int: 62 a.IntegralPromote(b.m_integer.getBitWidth(), b.m_integer.isSigned()); 63 break; 64 case e_float: 65 a.FloatPromote(b.m_float.getSemantics()); 66 } 67 }; 68 69 PromotionKey lhs_key = lhs.GetPromoKey(); 70 PromotionKey rhs_key = rhs.GetPromoKey(); 71 72 if (lhs_key > rhs_key) 73 Promote(rhs, lhs); 74 else if (rhs_key > lhs_key) 75 Promote(lhs, rhs); 76 77 // Make sure our type promotion worked as expected 78 if (lhs.GetPromoKey() == rhs.GetPromoKey()) 79 return lhs.GetType(); // Return the resulting type 80 81 // Return the void type (zero) if we fail to promote either of the values. 82 return Scalar::e_void; 83 } 84 85 bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const { 86 size_t byte_size = GetByteSize(); 87 if (byte_size == 0) { 88 data.Clear(); 89 return false; 90 } 91 auto buffer_up = std::make_unique<DataBufferHeap>(byte_size, 0); 92 GetBytes(buffer_up->GetData()); 93 lldb::offset_t offset = 0; 94 95 if (limit_byte_size < byte_size) { 96 if (endian::InlHostByteOrder() == eByteOrderLittle) { 97 // On little endian systems if we want fewer bytes from the current 98 // type we just specify fewer bytes since the LSByte is first... 99 byte_size = limit_byte_size; 100 } else if (endian::InlHostByteOrder() == eByteOrderBig) { 101 // On big endian systems if we want fewer bytes from the current type 102 // have to advance our initial byte pointer and trim down the number of 103 // bytes since the MSByte is first 104 offset = byte_size - limit_byte_size; 105 byte_size = limit_byte_size; 106 } 107 } 108 109 data.SetData(std::move(buffer_up), offset, byte_size); 110 data.SetByteOrder(endian::InlHostByteOrder()); 111 return true; 112 } 113 114 void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const { 115 assert(storage.size() >= GetByteSize()); 116 117 const auto &store = [&](const llvm::APInt &val) { 118 StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8); 119 }; 120 switch (m_type) { 121 case e_void: 122 break; 123 case e_int: 124 store(m_integer); 125 break; 126 case e_float: 127 store(m_float.bitcastToAPInt()); 128 break; 129 } 130 } 131 132 size_t Scalar::GetByteSize() const { 133 switch (m_type) { 134 case e_void: 135 break; 136 case e_int: 137 return (m_integer.getBitWidth() + 7) / 8; 138 case e_float: 139 return (m_float.bitcastToAPInt().getBitWidth() + 7) / 8; 140 } 141 return 0; 142 } 143 144 bool Scalar::IsZero() const { 145 switch (m_type) { 146 case e_void: 147 break; 148 case e_int: 149 return m_integer.isZero(); 150 case e_float: 151 return m_float.isZero(); 152 } 153 return false; 154 } 155 156 void Scalar::GetValue(Stream &s, bool show_type) const { 157 if (show_type) 158 s.Printf("(%s) ", GetTypeAsCString()); 159 160 switch (m_type) { 161 case e_void: 162 break; 163 case e_int: 164 s.PutCString(llvm::toString(m_integer, 10)); 165 break; 166 case e_float: 167 llvm::SmallString<24> string; 168 m_float.toString(string); 169 s.PutCString(string); 170 break; 171 } 172 } 173 174 void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) { 175 m_integer.setIsSigned(sign); 176 m_integer = m_integer.extOrTrunc(bits); 177 } 178 179 bool Scalar::IntegralPromote(uint16_t bits, bool sign) { 180 switch (m_type) { 181 case e_void: 182 case e_float: 183 break; 184 case e_int: 185 if (GetPromoKey() > PromotionKey(e_int, bits, !sign)) 186 break; 187 m_integer = m_integer.extOrTrunc(bits); 188 m_integer.setIsSigned(sign); 189 return true; 190 } 191 return false; 192 } 193 194 bool Scalar::FloatPromote(const llvm::fltSemantics &semantics) { 195 bool success = false; 196 switch (m_type) { 197 case e_void: 198 break; 199 case e_int: 200 m_float = llvm::APFloat(semantics); 201 m_float.convertFromAPInt(m_integer, m_integer.isSigned(), 202 llvm::APFloat::rmNearestTiesToEven); 203 success = true; 204 break; 205 case e_float: 206 if (GetFloatPromoKey(semantics) < GetFloatPromoKey(m_float.getSemantics())) 207 break; 208 bool ignore; 209 success = true; 210 m_float.convert(semantics, llvm::APFloat::rmNearestTiesToEven, &ignore); 211 } 212 213 if (success) 214 m_type = e_float; 215 return success; 216 } 217 218 const char *Scalar::GetValueTypeAsCString(Scalar::Type type) { 219 switch (type) { 220 case e_void: 221 return "void"; 222 case e_int: 223 return "int"; 224 case e_float: 225 return "float"; 226 } 227 return "???"; 228 } 229 230 bool Scalar::IsSigned() const { 231 switch (m_type) { 232 case e_void: 233 return false; 234 case e_int: 235 return m_integer.isSigned(); 236 case e_float: 237 return true; 238 } 239 llvm_unreachable("Unrecognized type!"); 240 } 241 242 bool Scalar::MakeSigned() { 243 bool success = false; 244 245 switch (m_type) { 246 case e_void: 247 break; 248 case e_int: 249 m_integer.setIsSigned(true); 250 success = true; 251 break; 252 case e_float: 253 success = true; 254 break; 255 } 256 257 return success; 258 } 259 260 bool Scalar::MakeUnsigned() { 261 bool success = false; 262 263 switch (m_type) { 264 case e_void: 265 break; 266 case e_int: 267 m_integer.setIsUnsigned(true); 268 success = true; 269 break; 270 case e_float: 271 success = true; 272 break; 273 } 274 275 return success; 276 } 277 278 static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits, 279 bool is_unsigned) { 280 llvm::APSInt result(bits, is_unsigned); 281 bool isExact; 282 f.convertToInteger(result, llvm::APFloat::rmTowardZero, &isExact); 283 return std::move(result); 284 } 285 286 template <typename T> T Scalar::GetAs(T fail_value) const { 287 switch (m_type) { 288 case e_void: 289 break; 290 case e_int: { 291 APSInt ext = m_integer.extOrTrunc(sizeof(T) * 8); 292 if (ext.isSigned()) 293 return ext.getSExtValue(); 294 return ext.getZExtValue(); 295 } 296 case e_float: 297 return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value) 298 .getSExtValue(); 299 } 300 return fail_value; 301 } 302 303 signed char Scalar::SChar(signed char fail_value) const { 304 return GetAs<signed char>(fail_value); 305 } 306 307 unsigned char Scalar::UChar(unsigned char fail_value) const { 308 return GetAs<unsigned char>(fail_value); 309 } 310 311 short Scalar::SShort(short fail_value) const { 312 return GetAs<short>(fail_value); 313 } 314 315 unsigned short Scalar::UShort(unsigned short fail_value) const { 316 return GetAs<unsigned short>(fail_value); 317 } 318 319 int Scalar::SInt(int fail_value) const { return GetAs<int>(fail_value); } 320 321 unsigned int Scalar::UInt(unsigned int fail_value) const { 322 return GetAs<unsigned int>(fail_value); 323 } 324 325 long Scalar::SLong(long fail_value) const { return GetAs<long>(fail_value); } 326 327 unsigned long Scalar::ULong(unsigned long fail_value) const { 328 return GetAs<unsigned long>(fail_value); 329 } 330 331 long long Scalar::SLongLong(long long fail_value) const { 332 return GetAs<long long>(fail_value); 333 } 334 335 unsigned long long Scalar::ULongLong(unsigned long long fail_value) const { 336 return GetAs<unsigned long long>(fail_value); 337 } 338 339 llvm::APInt Scalar::SInt128(const llvm::APInt &fail_value) const { 340 switch (m_type) { 341 case e_void: 342 break; 343 case e_int: 344 return m_integer; 345 case e_float: 346 return ToAPInt(m_float, 128, /*is_unsigned=*/false); 347 } 348 return fail_value; 349 } 350 351 llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const { 352 switch (m_type) { 353 case e_void: 354 break; 355 case e_int: 356 return m_integer; 357 case e_float: 358 return ToAPInt(m_float, 128, /*is_unsigned=*/true); 359 } 360 return fail_value; 361 } 362 363 float Scalar::Float(float fail_value) const { 364 switch (m_type) { 365 case e_void: 366 break; 367 case e_int: 368 if (m_integer.isSigned()) 369 return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer); 370 return llvm::APIntOps::RoundAPIntToFloat(m_integer); 371 372 case e_float: { 373 APFloat result = m_float; 374 bool losesInfo; 375 result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, 376 &losesInfo); 377 return result.convertToFloat(); 378 } 379 } 380 return fail_value; 381 } 382 383 double Scalar::Double(double fail_value) const { 384 switch (m_type) { 385 case e_void: 386 break; 387 case e_int: 388 if (m_integer.isSigned()) 389 return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer); 390 return llvm::APIntOps::RoundAPIntToDouble(m_integer); 391 392 case e_float: { 393 APFloat result = m_float; 394 bool losesInfo; 395 result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, 396 &losesInfo); 397 return result.convertToDouble(); 398 } 399 } 400 return fail_value; 401 } 402 403 long double Scalar::LongDouble(long double fail_value) const { 404 /// No way to get more precision at the moment. 405 return static_cast<long double>(Double(fail_value)); 406 } 407 408 Scalar &Scalar::operator+=(Scalar rhs) { 409 Scalar copy = *this; 410 if ((m_type = PromoteToMaxType(copy, rhs)) != Scalar::e_void) { 411 switch (m_type) { 412 case e_void: 413 break; 414 case e_int: 415 m_integer = copy.m_integer + rhs.m_integer; 416 break; 417 418 case e_float: 419 m_float = copy.m_float + rhs.m_float; 420 break; 421 } 422 } 423 return *this; 424 } 425 426 Scalar &Scalar::operator<<=(const Scalar &rhs) { 427 if (m_type == e_int && rhs.m_type == e_int) 428 static_cast<APInt &>(m_integer) <<= rhs.m_integer; 429 else 430 m_type = e_void; 431 return *this; 432 } 433 434 bool Scalar::ShiftRightLogical(const Scalar &rhs) { 435 if (m_type == e_int && rhs.m_type == e_int) { 436 m_integer = m_integer.lshr(rhs.m_integer); 437 return true; 438 } 439 m_type = e_void; 440 return false; 441 } 442 443 Scalar &Scalar::operator>>=(const Scalar &rhs) { 444 switch (m_type) { 445 case e_void: 446 case e_float: 447 m_type = e_void; 448 break; 449 450 case e_int: 451 switch (rhs.m_type) { 452 case e_void: 453 case e_float: 454 m_type = e_void; 455 break; 456 case e_int: 457 m_integer = m_integer.ashr(rhs.m_integer); 458 break; 459 } 460 break; 461 } 462 return *this; 463 } 464 465 Scalar &Scalar::operator&=(const Scalar &rhs) { 466 if (m_type == e_int && rhs.m_type == e_int) 467 m_integer &= rhs.m_integer; 468 else 469 m_type = e_void; 470 return *this; 471 } 472 473 bool Scalar::AbsoluteValue() { 474 switch (m_type) { 475 case e_void: 476 break; 477 478 case e_int: 479 if (m_integer.isNegative()) 480 m_integer = -m_integer; 481 return true; 482 483 case e_float: 484 m_float.clearSign(); 485 return true; 486 } 487 return false; 488 } 489 490 bool Scalar::UnaryNegate() { 491 switch (m_type) { 492 case e_void: 493 break; 494 case e_int: 495 m_integer = -m_integer; 496 return true; 497 case e_float: 498 m_float.changeSign(); 499 return true; 500 } 501 return false; 502 } 503 504 bool Scalar::OnesComplement() { 505 if (m_type == e_int) { 506 m_integer = ~m_integer; 507 return true; 508 } 509 510 return false; 511 } 512 513 const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) { 514 Scalar result = lhs; 515 result += rhs; 516 return result; 517 } 518 519 const Scalar lldb_private::operator-(Scalar lhs, Scalar rhs) { 520 Scalar result; 521 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 522 switch (result.m_type) { 523 case Scalar::e_void: 524 break; 525 case Scalar::e_int: 526 result.m_integer = lhs.m_integer - rhs.m_integer; 527 break; 528 case Scalar::e_float: 529 result.m_float = lhs.m_float - rhs.m_float; 530 break; 531 } 532 } 533 return result; 534 } 535 536 const Scalar lldb_private::operator/(Scalar lhs, Scalar rhs) { 537 Scalar result; 538 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void && 539 !rhs.IsZero()) { 540 switch (result.m_type) { 541 case Scalar::e_void: 542 break; 543 case Scalar::e_int: 544 result.m_integer = lhs.m_integer / rhs.m_integer; 545 return result; 546 case Scalar::e_float: 547 result.m_float = lhs.m_float / rhs.m_float; 548 return result; 549 } 550 } 551 // For division only, the only way it should make it here is if a promotion 552 // failed, or if we are trying to do a divide by zero. 553 result.m_type = Scalar::e_void; 554 return result; 555 } 556 557 const Scalar lldb_private::operator*(Scalar lhs, Scalar rhs) { 558 Scalar result; 559 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 560 switch (result.m_type) { 561 case Scalar::e_void: 562 break; 563 case Scalar::e_int: 564 result.m_integer = lhs.m_integer * rhs.m_integer; 565 break; 566 case Scalar::e_float: 567 result.m_float = lhs.m_float * rhs.m_float; 568 break; 569 } 570 } 571 return result; 572 } 573 574 const Scalar lldb_private::operator&(Scalar lhs, Scalar rhs) { 575 Scalar result; 576 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 577 if (result.m_type == Scalar::e_int) 578 result.m_integer = lhs.m_integer & rhs.m_integer; 579 else 580 result.m_type = Scalar::e_void; 581 } 582 return result; 583 } 584 585 const Scalar lldb_private::operator|(Scalar lhs, Scalar rhs) { 586 Scalar result; 587 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 588 if (result.m_type == Scalar::e_int) 589 result.m_integer = lhs.m_integer | rhs.m_integer; 590 else 591 result.m_type = Scalar::e_void; 592 } 593 return result; 594 } 595 596 const Scalar lldb_private::operator%(Scalar lhs, Scalar rhs) { 597 Scalar result; 598 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 599 if (!rhs.IsZero() && result.m_type == Scalar::e_int) { 600 result.m_integer = lhs.m_integer % rhs.m_integer; 601 return result; 602 } 603 } 604 result.m_type = Scalar::e_void; 605 return result; 606 } 607 608 const Scalar lldb_private::operator^(Scalar lhs, Scalar rhs) { 609 Scalar result; 610 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 611 if (result.m_type == Scalar::e_int) 612 result.m_integer = lhs.m_integer ^ rhs.m_integer; 613 else 614 result.m_type = Scalar::e_void; 615 } 616 return result; 617 } 618 619 const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) { 620 Scalar result = lhs; 621 result <<= rhs; 622 return result; 623 } 624 625 const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) { 626 Scalar result = lhs; 627 result >>= rhs; 628 return result; 629 } 630 631 Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding, 632 size_t byte_size) { 633 Status error; 634 if (value_str == nullptr || value_str[0] == '\0') { 635 return Status::FromErrorString("Invalid c-string value string."); 636 } 637 switch (encoding) { 638 case eEncodingInvalid: 639 return Status::FromErrorString("Invalid encoding."); 640 break; 641 642 case eEncodingSint: 643 case eEncodingUint: { 644 llvm::StringRef str = value_str; 645 bool is_signed = encoding == eEncodingSint; 646 bool is_negative = is_signed && str.consume_front("-"); 647 APInt integer; 648 if (str.getAsInteger(0, integer)) { 649 error = Status::FromErrorStringWithFormatv( 650 "'{0}' is not a valid integer string value", value_str); 651 break; 652 } 653 bool fits; 654 if (is_signed) { 655 integer = integer.zext(integer.getBitWidth() + 1); 656 if (is_negative) 657 integer.negate(); 658 fits = integer.isSignedIntN(byte_size * 8); 659 } else 660 fits = integer.isIntN(byte_size * 8); 661 if (!fits) { 662 error = Status::FromErrorStringWithFormatv( 663 "value {0} is too large to fit in a {1} byte integer value", 664 value_str, byte_size); 665 break; 666 } 667 m_type = e_int; 668 m_integer = 669 APSInt(std::move(integer), !is_signed).extOrTrunc(8 * byte_size); 670 break; 671 } 672 673 case eEncodingIEEE754: { 674 // FIXME: It's not possible to unambiguously map a byte size to a floating 675 // point type. This function should be refactored to take an explicit 676 // semantics argument. 677 const llvm::fltSemantics &sem = 678 byte_size <= 4 ? APFloat::IEEEsingle() 679 : byte_size <= 8 ? APFloat::IEEEdouble() 680 : APFloat::x87DoubleExtended(); 681 APFloat f(sem); 682 if (llvm::Expected<APFloat::opStatus> op = 683 f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) { 684 m_type = e_float; 685 m_float = std::move(f); 686 } else 687 error = Status::FromError(op.takeError()); 688 break; 689 } 690 691 case eEncodingVector: 692 return Status::FromErrorString("vector encoding unsupported."); 693 break; 694 } 695 if (error.Fail()) 696 m_type = e_void; 697 698 return error; 699 } 700 701 Status Scalar::SetValueFromData(const DataExtractor &data, 702 lldb::Encoding encoding, size_t byte_size) { 703 Status error; 704 switch (encoding) { 705 case lldb::eEncodingInvalid: 706 return Status::FromErrorString("invalid encoding"); 707 break; 708 case lldb::eEncodingVector: 709 return Status::FromErrorString("vector encoding unsupported"); 710 break; 711 case lldb::eEncodingUint: 712 case lldb::eEncodingSint: { 713 if (data.GetByteSize() < byte_size) 714 return Status::FromErrorString("insufficient data"); 715 m_type = e_int; 716 m_integer = 717 APSInt(APInt::getZero(8 * byte_size), encoding == eEncodingUint); 718 if (data.GetByteOrder() == endian::InlHostByteOrder()) { 719 llvm::LoadIntFromMemory(m_integer, data.GetDataStart(), byte_size); 720 } else { 721 std::vector<uint8_t> buffer(byte_size); 722 std::copy_n(data.GetDataStart(), byte_size, buffer.rbegin()); 723 llvm::LoadIntFromMemory(m_integer, buffer.data(), byte_size); 724 } 725 break; 726 } 727 case lldb::eEncodingIEEE754: { 728 lldb::offset_t offset = 0; 729 730 if (byte_size == sizeof(float)) 731 operator=(data.GetFloat(&offset)); 732 else if (byte_size == sizeof(double)) 733 operator=(data.GetDouble(&offset)); 734 else if (byte_size == sizeof(long double)) 735 operator=(data.GetLongDouble(&offset)); 736 else 737 return Status::FromErrorStringWithFormatv( 738 "unsupported float byte size: {0}", static_cast<uint64_t>(byte_size)); 739 } break; 740 } 741 742 return error; 743 } 744 745 bool Scalar::SignExtend(uint32_t sign_bit_pos) { 746 const uint32_t max_bit_pos = GetByteSize() * 8; 747 748 if (sign_bit_pos < max_bit_pos) { 749 switch (m_type) { 750 case Scalar::e_void: 751 case Scalar::e_float: 752 return false; 753 754 case Scalar::e_int: 755 if (sign_bit_pos < (max_bit_pos - 1)) { 756 llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1); 757 llvm::APInt bitwize_and = m_integer & sign_bit; 758 if (bitwize_and.getBoolValue()) { 759 llvm::APInt mask = 760 ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1); 761 m_integer |= APSInt(std::move(mask), m_integer.isUnsigned()); 762 } 763 return true; 764 } 765 break; 766 } 767 } 768 return false; 769 } 770 771 size_t Scalar::GetAsMemoryData(void *dst, size_t dst_len, 772 lldb::ByteOrder dst_byte_order, 773 Status &error) const { 774 // Get a data extractor that points to the native scalar data 775 DataExtractor data; 776 if (!GetData(data)) { 777 error = Status::FromErrorString("invalid scalar value"); 778 return 0; 779 } 780 781 const size_t src_len = data.GetByteSize(); 782 783 // Prepare a memory buffer that contains some or all of the register value 784 const size_t bytes_copied = 785 data.CopyByteOrderedData(0, // src offset 786 src_len, // src length 787 dst, // dst buffer 788 dst_len, // dst length 789 dst_byte_order); // dst byte order 790 if (bytes_copied == 0) 791 error = Status::FromErrorString("failed to copy data"); 792 793 return bytes_copied; 794 } 795 796 bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) { 797 if (bit_size == 0) 798 return true; 799 800 switch (m_type) { 801 case Scalar::e_void: 802 case Scalar::e_float: 803 break; 804 805 case Scalar::e_int: 806 m_integer >>= bit_offset; 807 m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize()); 808 return true; 809 } 810 return false; 811 } 812 813 llvm::APFloat Scalar::CreateAPFloatFromAPSInt(lldb::BasicType basic_type) { 814 switch (basic_type) { 815 case lldb::eBasicTypeFloat: 816 return llvm::APFloat( 817 m_integer.isSigned() 818 ? llvm::APIntOps::RoundSignedAPIntToFloat(m_integer) 819 : llvm::APIntOps::RoundAPIntToFloat(m_integer)); 820 case lldb::eBasicTypeDouble: 821 // No way to get more precision at the moment. 822 case lldb::eBasicTypeLongDouble: 823 return llvm::APFloat( 824 m_integer.isSigned() 825 ? llvm::APIntOps::RoundSignedAPIntToDouble(m_integer) 826 : llvm::APIntOps::RoundAPIntToDouble(m_integer)); 827 default: 828 const llvm::fltSemantics &sem = APFloat::IEEEsingle(); 829 return llvm::APFloat::getNaN(sem); 830 } 831 } 832 833 llvm::APFloat Scalar::CreateAPFloatFromAPFloat(lldb::BasicType basic_type) { 834 switch (basic_type) { 835 case lldb::eBasicTypeFloat: { 836 bool loses_info; 837 m_float.convert(llvm::APFloat::IEEEsingle(), 838 llvm::APFloat::rmNearestTiesToEven, &loses_info); 839 return m_float; 840 } 841 case lldb::eBasicTypeDouble: 842 // No way to get more precision at the moment. 843 case lldb::eBasicTypeLongDouble: { 844 bool loses_info; 845 m_float.convert(llvm::APFloat::IEEEdouble(), 846 llvm::APFloat::rmNearestTiesToEven, &loses_info); 847 return m_float; 848 } 849 default: 850 const llvm::fltSemantics &sem = APFloat::IEEEsingle(); 851 return llvm::APFloat::getNaN(sem); 852 } 853 } 854 855 APFloat::cmpResult lldb_private::compare(Scalar lhs, Scalar rhs) { 856 // If either entry is void then we can just compare the types 857 if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void) 858 return lhs.m_type == rhs.m_type ? APFloat::cmpEqual : APFloat::cmpUnordered; 859 860 switch (Scalar::PromoteToMaxType(lhs, rhs)) { 861 case Scalar::e_void: 862 break; 863 case Scalar::e_int: 864 if (lhs.m_integer < rhs.m_integer) 865 return APFloat::cmpLessThan; 866 if (lhs.m_integer > rhs.m_integer) 867 return APFloat::cmpGreaterThan; 868 return APFloat::cmpEqual; 869 case Scalar::e_float: 870 return lhs.m_float.compare(rhs.m_float); 871 } 872 return APFloat::cmpUnordered; 873 } 874 875 bool lldb_private::operator==(const Scalar &lhs, const Scalar &rhs) { 876 return compare(lhs, rhs) == APFloat::cmpEqual; 877 } 878 879 bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) { 880 return compare(lhs, rhs) != APFloat::cmpEqual; 881 } 882 883 bool lldb_private::operator<(const Scalar &lhs, const Scalar &rhs) { 884 return compare(lhs, rhs) == APFloat::cmpLessThan; 885 } 886 887 bool lldb_private::operator<=(const Scalar &lhs, const Scalar &rhs) { 888 APFloat::cmpResult Res = compare(lhs, rhs); 889 return Res == APFloat::cmpLessThan || Res == APFloat::cmpEqual; 890 } 891 892 bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) { 893 return compare(lhs, rhs) == APFloat::cmpGreaterThan; 894 } 895 896 bool lldb_private::operator>=(const Scalar &lhs, const Scalar &rhs) { 897 APFloat::cmpResult Res = compare(lhs, rhs); 898 return Res == APFloat::cmpGreaterThan || Res == APFloat::cmpEqual; 899 } 900 901 bool Scalar::ClearBit(uint32_t bit) { 902 switch (m_type) { 903 case e_void: 904 break; 905 case e_int: 906 m_integer.clearBit(bit); 907 return true; 908 case e_float: 909 break; 910 } 911 return false; 912 } 913 914 bool Scalar::SetBit(uint32_t bit) { 915 switch (m_type) { 916 case e_void: 917 break; 918 case e_int: 919 m_integer.setBit(bit); 920 return true; 921 case e_float: 922 break; 923 } 924 return false; 925 } 926 927 llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &os, const Scalar &scalar) { 928 StreamString s; 929 scalar.GetValue(s, /*show_type*/ true); 930 return os << s.GetString(); 931 } 932