]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/Opcode.cpp
Import libxo-0.7.2; add xo_options.7.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / Opcode.cpp
1 //===-- Opcode.cpp ----------------------------------------------*- 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 #include "lldb/Core/Opcode.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 #include "llvm/ADT/Triple.h"
16
17 // Project includes
18 #include "lldb/Core/ArchSpec.h"
19 #include "lldb/Core/DataBufferHeap.h"
20 #include "lldb/Core/DataExtractor.h"
21 #include "lldb/Core/Stream.h"
22 #include "lldb/Host/Endian.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 int Opcode::Dump(Stream *s, uint32_t min_byte_width) {
28   int bytes_written = 0;
29   switch (m_type) {
30   case Opcode::eTypeInvalid:
31     bytes_written = s->PutCString("<invalid>");
32     break;
33   case Opcode::eType8:
34     bytes_written = s->Printf("0x%2.2x", m_data.inst8);
35     break;
36   case Opcode::eType16:
37     bytes_written = s->Printf("0x%4.4x", m_data.inst16);
38     break;
39   case Opcode::eType16_2:
40   case Opcode::eType32:
41     bytes_written = s->Printf("0x%8.8x", m_data.inst32);
42     break;
43
44   case Opcode::eType64:
45     bytes_written = s->Printf("0x%16.16" PRIx64, m_data.inst64);
46     break;
47
48   case Opcode::eTypeBytes:
49     for (uint32_t i = 0; i < m_data.inst.length; ++i) {
50       if (i > 0)
51         bytes_written += s->PutChar(' ');
52       bytes_written += s->Printf("%2.2x", m_data.inst.bytes[i]);
53     }
54     break;
55   }
56
57   // Add spaces to make sure bytes dispay comes out even in case opcodes
58   // aren't all the same size
59   if (static_cast<uint32_t>(bytes_written) < min_byte_width)
60     bytes_written = s->Printf("%*s", min_byte_width - bytes_written, "");
61   return bytes_written;
62 }
63
64 lldb::ByteOrder Opcode::GetDataByteOrder() const {
65   if (m_byte_order != eByteOrderInvalid) {
66     return m_byte_order;
67   }
68   switch (m_type) {
69   case Opcode::eTypeInvalid:
70     break;
71   case Opcode::eType8:
72   case Opcode::eType16:
73   case Opcode::eType16_2:
74   case Opcode::eType32:
75   case Opcode::eType64:
76     return endian::InlHostByteOrder();
77   case Opcode::eTypeBytes:
78     break;
79   }
80   return eByteOrderInvalid;
81 }
82
83 uint32_t Opcode::GetData(DataExtractor &data) const {
84   uint32_t byte_size = GetByteSize();
85   uint8_t swap_buf[8];
86   const void *buf = nullptr;
87
88   if (byte_size > 0) {
89     if (!GetEndianSwap()) {
90       if (m_type == Opcode::eType16_2) {
91         // 32 bit thumb instruction, we need to sizzle this a bit
92         swap_buf[0] = m_data.inst.bytes[2];
93         swap_buf[1] = m_data.inst.bytes[3];
94         swap_buf[2] = m_data.inst.bytes[0];
95         swap_buf[3] = m_data.inst.bytes[1];
96         buf = swap_buf;
97       } else {
98         buf = GetOpcodeDataBytes();
99       }
100     } else {
101       switch (m_type) {
102       case Opcode::eTypeInvalid:
103         break;
104       case Opcode::eType8:
105         buf = GetOpcodeDataBytes();
106         break;
107       case Opcode::eType16:
108         *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16);
109         buf = swap_buf;
110         break;
111       case Opcode::eType16_2:
112         swap_buf[0] = m_data.inst.bytes[1];
113         swap_buf[1] = m_data.inst.bytes[0];
114         swap_buf[2] = m_data.inst.bytes[3];
115         swap_buf[3] = m_data.inst.bytes[2];
116         buf = swap_buf;
117         break;
118       case Opcode::eType32:
119         *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32);
120         buf = swap_buf;
121         break;
122       case Opcode::eType64:
123         *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64);
124         buf = swap_buf;
125         break;
126       case Opcode::eTypeBytes:
127         buf = GetOpcodeDataBytes();
128         break;
129       }
130     }
131   }
132   if (buf != nullptr) {
133     DataBufferSP buffer_sp;
134
135     buffer_sp.reset(new DataBufferHeap(buf, byte_size));
136     data.SetByteOrder(GetDataByteOrder());
137     data.SetData(buffer_sp);
138     return byte_size;
139   }
140   data.Clear();
141   return 0;
142 }