[mlir][int-range] Limit xor int range inference to i1 (#116968)
[llvm-project.git] / lldb / source / Utility / Scalar.cpp
blobf07a9f3bed00c7835c5e55a20217c0e423e060af
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 //===----------------------------------------------------------------------===//
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"
21 #include <cinttypes>
22 #include <cstdio>
24 using namespace lldb;
25 using namespace lldb_private;
27 using llvm::APFloat;
28 using llvm::APInt;
29 using llvm::APSInt;
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());
40 llvm_unreachable("Unhandled category!");
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};
51 llvm_unreachable("Unsupported semantics!");
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());
69 PromotionKey lhs_key = lhs.GetPromoKey();
70 PromotionKey rhs_key = rhs.GetPromoKey();
72 if (lhs_key > rhs_key)
73 Promote(rhs, lhs);
74 else if (rhs_key > lhs_key)
75 Promote(lhs, rhs);
77 // Make sure our type promotion worked as expected
78 if (lhs.GetPromoKey() == rhs.GetPromoKey())
79 return lhs.GetType(); // Return the resulting type
81 // Return the void type (zero) if we fail to promote either of the values.
82 return Scalar::e_void;
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;
91 auto buffer_up = std::make_unique<DataBufferHeap>(byte_size, 0);
92 GetBytes(buffer_up->GetData());
93 lldb::offset_t offset = 0;
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;
109 data.SetData(std::move(buffer_up), offset, byte_size);
110 data.SetByteOrder(endian::InlHostByteOrder());
111 return true;
114 void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const {
115 assert(storage.size() >= GetByteSize());
117 const auto &store = [&](const llvm::APInt &val) {
118 StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8);
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;
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;
141 return 0;
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();
153 return false;
156 void Scalar::GetValue(Stream &s, bool show_type) const {
157 if (show_type)
158 s.Printf("(%s) ", GetTypeAsCString());
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;
174 void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) {
175 m_integer.setIsSigned(sign);
176 m_integer = m_integer.extOrTrunc(bits);
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;
191 return false;
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);
213 if (success)
214 m_type = e_float;
215 return success;
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";
227 return "???";
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;
239 llvm_unreachable("Unrecognized type!");
242 bool Scalar::MakeSigned() {
243 bool success = false;
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;
257 return success;
260 bool Scalar::MakeUnsigned() {
261 bool success = false;
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;
275 return success;
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);
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();
296 case e_float:
297 return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value)
298 .getSExtValue();
300 return fail_value;
303 signed char Scalar::SChar(signed char fail_value) const {
304 return GetAs<signed char>(fail_value);
307 unsigned char Scalar::UChar(unsigned char fail_value) const {
308 return GetAs<unsigned char>(fail_value);
311 short Scalar::SShort(short fail_value) const {
312 return GetAs<short>(fail_value);
315 unsigned short Scalar::UShort(unsigned short fail_value) const {
316 return GetAs<unsigned short>(fail_value);
319 int Scalar::SInt(int fail_value) const { return GetAs<int>(fail_value); }
321 unsigned int Scalar::UInt(unsigned int fail_value) const {
322 return GetAs<unsigned int>(fail_value);
325 long Scalar::SLong(long fail_value) const { return GetAs<long>(fail_value); }
327 unsigned long Scalar::ULong(unsigned long fail_value) const {
328 return GetAs<unsigned long>(fail_value);
331 long long Scalar::SLongLong(long long fail_value) const {
332 return GetAs<long long>(fail_value);
335 unsigned long long Scalar::ULongLong(unsigned long long fail_value) const {
336 return GetAs<unsigned long long>(fail_value);
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);
348 return fail_value;
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);
360 return fail_value;
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);
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();
380 return fail_value;
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);
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();
400 return fail_value;
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));
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;
418 case e_float:
419 m_float = copy.m_float + rhs.m_float;
420 break;
423 return *this;
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;
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;
439 m_type = e_void;
440 return false;
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;
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;
460 break;
462 return *this;
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;
473 bool Scalar::AbsoluteValue() {
474 switch (m_type) {
475 case e_void:
476 break;
478 case e_int:
479 if (m_integer.isNegative())
480 m_integer = -m_integer;
481 return true;
483 case e_float:
484 m_float.clearSign();
485 return true;
487 return false;
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;
501 return false;
504 bool Scalar::OnesComplement() {
505 if (m_type == e_int) {
506 m_integer = ~m_integer;
507 return true;
510 return false;
513 const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
514 Scalar result = lhs;
515 result += rhs;
516 return result;
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;
533 return result;
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;
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;
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;
571 return result;
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;
582 return result;
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;
593 return result;
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;
604 result.m_type = Scalar::e_void;
605 return result;
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;
616 return result;
619 const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) {
620 Scalar result = lhs;
621 result <<= rhs;
622 return result;
625 const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) {
626 Scalar result = lhs;
627 result >>= rhs;
628 return result;
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.");
637 switch (encoding) {
638 case eEncodingInvalid:
639 return Status::FromErrorString("Invalid encoding.");
640 break;
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;
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;
667 m_type = e_int;
668 m_integer =
669 APSInt(std::move(integer), !is_signed).extOrTrunc(8 * byte_size);
670 break;
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;
691 case eEncodingVector:
692 return Status::FromErrorString("vector encoding unsupported.");
693 break;
695 if (error.Fail())
696 m_type = e_void;
698 return error;
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);
725 break;
727 case lldb::eEncodingIEEE754: {
728 lldb::offset_t offset = 0;
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;
742 return error;
745 bool Scalar::SignExtend(uint32_t sign_bit_pos) {
746 const uint32_t max_bit_pos = GetByteSize() * 8;
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;
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());
763 return true;
765 break;
768 return false;
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;
781 const size_t src_len = data.GetByteSize();
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");
793 return bytes_copied;
796 bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {
797 if (bit_size == 0)
798 return true;
800 switch (m_type) {
801 case Scalar::e_void:
802 case Scalar::e_float:
803 break;
805 case Scalar::e_int:
806 m_integer >>= bit_offset;
807 m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize());
808 return true;
810 return false;
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);
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;
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;
849 default:
850 const llvm::fltSemantics &sem = APFloat::IEEEsingle();
851 return llvm::APFloat::getNaN(sem);
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;
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);
872 return APFloat::cmpUnordered;
875 bool lldb_private::operator==(const Scalar &lhs, const Scalar &rhs) {
876 return compare(lhs, rhs) == APFloat::cmpEqual;
879 bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) {
880 return compare(lhs, rhs) != APFloat::cmpEqual;
883 bool lldb_private::operator<(const Scalar &lhs, const Scalar &rhs) {
884 return compare(lhs, rhs) == APFloat::cmpLessThan;
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;
892 bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) {
893 return compare(lhs, rhs) == APFloat::cmpGreaterThan;
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;
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;
911 return false;
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;
924 return false;
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();