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 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 const char* mnem = conditional_code_suffix[cond]; | 863 const char* mnem = conditional_code_suffix[cond]; |
864 AppendToBuffer("set%s%c ", mnem, operand_size_code()); | 864 AppendToBuffer("set%s%c ", mnem, operand_size_code()); |
865 PrintRightByteOperand(data + 2); | 865 PrintRightByteOperand(data + 2); |
866 return 3; // includes 0x0F | 866 return 3; // includes 0x0F |
867 } | 867 } |
868 | 868 |
869 | 869 |
870 int DisassemblerX64::AVXInstruction(byte* data) { | 870 int DisassemblerX64::AVXInstruction(byte* data) { |
871 byte opcode = *data; | 871 byte opcode = *data; |
872 byte* current = data + 1; | 872 byte* current = data + 1; |
873 if (vex_66() && vex_0f38()) { | 873 if (vex_0f() && opcode == 0x2e) { |
| 874 int mod, regop, rm; |
| 875 get_modrm(*current, &mod, ®op, &rm); |
| 876 AppendToBuffer("vucomis%c %s,", vex_66() ? 'd' : 's', |
| 877 NameOfXMMRegister(regop)); |
| 878 current += PrintRightXMMOperand(current); |
| 879 } else if (vex_66() && vex_0f38()) { |
874 int mod, regop, rm, vvvv = vex_vreg(); | 880 int mod, regop, rm, vvvv = vex_vreg(); |
875 get_modrm(*current, &mod, ®op, &rm); | 881 get_modrm(*current, &mod, ®op, &rm); |
876 switch (opcode) { | 882 switch (opcode) { |
877 case 0x99: | 883 case 0x99: |
878 AppendToBuffer("vfmadd132s%c %s,%s,", float_size_code(), | 884 AppendToBuffer("vfmadd132s%c %s,%s,", float_size_code(), |
879 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); | 885 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); |
880 current += PrintRightXMMOperand(current); | 886 current += PrintRightXMMOperand(current); |
881 break; | 887 break; |
882 case 0xa9: | 888 case 0xa9: |
883 AppendToBuffer("vfmadd213s%c %s,%s,", float_size_code(), | 889 AppendToBuffer("vfmadd213s%c %s,%s,", float_size_code(), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 current += PrintRightXMMOperand(current); | 936 current += PrintRightXMMOperand(current); |
931 break; | 937 break; |
932 case 0xbf: | 938 case 0xbf: |
933 AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(), | 939 AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(), |
934 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); | 940 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); |
935 current += PrintRightXMMOperand(current); | 941 current += PrintRightXMMOperand(current); |
936 break; | 942 break; |
937 default: | 943 default: |
938 UnimplementedInstruction(); | 944 UnimplementedInstruction(); |
939 } | 945 } |
| 946 } else if (vex_f3() && vex_0f()) { |
| 947 int mod, regop, rm, vvvv = vex_vreg(); |
| 948 get_modrm(*current, &mod, ®op, &rm); |
| 949 switch (opcode) { |
| 950 case 0x58: |
| 951 AppendToBuffer("vaddss %s,%s,", NameOfXMMRegister(regop), |
| 952 NameOfXMMRegister(vvvv)); |
| 953 current += PrintRightXMMOperand(current); |
| 954 break; |
| 955 case 0x59: |
| 956 AppendToBuffer("vmulss %s,%s,", NameOfXMMRegister(regop), |
| 957 NameOfXMMRegister(vvvv)); |
| 958 current += PrintRightXMMOperand(current); |
| 959 break; |
| 960 case 0x5c: |
| 961 AppendToBuffer("vsubss %s,%s,", NameOfXMMRegister(regop), |
| 962 NameOfXMMRegister(vvvv)); |
| 963 current += PrintRightXMMOperand(current); |
| 964 break; |
| 965 case 0x5d: |
| 966 AppendToBuffer("vminss %s,%s,", NameOfXMMRegister(regop), |
| 967 NameOfXMMRegister(vvvv)); |
| 968 current += PrintRightXMMOperand(current); |
| 969 break; |
| 970 case 0x5e: |
| 971 AppendToBuffer("vdivss %s,%s,", NameOfXMMRegister(regop), |
| 972 NameOfXMMRegister(vvvv)); |
| 973 current += PrintRightXMMOperand(current); |
| 974 break; |
| 975 case 0x5f: |
| 976 AppendToBuffer("vmaxss %s,%s,", NameOfXMMRegister(regop), |
| 977 NameOfXMMRegister(vvvv)); |
| 978 current += PrintRightXMMOperand(current); |
| 979 break; |
| 980 default: |
| 981 UnimplementedInstruction(); |
| 982 } |
940 } else if (vex_f2() && vex_0f()) { | 983 } else if (vex_f2() && vex_0f()) { |
941 int mod, regop, rm, vvvv = vex_vreg(); | 984 int mod, regop, rm, vvvv = vex_vreg(); |
942 get_modrm(*current, &mod, ®op, &rm); | 985 get_modrm(*current, &mod, ®op, &rm); |
943 switch (opcode) { | 986 switch (opcode) { |
944 case 0x58: | 987 case 0x58: |
945 AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop), | 988 AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop), |
946 NameOfXMMRegister(vvvv)); | 989 NameOfXMMRegister(vvvv)); |
947 current += PrintRightXMMOperand(current); | 990 current += PrintRightXMMOperand(current); |
948 break; | 991 break; |
949 case 0x59: | 992 case 0x59: |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 current += PrintRightXMMOperand(current); | 1340 current += PrintRightXMMOperand(current); |
1298 AppendToBuffer(",%s", NameOfXMMRegister(regop)); | 1341 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1299 } else { | 1342 } else { |
1300 AppendToBuffer("%s,", NameOfXMMRegister(regop)); | 1343 AppendToBuffer("%s,", NameOfXMMRegister(regop)); |
1301 current += PrintRightXMMOperand(current); | 1344 current += PrintRightXMMOperand(current); |
1302 } | 1345 } |
1303 } else if (opcode == 0x2A) { | 1346 } else if (opcode == 0x2A) { |
1304 // CVTSI2SD: integer to XMM double conversion. | 1347 // CVTSI2SD: integer to XMM double conversion. |
1305 int mod, regop, rm; | 1348 int mod, regop, rm; |
1306 get_modrm(*current, &mod, ®op, &rm); | 1349 get_modrm(*current, &mod, ®op, &rm); |
1307 AppendToBuffer("%sd %s,", mnemonic, NameOfXMMRegister(regop)); | 1350 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); |
1308 current += PrintRightOperand(current); | 1351 current += PrintRightOperand(current); |
1309 } else if (opcode == 0x2C) { | 1352 } else if (opcode == 0x2C) { |
1310 // CVTTSD2SI: | 1353 // CVTTSD2SI: |
1311 // Convert with truncation scalar double-precision FP to integer. | 1354 // Convert with truncation scalar double-precision FP to integer. |
1312 int mod, regop, rm; | 1355 int mod, regop, rm; |
1313 get_modrm(*current, &mod, ®op, &rm); | 1356 get_modrm(*current, &mod, ®op, &rm); |
1314 AppendToBuffer("cvttsd2si%c %s,", | 1357 AppendToBuffer("cvttsd2si%c %s,", |
1315 operand_size_code(), NameOfCPURegister(regop)); | 1358 operand_size_code(), NameOfCPURegister(regop)); |
1316 current += PrintRightXMMOperand(current); | 1359 current += PrintRightXMMOperand(current); |
1317 } else if (opcode == 0x2D) { | 1360 } else if (opcode == 0x2D) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 current += PrintRightOperand(current); | 1403 current += PrintRightOperand(current); |
1361 AppendToBuffer(",%s", NameOfXMMRegister(regop)); | 1404 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1362 } else { | 1405 } else { |
1363 AppendToBuffer("%s,", NameOfXMMRegister(regop)); | 1406 AppendToBuffer("%s,", NameOfXMMRegister(regop)); |
1364 current += PrintRightOperand(current); | 1407 current += PrintRightOperand(current); |
1365 } | 1408 } |
1366 } else if (opcode == 0x2A) { | 1409 } else if (opcode == 0x2A) { |
1367 // CVTSI2SS: integer to XMM single conversion. | 1410 // CVTSI2SS: integer to XMM single conversion. |
1368 int mod, regop, rm; | 1411 int mod, regop, rm; |
1369 get_modrm(*current, &mod, ®op, &rm); | 1412 get_modrm(*current, &mod, ®op, &rm); |
1370 AppendToBuffer("%ss %s,", mnemonic, NameOfXMMRegister(regop)); | 1413 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); |
1371 current += PrintRightOperand(current); | 1414 current += PrintRightOperand(current); |
1372 } else if (opcode == 0x2C) { | 1415 } else if (opcode == 0x2C) { |
1373 // CVTTSS2SI: | 1416 // CVTTSS2SI: |
1374 // Convert with truncation scalar single-precision FP to dword integer. | 1417 // Convert with truncation scalar single-precision FP to dword integer. |
1375 int mod, regop, rm; | 1418 int mod, regop, rm; |
1376 get_modrm(*current, &mod, ®op, &rm); | 1419 get_modrm(*current, &mod, ®op, &rm); |
1377 AppendToBuffer("cvttss2si%c %s,", | 1420 AppendToBuffer("cvttss2si%c %s,", |
1378 operand_size_code(), NameOfCPURegister(regop)); | 1421 operand_size_code(), NameOfCPURegister(regop)); |
1379 current += PrintRightXMMOperand(current); | 1422 current += PrintRightXMMOperand(current); |
1380 } else if (opcode == 0x58) { | |
1381 int mod, regop, rm; | |
1382 get_modrm(*current, &mod, ®op, &rm); | |
1383 AppendToBuffer("addss %s,", NameOfXMMRegister(regop)); | |
1384 current += PrintRightXMMOperand(current); | |
1385 } else if (opcode == 0x59) { | |
1386 int mod, regop, rm; | |
1387 get_modrm(*current, &mod, ®op, &rm); | |
1388 AppendToBuffer("mulss %s,", NameOfXMMRegister(regop)); | |
1389 current += PrintRightXMMOperand(current); | |
1390 } else if (opcode == 0x5A) { | |
1391 // CVTSS2SD: | |
1392 // Convert scalar single-precision FP to scalar double-precision FP. | |
1393 int mod, regop, rm; | |
1394 get_modrm(*current, &mod, ®op, &rm); | |
1395 AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop)); | |
1396 current += PrintRightXMMOperand(current); | |
1397 } else if (opcode == 0x5c) { | |
1398 int mod, regop, rm; | |
1399 get_modrm(*current, &mod, ®op, &rm); | |
1400 AppendToBuffer("subss %s,", NameOfXMMRegister(regop)); | |
1401 current += PrintRightXMMOperand(current); | |
1402 } else if (opcode == 0x5e) { | |
1403 int mod, regop, rm; | |
1404 get_modrm(*current, &mod, ®op, &rm); | |
1405 AppendToBuffer("divss %s,", NameOfXMMRegister(regop)); | |
1406 current += PrintRightXMMOperand(current); | |
1407 } else if (opcode == 0x7E) { | 1423 } else if (opcode == 0x7E) { |
1408 int mod, regop, rm; | 1424 int mod, regop, rm; |
1409 get_modrm(*current, &mod, ®op, &rm); | 1425 get_modrm(*current, &mod, ®op, &rm); |
1410 AppendToBuffer("movq %s,", NameOfXMMRegister(regop)); | 1426 AppendToBuffer("movq %s,", NameOfXMMRegister(regop)); |
1411 current += PrintRightXMMOperand(current); | 1427 current += PrintRightXMMOperand(current); |
| 1428 } else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) { |
| 1429 // XMM arithmetic. Mnemonic was retrieved at the start of this function. |
| 1430 int mod, regop, rm; |
| 1431 get_modrm(*current, &mod, ®op, &rm); |
| 1432 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); |
| 1433 current += PrintRightXMMOperand(current); |
| 1434 } else if (opcode == 0xC2) { |
| 1435 // Intel manual 2A, Table 3-18. |
| 1436 int mod, regop, rm; |
| 1437 get_modrm(*current, &mod, ®op, &rm); |
| 1438 const char* const pseudo_op[] = {"cmpeqss", "cmpltss", "cmpless", |
| 1439 "cmpunordss", "cmpneqss", "cmpnltss", |
| 1440 "cmpnless", "cmpordss"}; |
| 1441 AppendToBuffer("%s %s,%s", pseudo_op[current[1]], |
| 1442 NameOfXMMRegister(regop), NameOfXMMRegister(rm)); |
| 1443 current += 2; |
1412 } else { | 1444 } else { |
1413 UnimplementedInstruction(); | 1445 UnimplementedInstruction(); |
1414 } | 1446 } |
1415 } else if (opcode == 0x1F) { | 1447 } else if (opcode == 0x1F) { |
1416 // NOP | 1448 // NOP |
1417 int mod, regop, rm; | 1449 int mod, regop, rm; |
1418 get_modrm(*current, &mod, ®op, &rm); | 1450 get_modrm(*current, &mod, ®op, &rm); |
1419 current++; | 1451 current++; |
1420 if (rm == 4) { // SIB byte present. | 1452 if (rm == 4) { // SIB byte present. |
1421 current++; | 1453 current++; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 | 1569 |
1538 | 1570 |
1539 // Mnemonics for two-byte opcode instructions starting with 0x0F. | 1571 // Mnemonics for two-byte opcode instructions starting with 0x0F. |
1540 // The argument is the second byte of the two-byte opcode. | 1572 // The argument is the second byte of the two-byte opcode. |
1541 // Returns NULL if the instruction is not handled here. | 1573 // Returns NULL if the instruction is not handled here. |
1542 const char* DisassemblerX64::TwoByteMnemonic(byte opcode) { | 1574 const char* DisassemblerX64::TwoByteMnemonic(byte opcode) { |
1543 switch (opcode) { | 1575 switch (opcode) { |
1544 case 0x1F: | 1576 case 0x1F: |
1545 return "nop"; | 1577 return "nop"; |
1546 case 0x2A: // F2/F3 prefix. | 1578 case 0x2A: // F2/F3 prefix. |
1547 return "cvtsi2s"; | 1579 return (group_1_prefix_ == 0xF2) ? "cvtsi2sd" : "cvtsi2ss"; |
1548 case 0x51: // F2 prefix. | 1580 case 0x51: // F2/F3 prefix. |
1549 return "sqrtsd"; | 1581 return (group_1_prefix_ == 0xF2) ? "sqrtsd" : "sqrtss"; |
1550 case 0x58: // F2 prefix. | 1582 case 0x58: // F2/F3 prefix. |
1551 return "addsd"; | 1583 return (group_1_prefix_ == 0xF2) ? "addsd" : "addss"; |
1552 case 0x59: // F2 prefix. | 1584 case 0x59: // F2/F3 prefix. |
1553 return "mulsd"; | 1585 return (group_1_prefix_ == 0xF2) ? "mulsd" : "mulss"; |
1554 case 0x5A: // F2 prefix. | 1586 case 0x5A: // F2/F3 prefix. |
1555 return "cvtsd2ss"; | 1587 return (group_1_prefix_ == 0xF2) ? "cvtsd2ss" : "cvtss2sd"; |
1556 case 0x5D: // F2 prefix. | 1588 case 0x5D: // F2/F3 prefix. |
1557 return "minsd"; | 1589 return (group_1_prefix_ == 0xF2) ? "minsd" : "minss"; |
1558 case 0x5C: // F2 prefix. | 1590 case 0x5C: // F2/F3 prefix. |
1559 return "subsd"; | 1591 return (group_1_prefix_ == 0xF2) ? "subsd" : "subss"; |
1560 case 0x5E: // F2 prefix. | 1592 case 0x5E: // F2/F3 prefix. |
1561 return "divsd"; | 1593 return (group_1_prefix_ == 0xF2) ? "divsd" : "divss"; |
1562 case 0x5F: // F2 prefix. | 1594 case 0x5F: // F2/F3 prefix. |
1563 return "maxsd"; | 1595 return (group_1_prefix_ == 0xF2) ? "maxsd" : "maxss"; |
1564 case 0xA2: | 1596 case 0xA2: |
1565 return "cpuid"; | 1597 return "cpuid"; |
1566 case 0xA5: | 1598 case 0xA5: |
1567 return "shld"; | 1599 return "shld"; |
1568 case 0xAB: | 1600 case 0xAB: |
1569 return "bts"; | 1601 return "bts"; |
1570 case 0xAD: | 1602 case 0xAD: |
1571 return "shrd"; | 1603 return "shrd"; |
1572 case 0xAF: | 1604 case 0xAF: |
1573 return "imul"; | 1605 return "imul"; |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2144 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { | 2176 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { |
2145 fprintf(f, " "); | 2177 fprintf(f, " "); |
2146 } | 2178 } |
2147 fprintf(f, " %s\n", buffer.start()); | 2179 fprintf(f, " %s\n", buffer.start()); |
2148 } | 2180 } |
2149 } | 2181 } |
2150 | 2182 |
2151 } // namespace disasm | 2183 } // namespace disasm |
2152 | 2184 |
2153 #endif // V8_TARGET_ARCH_X64 | 2185 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |