17 #include "llvm/ADT/APSInt.h"
18 #include "llvm/ADT/SmallString.h"
35 return PromotionKey{e_int, m_integer.getBitWidth(), m_integer.isUnsigned()};
37 return GetFloatPromoKey(m_float.getSemantics());
39 llvm_unreachable(
"Unhandled category!");
43 static const llvm::fltSemantics *
const order[] = {
44 &APFloat::IEEEsingle(), &APFloat::IEEEdouble(),
45 &APFloat::x87DoubleExtended()};
46 for (
const auto &entry : llvm::enumerate(order)) {
47 if (entry.value() == &sem)
50 llvm_unreachable(
"Unsupported semantics!");
57 switch (b.GetType()) {
71 if (lhs_key > rhs_key)
73 else if (rhs_key > lhs_key)
81 return Scalar::e_void;
84 bool Scalar::GetData(
DataExtractor &data,
size_t limit_byte_size)
const {
85 size_t byte_size = GetByteSize();
90 auto buffer_up = std::make_unique<DataBufferHeap>(byte_size, 0);
91 GetBytes(buffer_up->GetData());
94 if (limit_byte_size < byte_size) {
98 byte_size = limit_byte_size;
103 offset = byte_size - limit_byte_size;
104 byte_size = limit_byte_size;
108 data.
SetData(std::move(buffer_up), offset, byte_size);
113 void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage)
const {
114 assert(storage.size() >= GetByteSize());
116 const auto &store = [&](
const llvm::APInt &val) {
117 StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8);
126 store(m_float.bitcastToAPInt());
131 size_t Scalar::GetByteSize()
const {
136 return (m_integer.getBitWidth() / 8);
138 return m_float.bitcastToAPInt().getBitWidth() / 8;
148 return m_integer.isNullValue();
150 return m_float.isZero();
155 void Scalar::GetValue(
Stream *s,
bool show_type)
const {
157 s->
Printf(
"(%s) ", GetTypeAsCString());
166 llvm::SmallString<24>
string;
167 m_float.toString(
string);
174 m_integer.setIsSigned(sign);
175 m_integer = m_integer.extOrTrunc(
bits);
186 m_integer = m_integer.extOrTrunc(
bits);
187 m_integer.setIsSigned(sign);
193 bool Scalar::FloatPromote(
const llvm::fltSemantics &semantics) {
194 bool success =
false;
199 m_float = llvm::APFloat(semantics);
200 m_float.convertFromAPInt(m_integer, m_integer.isSigned(),
201 llvm::APFloat::rmNearestTiesToEven);
205 if (GetFloatPromoKey(semantics) < GetFloatPromoKey(m_float.getSemantics()))
209 m_float.convert(semantics, llvm::APFloat::rmNearestTiesToEven, &ignore);
229 bool Scalar::IsSigned()
const {
234 return m_integer.isSigned();
238 llvm_unreachable(
"Unrecognized type!");
241 bool Scalar::MakeSigned() {
242 bool success =
false;
248 m_integer.setIsSigned(
true);
259 bool Scalar::MakeUnsigned() {
260 bool success =
false;
266 m_integer.setIsUnsigned(
true);
279 llvm::APSInt result(
bits, is_unsigned);
281 f.convertToInteger(result, llvm::APFloat::rmTowardZero, &isExact);
282 return std::move(result);
285 template <
typename T> T Scalar::GetAs(T fail_value)
const {
290 APSInt ext = m_integer.extOrTrunc(
sizeof(T) * 8);
292 return ext.getSExtValue();
293 return ext.getZExtValue();
296 return ToAPInt(m_float,
sizeof(T) * 8, std::is_unsigned<T>::value)
302 signed char Scalar::SChar(
signed char fail_value)
const {
303 return GetAs<signed char>(fail_value);
306 unsigned char Scalar::UChar(
unsigned char fail_value)
const {
307 return GetAs<unsigned char>(fail_value);
310 short Scalar::SShort(
short fail_value)
const {
311 return GetAs<short>(fail_value);
314 unsigned short Scalar::UShort(
unsigned short fail_value)
const {
315 return GetAs<unsigned short>(fail_value);
318 int Scalar::SInt(
int fail_value)
const {
return GetAs<int>(fail_value); }
321 return GetAs<unsigned int>(fail_value);
324 long Scalar::SLong(
long fail_value)
const {
return GetAs<long>(fail_value); }
326 unsigned long Scalar::ULong(
unsigned long fail_value)
const {
327 return GetAs<unsigned long>(fail_value);
330 long long Scalar::SLongLong(
long long fail_value)
const {
331 return GetAs<long long>(fail_value);
334 unsigned long long Scalar::ULongLong(
unsigned long long fail_value)
const {
335 return GetAs<unsigned long long>(fail_value);
338 llvm::APInt Scalar::SInt128(
const llvm::APInt &fail_value)
const {
345 return ToAPInt(m_float, 128,
false);
350 llvm::APInt Scalar::UInt128(
const llvm::APInt &fail_value)
const {
357 return ToAPInt(m_float, 128,
true);
362 float Scalar::Float(
float fail_value)
const {
367 if (m_integer.isSigned())
368 return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer);
369 return llvm::APIntOps::RoundAPIntToFloat(m_integer);
372 APFloat result = m_float;
374 result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
376 return result.convertToFloat();
382 double Scalar::Double(
double fail_value)
const {
387 if (m_integer.isSigned())
388 return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer);
389 return llvm::APIntOps::RoundAPIntToDouble(m_integer);
392 APFloat result = m_float;
394 result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
396 return result.convertToDouble();
402 long double Scalar::LongDouble(
long double fail_value)
const {
404 return static_cast<long double>(Double(fail_value));
409 if ((m_type = PromoteToMaxType(copy, rhs)) != Scalar::e_void) {
426 if (m_type == e_int && rhs.
m_type == e_int)
427 static_cast<APInt &
>(m_integer) <<= rhs.
m_integer;
433 bool Scalar::ShiftRightLogical(
const Scalar &rhs) {
434 if (m_type == e_int && rhs.
m_type == e_int) {
435 m_integer = m_integer.lshr(rhs.
m_integer);
456 m_integer = m_integer.ashr(rhs.
m_integer);
465 if (m_type == e_int && rhs.
m_type == e_int)
472 bool Scalar::AbsoluteValue() {
478 if (m_integer.isNegative())
479 m_integer = -m_integer;
489 bool Scalar::UnaryNegate() {
494 m_integer = -m_integer;
497 m_float.changeSign();
503 bool Scalar::OnesComplement() {
504 if (m_type == e_int) {
505 m_integer = ~m_integer;
520 if ((result.
m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
527 case Scalar::e_float:
537 if ((result.
m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void &&
545 case Scalar::e_float:
552 result.
m_type = Scalar::e_void;
558 if ((result.
m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
565 case Scalar::e_float:
575 if ((result.
m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
576 if (result.
m_type == Scalar::e_int)
579 result.
m_type = Scalar::e_void;
586 if ((result.
m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
587 if (result.
m_type == Scalar::e_int)
590 result.
m_type = Scalar::e_void;
597 if ((result.
m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
603 result.
m_type = Scalar::e_void;
609 if ((result.
m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
610 if (result.
m_type == Scalar::e_int)
613 result.
m_type = Scalar::e_void;
633 if (value_str ==
nullptr || value_str[0] ==
'\0') {
634 error.SetErrorString(
"Invalid c-string value string.");
639 error.SetErrorString(
"Invalid encoding.");
644 llvm::StringRef str = value_str;
646 bool is_negative = is_signed && str.consume_front(
"-");
648 if (str.getAsInteger(0,
integer)) {
649 error.SetErrorStringWithFormatv(
650 "'{0}' is not a valid integer string value", value_str);
658 fits =
integer.isSignedIntN(byte_size * 8);
660 fits =
integer.isIntN(byte_size * 8);
662 error.SetErrorStringWithFormatv(
663 "value {0} is too large to fit in a {1} byte integer value",
664 value_str, byte_size);
669 APSInt(std::move(
integer), !is_signed).extOrTrunc(8 * byte_size);
677 const llvm::fltSemantics &sem =
678 byte_size <= 4 ? APFloat::IEEEsingle()
679 : byte_size <= 8 ? APFloat::IEEEdouble()
680 : APFloat::x87DoubleExtended();
682 if (llvm::Expected<APFloat::opStatus> op =
683 f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) {
685 m_float = std::move(f);
687 error = op.takeError();
692 error.SetErrorString(
"vector encoding unsupported.");
706 error.SetErrorString(
"invalid encoding");
709 error.SetErrorString(
"vector encoding unsupported");
714 return Status(
"insufficient data");
717 APSInt(APInt::getZero(8 * byte_size), encoding ==
eEncodingUint);
719 llvm::LoadIntFromMemory(m_integer, data.
GetDataStart(), byte_size);
721 std::vector<uint8_t> buffer(byte_size);
722 std::copy_n(data.
GetDataStart(), byte_size, buffer.rbegin());
723 llvm::LoadIntFromMemory(m_integer, buffer.data(), byte_size);
730 if (byte_size ==
sizeof(
float))
732 else if (byte_size ==
sizeof(
double))
734 else if (byte_size ==
sizeof(
long double))
737 error.SetErrorStringWithFormat(
"unsupported float byte size: %" PRIu64
"",
738 static_cast<uint64_t
>(byte_size));
746 const uint32_t max_bit_pos = GetByteSize() * 8;
748 if (sign_bit_pos < max_bit_pos) {
751 case Scalar::e_float:
755 if (max_bit_pos == sign_bit_pos)
757 else if (sign_bit_pos < (max_bit_pos - 1)) {
758 llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1);
759 llvm::APInt bitwize_and = m_integer & sign_bit;
760 if (bitwize_and.getBoolValue()) {
762 ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
763 m_integer |= APSInt(std::move(mask), m_integer.isUnsigned());
773 size_t Scalar::GetAsMemoryData(
void *dst,
size_t dst_len,
778 if (!GetData(data)) {
779 error.SetErrorString(
"invalid scalar value");
786 const size_t bytes_copied =
792 if (bytes_copied == 0)
793 error.SetErrorString(
"failed to copy data");
804 case Scalar::e_float:
808 m_integer >>= bit_offset;
809 m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize());
817 if (lhs.
m_type == Scalar::e_void || rhs.
m_type == Scalar::e_void)
820 llvm::APFloat::cmpResult result;
821 switch (Scalar::PromoteToMaxType(lhs, rhs)) {
826 case Scalar::e_float:
828 if (result == llvm::APFloat::cmpEqual)
835 return !(lhs == rhs);
839 if (lhs.
m_type == Scalar::e_void || rhs.
m_type == Scalar::e_void)
842 llvm::APFloat::cmpResult result;
843 switch (Scalar::PromoteToMaxType(lhs, rhs)) {
848 case Scalar::e_float:
850 if (result == llvm::APFloat::cmpLessThan)
873 m_integer.clearBit(
bit);
886 m_integer.setBit(
bit);