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