OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 14 matching lines...) Expand all Loading... |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 // A Disassembler object is used to disassemble a block of code instruction by | 28 // A Disassembler object is used to disassemble a block of code instruction by |
29 // instruction. The default implementation of the NameConverter object can be | 29 // instruction. The default implementation of the NameConverter object can be |
30 // overriden to modify register names or to do symbol lookup on addresses. | 30 // overriden to modify register names or to do symbol lookup on addresses. |
31 // | 31 // |
32 // The example below will disassemble a block of code and print it to stdout. | 32 // The example below will disassemble a block of code and print it to stdout. |
33 // | 33 // |
34 // NameConverter converter; | 34 // NameConverter converter; |
35 // Disassembler d(converter); | 35 // Disassembler d(converter); |
36 // for (byte_* pc = begin; pc < end;) { | 36 // for (byte* pc = begin; pc < end;) { |
37 // v8::internal::EmbeddedVector<char, 256> buffer; | 37 // v8::internal::EmbeddedVector<char, 256> buffer; |
38 // byte* prev_pc = pc; | 38 // byte* prev_pc = pc; |
39 // pc += d.InstructionDecode(buffer, pc); | 39 // pc += d.InstructionDecode(buffer, pc); |
40 // printf("%p %08x %s\n", | 40 // printf("%p %08x %s\n", |
41 // prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer); | 41 // prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer); |
42 // } | 42 // } |
43 // | 43 // |
44 // The Disassembler class also has a convenience method to disassemble a block | 44 // The Disassembler class also has a convenience method to disassemble a block |
45 // of code into a FILE*, meaning that the above functionality could also be | 45 // of code into a FILE*, meaning that the above functionality could also be |
46 // achieved by just calling Disassembler::Disassemble(stdout, begin, end); | 46 // achieved by just calling Disassembler::Disassemble(stdout, begin, end); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 : converter_(converter), | 78 : converter_(converter), |
79 out_buffer_(out_buffer), | 79 out_buffer_(out_buffer), |
80 out_buffer_pos_(0) { | 80 out_buffer_pos_(0) { |
81 out_buffer_[out_buffer_pos_] = '\0'; | 81 out_buffer_[out_buffer_pos_] = '\0'; |
82 } | 82 } |
83 | 83 |
84 ~Decoder() {} | 84 ~Decoder() {} |
85 | 85 |
86 // Writes one disassembled instruction into 'buffer' (0-terminated). | 86 // Writes one disassembled instruction into 'buffer' (0-terminated). |
87 // Returns the length of the disassembled machine instruction in bytes. | 87 // Returns the length of the disassembled machine instruction in bytes. |
88 int InstructionDecode(byte_* instruction); | 88 int InstructionDecode(byte* instruction); |
89 | 89 |
90 private: | 90 private: |
91 // Bottleneck functions to print into the out_buffer. | 91 // Bottleneck functions to print into the out_buffer. |
92 void PrintChar(const char ch); | 92 void PrintChar(const char ch); |
93 void Print(const char* str); | 93 void Print(const char* str); |
94 | 94 |
95 // Printing of common values. | 95 // Printing of common values. |
96 void PrintRegister(int reg); | 96 void PrintRegister(int reg); |
97 void PrintFPURegister(int freg); | 97 void PrintFPURegister(int freg); |
98 void PrintRs(Instruction* instr); | 98 void PrintRs(Instruction* instr); |
99 void PrintRt(Instruction* instr); | 99 void PrintRt(Instruction* instr); |
100 void PrintRd(Instruction* instr); | 100 void PrintRd(Instruction* instr); |
101 void PrintFs(Instruction* instr); | 101 void PrintFs(Instruction* instr); |
102 void PrintFt(Instruction* instr); | 102 void PrintFt(Instruction* instr); |
103 void PrintFd(Instruction* instr); | 103 void PrintFd(Instruction* instr); |
104 void PrintSa(Instruction* instr); | 104 void PrintSa(Instruction* instr); |
105 void PrintSd(Instruction* instr); | 105 void PrintSd(Instruction* instr); |
| 106 void PrintSs1(Instruction* instr); |
| 107 void PrintSs2(Instruction* instr); |
106 void PrintBc(Instruction* instr); | 108 void PrintBc(Instruction* instr); |
107 void PrintCc(Instruction* instr); | 109 void PrintCc(Instruction* instr); |
108 void PrintFunction(Instruction* instr); | 110 void PrintFunction(Instruction* instr); |
109 void PrintSecondaryField(Instruction* instr); | 111 void PrintSecondaryField(Instruction* instr); |
110 void PrintUImm16(Instruction* instr); | 112 void PrintUImm16(Instruction* instr); |
111 void PrintSImm16(Instruction* instr); | 113 void PrintSImm16(Instruction* instr); |
112 void PrintXImm16(Instruction* instr); | 114 void PrintXImm16(Instruction* instr); |
113 void PrintImm26(Instruction* instr); | 115 void PrintImm26(Instruction* instr); |
114 void PrintCode(Instruction* instr); // For break and trap instructions. | 116 void PrintCode(Instruction* instr); // For break and trap instructions. |
115 // Printing of instruction name. | 117 // Printing of instruction name. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 } | 207 } |
206 | 208 |
207 | 209 |
208 // Print the integer value of the sa field. | 210 // Print the integer value of the sa field. |
209 void Decoder::PrintSa(Instruction* instr) { | 211 void Decoder::PrintSa(Instruction* instr) { |
210 int sa = instr->SaValue(); | 212 int sa = instr->SaValue(); |
211 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); | 213 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); |
212 } | 214 } |
213 | 215 |
214 | 216 |
215 // Print the integer value of the rd field, (when it is not used as reg). | 217 // Print the integer value of the rd field, when it is not used as reg. |
216 void Decoder::PrintSd(Instruction* instr) { | 218 void Decoder::PrintSd(Instruction* instr) { |
217 int sd = instr->RdValue(); | 219 int sd = instr->RdValue(); |
218 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd); | 220 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd); |
219 } | 221 } |
220 | 222 |
221 | 223 |
| 224 // Print the integer value of the rd field, when used as 'ext' size. |
| 225 void Decoder::PrintSs1(Instruction* instr) { |
| 226 int ss = instr->RdValue(); |
| 227 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1); |
| 228 } |
| 229 |
| 230 |
| 231 // Print the integer value of the rd field, when used as 'ins' size. |
| 232 void Decoder::PrintSs2(Instruction* instr) { |
| 233 int ss = instr->RdValue(); |
| 234 int pos = instr->SaValue(); |
| 235 out_buffer_pos_ += |
| 236 OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1); |
| 237 } |
| 238 |
| 239 |
222 // Print the integer value of the cc field for the bc1t/f instructions. | 240 // Print the integer value of the cc field for the bc1t/f instructions. |
223 void Decoder::PrintBc(Instruction* instr) { | 241 void Decoder::PrintBc(Instruction* instr) { |
224 int cc = instr->FBccValue(); | 242 int cc = instr->FBccValue(); |
225 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc); | 243 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc); |
226 } | 244 } |
227 | 245 |
228 | 246 |
229 // Print the integer value of the cc field for the FP compare instructions. | 247 // Print the integer value of the cc field for the FP compare instructions. |
230 void Decoder::PrintCc(Instruction* instr) { | 248 void Decoder::PrintCc(Instruction* instr) { |
231 int cc = instr->FCccValue(); | 249 int cc = instr->FCccValue(); |
232 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc); | 250 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc); |
233 } | 251 } |
234 | 252 |
235 | 253 |
236 // Print 16-bit unsigned immediate value. | 254 // Print 16-bit unsigned immediate value. |
237 void Decoder::PrintUImm16(Instruction* instr) { | 255 void Decoder::PrintUImm16(Instruction* instr) { |
238 int32_t imm = instr->Imm16Value(); | 256 int32_t imm = instr->Imm16Value(); |
239 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); | 257 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); |
240 } | 258 } |
241 | 259 |
242 | 260 |
243 // Print 16-bit signed immediate value. | 261 // Print 16-bit signed immediate value. |
244 void Decoder::PrintSImm16(Instruction* instr) { | 262 void Decoder::PrintSImm16(Instruction* instr) { |
245 int32_t imm = ((instr->Imm16Value())<<16)>>16; | 263 int32_t imm = ((instr->Imm16Value()) << 16) >> 16; |
246 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); | 264 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
247 } | 265 } |
248 | 266 |
249 | 267 |
250 // Print 16-bit hexa immediate value. | 268 // Print 16-bit hexa immediate value. |
251 void Decoder::PrintXImm16(Instruction* instr) { | 269 void Decoder::PrintXImm16(Instruction* instr) { |
252 int32_t imm = instr->Imm16Value(); | 270 int32_t imm = instr->Imm16Value(); |
253 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 271 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
254 } | 272 } |
255 | 273 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 | 309 |
292 // Printing of instruction name. | 310 // Printing of instruction name. |
293 void Decoder::PrintInstructionName(Instruction* instr) { | 311 void Decoder::PrintInstructionName(Instruction* instr) { |
294 } | 312 } |
295 | 313 |
296 | 314 |
297 // Handle all register based formatting in this function to reduce the | 315 // Handle all register based formatting in this function to reduce the |
298 // complexity of FormatOption. | 316 // complexity of FormatOption. |
299 int Decoder::FormatRegister(Instruction* instr, const char* format) { | 317 int Decoder::FormatRegister(Instruction* instr, const char* format) { |
300 ASSERT(format[0] == 'r'); | 318 ASSERT(format[0] == 'r'); |
301 if (format[1] == 's') { // 'rs: Rs register | 319 if (format[1] == 's') { // 'rs: Rs register. |
302 int reg = instr->RsValue(); | 320 int reg = instr->RsValue(); |
303 PrintRegister(reg); | 321 PrintRegister(reg); |
304 return 2; | 322 return 2; |
305 } else if (format[1] == 't') { // 'rt: rt register | 323 } else if (format[1] == 't') { // 'rt: rt register. |
306 int reg = instr->RtValue(); | 324 int reg = instr->RtValue(); |
307 PrintRegister(reg); | 325 PrintRegister(reg); |
308 return 2; | 326 return 2; |
309 } else if (format[1] == 'd') { // 'rd: rd register | 327 } else if (format[1] == 'd') { // 'rd: rd register. |
310 int reg = instr->RdValue(); | 328 int reg = instr->RdValue(); |
311 PrintRegister(reg); | 329 PrintRegister(reg); |
312 return 2; | 330 return 2; |
313 } | 331 } |
314 UNREACHABLE(); | 332 UNREACHABLE(); |
315 return -1; | 333 return -1; |
316 } | 334 } |
317 | 335 |
318 | 336 |
319 // Handle all FPUregister based formatting in this function to reduce the | 337 // Handle all FPUregister based formatting in this function to reduce the |
320 // complexity of FormatOption. | 338 // complexity of FormatOption. |
321 int Decoder::FormatFPURegister(Instruction* instr, const char* format) { | 339 int Decoder::FormatFPURegister(Instruction* instr, const char* format) { |
322 ASSERT(format[0] == 'f'); | 340 ASSERT(format[0] == 'f'); |
323 if (format[1] == 's') { // 'fs: fs register | 341 if (format[1] == 's') { // 'fs: fs register. |
324 int reg = instr->FsValue(); | 342 int reg = instr->FsValue(); |
325 PrintFPURegister(reg); | 343 PrintFPURegister(reg); |
326 return 2; | 344 return 2; |
327 } else if (format[1] == 't') { // 'ft: ft register | 345 } else if (format[1] == 't') { // 'ft: ft register. |
328 int reg = instr->FtValue(); | 346 int reg = instr->FtValue(); |
329 PrintFPURegister(reg); | 347 PrintFPURegister(reg); |
330 return 2; | 348 return 2; |
331 } else if (format[1] == 'd') { // 'fd: fd register | 349 } else if (format[1] == 'd') { // 'fd: fd register. |
332 int reg = instr->FdValue(); | 350 int reg = instr->FdValue(); |
333 PrintFPURegister(reg); | 351 PrintFPURegister(reg); |
334 return 2; | 352 return 2; |
335 } | 353 } |
336 UNREACHABLE(); | 354 UNREACHABLE(); |
337 return -1; | 355 return -1; |
338 } | 356 } |
339 | 357 |
340 | 358 |
341 // FormatOption takes a formatting string and interprets it based on | 359 // FormatOption takes a formatting string and interprets it based on |
342 // the current instructions. The format string points to the first | 360 // the current instructions. The format string points to the first |
343 // character of the option string (the option escape has already been | 361 // character of the option string (the option escape has already been |
344 // consumed by the caller.) FormatOption returns the number of | 362 // consumed by the caller.) FormatOption returns the number of |
345 // characters that were consumed from the formatting string. | 363 // characters that were consumed from the formatting string. |
346 int Decoder::FormatOption(Instruction* instr, const char* format) { | 364 int Decoder::FormatOption(Instruction* instr, const char* format) { |
347 switch (format[0]) { | 365 switch (format[0]) { |
348 case 'c': { // 'code for break or trap instructions | 366 case 'c': { // 'code for break or trap instructions. |
349 ASSERT(STRING_STARTS_WITH(format, "code")); | 367 ASSERT(STRING_STARTS_WITH(format, "code")); |
350 PrintCode(instr); | 368 PrintCode(instr); |
351 return 4; | 369 return 4; |
352 } | 370 } |
353 case 'i': { // 'imm16u or 'imm26 | 371 case 'i': { // 'imm16u or 'imm26. |
354 if (format[3] == '1') { | 372 if (format[3] == '1') { |
355 ASSERT(STRING_STARTS_WITH(format, "imm16")); | 373 ASSERT(STRING_STARTS_WITH(format, "imm16")); |
356 if (format[5] == 's') { | 374 if (format[5] == 's') { |
357 ASSERT(STRING_STARTS_WITH(format, "imm16s")); | 375 ASSERT(STRING_STARTS_WITH(format, "imm16s")); |
358 PrintSImm16(instr); | 376 PrintSImm16(instr); |
359 } else if (format[5] == 'u') { | 377 } else if (format[5] == 'u') { |
360 ASSERT(STRING_STARTS_WITH(format, "imm16u")); | 378 ASSERT(STRING_STARTS_WITH(format, "imm16u")); |
361 PrintSImm16(instr); | 379 PrintSImm16(instr); |
362 } else { | 380 } else { |
363 ASSERT(STRING_STARTS_WITH(format, "imm16x")); | 381 ASSERT(STRING_STARTS_WITH(format, "imm16x")); |
364 PrintXImm16(instr); | 382 PrintXImm16(instr); |
365 } | 383 } |
366 return 6; | 384 return 6; |
367 } else { | 385 } else { |
368 ASSERT(STRING_STARTS_WITH(format, "imm26")); | 386 ASSERT(STRING_STARTS_WITH(format, "imm26")); |
369 PrintImm26(instr); | 387 PrintImm26(instr); |
370 return 5; | 388 return 5; |
371 } | 389 } |
372 } | 390 } |
373 case 'r': { // 'r: registers | 391 case 'r': { // 'r: registers. |
374 return FormatRegister(instr, format); | 392 return FormatRegister(instr, format); |
375 } | 393 } |
376 case 'f': { // 'f: FPUregisters | 394 case 'f': { // 'f: FPUregisters. |
377 return FormatFPURegister(instr, format); | 395 return FormatFPURegister(instr, format); |
378 } | 396 } |
379 case 's': { // 'sa | 397 case 's': { // 'sa. |
380 switch (format[1]) { | 398 switch (format[1]) { |
381 case 'a': { | 399 case 'a': { |
382 ASSERT(STRING_STARTS_WITH(format, "sa")); | 400 ASSERT(STRING_STARTS_WITH(format, "sa")); |
383 PrintSa(instr); | 401 PrintSa(instr); |
384 return 2; | 402 return 2; |
385 } | 403 } |
386 case 'd': { | 404 case 'd': { |
387 ASSERT(STRING_STARTS_WITH(format, "sd")); | 405 ASSERT(STRING_STARTS_WITH(format, "sd")); |
388 PrintSd(instr); | 406 PrintSd(instr); |
389 return 2; | 407 return 2; |
390 } | 408 } |
| 409 case 's': { |
| 410 if (format[2] == '1') { |
| 411 ASSERT(STRING_STARTS_WITH(format, "ss1")); /* ext size */ |
| 412 PrintSs1(instr); |
| 413 return 3; |
| 414 } else { |
| 415 ASSERT(STRING_STARTS_WITH(format, "ss2")); /* ins size */ |
| 416 PrintSs2(instr); |
| 417 return 3; |
| 418 } |
| 419 } |
391 } | 420 } |
392 } | 421 } |
393 case 'b': { // 'bc - Special for bc1 cc field. | 422 case 'b': { // 'bc - Special for bc1 cc field. |
394 ASSERT(STRING_STARTS_WITH(format, "bc")); | 423 ASSERT(STRING_STARTS_WITH(format, "bc")); |
395 PrintBc(instr); | 424 PrintBc(instr); |
396 return 2; | 425 return 2; |
397 } | 426 } |
398 case 'C': { // 'Cc - Special for c.xx.d cc field. | 427 case 'C': { // 'Cc - Special for c.xx.d cc field. |
399 ASSERT(STRING_STARTS_WITH(format, "Cc")); | 428 ASSERT(STRING_STARTS_WITH(format, "Cc")); |
400 PrintCc(instr); | 429 PrintCc(instr); |
(...skipping 24 matching lines...) Expand all Loading... |
425 | 454 |
426 // For currently unimplemented decodings the disassembler calls Unknown(instr) | 455 // For currently unimplemented decodings the disassembler calls Unknown(instr) |
427 // which will just print "unknown" of the instruction bits. | 456 // which will just print "unknown" of the instruction bits. |
428 void Decoder::Unknown(Instruction* instr) { | 457 void Decoder::Unknown(Instruction* instr) { |
429 Format(instr, "unknown"); | 458 Format(instr, "unknown"); |
430 } | 459 } |
431 | 460 |
432 | 461 |
433 void Decoder::DecodeTypeRegister(Instruction* instr) { | 462 void Decoder::DecodeTypeRegister(Instruction* instr) { |
434 switch (instr->OpcodeFieldRaw()) { | 463 switch (instr->OpcodeFieldRaw()) { |
435 case COP1: // Coprocessor instructions | 464 case COP1: // Coprocessor instructions. |
436 switch (instr->RsFieldRaw()) { | 465 switch (instr->RsFieldRaw()) { |
437 case BC1: // bc1 handled in DecodeTypeImmediate. | 466 case BC1: // bc1 handled in DecodeTypeImmediate. |
438 UNREACHABLE(); | 467 UNREACHABLE(); |
439 break; | 468 break; |
440 case MFC1: | 469 case MFC1: |
441 Format(instr, "mfc1 'rt, 'fs"); | 470 Format(instr, "mfc1 'rt, 'fs"); |
442 break; | 471 break; |
443 case MFHC1: | 472 case MFHC1: |
444 Format(instr, "mfhc1 'rt, 'fs"); | 473 Format(instr, "mfhc1 'rt, 'fs"); |
445 break; | 474 break; |
446 case MTC1: | 475 case MTC1: |
447 Format(instr, "mtc1 'rt, 'fs"); | 476 Format(instr, "mtc1 'rt, 'fs"); |
448 break; | 477 break; |
449 // These are called "fs" too, although they are not FPU registers. | 478 // These are called "fs" too, although they are not FPU registers. |
450 case CTC1: | 479 case CTC1: |
451 Format(instr, "ctc1 'rt, 'fs"); | 480 Format(instr, "ctc1 'rt, 'fs"); |
452 break; | 481 break; |
453 case CFC1: | 482 case CFC1: |
454 Format(instr, "cfc1 'rt, 'fs"); | 483 Format(instr, "cfc1 'rt, 'fs"); |
455 break; | 484 break; |
456 case MTHC1: | 485 case MTHC1: |
457 Format(instr, "mthc1 'rt, 'fs"); | 486 Format(instr, "mthc1 'rt, 'fs"); |
458 break; | 487 break; |
459 case D: | 488 case D: |
460 switch (instr->FunctionFieldRaw()) { | 489 switch (instr->FunctionFieldRaw()) { |
461 case ADD_D: | 490 case ADD_D: |
462 Format(instr, "add.d 'fd, 'fs, 'ft"); | 491 Format(instr, "add.d 'fd, 'fs, 'ft"); |
463 break; | 492 break; |
464 case SUB_D: | 493 case SUB_D: |
465 Format(instr, "sub.d 'fd, 'fs, 'ft"); | 494 Format(instr, "sub.d 'fd, 'fs, 'ft"); |
466 break; | 495 break; |
467 case MUL_D: | 496 case MUL_D: |
468 Format(instr, "mul.d 'fd, 'fs, 'ft"); | 497 Format(instr, "mul.d 'fd, 'fs, 'ft"); |
469 break; | 498 break; |
470 case DIV_D: | 499 case DIV_D: |
471 Format(instr, "div.d 'fd, 'fs, 'ft"); | 500 Format(instr, "div.d 'fd, 'fs, 'ft"); |
472 break; | 501 break; |
473 case ABS_D: | 502 case ABS_D: |
474 Format(instr, "abs.d 'fd, 'fs"); | 503 Format(instr, "abs.d 'fd, 'fs"); |
475 break; | 504 break; |
476 case MOV_D: | 505 case MOV_D: |
477 Format(instr, "mov.d 'fd, 'fs"); | 506 Format(instr, "mov.d 'fd, 'fs"); |
478 break; | 507 break; |
479 case NEG_D: | 508 case NEG_D: |
480 Format(instr, "neg.d 'fd, 'fs"); | 509 Format(instr, "neg.d 'fd, 'fs"); |
481 break; | 510 break; |
482 case SQRT_D: | 511 case SQRT_D: |
483 Format(instr, "sqrt.d 'fd, 'fs"); | 512 Format(instr, "sqrt.d 'fd, 'fs"); |
484 break; | 513 break; |
485 case CVT_W_D: | 514 case CVT_W_D: |
486 Format(instr, "cvt.w.d 'fd, 'fs"); | 515 Format(instr, "cvt.w.d 'fd, 'fs"); |
487 break; | 516 break; |
488 case CVT_L_D: { | 517 case CVT_L_D: { |
489 if (mips32r2) { | 518 if (mips32r2) { |
490 Format(instr, "cvt.l.d 'fd, 'fs"); | 519 Format(instr, "cvt.l.d 'fd, 'fs"); |
491 } else { | 520 } else { |
492 Unknown(instr); | 521 Unknown(instr); |
493 } | 522 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 case PS: | 614 case PS: |
586 UNIMPLEMENTED_MIPS(); | 615 UNIMPLEMENTED_MIPS(); |
587 break; | 616 break; |
588 default: | 617 default: |
589 UNREACHABLE(); | 618 UNREACHABLE(); |
590 } | 619 } |
591 break; | 620 break; |
592 case SPECIAL: | 621 case SPECIAL: |
593 switch (instr->FunctionFieldRaw()) { | 622 switch (instr->FunctionFieldRaw()) { |
594 case JR: | 623 case JR: |
595 Format(instr, "jr 'rs"); | 624 Format(instr, "jr 'rs"); |
596 break; | 625 break; |
597 case JALR: | 626 case JALR: |
598 Format(instr, "jalr 'rs"); | 627 Format(instr, "jalr 'rs"); |
599 break; | 628 break; |
600 case SLL: | 629 case SLL: |
601 if ( 0x0 == static_cast<int>(instr->InstructionBits())) | 630 if ( 0x0 == static_cast<int>(instr->InstructionBits())) |
602 Format(instr, "nop"); | 631 Format(instr, "nop"); |
603 else | 632 else |
604 Format(instr, "sll 'rd, 'rt, 'sa"); | 633 Format(instr, "sll 'rd, 'rt, 'sa"); |
605 break; | 634 break; |
606 case SRL: | 635 case SRL: |
607 if (instr->RsValue() == 0) { | 636 if (instr->RsValue() == 0) { |
608 Format(instr, "srl 'rd, 'rt, 'sa"); | 637 Format(instr, "srl 'rd, 'rt, 'sa"); |
609 } else { | 638 } else { |
610 if (mips32r2) { | 639 if (mips32r2) { |
611 Format(instr, "rotr 'rd, 'rt, 'sa"); | 640 Format(instr, "rotr 'rd, 'rt, 'sa"); |
612 } else { | 641 } else { |
613 Unknown(instr); | 642 Unknown(instr); |
614 } | 643 } |
615 } | 644 } |
616 break; | 645 break; |
617 case SRA: | 646 case SRA: |
618 Format(instr, "sra 'rd, 'rt, 'sa"); | 647 Format(instr, "sra 'rd, 'rt, 'sa"); |
619 break; | 648 break; |
620 case SLLV: | 649 case SLLV: |
621 Format(instr, "sllv 'rd, 'rt, 'rs"); | 650 Format(instr, "sllv 'rd, 'rt, 'rs"); |
622 break; | 651 break; |
623 case SRLV: | 652 case SRLV: |
624 if (instr->SaValue() == 0) { | 653 if (instr->SaValue() == 0) { |
625 Format(instr, "srlv 'rd, 'rt, 'rs"); | 654 Format(instr, "srlv 'rd, 'rt, 'rs"); |
626 } else { | 655 } else { |
627 if (mips32r2) { | 656 if (mips32r2) { |
628 Format(instr, "rotrv 'rd, 'rt, 'rs"); | 657 Format(instr, "rotrv 'rd, 'rt, 'rs"); |
629 } else { | 658 } else { |
630 Unknown(instr); | 659 Unknown(instr); |
631 } | 660 } |
632 } | 661 } |
633 break; | 662 break; |
634 case SRAV: | 663 case SRAV: |
635 Format(instr, "srav 'rd, 'rt, 'rs"); | 664 Format(instr, "srav 'rd, 'rt, 'rs"); |
636 break; | 665 break; |
637 case MFHI: | 666 case MFHI: |
638 Format(instr, "mfhi 'rd"); | 667 Format(instr, "mfhi 'rd"); |
639 break; | 668 break; |
640 case MFLO: | 669 case MFLO: |
641 Format(instr, "mflo 'rd"); | 670 Format(instr, "mflo 'rd"); |
642 break; | 671 break; |
643 case MULT: | 672 case MULT: |
644 Format(instr, "mult 'rs, 'rt"); | 673 Format(instr, "mult 'rs, 'rt"); |
645 break; | 674 break; |
646 case MULTU: | 675 case MULTU: |
647 Format(instr, "multu 'rs, 'rt"); | 676 Format(instr, "multu 'rs, 'rt"); |
648 break; | 677 break; |
649 case DIV: | 678 case DIV: |
650 Format(instr, "div 'rs, 'rt"); | 679 Format(instr, "div 'rs, 'rt"); |
651 break; | 680 break; |
652 case DIVU: | 681 case DIVU: |
653 Format(instr, "divu 'rs, 'rt"); | 682 Format(instr, "divu 'rs, 'rt"); |
654 break; | 683 break; |
655 case ADD: | 684 case ADD: |
656 Format(instr, "add 'rd, 'rs, 'rt"); | 685 Format(instr, "add 'rd, 'rs, 'rt"); |
657 break; | 686 break; |
658 case ADDU: | 687 case ADDU: |
659 Format(instr, "addu 'rd, 'rs, 'rt"); | 688 Format(instr, "addu 'rd, 'rs, 'rt"); |
660 break; | 689 break; |
661 case SUB: | 690 case SUB: |
662 Format(instr, "sub 'rd, 'rs, 'rt"); | 691 Format(instr, "sub 'rd, 'rs, 'rt"); |
663 break; | 692 break; |
664 case SUBU: | 693 case SUBU: |
665 Format(instr, "sub 'rd, 'rs, 'rt"); | 694 Format(instr, "subu 'rd, 'rs, 'rt"); |
666 break; | 695 break; |
667 case AND: | 696 case AND: |
668 Format(instr, "and 'rd, 'rs, 'rt"); | 697 Format(instr, "and 'rd, 'rs, 'rt"); |
669 break; | 698 break; |
670 case OR: | 699 case OR: |
671 if (0 == instr->RsValue()) { | 700 if (0 == instr->RsValue()) { |
672 Format(instr, "mov 'rd, 'rt"); | 701 Format(instr, "mov 'rd, 'rt"); |
673 } else if (0 == instr->RtValue()) { | 702 } else if (0 == instr->RtValue()) { |
674 Format(instr, "mov 'rd, 'rs"); | 703 Format(instr, "mov 'rd, 'rs"); |
675 } else { | 704 } else { |
676 Format(instr, "or 'rd, 'rs, 'rt"); | 705 Format(instr, "or 'rd, 'rs, 'rt"); |
677 } | 706 } |
678 break; | 707 break; |
679 case XOR: | 708 case XOR: |
680 Format(instr, "xor 'rd, 'rs, 'rt"); | 709 Format(instr, "xor 'rd, 'rs, 'rt"); |
681 break; | 710 break; |
682 case NOR: | 711 case NOR: |
683 Format(instr, "nor 'rd, 'rs, 'rt"); | 712 Format(instr, "nor 'rd, 'rs, 'rt"); |
684 break; | 713 break; |
685 case SLT: | 714 case SLT: |
686 Format(instr, "slt 'rd, 'rs, 'rt"); | 715 Format(instr, "slt 'rd, 'rs, 'rt"); |
687 break; | 716 break; |
688 case SLTU: | 717 case SLTU: |
689 Format(instr, "sltu 'rd, 'rs, 'rt"); | 718 Format(instr, "sltu 'rd, 'rs, 'rt"); |
690 break; | 719 break; |
691 case BREAK: | 720 case BREAK: |
692 Format(instr, "break, code: 'code"); | 721 Format(instr, "break, code: 'code"); |
693 break; | 722 break; |
694 case TGE: | 723 case TGE: |
695 Format(instr, "tge 'rs, 'rt, code: 'code"); | 724 Format(instr, "tge 'rs, 'rt, code: 'code"); |
696 break; | 725 break; |
697 case TGEU: | 726 case TGEU: |
698 Format(instr, "tgeu 'rs, 'rt, code: 'code"); | 727 Format(instr, "tgeu 'rs, 'rt, code: 'code"); |
699 break; | 728 break; |
700 case TLT: | 729 case TLT: |
701 Format(instr, "tlt 'rs, 'rt, code: 'code"); | 730 Format(instr, "tlt 'rs, 'rt, code: 'code"); |
702 break; | 731 break; |
703 case TLTU: | 732 case TLTU: |
704 Format(instr, "tltu 'rs, 'rt, code: 'code"); | 733 Format(instr, "tltu 'rs, 'rt, code: 'code"); |
705 break; | 734 break; |
706 case TEQ: | 735 case TEQ: |
707 Format(instr, "teq 'rs, 'rt, code: 'code"); | 736 Format(instr, "teq 'rs, 'rt, code: 'code"); |
708 break; | 737 break; |
709 case TNE: | 738 case TNE: |
710 Format(instr, "tne 'rs, 'rt, code: 'code"); | 739 Format(instr, "tne 'rs, 'rt, code: 'code"); |
711 break; | 740 break; |
712 case MOVZ: | 741 case MOVZ: |
713 Format(instr, "movz 'rd, 'rs, 'rt"); | 742 Format(instr, "movz 'rd, 'rs, 'rt"); |
714 break; | 743 break; |
715 case MOVN: | 744 case MOVN: |
716 Format(instr, "movn 'rd, 'rs, 'rt"); | 745 Format(instr, "movn 'rd, 'rs, 'rt"); |
717 break; | 746 break; |
718 case MOVCI: | 747 case MOVCI: |
719 if (instr->Bit(16)) { | 748 if (instr->Bit(16)) { |
720 Format(instr, "movt 'rd, 'rs, 'Cc"); | 749 Format(instr, "movt 'rd, 'rs, 'bc"); |
721 } else { | 750 } else { |
722 Format(instr, "movf 'rd, 'rs, 'Cc"); | 751 Format(instr, "movf 'rd, 'rs, 'bc"); |
723 } | 752 } |
724 break; | 753 break; |
725 default: | 754 default: |
726 UNREACHABLE(); | 755 UNREACHABLE(); |
727 } | 756 } |
728 break; | 757 break; |
729 case SPECIAL2: | 758 case SPECIAL2: |
730 switch (instr->FunctionFieldRaw()) { | 759 switch (instr->FunctionFieldRaw()) { |
731 case MUL: | 760 case MUL: |
732 Format(instr, "mul 'rd, 'rs, 'rt"); | 761 Format(instr, "mul 'rd, 'rs, 'rt"); |
733 break; | 762 break; |
734 case CLZ: | 763 case CLZ: |
735 Format(instr, "clz 'rd, 'rs"); | 764 Format(instr, "clz 'rd, 'rs"); |
736 break; | 765 break; |
737 default: | 766 default: |
738 UNREACHABLE(); | 767 UNREACHABLE(); |
739 } | 768 } |
740 break; | 769 break; |
741 case SPECIAL3: | 770 case SPECIAL3: |
742 switch (instr->FunctionFieldRaw()) { | 771 switch (instr->FunctionFieldRaw()) { |
743 case INS: { | 772 case INS: { |
744 if (mips32r2) { | 773 if (mips32r2) { |
745 Format(instr, "ins 'rt, 'rs, 'sd, 'sa"); | 774 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); |
746 } else { | 775 } else { |
747 Unknown(instr); | 776 Unknown(instr); |
748 } | 777 } |
749 break; | 778 break; |
750 } | 779 } |
751 case EXT: { | 780 case EXT: { |
752 if (mips32r2) { | 781 if (mips32r2) { |
753 Format(instr, "ext 'rt, 'rs, 'sd, 'sa"); | 782 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); |
754 } else { | 783 } else { |
755 Unknown(instr); | 784 Unknown(instr); |
756 } | 785 } |
757 break; | 786 break; |
758 } | 787 } |
759 default: | 788 default: |
760 UNREACHABLE(); | 789 UNREACHABLE(); |
761 } | 790 } |
762 break; | 791 break; |
763 default: | 792 default: |
(...skipping 14 matching lines...) Expand all Loading... |
778 Format(instr, "bc1f 'bc, 'imm16u"); | 807 Format(instr, "bc1f 'bc, 'imm16u"); |
779 } | 808 } |
780 break; | 809 break; |
781 default: | 810 default: |
782 UNREACHABLE(); | 811 UNREACHABLE(); |
783 }; | 812 }; |
784 break; // Case COP1. | 813 break; // Case COP1. |
785 case REGIMM: | 814 case REGIMM: |
786 switch (instr->RtFieldRaw()) { | 815 switch (instr->RtFieldRaw()) { |
787 case BLTZ: | 816 case BLTZ: |
788 Format(instr, "bltz 'rs, 'imm16u"); | 817 Format(instr, "bltz 'rs, 'imm16u"); |
789 break; | 818 break; |
790 case BLTZAL: | 819 case BLTZAL: |
791 Format(instr, "bltzal 'rs, 'imm16u"); | 820 Format(instr, "bltzal 'rs, 'imm16u"); |
792 break; | 821 break; |
793 case BGEZ: | 822 case BGEZ: |
794 Format(instr, "bgez 'rs, 'imm16u"); | 823 Format(instr, "bgez 'rs, 'imm16u"); |
795 break; | 824 break; |
796 case BGEZAL: | 825 case BGEZAL: |
797 Format(instr, "bgezal 'rs, 'imm16u"); | 826 Format(instr, "bgezal 'rs, 'imm16u"); |
798 break; | 827 break; |
799 default: | 828 default: |
800 UNREACHABLE(); | 829 UNREACHABLE(); |
801 } | 830 } |
802 break; // Case REGIMM. | 831 break; // Case REGIMM. |
803 // ------------- Branch instructions. | 832 // ------------- Branch instructions. |
804 case BEQ: | 833 case BEQ: |
805 Format(instr, "beq 'rs, 'rt, 'imm16u"); | 834 Format(instr, "beq 'rs, 'rt, 'imm16u"); |
806 break; | 835 break; |
807 case BNE: | 836 case BNE: |
808 Format(instr, "bne 'rs, 'rt, 'imm16u"); | 837 Format(instr, "bne 'rs, 'rt, 'imm16u"); |
809 break; | 838 break; |
810 case BLEZ: | 839 case BLEZ: |
811 Format(instr, "blez 'rs, 'imm16u"); | 840 Format(instr, "blez 'rs, 'imm16u"); |
812 break; | 841 break; |
813 case BGTZ: | 842 case BGTZ: |
814 Format(instr, "bgtz 'rs, 'imm16u"); | 843 Format(instr, "bgtz 'rs, 'imm16u"); |
815 break; | 844 break; |
816 // ------------- Arithmetic instructions. | 845 // ------------- Arithmetic instructions. |
817 case ADDI: | 846 case ADDI: |
818 Format(instr, "addi 'rt, 'rs, 'imm16s"); | 847 Format(instr, "addi 'rt, 'rs, 'imm16s"); |
819 break; | 848 break; |
820 case ADDIU: | 849 case ADDIU: |
821 Format(instr, "addiu 'rt, 'rs, 'imm16s"); | 850 Format(instr, "addiu 'rt, 'rs, 'imm16s"); |
822 break; | 851 break; |
823 case SLTI: | 852 case SLTI: |
824 Format(instr, "slti 'rt, 'rs, 'imm16s"); | 853 Format(instr, "slti 'rt, 'rs, 'imm16s"); |
825 break; | 854 break; |
826 case SLTIU: | 855 case SLTIU: |
827 Format(instr, "sltiu 'rt, 'rs, 'imm16u"); | 856 Format(instr, "sltiu 'rt, 'rs, 'imm16u"); |
828 break; | 857 break; |
829 case ANDI: | 858 case ANDI: |
830 Format(instr, "andi 'rt, 'rs, 'imm16x"); | 859 Format(instr, "andi 'rt, 'rs, 'imm16x"); |
831 break; | 860 break; |
832 case ORI: | 861 case ORI: |
833 Format(instr, "ori 'rt, 'rs, 'imm16x"); | 862 Format(instr, "ori 'rt, 'rs, 'imm16x"); |
834 break; | 863 break; |
835 case XORI: | 864 case XORI: |
836 Format(instr, "xori 'rt, 'rs, 'imm16x"); | 865 Format(instr, "xori 'rt, 'rs, 'imm16x"); |
837 break; | 866 break; |
838 case LUI: | 867 case LUI: |
839 Format(instr, "lui 'rt, 'imm16x"); | 868 Format(instr, "lui 'rt, 'imm16x"); |
840 break; | 869 break; |
841 // ------------- Memory instructions. | 870 // ------------- Memory instructions. |
842 case LB: | 871 case LB: |
843 Format(instr, "lb 'rt, 'imm16s('rs)"); | 872 Format(instr, "lb 'rt, 'imm16s('rs)"); |
844 break; | 873 break; |
845 case LH: | 874 case LH: |
846 Format(instr, "lh 'rt, 'imm16s('rs)"); | 875 Format(instr, "lh 'rt, 'imm16s('rs)"); |
847 break; | 876 break; |
848 case LWL: | 877 case LWL: |
849 Format(instr, "lwl 'rt, 'imm16s('rs)"); | 878 Format(instr, "lwl 'rt, 'imm16s('rs)"); |
850 break; | 879 break; |
851 case LW: | 880 case LW: |
852 Format(instr, "lw 'rt, 'imm16s('rs)"); | 881 Format(instr, "lw 'rt, 'imm16s('rs)"); |
853 break; | 882 break; |
854 case LBU: | 883 case LBU: |
855 Format(instr, "lbu 'rt, 'imm16s('rs)"); | 884 Format(instr, "lbu 'rt, 'imm16s('rs)"); |
856 break; | 885 break; |
857 case LHU: | 886 case LHU: |
858 Format(instr, "lhu 'rt, 'imm16s('rs)"); | 887 Format(instr, "lhu 'rt, 'imm16s('rs)"); |
859 break; | 888 break; |
860 case LWR: | 889 case LWR: |
861 Format(instr, "lwr 'rt, 'imm16s('rs)"); | 890 Format(instr, "lwr 'rt, 'imm16s('rs)"); |
862 break; | 891 break; |
863 case SB: | 892 case SB: |
864 Format(instr, "sb 'rt, 'imm16s('rs)"); | 893 Format(instr, "sb 'rt, 'imm16s('rs)"); |
865 break; | 894 break; |
866 case SH: | 895 case SH: |
867 Format(instr, "sh 'rt, 'imm16s('rs)"); | 896 Format(instr, "sh 'rt, 'imm16s('rs)"); |
868 break; | 897 break; |
869 case SWL: | 898 case SWL: |
870 Format(instr, "swl 'rt, 'imm16s('rs)"); | 899 Format(instr, "swl 'rt, 'imm16s('rs)"); |
871 break; | 900 break; |
872 case SW: | 901 case SW: |
873 Format(instr, "sw 'rt, 'imm16s('rs)"); | 902 Format(instr, "sw 'rt, 'imm16s('rs)"); |
874 break; | 903 break; |
875 case SWR: | 904 case SWR: |
876 Format(instr, "swr 'rt, 'imm16s('rs)"); | 905 Format(instr, "swr 'rt, 'imm16s('rs)"); |
877 break; | 906 break; |
878 case LWC1: | 907 case LWC1: |
879 Format(instr, "lwc1 'ft, 'imm16s('rs)"); | 908 Format(instr, "lwc1 'ft, 'imm16s('rs)"); |
880 break; | 909 break; |
881 case LDC1: | 910 case LDC1: |
882 Format(instr, "ldc1 'ft, 'imm16s('rs)"); | 911 Format(instr, "ldc1 'ft, 'imm16s('rs)"); |
883 break; | 912 break; |
884 case SWC1: | 913 case SWC1: |
885 Format(instr, "swc1 'ft, 'imm16s('rs)"); | 914 Format(instr, "swc1 'ft, 'imm16s('rs)"); |
886 break; | 915 break; |
887 case SDC1: | 916 case SDC1: |
888 Format(instr, "sdc1 'ft, 'imm16s('rs)"); | 917 Format(instr, "sdc1 'ft, 'imm16s('rs)"); |
889 break; | 918 break; |
890 default: | 919 default: |
891 UNREACHABLE(); | 920 UNREACHABLE(); |
892 break; | 921 break; |
893 }; | 922 }; |
894 } | 923 } |
895 | 924 |
896 | 925 |
897 void Decoder::DecodeTypeJump(Instruction* instr) { | 926 void Decoder::DecodeTypeJump(Instruction* instr) { |
898 switch (instr->OpcodeFieldRaw()) { | 927 switch (instr->OpcodeFieldRaw()) { |
899 case J: | 928 case J: |
900 Format(instr, "j 'imm26"); | 929 Format(instr, "j 'imm26"); |
901 break; | 930 break; |
902 case JAL: | 931 case JAL: |
903 Format(instr, "jal 'imm26"); | 932 Format(instr, "jal 'imm26"); |
904 break; | 933 break; |
905 default: | 934 default: |
906 UNREACHABLE(); | 935 UNREACHABLE(); |
907 } | 936 } |
908 } | 937 } |
909 | 938 |
910 | 939 |
911 // Disassemble the instruction at *instr_ptr into the output buffer. | 940 // Disassemble the instruction at *instr_ptr into the output buffer. |
912 int Decoder::InstructionDecode(byte_* instr_ptr) { | 941 int Decoder::InstructionDecode(byte* instr_ptr) { |
913 Instruction* instr = Instruction::At(instr_ptr); | 942 Instruction* instr = Instruction::At(instr_ptr); |
914 // Print raw instruction bytes. | 943 // Print raw instruction bytes. |
915 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 944 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
916 "%08x ", | 945 "%08x ", |
917 instr->InstructionBits()); | 946 instr->InstructionBits()); |
918 switch (instr->InstructionType()) { | 947 switch (instr->InstructionType()) { |
919 case Instruction::kRegisterType: { | 948 case Instruction::kRegisterType: { |
920 DecodeTypeRegister(instr); | 949 DecodeTypeRegister(instr); |
921 break; | 950 break; |
922 } | 951 } |
(...skipping 14 matching lines...) Expand all Loading... |
937 | 966 |
938 | 967 |
939 } } // namespace v8::internal | 968 } } // namespace v8::internal |
940 | 969 |
941 | 970 |
942 | 971 |
943 //------------------------------------------------------------------------------ | 972 //------------------------------------------------------------------------------ |
944 | 973 |
945 namespace disasm { | 974 namespace disasm { |
946 | 975 |
947 using v8::internal::byte_; | 976 const char* NameConverter::NameOfAddress(byte* addr) const { |
948 | |
949 const char* NameConverter::NameOfAddress(byte_* addr) const { | |
950 v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr); | 977 v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr); |
951 return tmp_buffer_.start(); | 978 return tmp_buffer_.start(); |
952 } | 979 } |
953 | 980 |
954 | 981 |
955 const char* NameConverter::NameOfConstant(byte_* addr) const { | 982 const char* NameConverter::NameOfConstant(byte* addr) const { |
956 return NameOfAddress(addr); | 983 return NameOfAddress(addr); |
957 } | 984 } |
958 | 985 |
959 | 986 |
960 const char* NameConverter::NameOfCPURegister(int reg) const { | 987 const char* NameConverter::NameOfCPURegister(int reg) const { |
961 return v8::internal::Registers::Name(reg); | 988 return v8::internal::Registers::Name(reg); |
962 } | 989 } |
963 | 990 |
964 | 991 |
965 const char* NameConverter::NameOfXMMRegister(int reg) const { | 992 const char* NameConverter::NameOfXMMRegister(int reg) const { |
966 return v8::internal::FPURegisters::Name(reg); | 993 return v8::internal::FPURegisters::Name(reg); |
967 } | 994 } |
968 | 995 |
969 | 996 |
970 const char* NameConverter::NameOfByteCPURegister(int reg) const { | 997 const char* NameConverter::NameOfByteCPURegister(int reg) const { |
971 UNREACHABLE(); // MIPS does not have the concept of a byte register | 998 UNREACHABLE(); // MIPS does not have the concept of a byte register. |
972 return "nobytereg"; | 999 return "nobytereg"; |
973 } | 1000 } |
974 | 1001 |
975 | 1002 |
976 const char* NameConverter::NameInCode(byte_* addr) const { | 1003 const char* NameConverter::NameInCode(byte* addr) const { |
977 // The default name converter is called for unknown code. So we will not try | 1004 // The default name converter is called for unknown code. So we will not try |
978 // to access any memory. | 1005 // to access any memory. |
979 return ""; | 1006 return ""; |
980 } | 1007 } |
981 | 1008 |
982 | 1009 |
983 //------------------------------------------------------------------------------ | 1010 //------------------------------------------------------------------------------ |
984 | 1011 |
985 Disassembler::Disassembler(const NameConverter& converter) | 1012 Disassembler::Disassembler(const NameConverter& converter) |
986 : converter_(converter) {} | 1013 : converter_(converter) {} |
987 | 1014 |
988 | 1015 |
989 Disassembler::~Disassembler() {} | 1016 Disassembler::~Disassembler() {} |
990 | 1017 |
991 | 1018 |
992 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, | 1019 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, |
993 byte_* instruction) { | 1020 byte* instruction) { |
994 v8::internal::Decoder d(converter_, buffer); | 1021 v8::internal::Decoder d(converter_, buffer); |
995 return d.InstructionDecode(instruction); | 1022 return d.InstructionDecode(instruction); |
996 } | 1023 } |
997 | 1024 |
998 | 1025 |
999 // The MIPS assembler does not currently use constant pools. | 1026 // The MIPS assembler does not currently use constant pools. |
1000 int Disassembler::ConstantPoolSizeAt(byte_* instruction) { | 1027 int Disassembler::ConstantPoolSizeAt(byte* instruction) { |
1001 return -1; | 1028 return -1; |
1002 } | 1029 } |
1003 | 1030 |
1004 | 1031 |
1005 void Disassembler::Disassemble(FILE* f, byte_* begin, byte_* end) { | 1032 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { |
1006 NameConverter converter; | 1033 NameConverter converter; |
1007 Disassembler d(converter); | 1034 Disassembler d(converter); |
1008 for (byte_* pc = begin; pc < end;) { | 1035 for (byte* pc = begin; pc < end;) { |
1009 v8::internal::EmbeddedVector<char, 128> buffer; | 1036 v8::internal::EmbeddedVector<char, 128> buffer; |
1010 buffer[0] = '\0'; | 1037 buffer[0] = '\0'; |
1011 byte_* prev_pc = pc; | 1038 byte* prev_pc = pc; |
1012 pc += d.InstructionDecode(buffer, pc); | 1039 pc += d.InstructionDecode(buffer, pc); |
1013 fprintf(f, "%p %08x %s\n", | 1040 fprintf(f, "%p %08x %s\n", |
1014 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1041 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1015 } | 1042 } |
1016 } | 1043 } |
1017 | 1044 |
1018 | 1045 |
1019 #undef UNSUPPORTED | 1046 #undef UNSUPPORTED |
1020 | 1047 |
1021 } // namespace disasm | 1048 } // namespace disasm |
1022 | 1049 |
1023 #endif // V8_TARGET_ARCH_MIPS | 1050 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |