1 //===-- Opcode.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 //===----------------------------------------------------------------------===//
17 // Other libraries and framework includes
18 #include "llvm/Support/MathExtras.h"
20 #include "lldb/Host/Endian.h"
21 #include "lldb/lldb-public.h"
28 namespace lldb_private {
38 eType16_2, // a 32-bit Thumb instruction, made up of two words
44 Opcode () : m_byte_order (lldb::eByteOrderInvalid), m_type (eTypeInvalid)
48 Opcode (uint8_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType8)
53 Opcode (uint16_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType16)
58 Opcode (uint32_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType32)
63 Opcode (uint64_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType64)
68 Opcode (uint8_t *bytes, size_t length) : m_byte_order (lldb::eByteOrderInvalid)
70 SetOpcodeBytes (bytes, length);
76 m_byte_order = lldb::eByteOrderInvalid;
77 m_type = Opcode::eTypeInvalid;
86 GetOpcode8 (uint8_t invalid_opcode = UINT8_MAX) const
90 case Opcode::eTypeInvalid: break;
91 case Opcode::eType8: return m_data.inst8;
92 case Opcode::eType16: break;
93 case Opcode::eType16_2: break;
94 case Opcode::eType32: break;
95 case Opcode::eType64: break;
96 case Opcode::eTypeBytes: break;
98 return invalid_opcode;
102 GetOpcode16 (uint16_t invalid_opcode = UINT16_MAX) const
106 case Opcode::eTypeInvalid: break;
107 case Opcode::eType8: return m_data.inst8;
108 case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
109 case Opcode::eType16_2: break;
110 case Opcode::eType32: break;
111 case Opcode::eType64: break;
112 case Opcode::eTypeBytes: break;
114 return invalid_opcode;
118 GetOpcode32 (uint32_t invalid_opcode = UINT32_MAX) const
122 case Opcode::eTypeInvalid: break;
123 case Opcode::eType8: return m_data.inst8;
124 case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
125 case Opcode::eType16_2: // passthrough
126 case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
127 case Opcode::eType64: break;
128 case Opcode::eTypeBytes: break;
130 return invalid_opcode;
134 GetOpcode64 (uint64_t invalid_opcode = UINT64_MAX) const
138 case Opcode::eTypeInvalid: break;
139 case Opcode::eType8: return m_data.inst8;
140 case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
141 case Opcode::eType16_2: // passthrough
142 case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
143 case Opcode::eType64: return GetEndianSwap() ? llvm::ByteSwap_64(m_data.inst64) : m_data.inst64;
144 case Opcode::eTypeBytes: break;
146 return invalid_opcode;
150 SetOpcode8 (uint8_t inst, lldb::ByteOrder order)
154 m_byte_order = order;
158 SetOpcode16 (uint16_t inst, lldb::ByteOrder order)
161 m_data.inst16 = inst;
162 m_byte_order = order;
166 SetOpcode16_2 (uint32_t inst, lldb::ByteOrder order)
169 m_data.inst32 = inst;
170 m_byte_order = order;
174 SetOpcode32 (uint32_t inst, lldb::ByteOrder order)
177 m_data.inst32 = inst;
178 m_byte_order = order;
182 SetOpcode64 (uint64_t inst, lldb::ByteOrder order)
185 m_data.inst64 = inst;
186 m_byte_order = order;
190 SetOpcodeBytes (const void *bytes, size_t length)
192 if (bytes && length > 0)
195 m_data.inst.length = length;
196 assert (length < sizeof (m_data.inst.bytes));
197 memcpy (m_data.inst.bytes, bytes, length);
198 m_byte_order = lldb::eByteOrderInvalid;
202 m_type = eTypeInvalid;
203 m_data.inst.length = 0;
208 Dump (Stream *s, uint32_t min_byte_width);
211 GetOpcodeBytes () const
213 if (m_type == Opcode::eTypeBytes)
214 return m_data.inst.bytes;
223 case Opcode::eTypeInvalid: break;
224 case Opcode::eType8: return sizeof(m_data.inst8);
225 case Opcode::eType16: return sizeof(m_data.inst16);
226 case Opcode::eType16_2: // passthrough
227 case Opcode::eType32: return sizeof(m_data.inst32);
228 case Opcode::eType64: return sizeof(m_data.inst64);
229 case Opcode::eTypeBytes: return m_data.inst.length;
234 // Get the opcode exactly as it would be laid out in memory.
236 GetData (DataExtractor &data) const;
240 friend class lldb::SBInstruction;
243 GetOpcodeDataBytes () const
247 case Opcode::eTypeInvalid: break;
248 case Opcode::eType8: return &m_data.inst8;
249 case Opcode::eType16: return &m_data.inst16;
250 case Opcode::eType16_2: // passthrough
251 case Opcode::eType32: return &m_data.inst32;
252 case Opcode::eType64: return &m_data.inst64;
253 case Opcode::eTypeBytes: return m_data.inst.bytes;
259 GetDataByteOrder () const;
262 GetEndianSwap() const
264 return (m_byte_order == lldb::eByteOrderBig && lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle) ||
265 (m_byte_order == lldb::eByteOrderLittle && lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig);
268 lldb::ByteOrder m_byte_order;
279 uint8_t bytes[16]; // This must be big enough to handle any opcode for any supported target.
285 } // namespace lldb_private
287 #endif // lldb_Opcode_h