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
24namespace 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
49        RegisterValue () :
50            m_type (eTypeInvalid)
51        {
52        }
53
54        explicit
55        RegisterValue (uint8_t inst) :
56            m_type (eTypeUInt8)
57        {
58            m_data.uint8 = inst;
59        }
60
61        explicit
62        RegisterValue (uint16_t inst) :
63            m_type (eTypeUInt16)
64        {
65            m_data.uint16 = inst;
66        }
67
68        explicit
69        RegisterValue (uint32_t inst) :
70            m_type (eTypeUInt32)
71        {
72            m_data.uint32 = inst;
73        }
74
75        explicit
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
84        RegisterValue (__uint128_t inst) :
85            m_type (eTypeUInt128)
86        {
87            m_data.uint128 = inst;
88        }
89#endif
90        explicit
91        RegisterValue (float value) :
92            m_type (eTypeFloat)
93        {
94            m_data.ieee_float = value;
95        }
96
97        explicit
98        RegisterValue (double value) :
99            m_type (eTypeDouble)
100        {
101            m_data.ieee_double = value;
102        }
103
104        explicit
105        RegisterValue (long double value) :
106            m_type (eTypeLongDouble)
107        {
108            m_data.ieee_long_double = value;
109        }
110
111        explicit
112        RegisterValue (uint8_t *bytes, size_t length, lldb::ByteOrder byte_order)
113        {
114            SetBytes (bytes, length, byte_order);
115        }
116
117        RegisterValue::Type
118        GetType () const
119        {
120            return m_type;
121        }
122
123        bool
124        CopyValue (const RegisterValue &rhs);
125
126        void
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
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
276        SetUInt8 (uint8_t uint)
277        {
278            m_type = eTypeUInt8;
279            m_data.uint8 = uint;
280        }
281
282        void
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
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
315        SetFloat (float f)
316        {
317            m_type = eTypeFloat;
318            m_data.ieee_float = f;
319        }
320
321        void
322        SetDouble (double f)
323        {
324            m_type = eTypeDouble;
325            m_data.ieee_double = f;
326        }
327
328        void
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
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