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