| 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 |