OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "vm/disassembler.h" | |
6 | |
7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. | |
8 #if defined(TARGET_ARCH_DBC) | |
9 | |
10 #include "platform/assert.h" | |
11 #include "vm/cpu.h" | |
12 | |
13 namespace dart { | |
14 | |
15 static const char* kOpcodeNames[] = { | |
16 #define BYTECODE_NAME(name, encoding, op1, op2, op3) #name, | |
17 BYTECODES_LIST(BYTECODE_NAME) | |
zra
2016/04/14 18:27:47
It looks like vm/constants_dbc.h is coming in thro
Vyacheslav Egorov (Google)
2016/04/18 15:56:40
Done.
| |
18 #undef BYTECODE_NAME | |
19 }; | |
20 | |
21 static const size_t kOpcodeCount = | |
22 sizeof(kOpcodeNames) / sizeof(kOpcodeNames[0]); | |
23 | |
24 typedef void (*BytecodeFormatter)(char* buffer, | |
25 intptr_t size, | |
26 uword pc, | |
27 uint32_t bc); | |
28 typedef void (*Fmt)(char** buf, intptr_t* size, uword pc, int32_t value); | |
29 | |
30 | |
31 template <typename ValueType> | |
32 void FormatOperand(char** buf, | |
33 intptr_t* size, | |
34 const char* fmt, | |
35 ValueType value) { | |
36 intptr_t written = OS::SNPrint(*buf, *size, fmt, value); | |
37 if (written < *size) { | |
38 *buf += written; | |
39 *size += written; | |
40 } else { | |
41 *size = -1; | |
42 } | |
43 } | |
44 | |
45 | |
46 static void Fmt___(char** buf, intptr_t* size, uword pc, int32_t value) {} | |
47 | |
48 | |
49 static void Fmttgt(char** buf, intptr_t* size, uword pc, int32_t value) { | |
50 FormatOperand(buf, size, "-> %" Px, pc + (value << 2)); | |
51 } | |
52 | |
53 | |
54 static void Fmtlit(char** buf, intptr_t* size, uword pc, int32_t value) { | |
55 FormatOperand(buf, size, "k%d", value); | |
56 } | |
57 | |
58 | |
59 static void Fmtreg(char** buf, intptr_t* size, uword pc, int32_t value) { | |
60 FormatOperand(buf, size, "r%d", value); | |
61 } | |
62 | |
63 | |
64 static void Fmtxeg(char** buf, intptr_t* size, uword pc, int32_t value) { | |
65 FormatOperand(buf, size, "R(%d)", value); | |
66 } | |
67 | |
68 | |
69 static void Fmtnum(char** buf, intptr_t* size, uword pc, int32_t value) { | |
70 FormatOperand(buf, size, "#%d", value); | |
71 } | |
72 | |
73 | |
74 static void Apply(char** buf, | |
75 intptr_t* size, | |
76 uword pc, | |
77 Fmt fmt, | |
78 int32_t value, | |
79 const char* suffix) { | |
80 if (*size <= 0) { | |
81 return; | |
82 } | |
83 | |
84 fmt(buf, size, pc, value); | |
85 if (*size > 0) { | |
86 FormatOperand(buf, size, "%s", suffix); | |
87 } | |
88 } | |
89 | |
90 | |
91 static void Format0(char* buf, | |
92 intptr_t size, | |
93 uword pc, | |
94 uint32_t op, | |
95 Fmt op1, | |
96 Fmt op2, | |
97 Fmt op3) {} | |
98 | |
99 | |
100 static void FormatT(char* buf, | |
101 intptr_t size, | |
102 uword pc, | |
103 uint32_t op, | |
104 Fmt op1, | |
105 Fmt op2, | |
106 Fmt op3) { | |
107 const int32_t x = static_cast<int32_t>(op) >> 8; | |
108 Apply(&buf, &size, pc, op1, x, ""); | |
109 } | |
110 | |
111 | |
112 static void FormatA(char* buf, | |
113 intptr_t size, | |
114 uword pc, | |
115 uint32_t op, | |
116 Fmt op1, | |
117 Fmt op2, | |
118 Fmt op3) { | |
119 const int32_t a = (op & 0xFF00) >> 8; | |
120 Apply(&buf, &size, pc, op1, a, ""); | |
121 } | |
122 | |
123 | |
124 static void FormatA_D(char* buf, | |
125 intptr_t size, | |
126 uword pc, | |
127 uint32_t op, | |
128 Fmt op1, | |
129 Fmt op2, | |
130 Fmt op3) { | |
131 const int32_t a = (op & 0xFF00) >> 8; | |
132 const int32_t bc = op >> 16; | |
133 Apply(&buf, &size, pc, op1, a, ", "); | |
134 Apply(&buf, &size, pc, op2, bc, ""); | |
135 } | |
136 | |
137 | |
138 static void FormatA_X(char* buf, | |
139 intptr_t size, | |
140 uword pc, | |
141 uint32_t op, | |
142 Fmt op1, | |
143 Fmt op2, | |
144 Fmt op3) { | |
145 const int32_t a = (op & 0xFF00) >> 8; | |
146 const int32_t bc = static_cast<int32_t>(op) >> 16; | |
147 Apply(&buf, &size, pc, op1, a, ", "); | |
148 Apply(&buf, &size, pc, op2, bc, ""); | |
149 } | |
150 | |
151 | |
152 static void FormatX(char* buf, | |
153 intptr_t size, | |
154 uword pc, | |
155 uint32_t op, | |
156 Fmt op1, | |
157 Fmt op2, | |
158 Fmt op3) { | |
159 const int32_t bc = static_cast<int32_t>(op) >> 16; | |
160 Apply(&buf, &size, pc, op1, bc, ""); | |
161 } | |
162 | |
163 | |
164 static void FormatD(char* buf, | |
165 intptr_t size, | |
166 uword pc, | |
167 uint32_t op, | |
168 Fmt op1, | |
169 Fmt op2, | |
170 Fmt op3) { | |
171 const int32_t bc = op >> 16; | |
172 Apply(&buf, &size, pc, op1, bc, ""); | |
173 } | |
174 | |
175 | |
176 static void FormatA_B_C(char* buf, | |
177 intptr_t size, | |
178 uword pc, | |
179 uint32_t op, | |
180 Fmt op1, | |
181 Fmt op2, | |
182 Fmt op3) { | |
183 const int32_t a = (op >> 8) & 0xFF; | |
184 const int32_t b = (op >> 16) & 0xFF; | |
185 const int32_t c = (op >> 24) & 0xFF; | |
186 Apply(&buf, &size, pc, op1, a, ", "); | |
187 Apply(&buf, &size, pc, op2, b, ", "); | |
188 Apply(&buf, &size, pc, op3, c, ""); | |
189 } | |
190 | |
191 | |
192 #define BYTECODE_FORMATTER(name, encoding, op1, op2, op3) \ | |
193 static void Format##name(char* buf, intptr_t size, uword pc, uint32_t op) { \ | |
194 Format##encoding(buf, size, pc, op, Fmt##op1, Fmt##op2, Fmt##op3); \ | |
195 } | |
196 BYTECODES_LIST(BYTECODE_FORMATTER) | |
197 #undef BYTECODE_FORMATTER | |
198 | |
199 | |
200 static const BytecodeFormatter kFormatters[] = { | |
201 #define BYTECODE_FORMATTER(name, encoding, op1, op2, op3) &Format##name, | |
202 BYTECODES_LIST(BYTECODE_FORMATTER) | |
203 #undef BYTECODE_FORMATTER | |
204 }; | |
205 | |
206 | |
207 void Disassembler::DecodeInstruction(char* hex_buffer, | |
208 intptr_t hex_size, | |
209 char* human_buffer, | |
210 intptr_t human_size, | |
211 int* out_instr_size, | |
212 uword pc) { | |
213 const uint32_t instr = *reinterpret_cast<uint32_t*>(pc); | |
214 const uint8_t opcode = instr & 0xFF; | |
215 ASSERT(opcode < kOpcodeCount); | |
216 size_t name_size = | |
217 OS::SNPrint(human_buffer, human_size, "%-10s\t", kOpcodeNames[opcode]); | |
218 | |
219 human_buffer += name_size; | |
220 human_size -= name_size; | |
221 kFormatters[opcode](human_buffer, human_size, pc, instr); | |
222 | |
223 OS::SNPrint(hex_buffer, hex_size, "%08x", instr); | |
224 if (out_instr_size) { | |
225 *out_instr_size = sizeof(uint32_t); | |
226 } | |
227 } | |
228 | |
229 | |
230 } // namespace dart | |
231 | |
232 #endif // defined TARGET_ARCH_DBC | |
OLD | NEW |