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 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 switch (regop) { | 627 switch (regop) { |
628 case 2: | 628 case 2: |
629 mnem = "not"; | 629 mnem = "not"; |
630 break; | 630 break; |
631 case 3: | 631 case 3: |
632 mnem = "neg"; | 632 mnem = "neg"; |
633 break; | 633 break; |
634 case 4: | 634 case 4: |
635 mnem = "mul"; | 635 mnem = "mul"; |
636 break; | 636 break; |
| 637 case 6: |
| 638 mnem = "div"; |
| 639 break; |
637 case 7: | 640 case 7: |
638 mnem = "idiv"; | 641 mnem = "idiv"; |
639 break; | 642 break; |
640 default: | 643 default: |
641 UnimplementedInstruction(); | 644 UnimplementedInstruction(); |
642 } | 645 } |
643 AppendToBuffer("%s%c %s", | 646 AppendToBuffer("%s%c %s", |
644 mnem, | 647 mnem, |
645 operand_size_code(), | 648 operand_size_code(), |
646 NameOfCPURegister(rm)); | 649 NameOfCPURegister(rm)); |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 | 1515 |
1513 } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 || | 1516 } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 || |
1514 opcode == 0xB7 || opcode == 0xAF) { | 1517 opcode == 0xB7 || opcode == 0xAF) { |
1515 // Size-extending moves, IMUL. | 1518 // Size-extending moves, IMUL. |
1516 current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current); | 1519 current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current); |
1517 | 1520 |
1518 } else if ((opcode & 0xF0) == 0x90) { | 1521 } else if ((opcode & 0xF0) == 0x90) { |
1519 // SETcc: Set byte on condition. Needs pointer to beginning of instruction. | 1522 // SETcc: Set byte on condition. Needs pointer to beginning of instruction. |
1520 current = data + SetCC(data); | 1523 current = data + SetCC(data); |
1521 | 1524 |
1522 } else if (opcode == 0xAB || opcode == 0xA5 || opcode == 0xAD) { | 1525 } else if ((opcode & 0xFE) == 0xA4 || (opcode & 0xFE) == 0xAC || |
1523 // SHLD, SHRD (double-precision shift), BTS (bit set). | 1526 opcode == 0xAB || opcode == 0xA3) { |
1524 AppendToBuffer("%s ", mnemonic); | 1527 // SHLD, SHRD (double-prec. shift), BTS (bit test and set), BT (bit test). |
| 1528 AppendToBuffer("%s%c ", mnemonic, operand_size_code()); |
1525 int mod, regop, rm; | 1529 int mod, regop, rm; |
1526 get_modrm(*current, &mod, ®op, &rm); | 1530 get_modrm(*current, &mod, ®op, &rm); |
1527 current += PrintRightOperand(current); | 1531 current += PrintRightOperand(current); |
1528 if (opcode == 0xAB) { | 1532 AppendToBuffer(",%s", NameOfCPURegister(regop)); |
1529 AppendToBuffer(",%s", NameOfCPURegister(regop)); | 1533 if (opcode == 0xAB || opcode == 0xA3) { |
| 1534 // Done. |
| 1535 } else if (opcode == 0xA5 || opcode == 0xAD) { |
| 1536 AppendToBuffer(",cl"); |
1530 } else { | 1537 } else { |
1531 AppendToBuffer(",%s,cl", NameOfCPURegister(regop)); | 1538 AppendToBuffer(","); |
| 1539 current += PrintImmediate(current, BYTE_SIZE); |
1532 } | 1540 } |
1533 } else { | 1541 } else { |
1534 UnimplementedInstruction(); | 1542 UnimplementedInstruction(); |
1535 } | 1543 } |
1536 return static_cast<int>(current - data); | 1544 return static_cast<int>(current - data); |
1537 } | 1545 } |
1538 | 1546 |
1539 | 1547 |
1540 // Mnemonics for two-byte opcode instructions starting with 0x0F. | 1548 // Mnemonics for two-byte opcode instructions starting with 0x0F. |
1541 // The argument is the second byte of the two-byte opcode. | 1549 // The argument is the second byte of the two-byte opcode. |
(...skipping 11 matching lines...) Expand all Loading... |
1553 case 0x58: // F2 prefix. | 1561 case 0x58: // F2 prefix. |
1554 return "addsd"; | 1562 return "addsd"; |
1555 case 0x59: // F2 prefix. | 1563 case 0x59: // F2 prefix. |
1556 return "mulsd"; | 1564 return "mulsd"; |
1557 case 0x5C: // F2 prefix. | 1565 case 0x5C: // F2 prefix. |
1558 return "subsd"; | 1566 return "subsd"; |
1559 case 0x5E: // F2 prefix. | 1567 case 0x5E: // F2 prefix. |
1560 return "divsd"; | 1568 return "divsd"; |
1561 case 0xA2: | 1569 case 0xA2: |
1562 return "cpuid"; | 1570 return "cpuid"; |
| 1571 case 0xA3: |
| 1572 return "bt"; |
| 1573 case 0xA4: |
1563 case 0xA5: | 1574 case 0xA5: |
1564 return "shld"; | 1575 return "shld"; |
1565 case 0xAB: | 1576 case 0xAB: |
1566 return "bts"; | 1577 return "bts"; |
| 1578 case 0xAC: |
1567 case 0xAD: | 1579 case 0xAD: |
1568 return "shrd"; | 1580 return "shrd"; |
1569 case 0xAF: | 1581 case 0xAF: |
1570 return "imul"; | 1582 return "imul"; |
1571 case 0xB6: | 1583 case 0xB6: |
1572 return "movzxb"; | 1584 return "movzxb"; |
1573 case 0xB7: | 1585 case 0xB7: |
1574 return "movzxw"; | 1586 return "movzxw"; |
1575 case 0xBE: | 1587 case 0xBE: |
1576 return "movsxb"; | 1588 return "movsxb"; |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 pc); | 1979 pc); |
1968 pc += instruction_length; | 1980 pc += instruction_length; |
1969 } | 1981 } |
1970 | 1982 |
1971 return; | 1983 return; |
1972 } | 1984 } |
1973 | 1985 |
1974 } // namespace dart | 1986 } // namespace dart |
1975 | 1987 |
1976 #endif // defined TARGET_ARCH_X64 | 1988 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |