| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // A Disassembler object is used to disassemble a block of code instruction by | 5 // A Disassembler object is used to disassemble a block of code instruction by |
| 6 // instruction. The default implementation of the NameConverter object can be | 6 // instruction. The default implementation of the NameConverter object can be |
| 7 // overriden to modify register names or to do symbol lookup on addresses. | 7 // overriden to modify register names or to do symbol lookup on addresses. |
| 8 // | 8 // |
| 9 // The example below will disassemble a block of code and print it to stdout. | 9 // The example below will disassemble a block of code and print it to stdout. |
| 10 // | 10 // |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 void PrintSs1(Instruction* instr); | 80 void PrintSs1(Instruction* instr); |
| 81 void PrintSs2(Instruction* instr); | 81 void PrintSs2(Instruction* instr); |
| 82 void PrintBc(Instruction* instr); | 82 void PrintBc(Instruction* instr); |
| 83 void PrintCc(Instruction* instr); | 83 void PrintCc(Instruction* instr); |
| 84 void PrintBp2(Instruction* instr); | 84 void PrintBp2(Instruction* instr); |
| 85 void PrintFunction(Instruction* instr); | 85 void PrintFunction(Instruction* instr); |
| 86 void PrintSecondaryField(Instruction* instr); | 86 void PrintSecondaryField(Instruction* instr); |
| 87 void PrintUImm16(Instruction* instr); | 87 void PrintUImm16(Instruction* instr); |
| 88 void PrintSImm16(Instruction* instr); | 88 void PrintSImm16(Instruction* instr); |
| 89 void PrintXImm16(Instruction* instr); | 89 void PrintXImm16(Instruction* instr); |
| 90 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); |
| 90 void PrintXImm18(Instruction* instr); | 91 void PrintXImm18(Instruction* instr); |
| 91 void PrintSImm18(Instruction* instr); | 92 void PrintSImm18(Instruction* instr); |
| 92 void PrintXImm19(Instruction* instr); | 93 void PrintXImm19(Instruction* instr); |
| 93 void PrintSImm19(Instruction* instr); | 94 void PrintSImm19(Instruction* instr); |
| 94 void PrintXImm21(Instruction* instr); | 95 void PrintXImm21(Instruction* instr); |
| 95 void PrintSImm21(Instruction* instr); | 96 void PrintSImm21(Instruction* instr); |
| 97 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); |
| 96 void PrintXImm26(Instruction* instr); | 98 void PrintXImm26(Instruction* instr); |
| 97 void PrintSImm26(Instruction* instr); | 99 void PrintSImm26(Instruction* instr); |
| 100 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); |
| 101 void PrintPCImm26(Instruction* instr); |
| 98 void PrintCode(Instruction* instr); // For break and trap instructions. | 102 void PrintCode(Instruction* instr); // For break and trap instructions. |
| 99 void PrintFormat(Instruction* instr); // For floating format postfix. | 103 void PrintFormat(Instruction* instr); // For floating format postfix. |
| 100 // Printing of instruction name. | 104 // Printing of instruction name. |
| 101 void PrintInstructionName(Instruction* instr); | 105 void PrintInstructionName(Instruction* instr); |
| 102 | 106 |
| 103 // Handle formatting of instructions and their options. | 107 // Handle formatting of instructions and their options. |
| 104 int FormatRegister(Instruction* instr, const char* option); | 108 int FormatRegister(Instruction* instr, const char* option); |
| 105 int FormatFPURegister(Instruction* instr, const char* option); | 109 int FormatFPURegister(Instruction* instr, const char* option); |
| 106 int FormatOption(Instruction* instr, const char* option); | 110 int FormatOption(Instruction* instr, const char* option); |
| 107 void Format(Instruction* instr, const char* format); | 111 void Format(Instruction* instr, const char* format); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 } | 267 } |
| 264 | 268 |
| 265 | 269 |
| 266 // Print 16-bit hexa immediate value. | 270 // Print 16-bit hexa immediate value. |
| 267 void Decoder::PrintXImm16(Instruction* instr) { | 271 void Decoder::PrintXImm16(Instruction* instr) { |
| 268 int32_t imm = instr->Imm16Value(); | 272 int32_t imm = instr->Imm16Value(); |
| 269 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 273 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
| 270 } | 274 } |
| 271 | 275 |
| 272 | 276 |
| 277 // Print absoulte address for 16-bit offset or immediate value. |
| 278 // The absolute address is calculated according following expression: |
| 279 // PC + delta_pc + (offset << n_bits) |
| 280 void Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) { |
| 281 int16_t offset = instr->Imm16Value(); |
| 282 out_buffer_pos_ += |
| 283 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 284 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 285 delta_pc + (offset << n_bits))); |
| 286 } |
| 287 |
| 288 |
| 273 // Print 18-bit signed immediate value. | 289 // Print 18-bit signed immediate value. |
| 274 void Decoder::PrintSImm18(Instruction* instr) { | 290 void Decoder::PrintSImm18(Instruction* instr) { |
| 275 int32_t imm = | 291 int32_t imm = |
| 276 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); | 292 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); |
| 277 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); | 293 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
| 278 } | 294 } |
| 279 | 295 |
| 280 | 296 |
| 281 // Print 18-bit hexa immediate value. | 297 // Print 18-bit hexa immediate value. |
| 282 void Decoder::PrintXImm18(Instruction* instr) { | 298 void Decoder::PrintXImm18(Instruction* instr) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 312 // Print 21-bit signed immediate value. | 328 // Print 21-bit signed immediate value. |
| 313 void Decoder::PrintSImm21(Instruction* instr) { | 329 void Decoder::PrintSImm21(Instruction* instr) { |
| 314 int32_t imm21 = instr->Imm21Value(); | 330 int32_t imm21 = instr->Imm21Value(); |
| 315 // set sign | 331 // set sign |
| 316 imm21 <<= (32 - kImm21Bits); | 332 imm21 <<= (32 - kImm21Bits); |
| 317 imm21 >>= (32 - kImm21Bits); | 333 imm21 >>= (32 - kImm21Bits); |
| 318 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); | 334 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); |
| 319 } | 335 } |
| 320 | 336 |
| 321 | 337 |
| 338 // Print absoulte address for 21-bit offset or immediate value. |
| 339 // The absolute address is calculated according following expression: |
| 340 // PC + delta_pc + (offset << n_bits) |
| 341 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { |
| 342 int32_t imm21 = instr->Imm21Value(); |
| 343 // set sign |
| 344 imm21 <<= (32 - kImm21Bits); |
| 345 imm21 >>= (32 - kImm21Bits); |
| 346 out_buffer_pos_ += |
| 347 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 348 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 349 delta_pc + (imm21 << n_bits))); |
| 350 } |
| 351 |
| 352 |
| 322 // Print 26-bit hex immediate value. | 353 // Print 26-bit hex immediate value. |
| 323 void Decoder::PrintXImm26(Instruction* instr) { | 354 void Decoder::PrintXImm26(Instruction* instr) { |
| 324 uint32_t imm = instr->Imm26Value() << kImmFieldShift; | 355 uint32_t imm = instr->Imm26Value() << kImmFieldShift; |
| 325 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 356 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
| 326 } | 357 } |
| 327 | 358 |
| 328 | 359 |
| 329 // Print 26-bit signed immediate value. | 360 // Print 26-bit signed immediate value. |
| 330 void Decoder::PrintSImm26(Instruction* instr) { | 361 void Decoder::PrintSImm26(Instruction* instr) { |
| 331 int32_t imm26 = instr->Imm26Value(); | 362 int32_t imm26 = instr->Imm26Value(); |
| 332 // set sign | 363 // set sign |
| 333 imm26 <<= (32 - kImm26Bits); | 364 imm26 <<= (32 - kImm26Bits); |
| 334 imm26 >>= (32 - kImm26Bits); | 365 imm26 >>= (32 - kImm26Bits); |
| 335 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); | 366 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); |
| 336 } | 367 } |
| 337 | 368 |
| 338 | 369 |
| 370 // Print absoulte address for 26-bit offset or immediate value. |
| 371 // The absolute address is calculated according following expression: |
| 372 // PC + delta_pc + (offset << n_bits) |
| 373 void Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) { |
| 374 int32_t imm26 = instr->Imm26Value(); |
| 375 // set sign |
| 376 imm26 <<= (32 - kImm26Bits); |
| 377 imm26 >>= (32 - kImm26Bits); |
| 378 out_buffer_pos_ += |
| 379 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 380 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 381 delta_pc + (imm26 << n_bits))); |
| 382 } |
| 383 |
| 384 |
| 385 // Print absoulte address for 26-bit offset or immediate value. |
| 386 // The absolute address is calculated according following expression: |
| 387 // PC[GPRLEN-1 .. 28] || instr_index26 || 00 |
| 388 void Decoder::PrintPCImm26(Instruction* instr) { |
| 389 int32_t imm26 = instr->Imm26Value(); |
| 390 uint32_t pc_mask = ~0xfffffff; |
| 391 uint32_t pc = ((uint32_t)(instr + 1) & pc_mask) | (imm26 << 2); |
| 392 out_buffer_pos_ += |
| 393 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 394 converter_.NameOfAddress((reinterpret_cast<byte*>(pc)))); |
| 395 } |
| 396 |
| 397 |
| 339 // Print 26-bit immediate value. | 398 // Print 26-bit immediate value. |
| 340 void Decoder::PrintCode(Instruction* instr) { | 399 void Decoder::PrintCode(Instruction* instr) { |
| 341 if (instr->OpcodeFieldRaw() != SPECIAL) | 400 if (instr->OpcodeFieldRaw() != SPECIAL) |
| 342 return; // Not a break or trap instruction. | 401 return; // Not a break or trap instruction. |
| 343 switch (instr->FunctionFieldRaw()) { | 402 switch (instr->FunctionFieldRaw()) { |
| 344 case BREAK: { | 403 case BREAK: { |
| 345 int32_t code = instr->Bits(25, 6); | 404 int32_t code = instr->Bits(25, 6); |
| 346 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 405 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 347 "0x%05x (%d)", code, code); | 406 "0x%05x (%d)", code, code); |
| 348 break; | 407 break; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 PrintSImm16(instr); | 521 PrintSImm16(instr); |
| 463 break; | 522 break; |
| 464 case 'u': | 523 case 'u': |
| 465 DCHECK(STRING_STARTS_WITH(format, "imm16u")); | 524 DCHECK(STRING_STARTS_WITH(format, "imm16u")); |
| 466 PrintSImm16(instr); | 525 PrintSImm16(instr); |
| 467 break; | 526 break; |
| 468 case 'x': | 527 case 'x': |
| 469 DCHECK(STRING_STARTS_WITH(format, "imm16x")); | 528 DCHECK(STRING_STARTS_WITH(format, "imm16x")); |
| 470 PrintXImm16(instr); | 529 PrintXImm16(instr); |
| 471 break; | 530 break; |
| 531 case 'p': { // The PC relative address. |
| 532 DCHECK(STRING_STARTS_WITH(format, "imm16p")); |
| 533 int delta_pc = 0; |
| 534 int n_bits = 0; |
| 535 switch (format[6]) { |
| 536 case '4': { |
| 537 DCHECK(STRING_STARTS_WITH(format, "imm16p4")); |
| 538 delta_pc = 4; |
| 539 switch (format[8]) { |
| 540 case '2': |
| 541 DCHECK(STRING_STARTS_WITH(format, "imm16p4s2")); |
| 542 n_bits = 2; |
| 543 PrintPCImm16(instr, delta_pc, n_bits); |
| 544 return 9; |
| 545 } |
| 546 } |
| 547 } |
| 548 } |
| 472 } | 549 } |
| 473 return 6; | 550 return 6; |
| 474 } else if (format[4] == '8') { | 551 } else if (format[4] == '8') { |
| 475 DCHECK(STRING_STARTS_WITH(format, "imm18")); | 552 DCHECK(STRING_STARTS_WITH(format, "imm18")); |
| 476 switch (format[5]) { | 553 switch (format[5]) { |
| 477 case 's': | 554 case 's': |
| 478 DCHECK(STRING_STARTS_WITH(format, "imm18s")); | 555 DCHECK(STRING_STARTS_WITH(format, "imm18s")); |
| 479 PrintSImm18(instr); | 556 PrintSImm18(instr); |
| 480 break; | 557 break; |
| 481 case 'x': | 558 case 'x': |
| (...skipping 20 matching lines...) Expand all Loading... |
| 502 DCHECK(STRING_STARTS_WITH(format, "imm21")); | 579 DCHECK(STRING_STARTS_WITH(format, "imm21")); |
| 503 switch (format[5]) { | 580 switch (format[5]) { |
| 504 case 's': | 581 case 's': |
| 505 DCHECK(STRING_STARTS_WITH(format, "imm21s")); | 582 DCHECK(STRING_STARTS_WITH(format, "imm21s")); |
| 506 PrintSImm21(instr); | 583 PrintSImm21(instr); |
| 507 break; | 584 break; |
| 508 case 'x': | 585 case 'x': |
| 509 DCHECK(STRING_STARTS_WITH(format, "imm21x")); | 586 DCHECK(STRING_STARTS_WITH(format, "imm21x")); |
| 510 PrintXImm21(instr); | 587 PrintXImm21(instr); |
| 511 break; | 588 break; |
| 589 case 'p': { // The PC relative address. |
| 590 DCHECK(STRING_STARTS_WITH(format, "imm21p")); |
| 591 int delta_pc = 0; |
| 592 int n_bits = 0; |
| 593 switch (format[6]) { |
| 594 case '4': { |
| 595 DCHECK(STRING_STARTS_WITH(format, "imm21p4")); |
| 596 delta_pc = 4; |
| 597 switch (format[8]) { |
| 598 case '2': |
| 599 DCHECK(STRING_STARTS_WITH(format, "imm21p4s2")); |
| 600 n_bits = 2; |
| 601 PrintPCImm21(instr, delta_pc, n_bits); |
| 602 return 9; |
| 603 } |
| 604 } |
| 605 } |
| 606 } |
| 512 } | 607 } |
| 513 return 6; | 608 return 6; |
| 514 } else if (format[3] == '2' && format[4] == '6') { | 609 } else if (format[3] == '2' && format[4] == '6') { |
| 515 DCHECK(STRING_STARTS_WITH(format, "imm26")); | 610 DCHECK(STRING_STARTS_WITH(format, "imm26")); |
| 516 switch (format[5]) { | 611 switch (format[5]) { |
| 517 case 's': | 612 case 's': |
| 518 DCHECK(STRING_STARTS_WITH(format, "imm26s")); | 613 DCHECK(STRING_STARTS_WITH(format, "imm26s")); |
| 519 PrintSImm26(instr); | 614 PrintSImm26(instr); |
| 520 break; | 615 break; |
| 521 case 'x': | 616 case 'x': |
| 522 DCHECK(STRING_STARTS_WITH(format, "imm26x")); | 617 DCHECK(STRING_STARTS_WITH(format, "imm26x")); |
| 523 PrintXImm26(instr); | 618 PrintXImm26(instr); |
| 524 break; | 619 break; |
| 620 case 'p': { // The PC relative address. |
| 621 DCHECK(STRING_STARTS_WITH(format, "imm26p")); |
| 622 int delta_pc = 0; |
| 623 int n_bits = 0; |
| 624 switch (format[6]) { |
| 625 case '4': { |
| 626 DCHECK(STRING_STARTS_WITH(format, "imm26p4")); |
| 627 delta_pc = 4; |
| 628 switch (format[8]) { |
| 629 case '2': |
| 630 DCHECK(STRING_STARTS_WITH(format, "imm26p4s2")); |
| 631 n_bits = 2; |
| 632 PrintPCImm26(instr, delta_pc, n_bits); |
| 633 return 9; |
| 634 } |
| 635 } |
| 636 } |
| 637 } |
| 638 case 'j': { // Absolute address for jump instructions. |
| 639 DCHECK(STRING_STARTS_WITH(format, "imm26j")); |
| 640 PrintPCImm26(instr); |
| 641 break; |
| 642 } |
| 525 } | 643 } |
| 526 return 6; | 644 return 6; |
| 527 } | 645 } |
| 528 } | 646 } |
| 529 case 'r': { // 'r: registers. | 647 case 'r': { // 'r: registers. |
| 530 return FormatRegister(instr, format); | 648 return FormatRegister(instr, format); |
| 531 } | 649 } |
| 532 case 'f': { // 'f: FPUregisters. | 650 case 'f': { // 'f: FPUregisters. |
| 533 return FormatFPURegister(instr, format); | 651 return FormatFPURegister(instr, format); |
| 534 } | 652 } |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 } | 1311 } |
| 1194 } | 1312 } |
| 1195 | 1313 |
| 1196 | 1314 |
| 1197 void Decoder::DecodeTypeImmediate(Instruction* instr) { | 1315 void Decoder::DecodeTypeImmediate(Instruction* instr) { |
| 1198 switch (instr->OpcodeFieldRaw()) { | 1316 switch (instr->OpcodeFieldRaw()) { |
| 1199 case COP1: | 1317 case COP1: |
| 1200 switch (instr->RsFieldRaw()) { | 1318 switch (instr->RsFieldRaw()) { |
| 1201 case BC1: | 1319 case BC1: |
| 1202 if (instr->FBtrueValue()) { | 1320 if (instr->FBtrueValue()) { |
| 1203 Format(instr, "bc1t 'bc, 'imm16u"); | 1321 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); |
| 1204 } else { | 1322 } else { |
| 1205 Format(instr, "bc1f 'bc, 'imm16u"); | 1323 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); |
| 1206 } | 1324 } |
| 1207 break; | 1325 break; |
| 1208 case BC1EQZ: | 1326 case BC1EQZ: |
| 1209 Format(instr, "bc1eqz 'ft, 'imm16u"); | 1327 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); |
| 1210 break; | 1328 break; |
| 1211 case BC1NEZ: | 1329 case BC1NEZ: |
| 1212 Format(instr, "bc1nez 'ft, 'imm16u"); | 1330 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); |
| 1213 break; | 1331 break; |
| 1214 default: | 1332 default: |
| 1215 UNREACHABLE(); | 1333 UNREACHABLE(); |
| 1216 } | 1334 } |
| 1217 | 1335 |
| 1218 break; // Case COP1. | 1336 break; // Case COP1. |
| 1219 // ------------- REGIMM class. | 1337 // ------------- REGIMM class. |
| 1220 case REGIMM: | 1338 case REGIMM: |
| 1221 switch (instr->RtFieldRaw()) { | 1339 switch (instr->RtFieldRaw()) { |
| 1222 case BLTZ: | 1340 case BLTZ: |
| 1223 Format(instr, "bltz 'rs, 'imm16u"); | 1341 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); |
| 1224 break; | 1342 break; |
| 1225 case BLTZAL: | 1343 case BLTZAL: |
| 1226 Format(instr, "bltzal 'rs, 'imm16u"); | 1344 Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2"); |
| 1227 break; | 1345 break; |
| 1228 case BGEZ: | 1346 case BGEZ: |
| 1229 Format(instr, "bgez 'rs, 'imm16u"); | 1347 Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); |
| 1230 break; | 1348 break; |
| 1231 case BGEZAL: | 1349 case BGEZAL: |
| 1232 Format(instr, "bgezal 'rs, 'imm16u"); | 1350 Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); |
| 1233 break; | 1351 break; |
| 1234 case BGEZALL: | 1352 case BGEZALL: |
| 1235 Format(instr, "bgezall 'rs, 'imm16u"); | 1353 Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); |
| 1236 break; | 1354 break; |
| 1237 default: | 1355 default: |
| 1238 UNREACHABLE(); | 1356 UNREACHABLE(); |
| 1239 } | 1357 } |
| 1240 break; // Case REGIMM. | 1358 break; // Case REGIMM. |
| 1241 // ------------- Branch instructions. | 1359 // ------------- Branch instructions. |
| 1242 case BEQ: | 1360 case BEQ: |
| 1243 Format(instr, "beq 'rs, 'rt, 'imm16u"); | 1361 Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
| 1244 break; | 1362 break; |
| 1245 case BC: | 1363 case BC: |
| 1246 Format(instr, "bc 'imm26s"); | 1364 Format(instr, "bc 'imm26s -> 'imm26p4s2"); |
| 1247 break; | 1365 break; |
| 1248 case BALC: | 1366 case BALC: |
| 1249 Format(instr, "balc 'imm26s"); | 1367 Format(instr, "balc 'imm26s -> 'imm26p4s2"); |
| 1250 break; | 1368 break; |
| 1251 case BNE: | 1369 case BNE: |
| 1252 Format(instr, "bne 'rs, 'rt, 'imm16u"); | 1370 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
| 1253 break; | 1371 break; |
| 1254 case BLEZ: | 1372 case BLEZ: |
| 1255 if ((instr->RtFieldRaw() == 0) | 1373 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
| 1256 && (instr->RsFieldRaw() != 0)) { | 1374 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); |
| 1257 Format(instr, "blez 'rs, 'imm16u"); | 1375 } else if ((instr->RtValue() != instr->RsValue()) && |
| 1258 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1376 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
| 1259 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1377 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
| 1260 Format(instr, "bgeuc 'rs, 'rt, 'imm16u"); | 1378 } else if ((instr->RtValue() == instr->RsValue()) && |
| 1261 } else if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1379 (instr->RtValue() != 0)) { |
| 1262 && (instr->RtFieldRaw() != 0)) { | 1380 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); |
| 1263 Format(instr, "bgezalc 'rs, 'imm16u"); | 1381 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
| 1264 } else if ((instr->RsFieldRaw() == 0) | 1382 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); |
| 1265 && (instr->RtFieldRaw() != 0)) { | |
| 1266 Format(instr, "blezalc 'rs, 'imm16u"); | |
| 1267 } else { | 1383 } else { |
| 1268 UNREACHABLE(); | 1384 UNREACHABLE(); |
| 1269 } | 1385 } |
| 1270 break; | 1386 break; |
| 1271 case BGTZ: | 1387 case BGTZ: |
| 1272 if ((instr->RtFieldRaw() == 0) | 1388 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
| 1273 && (instr->RsFieldRaw() != 0)) { | 1389 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); |
| 1274 Format(instr, "bgtz 'rs, 'imm16u"); | 1390 } else if ((instr->RtValue() != instr->RsValue()) && |
| 1275 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1391 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
| 1276 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1392 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
| 1277 Format(instr, "bltuc 'rs, 'rt, 'imm16u"); | 1393 } else if ((instr->RtValue() == instr->RsValue()) && |
| 1278 } else if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1394 (instr->RtValue() != 0)) { |
| 1279 && (instr->RtFieldRaw() != 0)) { | 1395 Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2"); |
| 1280 Format(instr, "bltzalc 'rt, 'imm16u"); | 1396 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
| 1281 } else if ((instr->RsFieldRaw() == 0) | 1397 Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2"); |
| 1282 && (instr->RtFieldRaw() != 0)) { | |
| 1283 Format(instr, "bgtzalc 'rt, 'imm16u"); | |
| 1284 } else { | 1398 } else { |
| 1285 UNREACHABLE(); | 1399 UNREACHABLE(); |
| 1286 } | 1400 } |
| 1287 break; | 1401 break; |
| 1288 case BLEZL: | 1402 case BLEZL: |
| 1289 if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1403 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { |
| 1290 && (instr->RtFieldRaw() != 0)) { | 1404 Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2"); |
| 1291 Format(instr, "bgezc 'rt, 'imm16u"); | 1405 } else if ((instr->RtValue() != instr->RsValue()) && |
| 1292 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1406 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
| 1293 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1407 Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
| 1294 Format(instr, "bgec 'rs, 'rt, 'imm16u"); | 1408 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
| 1295 } else if ((instr->RsFieldRaw() == 0) | 1409 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); |
| 1296 && (instr->RtFieldRaw() != 0)) { | |
| 1297 Format(instr, "blezc 'rt, 'imm16u"); | |
| 1298 } else { | 1410 } else { |
| 1299 UNREACHABLE(); | 1411 UNREACHABLE(); |
| 1300 } | 1412 } |
| 1301 break; | 1413 break; |
| 1302 case BGTZL: | 1414 case BGTZL: |
| 1303 if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1415 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { |
| 1304 && (instr->RtFieldRaw() != 0)) { | 1416 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); |
| 1305 Format(instr, "bltzc 'rt, 'imm16u"); | 1417 } else if ((instr->RtValue() != instr->RsValue()) && |
| 1306 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1418 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
| 1307 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1419 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
| 1308 Format(instr, "bltc 'rs, 'rt, 'imm16u"); | 1420 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
| 1309 } else if ((instr->RsFieldRaw() == 0) | 1421 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); |
| 1310 && (instr->RtFieldRaw() != 0)) { | |
| 1311 Format(instr, "bgtzc 'rt, 'imm16u"); | |
| 1312 } else { | 1422 } else { |
| 1313 UNREACHABLE(); | 1423 UNREACHABLE(); |
| 1314 } | 1424 } |
| 1315 break; | 1425 break; |
| 1316 case POP66: | 1426 case POP66: |
| 1317 if (instr->RsValue() == JIC) { | 1427 if (instr->RsValue() == JIC) { |
| 1318 Format(instr, "jic 'rt, 'imm16s"); | 1428 Format(instr, "jic 'rt, 'imm16s"); |
| 1319 } else { | 1429 } else { |
| 1320 Format(instr, "beqzc 'rs, 'imm21s"); | 1430 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2"); |
| 1321 } | 1431 } |
| 1322 break; | 1432 break; |
| 1323 case POP76: | 1433 case POP76: |
| 1324 if (instr->RsValue() == JIALC) { | 1434 if (instr->RsValue() == JIALC) { |
| 1325 Format(instr, "jialc 'rt, 'imm16x"); | 1435 Format(instr, "jialc 'rt, 'imm16x"); |
| 1326 } else { | 1436 } else { |
| 1327 Format(instr, "bnezc 'rs, 'imm21x"); | 1437 Format(instr, "bnezc 'rs, 'imm21x -> 'imm21p4s2"); |
| 1328 } | 1438 } |
| 1329 break; | 1439 break; |
| 1330 // ------------- Arithmetic instructions. | 1440 // ------------- Arithmetic instructions. |
| 1331 case ADDI: | 1441 case ADDI: |
| 1332 if (!IsMipsArchVariant(kMips32r6)) { | 1442 if (!IsMipsArchVariant(kMips32r6)) { |
| 1333 Format(instr, "addi 'rt, 'rs, 'imm16s"); | 1443 Format(instr, "addi 'rt, 'rs, 'imm16s"); |
| 1334 } else { | 1444 } else { |
| 1335 // Check if BOVC or BEQC instruction. | 1445 // Check if BOVC or BEQC instruction. |
| 1336 if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { | 1446 if (instr->RsValue() >= instr->RtValue()) { |
| 1337 Format(instr, "bovc 'rs, 'rt, 'imm16s"); | 1447 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
| 1338 } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) { | 1448 } else if (instr->RsValue() < instr->RtValue()) { |
| 1339 Format(instr, "beqc 'rs, 'rt, 'imm16s"); | 1449 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
| 1340 } else { | 1450 } else { |
| 1341 UNREACHABLE(); | 1451 UNREACHABLE(); |
| 1342 } | 1452 } |
| 1343 } | 1453 } |
| 1344 break; | 1454 break; |
| 1345 case DADDI: | 1455 case DADDI: |
| 1346 if (IsMipsArchVariant(kMips32r6)) { | 1456 if (IsMipsArchVariant(kMips32r6)) { |
| 1347 // Check if BNVC or BNEC instruction. | 1457 // Check if BNVC or BNEC instruction. |
| 1348 if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { | 1458 if (instr->RsValue() >= instr->RtValue()) { |
| 1349 Format(instr, "bnvc 'rs, 'rt, 'imm16s"); | 1459 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
| 1350 } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) { | 1460 } else if (instr->RsValue() < instr->RtValue()) { |
| 1351 Format(instr, "bnec 'rs, 'rt, 'imm16s"); | 1461 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
| 1352 } else { | 1462 } else { |
| 1353 UNREACHABLE(); | 1463 UNREACHABLE(); |
| 1354 } | 1464 } |
| 1355 } | 1465 } |
| 1356 break; | 1466 break; |
| 1357 case ADDIU: | 1467 case ADDIU: |
| 1358 Format(instr, "addiu 'rt, 'rs, 'imm16s"); | 1468 Format(instr, "addiu 'rt, 'rs, 'imm16s"); |
| 1359 break; | 1469 break; |
| 1360 case SLTI: | 1470 case SLTI: |
| 1361 Format(instr, "slti 'rt, 'rs, 'imm16s"); | 1471 Format(instr, "slti 'rt, 'rs, 'imm16s"); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 printf("a 0x%x \n", instr->OpcodeFieldRaw()); | 1578 printf("a 0x%x \n", instr->OpcodeFieldRaw()); |
| 1469 UNREACHABLE(); | 1579 UNREACHABLE(); |
| 1470 break; | 1580 break; |
| 1471 } | 1581 } |
| 1472 } | 1582 } |
| 1473 | 1583 |
| 1474 | 1584 |
| 1475 void Decoder::DecodeTypeJump(Instruction* instr) { | 1585 void Decoder::DecodeTypeJump(Instruction* instr) { |
| 1476 switch (instr->OpcodeFieldRaw()) { | 1586 switch (instr->OpcodeFieldRaw()) { |
| 1477 case J: | 1587 case J: |
| 1478 Format(instr, "j 'imm26x"); | 1588 Format(instr, "j 'imm26x -> 'imm26j"); |
| 1479 break; | 1589 break; |
| 1480 case JAL: | 1590 case JAL: |
| 1481 Format(instr, "jal 'imm26x"); | 1591 Format(instr, "jal 'imm26x -> 'imm26j"); |
| 1482 break; | 1592 break; |
| 1483 default: | 1593 default: |
| 1484 UNREACHABLE(); | 1594 UNREACHABLE(); |
| 1485 } | 1595 } |
| 1486 } | 1596 } |
| 1487 | 1597 |
| 1488 | 1598 |
| 1489 // Disassemble the instruction at *instr_ptr into the output buffer. | 1599 // Disassemble the instruction at *instr_ptr into the output buffer. |
| 1490 int Decoder::InstructionDecode(byte* instr_ptr) { | 1600 int Decoder::InstructionDecode(byte* instr_ptr) { |
| 1491 Instruction* instr = Instruction::At(instr_ptr); | 1601 Instruction* instr = Instruction::At(instr_ptr); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1701 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
| 1592 } | 1702 } |
| 1593 } | 1703 } |
| 1594 | 1704 |
| 1595 | 1705 |
| 1596 #undef UNSUPPORTED | 1706 #undef UNSUPPORTED |
| 1597 | 1707 |
| 1598 } // namespace disasm | 1708 } // namespace disasm |
| 1599 | 1709 |
| 1600 #endif // V8_TARGET_ARCH_MIPS | 1710 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |