Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: runtime/vm/disassembler_mips.cc

Issue 12431016: Copies Simulator Debugger from ARM to MIPS. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/disassembler.h" 5 #include "vm/disassembler.h"
6 6
7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
8 #if defined(TARGET_ARCH_MIPS) 8 #if defined(TARGET_ARCH_MIPS)
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 10
11 namespace dart { 11 namespace dart {
12 12
13 class MIPSDecoder : public ValueObject { 13 class MIPSDecoder : public ValueObject {
14 public: 14 public:
15 MIPSDecoder(char* buffer, size_t buffer_size) 15 MIPSDecoder(char* buffer, size_t buffer_size)
16 : buffer_(buffer), 16 : buffer_(buffer),
17 buffer_size_(buffer_size), 17 buffer_size_(buffer_size),
18 buffer_pos_(0) { 18 buffer_pos_(0),
19 decode_failure_(false) {
19 buffer_[buffer_pos_] = '\0'; 20 buffer_[buffer_pos_] = '\0';
20 } 21 }
21 22
22 ~MIPSDecoder() {} 23 ~MIPSDecoder() {}
23 24
24 // Writes one disassembled instruction into 'buffer' (0-terminated). 25 // Writes one disassembled instruction into 'buffer' (0-terminated).
26 // Returns true if the instruction was successfully decoded, false otherwise.
25 void InstructionDecode(Instr* instr); 27 void InstructionDecode(Instr* instr);
26 28
29 void set_decode_failure(bool b) { decode_failure_ = b; }
30 bool decode_failure() const { return decode_failure_; }
31
27 private: 32 private:
28 // Bottleneck functions to print into the out_buffer. 33 // Bottleneck functions to print into the out_buffer.
29 void Print(const char* str); 34 void Print(const char* str);
30 35
31 // Printing of common values. 36 // Printing of common values.
32 void PrintRegister(Register reg); 37 void PrintRegister(Register reg);
33 38
34 int FormatRegister(Instr* instr, const char* format); 39 int FormatRegister(Instr* instr, const char* format);
35 int FormatOption(Instr* instr, const char* format); 40 int FormatOption(Instr* instr, const char* format);
36 void Format(Instr* instr, const char* format); 41 void Format(Instr* instr, const char* format);
42 void Unknown(Instr* instr);
37 43
38 void DecodeSpecial(Instr* instr); 44 void DecodeSpecial(Instr* instr);
39 void DecodeSpecial2(Instr* instr); 45 void DecodeSpecial2(Instr* instr);
40 void DecodeSpecial3(Instr* instr);
41 46
42 // Convenience functions. 47 // Convenience functions.
43 char* get_buffer() const { return buffer_; } 48 char* get_buffer() const { return buffer_; }
44 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } 49 char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
45 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } 50 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
46 51
47 char* buffer_; // Decode instructions into this buffer. 52 char* buffer_; // Decode instructions into this buffer.
48 size_t buffer_size_; // The size of the character buffer. 53 size_t buffer_size_; // The size of the character buffer.
49 size_t buffer_pos_; // Current character position in buffer. 54 size_t buffer_pos_; // Current character position in buffer.
50 55
56 bool decode_failure_; // Set to true when a failure to decode is detected.
57
51 DISALLOW_ALLOCATION(); 58 DISALLOW_ALLOCATION();
52 DISALLOW_COPY_AND_ASSIGN(MIPSDecoder); 59 DISALLOW_COPY_AND_ASSIGN(MIPSDecoder);
53 }; 60 };
54 61
55 62
56 // Support for assertions in the MIPSDecoder formatting functions. 63 // Support for assertions in the MIPSDecoder formatting functions.
57 #define STRING_STARTS_WITH(string, compare_string) \ 64 #define STRING_STARTS_WITH(string, compare_string) \
58 (strncmp(string, compare_string, strlen(compare_string)) == 0) 65 (strncmp(string, compare_string, strlen(compare_string)) == 0)
59 66
60 67
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 114 }
108 115
109 116
110 // FormatOption takes a formatting string and interprets it based on 117 // FormatOption takes a formatting string and interprets it based on
111 // the current instructions. The format string points to the first 118 // the current instructions. The format string points to the first
112 // character of the option string (the option escape has already been 119 // character of the option string (the option escape has already been
113 // consumed by the caller.) FormatOption returns the number of 120 // consumed by the caller.) FormatOption returns the number of
114 // characters that were consumed from the formatting string. 121 // characters that were consumed from the formatting string.
115 int MIPSDecoder::FormatOption(Instr* instr, const char* format) { 122 int MIPSDecoder::FormatOption(Instr* instr, const char* format) {
116 switch (format[0]) { 123 switch (format[0]) {
124 case 'c': {
125 ASSERT(STRING_STARTS_WITH(format, "code"));
126 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
127 remaining_size_in_buffer(),
128 "%d", instr->BreakCodeField());
129 return 4;
130 }
117 case 'h': { 131 case 'h': {
118 ASSERT(STRING_STARTS_WITH(format, "hint")); 132 ASSERT(STRING_STARTS_WITH(format, "hint"));
119 if (instr->SaField() != 0) { 133 if (instr->SaField() == 0x10) {
120 UNIMPLEMENTED(); 134 // The high bit of the SA field is the only one that means something for
135 // JALR and JR. TODO(zra): Fill in the other cases for PREF if needed.
136 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
137 remaining_size_in_buffer(),
138 ".hb");
139 } else if (instr->SaField() != 0) {
140 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
141 remaining_size_in_buffer(),
142 ".unknown");
121 } 143 }
122 return 4; 144 return 4;
123 } 145 }
124 case 'i': { 146 case 'i': {
125 ASSERT(STRING_STARTS_WITH(format, "imm")); 147 ASSERT(STRING_STARTS_WITH(format, "imm"));
126 if (format[3] == 'u') { 148 if (format[3] == 'u') {
127 int32_t imm = instr->UImmField(); 149 int32_t imm = instr->UImmField();
128 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 150 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
129 remaining_size_in_buffer(), 151 remaining_size_in_buffer(),
130 "0x%x", 152 "0x%x",
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 format += FormatOption(instr, format); 191 format += FormatOption(instr, format);
170 } else { 192 } else {
171 buffer_[buffer_pos_++] = cur; 193 buffer_[buffer_pos_++] = cur;
172 } 194 }
173 cur = *format++; 195 cur = *format++;
174 } 196 }
175 buffer_[buffer_pos_] = '\0'; 197 buffer_[buffer_pos_] = '\0';
176 } 198 }
177 199
178 200
201 // For currently unimplemented decodings the disassembler calls Unknown(instr)
202 // which will just print "unknown" of the instruction bits.
203 void MIPSDecoder::Unknown(Instr* instr) {
204 Format(instr, "unknown");
205 set_decode_failure(true);
206 }
207
208
179 void MIPSDecoder::DecodeSpecial(Instr* instr) { 209 void MIPSDecoder::DecodeSpecial(Instr* instr) {
180 ASSERT(instr->OpcodeField() == SPECIAL); 210 ASSERT(instr->OpcodeField() == SPECIAL);
181 switch (instr->FunctionField()) { 211 switch (instr->FunctionField()) {
182 case ADDU: { 212 case ADDU: {
183 Format(instr, "addu 'rd, 'rs, 'rt"); 213 Format(instr, "addu 'rd, 'rs, 'rt");
184 break; 214 break;
185 } 215 }
186 case AND: { 216 case AND: {
187 Format(instr, "and 'rd, 'rs, 'rt"); 217 Format(instr, "and 'rd, 'rs, 'rt");
188 break; 218 break;
189 } 219 }
220 case BREAK: {
221 Format(instr, "break 'code");
222 break;
223 }
190 case DIV: { 224 case DIV: {
191 Format(instr, "div 'rs, 'rt"); 225 Format(instr, "div 'rs, 'rt");
192 break; 226 break;
193 } 227 }
194 case DIVU: { 228 case DIVU: {
195 Format(instr, "divu 'rs, 'rt"); 229 Format(instr, "divu 'rs, 'rt");
196 break; 230 break;
197 } 231 }
198 case MFHI: { 232 case MFHI: {
199 Format(instr, "mfhi 'rd"); 233 Format(instr, "mfhi 'rd");
200 break; 234 break;
201 } 235 }
202 case MFLO: { 236 case MFLO: {
203 Format(instr, "mflo 'rd"); 237 Format(instr, "mflo 'rd");
204 break; 238 break;
205 } 239 }
206 case SLL: { 240 case SLL: {
207 if ((instr->RdField() == R0) && 241 if ((instr->RdField() == R0) &&
208 (instr->RtField() == R0) && 242 (instr->RtField() == R0) &&
209 (instr->SaField() == 0)) { 243 (instr->SaField() == 0)) {
210 Format(instr, "nop"); 244 Format(instr, "nop");
211 } else { 245 } else {
212 Format(instr, "sll 'rd, 'rt, 'sa"); 246 Format(instr, "sll 'rd, 'rt, 'sa");
213 } 247 }
214 break; 248 break;
215 } 249 }
216 case JR: { 250 case JR: {
217 ASSERT(instr->RtField() == R0);
218 ASSERT(instr->RdField() == R0);
219 Format(instr, "jr'hint 'rs"); 251 Format(instr, "jr'hint 'rs");
220 break; 252 break;
221 } 253 }
222 default: { 254 default: {
223 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits()); 255 Unknown(instr);
224 UNREACHABLE();
225 break; 256 break;
226 } 257 }
227 } 258 }
228 } 259 }
229 260
230 261
231 void MIPSDecoder::DecodeSpecial2(Instr* instr) { 262 void MIPSDecoder::DecodeSpecial2(Instr* instr) {
232 ASSERT(instr->OpcodeField() == SPECIAL2); 263 ASSERT(instr->OpcodeField() == SPECIAL2);
233 switch (instr->FunctionField()) { 264 switch (instr->FunctionField()) {
234 case CLO: { 265 case CLO: {
235 Format(instr, "clo 'rd, 'rs"); 266 Format(instr, "clo 'rd, 'rs");
236 break; 267 break;
237 } 268 }
238 case CLZ: { 269 case CLZ: {
239 Format(instr, "clz 'rd, 'rs"); 270 Format(instr, "clz 'rd, 'rs");
240 break; 271 break;
241 } 272 }
242 default: { 273 default: {
243 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits()); 274 Unknown(instr);
244 UNREACHABLE();
245 break;
246 }
247 }
248 }
249
250
251 void MIPSDecoder::DecodeSpecial3(Instr* instr) {
252 ASSERT(instr->OpcodeField() == SPECIAL3);
253 switch (instr->FunctionField()) {
254 default: {
255 OS::PrintErr("DecodeSpecial3: 0x%x\n", instr->InstructionBits());
256 UNREACHABLE();
257 break; 275 break;
258 } 276 }
259 } 277 }
260 } 278 }
261 279
262 280
263 void MIPSDecoder::InstructionDecode(Instr* instr) { 281 void MIPSDecoder::InstructionDecode(Instr* instr) {
264 switch (instr->OpcodeField()) { 282 switch (instr->OpcodeField()) {
265 case SPECIAL: { 283 case SPECIAL: {
266 DecodeSpecial(instr); 284 DecodeSpecial(instr);
267 break; 285 break;
268 } 286 }
269 case SPECIAL2: { 287 case SPECIAL2: {
270 DecodeSpecial2(instr); 288 DecodeSpecial2(instr);
271 break; 289 break;
272 } 290 }
273 case SPECIAL3: {
274 DecodeSpecial3(instr);
275 break;
276 }
277 case ADDIU: { 291 case ADDIU: {
278 Format(instr, "addiu 'rt, 'rs, 'imms"); 292 Format(instr, "addiu 'rt, 'rs, 'imms");
279 break; 293 break;
280 } 294 }
281 case ANDI: { 295 case ANDI: {
282 Format(instr, "andi 'rt, 'rs, 'immu"); 296 Format(instr, "andi 'rt, 'rs, 'immu");
283 break; 297 break;
284 } 298 }
285 case LB: { 299 case LB: {
286 Format(instr, "lb 'rt, 'imms('rs)"); 300 Format(instr, "lb 'rt, 'imms('rs)");
(...skipping 25 matching lines...) Expand all
312 } 326 }
313 case SH: { 327 case SH: {
314 Format(instr, "sh 'rt, 'imms('rs)"); 328 Format(instr, "sh 'rt, 'imms('rs)");
315 break; 329 break;
316 } 330 }
317 case SW: { 331 case SW: {
318 Format(instr, "sw 'rt, 'imms('rs)"); 332 Format(instr, "sw 'rt, 'imms('rs)");
319 break; 333 break;
320 } 334 }
321 default: { 335 default: {
322 OS::PrintErr("Undecoded instruction: 0x%x\n", instr->InstructionBits()); 336 Unknown(instr);
323 UNREACHABLE();
324 break; 337 break;
325 } 338 }
326 } 339 }
327 } 340 }
328 341
329 342
330 int Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, 343 bool Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
331 char* human_buffer, intptr_t human_size, 344 char* human_buffer, intptr_t human_size,
332 uword pc) { 345 int *out_instr_len, uword pc) {
333 MIPSDecoder decoder(human_buffer, human_size); 346 MIPSDecoder decoder(human_buffer, human_size);
334 Instr* instr = Instr::At(pc); 347 Instr* instr = Instr::At(pc);
335 decoder.InstructionDecode(instr); 348 decoder.InstructionDecode(instr);
336 OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits()); 349 OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits());
337 return Instr::kInstrSize; 350 if (out_instr_len) {
351 *out_instr_len = Instr::kInstrSize;
352 }
353 return !decoder.decode_failure();
338 } 354 }
339 355
340 356
341 void Disassembler::Disassemble(uword start, 357 bool Disassembler::Disassemble(uword start,
342 uword end, 358 uword end,
343 DisassemblyFormatter* formatter, 359 DisassemblyFormatter* formatter,
344 const Code::Comments& comments) { 360 const Code::Comments& comments) {
345 ASSERT(formatter != NULL); 361 ASSERT(formatter != NULL);
362 bool success = true;
346 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form. 363 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form.
347 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction. 364 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction.
348 uword pc = start; 365 uword pc = start;
349 intptr_t comment_finger = 0; 366 intptr_t comment_finger = 0;
350 while (pc < end) { 367 while (pc < end) {
351 const intptr_t offset = pc - start; 368 const intptr_t offset = pc - start;
352 while (comment_finger < comments.Length() && 369 while (comment_finger < comments.Length() &&
353 comments.PCOffsetAt(comment_finger) <= offset) { 370 comments.PCOffsetAt(comment_finger) <= offset) {
354 formatter->Print( 371 formatter->Print(
355 " ;; %s\n", 372 " ;; %s\n",
356 String::Handle(comments.CommentAt(comment_finger)).ToCString()); 373 String::Handle(comments.CommentAt(comment_finger)).ToCString());
357 comment_finger++; 374 comment_finger++;
358 } 375 }
359 int instruction_length = DecodeInstruction(hex_buffer, 376 int instruction_length;
360 sizeof(hex_buffer), 377 bool res = DecodeInstruction(hex_buffer, sizeof(hex_buffer),
361 human_buffer, 378 human_buffer, sizeof(human_buffer),
362 sizeof(human_buffer), 379 &instruction_length, pc);
363 pc); 380 if (!res) {
381 success = false;
382 }
364 formatter->ConsumeInstruction(hex_buffer, 383 formatter->ConsumeInstruction(hex_buffer,
365 sizeof(hex_buffer), 384 sizeof(hex_buffer),
366 human_buffer, 385 human_buffer,
367 sizeof(human_buffer), 386 sizeof(human_buffer),
368 pc); 387 pc);
369 pc += instruction_length; 388 pc += instruction_length;
370 } 389 }
390
391 return success;
371 } 392 }
372 393
373 } // namespace dart 394 } // namespace dart
374 395
375 #endif // defined TARGET_ARCH_MIPS 396 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698