OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 if (operand_size_ == 0x66) { | 1029 if (operand_size_ == 0x66) { |
1030 // 0x66 0x0F prefix. | 1030 // 0x66 0x0F prefix. |
1031 int mod, regop, rm; | 1031 int mod, regop, rm; |
1032 if (opcode == 0x3A) { | 1032 if (opcode == 0x3A) { |
1033 byte third_byte = *current; | 1033 byte third_byte = *current; |
1034 current = data + 3; | 1034 current = data + 3; |
1035 if (third_byte == 0x17) { | 1035 if (third_byte == 0x17) { |
1036 get_modrm(*current, &mod, ®op, &rm); | 1036 get_modrm(*current, &mod, ®op, &rm); |
1037 AppendToBuffer("extractps "); // reg/m32, xmm, imm8 | 1037 AppendToBuffer("extractps "); // reg/m32, xmm, imm8 |
1038 current += PrintRightOperand(current); | 1038 current += PrintRightOperand(current); |
1039 AppendToBuffer(", %s, %d", NameOfCPURegister(regop), (*current) & 3); | 1039 AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
1040 current += 1; | 1040 current += 1; |
1041 } else if (third_byte == 0x0b) { | 1041 } else if (third_byte == 0x0b) { |
1042 get_modrm(*current, &mod, ®op, &rm); | 1042 get_modrm(*current, &mod, ®op, &rm); |
1043 // roundsd xmm, xmm/m64, imm8 | 1043 // roundsd xmm, xmm/m64, imm8 |
1044 AppendToBuffer("roundsd %s, ", NameOfCPURegister(regop)); | 1044 AppendToBuffer("roundsd %s,", NameOfXMMRegister(regop)); |
1045 current += PrintRightOperand(current); | 1045 current += PrintRightXMMOperand(current); |
1046 AppendToBuffer(", %d", (*current) & 3); | 1046 AppendToBuffer(",%d", (*current) & 3); |
1047 current += 1; | 1047 current += 1; |
1048 } else { | 1048 } else { |
1049 UnimplementedInstruction(); | 1049 UnimplementedInstruction(); |
1050 } | 1050 } |
1051 } else { | 1051 } else { |
1052 get_modrm(*current, &mod, ®op, &rm); | 1052 get_modrm(*current, &mod, ®op, &rm); |
1053 if (opcode == 0x1f) { | 1053 if (opcode == 0x1f) { |
1054 current++; | 1054 current++; |
1055 if (rm == 4) { // SIB byte present. | 1055 if (rm == 4) { // SIB byte present. |
1056 current++; | 1056 current++; |
1057 } | 1057 } |
1058 if (mod == 1) { // Byte displacement. | 1058 if (mod == 1) { // Byte displacement. |
1059 current += 1; | 1059 current += 1; |
1060 } else if (mod == 2) { // 32-bit displacement. | 1060 } else if (mod == 2) { // 32-bit displacement. |
1061 current += 4; | 1061 current += 4; |
1062 } // else no immediate displacement. | 1062 } // else no immediate displacement. |
1063 AppendToBuffer("nop"); | 1063 AppendToBuffer("nop"); |
1064 } else if (opcode == 0x28) { | 1064 } else if (opcode == 0x28) { |
1065 AppendToBuffer("movapd %s, ", NameOfXMMRegister(regop)); | 1065 AppendToBuffer("movapd %s,", NameOfXMMRegister(regop)); |
1066 current += PrintRightXMMOperand(current); | 1066 current += PrintRightXMMOperand(current); |
1067 } else if (opcode == 0x29) { | 1067 } else if (opcode == 0x29) { |
1068 AppendToBuffer("movapd "); | 1068 AppendToBuffer("movapd "); |
1069 current += PrintRightXMMOperand(current); | 1069 current += PrintRightXMMOperand(current); |
1070 AppendToBuffer(", %s", NameOfXMMRegister(regop)); | 1070 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1071 } else if (opcode == 0x6E) { | 1071 } else if (opcode == 0x6E) { |
1072 AppendToBuffer("mov%c %s,", | 1072 AppendToBuffer("mov%c %s,", |
1073 rex_w() ? 'q' : 'd', | 1073 rex_w() ? 'q' : 'd', |
1074 NameOfXMMRegister(regop)); | 1074 NameOfXMMRegister(regop)); |
1075 current += PrintRightOperand(current); | 1075 current += PrintRightOperand(current); |
1076 } else if (opcode == 0x6F) { | 1076 } else if (opcode == 0x6F) { |
1077 AppendToBuffer("movdqa %s,", | 1077 AppendToBuffer("movdqa %s,", |
1078 NameOfXMMRegister(regop)); | 1078 NameOfXMMRegister(regop)); |
1079 current += PrintRightXMMOperand(current); | 1079 current += PrintRightXMMOperand(current); |
1080 } else if (opcode == 0x7E) { | 1080 } else if (opcode == 0x7E) { |
1081 AppendToBuffer("mov%c ", | 1081 AppendToBuffer("mov%c ", |
1082 rex_w() ? 'q' : 'd'); | 1082 rex_w() ? 'q' : 'd'); |
1083 current += PrintRightOperand(current); | 1083 current += PrintRightOperand(current); |
1084 AppendToBuffer(", %s", NameOfXMMRegister(regop)); | 1084 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1085 } else if (opcode == 0x7F) { | 1085 } else if (opcode == 0x7F) { |
1086 AppendToBuffer("movdqa "); | 1086 AppendToBuffer("movdqa "); |
1087 current += PrintRightXMMOperand(current); | 1087 current += PrintRightXMMOperand(current); |
1088 AppendToBuffer(", %s", NameOfXMMRegister(regop)); | 1088 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1089 } else if (opcode == 0xD6) { | 1089 } else if (opcode == 0xD6) { |
1090 AppendToBuffer("movq "); | 1090 AppendToBuffer("movq "); |
1091 current += PrintRightXMMOperand(current); | 1091 current += PrintRightXMMOperand(current); |
1092 AppendToBuffer(", %s", NameOfXMMRegister(regop)); | 1092 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1093 } else if (opcode == 0x50) { | 1093 } else if (opcode == 0x50) { |
1094 AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop)); | 1094 AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop)); |
1095 current += PrintRightXMMOperand(current); | 1095 current += PrintRightXMMOperand(current); |
1096 } else { | 1096 } else { |
1097 const char* mnemonic = "?"; | 1097 const char* mnemonic = "?"; |
1098 if (opcode == 0x54) { | 1098 if (opcode == 0x54) { |
1099 mnemonic = "andpd"; | 1099 mnemonic = "andpd"; |
1100 } else if (opcode == 0x56) { | 1100 } else if (opcode == 0x56) { |
1101 mnemonic = "orpd"; | 1101 mnemonic = "orpd"; |
1102 } else if (opcode == 0x57) { | 1102 } else if (opcode == 0x57) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 } else if (opcode == 0x5A) { | 1207 } else if (opcode == 0x5A) { |
1208 // CVTSS2SD: | 1208 // CVTSS2SD: |
1209 // Convert scalar single-precision FP to scalar double-precision FP. | 1209 // Convert scalar single-precision FP to scalar double-precision FP. |
1210 int mod, regop, rm; | 1210 int mod, regop, rm; |
1211 get_modrm(*current, &mod, ®op, &rm); | 1211 get_modrm(*current, &mod, ®op, &rm); |
1212 AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop)); | 1212 AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop)); |
1213 current += PrintRightXMMOperand(current); | 1213 current += PrintRightXMMOperand(current); |
1214 } else if (opcode == 0x7E) { | 1214 } else if (opcode == 0x7E) { |
1215 int mod, regop, rm; | 1215 int mod, regop, rm; |
1216 get_modrm(*current, &mod, ®op, &rm); | 1216 get_modrm(*current, &mod, ®op, &rm); |
1217 AppendToBuffer("movq %s, ", NameOfXMMRegister(regop)); | 1217 AppendToBuffer("movq %s,", NameOfXMMRegister(regop)); |
1218 current += PrintRightXMMOperand(current); | 1218 current += PrintRightXMMOperand(current); |
1219 } else { | 1219 } else { |
1220 UnimplementedInstruction(); | 1220 UnimplementedInstruction(); |
1221 } | 1221 } |
1222 } else if (opcode == 0x1F) { | 1222 } else if (opcode == 0x1F) { |
1223 // NOP | 1223 // NOP |
1224 int mod, regop, rm; | 1224 int mod, regop, rm; |
1225 get_modrm(*current, &mod, ®op, &rm); | 1225 get_modrm(*current, &mod, ®op, &rm); |
1226 current++; | 1226 current++; |
1227 if (rm == 4) { // SIB byte present. | 1227 if (rm == 4) { // SIB byte present. |
1228 current++; | 1228 current++; |
1229 } | 1229 } |
1230 if (mod == 1) { // Byte displacement. | 1230 if (mod == 1) { // Byte displacement. |
1231 current += 1; | 1231 current += 1; |
1232 } else if (mod == 2) { // 32-bit displacement. | 1232 } else if (mod == 2) { // 32-bit displacement. |
1233 current += 4; | 1233 current += 4; |
1234 } // else no immediate displacement. | 1234 } // else no immediate displacement. |
1235 AppendToBuffer("nop"); | 1235 AppendToBuffer("nop"); |
1236 | 1236 |
1237 } else if (opcode == 0x28) { | 1237 } else if (opcode == 0x28) { |
1238 // movaps xmm, xmm/m128 | 1238 // movaps xmm, xmm/m128 |
1239 int mod, regop, rm; | 1239 int mod, regop, rm; |
1240 get_modrm(*current, &mod, ®op, &rm); | 1240 get_modrm(*current, &mod, ®op, &rm); |
1241 AppendToBuffer("movaps %s, ", NameOfXMMRegister(regop)); | 1241 AppendToBuffer("movaps %s,", NameOfXMMRegister(regop)); |
1242 current += PrintRightXMMOperand(current); | 1242 current += PrintRightXMMOperand(current); |
1243 | 1243 |
1244 } else if (opcode == 0x29) { | 1244 } else if (opcode == 0x29) { |
1245 // movaps xmm/m128, xmm | 1245 // movaps xmm/m128, xmm |
1246 int mod, regop, rm; | 1246 int mod, regop, rm; |
1247 get_modrm(*current, &mod, ®op, &rm); | 1247 get_modrm(*current, &mod, ®op, &rm); |
1248 AppendToBuffer("movaps "); | 1248 AppendToBuffer("movaps "); |
1249 current += PrintRightXMMOperand(current); | 1249 current += PrintRightXMMOperand(current); |
1250 AppendToBuffer(", %s", NameOfXMMRegister(regop)); | 1250 AppendToBuffer(",%s", NameOfXMMRegister(regop)); |
1251 | 1251 |
1252 } else if (opcode == 0xA2) { | 1252 } else if (opcode == 0xA2) { |
1253 // CPUID | 1253 // CPUID |
1254 AppendToBuffer("%s", mnemonic); | 1254 AppendToBuffer("%s", mnemonic); |
1255 | 1255 |
1256 } else if ((opcode & 0xF0) == 0x40) { | 1256 } else if ((opcode & 0xF0) == 0x40) { |
1257 // CMOVcc: conditional move. | 1257 // CMOVcc: conditional move. |
1258 int condition = opcode & 0x0F; | 1258 int condition = opcode & 0x0F; |
1259 const InstructionDesc& idesc = cmov_instructions[condition]; | 1259 const InstructionDesc& idesc = cmov_instructions[condition]; |
1260 byte_size_operand_ = idesc.byte_size_operation; | 1260 byte_size_operand_ = idesc.byte_size_operation; |
1261 current += PrintOperands(idesc.mnem, idesc.op_order_, current); | 1261 current += PrintOperands(idesc.mnem, idesc.op_order_, current); |
1262 | 1262 |
1263 } else if (opcode == 0x57) { | 1263 } else if (opcode == 0x57) { |
1264 // xorps xmm, xmm/m128 | 1264 // xorps xmm, xmm/m128 |
1265 int mod, regop, rm; | 1265 int mod, regop, rm; |
1266 get_modrm(*current, &mod, ®op, &rm); | 1266 get_modrm(*current, &mod, ®op, &rm); |
1267 AppendToBuffer("xorps %s, ", NameOfXMMRegister(regop)); | 1267 AppendToBuffer("xorps %s,", NameOfXMMRegister(regop)); |
1268 current += PrintRightXMMOperand(current); | 1268 current += PrintRightXMMOperand(current); |
1269 | 1269 |
1270 } else if (opcode == 0x50) { | 1270 } else if (opcode == 0x50) { |
1271 // movmskps reg, xmm | 1271 // movmskps reg, xmm |
1272 int mod, regop, rm; | 1272 int mod, regop, rm; |
1273 get_modrm(*current, &mod, ®op, &rm); | 1273 get_modrm(*current, &mod, ®op, &rm); |
1274 AppendToBuffer("movmskps %s, ", NameOfCPURegister(regop)); | 1274 AppendToBuffer("movmskps %s,", NameOfCPURegister(regop)); |
1275 current += PrintRightXMMOperand(current); | 1275 current += PrintRightXMMOperand(current); |
1276 | 1276 |
1277 } else if ((opcode & 0xF0) == 0x80) { | 1277 } else if ((opcode & 0xF0) == 0x80) { |
1278 // Jcc: Conditional jump (branch). | 1278 // Jcc: Conditional jump (branch). |
1279 current = data + JumpConditional(data); | 1279 current = data + JumpConditional(data); |
1280 | 1280 |
1281 } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 || | 1281 } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 || |
1282 opcode == 0xB7 || opcode == 0xAF) { | 1282 opcode == 0xB7 || opcode == 0xAF) { |
1283 // Size-extending moves, IMUL. | 1283 // Size-extending moves, IMUL. |
1284 current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current); | 1284 current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1443 case CALL_JUMP_INSTR: { | 1443 case CALL_JUMP_INSTR: { |
1444 byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5; | 1444 byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5; |
1445 AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr)); | 1445 AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr)); |
1446 data += 5; | 1446 data += 5; |
1447 break; | 1447 break; |
1448 } | 1448 } |
1449 | 1449 |
1450 case SHORT_IMMEDIATE_INSTR: { | 1450 case SHORT_IMMEDIATE_INSTR: { |
1451 byte* addr = | 1451 byte* addr = |
1452 reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1)); | 1452 reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1)); |
1453 AppendToBuffer("%s rax, %s", idesc.mnem, NameOfAddress(addr)); | 1453 AppendToBuffer("%s rax,%s", idesc.mnem, NameOfAddress(addr)); |
1454 data += 5; | 1454 data += 5; |
1455 break; | 1455 break; |
1456 } | 1456 } |
1457 | 1457 |
1458 case NO_INSTR: | 1458 case NO_INSTR: |
1459 processed = false; | 1459 processed = false; |
1460 break; | 1460 break; |
1461 | 1461 |
1462 default: | 1462 default: |
1463 UNIMPLEMENTED(); // This type is not implemented. | 1463 UNIMPLEMENTED(); // This type is not implemented. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1592 case 0x92: | 1592 case 0x92: |
1593 case 0x93: | 1593 case 0x93: |
1594 case 0x94: | 1594 case 0x94: |
1595 case 0x95: | 1595 case 0x95: |
1596 case 0x96: | 1596 case 0x96: |
1597 case 0x97: { | 1597 case 0x97: { |
1598 int reg = (*data & 0x7) | (rex_b() ? 8 : 0); | 1598 int reg = (*data & 0x7) | (rex_b() ? 8 : 0); |
1599 if (reg == 0) { | 1599 if (reg == 0) { |
1600 AppendToBuffer("nop"); // Common name for xchg rax,rax. | 1600 AppendToBuffer("nop"); // Common name for xchg rax,rax. |
1601 } else { | 1601 } else { |
1602 AppendToBuffer("xchg%c rax, %s", | 1602 AppendToBuffer("xchg%c rax,%s", |
1603 operand_size_code(), | 1603 operand_size_code(), |
1604 NameOfCPURegister(reg)); | 1604 NameOfCPURegister(reg)); |
1605 } | 1605 } |
1606 data++; | 1606 data++; |
1607 } | 1607 } |
1608 break; | 1608 break; |
1609 case 0xB0: | 1609 case 0xB0: |
1610 case 0xB1: | 1610 case 0xB1: |
1611 case 0xB2: | 1611 case 0xB2: |
1612 case 0xB3: | 1612 case 0xB3: |
1613 case 0xB4: | 1613 case 0xB4: |
1614 case 0xB5: | 1614 case 0xB5: |
1615 case 0xB6: | 1615 case 0xB6: |
1616 case 0xB7: | 1616 case 0xB7: |
1617 case 0xB8: | 1617 case 0xB8: |
1618 case 0xB9: | 1618 case 0xB9: |
1619 case 0xBA: | 1619 case 0xBA: |
1620 case 0xBB: | 1620 case 0xBB: |
1621 case 0xBC: | 1621 case 0xBC: |
1622 case 0xBD: | 1622 case 0xBD: |
1623 case 0xBE: | 1623 case 0xBE: |
1624 case 0xBF: { | 1624 case 0xBF: { |
1625 // mov reg8,imm8 or mov reg32,imm32 | 1625 // mov reg8,imm8 or mov reg32,imm32 |
1626 byte opcode = *data; | 1626 byte opcode = *data; |
1627 data++; | 1627 data++; |
1628 bool is_32bit = (opcode >= 0xB8); | 1628 bool is_32bit = (opcode >= 0xB8); |
1629 int reg = (opcode & 0x7) | (rex_b() ? 8 : 0); | 1629 int reg = (opcode & 0x7) | (rex_b() ? 8 : 0); |
1630 if (is_32bit) { | 1630 if (is_32bit) { |
1631 AppendToBuffer("mov%c %s, ", | 1631 AppendToBuffer("mov%c %s,", |
1632 operand_size_code(), | 1632 operand_size_code(), |
1633 NameOfCPURegister(reg)); | 1633 NameOfCPURegister(reg)); |
1634 data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE); | 1634 data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE); |
1635 } else { | 1635 } else { |
1636 AppendToBuffer("movb %s, ", | 1636 AppendToBuffer("movb %s,", |
1637 NameOfByteCPURegister(reg)); | 1637 NameOfByteCPURegister(reg)); |
1638 data += PrintImmediate(data, OPERAND_BYTE_SIZE); | 1638 data += PrintImmediate(data, OPERAND_BYTE_SIZE); |
1639 } | 1639 } |
1640 break; | 1640 break; |
1641 } | 1641 } |
1642 case 0xFE: { | 1642 case 0xFE: { |
1643 data++; | 1643 data++; |
1644 int mod, regop, rm; | 1644 int mod, regop, rm; |
1645 get_modrm(*data, &mod, ®op, &rm); | 1645 get_modrm(*data, &mod, ®op, &rm); |
1646 if (regop == 1) { | 1646 if (regop == 1) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1748 data += JumpShort(data); | 1748 data += JumpShort(data); |
1749 break; | 1749 break; |
1750 | 1750 |
1751 case 0xF6: | 1751 case 0xF6: |
1752 byte_size_operand_ = true; // fall through | 1752 byte_size_operand_ = true; // fall through |
1753 case 0xF7: | 1753 case 0xF7: |
1754 data += F6F7Instruction(data); | 1754 data += F6F7Instruction(data); |
1755 break; | 1755 break; |
1756 | 1756 |
1757 case 0x3C: | 1757 case 0x3C: |
1758 AppendToBuffer("cmp al, 0x%x", *reinterpret_cast<int8_t*>(data + 1)); | 1758 AppendToBuffer("cmp al,0x%x", *reinterpret_cast<int8_t*>(data + 1)); |
1759 data +=2; | 1759 data +=2; |
1760 break; | 1760 break; |
1761 | 1761 |
1762 default: | 1762 default: |
1763 UnimplementedInstruction(); | 1763 UnimplementedInstruction(); |
1764 data += 1; | 1764 data += 1; |
1765 } | 1765 } |
1766 } // !processed | 1766 } // !processed |
1767 | 1767 |
1768 if (tmp_buffer_pos_ < sizeof tmp_buffer_) { | 1768 if (tmp_buffer_pos_ < sizeof tmp_buffer_) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1885 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { | 1885 for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { |
1886 fprintf(f, " "); | 1886 fprintf(f, " "); |
1887 } | 1887 } |
1888 fprintf(f, " %s\n", buffer.start()); | 1888 fprintf(f, " %s\n", buffer.start()); |
1889 } | 1889 } |
1890 } | 1890 } |
1891 | 1891 |
1892 } // namespace disasm | 1892 } // namespace disasm |
1893 | 1893 |
1894 #endif // V8_TARGET_ARCH_X64 | 1894 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |