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

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

Issue 1040603002: [x64] Introduce BMI instructions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix previous Patch Set Created 5 years, 8 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
« no previous file with comments | « src/x64/assembler-x64-inl.h ('k') | src/x64/macro-assembler-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 // 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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 bool rex_r() { return (rex_ & 0x04) != 0; } 352 bool rex_r() { return (rex_ & 0x04) != 0; }
353 353
354 bool rex_w() { return (rex_ & 0x08) != 0; } 354 bool rex_w() { return (rex_ & 0x08) != 0; }
355 355
356 bool vex_128() { 356 bool vex_128() {
357 DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX); 357 DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
358 byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_; 358 byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
359 return (checked & 4) != 1; 359 return (checked & 4) != 1;
360 } 360 }
361 361
362 bool vex_none() {
363 DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
364 byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
365 return (checked & 3) == 0;
366 }
367
362 bool vex_66() { 368 bool vex_66() {
363 DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX); 369 DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
364 byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_; 370 byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
365 return (checked & 3) == 1; 371 return (checked & 3) == 1;
366 } 372 }
367 373
368 bool vex_f3() { 374 bool vex_f3() {
369 DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX); 375 DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
370 byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_; 376 byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
371 return (checked & 3) == 2; 377 return (checked & 3) == 2;
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 case 0xaf: 939 case 0xaf:
934 AppendToBuffer("vfnmsub213s%c %s,%s,", float_size_code(), 940 AppendToBuffer("vfnmsub213s%c %s,%s,", float_size_code(),
935 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); 941 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
936 current += PrintRightXMMOperand(current); 942 current += PrintRightXMMOperand(current);
937 break; 943 break;
938 case 0xbf: 944 case 0xbf:
939 AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(), 945 AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(),
940 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); 946 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
941 current += PrintRightXMMOperand(current); 947 current += PrintRightXMMOperand(current);
942 break; 948 break;
949 case 0xf7:
950 AppendToBuffer("shlx%c %s,", operand_size_code(),
951 NameOfCPURegister(regop));
952 current += PrintRightOperand(current);
953 AppendToBuffer(",%s", NameOfCPURegister(vvvv));
954 break;
943 default: 955 default:
944 UnimplementedInstruction(); 956 UnimplementedInstruction();
945 } 957 }
946 } else if (vex_f3() && vex_0f()) { 958 } else if (vex_f3() && vex_0f()) {
947 int mod, regop, rm, vvvv = vex_vreg(); 959 int mod, regop, rm, vvvv = vex_vreg();
948 get_modrm(*current, &mod, &regop, &rm); 960 get_modrm(*current, &mod, &regop, &rm);
949 switch (opcode) { 961 switch (opcode) {
950 case 0x58: 962 case 0x58:
951 AppendToBuffer("vaddss %s,%s,", NameOfXMMRegister(regop), 963 AppendToBuffer("vaddss %s,%s,", NameOfXMMRegister(regop),
952 NameOfXMMRegister(vvvv)); 964 NameOfXMMRegister(vvvv));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 current += PrintRightXMMOperand(current); 1022 current += PrintRightXMMOperand(current);
1011 break; 1023 break;
1012 case 0x5f: 1024 case 0x5f:
1013 AppendToBuffer("vmaxsd %s,%s,", NameOfXMMRegister(regop), 1025 AppendToBuffer("vmaxsd %s,%s,", NameOfXMMRegister(regop),
1014 NameOfXMMRegister(vvvv)); 1026 NameOfXMMRegister(vvvv));
1015 current += PrintRightXMMOperand(current); 1027 current += PrintRightXMMOperand(current);
1016 break; 1028 break;
1017 default: 1029 default:
1018 UnimplementedInstruction(); 1030 UnimplementedInstruction();
1019 } 1031 }
1032 } else if (vex_none() && vex_0f38()) {
1033 int mod, regop, rm, vvvv = vex_vreg();
1034 get_modrm(*current, &mod, &regop, &rm);
1035 const char* mnem = "?";
1036 switch (opcode) {
1037 case 0xf2:
1038 AppendToBuffer("andn%c %s,%s,", operand_size_code(),
1039 NameOfCPURegister(regop), NameOfCPURegister(vvvv));
1040 current += PrintRightOperand(current);
1041 break;
1042 case 0xf5:
1043 AppendToBuffer("bzhi%c %s,", operand_size_code(),
1044 NameOfCPURegister(regop));
1045 current += PrintRightOperand(current);
1046 AppendToBuffer(",%s", NameOfCPURegister(vvvv));
1047 break;
1048 case 0xf7:
1049 AppendToBuffer("bextr%c %s,", operand_size_code(),
1050 NameOfCPURegister(regop));
1051 current += PrintRightOperand(current);
1052 AppendToBuffer(",%s", NameOfCPURegister(vvvv));
1053 break;
1054 case 0xf3:
1055 switch (regop) {
1056 case 1:
1057 mnem = "blsr";
1058 break;
1059 case 2:
1060 mnem = "blsmsk";
1061 break;
1062 case 3:
1063 mnem = "blsi";
1064 break;
1065 default:
1066 UnimplementedInstruction();
1067 }
1068 AppendToBuffer("%s%c %s,", mnem, operand_size_code(),
1069 NameOfCPURegister(vvvv));
1070 current += PrintRightOperand(current);
1071 mnem = "?";
1072 break;
1073 default:
1074 UnimplementedInstruction();
1075 }
1076 } else if (vex_f2() && vex_0f38()) {
1077 int mod, regop, rm, vvvv = vex_vreg();
1078 get_modrm(*current, &mod, &regop, &rm);
1079 switch (opcode) {
1080 case 0xf5:
1081 AppendToBuffer("pdep%c %s,%s,", operand_size_code(),
1082 NameOfCPURegister(regop), NameOfCPURegister(vvvv));
1083 current += PrintRightOperand(current);
1084 break;
1085 case 0xf6:
1086 AppendToBuffer("mulx%c %s,%s,", operand_size_code(),
1087 NameOfCPURegister(regop), NameOfCPURegister(vvvv));
1088 current += PrintRightOperand(current);
1089 break;
1090 case 0xf7:
1091 AppendToBuffer("shrx%c %s,", operand_size_code(),
1092 NameOfCPURegister(regop));
1093 current += PrintRightOperand(current);
1094 AppendToBuffer(",%s", NameOfCPURegister(vvvv));
1095 break;
1096 default:
1097 UnimplementedInstruction();
1098 }
1099 } else if (vex_f3() && vex_0f38()) {
1100 int mod, regop, rm, vvvv = vex_vreg();
1101 get_modrm(*current, &mod, &regop, &rm);
1102 switch (opcode) {
1103 case 0xf5:
1104 AppendToBuffer("pext%c %s,%s,", operand_size_code(),
1105 NameOfCPURegister(regop), NameOfCPURegister(vvvv));
1106 current += PrintRightOperand(current);
1107 break;
1108 case 0xf7:
1109 AppendToBuffer("sarx%c %s,", operand_size_code(),
1110 NameOfCPURegister(regop));
1111 current += PrintRightOperand(current);
1112 AppendToBuffer(",%s", NameOfCPURegister(vvvv));
1113 break;
1114 default:
1115 UnimplementedInstruction();
1116 }
1117 } else if (vex_f2() && vex_0f3a()) {
1118 int mod, regop, rm;
1119 get_modrm(*current, &mod, &regop, &rm);
1120 switch (opcode) {
1121 case 0xf0:
1122 AppendToBuffer("rorx%c %s,", operand_size_code(),
1123 NameOfCPURegister(regop));
1124 current += PrintRightOperand(current);
1125 switch (operand_size()) {
1126 case OPERAND_DOUBLEWORD_SIZE:
1127 AppendToBuffer(",%d", *current & 0x1f);
1128 break;
1129 case OPERAND_QUADWORD_SIZE:
1130 AppendToBuffer(",%d", *current & 0x3f);
1131 break;
1132 default:
1133 UnimplementedInstruction();
1134 }
1135 current += 1;
1136 break;
1137 default:
1138 UnimplementedInstruction();
1139 }
1020 } else { 1140 } else {
1021 UnimplementedInstruction(); 1141 UnimplementedInstruction();
1022 } 1142 }
1023 1143
1024 return static_cast<int>(current - data); 1144 return static_cast<int>(current - data);
1025 } 1145 }
1026 1146
1027 1147
1028 // Returns number of bytes used, including *data. 1148 // Returns number of bytes used, including *data.
1029 int DisassemblerX64::FPUInstruction(byte* data) { 1149 int DisassemblerX64::FPUInstruction(byte* data) {
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 int mod, regop, rm; 1544 int mod, regop, rm;
1425 get_modrm(*current, &mod, &regop, &rm); 1545 get_modrm(*current, &mod, &regop, &rm);
1426 AppendToBuffer("movq %s,", NameOfXMMRegister(regop)); 1546 AppendToBuffer("movq %s,", NameOfXMMRegister(regop));
1427 current += PrintRightXMMOperand(current); 1547 current += PrintRightXMMOperand(current);
1428 } else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) { 1548 } else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) {
1429 // XMM arithmetic. Mnemonic was retrieved at the start of this function. 1549 // XMM arithmetic. Mnemonic was retrieved at the start of this function.
1430 int mod, regop, rm; 1550 int mod, regop, rm;
1431 get_modrm(*current, &mod, &regop, &rm); 1551 get_modrm(*current, &mod, &regop, &rm);
1432 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); 1552 AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
1433 current += PrintRightXMMOperand(current); 1553 current += PrintRightXMMOperand(current);
1554 } else if (opcode == 0xB8) {
1555 int mod, regop, rm;
1556 get_modrm(*current, &mod, &regop, &rm);
1557 AppendToBuffer("popcnt%c %s,", operand_size_code(),
1558 NameOfCPURegister(regop));
1559 current += PrintRightOperand(current);
1560 } else if (opcode == 0xBC) {
1561 int mod, regop, rm;
1562 get_modrm(*current, &mod, &regop, &rm);
1563 AppendToBuffer("tzcnt%c %s,", operand_size_code(),
1564 NameOfCPURegister(regop));
1565 current += PrintRightOperand(current);
1566 } else if (opcode == 0xBD) {
1567 int mod, regop, rm;
1568 get_modrm(*current, &mod, &regop, &rm);
1569 AppendToBuffer("lzcnt%c %s,", operand_size_code(),
1570 NameOfCPURegister(regop));
1571 current += PrintRightOperand(current);
1434 } else if (opcode == 0xC2) { 1572 } else if (opcode == 0xC2) {
1435 // Intel manual 2A, Table 3-18. 1573 // Intel manual 2A, Table 3-18.
1436 int mod, regop, rm; 1574 int mod, regop, rm;
1437 get_modrm(*current, &mod, &regop, &rm); 1575 get_modrm(*current, &mod, &regop, &rm);
1438 const char* const pseudo_op[] = {"cmpeqss", "cmpltss", "cmpless", 1576 const char* const pseudo_op[] = {"cmpeqss", "cmpltss", "cmpless",
1439 "cmpunordss", "cmpneqss", "cmpnltss", 1577 "cmpunordss", "cmpneqss", "cmpnltss",
1440 "cmpnless", "cmpordss"}; 1578 "cmpnless", "cmpordss"};
1441 AppendToBuffer("%s %s,%s", pseudo_op[current[1]], 1579 AppendToBuffer("%s %s,%s", pseudo_op[current[1]],
1442 NameOfXMMRegister(regop), NameOfXMMRegister(rm)); 1580 NameOfXMMRegister(regop), NameOfXMMRegister(rm));
1443 current += 2; 1581 current += 2;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 } else if ((current & 0xF0) == 0x40) { // REX prefix. 1774 } else if ((current & 0xF0) == 0x40) { // REX prefix.
1637 setRex(current); 1775 setRex(current);
1638 if (rex_w()) AppendToBuffer("REX.W "); 1776 if (rex_w()) AppendToBuffer("REX.W ");
1639 } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3). 1777 } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3).
1640 group_1_prefix_ = current; 1778 group_1_prefix_ = current;
1641 } else if (current == VEX3_PREFIX) { 1779 } else if (current == VEX3_PREFIX) {
1642 vex_byte0_ = current; 1780 vex_byte0_ = current;
1643 vex_byte1_ = *(data + 1); 1781 vex_byte1_ = *(data + 1);
1644 vex_byte2_ = *(data + 2); 1782 vex_byte2_ = *(data + 2);
1645 setRex(0x40 | (~(vex_byte1_ >> 5) & 7) | ((vex_byte2_ >> 4) & 8)); 1783 setRex(0x40 | (~(vex_byte1_ >> 5) & 7) | ((vex_byte2_ >> 4) & 8));
1646 data += 2; 1784 data += 3;
1785 break; // Vex is the last prefix.
1647 } else if (current == VEX2_PREFIX) { 1786 } else if (current == VEX2_PREFIX) {
1648 vex_byte0_ = current; 1787 vex_byte0_ = current;
1649 vex_byte1_ = *(data + 1); 1788 vex_byte1_ = *(data + 1);
1650 setRex(0x40 | (~(vex_byte1_ >> 5) & 4)); 1789 setRex(0x40 | (~(vex_byte1_ >> 5) & 4));
1651 data++; 1790 data += 2;
1791 break; // Vex is the last prefix.
1652 } else { // Not a prefix - an opcode. 1792 } else { // Not a prefix - an opcode.
1653 break; 1793 break;
1654 } 1794 }
1655 data++; 1795 data++;
1656 } 1796 }
1657 1797
1658 // Decode AVX instructions. 1798 // Decode AVX instructions.
1659 if (vex_byte0_ != 0) { 1799 if (vex_byte0_ != 0) {
1660 processed = true; 1800 processed = true;
1661 data += AVXInstruction(data); 1801 data += AVXInstruction(data);
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
2176 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { 2316 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) {
2177 fprintf(f, " "); 2317 fprintf(f, " ");
2178 } 2318 }
2179 fprintf(f, " %s\n", buffer.start()); 2319 fprintf(f, " %s\n", buffer.start());
2180 } 2320 }
2181 } 2321 }
2182 2322
2183 } // namespace disasm 2323 } // namespace disasm
2184 2324
2185 #endif // V8_TARGET_ARCH_X64 2325 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64-inl.h ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698