using namespace lldb;
using namespace lldb_private;
+namespace {
+enum class Category { Void, Integral, Float };
+}
+
+static Category GetCategory(Scalar::Type type) {
+ switch (type) {
+ case Scalar::e_void:
+ return Category::Void;
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ return Category::Float;
+ case Scalar::e_sint:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ case Scalar::e_sint512:
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ case Scalar::e_uint512:
+ return Category::Integral;
+ }
+ llvm_unreachable("Unhandled type!");
+}
+
+static bool IsSigned(Scalar::Type type) {
+ switch (type) {
+ case Scalar::e_void:
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ case Scalar::e_uint512:
+ return false;
+ case Scalar::e_sint:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ case Scalar::e_sint512:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ return true;
+ }
+ llvm_unreachable("Unhandled type!");
+}
+
+
// Promote to max type currently follows the ANSI C rule for type promotion in
// expressions.
static Scalar::Type PromoteToMaxType(
void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const {
assert(storage.size() >= GetByteSize());
- switch (m_type) {
- case e_void:
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
- StoreIntToMemory(m_integer, storage.data(),
- (m_integer.getBitWidth() + 7) / 8);
- break;
- case e_float: {
- float val = m_float.convertToFloat();
- memcpy(storage.data(), &val, sizeof(val));
+ const auto &store = [&](const llvm::APInt val) {
+ StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8);
+ };
+ switch (GetCategory(m_type)) {
+ case Category::Void:
break;
- }
- case e_double: {
- double val = m_float.convertToDouble();
- memcpy(storage.data(), &val, sizeof(double));
+ case Category::Integral:
+ store(m_integer);
break;
- }
- case e_long_double: {
- llvm::APInt val = m_float.bitcastToAPInt();
- StoreIntToMemory(val, storage.data(), storage.size());
+ case Category::Float:
+ store(m_float.bitcastToAPInt());
break;
}
- }
}
size_t Scalar::GetByteSize() const {
}
bool Scalar::IsZero() const {
- llvm::APInt zero_int = llvm::APInt::getNullValue(m_integer.getBitWidth() / 8);
- switch (m_type) {
- case e_void:
+ switch (GetCategory(m_type)) {
+ case Category::Void:
break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_uint512:
- case e_sint512:
- return llvm::APInt::isSameValue(zero_int, m_integer);
- case e_float:
- case e_double:
- case e_long_double:
+ case Category::Integral:
+ return m_integer.isNullValue();
+ case Category::Float:
return m_float.isZero();
}
return false;
if (show_type)
s->Printf("(%s) ", GetTypeAsCString());
- switch (m_type) {
- case e_void:
- break;
- case e_sint:
- case e_slong:
- case e_slonglong:
- case e_sint128:
- case e_sint256:
- case e_sint512:
- s->PutCString(m_integer.toString(10, true));
+ switch (GetCategory(m_type)) {
+ case Category::Void:
break;
- case e_uint:
- case e_ulong:
- case e_ulonglong:
- case e_uint128:
- case e_uint256:
- case e_uint512:
- s->PutCString(m_integer.toString(10, false));
+ case Category::Integral:
+ s->PutCString(m_integer.toString(10, IsSigned(m_type)));
break;
- case e_float:
- case e_double:
- case e_long_double:
+ case Category::Float:
llvm::SmallString<24> string;
m_float.toString(string);
- s->Printf("%s", string.c_str());
+ s->PutCString(string);
break;
}
}
llvm_unreachable("Unhandled type!");
}
-static bool IsSigned(Scalar::Type type) {
- switch (type) {
- case Scalar::e_void:
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- case Scalar::e_uint512:
- return false;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- case Scalar::e_sint512:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- return true;
- }
- llvm_unreachable("Unhandled type!");
-}
-
-namespace {
-enum class Category { Void, Integral, Float };
-}
-
-static Category GetCategory(Scalar::Type type) {
- switch (type) {
- case Scalar::e_void:
- return Category::Void;
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- return Category::Float;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- case Scalar::e_sint512:
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- case Scalar::e_uint512:
- return Category::Integral;
- }
- llvm_unreachable("Unhandled type!");
-}
-
static const llvm::fltSemantics &GetFltSemantics(Scalar::Type type) {
switch (type) {
case Scalar::e_void:
const Scalar *b;
if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) !=
Scalar::e_void) {
- switch (m_type) {
- case e_void:
+ switch (GetCategory(m_type)) {
+ case Category::Void:
break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
+ case Category::Integral:
m_integer = a->m_integer + b->m_integer;
break;
- case e_float:
- case e_double:
- case e_long_double:
+ case Category::Float:
m_float = a->m_float + b->m_float;
break;
}
}
Scalar &Scalar::operator<<=(const Scalar &rhs) {
- switch (m_type) {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
+ if (GetCategory(m_type) == Category::Integral &&
+ GetCategory(rhs.m_type) == Category::Integral)
+ m_integer <<= rhs.m_integer;
+ else
m_type = e_void;
- break;
-
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
- switch (rhs.m_type) {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
- m_integer = m_integer << rhs.m_integer;
- break;
- }
- break;
- }
return *this;
}
bool Scalar::ShiftRightLogical(const Scalar &rhs) {
+ if (GetCategory(m_type) == Category::Integral &&
+ GetCategory(rhs.m_type) == Category::Integral) {
+ m_integer = m_integer.lshr(rhs.m_integer);
+ return true;
+ }
+ m_type = e_void;
+ return false;
+}
+
+Scalar &Scalar::operator>>=(const Scalar &rhs) {
switch (m_type) {
case e_void:
case e_float:
case e_uint256:
case e_sint512:
case e_uint512:
- m_integer = m_integer.lshr(rhs.m_integer);
+ m_integer = m_integer.ashr(rhs.m_integer);
break;
}
break;
}
- return m_type != e_void;
+ return *this;
}
-Scalar &Scalar::operator>>=(const Scalar &rhs) {
- switch (m_type) {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
-
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
- switch (rhs.m_type) {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
- m_integer = m_integer.ashr(rhs.m_integer);
- break;
- }
- break;
- }
- return *this;
-}
-
-Scalar &Scalar::operator&=(const Scalar &rhs) {
- switch (m_type) {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
-
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
- switch (rhs.m_type) {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
- m_integer &= rhs.m_integer;
- break;
- }
- break;
- }
- return *this;
-}
-
-bool Scalar::AbsoluteValue() {
+Scalar &Scalar::operator&=(const Scalar &rhs) {
+ if (GetCategory(m_type) == Category::Integral &&
+ GetCategory(rhs.m_type) == Category::Integral)
+ m_integer &= rhs.m_integer;
+ else
+ m_type = e_void;
+ return *this;
+}
+
+bool Scalar::AbsoluteValue() {
switch (m_type) {
case e_void:
break;
}
bool Scalar::UnaryNegate() {
- switch (m_type) {
- case e_void:
+ switch (GetCategory(m_type)) {
+ case Category::Void:
break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
+ case Category::Integral:
m_integer = -m_integer;
return true;
- case e_float:
- case e_double:
- case e_long_double:
+ case Category::Float:
m_float.changeSign();
return true;
}
}
bool Scalar::OnesComplement() {
- switch (m_type) {
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_sint512:
- case e_uint512:
+ if (GetCategory(m_type) == Category::Integral) {
m_integer = ~m_integer;
return true;
-
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- break;
}
+
return false;
}
const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
- Scalar result;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- switch (result.m_type) {
- case Scalar::e_void:
- break;
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
- result.m_integer = a->m_integer + b->m_integer;
- break;
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- result.m_float = a->m_float + b->m_float;
- break;
- }
- }
+ Scalar result = lhs;
+ result += rhs;
return result;
}
const Scalar *b;
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
Scalar::e_void) {
- switch (result.m_type) {
- case Scalar::e_void:
+ switch (GetCategory(result.m_type)) {
+ case Category::Void:
break;
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
+ case Category::Integral:
result.m_integer = a->m_integer - b->m_integer;
break;
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
+ case Category::Float:
result.m_float = a->m_float - b->m_float;
break;
}
const Scalar *a;
const Scalar *b;
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- switch (result.m_type) {
- case Scalar::e_void:
+ Scalar::e_void &&
+ !b->IsZero()) {
+ switch (GetCategory(result.m_type)) {
+ case Category::Void:
break;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- case Scalar::e_sint512:
- if (b->m_integer != 0) {
+ case Category::Integral:
+ if (IsSigned(result.m_type))
result.m_integer = a->m_integer.sdiv(b->m_integer);
- return result;
- }
- break;
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- case Scalar::e_uint512:
- if (b->m_integer != 0) {
+ else
result.m_integer = a->m_integer.udiv(b->m_integer);
- return result;
- }
- break;
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- if (!b->m_float.isZero()) {
- result.m_float = a->m_float / b->m_float;
- return result;
- }
- break;
+ return result;
+ case Category::Float:
+ result.m_float = a->m_float / b->m_float;
+ return result;
}
}
// For division only, the only way it should make it here is if a promotion
const Scalar *b;
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
Scalar::e_void) {
- switch (result.m_type) {
- case Scalar::e_void:
+ switch (GetCategory(result.m_type)) {
+ case Category::Void:
break;
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
+ case Category::Integral:
result.m_integer = a->m_integer * b->m_integer;
break;
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
+ case Category::Float:
result.m_float = a->m_float * b->m_float;
break;
}
const Scalar *b;
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
Scalar::e_void) {
- switch (result.m_type) {
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
+ if (GetCategory(result.m_type) == Category::Integral)
result.m_integer = a->m_integer & b->m_integer;
- break;
- case Scalar::e_void:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- // No bitwise AND on floats, doubles of long doubles
+ else
result.m_type = Scalar::e_void;
- break;
- }
}
return result;
}
const Scalar *b;
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
Scalar::e_void) {
- switch (result.m_type) {
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
+ if (GetCategory(result.m_type) == Category::Integral)
result.m_integer = a->m_integer | b->m_integer;
- break;
-
- case Scalar::e_void:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- // No bitwise AND on floats, doubles of long doubles
+ else
result.m_type = Scalar::e_void;
- break;
- }
}
return result;
}
const Scalar *b;
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
Scalar::e_void) {
- switch (result.m_type) {
- default:
- break;
- case Scalar::e_void:
- break;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- case Scalar::e_sint512:
- if (b->m_integer != 0) {
+ if (!b->IsZero() && GetCategory(result.m_type) == Category::Integral) {
+ if (IsSigned(result.m_type))
result.m_integer = a->m_integer.srem(b->m_integer);
- return result;
- }
- break;
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- case Scalar::e_uint512:
- if (b->m_integer != 0) {
+ else
result.m_integer = a->m_integer.urem(b->m_integer);
- return result;
- }
- break;
+ return result;
}
}
result.m_type = Scalar::e_void;
const Scalar *b;
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
Scalar::e_void) {
- switch (result.m_type) {
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
+ if (GetCategory(result.m_type) == Category::Integral)
result.m_integer = a->m_integer ^ b->m_integer;
- break;
-
- case Scalar::e_void:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- // No bitwise AND on floats, doubles of long doubles
+ else
result.m_type = Scalar::e_void;
- break;
- }
}
return result;
}