180814287SRaphael Isemann //===-- RegisterValue.cpp -------------------------------------------------===//
2d821c997SPavel Labath //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d821c997SPavel Labath //
7d821c997SPavel Labath //===----------------------------------------------------------------------===//
8d821c997SPavel Labath
9d821c997SPavel Labath #include "lldb/Utility/RegisterValue.h"
10d821c997SPavel Labath
11d821c997SPavel Labath #include "lldb/Utility/DataExtractor.h"
12d821c997SPavel Labath #include "lldb/Utility/Scalar.h"
13d821c997SPavel Labath #include "lldb/Utility/Status.h"
14d821c997SPavel Labath #include "lldb/Utility/Stream.h"
15d821c997SPavel Labath #include "lldb/Utility/StreamString.h"
16672d2c12SJonas Devlieghere #include "lldb/lldb-defines.h"
17672d2c12SJonas Devlieghere #include "lldb/lldb-private-types.h"
18d821c997SPavel Labath
19d821c997SPavel Labath #include "llvm/ADT/ArrayRef.h"
20d821c997SPavel Labath #include "llvm/ADT/StringRef.h"
21d821c997SPavel Labath
22672d2c12SJonas Devlieghere #include <cstdint>
23672d2c12SJonas Devlieghere #include <string>
24672d2c12SJonas Devlieghere #include <tuple>
25d821c997SPavel Labath #include <vector>
26d821c997SPavel Labath
27*76e47d48SRaphael Isemann #include <cassert>
28*76e47d48SRaphael Isemann #include <cinttypes>
29*76e47d48SRaphael Isemann #include <cstdio>
30d821c997SPavel Labath
31d821c997SPavel Labath using namespace lldb;
32d821c997SPavel Labath using namespace lldb_private;
33d821c997SPavel Labath
GetData(DataExtractor & data) const34d821c997SPavel Labath bool RegisterValue::GetData(DataExtractor &data) const {
35d821c997SPavel Labath return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
36d821c997SPavel Labath }
37d821c997SPavel Labath
GetAsMemoryData(const RegisterInfo * reg_info,void * dst,uint32_t dst_len,lldb::ByteOrder dst_byte_order,Status & error) const38d821c997SPavel Labath uint32_t RegisterValue::GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
39d821c997SPavel Labath uint32_t dst_len,
40d821c997SPavel Labath lldb::ByteOrder dst_byte_order,
41d821c997SPavel Labath Status &error) const {
42d821c997SPavel Labath if (reg_info == nullptr) {
43d821c997SPavel Labath error.SetErrorString("invalid register info argument.");
44d821c997SPavel Labath return 0;
45d821c997SPavel Labath }
46d821c997SPavel Labath
47d821c997SPavel Labath // ReadRegister should have already been called on this object prior to
48d821c997SPavel Labath // calling this.
49d821c997SPavel Labath if (GetType() == eTypeInvalid) {
50d821c997SPavel Labath // No value has been read into this object...
51d821c997SPavel Labath error.SetErrorStringWithFormat(
52d821c997SPavel Labath "invalid register value type for register %s", reg_info->name);
53d821c997SPavel Labath return 0;
54d821c997SPavel Labath }
55d821c997SPavel Labath
56d821c997SPavel Labath if (dst_len > kMaxRegisterByteSize) {
57d821c997SPavel Labath error.SetErrorString("destination is too big");
58d821c997SPavel Labath return 0;
59d821c997SPavel Labath }
60d821c997SPavel Labath
61d821c997SPavel Labath const uint32_t src_len = reg_info->byte_size;
62d821c997SPavel Labath
63d821c997SPavel Labath // Extract the register data into a data extractor
64d821c997SPavel Labath DataExtractor reg_data;
65d821c997SPavel Labath if (!GetData(reg_data)) {
66d821c997SPavel Labath error.SetErrorString("invalid register value to copy into");
67d821c997SPavel Labath return 0;
68d821c997SPavel Labath }
69d821c997SPavel Labath
70d821c997SPavel Labath // Prepare a memory buffer that contains some or all of the register value
71d821c997SPavel Labath const uint32_t bytes_copied =
72d821c997SPavel Labath reg_data.CopyByteOrderedData(0, // src offset
73d821c997SPavel Labath src_len, // src length
74d821c997SPavel Labath dst, // dst buffer
75d821c997SPavel Labath dst_len, // dst length
76d821c997SPavel Labath dst_byte_order); // dst byte order
77d821c997SPavel Labath if (bytes_copied == 0)
78d821c997SPavel Labath error.SetErrorStringWithFormat(
79d821c997SPavel Labath "failed to copy data for register write of %s", reg_info->name);
80d821c997SPavel Labath
81d821c997SPavel Labath return bytes_copied;
82d821c997SPavel Labath }
83d821c997SPavel Labath
SetFromMemoryData(const RegisterInfo * reg_info,const void * src,uint32_t src_len,lldb::ByteOrder src_byte_order,Status & error)84d821c997SPavel Labath uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo *reg_info,
85d821c997SPavel Labath const void *src, uint32_t src_len,
86d821c997SPavel Labath lldb::ByteOrder src_byte_order,
87d821c997SPavel Labath Status &error) {
88d821c997SPavel Labath if (reg_info == nullptr) {
89d821c997SPavel Labath error.SetErrorString("invalid register info argument.");
90d821c997SPavel Labath return 0;
91d821c997SPavel Labath }
92d821c997SPavel Labath
93d821c997SPavel Labath // Moving from addr into a register
94d821c997SPavel Labath //
95d821c997SPavel Labath // Case 1: src_len == dst_len
96d821c997SPavel Labath //
97d821c997SPavel Labath // |AABBCCDD| Address contents
98d821c997SPavel Labath // |AABBCCDD| Register contents
99d821c997SPavel Labath //
100d821c997SPavel Labath // Case 2: src_len > dst_len
101d821c997SPavel Labath //
102d821c997SPavel Labath // Status! (The register should always be big enough to hold the data)
103d821c997SPavel Labath //
104d821c997SPavel Labath // Case 3: src_len < dst_len
105d821c997SPavel Labath //
106d821c997SPavel Labath // |AABB| Address contents
107d821c997SPavel Labath // |AABB0000| Register contents [on little-endian hardware]
108d821c997SPavel Labath // |0000AABB| Register contents [on big-endian hardware]
109d821c997SPavel Labath if (src_len > kMaxRegisterByteSize) {
110d821c997SPavel Labath error.SetErrorStringWithFormat(
111d821c997SPavel Labath "register buffer is too small to receive %u bytes of data.", src_len);
112d821c997SPavel Labath return 0;
113d821c997SPavel Labath }
114d821c997SPavel Labath
115d821c997SPavel Labath const uint32_t dst_len = reg_info->byte_size;
116d821c997SPavel Labath
117d821c997SPavel Labath if (src_len > dst_len) {
118d821c997SPavel Labath error.SetErrorStringWithFormat(
119d821c997SPavel Labath "%u bytes is too big to store in register %s (%u bytes)", src_len,
120d821c997SPavel Labath reg_info->name, dst_len);
121d821c997SPavel Labath return 0;
122d821c997SPavel Labath }
123d821c997SPavel Labath
124d821c997SPavel Labath // Use a data extractor to correctly copy and pad the bytes read into the
125d821c997SPavel Labath // register value
126d821c997SPavel Labath DataExtractor src_data(src, src_len, src_byte_order, 4);
127d821c997SPavel Labath
128d821c997SPavel Labath error = SetValueFromData(reg_info, src_data, 0, true);
129d821c997SPavel Labath if (error.Fail())
130d821c997SPavel Labath return 0;
131d821c997SPavel Labath
132d821c997SPavel Labath // If SetValueFromData succeeded, we must have copied all of src_len
133d821c997SPavel Labath return src_len;
134d821c997SPavel Labath }
135d821c997SPavel Labath
GetScalarValue(Scalar & scalar) const136d821c997SPavel Labath bool RegisterValue::GetScalarValue(Scalar &scalar) const {
137d821c997SPavel Labath switch (m_type) {
138d821c997SPavel Labath case eTypeInvalid:
139d821c997SPavel Labath break;
140d821c997SPavel Labath case eTypeBytes: {
141ac6799d2SPavel Labath DataExtractor data(buffer.bytes, buffer.length, buffer.byte_order, 1);
142ac6799d2SPavel Labath if (scalar.SetValueFromData(data, lldb::eEncodingUint,
143ac6799d2SPavel Labath buffer.length).Success())
144d821c997SPavel Labath return true;
145d821c997SPavel Labath } break;
146d821c997SPavel Labath case eTypeUInt8:
147d821c997SPavel Labath case eTypeUInt16:
148d821c997SPavel Labath case eTypeUInt32:
149d821c997SPavel Labath case eTypeUInt64:
150d821c997SPavel Labath case eTypeUInt128:
151d821c997SPavel Labath case eTypeFloat:
152d821c997SPavel Labath case eTypeDouble:
153d821c997SPavel Labath case eTypeLongDouble:
154d821c997SPavel Labath scalar = m_scalar;
155d821c997SPavel Labath return true;
156d821c997SPavel Labath }
157d821c997SPavel Labath return false;
158d821c997SPavel Labath }
159d821c997SPavel Labath
Clear()160d821c997SPavel Labath void RegisterValue::Clear() { m_type = eTypeInvalid; }
161d821c997SPavel Labath
SetType(const RegisterInfo * reg_info)162d821c997SPavel Labath RegisterValue::Type RegisterValue::SetType(const RegisterInfo *reg_info) {
163d821c997SPavel Labath // To change the type, we simply copy the data in again, using the new format
164d821c997SPavel Labath RegisterValue copy;
165d821c997SPavel Labath DataExtractor copy_data;
166d821c997SPavel Labath if (copy.CopyValue(*this) && copy.GetData(copy_data))
167d821c997SPavel Labath SetValueFromData(reg_info, copy_data, 0, true);
168d821c997SPavel Labath
169d821c997SPavel Labath return m_type;
170d821c997SPavel Labath }
171d821c997SPavel Labath
SetValueFromData(const RegisterInfo * reg_info,DataExtractor & src,lldb::offset_t src_offset,bool partial_data_ok)172d821c997SPavel Labath Status RegisterValue::SetValueFromData(const RegisterInfo *reg_info,
173d821c997SPavel Labath DataExtractor &src,
174d821c997SPavel Labath lldb::offset_t src_offset,
175d821c997SPavel Labath bool partial_data_ok) {
176d821c997SPavel Labath Status error;
177d821c997SPavel Labath
178d821c997SPavel Labath if (src.GetByteSize() == 0) {
179d821c997SPavel Labath error.SetErrorString("empty data.");
180d821c997SPavel Labath return error;
181d821c997SPavel Labath }
182d821c997SPavel Labath
183d821c997SPavel Labath if (reg_info->byte_size == 0) {
184d821c997SPavel Labath error.SetErrorString("invalid register info.");
185d821c997SPavel Labath return error;
186d821c997SPavel Labath }
187d821c997SPavel Labath
188d821c997SPavel Labath uint32_t src_len = src.GetByteSize() - src_offset;
189d821c997SPavel Labath
190d821c997SPavel Labath if (!partial_data_ok && (src_len < reg_info->byte_size)) {
191d821c997SPavel Labath error.SetErrorString("not enough data.");
192d821c997SPavel Labath return error;
193d821c997SPavel Labath }
194d821c997SPavel Labath
195d821c997SPavel Labath // Cap the data length if there is more than enough bytes for this register
196d821c997SPavel Labath // value
197d821c997SPavel Labath if (src_len > reg_info->byte_size)
198d821c997SPavel Labath src_len = reg_info->byte_size;
199d821c997SPavel Labath
200d821c997SPavel Labath // Zero out the value in case we get partial data...
201d821c997SPavel Labath memset(buffer.bytes, 0, sizeof(buffer.bytes));
202d821c997SPavel Labath
203d821c997SPavel Labath type128 int128;
204d821c997SPavel Labath
205d821c997SPavel Labath m_type = eTypeInvalid;
206d821c997SPavel Labath switch (reg_info->encoding) {
207d821c997SPavel Labath case eEncodingInvalid:
208d821c997SPavel Labath break;
209d821c997SPavel Labath case eEncodingUint:
210d821c997SPavel Labath case eEncodingSint:
211d821c997SPavel Labath if (reg_info->byte_size == 1)
212d821c997SPavel Labath SetUInt8(src.GetMaxU32(&src_offset, src_len));
213d821c997SPavel Labath else if (reg_info->byte_size <= 2)
214d821c997SPavel Labath SetUInt16(src.GetMaxU32(&src_offset, src_len));
215d821c997SPavel Labath else if (reg_info->byte_size <= 4)
216d821c997SPavel Labath SetUInt32(src.GetMaxU32(&src_offset, src_len));
217d821c997SPavel Labath else if (reg_info->byte_size <= 8)
218d821c997SPavel Labath SetUInt64(src.GetMaxU64(&src_offset, src_len));
219d821c997SPavel Labath else if (reg_info->byte_size <= 16) {
220d821c997SPavel Labath uint64_t data1 = src.GetU64(&src_offset);
221d821c997SPavel Labath uint64_t data2 = src.GetU64(&src_offset);
222d821c997SPavel Labath if (src.GetByteSize() == eByteOrderBig) {
223d821c997SPavel Labath int128.x[0] = data1;
224d821c997SPavel Labath int128.x[1] = data2;
225d821c997SPavel Labath } else {
226d821c997SPavel Labath int128.x[0] = data2;
227d821c997SPavel Labath int128.x[1] = data1;
228d821c997SPavel Labath }
229d821c997SPavel Labath SetUInt128(llvm::APInt(128, 2, int128.x));
230d821c997SPavel Labath }
231d821c997SPavel Labath break;
232d821c997SPavel Labath case eEncodingIEEE754:
233d821c997SPavel Labath if (reg_info->byte_size == sizeof(float))
234d821c997SPavel Labath SetFloat(src.GetFloat(&src_offset));
235d821c997SPavel Labath else if (reg_info->byte_size == sizeof(double))
236d821c997SPavel Labath SetDouble(src.GetDouble(&src_offset));
237d821c997SPavel Labath else if (reg_info->byte_size == sizeof(long double))
238d821c997SPavel Labath SetLongDouble(src.GetLongDouble(&src_offset));
239d821c997SPavel Labath break;
240d821c997SPavel Labath case eEncodingVector: {
241d821c997SPavel Labath m_type = eTypeBytes;
242d821c997SPavel Labath buffer.length = reg_info->byte_size;
243d821c997SPavel Labath buffer.byte_order = src.GetByteOrder();
244d821c997SPavel Labath assert(buffer.length <= kMaxRegisterByteSize);
245d821c997SPavel Labath if (buffer.length > kMaxRegisterByteSize)
246d821c997SPavel Labath buffer.length = kMaxRegisterByteSize;
247d821c997SPavel Labath if (src.CopyByteOrderedData(
248d821c997SPavel Labath src_offset, // offset within "src" to start extracting data
249d821c997SPavel Labath src_len, // src length
250d821c997SPavel Labath buffer.bytes, // dst buffer
251d821c997SPavel Labath buffer.length, // dst length
252d821c997SPavel Labath buffer.byte_order) == 0) // dst byte order
253d821c997SPavel Labath {
254d821c997SPavel Labath error.SetErrorStringWithFormat(
255d821c997SPavel Labath "failed to copy data for register write of %s", reg_info->name);
256d821c997SPavel Labath return error;
257d821c997SPavel Labath }
258d821c997SPavel Labath }
259d821c997SPavel Labath }
260d821c997SPavel Labath
261d821c997SPavel Labath if (m_type == eTypeInvalid)
262d821c997SPavel Labath error.SetErrorStringWithFormat(
263d821c997SPavel Labath "invalid register value type for register %s", reg_info->name);
264d821c997SPavel Labath return error;
265d821c997SPavel Labath }
266d821c997SPavel Labath
267d821c997SPavel Labath // Helper function for RegisterValue::SetValueFromString()
ParseVectorEncoding(const RegisterInfo * reg_info,llvm::StringRef vector_str,const uint32_t byte_size,RegisterValue * reg_value)268d821c997SPavel Labath static bool ParseVectorEncoding(const RegisterInfo *reg_info,
269d821c997SPavel Labath llvm::StringRef vector_str,
270d821c997SPavel Labath const uint32_t byte_size,
271d821c997SPavel Labath RegisterValue *reg_value) {
272d821c997SPavel Labath // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
273d821c997SPavel Labath // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
274d821c997SPavel Labath vector_str = vector_str.trim();
275d821c997SPavel Labath vector_str.consume_front("{");
276d821c997SPavel Labath vector_str.consume_back("}");
277d821c997SPavel Labath vector_str = vector_str.trim();
278d821c997SPavel Labath
279d821c997SPavel Labath char Sep = ' ';
280d821c997SPavel Labath
281d821c997SPavel Labath // The first split should give us:
282d821c997SPavel Labath // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
283d821c997SPavel Labath // 0x2a 0x3e').
284d821c997SPavel Labath llvm::StringRef car;
285d821c997SPavel Labath llvm::StringRef cdr = vector_str;
286d821c997SPavel Labath std::tie(car, cdr) = vector_str.split(Sep);
287d821c997SPavel Labath std::vector<uint8_t> bytes;
288d821c997SPavel Labath unsigned byte = 0;
289d821c997SPavel Labath
290d821c997SPavel Labath // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
291d821c997SPavel Labath // vector elements as long as the parsing succeeds and the vector size is <
292d821c997SPavel Labath // byte_size.
293d821c997SPavel Labath while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
294d821c997SPavel Labath bytes.push_back(byte);
295d821c997SPavel Labath std::tie(car, cdr) = cdr.split(Sep);
296d821c997SPavel Labath }
297d821c997SPavel Labath
298d821c997SPavel Labath // Check for vector of exact byte_size elements.
299d821c997SPavel Labath if (bytes.size() != byte_size)
300d821c997SPavel Labath return false;
301d821c997SPavel Labath
302d821c997SPavel Labath reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
303d821c997SPavel Labath return true;
304d821c997SPavel Labath }
305d821c997SPavel Labath
UInt64ValueIsValidForByteSize(uint64_t uval64,size_t total_byte_size)306fc39b948SRaphael Isemann static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
307fc39b948SRaphael Isemann size_t total_byte_size) {
308fc39b948SRaphael Isemann if (total_byte_size > 8)
309fc39b948SRaphael Isemann return false;
310fc39b948SRaphael Isemann
311fc39b948SRaphael Isemann if (total_byte_size == 8)
312fc39b948SRaphael Isemann return true;
313fc39b948SRaphael Isemann
314fc39b948SRaphael Isemann const uint64_t max =
315fc39b948SRaphael Isemann (static_cast<uint64_t>(1) << static_cast<uint64_t>(total_byte_size * 8)) -
316fc39b948SRaphael Isemann 1;
317fc39b948SRaphael Isemann return uval64 <= max;
318fc39b948SRaphael Isemann }
319fc39b948SRaphael Isemann
SInt64ValueIsValidForByteSize(int64_t sval64,size_t total_byte_size)320fc39b948SRaphael Isemann static bool SInt64ValueIsValidForByteSize(int64_t sval64,
321fc39b948SRaphael Isemann size_t total_byte_size) {
322fc39b948SRaphael Isemann if (total_byte_size > 8)
323fc39b948SRaphael Isemann return false;
324fc39b948SRaphael Isemann
325fc39b948SRaphael Isemann if (total_byte_size == 8)
326fc39b948SRaphael Isemann return true;
327fc39b948SRaphael Isemann
328fc39b948SRaphael Isemann const int64_t max = (static_cast<int64_t>(1)
329fc39b948SRaphael Isemann << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
330fc39b948SRaphael Isemann 1;
331fc39b948SRaphael Isemann const int64_t min = ~(max);
332fc39b948SRaphael Isemann return min <= sval64 && sval64 <= max;
333fc39b948SRaphael Isemann }
334fc39b948SRaphael Isemann
SetValueFromString(const RegisterInfo * reg_info,llvm::StringRef value_str)335d821c997SPavel Labath Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info,
336d821c997SPavel Labath llvm::StringRef value_str) {
337d821c997SPavel Labath Status error;
338d821c997SPavel Labath if (reg_info == nullptr) {
339d821c997SPavel Labath error.SetErrorString("Invalid register info argument.");
340d821c997SPavel Labath return error;
341d821c997SPavel Labath }
342d821c997SPavel Labath
343d821c997SPavel Labath m_type = eTypeInvalid;
344d821c997SPavel Labath if (value_str.empty()) {
345d821c997SPavel Labath error.SetErrorString("Invalid c-string value string.");
346d821c997SPavel Labath return error;
347d821c997SPavel Labath }
348d821c997SPavel Labath const uint32_t byte_size = reg_info->byte_size;
349d821c997SPavel Labath
350d821c997SPavel Labath uint64_t uval64;
351d821c997SPavel Labath int64_t ival64;
352d821c997SPavel Labath float flt_val;
353d821c997SPavel Labath double dbl_val;
354d821c997SPavel Labath long double ldbl_val;
355d821c997SPavel Labath switch (reg_info->encoding) {
356d821c997SPavel Labath case eEncodingInvalid:
357d821c997SPavel Labath error.SetErrorString("Invalid encoding.");
358d821c997SPavel Labath break;
359d821c997SPavel Labath
360d821c997SPavel Labath case eEncodingUint:
361d821c997SPavel Labath if (byte_size > sizeof(uint64_t)) {
362d821c997SPavel Labath error.SetErrorStringWithFormat(
363d821c997SPavel Labath "unsupported unsigned integer byte size: %u", byte_size);
364d821c997SPavel Labath break;
365d821c997SPavel Labath }
366d821c997SPavel Labath if (value_str.getAsInteger(0, uval64)) {
367d821c997SPavel Labath error.SetErrorStringWithFormat(
368d821c997SPavel Labath "'%s' is not a valid unsigned integer string value",
369d821c997SPavel Labath value_str.str().c_str());
370d821c997SPavel Labath break;
371d821c997SPavel Labath }
372d821c997SPavel Labath
373fc39b948SRaphael Isemann if (!UInt64ValueIsValidForByteSize(uval64, byte_size)) {
374d821c997SPavel Labath error.SetErrorStringWithFormat(
375d821c997SPavel Labath "value 0x%" PRIx64
376d821c997SPavel Labath " is too large to fit in a %u byte unsigned integer value",
377d821c997SPavel Labath uval64, byte_size);
378d821c997SPavel Labath break;
379d821c997SPavel Labath }
380d821c997SPavel Labath
381d821c997SPavel Labath if (!SetUInt(uval64, reg_info->byte_size)) {
382d821c997SPavel Labath error.SetErrorStringWithFormat(
383d821c997SPavel Labath "unsupported unsigned integer byte size: %u", byte_size);
384d821c997SPavel Labath break;
385d821c997SPavel Labath }
386d821c997SPavel Labath break;
387d821c997SPavel Labath
388d821c997SPavel Labath case eEncodingSint:
389d821c997SPavel Labath if (byte_size > sizeof(long long)) {
390d821c997SPavel Labath error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
391d821c997SPavel Labath byte_size);
392d821c997SPavel Labath break;
393d821c997SPavel Labath }
394d821c997SPavel Labath
395d821c997SPavel Labath if (value_str.getAsInteger(0, ival64)) {
396d821c997SPavel Labath error.SetErrorStringWithFormat(
397d821c997SPavel Labath "'%s' is not a valid signed integer string value",
398d821c997SPavel Labath value_str.str().c_str());
399d821c997SPavel Labath break;
400d821c997SPavel Labath }
401d821c997SPavel Labath
402fc39b948SRaphael Isemann if (!SInt64ValueIsValidForByteSize(ival64, byte_size)) {
403d821c997SPavel Labath error.SetErrorStringWithFormat(
404d821c997SPavel Labath "value 0x%" PRIx64
405d821c997SPavel Labath " is too large to fit in a %u byte signed integer value",
406d821c997SPavel Labath ival64, byte_size);
407d821c997SPavel Labath break;
408d821c997SPavel Labath }
409d821c997SPavel Labath
410d821c997SPavel Labath if (!SetUInt(ival64, reg_info->byte_size)) {
411d821c997SPavel Labath error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
412d821c997SPavel Labath byte_size);
413d821c997SPavel Labath break;
414d821c997SPavel Labath }
415d821c997SPavel Labath break;
416d821c997SPavel Labath
417d821c997SPavel Labath case eEncodingIEEE754: {
418adcd0268SBenjamin Kramer std::string value_string = std::string(value_str);
419d821c997SPavel Labath if (byte_size == sizeof(float)) {
420d821c997SPavel Labath if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
421d821c997SPavel Labath error.SetErrorStringWithFormat("'%s' is not a valid float string value",
422d821c997SPavel Labath value_string.c_str());
423d821c997SPavel Labath break;
424d821c997SPavel Labath }
425d821c997SPavel Labath m_scalar = flt_val;
426d821c997SPavel Labath m_type = eTypeFloat;
427d821c997SPavel Labath } else if (byte_size == sizeof(double)) {
428d821c997SPavel Labath if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
429d821c997SPavel Labath error.SetErrorStringWithFormat("'%s' is not a valid float string value",
430d821c997SPavel Labath value_string.c_str());
431d821c997SPavel Labath break;
432d821c997SPavel Labath }
433d821c997SPavel Labath m_scalar = dbl_val;
434d821c997SPavel Labath m_type = eTypeDouble;
435d821c997SPavel Labath } else if (byte_size == sizeof(long double)) {
436d821c997SPavel Labath if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
437d821c997SPavel Labath error.SetErrorStringWithFormat("'%s' is not a valid float string value",
438d821c997SPavel Labath value_string.c_str());
439d821c997SPavel Labath break;
440d821c997SPavel Labath }
441d821c997SPavel Labath m_scalar = ldbl_val;
442d821c997SPavel Labath m_type = eTypeLongDouble;
443d821c997SPavel Labath } else {
444d821c997SPavel Labath error.SetErrorStringWithFormat("unsupported float byte size: %u",
445d821c997SPavel Labath byte_size);
446d821c997SPavel Labath return error;
447d821c997SPavel Labath }
448d821c997SPavel Labath break;
449d821c997SPavel Labath }
450d821c997SPavel Labath case eEncodingVector:
451d821c997SPavel Labath if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
452d821c997SPavel Labath error.SetErrorString("unrecognized vector encoding string value.");
453d821c997SPavel Labath break;
454d821c997SPavel Labath }
455d821c997SPavel Labath
456d821c997SPavel Labath return error;
457d821c997SPavel Labath }
458d821c997SPavel Labath
SignExtend(uint32_t sign_bitpos)459d821c997SPavel Labath bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
460d821c997SPavel Labath switch (m_type) {
461d821c997SPavel Labath case eTypeInvalid:
462d821c997SPavel Labath break;
463d821c997SPavel Labath
464d821c997SPavel Labath case eTypeUInt8:
465d821c997SPavel Labath case eTypeUInt16:
466d821c997SPavel Labath case eTypeUInt32:
467d821c997SPavel Labath case eTypeUInt64:
468d821c997SPavel Labath case eTypeUInt128:
469d821c997SPavel Labath return m_scalar.SignExtend(sign_bitpos);
470d821c997SPavel Labath case eTypeFloat:
471d821c997SPavel Labath case eTypeDouble:
472d821c997SPavel Labath case eTypeLongDouble:
473d821c997SPavel Labath case eTypeBytes:
474d821c997SPavel Labath break;
475d821c997SPavel Labath }
476d821c997SPavel Labath return false;
477d821c997SPavel Labath }
478d821c997SPavel Labath
CopyValue(const RegisterValue & rhs)479d821c997SPavel Labath bool RegisterValue::CopyValue(const RegisterValue &rhs) {
480d821c997SPavel Labath if (this == &rhs)
481a6682a41SJonas Devlieghere return rhs.m_type != eTypeInvalid;
482d821c997SPavel Labath
483d821c997SPavel Labath m_type = rhs.m_type;
484d821c997SPavel Labath switch (m_type) {
485d821c997SPavel Labath case eTypeInvalid:
486d821c997SPavel Labath return false;
487d821c997SPavel Labath case eTypeUInt8:
488d821c997SPavel Labath case eTypeUInt16:
489d821c997SPavel Labath case eTypeUInt32:
490d821c997SPavel Labath case eTypeUInt64:
491d821c997SPavel Labath case eTypeUInt128:
492d821c997SPavel Labath case eTypeFloat:
493d821c997SPavel Labath case eTypeDouble:
494d821c997SPavel Labath case eTypeLongDouble:
495d821c997SPavel Labath m_scalar = rhs.m_scalar;
496d821c997SPavel Labath break;
497d821c997SPavel Labath case eTypeBytes:
498d821c997SPavel Labath assert(rhs.buffer.length <= kMaxRegisterByteSize);
499d821c997SPavel Labath ::memcpy(buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize);
500d821c997SPavel Labath buffer.length = rhs.buffer.length;
501d821c997SPavel Labath buffer.byte_order = rhs.buffer.byte_order;
502d821c997SPavel Labath break;
503d821c997SPavel Labath }
504d821c997SPavel Labath return true;
505d821c997SPavel Labath }
506d821c997SPavel Labath
GetAsUInt16(uint16_t fail_value,bool * success_ptr) const507d821c997SPavel Labath uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
508d821c997SPavel Labath bool *success_ptr) const {
509d821c997SPavel Labath if (success_ptr)
510d821c997SPavel Labath *success_ptr = true;
511d821c997SPavel Labath
512d821c997SPavel Labath switch (m_type) {
513d821c997SPavel Labath default:
514d821c997SPavel Labath break;
515d821c997SPavel Labath case eTypeUInt8:
516d821c997SPavel Labath case eTypeUInt16:
517d821c997SPavel Labath return m_scalar.UShort(fail_value);
518d821c997SPavel Labath case eTypeBytes: {
519d821c997SPavel Labath switch (buffer.length) {
520d821c997SPavel Labath default:
521d821c997SPavel Labath break;
522d821c997SPavel Labath case 1:
523d821c997SPavel Labath case 2:
52424374aefSJonas Devlieghere return *reinterpret_cast<const uint16_t *>(buffer.bytes);
525d821c997SPavel Labath }
526d821c997SPavel Labath } break;
527d821c997SPavel Labath }
528d821c997SPavel Labath if (success_ptr)
529d821c997SPavel Labath *success_ptr = false;
530d821c997SPavel Labath return fail_value;
531d821c997SPavel Labath }
532d821c997SPavel Labath
GetAsUInt32(uint32_t fail_value,bool * success_ptr) const533d821c997SPavel Labath uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
534d821c997SPavel Labath bool *success_ptr) const {
535d821c997SPavel Labath if (success_ptr)
536d821c997SPavel Labath *success_ptr = true;
537d821c997SPavel Labath switch (m_type) {
538d821c997SPavel Labath default:
539d821c997SPavel Labath break;
540d821c997SPavel Labath case eTypeUInt8:
541d821c997SPavel Labath case eTypeUInt16:
542d821c997SPavel Labath case eTypeUInt32:
543d821c997SPavel Labath case eTypeFloat:
544d821c997SPavel Labath case eTypeDouble:
545d821c997SPavel Labath case eTypeLongDouble:
546d821c997SPavel Labath return m_scalar.UInt(fail_value);
547d821c997SPavel Labath case eTypeBytes: {
548d821c997SPavel Labath switch (buffer.length) {
549d821c997SPavel Labath default:
550d821c997SPavel Labath break;
551d821c997SPavel Labath case 1:
552d821c997SPavel Labath case 2:
553d821c997SPavel Labath case 4:
55424374aefSJonas Devlieghere return *reinterpret_cast<const uint32_t *>(buffer.bytes);
555d821c997SPavel Labath }
556d821c997SPavel Labath } break;
557d821c997SPavel Labath }
558d821c997SPavel Labath if (success_ptr)
559d821c997SPavel Labath *success_ptr = false;
560d821c997SPavel Labath return fail_value;
561d821c997SPavel Labath }
562d821c997SPavel Labath
GetAsUInt64(uint64_t fail_value,bool * success_ptr) const563d821c997SPavel Labath uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
564d821c997SPavel Labath bool *success_ptr) const {
565d821c997SPavel Labath if (success_ptr)
566d821c997SPavel Labath *success_ptr = true;
567d821c997SPavel Labath switch (m_type) {
568d821c997SPavel Labath default:
569d821c997SPavel Labath break;
570d821c997SPavel Labath case eTypeUInt8:
571d821c997SPavel Labath case eTypeUInt16:
572d821c997SPavel Labath case eTypeUInt32:
573d821c997SPavel Labath case eTypeUInt64:
574d821c997SPavel Labath case eTypeFloat:
575d821c997SPavel Labath case eTypeDouble:
576d821c997SPavel Labath case eTypeLongDouble:
577d821c997SPavel Labath return m_scalar.ULongLong(fail_value);
578d821c997SPavel Labath case eTypeBytes: {
579d821c997SPavel Labath switch (buffer.length) {
580d821c997SPavel Labath default:
581d821c997SPavel Labath break;
582d821c997SPavel Labath case 1:
583d821c997SPavel Labath return *(const uint8_t *)buffer.bytes;
584d821c997SPavel Labath case 2:
58524374aefSJonas Devlieghere return *reinterpret_cast<const uint16_t *>(buffer.bytes);
586d821c997SPavel Labath case 4:
58724374aefSJonas Devlieghere return *reinterpret_cast<const uint32_t *>(buffer.bytes);
588d821c997SPavel Labath case 8:
58924374aefSJonas Devlieghere return *reinterpret_cast<const uint64_t *>(buffer.bytes);
590d821c997SPavel Labath }
591d821c997SPavel Labath } break;
592d821c997SPavel Labath }
593d821c997SPavel Labath if (success_ptr)
594d821c997SPavel Labath *success_ptr = false;
595d821c997SPavel Labath return fail_value;
596d821c997SPavel Labath }
597d821c997SPavel Labath
GetAsUInt128(const llvm::APInt & fail_value,bool * success_ptr) const598d821c997SPavel Labath llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value,
599d821c997SPavel Labath bool *success_ptr) const {
600d821c997SPavel Labath if (success_ptr)
601d821c997SPavel Labath *success_ptr = true;
602d821c997SPavel Labath switch (m_type) {
603d821c997SPavel Labath default:
604d821c997SPavel Labath break;
605d821c997SPavel Labath case eTypeUInt8:
606d821c997SPavel Labath case eTypeUInt16:
607d821c997SPavel Labath case eTypeUInt32:
608d821c997SPavel Labath case eTypeUInt64:
609d821c997SPavel Labath case eTypeUInt128:
610d821c997SPavel Labath case eTypeFloat:
611d821c997SPavel Labath case eTypeDouble:
612d821c997SPavel Labath case eTypeLongDouble:
613d821c997SPavel Labath return m_scalar.UInt128(fail_value);
614d821c997SPavel Labath case eTypeBytes: {
615d821c997SPavel Labath switch (buffer.length) {
616d821c997SPavel Labath default:
617d821c997SPavel Labath break;
618d821c997SPavel Labath case 1:
619d821c997SPavel Labath case 2:
620d821c997SPavel Labath case 4:
621d821c997SPavel Labath case 8:
622d821c997SPavel Labath case 16:
623d821c997SPavel Labath return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
62424374aefSJonas Devlieghere (reinterpret_cast<const type128 *>(buffer.bytes))->x);
625d821c997SPavel Labath }
626d821c997SPavel Labath } break;
627d821c997SPavel Labath }
628d821c997SPavel Labath if (success_ptr)
629d821c997SPavel Labath *success_ptr = false;
630d821c997SPavel Labath return fail_value;
631d821c997SPavel Labath }
632d821c997SPavel Labath
GetAsFloat(float fail_value,bool * success_ptr) const633d821c997SPavel Labath float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
634d821c997SPavel Labath if (success_ptr)
635d821c997SPavel Labath *success_ptr = true;
636d821c997SPavel Labath switch (m_type) {
637d821c997SPavel Labath default:
638d821c997SPavel Labath break;
639d821c997SPavel Labath case eTypeUInt32:
640d821c997SPavel Labath case eTypeUInt64:
641d821c997SPavel Labath case eTypeUInt128:
642d821c997SPavel Labath case eTypeFloat:
643d821c997SPavel Labath case eTypeDouble:
644d821c997SPavel Labath case eTypeLongDouble:
645d821c997SPavel Labath return m_scalar.Float(fail_value);
646d821c997SPavel Labath }
647d821c997SPavel Labath if (success_ptr)
648d821c997SPavel Labath *success_ptr = false;
649d821c997SPavel Labath return fail_value;
650d821c997SPavel Labath }
651d821c997SPavel Labath
GetAsDouble(double fail_value,bool * success_ptr) const652d821c997SPavel Labath double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const {
653d821c997SPavel Labath if (success_ptr)
654d821c997SPavel Labath *success_ptr = true;
655d821c997SPavel Labath switch (m_type) {
656d821c997SPavel Labath default:
657d821c997SPavel Labath break;
658d821c997SPavel Labath
659d821c997SPavel Labath case eTypeUInt32:
660d821c997SPavel Labath case eTypeUInt64:
661d821c997SPavel Labath case eTypeUInt128:
662d821c997SPavel Labath case eTypeFloat:
663d821c997SPavel Labath case eTypeDouble:
664d821c997SPavel Labath case eTypeLongDouble:
665d821c997SPavel Labath return m_scalar.Double(fail_value);
666d821c997SPavel Labath }
667d821c997SPavel Labath if (success_ptr)
668d821c997SPavel Labath *success_ptr = false;
669d821c997SPavel Labath return fail_value;
670d821c997SPavel Labath }
671d821c997SPavel Labath
GetAsLongDouble(long double fail_value,bool * success_ptr) const672d821c997SPavel Labath long double RegisterValue::GetAsLongDouble(long double fail_value,
673d821c997SPavel Labath bool *success_ptr) const {
674d821c997SPavel Labath if (success_ptr)
675d821c997SPavel Labath *success_ptr = true;
676d821c997SPavel Labath switch (m_type) {
677d821c997SPavel Labath default:
678d821c997SPavel Labath break;
679d821c997SPavel Labath
680d821c997SPavel Labath case eTypeUInt32:
681d821c997SPavel Labath case eTypeUInt64:
682d821c997SPavel Labath case eTypeUInt128:
683d821c997SPavel Labath case eTypeFloat:
684d821c997SPavel Labath case eTypeDouble:
685d821c997SPavel Labath case eTypeLongDouble:
686d821c997SPavel Labath return m_scalar.LongDouble();
687d821c997SPavel Labath }
688d821c997SPavel Labath if (success_ptr)
689d821c997SPavel Labath *success_ptr = false;
690d821c997SPavel Labath return fail_value;
691d821c997SPavel Labath }
692d821c997SPavel Labath
GetBytes() const693d821c997SPavel Labath const void *RegisterValue::GetBytes() const {
694d821c997SPavel Labath switch (m_type) {
695d821c997SPavel Labath case eTypeInvalid:
696d821c997SPavel Labath break;
697d821c997SPavel Labath case eTypeUInt8:
698d821c997SPavel Labath case eTypeUInt16:
699d821c997SPavel Labath case eTypeUInt32:
700d821c997SPavel Labath case eTypeUInt64:
701d821c997SPavel Labath case eTypeUInt128:
702d821c997SPavel Labath case eTypeFloat:
703d821c997SPavel Labath case eTypeDouble:
704d821c997SPavel Labath case eTypeLongDouble:
705d0fa52ccSPavel Labath m_scalar.GetBytes(buffer.bytes);
706d0fa52ccSPavel Labath return buffer.bytes;
707d821c997SPavel Labath case eTypeBytes:
708d821c997SPavel Labath return buffer.bytes;
709d821c997SPavel Labath }
710d821c997SPavel Labath return nullptr;
711d821c997SPavel Labath }
712d821c997SPavel Labath
GetByteSize() const713d821c997SPavel Labath uint32_t RegisterValue::GetByteSize() const {
714d821c997SPavel Labath switch (m_type) {
715d821c997SPavel Labath case eTypeInvalid:
716d821c997SPavel Labath break;
717d821c997SPavel Labath case eTypeUInt8:
718d821c997SPavel Labath return 1;
719d821c997SPavel Labath case eTypeUInt16:
720d821c997SPavel Labath return 2;
721d821c997SPavel Labath case eTypeUInt32:
722d821c997SPavel Labath case eTypeUInt64:
723d821c997SPavel Labath case eTypeUInt128:
724d821c997SPavel Labath case eTypeFloat:
725d821c997SPavel Labath case eTypeDouble:
726d821c997SPavel Labath case eTypeLongDouble:
727d821c997SPavel Labath return m_scalar.GetByteSize();
728d821c997SPavel Labath case eTypeBytes:
729d821c997SPavel Labath return buffer.length;
730d821c997SPavel Labath }
731d821c997SPavel Labath return 0;
732d821c997SPavel Labath }
733d821c997SPavel Labath
SetUInt(uint64_t uint,uint32_t byte_size)734d821c997SPavel Labath bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
735d821c997SPavel Labath if (byte_size == 0) {
736d821c997SPavel Labath SetUInt64(uint);
737d821c997SPavel Labath } else if (byte_size == 1) {
738d821c997SPavel Labath SetUInt8(uint);
739d821c997SPavel Labath } else if (byte_size <= 2) {
740d821c997SPavel Labath SetUInt16(uint);
741d821c997SPavel Labath } else if (byte_size <= 4) {
742d821c997SPavel Labath SetUInt32(uint);
743d821c997SPavel Labath } else if (byte_size <= 8) {
744d821c997SPavel Labath SetUInt64(uint);
745d821c997SPavel Labath } else if (byte_size <= 16) {
746d821c997SPavel Labath SetUInt128(llvm::APInt(128, uint));
747d821c997SPavel Labath } else
748d821c997SPavel Labath return false;
749d821c997SPavel Labath return true;
750d821c997SPavel Labath }
751d821c997SPavel Labath
SetBytes(const void * bytes,size_t length,lldb::ByteOrder byte_order)752d821c997SPavel Labath void RegisterValue::SetBytes(const void *bytes, size_t length,
753d821c997SPavel Labath lldb::ByteOrder byte_order) {
754d821c997SPavel Labath // If this assertion fires off we need to increase the size of buffer.bytes,
755d821c997SPavel Labath // or make it something that is allocated on the heap. Since the data buffer
756d821c997SPavel Labath // is in a union, we can't make it a collection class like SmallVector...
757d821c997SPavel Labath if (bytes && length > 0) {
758d821c997SPavel Labath assert(length <= sizeof(buffer.bytes) &&
759d821c997SPavel Labath "Storing too many bytes in a RegisterValue.");
760d821c997SPavel Labath m_type = eTypeBytes;
761d821c997SPavel Labath buffer.length = length;
762d821c997SPavel Labath memcpy(buffer.bytes, bytes, length);
763d821c997SPavel Labath buffer.byte_order = byte_order;
764d821c997SPavel Labath } else {
765d821c997SPavel Labath m_type = eTypeInvalid;
766d821c997SPavel Labath buffer.length = 0;
767d821c997SPavel Labath }
768d821c997SPavel Labath }
769d821c997SPavel Labath
operator ==(const RegisterValue & rhs) const770d821c997SPavel Labath bool RegisterValue::operator==(const RegisterValue &rhs) const {
771d821c997SPavel Labath if (m_type == rhs.m_type) {
772d821c997SPavel Labath switch (m_type) {
773d821c997SPavel Labath case eTypeInvalid:
774d821c997SPavel Labath return true;
775d821c997SPavel Labath case eTypeUInt8:
776d821c997SPavel Labath case eTypeUInt16:
777d821c997SPavel Labath case eTypeUInt32:
778d821c997SPavel Labath case eTypeUInt64:
779d821c997SPavel Labath case eTypeUInt128:
780d821c997SPavel Labath case eTypeFloat:
781d821c997SPavel Labath case eTypeDouble:
782d821c997SPavel Labath case eTypeLongDouble:
783d821c997SPavel Labath return m_scalar == rhs.m_scalar;
784d821c997SPavel Labath case eTypeBytes:
785d821c997SPavel Labath if (buffer.length != rhs.buffer.length)
786d821c997SPavel Labath return false;
787d821c997SPavel Labath else {
7889f8b4472SMuhammad Omair Javaid uint16_t length = buffer.length;
789d821c997SPavel Labath if (length > kMaxRegisterByteSize)
790d821c997SPavel Labath length = kMaxRegisterByteSize;
791d821c997SPavel Labath return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0;
792d821c997SPavel Labath }
793d821c997SPavel Labath break;
794d821c997SPavel Labath }
795d821c997SPavel Labath }
796d821c997SPavel Labath return false;
797d821c997SPavel Labath }
798d821c997SPavel Labath
operator !=(const RegisterValue & rhs) const799d821c997SPavel Labath bool RegisterValue::operator!=(const RegisterValue &rhs) const {
800db057e77SDavide Italiano return !(*this == rhs);
801d821c997SPavel Labath }
802d821c997SPavel Labath
ClearBit(uint32_t bit)803d821c997SPavel Labath bool RegisterValue::ClearBit(uint32_t bit) {
804d821c997SPavel Labath switch (m_type) {
805d821c997SPavel Labath case eTypeInvalid:
806d821c997SPavel Labath break;
807d821c997SPavel Labath
808d821c997SPavel Labath case eTypeUInt8:
809d821c997SPavel Labath case eTypeUInt16:
810d821c997SPavel Labath case eTypeUInt32:
811d821c997SPavel Labath case eTypeUInt64:
812d821c997SPavel Labath case eTypeUInt128:
813d821c997SPavel Labath if (bit < (GetByteSize() * 8)) {
814d821c997SPavel Labath return m_scalar.ClearBit(bit);
815d821c997SPavel Labath }
816d821c997SPavel Labath break;
817d821c997SPavel Labath
818d821c997SPavel Labath case eTypeFloat:
819d821c997SPavel Labath case eTypeDouble:
820d821c997SPavel Labath case eTypeLongDouble:
821d821c997SPavel Labath break;
822d821c997SPavel Labath
823d821c997SPavel Labath case eTypeBytes:
824d821c997SPavel Labath if (buffer.byte_order == eByteOrderBig ||
825d821c997SPavel Labath buffer.byte_order == eByteOrderLittle) {
826d821c997SPavel Labath uint32_t byte_idx;
827d821c997SPavel Labath if (buffer.byte_order == eByteOrderBig)
828d821c997SPavel Labath byte_idx = buffer.length - (bit / 8) - 1;
829d821c997SPavel Labath else
830d821c997SPavel Labath byte_idx = bit / 8;
831d821c997SPavel Labath
832d821c997SPavel Labath const uint32_t byte_bit = bit % 8;
833d821c997SPavel Labath if (byte_idx < buffer.length) {
834d821c997SPavel Labath buffer.bytes[byte_idx] &= ~(1u << byte_bit);
835d821c997SPavel Labath return true;
836d821c997SPavel Labath }
837d821c997SPavel Labath }
838d821c997SPavel Labath break;
839d821c997SPavel Labath }
840d821c997SPavel Labath return false;
841d821c997SPavel Labath }
842d821c997SPavel Labath
SetBit(uint32_t bit)843d821c997SPavel Labath bool RegisterValue::SetBit(uint32_t bit) {
844d821c997SPavel Labath switch (m_type) {
845d821c997SPavel Labath case eTypeInvalid:
846d821c997SPavel Labath break;
847d821c997SPavel Labath
848d821c997SPavel Labath case eTypeUInt8:
849d821c997SPavel Labath case eTypeUInt16:
850d821c997SPavel Labath case eTypeUInt32:
851d821c997SPavel Labath case eTypeUInt64:
852d821c997SPavel Labath case eTypeUInt128:
853d821c997SPavel Labath if (bit < (GetByteSize() * 8)) {
854d821c997SPavel Labath return m_scalar.SetBit(bit);
855d821c997SPavel Labath }
856d821c997SPavel Labath break;
857d821c997SPavel Labath
858d821c997SPavel Labath case eTypeFloat:
859d821c997SPavel Labath case eTypeDouble:
860d821c997SPavel Labath case eTypeLongDouble:
861d821c997SPavel Labath break;
862d821c997SPavel Labath
863d821c997SPavel Labath case eTypeBytes:
864d821c997SPavel Labath if (buffer.byte_order == eByteOrderBig ||
865d821c997SPavel Labath buffer.byte_order == eByteOrderLittle) {
866d821c997SPavel Labath uint32_t byte_idx;
867d821c997SPavel Labath if (buffer.byte_order == eByteOrderBig)
868d821c997SPavel Labath byte_idx = buffer.length - (bit / 8) - 1;
869d821c997SPavel Labath else
870d821c997SPavel Labath byte_idx = bit / 8;
871d821c997SPavel Labath
872d821c997SPavel Labath const uint32_t byte_bit = bit % 8;
873d821c997SPavel Labath if (byte_idx < buffer.length) {
874d821c997SPavel Labath buffer.bytes[byte_idx] |= (1u << byte_bit);
875d821c997SPavel Labath return true;
876d821c997SPavel Labath }
877d821c997SPavel Labath }
878d821c997SPavel Labath break;
879d821c997SPavel Labath }
880d821c997SPavel Labath return false;
881d821c997SPavel Labath }
882