Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Utility/Scalar.cpp
39587 views
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
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());
39
}
40
llvm_unreachable("Unhandled category!");
41
}
42
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.
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
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;
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
114
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
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;
140
}
141
return 0;
142
}
143
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();
152
}
153
return false;
154
}
155
156
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
174
void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) {
175
m_integer.setIsSigned(sign);
176
m_integer = m_integer.extOrTrunc(bits);
177
}
178
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
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
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
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;
238
}
239
llvm_unreachable("Unrecognized type!");
240
}
241
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
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
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
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();
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
303
signed char Scalar::SChar(signed char fail_value) const {
304
return GetAs<signed char>(fail_value);
305
}
306
307
unsigned char Scalar::UChar(unsigned char fail_value) const {
308
return GetAs<unsigned char>(fail_value);
309
}
310
311
short Scalar::SShort(short fail_value) const {
312
return GetAs<short>(fail_value);
313
}
314
315
unsigned short Scalar::UShort(unsigned short fail_value) const {
316
return GetAs<unsigned short>(fail_value);
317
}
318
319
int Scalar::SInt(int fail_value) const { return GetAs<int>(fail_value); }
320
321
unsigned int Scalar::UInt(unsigned int fail_value) const {
322
return GetAs<unsigned int>(fail_value);
323
}
324
325
long Scalar::SLong(long fail_value) const { return GetAs<long>(fail_value); }
326
327
unsigned long Scalar::ULong(unsigned long fail_value) const {
328
return GetAs<unsigned long>(fail_value);
329
}
330
331
long long Scalar::SLongLong(long long fail_value) const {
332
return GetAs<long long>(fail_value);
333
}
334
335
unsigned long long Scalar::ULongLong(unsigned long long fail_value) const {
336
return GetAs<unsigned long long>(fail_value);
337
}
338
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);
347
}
348
return fail_value;
349
}
350
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);
359
}
360
return fail_value;
361
}
362
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);
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
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);
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
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));
406
}
407
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
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
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
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
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
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
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
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
513
const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
514
Scalar result = lhs;
515
result += rhs;
516
return result;
517
}
518
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
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
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
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
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
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
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
619
const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) {
620
Scalar result = lhs;
621
result <<= rhs;
622
return result;
623
}
624
625
const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) {
626
Scalar result = lhs;
627
result >>= rhs;
628
return result;
629
}
630
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
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
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
772
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
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
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
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
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
875
bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) {
876
return !(lhs == rhs);
877
}
878
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
897
bool lldb_private::operator<=(const Scalar &lhs, const Scalar &rhs) {
898
return !(rhs < lhs);
899
}
900
901
bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) {
902
return rhs < lhs;
903
}
904
905
bool lldb_private::operator>=(const Scalar &lhs, const Scalar &rhs) {
906
return !(lhs < rhs);
907
}
908
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
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
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
941