1 //===-- RegisterValue.h -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef lldb_RegisterValue_h
11 #define lldb_RegisterValue_h
13 #include "lldb/Core/Scalar.h"
14 #include "lldb/Utility/Endian.h"
15 #include "lldb/Utility/Error.h" // for Error
16 #include "lldb/lldb-enumerations.h" // for ByteOrder, Format
17 #include "lldb/lldb-types.h" // for offset_t
19 #include "llvm/ADT/APInt.h"
20 #include "llvm/ADT/StringRef.h" // for StringRef
22 #include <stdint.h> // for uint32_t, uint8_t, uint64_t, uin...
25 namespace lldb_private {
28 namespace lldb_private {
31 namespace lldb_private {
34 namespace lldb_private {
38 enum { kMaxRegisterByteSize = 32u };
53 RegisterValue() : m_type(eTypeInvalid), m_scalar((unsigned long)0) {}
55 explicit RegisterValue(uint8_t inst) : m_type(eTypeUInt8) { m_scalar = inst; }
57 explicit RegisterValue(uint16_t inst) : m_type(eTypeUInt16) {
61 explicit RegisterValue(uint32_t inst) : m_type(eTypeUInt32) {
65 explicit RegisterValue(uint64_t inst) : m_type(eTypeUInt64) {
69 explicit RegisterValue(llvm::APInt inst) : m_type(eTypeUInt128) {
70 m_scalar = llvm::APInt(inst);
73 explicit RegisterValue(float value) : m_type(eTypeFloat) { m_scalar = value; }
75 explicit RegisterValue(double value) : m_type(eTypeDouble) {
79 explicit RegisterValue(long double value) : m_type(eTypeLongDouble) {
83 explicit RegisterValue(uint8_t *bytes, size_t length,
84 lldb::ByteOrder byte_order) {
85 SetBytes(bytes, length, byte_order);
88 RegisterValue::Type GetType() const { return m_type; }
90 bool CopyValue(const RegisterValue &rhs);
92 void SetType(RegisterValue::Type type) { m_type = type; }
94 RegisterValue::Type SetType(const RegisterInfo *reg_info);
96 bool GetData(DataExtractor &data) const;
98 // Copy the register value from this object into a buffer in "dst"
99 // and obey the "dst_byte_order" when copying the data. Also watch out
100 // in case "dst_len" is longer or shorter than the register value
101 // described by "reg_info" and only copy the least significant bytes
102 // of the register value, or pad the destination with zeroes if the
103 // register byte size is shorter that "dst_len" (all while correctly
104 // abiding the "dst_byte_order"). Returns the number of bytes copied
106 uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
107 uint32_t dst_len, lldb::ByteOrder dst_byte_order,
110 uint32_t SetFromMemoryData(const RegisterInfo *reg_info, const void *src,
111 uint32_t src_len, lldb::ByteOrder src_byte_order,
114 bool GetScalarValue(Scalar &scalar) const;
116 uint8_t GetAsUInt8(uint8_t fail_value = UINT8_MAX,
117 bool *success_ptr = nullptr) const {
118 if (m_type == eTypeUInt8) {
121 return m_scalar.UChar(fail_value);
128 uint16_t GetAsUInt16(uint16_t fail_value = UINT16_MAX,
129 bool *success_ptr = nullptr) const;
131 uint32_t GetAsUInt32(uint32_t fail_value = UINT32_MAX,
132 bool *success_ptr = nullptr) const;
134 uint64_t GetAsUInt64(uint64_t fail_value = UINT64_MAX,
135 bool *success_ptr = nullptr) const;
137 llvm::APInt GetAsUInt128(const llvm::APInt &fail_value,
138 bool *success_ptr = nullptr) const;
140 float GetAsFloat(float fail_value = 0.0f, bool *success_ptr = nullptr) const;
142 double GetAsDouble(double fail_value = 0.0,
143 bool *success_ptr = nullptr) const;
145 long double GetAsLongDouble(long double fail_value = 0.0,
146 bool *success_ptr = nullptr) const;
148 void SetValueToInvalid() { m_type = eTypeInvalid; }
150 bool ClearBit(uint32_t bit);
152 bool SetBit(uint32_t bit);
154 bool operator==(const RegisterValue &rhs) const;
156 bool operator!=(const RegisterValue &rhs) const;
158 void operator=(uint8_t uint) {
163 void operator=(uint16_t uint) {
164 m_type = eTypeUInt16;
168 void operator=(uint32_t uint) {
169 m_type = eTypeUInt32;
173 void operator=(uint64_t uint) {
174 m_type = eTypeUInt64;
178 void operator=(llvm::APInt uint) {
179 m_type = eTypeUInt128;
180 m_scalar = llvm::APInt(uint);
183 void operator=(float f) {
188 void operator=(double f) {
189 m_type = eTypeDouble;
193 void operator=(long double f) {
194 m_type = eTypeLongDouble;
198 void SetUInt8(uint8_t uint) {
203 void SetUInt16(uint16_t uint) {
204 m_type = eTypeUInt16;
208 void SetUInt32(uint32_t uint, Type t = eTypeUInt32) {
213 void SetUInt64(uint64_t uint, Type t = eTypeUInt64) {
218 void SetUInt128(llvm::APInt uint) {
219 m_type = eTypeUInt128;
223 bool SetUInt(uint64_t uint, uint32_t byte_size);
225 void SetFloat(float f) {
230 void SetDouble(double f) {
231 m_type = eTypeDouble;
235 void SetLongDouble(long double f) {
236 m_type = eTypeLongDouble;
240 void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order);
242 bool SignExtend(uint32_t sign_bitpos);
244 Error SetValueFromString(const RegisterInfo *reg_info,
245 llvm::StringRef value_str);
246 Error SetValueFromString(const RegisterInfo *reg_info,
247 const char *value_str) = delete;
249 Error SetValueFromData(const RegisterInfo *reg_info, DataExtractor &data,
250 lldb::offset_t offset, bool partial_data_ok);
252 // The default value of 0 for reg_name_right_align_at means no alignment at
254 bool Dump(Stream *s, const RegisterInfo *reg_info, bool prefix_with_name,
255 bool prefix_with_alt_name, lldb::Format format,
256 uint32_t reg_name_right_align_at = 0) const;
258 const void *GetBytes() const;
260 lldb::ByteOrder GetByteOrder() const {
261 if (m_type == eTypeBytes)
262 return buffer.byte_order;
263 return endian::InlHostByteOrder();
266 uint32_t GetByteSize() const;
268 static uint32_t GetMaxByteSize() { return kMaxRegisterByteSize; }
273 RegisterValue::Type m_type;
277 uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any
278 // register for any supported target.
280 lldb::ByteOrder byte_order;
284 } // namespace lldb_private
286 #endif // lldb_RegisterValue_h