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