OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <assert.h> | 5 #include <assert.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #if V8_TARGET_ARCH_X64 | 9 #if V8_TARGET_ARCH_X64 |
10 | 10 |
11 #include "src/base/compiler-specific.h" | 11 #include "src/base/compiler-specific.h" |
12 #include "src/base/lazy-instance.h" | 12 #include "src/base/lazy-instance.h" |
13 #include "src/disasm.h" | 13 #include "src/disasm.h" |
| 14 #include "src/x64/sse-instr.h" |
14 | 15 |
15 namespace disasm { | 16 namespace disasm { |
16 | 17 |
17 enum OperandType { | 18 enum OperandType { |
18 UNSET_OP_ORDER = 0, | 19 UNSET_OP_ORDER = 0, |
19 // Operand size decides between 16, 32 and 64 bit operands. | 20 // Operand size decides between 16, 32 and 64 bit operands. |
20 REG_OPER_OP_ORDER = 1, // Register destination, operand source. | 21 REG_OPER_OP_ORDER = 1, // Register destination, operand source. |
21 OPER_REG_OP_ORDER = 2, // Operand destination, register source. | 22 OPER_REG_OP_ORDER = 2, // Operand destination, register source. |
22 // Fixed 8-bit operands. | 23 // Fixed 8-bit operands. |
23 BYTE_SIZE_OPERAND_FLAG = 4, | 24 BYTE_SIZE_OPERAND_FLAG = 4, |
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 // Returns number of bytes used, including *data. | 869 // Returns number of bytes used, including *data. |
869 int DisassemblerX64::SetCC(byte* data) { | 870 int DisassemblerX64::SetCC(byte* data) { |
870 DCHECK_EQ(0x0F, *data); | 871 DCHECK_EQ(0x0F, *data); |
871 byte cond = *(data + 1) & 0x0F; | 872 byte cond = *(data + 1) & 0x0F; |
872 const char* mnem = conditional_code_suffix[cond]; | 873 const char* mnem = conditional_code_suffix[cond]; |
873 AppendToBuffer("set%s%c ", mnem, operand_size_code()); | 874 AppendToBuffer("set%s%c ", mnem, operand_size_code()); |
874 PrintRightByteOperand(data + 2); | 875 PrintRightByteOperand(data + 2); |
875 return 3; // includes 0x0F | 876 return 3; // includes 0x0F |
876 } | 877 } |
877 | 878 |
| 879 const char* sf_str[4] = {"", "rl", "ra", "ll"}; |
878 | 880 |
879 int DisassemblerX64::AVXInstruction(byte* data) { | 881 int DisassemblerX64::AVXInstruction(byte* data) { |
880 byte opcode = *data; | 882 byte opcode = *data; |
881 byte* current = data + 1; | 883 byte* current = data + 1; |
882 if (vex_66() && vex_0f38()) { | 884 if (vex_66() && vex_0f38()) { |
883 int mod, regop, rm, vvvv = vex_vreg(); | 885 int mod, regop, rm, vvvv = vex_vreg(); |
884 get_modrm(*current, &mod, ®op, &rm); | 886 get_modrm(*current, &mod, ®op, &rm); |
885 switch (opcode) { | 887 switch (opcode) { |
886 case 0x99: | 888 case 0x99: |
887 AppendToBuffer("vfmadd132s%c %s,%s,", float_size_code(), | 889 AppendToBuffer("vfmadd132s%c %s,%s,", float_size_code(), |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(), | 944 AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(), |
943 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); | 945 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); |
944 current += PrintRightXMMOperand(current); | 946 current += PrintRightXMMOperand(current); |
945 break; | 947 break; |
946 case 0xf7: | 948 case 0xf7: |
947 AppendToBuffer("shlx%c %s,", operand_size_code(), | 949 AppendToBuffer("shlx%c %s,", operand_size_code(), |
948 NameOfCPURegister(regop)); | 950 NameOfCPURegister(regop)); |
949 current += PrintRightOperand(current); | 951 current += PrintRightOperand(current); |
950 AppendToBuffer(",%s", NameOfCPURegister(vvvv)); | 952 AppendToBuffer(",%s", NameOfCPURegister(vvvv)); |
951 break; | 953 break; |
| 954 #define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, \ |
| 955 opcode) \ |
| 956 case 0x##opcode: { \ |
| 957 AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \ |
| 958 NameOfXMMRegister(vvvv)); \ |
| 959 current += PrintRightXMMOperand(current); \ |
| 960 break; \ |
| 961 } |
| 962 |
| 963 SSSE3_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE) |
| 964 SSE4_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE) |
| 965 #undef DECLARE_SSE_AVX_DIS_CASE |
952 default: | 966 default: |
953 UnimplementedInstruction(); | 967 UnimplementedInstruction(); |
954 } | 968 } |
955 } else if (vex_66() && vex_0f3a()) { | 969 } else if (vex_66() && vex_0f3a()) { |
956 int mod, regop, rm, vvvv = vex_vreg(); | 970 int mod, regop, rm, vvvv = vex_vreg(); |
957 get_modrm(*current, &mod, ®op, &rm); | 971 get_modrm(*current, &mod, ®op, &rm); |
958 switch (opcode) { | 972 switch (opcode) { |
959 case 0x0a: | 973 case 0x0a: |
960 AppendToBuffer("vroundss %s,%s,", NameOfXMMRegister(regop), | 974 AppendToBuffer("vroundss %s,%s,", NameOfXMMRegister(regop), |
961 NameOfXMMRegister(vvvv)); | 975 NameOfXMMRegister(vvvv)); |
962 current += PrintRightXMMOperand(current); | 976 current += PrintRightXMMOperand(current); |
963 AppendToBuffer(",0x%x", *current++); | 977 AppendToBuffer(",0x%x", *current++); |
964 break; | 978 break; |
965 case 0x0b: | 979 case 0x0b: |
966 AppendToBuffer("vroundsd %s,%s,", NameOfXMMRegister(regop), | 980 AppendToBuffer("vroundsd %s,%s,", NameOfXMMRegister(regop), |
967 NameOfXMMRegister(vvvv)); | 981 NameOfXMMRegister(vvvv)); |
968 current += PrintRightXMMOperand(current); | 982 current += PrintRightXMMOperand(current); |
969 AppendToBuffer(",0x%x", *current++); | 983 AppendToBuffer(",0x%x", *current++); |
970 break; | 984 break; |
| 985 case 0x14: |
| 986 AppendToBuffer("vpextrb "); |
| 987 current += PrintRightByteOperand(current); |
| 988 AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++); |
| 989 break; |
| 990 case 0x15: |
| 991 AppendToBuffer("vpextrw "); |
| 992 current += PrintRightOperand(current); |
| 993 AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++); |
| 994 break; |
| 995 case 0x16: |
| 996 AppendToBuffer("vpextrd "); |
| 997 current += PrintRightOperand(current); |
| 998 AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++); |
| 999 break; |
| 1000 case 0x20: |
| 1001 AppendToBuffer("vpinsrb %s,%s,", NameOfXMMRegister(regop), |
| 1002 NameOfXMMRegister(vvvv)); |
| 1003 current += PrintRightByteOperand(current); |
| 1004 AppendToBuffer(",0x%x", *current++); |
| 1005 break; |
| 1006 case 0x22: |
| 1007 AppendToBuffer("vpinsrd %s,%s,", NameOfXMMRegister(regop), |
| 1008 NameOfXMMRegister(vvvv)); |
| 1009 current += PrintRightOperand(current); |
| 1010 AppendToBuffer(",0x%x", *current++); |
| 1011 break; |
971 default: | 1012 default: |
972 UnimplementedInstruction(); | 1013 UnimplementedInstruction(); |
973 } | 1014 } |
974 } else if (vex_f3() && vex_0f()) { | 1015 } else if (vex_f3() && vex_0f()) { |
975 int mod, regop, rm, vvvv = vex_vreg(); | 1016 int mod, regop, rm, vvvv = vex_vreg(); |
976 get_modrm(*current, &mod, ®op, &rm); | 1017 get_modrm(*current, &mod, ®op, &rm); |
977 switch (opcode) { | 1018 switch (opcode) { |
978 case 0x10: | 1019 case 0x10: |
979 AppendToBuffer("vmovss %s,", NameOfXMMRegister(regop)); | 1020 AppendToBuffer("vmovss %s,", NameOfXMMRegister(regop)); |
980 if (mod == 3) { | 1021 if (mod == 3) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 case 0x5e: | 1146 case 0x5e: |
1106 AppendToBuffer("vdivsd %s,%s,", NameOfXMMRegister(regop), | 1147 AppendToBuffer("vdivsd %s,%s,", NameOfXMMRegister(regop), |
1107 NameOfXMMRegister(vvvv)); | 1148 NameOfXMMRegister(vvvv)); |
1108 current += PrintRightXMMOperand(current); | 1149 current += PrintRightXMMOperand(current); |
1109 break; | 1150 break; |
1110 case 0x5f: | 1151 case 0x5f: |
1111 AppendToBuffer("vmaxsd %s,%s,", NameOfXMMRegister(regop), | 1152 AppendToBuffer("vmaxsd %s,%s,", NameOfXMMRegister(regop), |
1112 NameOfXMMRegister(vvvv)); | 1153 NameOfXMMRegister(vvvv)); |
1113 current += PrintRightXMMOperand(current); | 1154 current += PrintRightXMMOperand(current); |
1114 break; | 1155 break; |
| 1156 case 0xf0: |
| 1157 AppendToBuffer("vlddqu %s,", NameOfXMMRegister(regop)); |
| 1158 current += PrintRightXMMOperand(current); |
| 1159 break; |
1115 default: | 1160 default: |
1116 UnimplementedInstruction(); | 1161 UnimplementedInstruction(); |
1117 } | 1162 } |
1118 } else if (vex_none() && vex_0f38()) { | 1163 } else if (vex_none() && vex_0f38()) { |
1119 int mod, regop, rm, vvvv = vex_vreg(); | 1164 int mod, regop, rm, vvvv = vex_vreg(); |
1120 get_modrm(*current, &mod, ®op, &rm); | 1165 get_modrm(*current, &mod, ®op, &rm); |
1121 const char* mnem = "?"; | 1166 const char* mnem = "?"; |
1122 switch (opcode) { | 1167 switch (opcode) { |
1123 case 0xf2: | 1168 case 0xf2: |
1124 AppendToBuffer("andn%c %s,%s,", operand_size_code(), | 1169 AppendToBuffer("andn%c %s,%s,", operand_size_code(), |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1319 case 0x57: | 1364 case 0x57: |
1320 AppendToBuffer("vxorpd %s,%s,", NameOfXMMRegister(regop), | 1365 AppendToBuffer("vxorpd %s,%s,", NameOfXMMRegister(regop), |
1321 NameOfXMMRegister(vvvv)); | 1366 NameOfXMMRegister(vvvv)); |
1322 current += PrintRightXMMOperand(current); | 1367 current += PrintRightXMMOperand(current); |
1323 break; | 1368 break; |
1324 case 0x6e: | 1369 case 0x6e: |
1325 AppendToBuffer("vmov%c %s,", vex_w() ? 'q' : 'd', | 1370 AppendToBuffer("vmov%c %s,", vex_w() ? 'q' : 'd', |
1326 NameOfXMMRegister(regop)); | 1371 NameOfXMMRegister(regop)); |
1327 current += PrintRightOperand(current); | 1372 current += PrintRightOperand(current); |
1328 break; | 1373 break; |
1329 case 0x73: | 1374 case 0x70: |
1330 AppendToBuffer("%s %s,", regop == 6 ? "vpsllq" : "vpsrlq", | 1375 AppendToBuffer("vpshufd %s,", NameOfXMMRegister(regop)); |
| 1376 current += PrintRightXMMOperand(current); |
| 1377 AppendToBuffer(",0x%x", *current++); |
| 1378 break; |
| 1379 case 0x71: |
| 1380 AppendToBuffer("vps%sw %s,", sf_str[regop / 2], |
1331 NameOfXMMRegister(vvvv)); | 1381 NameOfXMMRegister(vvvv)); |
1332 current += PrintRightXMMOperand(current); | 1382 current += PrintRightXMMOperand(current); |
1333 AppendToBuffer(",%u", *current++); | 1383 AppendToBuffer(",%u", *current++); |
1334 break; | 1384 break; |
1335 case 0x76: | 1385 case 0x72: |
1336 AppendToBuffer("vpcmpeqd %s,%s,", NameOfXMMRegister(regop), | 1386 AppendToBuffer("vps%sd %s,", sf_str[regop / 2], |
1337 NameOfXMMRegister(vvvv)); | 1387 NameOfXMMRegister(vvvv)); |
1338 current += PrintRightXMMOperand(current); | 1388 current += PrintRightXMMOperand(current); |
| 1389 AppendToBuffer(",%u", *current++); |
| 1390 break; |
| 1391 case 0x73: |
| 1392 AppendToBuffer("vps%sq %s,", sf_str[regop / 2], |
| 1393 NameOfXMMRegister(vvvv)); |
| 1394 current += PrintRightXMMOperand(current); |
| 1395 AppendToBuffer(",%u", *current++); |
1339 break; | 1396 break; |
1340 case 0x7e: | 1397 case 0x7e: |
1341 AppendToBuffer("vmov%c ", vex_w() ? 'q' : 'd'); | 1398 AppendToBuffer("vmov%c ", vex_w() ? 'q' : 'd'); |
1342 current += PrintRightOperand(current); | 1399 current += PrintRightOperand(current); |
1343 AppendToBuffer(",%s", NameOfXMMRegister(regop)); | 1400 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1344 break; | 1401 break; |
1345 case 0xC2: { | 1402 case 0xC2: { |
1346 AppendToBuffer("vcmppd %s,%s,", NameOfXMMRegister(regop), | 1403 AppendToBuffer("vcmppd %s,%s,", NameOfXMMRegister(regop), |
1347 NameOfXMMRegister(vvvv)); | 1404 NameOfXMMRegister(vvvv)); |
1348 current += PrintRightXMMOperand(current); | 1405 current += PrintRightXMMOperand(current); |
1349 const char* const pseudo_op[] = {"eq", "lt", "le", "unord", | 1406 const char* const pseudo_op[] = {"eq", "lt", "le", "unord", |
1350 "neq", "nlt", "nle", "ord"}; | 1407 "neq", "nlt", "nle", "ord"}; |
1351 AppendToBuffer(", (%s)", pseudo_op[*current]); | 1408 AppendToBuffer(", (%s)", pseudo_op[*current]); |
1352 current += 1; | 1409 current += 1; |
1353 break; | 1410 break; |
1354 } | 1411 } |
| 1412 case 0xc4: |
| 1413 AppendToBuffer("vpinsrw %s,%s,", NameOfXMMRegister(regop), |
| 1414 NameOfXMMRegister(vvvv)); |
| 1415 current += PrintRightOperand(current); |
| 1416 AppendToBuffer(",0x%x", *current++); |
| 1417 break; |
| 1418 case 0xc5: |
| 1419 AppendToBuffer("vpextrw %s,", NameOfCPURegister(regop)); |
| 1420 current += PrintRightXMMOperand(current); |
| 1421 AppendToBuffer(",0x%x", *current++); |
| 1422 break; |
| 1423 #define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \ |
| 1424 case 0x##opcode: { \ |
| 1425 AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \ |
| 1426 NameOfXMMRegister(vvvv)); \ |
| 1427 current += PrintRightXMMOperand(current); \ |
| 1428 break; \ |
| 1429 } |
| 1430 |
| 1431 SSE2_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE) |
| 1432 #undef DECLARE_SSE_AVX_DIS_CASE |
1355 default: | 1433 default: |
1356 UnimplementedInstruction(); | 1434 UnimplementedInstruction(); |
1357 } | 1435 } |
1358 | 1436 |
1359 } else { | 1437 } else { |
1360 UnimplementedInstruction(); | 1438 UnimplementedInstruction(); |
1361 } | 1439 } |
1362 | 1440 |
1363 return static_cast<int>(current - data); | 1441 return static_cast<int>(current - data); |
1364 } | 1442 } |
1365 | 1443 |
1366 | |
1367 // Returns number of bytes used, including *data. | 1444 // Returns number of bytes used, including *data. |
1368 int DisassemblerX64::FPUInstruction(byte* data) { | 1445 int DisassemblerX64::FPUInstruction(byte* data) { |
1369 byte escape_opcode = *data; | 1446 byte escape_opcode = *data; |
1370 DCHECK_EQ(0xD8, escape_opcode & 0xF8); | 1447 DCHECK_EQ(0xD8, escape_opcode & 0xF8); |
1371 byte modrm_byte = *(data+1); | 1448 byte modrm_byte = *(data+1); |
1372 | 1449 |
1373 if (modrm_byte >= 0xC0) { | 1450 if (modrm_byte >= 0xC0) { |
1374 return RegisterFPUInstruction(escape_opcode, modrm_byte); | 1451 return RegisterFPUInstruction(escape_opcode, modrm_byte); |
1375 } else { | 1452 } else { |
1376 return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1); | 1453 return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 byte opcode = *(data + 1); | 1628 byte opcode = *(data + 1); |
1552 byte* current = data + 2; | 1629 byte* current = data + 2; |
1553 // At return, "current" points to the start of the next instruction. | 1630 // At return, "current" points to the start of the next instruction. |
1554 const char* mnemonic = TwoByteMnemonic(opcode); | 1631 const char* mnemonic = TwoByteMnemonic(opcode); |
1555 if (operand_size_ == 0x66) { | 1632 if (operand_size_ == 0x66) { |
1556 // 0x66 0x0F prefix. | 1633 // 0x66 0x0F prefix. |
1557 int mod, regop, rm; | 1634 int mod, regop, rm; |
1558 if (opcode == 0x38) { | 1635 if (opcode == 0x38) { |
1559 byte third_byte = *current; | 1636 byte third_byte = *current; |
1560 current = data + 3; | 1637 current = data + 3; |
1561 if (third_byte == 0x40) { | 1638 get_modrm(*current, &mod, ®op, &rm); |
1562 // pmulld xmm, xmm/m128 | 1639 switch (third_byte) { |
1563 get_modrm(*current, &mod, ®op, &rm); | 1640 #define SSE34_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, opcode) \ |
1564 AppendToBuffer("pmulld %s,", NameOfXMMRegister(regop)); | 1641 case 0x##opcode: { \ |
1565 current += PrintRightXMMOperand(current); | 1642 AppendToBuffer(#instruction " %s,", NameOfXMMRegister(regop)); \ |
| 1643 current += PrintRightXMMOperand(current); \ |
| 1644 break; \ |
| 1645 } |
| 1646 |
| 1647 SSSE3_INSTRUCTION_LIST(SSE34_DIS_CASE) |
| 1648 SSE4_INSTRUCTION_LIST(SSE34_DIS_CASE) |
| 1649 #undef SSE34_DIS_CASE |
| 1650 default: |
| 1651 UnimplementedInstruction(); |
1566 } | 1652 } |
1567 } else if (opcode == 0x3A) { | 1653 } else if (opcode == 0x3A) { |
1568 byte third_byte = *current; | 1654 byte third_byte = *current; |
1569 current = data + 3; | 1655 current = data + 3; |
1570 if (third_byte == 0x17) { | 1656 if (third_byte == 0x17) { |
1571 get_modrm(*current, &mod, ®op, &rm); | 1657 get_modrm(*current, &mod, ®op, &rm); |
1572 AppendToBuffer("extractps "); // reg/m32, xmm, imm8 | 1658 AppendToBuffer("extractps "); // reg/m32, xmm, imm8 |
1573 current += PrintRightOperand(current); | 1659 current += PrintRightOperand(current); |
1574 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); | 1660 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
1575 current += 1; | 1661 current += 1; |
1576 } else if (third_byte == 0x0a) { | 1662 } else if (third_byte == 0x0a) { |
1577 get_modrm(*current, &mod, ®op, &rm); | 1663 get_modrm(*current, &mod, ®op, &rm); |
1578 AppendToBuffer("roundss %s,", NameOfXMMRegister(regop)); | 1664 AppendToBuffer("roundss %s,", NameOfXMMRegister(regop)); |
1579 current += PrintRightXMMOperand(current); | 1665 current += PrintRightXMMOperand(current); |
1580 AppendToBuffer(",0x%x", (*current) & 3); | 1666 AppendToBuffer(",0x%x", (*current) & 3); |
1581 current += 1; | 1667 current += 1; |
1582 } else if (third_byte == 0x0b) { | 1668 } else if (third_byte == 0x0b) { |
1583 get_modrm(*current, &mod, ®op, &rm); | 1669 get_modrm(*current, &mod, ®op, &rm); |
1584 // roundsd xmm, xmm/m64, imm8 | 1670 // roundsd xmm, xmm/m64, imm8 |
1585 AppendToBuffer("roundsd %s,", NameOfXMMRegister(regop)); | 1671 AppendToBuffer("roundsd %s,", NameOfXMMRegister(regop)); |
1586 current += PrintRightXMMOperand(current); | 1672 current += PrintRightXMMOperand(current); |
1587 AppendToBuffer(",0x%x", (*current) & 3); | 1673 AppendToBuffer(",0x%x", (*current) & 3); |
1588 current += 1; | 1674 current += 1; |
| 1675 } else if (third_byte == 0x14) { |
| 1676 get_modrm(*current, &mod, ®op, &rm); |
| 1677 AppendToBuffer("pextrb "); // reg/m32, xmm, imm8 |
| 1678 current += PrintRightOperand(current); |
| 1679 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
| 1680 current += 1; |
| 1681 } else if (third_byte == 0x15) { |
| 1682 get_modrm(*current, &mod, ®op, &rm); |
| 1683 AppendToBuffer("pextrw "); // reg/m32, xmm, imm8 |
| 1684 current += PrintRightOperand(current); |
| 1685 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
| 1686 current += 1; |
1589 } else if (third_byte == 0x16) { | 1687 } else if (third_byte == 0x16) { |
1590 get_modrm(*current, &mod, ®op, &rm); | 1688 get_modrm(*current, &mod, ®op, &rm); |
1591 AppendToBuffer("pextrd "); // reg/m32, xmm, imm8 | 1689 AppendToBuffer("pextrd "); // reg/m32, xmm, imm8 |
1592 current += PrintRightOperand(current); | 1690 current += PrintRightOperand(current); |
1593 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); | 1691 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
1594 current += 1; | 1692 current += 1; |
| 1693 } else if (third_byte == 0x20) { |
| 1694 get_modrm(*current, &mod, ®op, &rm); |
| 1695 AppendToBuffer("pinsrd "); // xmm, reg/m32, imm8 |
| 1696 AppendToBuffer(" %s,", NameOfXMMRegister(regop)); |
| 1697 current += PrintRightOperand(current); |
| 1698 AppendToBuffer(",%d", (*current) & 3); |
| 1699 current += 1; |
1595 } else if (third_byte == 0x21) { | 1700 } else if (third_byte == 0x21) { |
1596 get_modrm(*current, &mod, ®op, &rm); | 1701 get_modrm(*current, &mod, ®op, &rm); |
1597 // insertps xmm, xmm/m32, imm8 | 1702 // insertps xmm, xmm/m32, imm8 |
1598 AppendToBuffer("insertps %s,", NameOfXMMRegister(regop)); | 1703 AppendToBuffer("insertps %s,", NameOfXMMRegister(regop)); |
1599 current += PrintRightXMMOperand(current); | 1704 current += PrintRightXMMOperand(current); |
1600 AppendToBuffer(",0x%x", (*current) & 3); | 1705 AppendToBuffer(",0x%x", (*current) & 3); |
1601 current += 1; | 1706 current += 1; |
1602 } else if (third_byte == 0x22) { | 1707 } else if (third_byte == 0x22) { |
1603 get_modrm(*current, &mod, ®op, &rm); | 1708 get_modrm(*current, &mod, ®op, &rm); |
1604 AppendToBuffer("pinsrd "); // xmm, reg/m32, imm8 | 1709 AppendToBuffer("pinsrd "); // xmm, reg/m32, imm8 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 current += PrintRightXMMOperand(current); | 1764 current += PrintRightXMMOperand(current); |
1660 AppendToBuffer(",%s", NameOfXMMRegister(regop)); | 1765 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1661 } else if (opcode == 0x50) { | 1766 } else if (opcode == 0x50) { |
1662 AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop)); | 1767 AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop)); |
1663 current += PrintRightXMMOperand(current); | 1768 current += PrintRightXMMOperand(current); |
1664 } else if (opcode == 0x70) { | 1769 } else if (opcode == 0x70) { |
1665 AppendToBuffer("pshufd %s,", NameOfXMMRegister(regop)); | 1770 AppendToBuffer("pshufd %s,", NameOfXMMRegister(regop)); |
1666 current += PrintRightXMMOperand(current); | 1771 current += PrintRightXMMOperand(current); |
1667 AppendToBuffer(",0x%x", *current); | 1772 AppendToBuffer(",0x%x", *current); |
1668 current += 1; | 1773 current += 1; |
| 1774 } else if (opcode == 0x71) { |
| 1775 current += 1; |
| 1776 AppendToBuffer("ps%sw %s,%d", sf_str[regop / 2], NameOfXMMRegister(rm), |
| 1777 *current & 0x7f); |
| 1778 current += 1; |
1669 } else if (opcode == 0x72) { | 1779 } else if (opcode == 0x72) { |
1670 current += 1; | 1780 current += 1; |
1671 AppendToBuffer("%s %s,%d", (regop == 6) ? "pslld" : "psrld", | 1781 AppendToBuffer("ps%sd %s,%d", sf_str[regop / 2], NameOfXMMRegister(rm), |
1672 NameOfXMMRegister(rm), *current & 0x7f); | 1782 *current & 0x7f); |
1673 current += 1; | 1783 current += 1; |
1674 } else if (opcode == 0x73) { | 1784 } else if (opcode == 0x73) { |
1675 current += 1; | 1785 current += 1; |
1676 AppendToBuffer("%s %s,%d", (regop == 6) ? "psllq" : "psrlq", | 1786 AppendToBuffer("ps%sq %s,%d", sf_str[regop / 2], NameOfXMMRegister(rm), |
1677 NameOfXMMRegister(rm), *current & 0x7f); | 1787 *current & 0x7f); |
1678 current += 1; | 1788 current += 1; |
1679 } else if (opcode == 0xB1) { | 1789 } else if (opcode == 0xB1) { |
1680 current += PrintOperands("cmpxchg", OPER_REG_OP_ORDER, current); | 1790 current += PrintOperands("cmpxchg", OPER_REG_OP_ORDER, current); |
1681 } else { | 1791 } else { |
1682 const char* mnemonic = "?"; | 1792 const char* mnemonic = "?"; |
1683 if (opcode == 0x54) { | 1793 if (opcode == 0x54) { |
1684 mnemonic = "andpd"; | 1794 mnemonic = "andpd"; |
1685 } else if (opcode == 0x56) { | 1795 } else if (opcode == 0x56) { |
1686 mnemonic = "orpd"; | 1796 mnemonic = "orpd"; |
1687 } else if (opcode == 0x57) { | 1797 } else if (opcode == 0x57) { |
1688 mnemonic = "xorpd"; | 1798 mnemonic = "xorpd"; |
1689 } else if (opcode == 0x5B) { | 1799 } else if (opcode == 0x5B) { |
1690 mnemonic = "cvtps2dq"; | 1800 mnemonic = "cvtps2dq"; |
1691 } else if (opcode == 0x2E) { | 1801 } else if (opcode == 0x2E) { |
1692 mnemonic = "ucomisd"; | 1802 mnemonic = "ucomisd"; |
1693 } else if (opcode == 0x2F) { | 1803 } else if (opcode == 0x2F) { |
1694 mnemonic = "comisd"; | 1804 mnemonic = "comisd"; |
| 1805 } else if (opcode == 0x64) { |
| 1806 mnemonic = "pcmpgtb"; |
| 1807 } else if (opcode == 0x65) { |
| 1808 mnemonic = "pcmpgtw"; |
| 1809 } else if (opcode == 0x66) { |
| 1810 mnemonic = "pcmpgtd"; |
| 1811 } else if (opcode == 0x74) { |
| 1812 mnemonic = "pcmpeqb"; |
| 1813 } else if (opcode == 0x75) { |
| 1814 mnemonic = "pcmpeqw"; |
1695 } else if (opcode == 0x76) { | 1815 } else if (opcode == 0x76) { |
1696 mnemonic = "pcmpeqd"; | 1816 mnemonic = "pcmpeqd"; |
1697 } else if (opcode == 0x62) { | 1817 } else if (opcode == 0x62) { |
1698 mnemonic = "punpckldq"; | 1818 mnemonic = "punpckldq"; |
| 1819 } else if (opcode == 0x63) { |
| 1820 mnemonic = "packsswb"; |
| 1821 } else if (opcode == 0x67) { |
| 1822 mnemonic = "packuswb"; |
1699 } else if (opcode == 0x6A) { | 1823 } else if (opcode == 0x6A) { |
1700 mnemonic = "punpckhdq"; | 1824 mnemonic = "punpckhdq"; |
| 1825 } else if (opcode == 0x6B) { |
| 1826 mnemonic = "packssdw"; |
| 1827 } else if (opcode == 0xC4) { |
| 1828 mnemonic = "pinsrw"; |
| 1829 } else if (opcode == 0xC5) { |
| 1830 mnemonic = "pextrw"; |
| 1831 } else if (opcode == 0xD1) { |
| 1832 mnemonic = "psrlw"; |
| 1833 } else if (opcode == 0xD2) { |
| 1834 mnemonic = "psrld"; |
| 1835 } else if (opcode == 0xD5) { |
| 1836 mnemonic = "pmullw"; |
| 1837 } else if (opcode == 0xD7) { |
| 1838 mnemonic = "pmovmskb"; |
| 1839 } else if (opcode == 0xD8) { |
| 1840 mnemonic = "psubusb"; |
| 1841 } else if (opcode == 0xD9) { |
| 1842 mnemonic = "psubusw"; |
| 1843 } else if (opcode == 0xDA) { |
| 1844 mnemonic = "pminub"; |
| 1845 } else if (opcode == 0xDC) { |
| 1846 mnemonic = "paddusb"; |
| 1847 } else if (opcode == 0xDD) { |
| 1848 mnemonic = "paddusw"; |
| 1849 } else if (opcode == 0xDE) { |
| 1850 mnemonic = "pmaxub"; |
| 1851 } else if (opcode == 0xE1) { |
| 1852 mnemonic = "psraw"; |
| 1853 } else if (opcode == 0xE2) { |
| 1854 mnemonic = "psrad"; |
| 1855 } else if (opcode == 0xE8) { |
| 1856 mnemonic = "psubsb"; |
| 1857 } else if (opcode == 0xE9) { |
| 1858 mnemonic = "psubsw"; |
| 1859 } else if (opcode == 0xEA) { |
| 1860 mnemonic = "pminsw"; |
| 1861 } else if (opcode == 0xEC) { |
| 1862 mnemonic = "paddsb"; |
| 1863 } else if (opcode == 0xED) { |
| 1864 mnemonic = "paddsw"; |
| 1865 } else if (opcode == 0xEE) { |
| 1866 mnemonic = "pmaxsw"; |
| 1867 } else if (opcode == 0xEF) { |
| 1868 mnemonic = "pxor"; |
| 1869 } else if (opcode == 0xF1) { |
| 1870 mnemonic = "psllw"; |
| 1871 } else if (opcode == 0xF2) { |
| 1872 mnemonic = "pslld"; |
1701 } else if (opcode == 0xF4) { | 1873 } else if (opcode == 0xF4) { |
1702 mnemonic = "pmuludq"; | 1874 mnemonic = "pmuludq"; |
| 1875 } else if (opcode == 0xF8) { |
| 1876 mnemonic = "psubb"; |
| 1877 } else if (opcode == 0xF9) { |
| 1878 mnemonic = "psubw"; |
1703 } else if (opcode == 0xFA) { | 1879 } else if (opcode == 0xFA) { |
1704 mnemonic = "psubd"; | 1880 mnemonic = "psubd"; |
| 1881 } else if (opcode == 0xFC) { |
| 1882 mnemonic = "paddb"; |
| 1883 } else if (opcode == 0xFD) { |
| 1884 mnemonic = "paddw"; |
1705 } else if (opcode == 0xFE) { | 1885 } else if (opcode == 0xFE) { |
1706 mnemonic = "paddd"; | 1886 mnemonic = "paddd"; |
1707 } else if (opcode == 0xC2) { | 1887 } else if (opcode == 0xC2) { |
1708 mnemonic = "cmppd"; | 1888 mnemonic = "cmppd"; |
1709 } else { | 1889 } else { |
1710 UnimplementedInstruction(); | 1890 UnimplementedInstruction(); |
1711 } | 1891 } |
1712 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); | 1892 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); |
1713 current += PrintRightXMMOperand(current); | 1893 current += PrintRightXMMOperand(current); |
1714 if (opcode == 0xC2) { | 1894 if (opcode == 0xC2) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1773 "cmpneqsd", | 1953 "cmpneqsd", |
1774 "cmpnltsd", | 1954 "cmpnltsd", |
1775 "cmpnlesd", | 1955 "cmpnlesd", |
1776 "cmpordsd" | 1956 "cmpordsd" |
1777 }; | 1957 }; |
1778 AppendToBuffer("%s %s,%s", | 1958 AppendToBuffer("%s %s,%s", |
1779 pseudo_op[current[1]], | 1959 pseudo_op[current[1]], |
1780 NameOfXMMRegister(regop), | 1960 NameOfXMMRegister(regop), |
1781 NameOfXMMRegister(rm)); | 1961 NameOfXMMRegister(rm)); |
1782 current += 2; | 1962 current += 2; |
| 1963 } else if (opcode == 0xF0) { |
| 1964 int mod, regop, rm; |
| 1965 get_modrm(*current, &mod, ®op, &rm); |
| 1966 AppendToBuffer("lddqu %s,", NameOfXMMRegister(regop)); |
| 1967 current += PrintRightOperand(current); |
1783 } else { | 1968 } else { |
1784 UnimplementedInstruction(); | 1969 UnimplementedInstruction(); |
1785 } | 1970 } |
1786 } else if (group_1_prefix_ == 0xF3) { | 1971 } else if (group_1_prefix_ == 0xF3) { |
1787 // Instructions with prefix 0xF3. | 1972 // Instructions with prefix 0xF3. |
1788 if (opcode == 0x11 || opcode == 0x10) { | 1973 if (opcode == 0x11 || opcode == 0x10) { |
1789 // MOVSS: Move scalar double-precision fp to/from/between XMM registers. | 1974 // MOVSS: Move scalar double-precision fp to/from/between XMM registers. |
1790 AppendToBuffer("movss "); | 1975 AppendToBuffer("movss "); |
1791 int mod, regop, rm; | 1976 int mod, regop, rm; |
1792 get_modrm(*current, &mod, ®op, &rm); | 1977 get_modrm(*current, &mod, ®op, &rm); |
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2612 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { | 2797 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { |
2613 fprintf(f, " "); | 2798 fprintf(f, " "); |
2614 } | 2799 } |
2615 fprintf(f, " %s\n", buffer.start()); | 2800 fprintf(f, " %s\n", buffer.start()); |
2616 } | 2801 } |
2617 } | 2802 } |
2618 | 2803 |
2619 } // namespace disasm | 2804 } // namespace disasm |
2620 | 2805 |
2621 #endif // V8_TARGET_ARCH_X64 | 2806 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |