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 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 ZERO_OPERANDS_INSTR, | 135 ZERO_OPERANDS_INSTR, |
136 TWO_OPERANDS_INSTR, | 136 TWO_OPERANDS_INSTR, |
137 JUMP_CONDITIONAL_SHORT_INSTR, | 137 JUMP_CONDITIONAL_SHORT_INSTR, |
138 REGISTER_INSTR, | 138 REGISTER_INSTR, |
139 PUSHPOP_INSTR, // Has implicit 64-bit operand size. | 139 PUSHPOP_INSTR, // Has implicit 64-bit operand size. |
140 MOVE_REG_INSTR, | 140 MOVE_REG_INSTR, |
141 CALL_JUMP_INSTR, | 141 CALL_JUMP_INSTR, |
142 SHORT_IMMEDIATE_INSTR | 142 SHORT_IMMEDIATE_INSTR |
143 }; | 143 }; |
144 | 144 |
145 | |
146 enum Prefixes { | 145 enum Prefixes { |
147 ESCAPE_PREFIX = 0x0F, | 146 ESCAPE_PREFIX = 0x0F, |
148 OPERAND_SIZE_OVERRIDE_PREFIX = 0x66, | 147 OPERAND_SIZE_OVERRIDE_PREFIX = 0x66, |
149 ADDRESS_SIZE_OVERRIDE_PREFIX = 0x67, | 148 ADDRESS_SIZE_OVERRIDE_PREFIX = 0x67, |
150 VEX3_PREFIX = 0xC4, | 149 VEX3_PREFIX = 0xC4, |
151 VEX2_PREFIX = 0xC5, | 150 VEX2_PREFIX = 0xC5, |
| 151 LOCK_PREFIX = 0xF0, |
152 REPNE_PREFIX = 0xF2, | 152 REPNE_PREFIX = 0xF2, |
153 REP_PREFIX = 0xF3, | 153 REP_PREFIX = 0xF3, |
154 REPEQ_PREFIX = REP_PREFIX | 154 REPEQ_PREFIX = REP_PREFIX |
155 }; | 155 }; |
156 | 156 |
157 | |
158 struct InstructionDesc { | 157 struct InstructionDesc { |
159 const char* mnem; | 158 const char* mnem; |
160 InstructionType type; | 159 InstructionType type; |
161 OperandType op_order_; | 160 OperandType op_order_; |
162 bool byte_size_operation; // Fixed 8-bit operation. | 161 bool byte_size_operation; // Fixed 8-bit operation. |
163 }; | 162 }; |
164 | 163 |
165 | 164 |
166 class InstructionTable { | 165 class InstructionTable { |
167 public: | 166 public: |
(...skipping 1432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1600 } else if (opcode == 0x72) { | 1599 } else if (opcode == 0x72) { |
1601 current += 1; | 1600 current += 1; |
1602 AppendToBuffer("%s %s,%d", (regop == 6) ? "pslld" : "psrld", | 1601 AppendToBuffer("%s %s,%d", (regop == 6) ? "pslld" : "psrld", |
1603 NameOfXMMRegister(rm), *current & 0x7f); | 1602 NameOfXMMRegister(rm), *current & 0x7f); |
1604 current += 1; | 1603 current += 1; |
1605 } else if (opcode == 0x73) { | 1604 } else if (opcode == 0x73) { |
1606 current += 1; | 1605 current += 1; |
1607 AppendToBuffer("%s %s,%d", (regop == 6) ? "psllq" : "psrlq", | 1606 AppendToBuffer("%s %s,%d", (regop == 6) ? "psllq" : "psrlq", |
1608 NameOfXMMRegister(rm), *current & 0x7f); | 1607 NameOfXMMRegister(rm), *current & 0x7f); |
1609 current += 1; | 1608 current += 1; |
| 1609 } else if (opcode == 0xB1) { |
| 1610 current += PrintOperands("cmpxchg", OPER_REG_OP_ORDER, current); |
1610 } else { | 1611 } else { |
1611 const char* mnemonic = "?"; | 1612 const char* mnemonic = "?"; |
1612 if (opcode == 0x54) { | 1613 if (opcode == 0x54) { |
1613 mnemonic = "andpd"; | 1614 mnemonic = "andpd"; |
1614 } else if (opcode == 0x56) { | 1615 } else if (opcode == 0x56) { |
1615 mnemonic = "orpd"; | 1616 mnemonic = "orpd"; |
1616 } else if (opcode == 0x57) { | 1617 } else if (opcode == 0x57) { |
1617 mnemonic = "xorpd"; | 1618 mnemonic = "xorpd"; |
1618 } else if (opcode == 0x2E) { | 1619 } else if (opcode == 0x2E) { |
1619 mnemonic = "ucomisd"; | 1620 mnemonic = "ucomisd"; |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1877 } | 1878 } |
1878 } else if (opcode == 0xB8 || opcode == 0xBC || opcode == 0xBD) { | 1879 } else if (opcode == 0xB8 || opcode == 0xBC || opcode == 0xBD) { |
1879 // POPCNT, CTZ, CLZ. | 1880 // POPCNT, CTZ, CLZ. |
1880 AppendToBuffer("%s%c ", mnemonic, operand_size_code()); | 1881 AppendToBuffer("%s%c ", mnemonic, operand_size_code()); |
1881 int mod, regop, rm; | 1882 int mod, regop, rm; |
1882 get_modrm(*current, &mod, ®op, &rm); | 1883 get_modrm(*current, &mod, ®op, &rm); |
1883 AppendToBuffer("%s,", NameOfCPURegister(regop)); | 1884 AppendToBuffer("%s,", NameOfCPURegister(regop)); |
1884 current += PrintRightOperand(current); | 1885 current += PrintRightOperand(current); |
1885 } else if (opcode == 0x0B) { | 1886 } else if (opcode == 0x0B) { |
1886 AppendToBuffer("ud2"); | 1887 AppendToBuffer("ud2"); |
| 1888 } else if (opcode == 0xB0 || opcode == 0xB1) { |
| 1889 // CMPXCHG. |
| 1890 if (opcode == 0xB0) { |
| 1891 byte_size_operand_ = true; |
| 1892 } |
| 1893 current += PrintOperands(mnemonic, OPER_REG_OP_ORDER, current); |
1887 } else { | 1894 } else { |
1888 UnimplementedInstruction(); | 1895 UnimplementedInstruction(); |
1889 } | 1896 } |
1890 return static_cast<int>(current - data); | 1897 return static_cast<int>(current - data); |
1891 } | 1898 } |
1892 | 1899 |
1893 | 1900 |
1894 // Mnemonics for two-byte opcode instructions starting with 0x0F. | 1901 // Mnemonics for two-byte opcode instructions starting with 0x0F. |
1895 // The argument is the second byte of the two-byte opcode. | 1902 // The argument is the second byte of the two-byte opcode. |
1896 // Returns NULL if the instruction is not handled here. | 1903 // Returns NULL if the instruction is not handled here. |
(...skipping 22 matching lines...) Expand all Loading... |
1919 case 0xA2: | 1926 case 0xA2: |
1920 return "cpuid"; | 1927 return "cpuid"; |
1921 case 0xA5: | 1928 case 0xA5: |
1922 return "shld"; | 1929 return "shld"; |
1923 case 0xAB: | 1930 case 0xAB: |
1924 return "bts"; | 1931 return "bts"; |
1925 case 0xAD: | 1932 case 0xAD: |
1926 return "shrd"; | 1933 return "shrd"; |
1927 case 0xAF: | 1934 case 0xAF: |
1928 return "imul"; | 1935 return "imul"; |
| 1936 case 0xB0: |
| 1937 case 0xB1: |
| 1938 return "cmpxchg"; |
1929 case 0xB6: | 1939 case 0xB6: |
1930 return "movzxb"; | 1940 return "movzxb"; |
1931 case 0xB7: | 1941 case 0xB7: |
1932 return "movzxw"; | 1942 return "movzxw"; |
1933 case 0xBC: | 1943 case 0xBC: |
1934 return "bsf"; | 1944 return "bsf"; |
1935 case 0xBD: | 1945 case 0xBD: |
1936 return "bsr"; | 1946 return "bsr"; |
1937 case 0xBE: | 1947 case 0xBE: |
1938 return "movsxb"; | 1948 return "movsxb"; |
(...skipping 17 matching lines...) Expand all Loading... |
1956 // Scan for prefixes. | 1966 // Scan for prefixes. |
1957 while (true) { | 1967 while (true) { |
1958 current = *data; | 1968 current = *data; |
1959 if (current == OPERAND_SIZE_OVERRIDE_PREFIX) { // Group 3 prefix. | 1969 if (current == OPERAND_SIZE_OVERRIDE_PREFIX) { // Group 3 prefix. |
1960 operand_size_ = current; | 1970 operand_size_ = current; |
1961 } else if ((current & 0xF0) == 0x40) { // REX prefix. | 1971 } else if ((current & 0xF0) == 0x40) { // REX prefix. |
1962 setRex(current); | 1972 setRex(current); |
1963 if (rex_w()) AppendToBuffer("REX.W "); | 1973 if (rex_w()) AppendToBuffer("REX.W "); |
1964 } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3). | 1974 } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3). |
1965 group_1_prefix_ = current; | 1975 group_1_prefix_ = current; |
| 1976 } else if (current == LOCK_PREFIX) { |
| 1977 AppendToBuffer("lock "); |
1966 } else if (current == VEX3_PREFIX) { | 1978 } else if (current == VEX3_PREFIX) { |
1967 vex_byte0_ = current; | 1979 vex_byte0_ = current; |
1968 vex_byte1_ = *(data + 1); | 1980 vex_byte1_ = *(data + 1); |
1969 vex_byte2_ = *(data + 2); | 1981 vex_byte2_ = *(data + 2); |
1970 setRex(0x40 | (~(vex_byte1_ >> 5) & 7) | ((vex_byte2_ >> 4) & 8)); | 1982 setRex(0x40 | (~(vex_byte1_ >> 5) & 7) | ((vex_byte2_ >> 4) & 8)); |
1971 data += 3; | 1983 data += 3; |
1972 break; // Vex is the last prefix. | 1984 break; // Vex is the last prefix. |
1973 } else if (current == VEX2_PREFIX) { | 1985 } else if (current == VEX2_PREFIX) { |
1974 vex_byte0_ = current; | 1986 vex_byte0_ = current; |
1975 vex_byte1_ = *(data + 1); | 1987 vex_byte1_ = *(data + 1); |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { | 2515 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { |
2504 fprintf(f, " "); | 2516 fprintf(f, " "); |
2505 } | 2517 } |
2506 fprintf(f, " %s\n", buffer.start()); | 2518 fprintf(f, " %s\n", buffer.start()); |
2507 } | 2519 } |
2508 } | 2520 } |
2509 | 2521 |
2510 } // namespace disasm | 2522 } // namespace disasm |
2511 | 2523 |
2512 #endif // V8_TARGET_ARCH_X64 | 2524 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |