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