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 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 | 366 |
367 const char* NameOfByteCPURegister(int reg) const { | 367 const char* NameOfByteCPURegister(int reg) const { |
368 return NameOfCPURegister(reg); | 368 return NameOfCPURegister(reg); |
369 } | 369 } |
370 | 370 |
371 const char* NameOfXMMRegister(int reg) const { | 371 const char* NameOfXMMRegister(int reg) const { |
372 ASSERT((0 <= reg) && (reg < kMaxXmmRegisters)); | 372 ASSERT((0 <= reg) && (reg < kMaxXmmRegisters)); |
373 return xmm_regs[reg]; | 373 return xmm_regs[reg]; |
374 } | 374 } |
375 | 375 |
376 void AppendToBuffer(const char* format, ...); | 376 void AppendToBuffer(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
377 void AppendAddressToBuffer(uint8_t* addr); | 377 void AppendAddressToBuffer(uint8_t* addr); |
378 | 378 |
379 int PrintOperands(const char* mnem, | 379 int PrintOperands(const char* mnem, |
380 OperandType op_order, | 380 OperandType op_order, |
381 uint8_t* data); | 381 uint8_t* data); |
382 | 382 |
383 typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; | 383 typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; |
384 | 384 |
385 int PrintRightOperandHelper(uint8_t* modrmp, | 385 int PrintRightOperandHelper(uint8_t* modrmp, |
386 RegisterNameMapping register_name); | 386 RegisterNameMapping register_name); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 uint8_t* modrmp, | 439 uint8_t* modrmp, |
440 RegisterNameMapping direct_register_name) { | 440 RegisterNameMapping direct_register_name) { |
441 int mod, regop, rm; | 441 int mod, regop, rm; |
442 get_modrm(*modrmp, &mod, ®op, &rm); | 442 get_modrm(*modrmp, &mod, ®op, &rm); |
443 RegisterNameMapping register_name = (mod == 3) ? direct_register_name : | 443 RegisterNameMapping register_name = (mod == 3) ? direct_register_name : |
444 &DisassemblerX64::NameOfCPURegister; | 444 &DisassemblerX64::NameOfCPURegister; |
445 switch (mod) { | 445 switch (mod) { |
446 case 0: | 446 case 0: |
447 if ((rm & 7) == 5) { | 447 if ((rm & 7) == 5) { |
448 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); | 448 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); |
449 AppendToBuffer("[0x%x]", disp); | 449 AppendToBuffer("[%#x]", disp); |
450 return 5; | 450 return 5; |
451 } else if ((rm & 7) == 4) { | 451 } else if ((rm & 7) == 4) { |
452 // Codes for SIB byte. | 452 // Codes for SIB byte. |
453 uint8_t sib = *(modrmp + 1); | 453 uint8_t sib = *(modrmp + 1); |
454 int scale, index, base; | 454 int scale, index, base; |
455 get_sib(sib, &scale, &index, &base); | 455 get_sib(sib, &scale, &index, &base); |
456 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { | 456 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { |
457 // index == rsp means no index. Only use sib byte with no index for | 457 // index == rsp means no index. Only use sib byte with no index for |
458 // rsp and r12 base. | 458 // rsp and r12 base. |
459 AppendToBuffer("[%s]", NameOfCPURegister(base)); | 459 AppendToBuffer("[%s]", NameOfCPURegister(base)); |
460 return 2; | 460 return 2; |
461 } else if (base == 5) { | 461 } else if (base == 5) { |
462 // base == rbp means no base register (when mod == 0). | 462 // base == rbp means no base register (when mod == 0). |
463 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); | 463 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); |
464 AppendToBuffer("[%s*%d+0x%x]", | 464 AppendToBuffer("[%s*%d+%#x]", |
465 NameOfCPURegister(index), | 465 NameOfCPURegister(index), |
466 1 << scale, disp); | 466 1 << scale, disp); |
467 return 6; | 467 return 6; |
468 } else if (index != 4 && base != 5) { | 468 } else if (index != 4 && base != 5) { |
469 // [base+index*scale] | 469 // [base+index*scale] |
470 AppendToBuffer("[%s+%s*%d]", | 470 AppendToBuffer("[%s+%s*%d]", |
471 NameOfCPURegister(base), | 471 NameOfCPURegister(base), |
472 NameOfCPURegister(index), | 472 NameOfCPURegister(index), |
473 1 << scale); | 473 1 << scale); |
474 return 2; | 474 return 2; |
475 } else { | 475 } else { |
476 UnimplementedInstruction(); | 476 UnimplementedInstruction(); |
477 return 1; | 477 return 1; |
478 } | 478 } |
479 } else { | 479 } else { |
480 AppendToBuffer("[%s]", NameOfCPURegister(rm)); | 480 AppendToBuffer("[%s]", NameOfCPURegister(rm)); |
481 return 1; | 481 return 1; |
482 } | 482 } |
483 break; | 483 break; |
484 case 1: // fall through | 484 case 1: // fall through |
485 case 2: | 485 case 2: |
486 if ((rm & 7) == 4) { | 486 if ((rm & 7) == 4) { |
487 uint8_t sib = *(modrmp + 1); | 487 uint8_t sib = *(modrmp + 1); |
488 int scale, index, base; | 488 int scale, index, base; |
489 get_sib(sib, &scale, &index, &base); | 489 get_sib(sib, &scale, &index, &base); |
490 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2) | 490 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2) |
491 : *reinterpret_cast<char*>(modrmp + 2); | 491 : *reinterpret_cast<char*>(modrmp + 2); |
492 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { | 492 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { |
493 if (-disp > 0) { | 493 if (-disp > 0) { |
494 AppendToBuffer("[%s-0x%x]", NameOfCPURegister(base), -disp); | 494 AppendToBuffer("[%s-%#x]", NameOfCPURegister(base), -disp); |
495 } else { | 495 } else { |
496 AppendToBuffer("[%s+0x%x]", NameOfCPURegister(base), disp); | 496 AppendToBuffer("[%s+%#x]", NameOfCPURegister(base), disp); |
497 } | 497 } |
498 } else { | 498 } else { |
499 if (-disp > 0) { | 499 if (-disp > 0) { |
500 AppendToBuffer("[%s+%s*%d-0x%x]", | 500 AppendToBuffer("[%s+%s*%d-%#x]", |
501 NameOfCPURegister(base), | 501 NameOfCPURegister(base), |
502 NameOfCPURegister(index), | 502 NameOfCPURegister(index), |
503 1 << scale, | 503 1 << scale, |
504 -disp); | 504 -disp); |
505 } else { | 505 } else { |
506 AppendToBuffer("[%s+%s*%d+0x%x]", | 506 AppendToBuffer("[%s+%s*%d+%#x]", |
507 NameOfCPURegister(base), | 507 NameOfCPURegister(base), |
508 NameOfCPURegister(index), | 508 NameOfCPURegister(index), |
509 1 << scale, | 509 1 << scale, |
510 disp); | 510 disp); |
511 } | 511 } |
512 } | 512 } |
513 return mod == 2 ? 6 : 3; | 513 return mod == 2 ? 6 : 3; |
514 } else { | 514 } else { |
515 // No sib. | 515 // No sib. |
516 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) | 516 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) |
517 : *reinterpret_cast<char*>(modrmp + 1); | 517 : *reinterpret_cast<char*>(modrmp + 1); |
518 if (-disp > 0) { | 518 if (-disp > 0) { |
519 AppendToBuffer("[%s-0x%x]", NameOfCPURegister(rm), -disp); | 519 AppendToBuffer("[%s-%#x]", NameOfCPURegister(rm), -disp); |
520 } else { | 520 } else { |
521 AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp); | 521 AppendToBuffer("[%s+%#x]", NameOfCPURegister(rm), disp); |
522 } | 522 } |
523 return (mod == 2) ? 5 : 2; | 523 return (mod == 2) ? 5 : 2; |
524 } | 524 } |
525 break; | 525 break; |
526 case 3: | 526 case 3: |
527 AppendToBuffer("%s", (this->*register_name)(rm)); | 527 AppendToBuffer("%s", (this->*register_name)(rm)); |
528 return 1; | 528 return 1; |
529 default: | 529 default: |
530 UnimplementedInstruction(); | 530 UnimplementedInstruction(); |
531 return 1; | 531 return 1; |
(...skipping 20 matching lines...) Expand all Loading... |
552 break; | 552 break; |
553 case QUADWORD_SIZE: | 553 case QUADWORD_SIZE: |
554 value = *reinterpret_cast<int32_t*>(data); | 554 value = *reinterpret_cast<int32_t*>(data); |
555 count = 4; | 555 count = 4; |
556 break; | 556 break; |
557 default: | 557 default: |
558 UNREACHABLE(); | 558 UNREACHABLE(); |
559 value = 0; // Initialize variables on all paths to satisfy the compiler. | 559 value = 0; // Initialize variables on all paths to satisfy the compiler. |
560 count = 0; | 560 count = 0; |
561 } | 561 } |
562 AppendToBuffer("%"PRIxPTR, value); | 562 AppendToBuffer("%#"Px"", value); |
563 return count; | 563 return count; |
564 } | 564 } |
565 | 565 |
566 | 566 |
567 // Returns number of bytes used by machine instruction, including *data byte. | 567 // Returns number of bytes used by machine instruction, including *data byte. |
568 // Writes immediate instructions to 'tmp_buffer_'. | 568 // Writes immediate instructions to 'tmp_buffer_'. |
569 int DisassemblerX64::PrintImmediateOp(uint8_t* data) { | 569 int DisassemblerX64::PrintImmediateOp(uint8_t* data) { |
570 bool byte_size_immediate = (*data & 0x02) != 0; | 570 bool byte_size_immediate = (*data & 0x02) != 0; |
571 uint8_t modrm = *(data + 1); | 571 uint8_t modrm = *(data + 1); |
572 int mod, regop, rm; | 572 int mod, regop, rm; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 intptr_t len = OS::SNPrint(NULL, 0, format, full_class_name) + 1; | 790 intptr_t len = OS::SNPrint(NULL, 0, format, full_class_name) + 1; |
791 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 791 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
792 OS::SNPrint(chars, len, format, full_class_name); | 792 OS::SNPrint(chars, len, format, full_class_name); |
793 return chars; | 793 return chars; |
794 } | 794 } |
795 | 795 |
796 | 796 |
797 void DisassemblerX64::AppendAddressToBuffer(uint8_t* addr_byte_ptr) { | 797 void DisassemblerX64::AppendAddressToBuffer(uint8_t* addr_byte_ptr) { |
798 NoGCScope no_gc; | 798 NoGCScope no_gc; |
799 uword addr = reinterpret_cast<uword>(addr_byte_ptr); | 799 uword addr = reinterpret_cast<uword>(addr_byte_ptr); |
800 AppendToBuffer("0x%0"PRIxPTR, addr); | 800 AppendToBuffer("%#"Px"", addr); |
801 // Try to print as heap object or stub name | 801 // Try to print as heap object or stub name |
802 if (!Isolate::Current()->heap()->CodeContains(addr) && | 802 if (!Isolate::Current()->heap()->CodeContains(addr) && |
803 Isolate::Current()->heap()->Contains(addr - kHeapObjectTag)) { | 803 Isolate::Current()->heap()->Contains(addr - kHeapObjectTag)) { |
804 Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr)); | 804 Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr)); |
805 if (obj.IsArray()) { | 805 if (obj.IsArray()) { |
806 const Array& arr = Array::CheckedHandle(obj.raw()); | 806 const Array& arr = Array::CheckedHandle(obj.raw()); |
807 intptr_t len = arr.Length(); | 807 intptr_t len = arr.Length(); |
808 if (len > 5) len = 5; // Print a max of 5 elements. | 808 if (len > 5) len = 5; // Print a max of 5 elements. |
809 AppendToBuffer(" Array["); | 809 AppendToBuffer(" Array["); |
810 int i = 0; | 810 int i = 0; |
811 while (i < len) { | 811 while (i < len) { |
812 obj = arr.At(i); | 812 obj = arr.At(i); |
813 if (i > 0) AppendToBuffer(", "); | 813 if (i > 0) AppendToBuffer(", "); |
814 AppendToBuffer(ObjectToCStringNoGC(obj)); | 814 AppendToBuffer("%s", ObjectToCStringNoGC(obj)); |
815 i++; | 815 i++; |
816 } | 816 } |
817 if (i < arr.Length()) AppendToBuffer(", ..."); | 817 if (i < arr.Length()) AppendToBuffer(", ..."); |
818 AppendToBuffer("]"); | 818 AppendToBuffer("]"); |
819 return; | 819 return; |
820 } | 820 } |
821 AppendToBuffer(" '%s'", ObjectToCStringNoGC(obj)); | 821 AppendToBuffer(" '%s'", ObjectToCStringNoGC(obj)); |
822 } else { | 822 } else { |
823 // 'addr' is not an object, but probably a code address. | 823 // 'addr' is not an object, but probably a code address. |
824 const char* name_of_stub = StubCode::NameOfStub(addr); | 824 const char* name_of_stub = StubCode::NameOfStub(addr); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 if (current >= 0xA4 && current <= 0xA7) { | 1093 if (current >= 0xA4 && current <= 0xA7) { |
1094 // String move or compare operations. | 1094 // String move or compare operations. |
1095 if (group_1_prefix_ == REP_PREFIX) { | 1095 if (group_1_prefix_ == REP_PREFIX) { |
1096 // REP. | 1096 // REP. |
1097 AppendToBuffer("rep "); | 1097 AppendToBuffer("rep "); |
1098 } | 1098 } |
1099 // TODO(srdjan): Should we enable printing of REX.W? | 1099 // TODO(srdjan): Should we enable printing of REX.W? |
1100 // if (rex_w()) AppendToBuffer("REX.W "); | 1100 // if (rex_w()) AppendToBuffer("REX.W "); |
1101 AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); | 1101 AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); |
1102 } else { | 1102 } else { |
1103 AppendToBuffer("%s", idesc.mnem, operand_size_code()); | 1103 AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); |
1104 } | 1104 } |
1105 (*data)++; | 1105 (*data)++; |
1106 break; | 1106 break; |
1107 | 1107 |
1108 case TWO_OPERANDS_INSTR: | 1108 case TWO_OPERANDS_INSTR: |
1109 (*data)++; | 1109 (*data)++; |
1110 (*data) += PrintOperands(idesc.mnem, idesc.op_order_, *data); | 1110 (*data) += PrintOperands(idesc.mnem, idesc.op_order_, *data); |
1111 break; | 1111 break; |
1112 | 1112 |
1113 case JUMP_CONDITIONAL_SHORT_INSTR: | 1113 case JUMP_CONDITIONAL_SHORT_INSTR: |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 | 1489 |
1490 | 1490 |
1491 int DisassemblerX64::InstructionDecode(uword pc) { | 1491 int DisassemblerX64::InstructionDecode(uword pc) { |
1492 uint8_t* data = reinterpret_cast<uint8_t*>(pc); | 1492 uint8_t* data = reinterpret_cast<uint8_t*>(pc); |
1493 | 1493 |
1494 const bool processed = DecodeInstructionType(&data); | 1494 const bool processed = DecodeInstructionType(&data); |
1495 | 1495 |
1496 if (!processed) { | 1496 if (!processed) { |
1497 switch (*data) { | 1497 switch (*data) { |
1498 case 0xC2: | 1498 case 0xC2: |
1499 AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data + 1)); | 1499 AppendToBuffer("ret %#x", *reinterpret_cast<uint16_t*>(data + 1)); |
1500 data += 3; | 1500 data += 3; |
1501 break; | 1501 break; |
1502 | 1502 |
1503 case 0x69: // fall through | 1503 case 0x69: // fall through |
1504 case 0x6B: { | 1504 case 0x6B: { |
1505 int mod, regop, rm; | 1505 int mod, regop, rm; |
1506 get_modrm(*(data + 1), &mod, ®op, &rm); | 1506 get_modrm(*(data + 1), &mod, ®op, &rm); |
1507 int32_t imm = *data == 0x6B ? *(data + 2) | 1507 int32_t imm = *data == 0x6B ? *(data + 2) |
1508 : *reinterpret_cast<int32_t*>(data + 2); | 1508 : *reinterpret_cast<int32_t*>(data + 2); |
1509 AppendToBuffer("imul%c %s,%s,0x%x", | 1509 AppendToBuffer("imul%c %s,%s,%#x", |
1510 operand_size_code(), | 1510 operand_size_code(), |
1511 NameOfCPURegister(regop), | 1511 NameOfCPURegister(regop), |
1512 NameOfCPURegister(rm), imm); | 1512 NameOfCPURegister(rm), imm); |
1513 data += 2 + (*data == 0x6B ? 1 : 4); | 1513 data += 2 + (*data == 0x6B ? 1 : 4); |
1514 break; | 1514 break; |
1515 } | 1515 } |
1516 | 1516 |
1517 case 0x81: // fall through | 1517 case 0x81: // fall through |
1518 case 0x83: // 0x81 with sign extension bit set | 1518 case 0x83: // 0x81 with sign extension bit set |
1519 data += PrintImmediateOp(data); | 1519 data += PrintImmediateOp(data); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 | 1567 |
1568 case 0xC7: // imm32, fall through | 1568 case 0xC7: // imm32, fall through |
1569 case 0xC6: // imm8 | 1569 case 0xC6: // imm8 |
1570 { | 1570 { |
1571 bool is_byte = *data == 0xC6; | 1571 bool is_byte = *data == 0xC6; |
1572 data++; | 1572 data++; |
1573 if (is_byte) { | 1573 if (is_byte) { |
1574 AppendToBuffer("movb "); | 1574 AppendToBuffer("movb "); |
1575 data += PrintRightByteOperand(data); | 1575 data += PrintRightByteOperand(data); |
1576 int32_t imm = *data; | 1576 int32_t imm = *data; |
1577 AppendToBuffer(",0x%x", imm); | 1577 AppendToBuffer(",%#x", imm); |
1578 data++; | 1578 data++; |
1579 } else { | 1579 } else { |
1580 AppendToBuffer("mov%c ", operand_size_code()); | 1580 AppendToBuffer("mov%c ", operand_size_code()); |
1581 data += PrintRightOperand(data); | 1581 data += PrintRightOperand(data); |
1582 int32_t imm = *reinterpret_cast<int32_t*>(data); | 1582 int32_t imm = *reinterpret_cast<int32_t*>(data); |
1583 AppendToBuffer(",0x%x", imm); | 1583 AppendToBuffer(",%#x", imm); |
1584 data += 4; | 1584 data += 4; |
1585 } | 1585 } |
1586 } | 1586 } |
1587 break; | 1587 break; |
1588 | 1588 |
1589 case 0x80: { | 1589 case 0x80: { |
1590 data++; | 1590 data++; |
1591 AppendToBuffer("cmpb "); | 1591 AppendToBuffer("cmpb "); |
1592 data += PrintRightByteOperand(data); | 1592 data += PrintRightByteOperand(data); |
1593 int32_t imm = *data; | 1593 int32_t imm = *data; |
1594 AppendToBuffer(",0x%x", imm); | 1594 AppendToBuffer(",%#x", imm); |
1595 data++; | 1595 data++; |
1596 } | 1596 } |
1597 break; | 1597 break; |
1598 | 1598 |
1599 case 0x88: // 8bit, fall through | 1599 case 0x88: // 8bit, fall through |
1600 case 0x89: // 32bit | 1600 case 0x89: // 32bit |
1601 { | 1601 { |
1602 bool is_byte = *data == 0x88; | 1602 bool is_byte = *data == 0x88; |
1603 int mod, regop, rm; | 1603 int mod, regop, rm; |
1604 data++; | 1604 data++; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1673 get_modrm(*data, &mod, ®op, &rm); | 1673 get_modrm(*data, &mod, ®op, &rm); |
1674 if (regop == 1) { | 1674 if (regop == 1) { |
1675 AppendToBuffer("decb "); | 1675 AppendToBuffer("decb "); |
1676 data += PrintRightByteOperand(data); | 1676 data += PrintRightByteOperand(data); |
1677 } else { | 1677 } else { |
1678 UnimplementedInstruction(); | 1678 UnimplementedInstruction(); |
1679 } | 1679 } |
1680 break; | 1680 break; |
1681 } | 1681 } |
1682 case 0x68: | 1682 case 0x68: |
1683 AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1)); | 1683 AppendToBuffer("push %#x", *reinterpret_cast<int32_t*>(data + 1)); |
1684 data += 5; | 1684 data += 5; |
1685 break; | 1685 break; |
1686 | 1686 |
1687 case 0x6A: | 1687 case 0x6A: |
1688 AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); | 1688 AppendToBuffer("push %#x", *reinterpret_cast<int8_t*>(data + 1)); |
1689 data += 2; | 1689 data += 2; |
1690 break; | 1690 break; |
1691 | 1691 |
1692 case 0xA1: // Fall through. | 1692 case 0xA1: // Fall through. |
1693 case 0xA3: | 1693 case 0xA3: |
1694 switch (operand_size()) { | 1694 switch (operand_size()) { |
1695 case DOUBLEWORD_SIZE: { | 1695 case DOUBLEWORD_SIZE: { |
1696 AppendAddressToBuffer( | 1696 AppendAddressToBuffer( |
1697 reinterpret_cast<uint8_t*>( | 1697 reinterpret_cast<uint8_t*>( |
1698 *reinterpret_cast<int32_t*>(data + 1))); | 1698 *reinterpret_cast<int32_t*>(data + 1))); |
(...skipping 27 matching lines...) Expand all Loading... |
1726 data += 9; | 1726 data += 9; |
1727 break; | 1727 break; |
1728 } | 1728 } |
1729 default: | 1729 default: |
1730 UnimplementedInstruction(); | 1730 UnimplementedInstruction(); |
1731 data += 2; | 1731 data += 2; |
1732 } | 1732 } |
1733 break; | 1733 break; |
1734 | 1734 |
1735 case 0xA8: | 1735 case 0xA8: |
1736 AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data + 1)); | 1736 AppendToBuffer("test al,%#x", *reinterpret_cast<uint8_t*>(data + 1)); |
1737 data += 2; | 1737 data += 2; |
1738 break; | 1738 break; |
1739 | 1739 |
1740 case 0xA9: { | 1740 case 0xA9: { |
1741 int64_t value = 0; | 1741 int64_t value = 0; |
1742 switch (operand_size()) { | 1742 switch (operand_size()) { |
1743 case WORD_SIZE: | 1743 case WORD_SIZE: |
1744 value = *reinterpret_cast<uint16_t*>(data + 1); | 1744 value = *reinterpret_cast<uint16_t*>(data + 1); |
1745 data += 3; | 1745 data += 3; |
1746 break; | 1746 break; |
1747 case DOUBLEWORD_SIZE: | 1747 case DOUBLEWORD_SIZE: |
1748 value = *reinterpret_cast<uint32_t*>(data + 1); | 1748 value = *reinterpret_cast<uint32_t*>(data + 1); |
1749 data += 5; | 1749 data += 5; |
1750 break; | 1750 break; |
1751 case QUADWORD_SIZE: | 1751 case QUADWORD_SIZE: |
1752 value = *reinterpret_cast<int32_t*>(data + 1); | 1752 value = *reinterpret_cast<int32_t*>(data + 1); |
1753 data += 5; | 1753 data += 5; |
1754 break; | 1754 break; |
1755 default: | 1755 default: |
1756 UNREACHABLE(); | 1756 UNREACHABLE(); |
1757 } | 1757 } |
1758 AppendToBuffer("test%c rax,0x%0"PRIxPTR, | 1758 AppendToBuffer("test%c rax,%#"Px"", |
1759 operand_size_code(), | 1759 operand_size_code(), |
1760 value); | 1760 value); |
1761 break; | 1761 break; |
1762 } | 1762 } |
1763 case 0xD1: // fall through | 1763 case 0xD1: // fall through |
1764 case 0xD3: // fall through | 1764 case 0xD3: // fall through |
1765 case 0xC1: | 1765 case 0xC1: |
1766 data += ShiftInstruction(data); | 1766 data += ShiftInstruction(data); |
1767 break; | 1767 break; |
1768 case 0xD0: // fall through | 1768 case 0xD0: // fall through |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1856 human_buffer, | 1856 human_buffer, |
1857 sizeof(human_buffer), | 1857 sizeof(human_buffer), |
1858 pc); | 1858 pc); |
1859 pc += instruction_length; | 1859 pc += instruction_length; |
1860 } | 1860 } |
1861 } | 1861 } |
1862 | 1862 |
1863 } // namespace dart | 1863 } // namespace dart |
1864 | 1864 |
1865 #endif // defined TARGET_ARCH_X64 | 1865 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |