1 //===-- Opcode.cpp --------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Core/Opcode.h"
11 #include "lldb/Utility/DataBufferHeap.h"
12 #include "lldb/Utility/DataExtractor.h"
13 #include "lldb/Utility/Endian.h"
14 #include "lldb/Utility/Stream.h"
15 #include "lldb/lldb-forward.h"
22 using namespace lldb_private
;
24 int Opcode::Dump(Stream
*s
, uint32_t min_byte_width
) {
25 const uint32_t previous_bytes
= s
->GetWrittenBytes();
27 case Opcode::eTypeInvalid
:
28 s
->PutCString("<invalid>");
31 s
->Printf("0x%2.2x", m_data
.inst8
);
34 s
->Printf("0x%4.4x", m_data
.inst16
);
36 case Opcode::eType16_2
:
38 s
->Printf("0x%8.8x", m_data
.inst32
);
42 s
->Printf("0x%16.16" PRIx64
, m_data
.inst64
);
45 case Opcode::eTypeBytes
:
46 for (uint32_t i
= 0; i
< m_data
.inst
.length
; ++i
) {
49 s
->Printf("%2.2x", m_data
.inst
.bytes
[i
]);
54 uint32_t bytes_written_so_far
= s
->GetWrittenBytes() - previous_bytes
;
55 // Add spaces to make sure bytes display comes out even in case opcodes aren't
57 if (bytes_written_so_far
< min_byte_width
)
58 s
->Printf("%*s", min_byte_width
- bytes_written_so_far
, "");
59 return s
->GetWrittenBytes() - previous_bytes
;
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
<uint16_t>(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
<uint32_t>(m_data
.inst32
);
120 case Opcode::eType64
:
121 *(uint32_t *)swap_buf
= llvm::byteswap
<uint64_t>(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
);