| 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_IA32) | 8 #if defined(TARGET_ARCH_IA32) |
| 9 #include "platform/utils.h" | 9 #include "platform/utils.h" |
| 10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 const char* mnem; | 28 const char* mnem; |
| 29 OperandOrder op_order_; | 29 OperandOrder op_order_; |
| 30 }; | 30 }; |
| 31 | 31 |
| 32 | 32 |
| 33 static ByteMnemonic two_operands_instr[] = { | 33 static ByteMnemonic two_operands_instr[] = { |
| 34 {0x01, "add", OPER_REG_OP_ORDER}, | 34 {0x01, "add", OPER_REG_OP_ORDER}, |
| 35 {0x03, "add", REG_OPER_OP_ORDER}, | 35 {0x03, "add", REG_OPER_OP_ORDER}, |
| 36 {0x09, "or", OPER_REG_OP_ORDER}, | 36 {0x09, "or", OPER_REG_OP_ORDER}, |
| 37 {0x0B, "or", REG_OPER_OP_ORDER}, | 37 {0x0B, "or", REG_OPER_OP_ORDER}, |
| 38 {0x11, "adc", OPER_REG_OP_ORDER}, |
| 38 {0x13, "adc", REG_OPER_OP_ORDER}, | 39 {0x13, "adc", REG_OPER_OP_ORDER}, |
| 40 {0x19, "sbb", OPER_REG_OP_ORDER}, |
| 39 {0x1B, "sbb", REG_OPER_OP_ORDER}, | 41 {0x1B, "sbb", REG_OPER_OP_ORDER}, |
| 40 {0x21, "and", OPER_REG_OP_ORDER}, | 42 {0x21, "and", OPER_REG_OP_ORDER}, |
| 41 {0x23, "and", REG_OPER_OP_ORDER}, | 43 {0x23, "and", REG_OPER_OP_ORDER}, |
| 42 {0x29, "sub", OPER_REG_OP_ORDER}, | 44 {0x29, "sub", OPER_REG_OP_ORDER}, |
| 43 {0x2B, "sub", REG_OPER_OP_ORDER}, | 45 {0x2B, "sub", REG_OPER_OP_ORDER}, |
| 44 {0x31, "xor", OPER_REG_OP_ORDER}, | 46 {0x31, "xor", OPER_REG_OP_ORDER}, |
| 45 {0x33, "xor", REG_OPER_OP_ORDER}, | 47 {0x33, "xor", REG_OPER_OP_ORDER}, |
| 46 {0x39, "cmp", OPER_REG_OP_ORDER}, | 48 {0x39, "cmp", OPER_REG_OP_ORDER}, |
| 47 {0x3B, "cmp", REG_OPER_OP_ORDER}, | 49 {0x3B, "cmp", REG_OPER_OP_ORDER}, |
| 48 {0x85, "test", REG_OPER_OP_ORDER}, | 50 {0x85, "test", REG_OPER_OP_ORDER}, |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 int PrintOperands(const char* mnem, OperandOrder op_order, uint8_t* data); | 298 int PrintOperands(const char* mnem, OperandOrder op_order, uint8_t* data); |
| 297 int PrintImmediateOp(uint8_t* data); | 299 int PrintImmediateOp(uint8_t* data); |
| 298 | 300 |
| 299 // Handle special encodings. | 301 // Handle special encodings. |
| 300 int JumpShort(uint8_t* data); | 302 int JumpShort(uint8_t* data); |
| 301 int JumpConditional(uint8_t* data, const char* comment); | 303 int JumpConditional(uint8_t* data, const char* comment); |
| 302 int JumpConditionalShort(uint8_t* data, const char* comment); | 304 int JumpConditionalShort(uint8_t* data, const char* comment); |
| 303 int SetCC(uint8_t* data); | 305 int SetCC(uint8_t* data); |
| 304 int CMov(uint8_t* data); | 306 int CMov(uint8_t* data); |
| 305 int D1D3C1Instruction(uint8_t* data); | 307 int D1D3C1Instruction(uint8_t* data); |
| 308 uint8_t* F3Instruction(uint8_t* data); |
| 306 int F7Instruction(uint8_t* data); | 309 int F7Instruction(uint8_t* data); |
| 307 int FPUInstruction(uint8_t* data); | 310 int FPUInstruction(uint8_t* data); |
| 308 int BitwisePDInstruction(uint8_t* data); | 311 int BitwisePDInstruction(uint8_t* data); |
| 309 int Packed660F38Instruction(uint8_t* data); | 312 int Packed660F38Instruction(uint8_t* data); |
| 310 int DecodeEnter(uint8_t* data); | 313 int DecodeEnter(uint8_t* data); |
| 311 void CheckPrintStop(uint8_t* data); | 314 void CheckPrintStop(uint8_t* data); |
| 312 | 315 |
| 313 // Disassembler helper functions. | 316 // Disassembler helper functions. |
| 314 static void GetModRm(uint8_t data, int* mod, int* regop, int* rm) { | 317 static void GetModRm(uint8_t data, int* mod, int* regop, int* rm) { |
| 315 *mod = (data >> 6) & 3; | 318 *mod = (data >> 6) & 3; |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 } else { | 804 } else { |
| 802 Print("cl"); | 805 Print("cl"); |
| 803 } | 806 } |
| 804 } else { | 807 } else { |
| 805 UNIMPLEMENTED(); | 808 UNIMPLEMENTED(); |
| 806 } | 809 } |
| 807 return num_bytes; | 810 return num_bytes; |
| 808 } | 811 } |
| 809 | 812 |
| 810 | 813 |
| 814 uint8_t* X86Decoder::F3Instruction(uint8_t* data) { |
| 815 if (*(data+1) == 0x0F) { |
| 816 uint8_t b2 = *(data+2); |
| 817 switch (b2) { |
| 818 case 0x2C: { |
| 819 data += 3; |
| 820 data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data); |
| 821 break; |
| 822 } |
| 823 case 0x2A: { |
| 824 data += 3; |
| 825 int mod, regop, rm; |
| 826 GetModRm(*data, &mod, ®op, &rm); |
| 827 Print("cvtsi2ss "); |
| 828 PrintXmmRegister(regop); |
| 829 Print(","); |
| 830 data += PrintRightOperand(data); |
| 831 break; |
| 832 } |
| 833 case 0x2D: { |
| 834 data += 3; |
| 835 int mod, regop, rm; |
| 836 GetModRm(*data, &mod, ®op, &rm); |
| 837 Print("cvtss2si "); |
| 838 PrintCPURegister(regop); |
| 839 Print(","); |
| 840 data += PrintRightXmmOperand(data); |
| 841 break; |
| 842 } |
| 843 case 0x11: { |
| 844 // movss xmm <- address |
| 845 Print("movss "); |
| 846 data += 3; |
| 847 int mod, regop, rm; |
| 848 GetModRm(*data, &mod, ®op, &rm); |
| 849 data += PrintRightXmmOperand(data); |
| 850 Print(","); |
| 851 PrintXmmRegister(regop); |
| 852 break; |
| 853 } |
| 854 case 0x10: { |
| 855 // movss address <- xmm |
| 856 data += 3; |
| 857 int mod, regop, rm; |
| 858 GetModRm(*data, &mod, ®op, &rm); |
| 859 Print("movss "); |
| 860 PrintXmmRegister(regop); |
| 861 Print(","); |
| 862 data += PrintRightOperand(data); |
| 863 break; |
| 864 } |
| 865 case 0x51: // Fall through. |
| 866 case 0x58: // Fall through. |
| 867 case 0x59: // Fall through. |
| 868 case 0x5A: // Fall through. |
| 869 case 0x5C: // Fall through. |
| 870 case 0x5E: // Fall through. |
| 871 case 0xE6: { |
| 872 // divss xmm, xmm |
| 873 data += 3; |
| 874 int mod, regop, rm; |
| 875 GetModRm(*data, &mod, ®op, &rm); |
| 876 const char* mnem = "?? 0xF3"; |
| 877 switch (b2) { |
| 878 case 0x51: mnem = "sqrtss"; break; |
| 879 case 0x58: mnem = "addss"; break; |
| 880 case 0x59: mnem = "mulss"; break; |
| 881 case 0x5A: mnem = "cvtss2sd"; break; |
| 882 case 0x5C: mnem = "subss"; break; |
| 883 case 0x5E: mnem = "divss"; break; |
| 884 case 0xE6: mnem = "cvtdq2pd"; break; |
| 885 default: UNIMPLEMENTED(); |
| 886 } |
| 887 Print(mnem); |
| 888 Print(" "); |
| 889 PrintXmmRegister(regop); |
| 890 Print(","); |
| 891 data += PrintRightXmmOperand(data); |
| 892 break; |
| 893 } |
| 894 case 0x7E: { |
| 895 data += 3; |
| 896 int mod, regop, rm; |
| 897 GetModRm(*data, &mod, ®op, &rm); |
| 898 Print("movq "); |
| 899 PrintXmmRegister(regop); |
| 900 Print(","); |
| 901 data += PrintRightOperand(data); |
| 902 break; |
| 903 } |
| 904 default: |
| 905 UNIMPLEMENTED(); |
| 906 } |
| 907 } |
| 908 return data; |
| 909 } |
| 910 |
| 911 |
| 811 // Returns number of bytes used, including *data. | 912 // Returns number of bytes used, including *data. |
| 812 int X86Decoder::F7Instruction(uint8_t* data) { | 913 int X86Decoder::F7Instruction(uint8_t* data) { |
| 813 ASSERT(*data == 0xF7); | 914 ASSERT(*data == 0xF7); |
| 814 uint8_t modrm = *(data+1); | 915 uint8_t modrm = *(data+1); |
| 815 int mod, regop, rm; | 916 int mod, regop, rm; |
| 816 GetModRm(modrm, &mod, ®op, &rm); | 917 GetModRm(modrm, &mod, ®op, &rm); |
| 817 if (mod == 3 && regop != 0) { | 918 if (mod == 3 && regop != 0) { |
| 818 const char* mnem = NULL; | 919 const char* mnem = NULL; |
| 819 switch (regop) { | 920 switch (regop) { |
| 820 case 2: mnem = "not"; break; | 921 case 2: mnem = "not"; break; |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 data++; | 1466 data++; |
| 1366 } else if (*data == 0X7E) { | 1467 } else if (*data == 0X7E) { |
| 1367 data++; | 1468 data++; |
| 1368 int mod, regop, rm; | 1469 int mod, regop, rm; |
| 1369 GetModRm(*data, &mod, ®op, &rm); | 1470 GetModRm(*data, &mod, ®op, &rm); |
| 1370 Print("movd "); | 1471 Print("movd "); |
| 1371 PrintCPURegister(rm); | 1472 PrintCPURegister(rm); |
| 1372 Print(","); | 1473 Print(","); |
| 1373 PrintXmmRegister(regop); | 1474 PrintXmmRegister(regop); |
| 1374 data++; | 1475 data++; |
| 1476 } else if (*data == 0xD6) { |
| 1477 data++; |
| 1478 int mod, regop, rm; |
| 1479 GetModRm(*data, &mod, ®op, &rm); |
| 1480 Print("movq "); |
| 1481 data += PrintRightOperand(data); |
| 1482 Print(","); |
| 1483 PrintXmmRegister(regop); |
| 1375 } else if (*data == 0x57 || *data == 0x56 || *data == 0x54) { | 1484 } else if (*data == 0x57 || *data == 0x56 || *data == 0x54) { |
| 1376 data += BitwisePDInstruction(data); | 1485 data += BitwisePDInstruction(data); |
| 1377 } else if (*data == 0x1F && | 1486 } else if (*data == 0x1F && |
| 1378 *(data+1) == 0x44 && | 1487 *(data+1) == 0x44 && |
| 1379 *(data+2) == 0x00 && | 1488 *(data+2) == 0x00 && |
| 1380 *(data+3) == 0x00) { | 1489 *(data+3) == 0x00) { |
| 1381 data += 4; | 1490 data += 4; |
| 1382 Print("nop"); | 1491 Print("nop"); |
| 1383 } else if (*data == 0x50) { | 1492 } else if (*data == 0x50) { |
| 1384 Print("movmskpd "); | 1493 Print("movmskpd "); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1466 case 0xDE: // fall through | 1575 case 0xDE: // fall through |
| 1467 case 0xDF: | 1576 case 0xDF: |
| 1468 data += FPUInstruction(data); | 1577 data += FPUInstruction(data); |
| 1469 break; | 1578 break; |
| 1470 | 1579 |
| 1471 case 0xEB: | 1580 case 0xEB: |
| 1472 data += JumpShort(data); | 1581 data += JumpShort(data); |
| 1473 break; | 1582 break; |
| 1474 | 1583 |
| 1475 case 0xF3: | 1584 case 0xF3: |
| 1476 if (*(data+1) == 0x0F) { | 1585 data = F3Instruction(data); |
| 1477 uint8_t b2 = *(data+2); | |
| 1478 switch (b2) { | |
| 1479 case 0x2C: { | |
| 1480 data += 3; | |
| 1481 data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data); | |
| 1482 break; | |
| 1483 } | |
| 1484 case 0x2A: { | |
| 1485 data += 3; | |
| 1486 int mod, regop, rm; | |
| 1487 GetModRm(*data, &mod, ®op, &rm); | |
| 1488 Print("cvtsi2ss "); | |
| 1489 PrintXmmRegister(regop); | |
| 1490 Print(","); | |
| 1491 data += PrintRightOperand(data); | |
| 1492 break; | |
| 1493 } | |
| 1494 case 0x2D: { | |
| 1495 data += 3; | |
| 1496 int mod, regop, rm; | |
| 1497 GetModRm(*data, &mod, ®op, &rm); | |
| 1498 Print("cvtss2si "); | |
| 1499 PrintCPURegister(regop); | |
| 1500 Print(","); | |
| 1501 data += PrintRightXmmOperand(data); | |
| 1502 break; | |
| 1503 } | |
| 1504 case 0x11: { | |
| 1505 // movss xmm <- address | |
| 1506 Print("movss "); | |
| 1507 data += 3; | |
| 1508 int mod, regop, rm; | |
| 1509 GetModRm(*data, &mod, ®op, &rm); | |
| 1510 data += PrintRightXmmOperand(data); | |
| 1511 Print(","); | |
| 1512 PrintXmmRegister(regop); | |
| 1513 break; | |
| 1514 } | |
| 1515 case 0x10: { | |
| 1516 // movss address <- xmm | |
| 1517 data += 3; | |
| 1518 int mod, regop, rm; | |
| 1519 GetModRm(*data, &mod, ®op, &rm); | |
| 1520 Print("movss "); | |
| 1521 PrintXmmRegister(regop); | |
| 1522 Print(","); | |
| 1523 data += PrintRightOperand(data); | |
| 1524 break; | |
| 1525 } | |
| 1526 case 0x51: // Fall through. | |
| 1527 case 0x58: // Fall through. | |
| 1528 case 0x59: // Fall through. | |
| 1529 case 0x5A: // Fall through. | |
| 1530 case 0x5C: // Fall through. | |
| 1531 case 0x5E: // Fall through. | |
| 1532 case 0xE6: { | |
| 1533 // divss xmm, xmm | |
| 1534 data += 3; | |
| 1535 int mod, regop, rm; | |
| 1536 GetModRm(*data, &mod, ®op, &rm); | |
| 1537 const char* mnem = "?? 0xF3"; | |
| 1538 switch (b2) { | |
| 1539 case 0x51: mnem = "sqrtss"; break; | |
| 1540 case 0x58: mnem = "addss"; break; | |
| 1541 case 0x59: mnem = "mulss"; break; | |
| 1542 case 0x5A: mnem = "cvtss2sd"; break; | |
| 1543 case 0x5C: mnem = "subss"; break; | |
| 1544 case 0x5E: mnem = "divss"; break; | |
| 1545 case 0xE6: mnem = "cvtdq2pd"; break; | |
| 1546 default: UNIMPLEMENTED(); | |
| 1547 } | |
| 1548 Print(mnem); | |
| 1549 Print(" "); | |
| 1550 PrintXmmRegister(regop); | |
| 1551 Print(","); | |
| 1552 data += PrintRightXmmOperand(data); | |
| 1553 break; | |
| 1554 } | |
| 1555 default: | |
| 1556 UNIMPLEMENTED(); | |
| 1557 } | |
| 1558 } | |
| 1559 break; | 1586 break; |
| 1560 case 0xF2: { | 1587 case 0xF2: { |
| 1561 if (*(data+1) == 0x0F) { | 1588 if (*(data+1) == 0x0F) { |
| 1562 uint8_t b2 = *(data+2); | 1589 uint8_t b2 = *(data+2); |
| 1563 if (b2 == 0x11) { | 1590 if (b2 == 0x11) { |
| 1564 Print("movsd "); | 1591 Print("movsd "); |
| 1565 data += 3; | 1592 data += 3; |
| 1566 int mod, regop, rm; | 1593 int mod, regop, rm; |
| 1567 GetModRm(*data, &mod, ®op, &rm); | 1594 GetModRm(*data, &mod, ®op, &rm); |
| 1568 data += PrintRightXmmOperand(data); | 1595 data += PrintRightXmmOperand(data); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1685 human_buffer, | 1712 human_buffer, |
| 1686 sizeof(human_buffer), | 1713 sizeof(human_buffer), |
| 1687 pc); | 1714 pc); |
| 1688 pc += instruction_length; | 1715 pc += instruction_length; |
| 1689 } | 1716 } |
| 1690 } | 1717 } |
| 1691 | 1718 |
| 1692 } // namespace dart | 1719 } // namespace dart |
| 1693 | 1720 |
| 1694 #endif // defined TARGET_ARCH_IA32 | 1721 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |