Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <getopt.h> | 8 #include <getopt.h> |
| 9 #include <libgen.h> | 9 #include <libgen.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| (...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1245 c_identifier(pair.first).c_str(), pair.second); | 1245 c_identifier(pair.first).c_str(), pair.second); |
| 1246 } | 1246 } |
| 1247 } | 1247 } |
| 1248 | 1248 |
| 1249 class MarkedInstruction : Instruction { | 1249 class MarkedInstruction : Instruction { |
| 1250 public: | 1250 public: |
| 1251 /* Additional marks are created in the process of parsing. */ | 1251 /* Additional marks are created in the process of parsing. */ |
| 1252 explicit MarkedInstruction(Instruction instruction_) : | 1252 explicit MarkedInstruction(Instruction instruction_) : |
| 1253 Instruction(instruction_), | 1253 Instruction(instruction_), |
| 1254 instruction_class(get_instruction_class(instruction_)), | 1254 instruction_class(get_instruction_class(instruction_)), |
| 1255 rex { }, opcode_in_modrm(false), opcode_in_imm(false) { | 1255 rex { }, opcode_in_modrm(false), opcode_in_imm(false), |
| 1256 rm_half_enabled(false) { | |
| 1256 if (has_flag("branch_hint")) { | 1257 if (has_flag("branch_hint")) { |
| 1257 optional_prefixes.insert("branch_hint"); | 1258 optional_prefixes.insert("branch_hint"); |
| 1258 } | 1259 } |
| 1259 if (has_flag("condrep")) { | 1260 if (has_flag("condrep")) { |
| 1260 optional_prefixes.insert("condrep"); | 1261 optional_prefixes.insert("condrep"); |
| 1261 } | 1262 } |
| 1262 if (has_flag("rep")) { | 1263 if (has_flag("rep")) { |
| 1263 optional_prefixes.insert("rep"); | 1264 optional_prefixes.insert("rep"); |
| 1264 } | 1265 } |
| 1265 for (auto opcode_it = opcodes.begin(); | 1266 for (auto opcode_it = opcodes.begin(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1379 std::multiset<std::string> required_prefixes; | 1380 std::multiset<std::string> required_prefixes; |
| 1380 std::multiset<std::string> optional_prefixes; | 1381 std::multiset<std::string> optional_prefixes; |
| 1381 struct { | 1382 struct { |
| 1382 bool b : 1; | 1383 bool b : 1; |
| 1383 bool x : 1; | 1384 bool x : 1; |
| 1384 bool r : 1; | 1385 bool r : 1; |
| 1385 bool w : 1; | 1386 bool w : 1; |
| 1386 } rex; | 1387 } rex; |
| 1387 bool opcode_in_modrm : 1; | 1388 bool opcode_in_modrm : 1; |
| 1388 bool opcode_in_imm : 1; | 1389 bool opcode_in_imm : 1; |
| 1390 bool rm_half_enabled : 1; | |
| 1389 | 1391 |
| 1390 static InstructionClass get_instruction_class( | 1392 static InstructionClass get_instruction_class( |
| 1391 const Instruction &instruction) { | 1393 const Instruction &instruction) { |
| 1392 InstructionClass instruction_class = InstructionClass::kUnknown; | 1394 InstructionClass instruction_class = InstructionClass::kUnknown; |
| 1393 for (auto operand_it = instruction.operands.begin(); | 1395 for (auto operand_it = instruction.operands.begin(); |
| 1394 operand_it != instruction.operands.end(); ++operand_it) { | 1396 operand_it != instruction.operands.end(); ++operand_it) { |
| 1395 auto &operand = *operand_it; | 1397 auto &operand = *operand_it; |
| 1396 static const std::map<std::string, InstructionClass> classes_map { | 1398 static const std::map<std::string, InstructionClass> classes_map { |
| 1397 /* 'size8' is special 'prefix' not included in AMD manual: w bit in | 1399 /* 'size8' is special 'prefix' not included in AMD manual: w bit in |
| 1398 opcode switches between 8bit and 16/32/64 bit versions. M is just | 1400 opcode switches between 8bit and 16/32/64 bit versions. M is just |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1684 print_legacy_prefixes(); | 1686 print_legacy_prefixes(); |
| 1685 print_rex_prefix(); | 1687 print_rex_prefix(); |
| 1686 print_opcode_nomodrm(); | 1688 print_opcode_nomodrm(); |
| 1687 if (opcode_in_imm) { | 1689 if (opcode_in_imm) { |
| 1688 print_immediate_opcode(); | 1690 print_immediate_opcode(); |
| 1689 print_opcode_recognition(false); | 1691 print_opcode_recognition(false); |
| 1690 } else { | 1692 } else { |
| 1691 print_opcode_recognition(false); | 1693 print_opcode_recognition(false); |
| 1692 print_immediate_arguments(); | 1694 print_immediate_arguments(); |
| 1693 } | 1695 } |
| 1696 print_instruction_processing(); | |
| 1694 } | 1697 } |
| 1695 | 1698 |
| 1696 void print_one_size_definition_modrm_register(void) { | 1699 void print_one_size_definition_modrm_register(void) { |
| 1697 print_operator_delimiter(); | 1700 print_operator_delimiter(); |
| 1698 if (mod_reg_is_used()) { | 1701 if (mod_reg_is_used()) { |
| 1699 rex.r = true; | 1702 rex.r = true; |
| 1700 } | 1703 } |
| 1701 if (mod_rm_is_used()) { | 1704 if (mod_rm_is_used()) { |
| 1702 rex.b = true; | 1705 rex.b = true; |
| 1703 } | 1706 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1742 } | 1745 } |
| 1743 if (opcode_in_modrm) { | 1746 if (opcode_in_modrm) { |
| 1744 fprintf(out_file, ")"); | 1747 fprintf(out_file, ")"); |
| 1745 } | 1748 } |
| 1746 if (opcode_in_imm) { | 1749 if (opcode_in_imm) { |
| 1747 print_immediate_opcode(); | 1750 print_immediate_opcode(); |
| 1748 print_opcode_recognition(false); | 1751 print_opcode_recognition(false); |
| 1749 } else { | 1752 } else { |
| 1750 print_immediate_arguments(); | 1753 print_immediate_arguments(); |
| 1751 } | 1754 } |
| 1755 print_instruction_processing(); | |
| 1752 } | 1756 } |
| 1753 | 1757 |
| 1754 void print_one_size_definition_modrm_memory(void) { | 1758 void print_one_size_definition_modrm_memory(void) { |
| 1755 typedef std::tuple<const char *, bool, bool> T; | 1759 typedef std::tuple<const char *, bool, bool> T; |
| 1756 static const T modes[] = { | 1760 static const T modes[] = { |
| 1757 T { " operand_disp", false, true }, | 1761 T { " operand_disp", false, true }, |
| 1758 T { " operand_rip", false, false }, | 1762 T { " operand_rip", false, false }, |
| 1759 T { " single_register_memory", false, true }, | 1763 T { " single_register_memory", false, true }, |
| 1760 T { " operand_sib_pure_index", true, false }, | 1764 T { " operand_sib_pure_index", true, false }, |
| 1761 T { " operand_sib_base_index", true, true } | 1765 T { " operand_sib_base_index", true, true } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1796 { 'P', "from_modrm_reg" }, | 1800 { 'P', "from_modrm_reg" }, |
| 1797 { 'Q', "rm" }, | 1801 { 'Q', "rm" }, |
| 1798 { 'R', "rm" }, | 1802 { 'R', "rm" }, |
| 1799 { 'S', "from_modrm_reg_norex" }, | 1803 { 'S', "from_modrm_reg_norex" }, |
| 1800 { 'U', "rm" }, | 1804 { 'U', "rm" }, |
| 1801 { 'V', "from_modrm_reg" }, | 1805 { 'V', "from_modrm_reg" }, |
| 1802 { 'W', "rm" } | 1806 { 'W', "rm" } |
| 1803 }; | 1807 }; |
| 1804 if (operand.enabled) { | 1808 if (operand.enabled) { |
| 1805 auto it = operand_type.find(operand.source); | 1809 auto it = operand_type.find(operand.source); |
| 1806 if (it != operand_type.end() && | 1810 if (it != operand_type.end()) { |
| 1807 (strcmp(it->second, "rm") || | 1811 if (enabled(Actions::kParseOperandPositions) || |
| 1808 enabled(Actions::kParseOperandPositions))) { | 1812 strcmp(it->second, "rm")) { |
| 1809 fprintf(out_file, " @operand%zd_%s", operand_index, it->second); | 1813 fprintf(out_file, " @operand%zd_%s", operand_index, it->second ); |
|
pasko-google - do not use
2012/05/12 13:54:31
80
pasko-google - do not use
2012/05/12 13:54:31
80
| |
| 1814 } else { | |
| 1815 rm_half_enabled = true; | |
|
pasko-google - do not use
2012/05/12 13:54:31
if (enabled(Actions::kParseOperandPositions) || op
khim
2012/05/12 14:32:16
Done.
| |
| 1816 } | |
| 1810 } | 1817 } |
| 1811 } | 1818 } |
| 1812 if (operand.enabled || enabled(Actions::kParseOperandPositions)) { | 1819 if (operand.enabled || enabled(Actions::kParseOperandPositions)) { |
| 1813 ++operand_index; | 1820 ++operand_index; |
| 1814 } | 1821 } |
| 1815 } | 1822 } |
| 1816 } | 1823 } |
| 1817 fprintf(out_file, " . any* &%s", std::get<0>(mode)); | 1824 fprintf(out_file, " . any* &%s", std::get<0>(mode)); |
| 1818 if (enabled(Actions::kCheckAccess) && !has_flag("no_memory_access")) { | 1825 if (enabled(Actions::kCheckAccess) && !has_flag("no_memory_access")) { |
| 1819 fprintf(out_file, " @check_access"); | 1826 fprintf(out_file, " @check_access"); |
| 1820 } | 1827 } |
| 1821 fprintf(out_file, ")"); | 1828 fprintf(out_file, ")"); |
| 1822 if (opcode_in_imm) { | 1829 if (opcode_in_imm) { |
| 1823 print_immediate_opcode(); | 1830 print_immediate_opcode(); |
| 1824 print_opcode_recognition(true); | 1831 print_opcode_recognition(true); |
| 1825 } else { | 1832 } else { |
| 1826 print_immediate_arguments(); | 1833 print_immediate_arguments(); |
| 1827 } | 1834 } |
| 1835 print_instruction_processing(); | |
| 1828 } | 1836 } |
| 1829 } | 1837 } |
| 1830 | 1838 |
| 1831 static bool first_delimiter; | 1839 static bool first_delimiter; |
| 1832 void print_operator_delimiter(void) { | 1840 void print_operator_delimiter(void) { |
| 1833 if (first_delimiter) { | 1841 if (first_delimiter) { |
| 1834 fprintf(out_file, "\n ("); | 1842 fprintf(out_file, "\n ("); |
| 1835 } else { | 1843 } else { |
| 1836 fprintf(out_file, ") |\n ("); | 1844 fprintf(out_file, ") |\n ("); |
| 1837 } | 1845 } |
| 1838 first_delimiter = false; | 1846 first_delimiter = false; |
| 1839 } | 1847 } |
| 1840 | 1848 |
| 1849 void print_instruction_processing() { | |
|
pasko-google - do not use
2012/05/12 13:54:31
print_inst_end_actions
khim
2012/05/12 14:32:16
Done.
| |
| 1850 if (enabled(Actions::kParseOperands)) { | |
| 1851 if (!enabled(Actions::kParseOperandPositions)) { | |
| 1852 int operands_count = rm_half_enabled ? -1 : 0; | |
| 1853 for (auto operand_it = operands.begin(); | |
| 1854 operand_it != operands.end(); ++operand_it) { | |
| 1855 auto &operand = *operand_it; | |
| 1856 if (operand.enabled) { | |
| 1857 ++operands_count; | |
| 1858 } | |
| 1859 } | |
| 1860 fprintf(out_file, " @process_%d_operands", operands_count); | |
| 1861 } | |
| 1862 } | |
| 1863 } | |
| 1864 | |
| 1841 bool mod_reg_is_used() { | 1865 bool mod_reg_is_used() { |
| 1842 for (auto operand_it = operands.begin(); | 1866 for (auto operand_it = operands.begin(); |
| 1843 operand_it != operands.end(); ++operand_it) { | 1867 operand_it != operands.end(); ++operand_it) { |
| 1844 auto &operand = *operand_it; | 1868 auto &operand = *operand_it; |
| 1845 if (operand.source == 'C' && | 1869 if (operand.source == 'C' && |
| 1846 required_prefixes.find("0xf0") == required_prefixes.end()) { | 1870 required_prefixes.find("0xf0") == required_prefixes.end()) { |
| 1847 return true; | 1871 return true; |
| 1848 } | 1872 } |
| 1849 static const char cc[] = { 'G', 'P', 'V' }; | 1873 static const char cc[] = { 'G', 'P', 'V' }; |
| 1850 for (size_t c_it = 0; c_it < arraysize(cc); ++c_it) { | 1874 for (size_t c_it = 0; c_it < arraysize(cc); ++c_it) { |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2660 | 2684 |
| 2661 fprintf(out_file, "\n one_instruction ="); | 2685 fprintf(out_file, "\n one_instruction ="); |
| 2662 | 2686 |
| 2663 print_one_instruction_definition(); | 2687 print_one_instruction_definition(); |
| 2664 | 2688 |
| 2665 fprintf(out_file, ");\n" | 2689 fprintf(out_file, ");\n" |
| 2666 "}%%%%\n" | 2690 "}%%%%\n" |
| 2667 ""); | 2691 ""); |
| 2668 return 0; | 2692 return 0; |
| 2669 } | 2693 } |
| OLD | NEW |