1 //===-- RegisterValue.h ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef lldb_RegisterValue_h
11 #define lldb_RegisterValue_h
12 
13 // C Includes
14 #include <string.h>
15 
16 // C++ Includes
17 // Other libraries and framework includes
18 // Project includes
19 #include "lldb/lldb-public.h"
20 #include "lldb/lldb-private.h"
21 #include "lldb/Host/Endian.h"
22 
23 //#define ENABLE_128_BIT_SUPPORT 1
24 namespace lldb_private {
25 
26     class RegisterValue
27     {
28     public:
29         enum
30         {
31             kMaxRegisterByteSize = 32u
32         };
33         enum Type
34         {
35             eTypeInvalid,
36             eTypeUInt8,
37             eTypeUInt16,
38             eTypeUInt32,
39             eTypeUInt64,
40 #if defined (ENABLE_128_BIT_SUPPORT)
41             eTypeUInt128,
42 #endif
43             eTypeFloat,
44             eTypeDouble,
45             eTypeLongDouble,
46             eTypeBytes
47         };
48 
RegisterValue()49         RegisterValue () :
50             m_type (eTypeInvalid)
51         {
52         }
53 
54         explicit
RegisterValue(uint8_t inst)55         RegisterValue (uint8_t inst) :
56             m_type (eTypeUInt8)
57         {
58             m_data.uint8 = inst;
59         }
60 
61         explicit
RegisterValue(uint16_t inst)62         RegisterValue (uint16_t inst) :
63             m_type (eTypeUInt16)
64         {
65             m_data.uint16 = inst;
66         }
67 
68         explicit
RegisterValue(uint32_t inst)69         RegisterValue (uint32_t inst) :
70             m_type (eTypeUInt32)
71         {
72             m_data.uint32 = inst;
73         }
74 
75         explicit
RegisterValue(uint64_t inst)76         RegisterValue (uint64_t inst) :
77             m_type (eTypeUInt64)
78         {
79             m_data.uint64 = inst;
80         }
81 
82 #if defined (ENABLE_128_BIT_SUPPORT)
83         explicit
RegisterValue(__uint128_t inst)84         RegisterValue (__uint128_t inst) :
85             m_type (eTypeUInt128)
86         {
87             m_data.uint128 = inst;
88         }
89 #endif
90         explicit
RegisterValue(float value)91         RegisterValue (float value) :
92             m_type (eTypeFloat)
93         {
94             m_data.ieee_float = value;
95         }
96 
97         explicit
RegisterValue(double value)98         RegisterValue (double value) :
99             m_type (eTypeDouble)
100         {
101             m_data.ieee_double = value;
102         }
103 
104         explicit
RegisterValue(long double value)105         RegisterValue (long double value) :
106             m_type (eTypeLongDouble)
107         {
108             m_data.ieee_long_double = value;
109         }
110 
111         explicit
RegisterValue(uint8_t * bytes,size_t length,lldb::ByteOrder byte_order)112         RegisterValue (uint8_t *bytes, size_t length, lldb::ByteOrder byte_order)
113         {
114             SetBytes (bytes, length, byte_order);
115         }
116 
117         RegisterValue::Type
GetType()118         GetType () const
119         {
120             return m_type;
121         }
122 
123         bool
124         CopyValue (const RegisterValue &rhs);
125 
126         void
SetType(RegisterValue::Type type)127         SetType (RegisterValue::Type type)
128         {
129             m_type = type;
130         }
131 
132         RegisterValue::Type
133         SetType (const RegisterInfo *reg_info);
134 
135         bool
136         GetData (DataExtractor &data) const;
137 
138         // Copy the register value from this object into a buffer in "dst"
139         // and obey the "dst_byte_order" when copying the data. Also watch out
140         // in case "dst_len" is longer or shorter than the register value
141         // described by "reg_info" and only copy the least significant bytes
142         // of the register value, or pad the destination with zeroes if the
143         // register byte size is shorter that "dst_len" (all while correctly
144         // abiding the "dst_byte_order"). Returns the number of bytes copied
145         // into "dst".
146         uint32_t
147         GetAsMemoryData (const RegisterInfo *reg_info,
148                          void *dst,
149                          uint32_t dst_len,
150                          lldb::ByteOrder dst_byte_order,
151                          Error &error) const;
152 
153         uint32_t
154         SetFromMemoryData (const RegisterInfo *reg_info,
155                            const void *src,
156                            uint32_t src_len,
157                            lldb::ByteOrder src_byte_order,
158                            Error &error);
159 
160         bool
161         GetScalarValue (Scalar &scalar) const;
162 
163         uint8_t
164         GetAsUInt8 (uint8_t fail_value = UINT8_MAX, bool *success_ptr = NULL) const
165         {
166             if (m_type == eTypeUInt8)
167             {
168                 if (success_ptr)
169                     *success_ptr = true;
170                 return m_data.uint8;
171             }
172             if (success_ptr)
173                 *success_ptr = true;
174             return fail_value;
175         }
176 
177         uint16_t
178         GetAsUInt16 (uint16_t fail_value = UINT16_MAX, bool *success_ptr = NULL) const;
179 
180         uint32_t
181         GetAsUInt32 (uint32_t fail_value = UINT32_MAX, bool *success_ptr = NULL) const;
182 
183         uint64_t
184         GetAsUInt64 (uint64_t fail_value = UINT64_MAX, bool *success_ptr = NULL) const;
185 
186 #if defined (ENABLE_128_BIT_SUPPORT)
187         __uint128_t
188         GetAsUInt128 (__uint128_t fail_value = ~((__uint128_t)0), bool *success_ptr = NULL) const;
189 #endif
190 
191         float
192         GetAsFloat (float fail_value = 0.0f, bool *success_ptr = NULL) const;
193 
194         double
195         GetAsDouble (double fail_value = 0.0, bool *success_ptr = NULL) const;
196 
197         long double
198         GetAsLongDouble (long double fail_value = 0.0, bool *success_ptr = NULL) const;
199 
200         void
SetValueToInvalid()201         SetValueToInvalid ()
202         {
203             m_type = eTypeInvalid;
204         }
205 
206         bool
207         ClearBit (uint32_t bit);
208 
209         bool
210         SetBit (uint32_t bit);
211 
212         bool
213         operator == (const RegisterValue &rhs) const;
214 
215         bool
216         operator != (const RegisterValue &rhs) const;
217 
218         void
219         operator = (uint8_t uint)
220         {
221             m_type = eTypeUInt8;
222             m_data.uint8 = uint;
223         }
224 
225         void
226         operator = (uint16_t uint)
227         {
228             m_type = eTypeUInt16;
229             m_data.uint16 = uint;
230         }
231 
232         void
233         operator = (uint32_t uint)
234         {
235             m_type = eTypeUInt32;
236             m_data.uint32 = uint;
237         }
238 
239         void
240         operator = (uint64_t uint)
241         {
242             m_type = eTypeUInt64;
243             m_data.uint64 = uint;
244         }
245 
246 #if defined (ENABLE_128_BIT_SUPPORT)
247         void
248         operator = (__uint128_t uint)
249         {
250             m_type = eTypeUInt128;
251             m_data.uint128 = uint;
252         }
253 #endif
254         void
255         operator = (float f)
256         {
257             m_type = eTypeFloat;
258             m_data.ieee_float = f;
259         }
260 
261         void
262         operator = (double f)
263         {
264             m_type = eTypeDouble;
265             m_data.ieee_double = f;
266         }
267 
268         void
269         operator = (long double f)
270         {
271             m_type = eTypeLongDouble;
272             m_data.ieee_long_double = f;
273         }
274 
275         void
SetUInt8(uint8_t uint)276         SetUInt8 (uint8_t uint)
277         {
278             m_type = eTypeUInt8;
279             m_data.uint8 = uint;
280         }
281 
282         void
SetUInt16(uint16_t uint)283         SetUInt16 (uint16_t uint)
284         {
285             m_type = eTypeUInt16;
286             m_data.uint16 = uint;
287         }
288 
289         void
290         SetUInt32 (uint32_t uint, Type t = eTypeUInt32)
291         {
292             m_type = t;
293             m_data.uint32 = uint;
294         }
295 
296         void
297         SetUInt64 (uint64_t uint, Type t = eTypeUInt64)
298         {
299             m_type = t;
300             m_data.uint64 = uint;
301         }
302 
303 #if defined (ENABLE_128_BIT_SUPPORT)
304         void
SetUInt128(__uint128_t uint)305         SetUInt128 (__uint128_t uint)
306         {
307             m_type = eTypeUInt128;
308             m_data.uint128 = uint;
309         }
310 #endif
311         bool
312         SetUInt (uint64_t uint, uint32_t byte_size);
313 
314         void
SetFloat(float f)315         SetFloat (float f)
316         {
317             m_type = eTypeFloat;
318             m_data.ieee_float = f;
319         }
320 
321         void
SetDouble(double f)322         SetDouble (double f)
323         {
324             m_type = eTypeDouble;
325             m_data.ieee_double = f;
326         }
327 
328         void
SetLongDouble(long double f)329         SetLongDouble (long double f)
330         {
331             m_type = eTypeLongDouble;
332             m_data.ieee_long_double = f;
333         }
334 
335         void
336         SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_order);
337 
338         bool
339         SignExtend (uint32_t sign_bitpos);
340 
341         Error
342         SetValueFromCString (const RegisterInfo *reg_info,
343                              const char *value_str);
344 
345         Error
346         SetValueFromData (const RegisterInfo *reg_info,
347                           DataExtractor &data,
348                           lldb::offset_t offset,
349                           bool partial_data_ok);
350 
351         // The default value of 0 for reg_name_right_align_at means no alignment at all.
352         bool
353         Dump (Stream *s,
354               const RegisterInfo *reg_info,
355               bool prefix_with_name,
356               bool prefix_with_alt_name,
357               lldb::Format format,
358               uint32_t reg_name_right_align_at = 0) const;
359 
360         void *
361         GetBytes ();
362 
363         const void *
364         GetBytes () const;
365 
366         lldb::ByteOrder
GetByteOrder()367         GetByteOrder () const
368         {
369             if (m_type == eTypeBytes)
370                 return m_data.buffer.byte_order;
371             return lldb::endian::InlHostByteOrder();
372         }
373 
374         uint32_t
375         GetByteSize () const;
376 
377         void
378         Clear();
379 
380     protected:
381 
382         RegisterValue::Type m_type;
383         union
384         {
385             uint8_t  uint8;
386             uint16_t uint16;
387             uint32_t uint32;
388             uint64_t uint64;
389 #if defined (ENABLE_128_BIT_SUPPORT)
390             __uint128_t uint128;
391 #endif
392             float ieee_float;
393             double ieee_double;
394             long double ieee_long_double;
395             struct
396             {
397                 uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any register for any supported target.
398                 uint8_t length;
399                 lldb::ByteOrder byte_order;
400             } buffer;
401         } m_data;
402     };
403 
404 } // namespace lldb_private
405 
406 #endif	// lldb_RegisterValue_h
407