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

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 buffer_[buffer_pos_] = '\0'; 19 buffer_[buffer_pos_] = '\0';
20 } 20 }
21 21
22 ~MIPSDecoder() {} 22 ~MIPSDecoder() {}
23 23
24 // Writes one disassembled instruction into 'buffer' (0-terminated). 24 // Writes one disassembled instruction into 'buffer' (0-terminated).
25 void InstructionDecode(Instr* instr); 25 // Returns true if the instruction was successfully decoded, false otherwise.
26 bool InstructionDecode(Instr* instr);
26 27
27 private: 28 private:
28 // Bottleneck functions to print into the out_buffer. 29 // Bottleneck functions to print into the out_buffer.
29 void Print(const char* str); 30 void Print(const char* str);
30 31
31 // Printing of common values. 32 // Printing of common values.
32 void PrintRegister(Register reg); 33 void PrintRegister(Register reg);
33 34
34 int FormatRegister(Instr* instr, const char* format); 35 int FormatRegister(Instr* instr, const char* format);
35 int FormatOption(Instr* instr, const char* format); 36 int FormatOption(Instr* instr, const char* format);
36 void Format(Instr* instr, const char* format); 37 void Format(Instr* instr, const char* format);
38 void Unknown(Instr* instr);
37 39
38 void DecodeSpecial(Instr* instr); 40 bool DecodeSpecial(Instr* instr);
39 void DecodeSpecial2(Instr* instr); 41 bool DecodeSpecial2(Instr* instr);
40 void DecodeSpecial3(Instr* instr);
41 42
42 // Convenience functions. 43 // Convenience functions.
43 char* get_buffer() const { return buffer_; } 44 char* get_buffer() const { return buffer_; }
44 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } 45 char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
45 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } 46 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
46 47
47 char* buffer_; // Decode instructions into this buffer. 48 char* buffer_; // Decode instructions into this buffer.
48 size_t buffer_size_; // The size of the character buffer. 49 size_t buffer_size_; // The size of the character buffer.
49 size_t buffer_pos_; // Current character position in buffer. 50 size_t buffer_pos_; // Current character position in buffer.
50 51
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 108 }
108 109
109 110
110 // FormatOption takes a formatting string and interprets it based on 111 // FormatOption takes a formatting string and interprets it based on
111 // the current instructions. The format string points to the first 112 // the current instructions. The format string points to the first
112 // character of the option string (the option escape has already been 113 // character of the option string (the option escape has already been
113 // consumed by the caller.) FormatOption returns the number of 114 // consumed by the caller.) FormatOption returns the number of
114 // characters that were consumed from the formatting string. 115 // characters that were consumed from the formatting string.
115 int MIPSDecoder::FormatOption(Instr* instr, const char* format) { 116 int MIPSDecoder::FormatOption(Instr* instr, const char* format) {
116 switch (format[0]) { 117 switch (format[0]) {
118 case 'c': {
119 ASSERT(STRING_STARTS_WITH(format, "code"));
120 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
121 remaining_size_in_buffer(),
122 "%d", instr->BreakCodeField());
123 return 4;
124 }
117 case 'h': { 125 case 'h': {
118 ASSERT(STRING_STARTS_WITH(format, "hint")); 126 ASSERT(STRING_STARTS_WITH(format, "hint"));
119 if (instr->SaField() != 0) { 127 if (instr->SaField() == 0x10) {
120 UNIMPLEMENTED(); 128 // The high bit of the SA field is the only one that means something for
129 // JALR and JR. TODO(zra): Fill in the other cases for PREF if needed.
130 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
131 remaining_size_in_buffer(),
132 ".hb");
133 } else if (instr->SaField() != 0) {
134 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
135 remaining_size_in_buffer(),
136 ".unknown");
121 } 137 }
122 return 4; 138 return 4;
123 } 139 }
124 case 'i': { 140 case 'i': {
125 ASSERT(STRING_STARTS_WITH(format, "imm")); 141 ASSERT(STRING_STARTS_WITH(format, "imm"));
126 if (format[3] == 'u') { 142 if (format[3] == 'u') {
127 int32_t imm = instr->UImmField(); 143 int32_t imm = instr->UImmField();
128 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 144 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
129 remaining_size_in_buffer(), 145 remaining_size_in_buffer(),
130 "0x%x", 146 "0x%x",
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 format += FormatOption(instr, format); 185 format += FormatOption(instr, format);
170 } else { 186 } else {
171 buffer_[buffer_pos_++] = cur; 187 buffer_[buffer_pos_++] = cur;
172 } 188 }
173 cur = *format++; 189 cur = *format++;
174 } 190 }
175 buffer_[buffer_pos_] = '\0'; 191 buffer_[buffer_pos_] = '\0';
176 } 192 }
177 193
178 194
179 void MIPSDecoder::DecodeSpecial(Instr* instr) { 195 // For currently unimplemented decodings the disassembler calls Unknown(instr)
196 // which will just print "unknown" of the instruction bits.
197 void MIPSDecoder::Unknown(Instr* instr) {
198 Format(instr, "unknown");
199 }
200
201
202 bool MIPSDecoder::DecodeSpecial(Instr* instr) {
203 bool decoded = true;
204
180 ASSERT(instr->OpcodeField() == SPECIAL); 205 ASSERT(instr->OpcodeField() == SPECIAL);
181 switch (instr->FunctionField()) { 206 switch (instr->FunctionField()) {
182 case ADDU: { 207 case ADDU: {
183 Format(instr, "addu 'rd, 'rs, 'rt"); 208 Format(instr, "addu 'rd, 'rs, 'rt");
184 break; 209 break;
185 } 210 }
186 case AND: { 211 case AND: {
187 Format(instr, "and 'rd, 'rs, 'rt"); 212 Format(instr, "and 'rd, 'rs, 'rt");
188 break; 213 break;
189 } 214 }
215 case BREAK: {
216 Format(instr, "break 'code");
217 break;
218 }
190 case DIV: { 219 case DIV: {
191 Format(instr, "div 'rs, 'rt"); 220 Format(instr, "div 'rs, 'rt");
192 break; 221 break;
193 } 222 }
194 case DIVU: { 223 case DIVU: {
195 Format(instr, "divu 'rs, 'rt"); 224 Format(instr, "divu 'rs, 'rt");
196 break; 225 break;
197 } 226 }
198 case MFHI: { 227 case MFHI: {
199 Format(instr, "mfhi 'rd"); 228 Format(instr, "mfhi 'rd");
200 break; 229 break;
201 } 230 }
202 case MFLO: { 231 case MFLO: {
203 Format(instr, "mflo 'rd"); 232 Format(instr, "mflo 'rd");
204 break; 233 break;
205 } 234 }
206 case SLL: { 235 case SLL: {
207 if ((instr->RdField() == R0) && 236 if ((instr->RdField() == R0) &&
208 (instr->RtField() == R0) && 237 (instr->RtField() == R0) &&
209 (instr->SaField() == 0)) { 238 (instr->SaField() == 0)) {
210 Format(instr, "nop"); 239 Format(instr, "nop");
211 } else { 240 } else {
212 Format(instr, "sll 'rd, 'rt, 'sa"); 241 Format(instr, "sll 'rd, 'rt, 'sa");
213 } 242 }
214 break; 243 break;
215 } 244 }
216 case JR: { 245 case JR: {
217 ASSERT(instr->RtField() == R0);
218 ASSERT(instr->RdField() == R0);
219 Format(instr, "jr'hint 'rs"); 246 Format(instr, "jr'hint 'rs");
220 break; 247 break;
221 } 248 }
222 default: { 249 default: {
223 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits()); 250 Unknown(instr);
224 UNREACHABLE(); 251 decoded = false;
225 break; 252 break;
226 } 253 }
227 } 254 }
255
256 return decoded;
228 } 257 }
229 258
230 259
231 void MIPSDecoder::DecodeSpecial2(Instr* instr) { 260 bool MIPSDecoder::DecodeSpecial2(Instr* instr) {
261 bool decoded = true;
262
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(); 275 decoded = false;
245 break; 276 break;
246 } 277 }
247 } 278 }
279
280 return decoded;
248 } 281 }
249 282
250 283
251 void MIPSDecoder::DecodeSpecial3(Instr* instr) { 284 bool MIPSDecoder::InstructionDecode(Instr* instr) {
252 ASSERT(instr->OpcodeField() == SPECIAL3); 285 bool decoded = true;
253 switch (instr->FunctionField()) {
254 default: {
255 OS::PrintErr("DecodeSpecial3: 0x%x\n", instr->InstructionBits());
256 UNREACHABLE();
257 break;
258 }
259 }
260 }
261 286
262
263 void MIPSDecoder::InstructionDecode(Instr* instr) {
264 switch (instr->OpcodeField()) { 287 switch (instr->OpcodeField()) {
265 case SPECIAL: { 288 case SPECIAL: {
266 DecodeSpecial(instr); 289 decoded = DecodeSpecial(instr);
267 break; 290 break;
268 } 291 }
269 case SPECIAL2: { 292 case SPECIAL2: {
270 DecodeSpecial2(instr); 293 decoded = DecodeSpecial2(instr);
271 break;
272 }
273 case SPECIAL3: {
274 DecodeSpecial3(instr);
275 break; 294 break;
276 } 295 }
277 case ADDIU: { 296 case ADDIU: {
278 Format(instr, "addiu 'rt, 'rs, 'imms"); 297 Format(instr, "addiu 'rt, 'rs, 'imms");
279 break; 298 break;
280 } 299 }
281 case ANDI: { 300 case ANDI: {
282 Format(instr, "andi 'rt, 'rs, 'immu"); 301 Format(instr, "andi 'rt, 'rs, 'immu");
283 break; 302 break;
284 } 303 }
(...skipping 27 matching lines...) Expand all
312 } 331 }
313 case SH: { 332 case SH: {
314 Format(instr, "sh 'rt, 'imms('rs)"); 333 Format(instr, "sh 'rt, 'imms('rs)");
315 break; 334 break;
316 } 335 }
317 case SW: { 336 case SW: {
318 Format(instr, "sw 'rt, 'imms('rs)"); 337 Format(instr, "sw 'rt, 'imms('rs)");
319 break; 338 break;
320 } 339 }
321 default: { 340 default: {
322 OS::PrintErr("Undecoded instruction: 0x%x\n", instr->InstructionBits()); 341 Unknown(instr);
323 UNREACHABLE(); 342 decoded = false;
324 break; 343 break;
325 } 344 }
326 } 345 }
346
347 return decoded;
327 } 348 }
328 349
329 350
330 int Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, 351 int Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
331 char* human_buffer, intptr_t human_size, 352 char* human_buffer, intptr_t human_size,
332 uword pc) { 353 uword pc) {
333 MIPSDecoder decoder(human_buffer, human_size); 354 MIPSDecoder decoder(human_buffer, human_size);
334 Instr* instr = Instr::At(pc); 355 Instr* instr = Instr::At(pc);
335 decoder.InstructionDecode(instr); 356 if (decoder.InstructionDecode(instr)) {
336 OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits()); 357 OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits());
337 return Instr::kInstrSize; 358 return Instr::kInstrSize;
359 } else {
360 return -Instr::kInstrSize;
361 }
338 } 362 }
339 363
340 364
341 void Disassembler::Disassemble(uword start, 365 bool Disassembler::Disassemble(uword start,
342 uword end, 366 uword end,
343 DisassemblyFormatter* formatter, 367 DisassemblyFormatter* formatter,
344 const Code::Comments& comments) { 368 const Code::Comments& comments) {
345 ASSERT(formatter != NULL); 369 ASSERT(formatter != NULL);
370 bool success = true;
346 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form. 371 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form.
347 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction. 372 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction.
348 uword pc = start; 373 uword pc = start;
349 intptr_t comment_finger = 0; 374 intptr_t comment_finger = 0;
350 while (pc < end) { 375 while (pc < end) {
351 const intptr_t offset = pc - start; 376 const intptr_t offset = pc - start;
352 while (comment_finger < comments.Length() && 377 while (comment_finger < comments.Length() &&
353 comments.PCOffsetAt(comment_finger) <= offset) { 378 comments.PCOffsetAt(comment_finger) <= offset) {
354 formatter->Print( 379 formatter->Print(
355 " ;; %s\n", 380 " ;; %s\n",
356 String::Handle(comments.CommentAt(comment_finger)).ToCString()); 381 String::Handle(comments.CommentAt(comment_finger)).ToCString());
357 comment_finger++; 382 comment_finger++;
358 } 383 }
359 int instruction_length = DecodeInstruction(hex_buffer, 384 int instruction_length = DecodeInstruction(hex_buffer,
360 sizeof(hex_buffer), 385 sizeof(hex_buffer),
361 human_buffer, 386 human_buffer,
362 sizeof(human_buffer), 387 sizeof(human_buffer),
363 pc); 388 pc);
364 formatter->ConsumeInstruction(hex_buffer, 389 if (instruction_length > 0) {
365 sizeof(hex_buffer), 390 formatter->ConsumeInstruction(hex_buffer,
366 human_buffer, 391 sizeof(hex_buffer),
367 sizeof(human_buffer), 392 human_buffer,
368 pc); 393 sizeof(human_buffer),
369 pc += instruction_length; 394 pc);
395 pc += instruction_length;
396 } else {
397 ASSERT(instruction_length < 0);
398 success = false;
399 pc += (-instruction_length);
400 }
370 } 401 }
402
403 return success;
371 } 404 }
372 405
373 } // namespace dart 406 } // namespace dart
374 407
375 #endif // defined TARGET_ARCH_MIPS 408 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698