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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 void PrintSd(Instruction* instr); | 79 void PrintSd(Instruction* instr); |
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 PrintFunction(Instruction* instr); | 84 void PrintFunction(Instruction* instr); |
85 void PrintSecondaryField(Instruction* instr); | 85 void PrintSecondaryField(Instruction* instr); |
86 void PrintUImm16(Instruction* instr); | 86 void PrintUImm16(Instruction* instr); |
87 void PrintSImm16(Instruction* instr); | 87 void PrintSImm16(Instruction* instr); |
88 void PrintXImm16(Instruction* instr); | 88 void PrintXImm16(Instruction* instr); |
| 89 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); |
89 void PrintXImm18(Instruction* instr); | 90 void PrintXImm18(Instruction* instr); |
90 void PrintSImm18(Instruction* instr); | 91 void PrintSImm18(Instruction* instr); |
91 void PrintXImm19(Instruction* instr); | 92 void PrintXImm19(Instruction* instr); |
92 void PrintSImm19(Instruction* instr); | 93 void PrintSImm19(Instruction* instr); |
93 void PrintXImm21(Instruction* instr); | 94 void PrintXImm21(Instruction* instr); |
| 95 |
| 96 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); |
94 void PrintXImm26(Instruction* instr); | 97 void PrintXImm26(Instruction* instr); |
95 void PrintSImm26(Instruction* instr); | 98 void PrintSImm26(Instruction* instr); |
| 99 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); |
| 100 void PrintPCImm26(Instruction* instr); |
96 void PrintCode(Instruction* instr); // For break and trap instructions. | 101 void PrintCode(Instruction* instr); // For break and trap instructions. |
97 void PrintFormat(Instruction* instr); // For floating format postfix. | 102 void PrintFormat(Instruction* instr); // For floating format postfix. |
98 void PrintBp2(Instruction* instr); | 103 void PrintBp2(Instruction* instr); |
99 void PrintBp3(Instruction* instr); | 104 void PrintBp3(Instruction* instr); |
100 // Printing of instruction name. | 105 // Printing of instruction name. |
101 void PrintInstructionName(Instruction* instr); | 106 void PrintInstructionName(Instruction* instr); |
102 | 107 |
103 // Handle formatting of instructions and their options. | 108 // Handle formatting of instructions and their options. |
104 int FormatRegister(Instruction* instr, const char* option); | 109 int FormatRegister(Instruction* instr, const char* option); |
105 int FormatFPURegister(Instruction* instr, const char* option); | 110 int FormatFPURegister(Instruction* instr, const char* option); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 } | 269 } |
265 | 270 |
266 | 271 |
267 // Print 16-bit hexa immediate value. | 272 // Print 16-bit hexa immediate value. |
268 void Decoder::PrintXImm16(Instruction* instr) { | 273 void Decoder::PrintXImm16(Instruction* instr) { |
269 int32_t imm = instr->Imm16Value(); | 274 int32_t imm = instr->Imm16Value(); |
270 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 275 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
271 } | 276 } |
272 | 277 |
273 | 278 |
| 279 // Print absoulte address for 16-bit offset or immediate value. |
| 280 // The absolute address is calculated according following expression: |
| 281 // PC + delta_pc + (offset << n_bits) |
| 282 void Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) { |
| 283 int16_t offset = instr->Imm16Value(); |
| 284 out_buffer_pos_ += |
| 285 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 286 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 287 delta_pc + (offset << n_bits))); |
| 288 } |
| 289 |
| 290 |
274 // Print 18-bit signed immediate value. | 291 // Print 18-bit signed immediate value. |
275 void Decoder::PrintSImm18(Instruction* instr) { | 292 void Decoder::PrintSImm18(Instruction* instr) { |
276 int32_t imm = | 293 int32_t imm = |
277 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); | 294 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); |
278 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); | 295 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
279 } | 296 } |
280 | 297 |
281 | 298 |
282 // Print 18-bit hexa immediate value. | 299 // Print 18-bit hexa immediate value. |
283 void Decoder::PrintXImm18(Instruction* instr) { | 300 void Decoder::PrintXImm18(Instruction* instr) { |
(...skipping 19 matching lines...) Expand all Loading... |
303 } | 320 } |
304 | 321 |
305 | 322 |
306 // Print 21-bit immediate value. | 323 // Print 21-bit immediate value. |
307 void Decoder::PrintXImm21(Instruction* instr) { | 324 void Decoder::PrintXImm21(Instruction* instr) { |
308 uint32_t imm = instr->Imm21Value(); | 325 uint32_t imm = instr->Imm21Value(); |
309 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 326 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
310 } | 327 } |
311 | 328 |
312 | 329 |
| 330 // Print absoulte address for 21-bit offset or immediate value. |
| 331 // The absolute address is calculated according following expression: |
| 332 // PC + delta_pc + (offset << n_bits) |
| 333 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { |
| 334 int32_t imm21 = instr->Imm21Value(); |
| 335 // set sign |
| 336 imm21 <<= (32 - kImm21Bits); |
| 337 imm21 >>= (32 - kImm21Bits); |
| 338 out_buffer_pos_ += |
| 339 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 340 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 341 delta_pc + (imm21 << n_bits))); |
| 342 } |
| 343 |
| 344 |
313 // Print 26-bit hex immediate value. | 345 // Print 26-bit hex immediate value. |
314 void Decoder::PrintXImm26(Instruction* instr) { | 346 void Decoder::PrintXImm26(Instruction* instr) { |
315 uint32_t imm = static_cast<uint32_t>(instr->Imm26Value()) << kImmFieldShift; | 347 uint32_t imm = static_cast<uint32_t>(instr->Imm26Value()) << kImmFieldShift; |
316 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 348 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
317 } | 349 } |
318 | 350 |
319 | 351 |
320 // Print 26-bit signed immediate value. | 352 // Print 26-bit signed immediate value. |
321 void Decoder::PrintSImm26(Instruction* instr) { | 353 void Decoder::PrintSImm26(Instruction* instr) { |
322 int32_t imm26 = instr->Imm26Value(); | 354 int32_t imm26 = instr->Imm26Value(); |
323 // set sign | 355 // set sign |
324 imm26 <<= (32 - kImm26Bits); | 356 imm26 <<= (32 - kImm26Bits); |
325 imm26 >>= (32 - kImm26Bits); | 357 imm26 >>= (32 - kImm26Bits); |
326 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); | 358 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); |
327 } | 359 } |
328 | 360 |
329 | 361 |
| 362 // Print absoulte address for 26-bit offset or immediate value. |
| 363 // The absolute address is calculated according following expression: |
| 364 // PC + delta_pc + (offset << n_bits) |
| 365 void Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) { |
| 366 int32_t imm26 = instr->Imm26Value(); |
| 367 // set sign |
| 368 imm26 <<= (32 - kImm26Bits); |
| 369 imm26 >>= (32 - kImm26Bits); |
| 370 out_buffer_pos_ += |
| 371 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 372 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 373 delta_pc + (imm26 << n_bits))); |
| 374 } |
| 375 |
| 376 |
| 377 // Print absoulte address for 26-bit offset or immediate value. |
| 378 // The absolute address is calculated according following expression: |
| 379 // PC[GPRLEN-1 .. 28] || instr_index26 || 00 |
| 380 void Decoder::PrintPCImm26(Instruction* instr) { |
| 381 int32_t imm26 = instr->Imm26Value(); |
| 382 uint64_t pc_mask = ~0xfffffff; |
| 383 uint64_t pc = ((uint64_t)(instr + 1) & pc_mask) | (imm26 << 2); |
| 384 out_buffer_pos_ += |
| 385 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 386 converter_.NameOfAddress((reinterpret_cast<byte*>(pc)))); |
| 387 } |
| 388 |
| 389 |
330 void Decoder::PrintBp2(Instruction* instr) { | 390 void Decoder::PrintBp2(Instruction* instr) { |
331 int bp2 = instr->Bp2Value(); | 391 int bp2 = instr->Bp2Value(); |
332 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2); | 392 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2); |
333 } | 393 } |
334 | 394 |
335 | 395 |
336 void Decoder::PrintBp3(Instruction* instr) { | 396 void Decoder::PrintBp3(Instruction* instr) { |
337 int bp3 = instr->Bp3Value(); | 397 int bp3 = instr->Bp3Value(); |
338 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp3); | 398 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp3); |
339 } | 399 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 PrintSImm16(instr); | 525 PrintSImm16(instr); |
466 break; | 526 break; |
467 case 'u': | 527 case 'u': |
468 DCHECK(STRING_STARTS_WITH(format, "imm16u")); | 528 DCHECK(STRING_STARTS_WITH(format, "imm16u")); |
469 PrintSImm16(instr); | 529 PrintSImm16(instr); |
470 break; | 530 break; |
471 case 'x': | 531 case 'x': |
472 DCHECK(STRING_STARTS_WITH(format, "imm16x")); | 532 DCHECK(STRING_STARTS_WITH(format, "imm16x")); |
473 PrintXImm16(instr); | 533 PrintXImm16(instr); |
474 break; | 534 break; |
| 535 case 'p': { // The PC relative address. |
| 536 DCHECK(STRING_STARTS_WITH(format, "imm16p")); |
| 537 int delta_pc = 0; |
| 538 int n_bits = 0; |
| 539 switch (format[6]) { |
| 540 case '4': { |
| 541 DCHECK(STRING_STARTS_WITH(format, "imm16p4")); |
| 542 delta_pc = 4; |
| 543 switch (format[8]) { |
| 544 case '2': |
| 545 DCHECK(STRING_STARTS_WITH(format, "imm16p4s2")); |
| 546 n_bits = 2; |
| 547 PrintPCImm16(instr, delta_pc, n_bits); |
| 548 return 9; |
| 549 } |
| 550 } |
| 551 } |
| 552 } |
475 } | 553 } |
476 return 6; | 554 return 6; |
477 } else if (format[4] == '8') { | 555 } else if (format[4] == '8') { |
478 DCHECK(STRING_STARTS_WITH(format, "imm18")); | 556 DCHECK(STRING_STARTS_WITH(format, "imm18")); |
479 switch (format[5]) { | 557 switch (format[5]) { |
480 case 's': | 558 case 's': |
481 DCHECK(STRING_STARTS_WITH(format, "imm18s")); | 559 DCHECK(STRING_STARTS_WITH(format, "imm18s")); |
482 PrintSImm18(instr); | 560 PrintSImm18(instr); |
483 break; | 561 break; |
484 case 'x': | 562 case 'x': |
(...skipping 10 matching lines...) Expand all Loading... |
495 PrintSImm19(instr); | 573 PrintSImm19(instr); |
496 break; | 574 break; |
497 case 'x': | 575 case 'x': |
498 DCHECK(STRING_STARTS_WITH(format, "imm19x")); | 576 DCHECK(STRING_STARTS_WITH(format, "imm19x")); |
499 PrintXImm19(instr); | 577 PrintXImm19(instr); |
500 break; | 578 break; |
501 } | 579 } |
502 return 6; | 580 return 6; |
503 } | 581 } |
504 } else if (format[3] == '2' && format[4] == '1') { | 582 } else if (format[3] == '2' && format[4] == '1') { |
505 DCHECK(STRING_STARTS_WITH(format, "imm21x")); | 583 DCHECK(STRING_STARTS_WITH(format, "imm21")); |
506 PrintXImm21(instr); | 584 switch (format[5]) { |
| 585 case 'x': |
| 586 DCHECK(STRING_STARTS_WITH(format, "imm21x")); |
| 587 PrintXImm21(instr); |
| 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 } |
| 607 } |
507 return 6; | 608 return 6; |
508 } else if (format[3] == '2' && format[4] == '6') { | 609 } else if (format[3] == '2' && format[4] == '6') { |
509 DCHECK(STRING_STARTS_WITH(format, "imm26")); | 610 DCHECK(STRING_STARTS_WITH(format, "imm26")); |
510 switch (format[5]) { | 611 switch (format[5]) { |
511 case 's': | 612 case 's': |
512 DCHECK(STRING_STARTS_WITH(format, "imm26s")); | 613 DCHECK(STRING_STARTS_WITH(format, "imm26s")); |
513 PrintSImm26(instr); | 614 PrintSImm26(instr); |
514 break; | 615 break; |
515 case 'x': | 616 case 'x': |
516 DCHECK(STRING_STARTS_WITH(format, "imm26x")); | 617 DCHECK(STRING_STARTS_WITH(format, "imm26x")); |
517 PrintXImm26(instr); | 618 PrintXImm26(instr); |
518 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 } |
519 } | 643 } |
520 return 6; | 644 return 6; |
521 } | 645 } |
522 } | 646 } |
523 case 'r': { // 'r: registers. | 647 case 'r': { // 'r: registers. |
524 return FormatRegister(instr, format); | 648 return FormatRegister(instr, format); |
525 } | 649 } |
526 case 'f': { // 'f: FPUregisters. | 650 case 'f': { // 'f: FPUregisters. |
527 return FormatFPURegister(instr, format); | 651 return FormatFPURegister(instr, format); |
528 } | 652 } |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 UNREACHABLE(); | 1475 UNREACHABLE(); |
1352 } | 1476 } |
1353 return Instruction::kInstrSize; | 1477 return Instruction::kInstrSize; |
1354 } | 1478 } |
1355 | 1479 |
1356 | 1480 |
1357 void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) { | 1481 void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) { |
1358 switch (instr->RsFieldRaw()) { | 1482 switch (instr->RsFieldRaw()) { |
1359 case BC1: | 1483 case BC1: |
1360 if (instr->FBtrueValue()) { | 1484 if (instr->FBtrueValue()) { |
1361 Format(instr, "bc1t 'bc, 'imm16u"); | 1485 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); |
1362 } else { | 1486 } else { |
1363 Format(instr, "bc1f 'bc, 'imm16u"); | 1487 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); |
1364 } | 1488 } |
1365 break; | 1489 break; |
1366 case BC1EQZ: | 1490 case BC1EQZ: |
1367 Format(instr, "bc1eqz 'ft, 'imm16u"); | 1491 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); |
1368 break; | 1492 break; |
1369 case BC1NEZ: | 1493 case BC1NEZ: |
1370 Format(instr, "bc1nez 'ft, 'imm16u"); | 1494 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); |
1371 break; | 1495 break; |
1372 default: | 1496 default: |
1373 UNREACHABLE(); | 1497 UNREACHABLE(); |
1374 } | 1498 } |
1375 } | 1499 } |
1376 | 1500 |
1377 | 1501 |
1378 void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) { | 1502 void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) { |
1379 switch (instr->RtFieldRaw()) { | 1503 switch (instr->RtFieldRaw()) { |
1380 case BLTZ: | 1504 case BLTZ: |
1381 Format(instr, "bltz 'rs, 'imm16u"); | 1505 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); |
1382 break; | 1506 break; |
1383 case BLTZAL: | 1507 case BLTZAL: |
1384 Format(instr, "bltzal 'rs, 'imm16u"); | 1508 Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2"); |
1385 break; | 1509 break; |
1386 case BGEZ: | 1510 case BGEZ: |
1387 Format(instr, "bgez 'rs, 'imm16u"); | 1511 Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); |
1388 break; | 1512 break; |
1389 case BGEZAL: | 1513 case BGEZAL: |
1390 Format(instr, "bgezal 'rs, 'imm16u"); | 1514 Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); |
1391 break; | 1515 break; |
1392 case BGEZALL: | 1516 case BGEZALL: |
1393 Format(instr, "bgezall 'rs, 'imm16u"); | 1517 Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); |
1394 break; | 1518 break; |
1395 case DAHI: | 1519 case DAHI: |
1396 Format(instr, "dahi 'rs, 'imm16u"); | 1520 Format(instr, "dahi 'rs, 'imm16u"); |
1397 break; | 1521 break; |
1398 case DATI: | 1522 case DATI: |
1399 Format(instr, "dati 'rs, 'imm16u"); | 1523 Format(instr, "dati 'rs, 'imm16u"); |
1400 break; | 1524 break; |
1401 default: | 1525 default: |
1402 UNREACHABLE(); | 1526 UNREACHABLE(); |
1403 } | 1527 } |
1404 } | 1528 } |
1405 | 1529 |
1406 | 1530 |
1407 void Decoder::DecodeTypeImmediate(Instruction* instr) { | 1531 void Decoder::DecodeTypeImmediate(Instruction* instr) { |
1408 switch (instr->OpcodeFieldRaw()) { | 1532 switch (instr->OpcodeFieldRaw()) { |
1409 case COP1: | 1533 case COP1: |
1410 DecodeTypeImmediateCOP1(instr); | 1534 DecodeTypeImmediateCOP1(instr); |
1411 break; // Case COP1. | 1535 break; // Case COP1. |
1412 // ------------- REGIMM class. | 1536 // ------------- REGIMM class. |
1413 case REGIMM: | 1537 case REGIMM: |
1414 | 1538 DecodeTypeImmediateREGIMM(instr); |
1415 break; // Case REGIMM. | 1539 break; // Case REGIMM. |
1416 // ------------- Branch instructions. | 1540 // ------------- Branch instructions. |
1417 case BEQ: | 1541 case BEQ: |
1418 Format(instr, "beq 'rs, 'rt, 'imm16u"); | 1542 Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1419 break; | 1543 break; |
1420 case BC: | 1544 case BC: |
1421 Format(instr, "bc 'imm26s"); | 1545 Format(instr, "bc 'imm26s -> 'imm26p4s2"); |
1422 break; | 1546 break; |
1423 case BALC: | 1547 case BALC: |
1424 Format(instr, "balc 'imm26s"); | 1548 Format(instr, "balc 'imm26s -> 'imm26p4s2"); |
1425 break; | 1549 break; |
1426 case BNE: | 1550 case BNE: |
1427 Format(instr, "bne 'rs, 'rt, 'imm16u"); | 1551 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1428 break; | 1552 break; |
1429 case BLEZ: | 1553 case BLEZ: |
1430 if ((instr->RtFieldRaw() == 0) | 1554 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
1431 && (instr->RsFieldRaw() != 0)) { | 1555 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); |
1432 Format(instr, "blez 'rs, 'imm16u"); | 1556 } else if ((instr->RtValue() != instr->RsValue()) && |
1433 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1557 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1434 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1558 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1435 Format(instr, "bgeuc 'rs, 'rt, 'imm16u"); | 1559 } else if ((instr->RtValue() == instr->RsValue()) && |
1436 } else if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1560 (instr->RtValue() != 0)) { |
1437 && (instr->RtFieldRaw() != 0)) { | 1561 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); |
1438 Format(instr, "bgezalc 'rs, 'imm16u"); | 1562 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1439 } else if ((instr->RsFieldRaw() == 0) | 1563 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); |
1440 && (instr->RtFieldRaw() != 0)) { | |
1441 Format(instr, "blezalc 'rs, 'imm16u"); | |
1442 } else { | 1564 } else { |
1443 UNREACHABLE(); | 1565 UNREACHABLE(); |
1444 } | 1566 } |
1445 break; | 1567 break; |
1446 case BGTZ: | 1568 case BGTZ: |
1447 if ((instr->RtFieldRaw() == 0) | 1569 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
1448 && (instr->RsFieldRaw() != 0)) { | 1570 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); |
1449 Format(instr, "bgtz 'rs, 'imm16u"); | 1571 } else if ((instr->RtValue() != instr->RsValue()) && |
1450 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1572 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1451 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1573 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1452 Format(instr, "bltuc 'rs, 'rt, 'imm16u"); | 1574 } else if ((instr->RtValue() == instr->RsValue()) && |
1453 } else if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1575 (instr->RtValue() != 0)) { |
1454 && (instr->RtFieldRaw() != 0)) { | 1576 Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2"); |
1455 Format(instr, "bltzalc 'rt, 'imm16u"); | 1577 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1456 } else if ((instr->RsFieldRaw() == 0) | 1578 Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2"); |
1457 && (instr->RtFieldRaw() != 0)) { | |
1458 Format(instr, "bgtzalc 'rt, 'imm16u"); | |
1459 } else { | 1579 } else { |
1460 UNREACHABLE(); | 1580 UNREACHABLE(); |
1461 } | 1581 } |
1462 break; | 1582 break; |
1463 case BLEZL: | 1583 case BLEZL: |
1464 if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1584 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { |
1465 && (instr->RtFieldRaw() != 0)) { | 1585 Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2"); |
1466 Format(instr, "bgezc 'rt, 'imm16u"); | 1586 } else if ((instr->RtValue() != instr->RsValue()) && |
1467 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1587 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1468 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1588 Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1469 Format(instr, "bgec 'rs, 'rt, 'imm16u"); | 1589 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1470 } else if ((instr->RsFieldRaw() == 0) | 1590 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); |
1471 && (instr->RtFieldRaw() != 0)) { | |
1472 Format(instr, "blezc 'rt, 'imm16u"); | |
1473 } else { | 1591 } else { |
1474 UNREACHABLE(); | 1592 UNREACHABLE(); |
1475 } | 1593 } |
1476 break; | 1594 break; |
1477 case BGTZL: | 1595 case BGTZL: |
1478 if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1596 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { |
1479 && (instr->RtFieldRaw() != 0)) { | 1597 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); |
1480 Format(instr, "bltzc 'rt, 'imm16u"); | 1598 } else if ((instr->RtValue() != instr->RsValue()) && |
1481 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1599 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1482 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1600 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1483 Format(instr, "bltc 'rs, 'rt, 'imm16u"); | 1601 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1484 } else if ((instr->RsFieldRaw() == 0) | 1602 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); |
1485 && (instr->RtFieldRaw() != 0)) { | |
1486 Format(instr, "bgtzc 'rt, 'imm16u"); | |
1487 } else { | 1603 } else { |
1488 UNREACHABLE(); | 1604 UNREACHABLE(); |
1489 } | 1605 } |
1490 break; | 1606 break; |
1491 case POP66: | 1607 case POP66: |
1492 if (instr->RsValue() == JIC) { | 1608 if (instr->RsValue() == JIC) { |
1493 Format(instr, "jic 'rt, 'imm16s"); | 1609 Format(instr, "jic 'rt, 'imm16s"); |
1494 } else { | 1610 } else { |
1495 Format(instr, "beqzc 'rs, 'imm21x"); | 1611 Format(instr, "beqzc 'rs, 'imm21x -> 'imm21p4s2"); |
1496 } | 1612 } |
1497 break; | 1613 break; |
1498 case POP76: | 1614 case POP76: |
1499 if (instr->RsValue() == JIALC) { | 1615 if (instr->RsValue() == JIALC) { |
1500 Format(instr, "jialc 'rt, 'imm16x"); | 1616 Format(instr, "jialc 'rt, 'imm16x"); |
1501 } else { | 1617 } else { |
1502 Format(instr, "bnezc 'rs, 'imm21x"); | 1618 Format(instr, "bnezc 'rs, 'imm21x -> 'imm21p4s2"); |
1503 } | 1619 } |
1504 break; | 1620 break; |
1505 // ------------- Arithmetic instructions. | 1621 // ------------- Arithmetic instructions. |
1506 case ADDI: | 1622 case ADDI: |
1507 if (kArchVariant != kMips64r6) { | 1623 if (kArchVariant != kMips64r6) { |
1508 Format(instr, "addi 'rt, 'rs, 'imm16s"); | 1624 Format(instr, "addi 'rt, 'rs, 'imm16s"); |
1509 } else { | 1625 } else { |
1510 // Check if BOVC or BEQC instruction. | 1626 // Check if BOVC or BEQC instruction. |
1511 if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { | 1627 if (instr->RsValue() >= instr->RtValue()) { |
1512 Format(instr, "bovc 'rs, 'rt, 'imm16s"); | 1628 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1513 } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) { | 1629 } else if (instr->RsValue() < instr->RtValue()) { |
1514 Format(instr, "beqc 'rs, 'rt, 'imm16s"); | 1630 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1515 } else { | 1631 } else { |
1516 UNREACHABLE(); | 1632 UNREACHABLE(); |
1517 } | 1633 } |
1518 } | 1634 } |
1519 break; | 1635 break; |
1520 case DADDI: | 1636 case DADDI: |
1521 if (kArchVariant != kMips64r6) { | 1637 if (kArchVariant != kMips64r6) { |
1522 Format(instr, "daddi 'rt, 'rs, 'imm16s"); | 1638 Format(instr, "daddi 'rt, 'rs, 'imm16s"); |
1523 } else { | 1639 } else { |
1524 // Check if BNVC or BNEC instruction. | 1640 // Check if BNVC or BNEC instruction. |
1525 if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { | 1641 if (instr->RsValue() >= instr->RtValue()) { |
1526 Format(instr, "bnvc 'rs, 'rt, 'imm16s"); | 1642 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1527 } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) { | 1643 } else if (instr->RsValue() < instr->RtValue()) { |
1528 Format(instr, "bnec 'rs, 'rt, 'imm16s"); | 1644 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1529 } else { | 1645 } else { |
1530 UNREACHABLE(); | 1646 UNREACHABLE(); |
1531 } | 1647 } |
1532 } | 1648 } |
1533 break; | 1649 break; |
1534 case ADDIU: | 1650 case ADDIU: |
1535 Format(instr, "addiu 'rt, 'rs, 'imm16s"); | 1651 Format(instr, "addiu 'rt, 'rs, 'imm16s"); |
1536 break; | 1652 break; |
1537 case DADDIU: | 1653 case DADDIU: |
1538 Format(instr, "daddiu 'rt, 'rs, 'imm16s"); | 1654 Format(instr, "daddiu 'rt, 'rs, 'imm16s"); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 printf("a 0x%x \n", instr->OpcodeFieldRaw()); | 1796 printf("a 0x%x \n", instr->OpcodeFieldRaw()); |
1681 UNREACHABLE(); | 1797 UNREACHABLE(); |
1682 break; | 1798 break; |
1683 } | 1799 } |
1684 } | 1800 } |
1685 | 1801 |
1686 | 1802 |
1687 void Decoder::DecodeTypeJump(Instruction* instr) { | 1803 void Decoder::DecodeTypeJump(Instruction* instr) { |
1688 switch (instr->OpcodeFieldRaw()) { | 1804 switch (instr->OpcodeFieldRaw()) { |
1689 case J: | 1805 case J: |
1690 Format(instr, "j 'imm26x"); | 1806 Format(instr, "j 'imm26x -> 'imm26j"); |
1691 break; | 1807 break; |
1692 case JAL: | 1808 case JAL: |
1693 Format(instr, "jal 'imm26x"); | 1809 Format(instr, "jal 'imm26x -> 'imm26j"); |
1694 break; | 1810 break; |
1695 default: | 1811 default: |
1696 UNREACHABLE(); | 1812 UNREACHABLE(); |
1697 } | 1813 } |
1698 } | 1814 } |
1699 | 1815 |
1700 | 1816 |
1701 // Disassemble the instruction at *instr_ptr into the output buffer. | 1817 // Disassemble the instruction at *instr_ptr into the output buffer. |
1702 // All instructions are one word long, except for the simulator | 1818 // All instructions are one word long, except for the simulator |
1703 // psuedo-instruction stop(msg). For that one special case, we return | 1819 // psuedo-instruction stop(msg). For that one special case, we return |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1921 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1806 } | 1922 } |
1807 } | 1923 } |
1808 | 1924 |
1809 | 1925 |
1810 #undef UNSUPPORTED | 1926 #undef UNSUPPORTED |
1811 | 1927 |
1812 } // namespace disasm | 1928 } // namespace disasm |
1813 | 1929 |
1814 #endif // V8_TARGET_ARCH_MIPS64 | 1930 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |