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 |