brintos

brintos / llvm-project-archived public Read only

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