Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/disassembler.h" | 5 #include "vm/disassembler.h" |
| 6 | 6 |
| 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 8 #if defined(TARGET_ARCH_X64) | 8 #if defined(TARGET_ARCH_X64) |
| 9 #include "platform/utils.h" | 9 #include "platform/utils.h" |
| 10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 int PrintOperands(const char* mnem, OperandType op_order, uint8_t* data); | 350 int PrintOperands(const char* mnem, OperandType op_order, uint8_t* data); |
| 351 | 351 |
| 352 typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; | 352 typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; |
| 353 | 353 |
| 354 int PrintRightOperandHelper(uint8_t* modrmp, | 354 int PrintRightOperandHelper(uint8_t* modrmp, |
| 355 RegisterNameMapping register_name); | 355 RegisterNameMapping register_name); |
| 356 int PrintRightOperand(uint8_t* modrmp); | 356 int PrintRightOperand(uint8_t* modrmp); |
| 357 int PrintRightByteOperand(uint8_t* modrmp); | 357 int PrintRightByteOperand(uint8_t* modrmp); |
| 358 int PrintRightXMMOperand(uint8_t* modrmp); | 358 int PrintRightXMMOperand(uint8_t* modrmp); |
| 359 void PrintDisp(int disp, const char* after); | 359 void PrintDisp(int disp, const char* after); |
| 360 int PrintImmediate(uint8_t* data, OperandSize size); | 360 int PrintImmediate(uint8_t* data, OperandSize size, bool sign_extend = false); |
| 361 void PrintImmediateValue(int64_t value); | 361 void PrintImmediateValue(int64_t value, bool signed_value = false); |
| 362 int PrintImmediateOp(uint8_t* data); | 362 int PrintImmediateOp(uint8_t* data); |
| 363 const char* TwoByteMnemonic(uint8_t opcode); | 363 const char* TwoByteMnemonic(uint8_t opcode); |
| 364 int TwoByteOpcodeInstruction(uint8_t* data); | 364 int TwoByteOpcodeInstruction(uint8_t* data); |
| 365 | 365 |
| 366 int F6F7Instruction(uint8_t* data); | 366 int F6F7Instruction(uint8_t* data); |
| 367 int ShiftInstruction(uint8_t* data); | 367 int ShiftInstruction(uint8_t* data); |
| 368 int JumpShort(uint8_t* data); | 368 int JumpShort(uint8_t* data); |
| 369 int JumpConditional(uint8_t* data); | 369 int JumpConditional(uint8_t* data); |
| 370 int JumpConditionalShort(uint8_t* data); | 370 int JumpConditionalShort(uint8_t* data); |
| 371 int SetCC(uint8_t* data); | 371 int SetCC(uint8_t* data); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 485 Print("%s", (this->*register_name)(rm)); | 485 Print("%s", (this->*register_name)(rm)); |
| 486 return 1; | 486 return 1; |
| 487 default: | 487 default: |
| 488 UnimplementedInstruction(); | 488 UnimplementedInstruction(); |
| 489 return 1; | 489 return 1; |
| 490 } | 490 } |
| 491 UNREACHABLE(); | 491 UNREACHABLE(); |
| 492 } | 492 } |
| 493 | 493 |
| 494 | 494 |
| 495 int DisassemblerX64::PrintImmediate(uint8_t* data, OperandSize size) { | 495 int DisassemblerX64::PrintImmediate(uint8_t* data, |
| 496 OperandSize size, | |
| 497 bool sign_extend) { | |
| 496 int64_t value; | 498 int64_t value; |
| 497 int count; | 499 int count; |
| 498 switch (size) { | 500 switch (size) { |
| 499 case BYTE_SIZE: | 501 case BYTE_SIZE: |
| 500 value = *data; | 502 if (sign_extend) { |
| 503 value = *reinterpret_cast<int8_t*>(data); | |
| 504 } else { | |
| 505 value = *data; | |
| 506 } | |
| 501 count = 1; | 507 count = 1; |
| 502 break; | 508 break; |
| 503 case WORD_SIZE: | 509 case WORD_SIZE: |
| 504 value = *reinterpret_cast<int16_t*>(data); | 510 if (sign_extend) { |
| 511 value = *reinterpret_cast<int16_t*>(data); | |
| 512 } else { | |
| 513 value = *reinterpret_cast<uint16_t*>(data); | |
| 514 } | |
| 505 count = 2; | 515 count = 2; |
| 506 break; | 516 break; |
| 507 case DOUBLEWORD_SIZE: | 517 case DOUBLEWORD_SIZE: |
| 508 value = *reinterpret_cast<uint32_t*>(data); | |
| 509 count = 4; | |
| 510 break; | |
| 511 case QUADWORD_SIZE: | 518 case QUADWORD_SIZE: |
| 512 value = *reinterpret_cast<int32_t*>(data); | 519 if (sign_extend) { |
| 520 value = *reinterpret_cast<int32_t*>(data); | |
| 521 } else { | |
| 522 value = *reinterpret_cast<uint32_t*>(data); | |
| 523 } | |
| 513 count = 4; | 524 count = 4; |
| 514 break; | 525 break; |
| 515 default: | 526 default: |
| 516 UNREACHABLE(); | 527 UNREACHABLE(); |
| 517 value = 0; // Initialize variables on all paths to satisfy the compiler. | 528 value = 0; // Initialize variables on all paths to satisfy the compiler. |
| 518 count = 0; | 529 count = 0; |
| 519 } | 530 } |
| 520 PrintImmediateValue(value); | 531 PrintImmediateValue(value, sign_extend); |
| 521 return count; | 532 return count; |
| 522 } | 533 } |
| 523 | 534 |
| 524 void DisassemblerX64::PrintImmediateValue(int64_t value) { | 535 void DisassemblerX64::PrintImmediateValue(int64_t value, bool signed_value) { |
| 525 if ((value >= 0) && (value <= 9)) { | 536 if ((value >= 0) && (value <= 9)) { |
|
sra1
2017/03/15 17:09:54
It is nice that 1 prints as "1" and not "0x1"
Perh
| |
| 526 Print("%" Pd64 "", value); | 537 Print("%" Pd64 "", value); |
| 527 } else { | 538 } else { |
| 528 Print("%#" Px64 "", value); | 539 if (value < 0 && signed_value) { |
| 540 Print("-%#" Px64 "", -value); | |
| 541 } else { | |
| 542 Print("%#" Px64 "", value); | |
| 543 } | |
| 529 } | 544 } |
| 530 } | 545 } |
| 531 | 546 |
| 532 void DisassemblerX64::PrintDisp(int disp, const char* after) { | 547 void DisassemblerX64::PrintDisp(int disp, const char* after) { |
| 533 if (-disp > 0) { | 548 if (-disp > 0) { |
| 534 Print("-%#x", -disp); | 549 Print("-%#x", -disp); |
| 535 } else { | 550 } else { |
| 536 Print("+%#x", disp); | 551 Print("+%#x", disp); |
| 537 } | 552 } |
| 538 if (after != NULL) Print("%s", after); | 553 if (after != NULL) Print("%s", after); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 case 7: | 587 case 7: |
| 573 mnem = "cmp"; | 588 mnem = "cmp"; |
| 574 break; | 589 break; |
| 575 default: | 590 default: |
| 576 UnimplementedInstruction(); | 591 UnimplementedInstruction(); |
| 577 } | 592 } |
| 578 Print("%s%c ", mnem, operand_size_code()); | 593 Print("%s%c ", mnem, operand_size_code()); |
| 579 int count = PrintRightOperand(data + 1); | 594 int count = PrintRightOperand(data + 1); |
| 580 Print(","); | 595 Print(","); |
| 581 OperandSize immediate_size = byte_size_immediate ? BYTE_SIZE : operand_size(); | 596 OperandSize immediate_size = byte_size_immediate ? BYTE_SIZE : operand_size(); |
| 582 count += PrintImmediate(data + 1 + count, immediate_size); | 597 count += |
| 598 PrintImmediate(data + 1 + count, immediate_size, byte_size_immediate); | |
| 583 return 1 + count; | 599 return 1 + count; |
| 584 } | 600 } |
| 585 | 601 |
| 586 | 602 |
| 587 // Returns number of bytes used, including *data. | 603 // Returns number of bytes used, including *data. |
| 588 int DisassemblerX64::F6F7Instruction(uint8_t* data) { | 604 int DisassemblerX64::F6F7Instruction(uint8_t* data) { |
| 589 ASSERT(*data == 0xF7 || *data == 0xF6); | 605 ASSERT(*data == 0xF7 || *data == 0xF6); |
| 590 uint8_t modrm = *(data + 1); | 606 uint8_t modrm = *(data + 1); |
| 591 int mod, regop, rm; | 607 int mod, regop, rm; |
| 592 get_modrm(modrm, &mod, ®op, &rm); | 608 get_modrm(modrm, &mod, ®op, &rm); |
| (...skipping 1367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1960 *object = NULL; | 1976 *object = NULL; |
| 1961 } | 1977 } |
| 1962 } | 1978 } |
| 1963 } | 1979 } |
| 1964 | 1980 |
| 1965 #endif // !PRODUCT | 1981 #endif // !PRODUCT |
| 1966 | 1982 |
| 1967 } // namespace dart | 1983 } // namespace dart |
| 1968 | 1984 |
| 1969 #endif // defined TARGET_ARCH_X64 | 1985 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |