Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Side by Side Diff: src/x64/disasm-x64.cc

Issue 151603004: A64: Synchronize with r16587. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/version.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 325
326 virtual ~DisassemblerX64() { 326 virtual ~DisassemblerX64() {
327 } 327 }
328 328
329 // Writes one disassembled instruction into 'buffer' (0-terminated). 329 // Writes one disassembled instruction into 'buffer' (0-terminated).
330 // Returns the length of the disassembled machine instruction in bytes. 330 // Returns the length of the disassembled machine instruction in bytes.
331 int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction); 331 int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction);
332 332
333 private: 333 private:
334 enum OperandSize { 334 enum OperandSize {
335 BYTE_SIZE = 0, 335 OPERAND_BYTE_SIZE = 0,
336 WORD_SIZE = 1, 336 OPERAND_WORD_SIZE = 1,
337 DOUBLEWORD_SIZE = 2, 337 OPERAND_DOUBLEWORD_SIZE = 2,
338 QUADWORD_SIZE = 3 338 OPERAND_QUADWORD_SIZE = 3
339 }; 339 };
340 340
341 const NameConverter& converter_; 341 const NameConverter& converter_;
342 v8::internal::EmbeddedVector<char, 128> tmp_buffer_; 342 v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
343 unsigned int tmp_buffer_pos_; 343 unsigned int tmp_buffer_pos_;
344 bool abort_on_unimplemented_; 344 bool abort_on_unimplemented_;
345 // Prefixes parsed 345 // Prefixes parsed
346 byte rex_; 346 byte rex_;
347 byte operand_size_; // 0x66 or (if no group 3 prefix is present) 0x0. 347 byte operand_size_; // 0x66 or (if no group 3 prefix is present) 0x0.
348 byte group_1_prefix_; // 0xF2, 0xF3, or (if no group 1 prefix is present) 0. 348 byte group_1_prefix_; // 0xF2, 0xF3, or (if no group 1 prefix is present) 0.
(...skipping 13 matching lines...) Expand all
362 // Actual number of base register given the low bits and the rex.b state. 362 // Actual number of base register given the low bits and the rex.b state.
363 int base_reg(int low_bits) { return low_bits | ((rex_ & 0x01) << 3); } 363 int base_reg(int low_bits) { return low_bits | ((rex_ & 0x01) << 3); }
364 364
365 bool rex_x() { return (rex_ & 0x02) != 0; } 365 bool rex_x() { return (rex_ & 0x02) != 0; }
366 366
367 bool rex_r() { return (rex_ & 0x04) != 0; } 367 bool rex_r() { return (rex_ & 0x04) != 0; }
368 368
369 bool rex_w() { return (rex_ & 0x08) != 0; } 369 bool rex_w() { return (rex_ & 0x08) != 0; }
370 370
371 OperandSize operand_size() { 371 OperandSize operand_size() {
372 if (byte_size_operand_) return BYTE_SIZE; 372 if (byte_size_operand_) return OPERAND_BYTE_SIZE;
373 if (rex_w()) return QUADWORD_SIZE; 373 if (rex_w()) return OPERAND_QUADWORD_SIZE;
374 if (operand_size_ != 0) return WORD_SIZE; 374 if (operand_size_ != 0) return OPERAND_WORD_SIZE;
375 return DOUBLEWORD_SIZE; 375 return OPERAND_DOUBLEWORD_SIZE;
376 } 376 }
377 377
378 char operand_size_code() { 378 char operand_size_code() {
379 return "bwlq"[operand_size()]; 379 return "bwlq"[operand_size()];
380 } 380 }
381 381
382 const char* NameOfCPURegister(int reg) const { 382 const char* NameOfCPURegister(int reg) const {
383 return converter_.NameOfCPURegister(reg); 383 return converter_.NameOfCPURegister(reg);
384 } 384 }
385 385
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 return 1; 555 return 1;
556 } 556 }
557 UNREACHABLE(); 557 UNREACHABLE();
558 } 558 }
559 559
560 560
561 int DisassemblerX64::PrintImmediate(byte* data, OperandSize size) { 561 int DisassemblerX64::PrintImmediate(byte* data, OperandSize size) {
562 int64_t value; 562 int64_t value;
563 int count; 563 int count;
564 switch (size) { 564 switch (size) {
565 case BYTE_SIZE: 565 case OPERAND_BYTE_SIZE:
566 value = *data; 566 value = *data;
567 count = 1; 567 count = 1;
568 break; 568 break;
569 case WORD_SIZE: 569 case OPERAND_WORD_SIZE:
570 value = *reinterpret_cast<int16_t*>(data); 570 value = *reinterpret_cast<int16_t*>(data);
571 count = 2; 571 count = 2;
572 break; 572 break;
573 case DOUBLEWORD_SIZE: 573 case OPERAND_DOUBLEWORD_SIZE:
574 value = *reinterpret_cast<uint32_t*>(data); 574 value = *reinterpret_cast<uint32_t*>(data);
575 count = 4; 575 count = 4;
576 break; 576 break;
577 case QUADWORD_SIZE: 577 case OPERAND_QUADWORD_SIZE:
578 value = *reinterpret_cast<int32_t*>(data); 578 value = *reinterpret_cast<int32_t*>(data);
579 count = 4; 579 count = 4;
580 break; 580 break;
581 default: 581 default:
582 UNREACHABLE(); 582 UNREACHABLE();
583 value = 0; // Initialize variables on all paths to satisfy the compiler. 583 value = 0; // Initialize variables on all paths to satisfy the compiler.
584 count = 0; 584 count = 0;
585 } 585 }
586 AppendToBuffer("%" V8_PTR_PREFIX "x", value); 586 AppendToBuffer("%" V8_PTR_PREFIX "x", value);
587 return count; 587 return count;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 break; 675 break;
676 case 7: 676 case 7:
677 mnem = "cmp"; 677 mnem = "cmp";
678 break; 678 break;
679 default: 679 default:
680 UnimplementedInstruction(); 680 UnimplementedInstruction();
681 } 681 }
682 AppendToBuffer("%s%c ", mnem, operand_size_code()); 682 AppendToBuffer("%s%c ", mnem, operand_size_code());
683 int count = PrintRightOperand(data + 1); 683 int count = PrintRightOperand(data + 1);
684 AppendToBuffer(",0x"); 684 AppendToBuffer(",0x");
685 OperandSize immediate_size = byte_size_immediate ? BYTE_SIZE : operand_size(); 685 OperandSize immediate_size =
686 byte_size_immediate ? OPERAND_BYTE_SIZE : operand_size();
686 count += PrintImmediate(data + 1 + count, immediate_size); 687 count += PrintImmediate(data + 1 + count, immediate_size);
687 return 1 + count; 688 return 1 + count;
688 } 689 }
689 690
690 691
691 // Returns number of bytes used, including *data. 692 // Returns number of bytes used, including *data.
692 int DisassemblerX64::F6F7Instruction(byte* data) { 693 int DisassemblerX64::F6F7Instruction(byte* data) {
693 ASSERT(*data == 0xF7 || *data == 0xF6); 694 ASSERT(*data == 0xF7 || *data == 0xF6);
694 byte modrm = *(data + 1); 695 byte modrm = *(data + 1);
695 int mod, regop, rm; 696 int mod, regop, rm;
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 case 0x1F: 1313 case 0x1F:
1313 return "nop"; 1314 return "nop";
1314 case 0x2A: // F2/F3 prefix. 1315 case 0x2A: // F2/F3 prefix.
1315 return "cvtsi2s"; 1316 return "cvtsi2s";
1316 case 0x51: // F2 prefix. 1317 case 0x51: // F2 prefix.
1317 return "sqrtsd"; 1318 return "sqrtsd";
1318 case 0x58: // F2 prefix. 1319 case 0x58: // F2 prefix.
1319 return "addsd"; 1320 return "addsd";
1320 case 0x59: // F2 prefix. 1321 case 0x59: // F2 prefix.
1321 return "mulsd"; 1322 return "mulsd";
1323 case 0x5A: // F2 prefix.
1324 return "cvtsd2ss";
1322 case 0x5C: // F2 prefix. 1325 case 0x5C: // F2 prefix.
1323 return "subsd"; 1326 return "subsd";
1324 case 0x5E: // F2 prefix. 1327 case 0x5E: // F2 prefix.
1325 return "divsd"; 1328 return "divsd";
1326 case 0xA2: 1329 case 0xA2:
1327 return "cpuid"; 1330 return "cpuid";
1328 case 0xA5: 1331 case 0xA5:
1329 return "shld"; 1332 return "shld";
1330 case 0xAB: 1333 case 0xAB:
1331 return "bts"; 1334 return "bts";
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 break; 1411 break;
1409 case PUSHPOP_INSTR: 1412 case PUSHPOP_INSTR:
1410 AppendToBuffer("%s %s", 1413 AppendToBuffer("%s %s",
1411 idesc.mnem, 1414 idesc.mnem,
1412 NameOfCPURegister(base_reg(current & 0x07))); 1415 NameOfCPURegister(base_reg(current & 0x07)));
1413 data++; 1416 data++;
1414 break; 1417 break;
1415 case MOVE_REG_INSTR: { 1418 case MOVE_REG_INSTR: {
1416 byte* addr = NULL; 1419 byte* addr = NULL;
1417 switch (operand_size()) { 1420 switch (operand_size()) {
1418 case WORD_SIZE: 1421 case OPERAND_WORD_SIZE:
1419 addr = reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1)); 1422 addr = reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1));
1420 data += 3; 1423 data += 3;
1421 break; 1424 break;
1422 case DOUBLEWORD_SIZE: 1425 case OPERAND_DOUBLEWORD_SIZE:
1423 addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1)); 1426 addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
1424 data += 5; 1427 data += 5;
1425 break; 1428 break;
1426 case QUADWORD_SIZE: 1429 case OPERAND_QUADWORD_SIZE:
1427 addr = reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1)); 1430 addr = reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1));
1428 data += 9; 1431 data += 9;
1429 break; 1432 break;
1430 default: 1433 default:
1431 UNREACHABLE(); 1434 UNREACHABLE();
1432 } 1435 }
1433 AppendToBuffer("mov%c %s,%s", 1436 AppendToBuffer("mov%c %s,%s",
1434 operand_size_code(), 1437 operand_size_code(),
1435 NameOfCPURegister(base_reg(current & 0x07)), 1438 NameOfCPURegister(base_reg(current & 0x07)),
1436 NameOfAddress(addr)); 1439 NameOfAddress(addr));
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 case 0xBF: { 1624 case 0xBF: {
1622 // mov reg8,imm8 or mov reg32,imm32 1625 // mov reg8,imm8 or mov reg32,imm32
1623 byte opcode = *data; 1626 byte opcode = *data;
1624 data++; 1627 data++;
1625 bool is_32bit = (opcode >= 0xB8); 1628 bool is_32bit = (opcode >= 0xB8);
1626 int reg = (opcode & 0x7) | (rex_b() ? 8 : 0); 1629 int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
1627 if (is_32bit) { 1630 if (is_32bit) {
1628 AppendToBuffer("mov%c %s, ", 1631 AppendToBuffer("mov%c %s, ",
1629 operand_size_code(), 1632 operand_size_code(),
1630 NameOfCPURegister(reg)); 1633 NameOfCPURegister(reg));
1631 data += PrintImmediate(data, DOUBLEWORD_SIZE); 1634 data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE);
1632 } else { 1635 } else {
1633 AppendToBuffer("movb %s, ", 1636 AppendToBuffer("movb %s, ",
1634 NameOfByteCPURegister(reg)); 1637 NameOfByteCPURegister(reg));
1635 data += PrintImmediate(data, BYTE_SIZE); 1638 data += PrintImmediate(data, OPERAND_BYTE_SIZE);
1636 } 1639 }
1637 break; 1640 break;
1638 } 1641 }
1639 case 0xFE: { 1642 case 0xFE: {
1640 data++; 1643 data++;
1641 int mod, regop, rm; 1644 int mod, regop, rm;
1642 get_modrm(*data, &mod, &regop, &rm); 1645 get_modrm(*data, &mod, &regop, &rm);
1643 if (regop == 1) { 1646 if (regop == 1) {
1644 AppendToBuffer("decb "); 1647 AppendToBuffer("decb ");
1645 data += PrintRightByteOperand(data); 1648 data += PrintRightByteOperand(data);
1646 } else { 1649 } else {
1647 UnimplementedInstruction(); 1650 UnimplementedInstruction();
1648 } 1651 }
1649 break; 1652 break;
1650 } 1653 }
1651 case 0x68: 1654 case 0x68:
1652 AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1)); 1655 AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1));
1653 data += 5; 1656 data += 5;
1654 break; 1657 break;
1655 1658
1656 case 0x6A: 1659 case 0x6A:
1657 AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); 1660 AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1));
1658 data += 2; 1661 data += 2;
1659 break; 1662 break;
1660 1663
1661 case 0xA1: // Fall through. 1664 case 0xA1: // Fall through.
1662 case 0xA3: 1665 case 0xA3:
1663 switch (operand_size()) { 1666 switch (operand_size()) {
1664 case DOUBLEWORD_SIZE: { 1667 case OPERAND_DOUBLEWORD_SIZE: {
1665 const char* memory_location = NameOfAddress( 1668 const char* memory_location = NameOfAddress(
1666 reinterpret_cast<byte*>( 1669 reinterpret_cast<byte*>(
1667 *reinterpret_cast<int32_t*>(data + 1))); 1670 *reinterpret_cast<int32_t*>(data + 1)));
1668 if (*data == 0xA1) { // Opcode 0xA1 1671 if (*data == 0xA1) { // Opcode 0xA1
1669 AppendToBuffer("movzxlq rax,(%s)", memory_location); 1672 AppendToBuffer("movzxlq rax,(%s)", memory_location);
1670 } else { // Opcode 0xA3 1673 } else { // Opcode 0xA3
1671 AppendToBuffer("movzxlq (%s),rax", memory_location); 1674 AppendToBuffer("movzxlq (%s),rax", memory_location);
1672 } 1675 }
1673 data += 5; 1676 data += 5;
1674 break; 1677 break;
1675 } 1678 }
1676 case QUADWORD_SIZE: { 1679 case OPERAND_QUADWORD_SIZE: {
1677 // New x64 instruction mov rax,(imm_64). 1680 // New x64 instruction mov rax,(imm_64).
1678 const char* memory_location = NameOfAddress( 1681 const char* memory_location = NameOfAddress(
1679 *reinterpret_cast<byte**>(data + 1)); 1682 *reinterpret_cast<byte**>(data + 1));
1680 if (*data == 0xA1) { // Opcode 0xA1 1683 if (*data == 0xA1) { // Opcode 0xA1
1681 AppendToBuffer("movq rax,(%s)", memory_location); 1684 AppendToBuffer("movq rax,(%s)", memory_location);
1682 } else { // Opcode 0xA3 1685 } else { // Opcode 0xA3
1683 AppendToBuffer("movq (%s),rax", memory_location); 1686 AppendToBuffer("movq (%s),rax", memory_location);
1684 } 1687 }
1685 data += 9; 1688 data += 9;
1686 break; 1689 break;
1687 } 1690 }
1688 default: 1691 default:
1689 UnimplementedInstruction(); 1692 UnimplementedInstruction();
1690 data += 2; 1693 data += 2;
1691 } 1694 }
1692 break; 1695 break;
1693 1696
1694 case 0xA8: 1697 case 0xA8:
1695 AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data + 1)); 1698 AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data + 1));
1696 data += 2; 1699 data += 2;
1697 break; 1700 break;
1698 1701
1699 case 0xA9: { 1702 case 0xA9: {
1700 int64_t value = 0; 1703 int64_t value = 0;
1701 switch (operand_size()) { 1704 switch (operand_size()) {
1702 case WORD_SIZE: 1705 case OPERAND_WORD_SIZE:
1703 value = *reinterpret_cast<uint16_t*>(data + 1); 1706 value = *reinterpret_cast<uint16_t*>(data + 1);
1704 data += 3; 1707 data += 3;
1705 break; 1708 break;
1706 case DOUBLEWORD_SIZE: 1709 case OPERAND_DOUBLEWORD_SIZE:
1707 value = *reinterpret_cast<uint32_t*>(data + 1); 1710 value = *reinterpret_cast<uint32_t*>(data + 1);
1708 data += 5; 1711 data += 5;
1709 break; 1712 break;
1710 case QUADWORD_SIZE: 1713 case OPERAND_QUADWORD_SIZE:
1711 value = *reinterpret_cast<int32_t*>(data + 1); 1714 value = *reinterpret_cast<int32_t*>(data + 1);
1712 data += 5; 1715 data += 5;
1713 break; 1716 break;
1714 default: 1717 default:
1715 UNREACHABLE(); 1718 UNREACHABLE();
1716 } 1719 }
1717 AppendToBuffer("test%c rax,0x%" V8_PTR_PREFIX "x", 1720 AppendToBuffer("test%c rax,0x%" V8_PTR_PREFIX "x",
1718 operand_size_code(), 1721 operand_size_code(),
1719 value); 1722 value);
1720 break; 1723 break;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { 1885 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) {
1883 fprintf(f, " "); 1886 fprintf(f, " ");
1884 } 1887 }
1885 fprintf(f, " %s\n", buffer.start()); 1888 fprintf(f, " %s\n", buffer.start());
1886 } 1889 }
1887 } 1890 }
1888 1891
1889 } // namespace disasm 1892 } // namespace disasm
1890 1893
1891 #endif // V8_TARGET_ARCH_X64 1894 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/version.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698