1 //===-- Opcode.cpp ----------------------------------------------*- 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 //===----------------------------------------------------------------------===//
10 #include "lldb/Core/Opcode.h"
12 #include "lldb/Utility/DataBufferHeap.h"
13 #include "lldb/Utility/DataExtractor.h"
14 #include "lldb/Utility/Endian.h"
15 #include "lldb/Utility/Stream.h"
16 #include "lldb/lldb-forward.h" // for DataBufferSP
18 #include <memory> // for make_shared
20 #include <inttypes.h> // for PRIx64
23 using namespace lldb_private;
25 int Opcode::Dump(Stream *s, uint32_t min_byte_width) {
26 int bytes_written = 0;
28 case Opcode::eTypeInvalid:
29 bytes_written = s->PutCString("<invalid>");
32 bytes_written = s->Printf("0x%2.2x", m_data.inst8);
35 bytes_written = s->Printf("0x%4.4x", m_data.inst16);
37 case Opcode::eType16_2:
39 bytes_written = s->Printf("0x%8.8x", m_data.inst32);
43 bytes_written = s->Printf("0x%16.16" PRIx64, m_data.inst64);
46 case Opcode::eTypeBytes:
47 for (uint32_t i = 0; i < m_data.inst.length; ++i) {
49 bytes_written += s->PutChar(' ');
50 bytes_written += s->Printf("%2.2x", m_data.inst.bytes[i]);
55 // Add spaces to make sure bytes dispay comes out even in case opcodes
56 // aren't all the same size
57 if (static_cast<uint32_t>(bytes_written) < min_byte_width)
58 bytes_written = s->Printf("%*s", min_byte_width - bytes_written, "");
62 lldb::ByteOrder Opcode::GetDataByteOrder() const {
63 if (m_byte_order != eByteOrderInvalid) {
67 case Opcode::eTypeInvalid:
71 case Opcode::eType16_2:
74 return endian::InlHostByteOrder();
75 case Opcode::eTypeBytes:
78 return eByteOrderInvalid;
81 uint32_t Opcode::GetData(DataExtractor &data) const {
82 uint32_t byte_size = GetByteSize();
84 const void *buf = nullptr;
87 if (!GetEndianSwap()) {
88 if (m_type == Opcode::eType16_2) {
89 // 32 bit thumb instruction, we need to sizzle this a bit
90 swap_buf[0] = m_data.inst.bytes[2];
91 swap_buf[1] = m_data.inst.bytes[3];
92 swap_buf[2] = m_data.inst.bytes[0];
93 swap_buf[3] = m_data.inst.bytes[1];
96 buf = GetOpcodeDataBytes();
100 case Opcode::eTypeInvalid:
103 buf = GetOpcodeDataBytes();
105 case Opcode::eType16:
106 *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16);
109 case Opcode::eType16_2:
110 swap_buf[0] = m_data.inst.bytes[1];
111 swap_buf[1] = m_data.inst.bytes[0];
112 swap_buf[2] = m_data.inst.bytes[3];
113 swap_buf[3] = m_data.inst.bytes[2];
116 case Opcode::eType32:
117 *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32);
120 case Opcode::eType64:
121 *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64);
124 case Opcode::eTypeBytes:
125 buf = GetOpcodeDataBytes();
130 if (buf != nullptr) {
131 DataBufferSP buffer_sp;
133 buffer_sp = std::make_shared<DataBufferHeap>(buf, byte_size);
134 data.SetByteOrder(GetDataByteOrder());
135 data.SetData(buffer_sp);