Opcode.h revision ba083b2404ce8753548c5d8c606e25e821f1d6ef
1//===-- Opcode.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_Opcode_h
11#define lldb_Opcode_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
21namespace lldb_private {
22
23    class Opcode
24    {
25    public:
26        enum Type
27        {
28            eTypeInvalid,
29            eType8,
30            eType16,
31            eType32,
32            eType64,
33            eTypeBytes
34        };
35
36        Opcode () : m_type (eTypeInvalid)
37        {
38        }
39
40        Opcode (uint8_t inst) : m_type (eType8)
41        {
42            m_data.inst8 = inst;
43        }
44
45        Opcode (uint16_t inst) : m_type (eType16)
46        {
47            m_data.inst16 = inst;
48        }
49
50        Opcode (uint32_t inst) : m_type (eType32)
51        {
52            m_data.inst32 = inst;
53        }
54
55        Opcode (uint64_t inst) : m_type (eType64)
56        {
57            m_data.inst64 = inst;
58        }
59
60        Opcode (uint8_t *bytes, size_t length)
61        {
62            SetOpcodeBytes (bytes, length);
63        }
64
65        Opcode::Type
66        GetType () const
67        {
68            return m_type;
69        }
70
71        uint8_t
72        GetOpcode8 (uint8_t invalid_opcode = UINT8_MAX) const
73        {
74            switch (m_type)
75            {
76            case Opcode::eTypeInvalid:  break;
77            case Opcode::eType8:        return m_data.inst8;
78            case Opcode::eType16:       break;
79            case Opcode::eType32:       break;
80            case Opcode::eType64:       break;
81            case Opcode::eTypeBytes:    break;
82                break;
83            }
84            return invalid_opcode;
85        }
86
87        uint16_t
88        GetOpcode16 (uint16_t invalid_opcode = UINT16_MAX) const
89        {
90            switch (m_type)
91            {
92            case Opcode::eTypeInvalid:  break;
93            case Opcode::eType8:        return m_data.inst8;
94            case Opcode::eType16:       return m_data.inst16;
95            case Opcode::eType32:       break;
96            case Opcode::eType64:       break;
97            case Opcode::eTypeBytes:    break;
98            }
99            return invalid_opcode;
100        }
101
102        uint32_t
103        GetOpcode32 (uint32_t invalid_opcode = UINT32_MAX) const
104        {
105            switch (m_type)
106            {
107            case Opcode::eTypeInvalid:  break;
108            case Opcode::eType8:        return m_data.inst8;
109            case Opcode::eType16:       return m_data.inst16;
110            case Opcode::eType32:       return m_data.inst32;
111            case Opcode::eType64:       break;
112            case Opcode::eTypeBytes:    break;
113            }
114            return invalid_opcode;
115        }
116
117        uint64_t
118        GetOpcode64 (uint64_t invalid_opcode = UINT64_MAX) const
119        {
120            switch (m_type)
121            {
122            case Opcode::eTypeInvalid:  break;
123            case Opcode::eType8:        return m_data.inst8;
124            case Opcode::eType16:       return m_data.inst16;
125            case Opcode::eType32:       return m_data.inst32;
126            case Opcode::eType64:       return m_data.inst64;
127            case Opcode::eTypeBytes:    break;
128            }
129            return invalid_opcode;
130        }
131
132        void
133        SetOpcode8 (uint8_t inst)
134        {
135            m_type = eType8;
136            m_data.inst8 = inst;
137        }
138
139        void
140        SetOpcode16 (uint16_t inst)
141        {
142            m_type = eType16;
143            m_data.inst16 = inst;
144        }
145
146        void
147        SetOpcode32 (uint32_t inst)
148        {
149            m_type = eType32;
150            m_data.inst32 = inst;
151        }
152
153        void
154        SetOpcode64 (uint64_t inst)
155        {
156            m_type = eType64;
157            m_data.inst64 = inst;
158        }
159
160        void
161        SetOpcodeBytes (const void *bytes, size_t length)
162        {
163            if (bytes && length > 0)
164            {
165                m_type = eTypeBytes;
166                assert (length < sizeof (m_data.inst.bytes));
167                memcpy (m_data.inst.bytes, bytes, length);
168            }
169            else
170            {
171                m_type = eTypeInvalid;
172                m_data.inst.length = 0;
173            }
174        }
175
176        int
177        Dump (Stream *s, uint32_t min_byte_width);
178
179        const void *
180        GetOpcodeBytes () const
181        {
182            if (m_type == Opcode::eTypeBytes)
183                return m_data.inst.bytes;
184            return NULL;
185        }
186
187        uint32_t
188        GetByteSize () const
189        {
190            switch (m_type)
191            {
192            case Opcode::eTypeInvalid: break;
193            case Opcode::eType8:     return sizeof(m_data.inst8);
194            case Opcode::eType16:    return sizeof(m_data.inst16);
195            case Opcode::eType32:    return sizeof(m_data.inst32);
196            case Opcode::eType64:    return sizeof(m_data.inst64);
197            case Opcode::eTypeBytes: return m_data.inst.length;
198            }
199            return 0;
200        }
201
202
203    protected:
204
205        Opcode::Type m_type;
206        union
207        {
208            uint8_t inst8;
209            uint16_t inst16;
210            uint32_t inst32;
211            uint64_t inst64;
212            struct
213            {
214                uint8_t length;
215                uint8_t bytes[16]; // This must be big enough to handle any opcode for any supported target.
216            } inst;
217        } m_data;
218    };
219
220} // namespace lldb_private
221
222#endif	// lldb_Opcode_h
223