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

Side by Side Diff: src/trusted/validator_ragel/unreviewed/gen-dfa.cc

Issue 9968039: Add ragel machine generators to SCONS (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 8 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 | Annotate | Revision Log
OLDNEW
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>
11 #include <stdlib.h> 11 #include <stdlib.h>
12 #include <string.h> 12 #include <string.h>
13 13
14 #include <algorithm> 14 #include <algorithm>
15 #include <iterator>
15 #include <map> 16 #include <map>
16 #include <set> 17 #include <set>
17 #include <string> 18 #include <string>
18 #include <tuple> 19 #include <tuple>
19 #include <vector> 20 #include <vector>
20 21
22 #ifndef NACL_TRUSTED_BUT_NOT_TCB
23 #error("This file is not meant for use in the TCB")
24 #endif
25
26 #ifdef __GNUC__
27 /* We use operand number formats here. They are defined in SUSv2 and supported
28 on all POSIX systems (including all versions of Linux and MacOS), yet
29 -pedantic warns about them. */
30 #pragma GCC diagnostic ignored "-Wformat"
31 /* GCC complains even when we explicitly use empty initializer list. Can be
32 easily fixed with data member initializers, but this requires GCC 4.7+. */
33 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
34 /* Default is perfectly valid way to handle missing cases. Especially if we
35 only care about very few non-default ones as often here. */
36 #pragma GCC diagnostic ignored "-Wswitch-enum"
37 #pragma GCC diagnostic error "-Wswitch"
38 #endif
39
21 template <typename T, size_t N> 40 template <typename T, size_t N>
22 char (&ArraySizeHelper(T (&array)[N]))[N]; 41 char (&ArraySizeHelper(T (&array)[N]))[N];
23 #define arraysize(array) (sizeof(ArraySizeHelper(array))) 42 #define arraysize(array) (sizeof(ArraySizeHelper(array)))
24 43
25 namespace { 44 namespace {
26 const char* short_program_name; 45 const char* short_program_name;
27 46
28 const struct option kProgramOptions[] = { 47 const struct option kProgramOptions[] = {
29 {"mode", required_argument, NULL, 'm'}, 48 {"mode", required_argument, NULL, 'm'},
30 {"disable", required_argument, NULL, 'd'}, 49 {"disable", required_argument, NULL, 'd'},
31 {"output", required_argument, NULL, 'o'}, 50 {"output", required_argument, NULL, 'o'},
32 {"help", no_argument, NULL, 'h'}, 51 {"const_file", required_argument, NULL, 'c'},
33 {"version", no_argument, NULL, 'v'}, 52 {"help", no_argument, NULL, 'h'},
34 {NULL, 0, NULL, 0} 53 {"version", no_argument, NULL, 'v'},
54 {NULL, 0, NULL, 0}
35 }; 55 };
36 56
37 const char kVersion[] = "0.0"; 57 const char kVersion[] = "0.0";
38 58
39 const char* const kProgramHelp = "Usage: %1$s [OPTION]... [FILE]...\n" 59 const char* const kProgramHelp = "Usage: %1$s [OPTION]... [FILE]...\n"
40 "\n" 60 "\n"
41 "Creates ragel machine which recognizes instructions listed in given files.\n" 61 "Creates ragel machine which recognizes instructions listed in given files.\n"
42 "\n" 62 "\n"
43 "Mandatory arguments to long options are mandatory for short options too.\n" 63 "Mandatory arguments to long options are mandatory for short options too.\n"
44 "\n" 64 "\n"
45 "Options list:\n" 65 "Options list:\n"
46 " -m, --mode=mode CPU mode: ia32 for IA32, amd64 for x86-64\n" 66 " -m, --mode=mode CPU mode: ia32 for IA32, amd64 for x86-64\n"
47 " -d, --disable=action_list disable actions from the comma-separated list\n" 67 " -d, --disable=action_list disable actions from the comma-separated list\n"
48 " -o, --output=FILE write result to FILE instead of standard output\n" 68 " -o, --output=FILE write result to FILE instead of standard output\n"
69 " -c, --const_file=FILE wrire result of FILE instead of standard output\n"
49 " -h, --help display this help and exit\n" 70 " -h, --help display this help and exit\n"
50 " -v, --version output version information and exit\n" 71 " -v, --version output version information and exit\n"
51 "\n" 72 "\n"
52 "Here is the full list of possible action types with short descrion of places\n" 73 "Here is the full list of possible action types with short descrion of places\n"
53 "where they are insered:\n" 74 "where they are insered:\n"
54 " rex_prefix triggered when legacy REX prefix is parsed\n" 75 " rex_prefix triggered when legacy REX prefix is parsed\n"
55 " @rex_prefix inserted after possible REX prefix\n" 76 " @rex_prefix inserted after possible REX prefix\n"
56 " vex_prefix triggered when VEX-encoded action is detected\n" 77 " vex_prefix triggered when VEX-encoded action is detected\n"
57 " @vex_prefix2 inserted after second byte of 3-byte VEX/XOP prefix\n" 78 " @vex_prefix2 inserted after second byte of 3-byte VEX/XOP prefix\n"
58 " @vex_prefix3 inserted after third byte of 3-byte VEX/XOP prefix\n" 79 " @vex_prefix3 inserted after third byte of 3-byte VEX/XOP prefix\n"
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 /* Flags for enabling/disabling based on architecture and validity. */ 203 /* Flags for enabling/disabling based on architecture and validity. */
183 "ia32", 204 "ia32",
184 "amd64", 205 "amd64",
185 "nacl-ia32-forbidden", 206 "nacl-ia32-forbidden",
186 "nacl-amd64-forbidden", 207 "nacl-amd64-forbidden",
187 "nacl-forbidden" 208 "nacl-forbidden"
188 }; 209 };
189 210
190 class Instruction { 211 class Instruction {
191 public: 212 public:
192 static bool check_flag_valid(const std::string &flag) { 213 static void check_flag_valid(const std::string &flag) {
193 if (all_instruction_flags.find(flag) == all_instruction_flags.end()) { 214 if (all_instruction_flags.find(flag) == all_instruction_flags.end()) {
194 fprintf(stderr, "%s: unknown flag: '%s'\n", 215 fprintf(stderr, "%s: unknown flag: '%s'\n",
195 short_program_name, flag.c_str()); 216 short_program_name, flag.c_str());
196 exit(1); 217 exit(1);
197 } 218 }
198 } 219 }
199 220
200 void add_flag(const std::string &flag) { 221 void add_flag(const std::string &flag) {
201 check_flag_valid(flag); 222 check_flag_valid(flag);
202 flags.insert(flag); 223 flags.insert(flag);
(...skipping 14 matching lines...) Expand all
217 }; 238 };
218 std::vector<Operand> operands; 239 std::vector<Operand> operands;
219 std::vector<std::string> opcodes; 240 std::vector<std::string> opcodes;
220 std::set<std::string> flags; 241 std::set<std::string> flags;
221 }; 242 };
222 std::vector<Instruction> instructions; 243 std::vector<Instruction> instructions;
223 244
224 FILE *out_file = stdout; 245 FILE *out_file = stdout;
225 FILE *const_file = stdout; 246 FILE *const_file = stdout;
226 char *out_file_name = NULL; 247 char *out_file_name = NULL;
248 char *const_file_name = NULL;
227 249
228 auto ia32_mode = true; 250 auto ia32_mode = true;
229 251
230 std::string read_file(const char *filename) { 252 std::string read_file(const char *filename) {
231 std::string file_content; 253 std::string file_content;
232 auto file = open(filename, O_RDONLY); 254 auto file = open(filename, O_RDONLY);
233 char buf[1024]; 255 char buf[1024];
234 ssize_t count; 256 ssize_t count;
235 257
236 if (file == -1) { 258 if (file == -1) {
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 } 583 }
562 } 584 }
563 return name; 585 return name;
564 } 586 }
565 587
566 void print_common_decoding(void) { 588 void print_common_decoding(void) {
567 if (enabled(Actions::kRelOperandAction)) { 589 if (enabled(Actions::kRelOperandAction)) {
568 fprintf(out_file, " action rel8_operand {\n" 590 fprintf(out_file, " action rel8_operand {\n"
569 " operand0 = JMP_TO;\n" 591 " operand0 = JMP_TO;\n"
570 " base = REG_RIP;\n" 592 " base = REG_RIP;\n"
571 " index = REG_NONE;\n" 593 " index = NO_REG;\n"
572 " scale = 0;\n" 594 " scale = 0;\n"
573 " disp_type = DISP8;\n" 595 " disp_type = DISP8;\n"
574 " disp = p;\n" 596 " disp = p;\n"
575 " }\n" 597 " }\n"
576 " action rel16_operand {\n" 598 " action rel16_operand {\n"
577 " operand0 = JMP_TO;\n" 599 " operand0 = JMP_TO;\n"
578 " base = REG_RIP;\n" 600 " base = REG_RIP;\n"
579 " index = REG_NONE;\n" 601 " index = NO_REG;\n"
580 " scale = 0;\n" 602 " scale = 0;\n"
581 " disp_type = DISP16;\n" 603 " disp_type = DISP16;\n"
582 " disp = p - 1;\n" 604 " disp = p - 1;\n"
583 " }\n" 605 " }\n"
584 " action rel32_operand {\n" 606 " action rel32_operand {\n"
585 " operand0 = JMP_TO;\n" 607 " operand0 = JMP_TO;\n"
586 " base = REG_RIP;\n" 608 " base = REG_RIP;\n"
587 " index = REG_NONE;\n" 609 " index = NO_REG;\n"
588 " scale = 0;\n" 610 " scale = 0;\n"
589 " disp_type = DISP32;\n" 611 " disp_type = DISP32;\n"
590 " disp = p - 3;\n" 612 " disp = p - 3;\n"
591 " }\n" 613 " }\n"
592 ""); 614 "");
593 } 615 }
594 fprintf(out_file, 616 fprintf(out_file,
595 " action branch_not_taken {\n" 617 " action branch_not_taken {\n"
596 " branch_not_taken = TRUE;\n" 618 " branch_not_taken = TRUE;\n"
597 " }\n" 619 " }\n"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 " action imm64_second_operand {\n" 700 " action imm64_second_operand {\n"
679 " imm2_operand = IMM64;\n" 701 " imm2_operand = IMM64;\n"
680 " imm2 = p - 7;\n" 702 " imm2 = p - 7;\n"
681 " }\n" 703 " }\n"
682 ""); 704 "");
683 } 705 }
684 if (enabled(Actions::kParseOperands)) { 706 if (enabled(Actions::kParseOperands)) {
685 if (ia32_mode) { 707 if (ia32_mode) {
686 fprintf(out_file, " action modrm_only_base {\n" 708 fprintf(out_file, " action modrm_only_base {\n"
687 " disp_type = DISPNONE;\n" 709 " disp_type = DISPNONE;\n"
688 " index = REG_NONE;\n" 710 " index = NO_REG;\n"
689 " base = (*p) & 0x07;\n" 711 " base = (*p) & 0x07;\n"
690 " scale = 0;\n" 712 " scale = 0;\n"
691 " }\n" 713 " }\n"
692 " action modrm_base_disp {\n" 714 " action modrm_base_disp {\n"
693 " index = REG_NONE;\n" 715 " index = NO_REG;\n"
694 " base = (*p) & 0x07;\n" 716 " base = (*p) & 0x07;\n"
695 " scale = 0;\n" 717 " scale = 0;\n"
696 " }\n" 718 " }\n"
697 " action modrm_pure_disp {\n" 719 " action modrm_pure_disp {\n"
698 " base = REG_NONE;\n" 720 " base = NO_REG;\n"
699 " index = REG_NONE;\n" 721 " index = NO_REG;\n"
700 " scale = 0;\n" 722 " scale = 0;\n"
701 " }\n" 723 " }\n"
702 " action modrm_pure_index {\n" 724 " action modrm_pure_index {\n"
703 " disp_type = DISPNONE;\n" 725 " disp_type = DISPNONE;\n"
704 " base = REG_NONE;\n" 726 " base = NO_REG;\n"
705 " index = index_registers[((*p) & 0x38) >> 3];\n" 727 " index = index_registers[((*p) & 0x38) >> 3];\n"
706 " scale = ((*p) & 0xc0) >> 6;\n" 728 " scale = ((*p) & 0xc0) >> 6;\n"
707 " }\n" 729 " }\n"
708 " action modrm_parse_sib {\n" 730 " action modrm_parse_sib {\n"
709 " disp_type = DISPNONE;\n" 731 " disp_type = DISPNONE;\n"
710 " base = (*p) & 0x7;\n" 732 " base = (*p) & 0x7;\n"
711 " index = index_registers[((*p) & 0x38) >> 3];\n" 733 " index = index_registers[((*p) & 0x38) >> 3];\n"
712 " scale = ((*p) & 0xc0) >> 6;\n" 734 " scale = ((*p) & 0xc0) >> 6;\n"
713 " }\n"); 735 " }\n");
714 } else { 736 } else {
715 fprintf(out_file, " action modrm_only_base {\n" 737 fprintf(out_file, " action modrm_only_base {\n"
716 " disp_type = DISPNONE;\n" 738 " disp_type = DISPNONE;\n"
717 " index = REG_NONE;\n" 739 " index = NO_REG;\n"
718 " base = ((*p) & 0x07) |\n" 740 " base = ((*p) & 0x07) |\n"
719 " ((rex_prefix & 0x01) << 3) |\n" 741 " ((rex_prefix & 0x01) << 3) |\n"
720 " (((~vex_prefix2) & 0x20) >> 2);\n" 742 " (((~vex_prefix2) & 0x20) >> 2);\n"
721 " scale = 0;\n" 743 " scale = 0;\n"
722 " }\n" 744 " }\n"
723 " action modrm_base_disp {\n" 745 " action modrm_base_disp {\n"
724 " index = REG_NONE;\n" 746 " index = NO_REG;\n"
725 " base = ((*p) & 0x07) |\n" 747 " base = ((*p) & 0x07) |\n"
726 " ((rex_prefix & 0x01) << 3) |\n" 748 " ((rex_prefix & 0x01) << 3) |\n"
727 " (((~vex_prefix2) & 0x20) >> 2);\n" 749 " (((~vex_prefix2) & 0x20) >> 2);\n"
728 " scale = 0;\n" 750 " scale = 0;\n"
729 " }\n" 751 " }\n"
730 " action modrm_rip {\n" 752 " action modrm_rip {\n"
731 " index = REG_NONE;\n" 753 " index = NO_REG;\n"
732 " base = REG_RIP;\n" 754 " base = REG_RIP;\n"
733 " scale = 0;\n" 755 " scale = 0;\n"
734 " }\n" 756 " }\n"
735 " action modrm_pure_index {\n" 757 " action modrm_pure_index {\n"
736 " disp_type = DISPNONE;\n" 758 " disp_type = DISPNONE;\n"
737 " base = REG_NONE;\n" 759 " base = NO_REG;\n"
738 " index = index_registers[(((*p) & 0x38) >> 3) |\n" 760 " index = index_registers[(((*p) & 0x38) >> 3) |\n"
739 " ((rex_prefix & 0x02) << 2) |\n" 761 " ((rex_prefix & 0x02) << 2) |\n"
740 " (((~vex_prefix2) & 0x40) >> 3)];\n" 762 " (((~vex_prefix2) & 0x40) >> 3)];\n"
741 " scale = ((*p) & 0xc0) >> 6;\n" 763 " scale = ((*p) & 0xc0) >> 6;\n"
742 " }\n" 764 " }\n"
743 " action modrm_parse_sib {\n" 765 " action modrm_parse_sib {\n"
744 " disp_type = DISPNONE;\n" 766 " disp_type = DISPNONE;\n"
745 " base = ((*p) & 0x7) |\n" 767 " base = ((*p) & 0x7) |\n"
746 " ((rex_prefix & 0x01) << 3) |\n" 768 " ((rex_prefix & 0x01) << 3) |\n"
747 " (((~vex_prefix2) & 0x20) >> 2);\n" 769 " (((~vex_prefix2) & 0x20) >> 2);\n"
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 static const T vex_fields[] = { 1002 static const T vex_fields[] = {
981 T { "NONE", 0xe0 }, 1003 T { "NONE", 0xe0 },
982 T { "R", 0x60 }, 1004 T { "R", 0x60 },
983 T { "X", 0xa0 }, 1005 T { "X", 0xa0 },
984 T { "B", 0xc0 }, 1006 T { "B", 0xc0 },
985 T { "RX", 0x20 }, 1007 T { "RX", 0x20 },
986 T { "RB", 0x40 }, 1008 T { "RB", 0x40 },
987 T { "XB", 0x80 }, 1009 T { "XB", 0x80 },
988 T { "RXB", 0x00 } 1010 T { "RXB", 0x00 }
989 }; 1011 };
990 for (int vex_it = 0; vex_it < arraysize(vex_fields); ++vex_it) { 1012 for (size_t vex_it = 0; vex_it < arraysize(vex_fields); ++vex_it) {
991 auto vex = vex_fields[vex_it]; 1013 auto vex = vex_fields[vex_it];
992 fprintf(out_file, " VEX_%2$s = %3$s%1$s;\n" 1014 fprintf(out_file, " VEX_%2$s = %3$s%1$s;\n"
993 "", enabled(Actions::kVexPrefix) && !ia32_mode ? " @vex_prefix2" : "", 1015 "", enabled(Actions::kVexPrefix) && !ia32_mode ? " @vex_prefix2" : "",
994 vex.first, chartest((c & vex.second) == vex.second)); 1016 vex.first, chartest((c & vex.second) == vex.second));
995 } 1017 }
996 static const T vex_map[] = { 1018 static const T vex_map[] = {
997 T { "01", 1 }, 1019 T { "01", 1 },
998 T { "02", 2 }, 1020 T { "02", 2 },
999 T { "03", 3 }, 1021 T { "03", 3 },
1000 T { "08", 8 }, 1022 T { "08", 8 },
1001 T { "09", 9 }, 1023 T { "09", 9 },
1002 T { "0A", 10 }, 1024 T { "0A", 10 },
1003 T { "00001", 1 }, 1025 T { "00001", 1 },
1004 T { "00010", 2 }, 1026 T { "00010", 2 },
1005 T { "00011", 3 }, 1027 T { "00011", 3 },
1006 T { "01000", 8 }, 1028 T { "01000", 8 },
1007 T { "01001", 9 }, 1029 T { "01001", 9 },
1008 T { "01010", 10 }, 1030 T { "01010", 10 },
1009 }; 1031 };
1010 for (int vex_it = 0; vex_it < arraysize(vex_map); ++vex_it) { 1032 for (size_t vex_it = 0; vex_it < arraysize(vex_map); ++vex_it) {
1011 auto vex = vex_map[vex_it]; 1033 auto vex = vex_map[vex_it];
1012 fprintf(out_file, " VEX_map%1$s = %2$s;\n" 1034 fprintf(out_file, " VEX_map%1$s = %2$s;\n"
1013 "", vex.first, chartest((c & 0x1f) == vex.second)); 1035 "", vex.first, chartest((c & 0x1f) == vex.second));
1014 } 1036 }
1015 if (enabled(Actions::kOpcode)) { 1037 if (enabled(Actions::kOpcode)) {
1016 fprintf(out_file, "\n" 1038 fprintf(out_file, "\n"
1017 " action begin_opcode {\n" 1039 " action begin_opcode {\n"
1018 " begin_opcode = p;\n" 1040 " begin_opcode = p;\n"
1019 " }\n" 1041 " }\n"
1020 " action end_opcode {\n" 1042 " action end_opcode {\n"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 T { "x87", "ST" }, 1077 T { "x87", "ST" },
1056 T { "mmx", "MMX" }, 1078 T { "mmx", "MMX" },
1057 T { "xmm", "XMM" }, 1079 T { "xmm", "XMM" },
1058 T { "ymm", "YMM" }, 1080 T { "ymm", "YMM" },
1059 T { "farptr", "FarPtr" }, 1081 T { "farptr", "FarPtr" },
1060 T { "segreg", "SegmentRegister" }, 1082 T { "segreg", "SegmentRegister" },
1061 T { "creg", "ControlRegister" }, 1083 T { "creg", "ControlRegister" },
1062 T { "dreg", "DebugRegister" }, 1084 T { "dreg", "DebugRegister" },
1063 T { "selector", "Selector" } 1085 T { "selector", "Selector" }
1064 }; 1086 };
1065 for (int size_it = 0; size_it < arraysize(sizes); ++size_it) { 1087 for (size_t size_it = 0; size_it < arraysize(sizes); ++size_it) {
1066 auto size = sizes[size_it]; 1088 auto size = sizes[size_it];
1067 fprintf(out_file, " action operand%1$d_%2$s {\n" 1089 fprintf(out_file, " action operand%1$d_%2$s {\n"
1068 " operand%1$d_type = Operand%3$s;\n" 1090 " operand%1$d_type = Operand%3$s;\n"
1069 " }\n" 1091 " }\n"
1070 "", i, size.first, size.second); 1092 "", i, size.first, size.second);
1071 } 1093 }
1072 if (ia32_mode) { 1094 if (ia32_mode) {
1073 fprintf(out_file, " action operand%1$d_absolute_disp {\n" 1095 fprintf(out_file, " action operand%1$d_absolute_disp {\n"
1074 " operand%1$d = REG_RM;\n" 1096 " operand%1$d = REG_RM;\n"
1075 " base = REG_NONE;\n" 1097 " base = NO_REG;\n"
1076 " index = REG_NONE;\n" 1098 " index = NO_REG;\n"
1077 " scale = 0;\n" 1099 " scale = 0;\n"
1078 " }\n" 1100 " }\n"
1079 " action operand%1$d_from_opcode {\n" 1101 " action operand%1$d_from_opcode {\n"
1080 " operand%1$d = (*p) & 0x7;\n" 1102 " operand%1$d = (*p) & 0x7;\n"
1081 " }\n" 1103 " }\n"
1082 " action operand%1$d_from_is4 {\n" 1104 " action operand%1$d_from_is4 {\n"
1083 " operand%1$d = p[0] >> 4;\n" 1105 " operand%1$d = p[0] >> 4;\n"
1084 " }\n" 1106 " }\n"
1085 " action operand%1$d_from_modrm_rm {\n" 1107 " action operand%1$d_from_modrm_rm {\n"
1086 " operand%1$d = (*p) & 0x07;\n" 1108 " operand%1$d = (*p) & 0x07;\n"
1087 " }\n" 1109 " }\n"
1088 " action operand%1$d_from_modrm_reg {\n" 1110 " action operand%1$d_from_modrm_reg {\n"
1089 " operand%1$d = ((*p) & 0x38) >> 3;\n" 1111 " operand%1$d = ((*p) & 0x38) >> 3;\n"
1090 " }\n" 1112 " }\n"
1091 " action operand%1$d_from_modrm_reg_norex {\n" 1113 " action operand%1$d_from_modrm_reg_norex {\n"
1092 " operand%1$d = ((*p) & 0x38) >> 3;\n" 1114 " operand%1$d = ((*p) & 0x38) >> 3;\n"
1093 " }\n" 1115 " }\n"
1094 " action operand%1$d_from_vex {\n" 1116 " action operand%1$d_from_vex {\n"
1095 " operand%1$d = ((~vex_prefix3) & 0x38) >> 3;\n" 1117 " operand%1$d = ((~vex_prefix3) & 0x38) >> 3;\n"
1096 " }\n" 1118 " }\n"
1097 "", i); 1119 "", i);
1098 } else { 1120 } else {
1099 fprintf(out_file, " action operand%1$d_absolute_disp {\n" 1121 fprintf(out_file, " action operand%1$d_absolute_disp {\n"
1100 " operand%1$d = REG_RM;\n" 1122 " operand%1$d = REG_RM;\n"
1101 " base = REG_NONE;\n" 1123 " base = NO_REG;\n"
1102 " index = REG_RIZ;\n" 1124 " index = REG_RIZ;\n"
1103 " scale = 0;\n" 1125 " scale = 0;\n"
1104 " }\n" 1126 " }\n"
1105 " action operand%1$d_from_opcode {\n" 1127 " action operand%1$d_from_opcode {\n"
1106 " operand%1$d = ((*p) & 0x7) |\n" 1128 " operand%1$d = ((*p) & 0x7) |\n"
1107 " ((rex_prefix & 0x01) << 3) |\n" 1129 " ((rex_prefix & 0x01) << 3) |\n"
1108 " (((~vex_prefix2) & 0x20) >> 2);\n" 1130 " (((~vex_prefix2) & 0x20) >> 2);\n"
1109 " }\n" 1131 " }\n"
1110 " action operand%1$d_from_is4 {\n" 1132 " action operand%1$d_from_is4 {\n"
1111 " operand%1$d = p[0] >> 4;\n" 1133 " operand%1$d = p[0] >> 4;\n"
(...skipping 22 matching lines...) Expand all
1134 T { "es_rdi", "REG_ES_RDI" }, 1156 T { "es_rdi", "REG_ES_RDI" },
1135 T { "immediate", "REG_IMM" }, 1157 T { "immediate", "REG_IMM" },
1136 T { "second_immediate", "REG_IMM2" }, 1158 T { "second_immediate", "REG_IMM2" },
1137 T { "port_dx", "REG_PORT_DX" }, 1159 T { "port_dx", "REG_PORT_DX" },
1138 T { "rax", "REG_RAX" }, 1160 T { "rax", "REG_RAX" },
1139 T { "rcx", "REG_RCX" }, 1161 T { "rcx", "REG_RCX" },
1140 T { "rdx", "REG_RDX" }, 1162 T { "rdx", "REG_RDX" },
1141 T { "rm", "REG_RM" }, 1163 T { "rm", "REG_RM" },
1142 T { "st", "REG_ST" } 1164 T { "st", "REG_ST" }
1143 }; 1165 };
1144 for (int type_it = 0; type_it < arraysize(types); ++type_it) { 1166 for (size_t type_it = 0; type_it < arraysize(types); ++type_it) {
1145 auto type = types[type_it]; 1167 auto type = types[type_it];
1146 fprintf(out_file, " action operand%1$d_%2$s {\n" 1168 fprintf(out_file, " action operand%1$d_%2$s {\n"
1147 " operand%1$d = %3$s;\n" 1169 " operand%1$d = %3$s;\n"
1148 " }\n" 1170 " }\n"
1149 "", i, type.first, type.second); 1171 "", i, type.first, type.second);
1150 } 1172 }
1151 } 1173 }
1152 } 1174 }
1153 if (enabled(Actions::kParseOperandsStates)) { 1175 if (enabled(Actions::kParseOperandsStates)) {
1154 for (auto i = 0 ; i < 5; ++i) { 1176 for (auto i = 0 ; i < 5; ++i) {
1155 fprintf(out_file, " action operand%1$d_unused {\n" 1177 fprintf(out_file, " action operand%1$d_unused {\n"
1156 " operand%1$d_read = false;\n" 1178 " operand%1$d_read = FALSE;\n"
1157 " operand%1$d_write = false;\n" 1179 " operand%1$d_write = FALSE;\n"
1158 " }\n" 1180 " }\n"
1159 " action operand%1$d_read {\n" 1181 " action operand%1$d_read {\n"
1160 " operand%1$d_read = true;\n" 1182 " operand%1$d_read = TRUE;\n"
1161 " operand%1$d_write = false;\n" 1183 " operand%1$d_write = FALSE;\n"
1162 " }\n" 1184 " }\n"
1163 " action operand%1$d_write {\n" 1185 " action operand%1$d_write {\n"
1164 " operand%1$d_read = false;\n" 1186 " operand%1$d_read = FALSE;\n"
1165 " operand%1$d_write = true;\n" 1187 " operand%1$d_write = TRUE;\n"
1166 " }\n" 1188 " }\n"
1167 " action operand%1$d_readwrite {\n" 1189 " action operand%1$d_readwrite {\n"
1168 " operand%1$d_read = true;\n" 1190 " operand%1$d_read = TRUE;\n"
1169 " operand%1$d_write = true;\n" 1191 " operand%1$d_write = TRUE;\n"
1170 " }\n" 1192 " }\n"
1171 "", i); 1193 "", i);
1172 } 1194 }
1173 } 1195 }
1174 } 1196 }
1175 1197
1176 void print_name_actions(void) { 1198 void print_name_actions(void) {
1177 for (auto pair_it = instruction_names.begin(); 1199 for (auto pair_it = instruction_names.begin();
1178 pair_it != instruction_names.end(); ++pair_it) { 1200 pair_it != instruction_names.end(); ++pair_it) {
1179 auto &pair = *pair_it; 1201 auto &pair = *pair_it;
1180 fprintf(out_file, " action instruction_%s" 1202 fprintf(out_file, " action instruction_%s"
1181 " { instruction_name = instruction_names + %zd; }\n", 1203 " { instruction_name = instruction_names + %zd; }\n",
1182 c_identifier(pair.first).c_str(), pair.second); 1204 c_identifier(pair.first).c_str(), pair.second);
1183 } 1205 }
1184 } 1206 }
1185 1207
1186 class MarkedInstruction : Instruction { 1208 class MarkedInstruction : Instruction {
1187 public: 1209 public:
1188 /* Additional marks are created in the process of parsing. */ 1210 /* Additional marks are created in the process of parsing. */
1189 explicit MarkedInstruction(Instruction instruction_) : 1211 explicit MarkedInstruction(Instruction instruction_) :
1190 Instruction(instruction_), 1212 Instruction(instruction_),
1191 instruction_class(get_instruction_class(instruction_)), 1213 instruction_class(get_instruction_class(instruction_)),
1192 opcode_in_modrm(false), opcode_in_imm(false), rex { } { 1214 rex { }, opcode_in_modrm(false), opcode_in_imm(false) {
1193 if (has_flag("branch_hint")) { 1215 if (has_flag("branch_hint")) {
1194 optional_prefixes.insert("branch_hint"); 1216 optional_prefixes.insert("branch_hint");
1195 } 1217 }
1196 if (has_flag("condrep")) { 1218 if (has_flag("condrep")) {
1197 optional_prefixes.insert("condrep"); 1219 optional_prefixes.insert("condrep");
1198 } 1220 }
1199 if (has_flag("rep")) { 1221 if (has_flag("rep")) {
1200 optional_prefixes.insert("rep"); 1222 optional_prefixes.insert("rep");
1201 } 1223 }
1202 for (auto opcode_it = opcodes.begin(); 1224 for (auto opcode_it = opcodes.begin();
(...skipping 27 matching lines...) Expand all
1230 } 1252 }
1231 opcode->push_back(')'); 1253 opcode->push_back(')');
1232 if (saved_opcode == "0x97") { 1254 if (saved_opcode == "0x97") {
1233 opcode->erase(1, 5); 1255 opcode->erase(1, 5);
1234 } 1256 }
1235 break; 1257 break;
1236 case '8': 1258 case '8':
1237 (*opcode) = "("; 1259 (*opcode) = "(";
1238 opcode->append(saved_opcode); 1260 opcode->append(saved_opcode);
1239 static const char cc[] = {'9', 'a', 'b', 'c', 'd', 'e', 'f'}; 1261 static const char cc[] = {'9', 'a', 'b', 'c', 'd', 'e', 'f'};
1240 for (int c_it = 0; c_it < arraysize(cc); ++c_it) { 1262 for (size_t c_it = 0; c_it < arraysize(cc); ++c_it) {
1241 auto c = cc[c_it]; 1263 auto c = cc[c_it];
1242 opcode->push_back('|'); 1264 opcode->push_back('|');
1243 (*(saved_opcode.rbegin())) = c; 1265 (*(saved_opcode.rbegin())) = c;
1244 opcode->append(saved_opcode); 1266 opcode->append(saved_opcode);
1245 } 1267 }
1246 opcode->push_back(')'); 1268 opcode->push_back(')');
1247 break; 1269 break;
1248 default: 1270 default:
1249 fprintf(stderr, "%s: error - can not use 'r' operand in " 1271 fprintf(stderr, "%s: error - can not use 'r' operand in "
1250 "instruction '%s'", short_program_name, name.c_str()); 1272 "instruction '%s'", short_program_name, name.c_str());
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 if (saved_class == InstructionClass::kLSetUnsetDefaultRexW) { 1524 if (saved_class == InstructionClass::kLSetUnsetDefaultRexW) {
1503 instruction_class = InstructionClass::kRexW; 1525 instruction_class = InstructionClass::kRexW;
1504 print_one_size_definition_rexw(); 1526 print_one_size_definition_rexw();
1505 } 1527 }
1506 opcode[Lbit] = '0'; 1528 opcode[Lbit] = '0';
1507 auto saved_operands = operands; 1529 auto saved_operands = operands;
1508 for (auto operand_it = operands.begin(); 1530 for (auto operand_it = operands.begin();
1509 operand_it != operands.end(); ++operand_it) { 1531 operand_it != operands.end(); ++operand_it) {
1510 auto &operand = *operand_it; 1532 auto &operand = *operand_it;
1511 static const char cc[] = {'H', 'L', 'U', 'V', 'W'}; 1533 static const char cc[] = {'H', 'L', 'U', 'V', 'W'};
1512 for (int c_it = 0; c_it < arraysize(cc); ++c_it) { 1534 for (size_t c_it = 0; c_it < arraysize(cc); ++c_it) {
1513 auto c = cc[c_it]; 1535 auto c = cc[c_it];
1514 if ((operand.source == c) && 1536 if ((operand.source == c) &&
1515 (*(operand.size.rbegin()) == 'x') && 1537 (*(operand.size.rbegin()) == 'x') &&
1516 (((operand.size.length() > 1) && 1538 (((operand.size.length() > 1) &&
1517 (operand.size[0] == 'p')) || 1539 (operand.size[0] == 'p')) ||
1518 (operand.size.length() == 1))) { 1540 (operand.size.length() == 1))) {
1519 operand.size.resize(operand.size.length() - 1); 1541 operand.size.resize(operand.size.length() - 1);
1520 } 1542 }
1521 } 1543 }
1522 } 1544 }
(...skipping 18 matching lines...) Expand all
1541 } 1563 }
1542 } 1564 }
1543 1565
1544 void print_one_size_definition(void) { 1566 void print_one_size_definition(void) {
1545 /* 64bit commands are not supported in ia32 mode. */ 1567 /* 64bit commands are not supported in ia32 mode. */
1546 if (ia32_mode && rex.w) { 1568 if (ia32_mode && rex.w) {
1547 return; 1569 return;
1548 } 1570 }
1549 bool modrm_memory = false; 1571 bool modrm_memory = false;
1550 bool modrm_register = false; 1572 bool modrm_register = false;
1551 char operand_source; 1573 char operand_source = ' ';
1552 for (auto operand_it = operands.begin(); 1574 for (auto operand_it = operands.begin();
1553 operand_it != operands.end(); ++operand_it) { 1575 operand_it != operands.end(); ++operand_it) {
1554 auto &operand = *operand_it; 1576 auto &operand = *operand_it;
1555 static std::map<char, std::pair<bool, bool> > operand_map { 1577 static std::map<char, std::pair<bool, bool> > operand_map {
1556 { 'E', std::make_pair(true, true) }, 1578 { 'E', std::make_pair(true, true) },
1557 { 'M', std::make_pair(true, false) }, 1579 { 'M', std::make_pair(true, false) },
1558 { 'N', std::make_pair(false, true) }, 1580 { 'N', std::make_pair(false, true) },
1559 { 'Q', std::make_pair(true, true) }, 1581 { 'Q', std::make_pair(true, true) },
1560 { 'R', std::make_pair(false, true) }, 1582 { 'R', std::make_pair(false, true) },
1561 { 'U', std::make_pair(false, true) }, 1583 { 'U', std::make_pair(false, true) },
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 1686
1665 void print_one_size_definition_modrm_memory(void) { 1687 void print_one_size_definition_modrm_memory(void) {
1666 typedef std::tuple<const char *, bool, bool> T; 1688 typedef std::tuple<const char *, bool, bool> T;
1667 static const T modes[] = { 1689 static const T modes[] = {
1668 T { " operand_disp", false, true }, 1690 T { " operand_disp", false, true },
1669 T { " operand_rip", false, false }, 1691 T { " operand_rip", false, false },
1670 T { " single_register_memory", false, true }, 1692 T { " single_register_memory", false, true },
1671 T { " operand_sib_pure_index", true, false }, 1693 T { " operand_sib_pure_index", true, false },
1672 T { " operand_sib_base_index", true, true } 1694 T { " operand_sib_base_index", true, true }
1673 }; 1695 };
1674 for (int mode_it = 0; mode_it < arraysize(modes); ++mode_it) { 1696 for (size_t mode_it = 0; mode_it < arraysize(modes); ++mode_it) {
1675 auto mode = modes[mode_it]; 1697 auto mode = modes[mode_it];
1676 print_operator_delimiter(); 1698 print_operator_delimiter();
1677 if (mod_reg_is_used()) { 1699 if (mod_reg_is_used()) {
1678 rex.r = true; 1700 rex.r = true;
1679 } 1701 }
1680 if (mod_rm_is_used()) { 1702 if (mod_rm_is_used()) {
1681 rex.x = std::get<1>(mode); 1703 rex.x = std::get<1>(mode);
1682 rex.b = std::get<2>(mode); 1704 rex.b = std::get<2>(mode);
1683 } 1705 }
1684 print_legacy_prefixes(); 1706 print_legacy_prefixes();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 1766
1745 bool mod_reg_is_used() { 1767 bool mod_reg_is_used() {
1746 for (auto operand_it = operands.begin(); 1768 for (auto operand_it = operands.begin();
1747 operand_it != operands.end(); ++operand_it) { 1769 operand_it != operands.end(); ++operand_it) {
1748 auto &operand = *operand_it; 1770 auto &operand = *operand_it;
1749 if (operand.source == 'C' && 1771 if (operand.source == 'C' &&
1750 required_prefixes.find("0xf0") == required_prefixes.end()) { 1772 required_prefixes.find("0xf0") == required_prefixes.end()) {
1751 return true; 1773 return true;
1752 } 1774 }
1753 static const char cc[] = { 'G', 'P', 'V' }; 1775 static const char cc[] = { 'G', 'P', 'V' };
1754 for (int c_it = 0; c_it < arraysize(cc); ++c_it) { 1776 for (size_t c_it = 0; c_it < arraysize(cc); ++c_it) {
1755 auto c = cc[c_it]; 1777 auto c = cc[c_it];
1756 if (operand.source == c) { 1778 if (operand.source == c) {
1757 return true; 1779 return true;
1758 } 1780 }
1759 } 1781 }
1760 } 1782 }
1761 return false; 1783 return false;
1762 } 1784 }
1763 1785
1764 bool mod_rm_is_used() { 1786 bool mod_rm_is_used() {
1765 for (auto operand_it = operands.begin(); 1787 for (auto operand_it = operands.begin();
1766 operand_it != operands.end(); ++operand_it) { 1788 operand_it != operands.end(); ++operand_it) {
1767 auto &operand = *operand_it; 1789 auto &operand = *operand_it;
1768 static const char cc[] = { 'E', 'M', 'N', 'Q', 'R', 'U', 'W' }; 1790 static const char cc[] = { 'E', 'M', 'N', 'Q', 'R', 'U', 'W' };
1769 for (int c_it = 0; c_it < arraysize(cc); ++c_it) { 1791 for (size_t c_it = 0; c_it < arraysize(cc); ++c_it) {
1770 auto c = cc[c_it]; 1792 auto c = cc[c_it];
1771 if (operand.source == c) { 1793 if (operand.source == c) {
1772 return true; 1794 return true;
1773 } 1795 }
1774 } 1796 }
1775 } 1797 }
1776 return false; 1798 return false;
1777 } 1799 }
1778 1800
1779 void print_legacy_prefixes(void) { 1801 void print_legacy_prefixes(void) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1910 if (ia32_mode || (!rex.r && !rex.x & !rex.b)) { 1932 if (ia32_mode || (!rex.r && !rex.x & !rex.b)) {
1911 fprintf(out_file, "NONE"); 1933 fprintf(out_file, "NONE");
1912 } else { 1934 } else {
1913 if (rex.r) fprintf(out_file, "R"); 1935 if (rex.r) fprintf(out_file, "R");
1914 if (rex.x) fprintf(out_file, "X"); 1936 if (rex.x) fprintf(out_file, "X");
1915 if (rex.b) fprintf(out_file, "B"); 1937 if (rex.b) fprintf(out_file, "B");
1916 } 1938 }
1917 fprintf(out_file, " & VEX_map%s) ", opcodes[1].c_str() + 4); 1939 fprintf(out_file, " & VEX_map%s) ", opcodes[1].c_str() + 4);
1918 auto third_byte = opcodes[2]; 1940 auto third_byte = opcodes[2];
1919 static const char* symbolic_names[] = { "cntl", "dest", "src1", "src" }; 1941 static const char* symbolic_names[] = { "cntl", "dest", "src1", "src" };
1920 for (int symbolic_it = 0; 1942 for (size_t symbolic_it = 0;
1921 symbolic_it < arraysize(symbolic_names); ++symbolic_it) { 1943 symbolic_it < arraysize(symbolic_names); ++symbolic_it) {
1922 auto symbolic = symbolic_names[symbolic_it]; 1944 auto symbolic = symbolic_names[symbolic_it];
1923 for (auto it = third_byte.begin(); it != third_byte.end(); ++it) { 1945 for (auto it = third_byte.begin(); it != third_byte.end(); ++it) {
1924 if ((third_byte.end() - it) >= strlen(symbolic) && 1946 auto symbolic_len = strlen(symbolic);
1947 if (static_cast<size_t>(third_byte.end() - it) >= symbolic_len &&
1925 !strncmp(&*it, symbolic, strlen(symbolic))) { 1948 !strncmp(&*it, symbolic, strlen(symbolic))) {
1926 third_byte.replace(it, it + strlen(symbolic), "XXXX"); 1949 third_byte.replace(it, it + strlen(symbolic), "XXXX");
1927 break; 1950 break;
1928 } 1951 }
1929 } 1952 }
1930 } 1953 }
1931 static const std::set<char> third_byte_check[] { 1954 static const std::set<char> third_byte_check[] {
1932 { '0', '1', 'x', 'X', 'W' }, 1955 { '0', '1', 'x', 'X', 'W' },
1933 { '.' }, 1956 { '.' },
1934 { '0', '1', 'x', 'X' }, 1957 { '0', '1', 'x', 'X' },
1935 { '0', '1', 'x', 'X' }, 1958 { '0', '1', 'x', 'X' },
1936 { '0', '1', 'x', 'X' }, 1959 { '0', '1', 'x', 'X' },
1937 { '0', '1', 'x', 'X' }, 1960 { '0', '1', 'x', 'X' },
1938 { '.' }, 1961 { '.' },
1939 { '0', '1', 'x', 'X' }, 1962 { '0', '1', 'x', 'X' },
1940 { '.' }, 1963 { '.' },
1941 { '0', '1' }, 1964 { '0', '1' },
1942 { '0', '1' } 1965 { '0', '1' }
1943 }; 1966 };
1944 auto third_byte_ok = (arraysize(third_byte_check) == 1967 auto third_byte_ok = (arraysize(third_byte_check) ==
1945 third_byte.length()); 1968 third_byte.length());
1946 if (third_byte_ok) { 1969 if (third_byte_ok) {
1947 for (int set_it = 0; set_it < arraysize(third_byte_check); ++set_it) { 1970 for (size_t set_it = 0; set_it < arraysize(third_byte_check);
1971 ++set_it) {
1948 auto &set = third_byte_check[set_it]; 1972 auto &set = third_byte_check[set_it];
1949 if (set.find(third_byte[&set - third_byte_check]) == set.end()) { 1973 if (set.find(third_byte[&set - third_byte_check]) == set.end()) {
1950 third_byte_ok = false; 1974 third_byte_ok = false;
1951 break; 1975 break;
1952 } 1976 }
1953 } 1977 }
1954 } 1978 }
1955 if (third_byte_ok) { 1979 if (third_byte_ok) {
1956 if (ia32_mode && third_byte[2] == 'X') { 1980 if (ia32_mode && third_byte[2] == 'X') {
1957 third_byte[2] = '1'; 1981 third_byte[2] = '1';
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
2361 2385
2362 int main(int argc, char *argv[]) { 2386 int main(int argc, char *argv[]) {
2363 /* basename(3) may change the passed argument thus we are using copy 2387 /* basename(3) may change the passed argument thus we are using copy
2364 of argv[0]. This creates tiny memory leak but since we only do that 2388 of argv[0]. This creates tiny memory leak but since we only do that
2365 once per program invocation it's contained. */ 2389 once per program invocation it's contained. */
2366 short_program_name = basename(strdup(argv[0])); 2390 short_program_name = basename(strdup(argv[0]));
2367 2391
2368 for (;;) { 2392 for (;;) {
2369 int option_index; 2393 int option_index;
2370 2394
2371 int option = getopt_long(argc, argv, "d:hm:o:v", 2395 int option = getopt_long(argc, argv, "c:d:hm:o:v",
2372 kProgramOptions, &option_index); 2396 kProgramOptions, &option_index);
2373 2397
2374 if (option == -1) { 2398 if (option == -1) {
2375 break; 2399 break;
2376 } 2400 }
2377 2401
2378 switch (option) { 2402 switch (option) {
2403 case 'c': {
2404 const_file_name = optarg;
2405 break;
2406 }
2379 case 'd': { 2407 case 'd': {
2380 for (auto action_to_disable = strtok(optarg, ","); 2408 for (auto action_to_disable = strtok(optarg, ",");
2381 action_to_disable; 2409 action_to_disable;
2382 action_to_disable = strtok(NULL, ",")) { 2410 action_to_disable = strtok(NULL, ",")) {
2383 compare_action compare_with_action_to_disable(action_to_disable); 2411 compare_action compare_with_action_to_disable(action_to_disable);
2384 auto action_number = std::find_if( 2412 auto action_number = std::find_if(
2385 kDisablableActionsList, 2413 kDisablableActionsList,
2386 kDisablableActionsList + arraysize(kDisablableActionsList), 2414 kDisablableActionsList + arraysize(kDisablableActionsList),
2387 compare_with_action_to_disable); 2415 compare_with_action_to_disable);
2388 if (action_number != 2416 if (action_number !=
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2422 return 1; 2450 return 1;
2423 default: 2451 default:
2424 abort(); 2452 abort();
2425 } 2453 }
2426 } 2454 }
2427 2455
2428 for (auto i = optind; i < argc; ++i) { 2456 for (auto i = optind; i < argc; ++i) {
2429 load_instructions(argv[i]); 2457 load_instructions(argv[i]);
2430 } 2458 }
2431 2459
2432 if (!(out_file = fopen(out_file_name, "w"))) { 2460 if (out_file_name && !(out_file = fopen(out_file_name, "w"))) {
2433 fprintf(stderr, 2461 fprintf(stderr,
2434 "%s: can not open '%s' file (%s)\n", 2462 "%s: can not open '%s' file (%s)\n",
2435 short_program_name, out_file_name, strerror(errno)); 2463 short_program_name, out_file_name, strerror(errno));
2436 return 1; 2464 return 1;
2437 } else if (enabled(Actions::kInstructionName) || 2465 } else if ((out_file_name || const_file_name) &&
2438 enabled(Actions::kParseOperands)) { 2466 (enabled(Actions::kInstructionName) ||
2439 size_t const_name_len = strlen(out_file_name) + 10; 2467 enabled(Actions::kParseOperands))) {
2440 char* const_name = static_cast<char *>(malloc(const_name_len)); 2468 size_t const_name_len = 0;
2441 strncpy(const_name, out_file_name, const_name_len); 2469 if (out_file_name && !const_file_name) {
2442 char* dot_position = strrchr(const_name, '.'); 2470 const_name_len = strlen(out_file_name) + 10;
2443 if (!dot_position) { 2471 const_file_name = static_cast<char *>(malloc(const_name_len));
2444 dot_position = strrchr(const_name, '\0'); 2472 strcpy(const_file_name, out_file_name);
2473 char* dot_position = strrchr(const_file_name, '.');
2474 if (!dot_position) {
2475 dot_position = strrchr(const_file_name, '\0');
2476 }
2477 strcpy(dot_position, "-consts.c");
2445 } 2478 }
2446 strncpy(dot_position, 2479 if (!(const_file = fopen(const_file_name, "w"))) {
2447 "-consts.c",
2448 const_name_len - (dot_position - const_name));
2449 if (!(const_file = fopen(const_name, "w"))) {
2450 fprintf(stderr, "%s: can not open '%s' file (%s)\n", 2480 fprintf(stderr, "%s: can not open '%s' file (%s)\n",
2451 short_program_name, const_name, strerror(errno)); 2481 short_program_name, const_file_name, strerror(errno));
2452 return 1; 2482 return 1;
2453 } 2483 }
2454 free(const_name); 2484 if (const_name_len) {
2485 free(const_file_name);
2486 const_file_name = NULL;
2487 }
2455 } 2488 }
2456 2489
2457 if (enabled(Actions::kInstructionName) || 2490 if (enabled(Actions::kInstructionName) ||
2458 enabled(Actions::kParseOperands)) { 2491 enabled(Actions::kParseOperands)) {
2459 print_consts(); 2492 print_consts();
2460 2493
2461 if (out_file == const_file) { 2494 if (out_file == const_file) {
2462 for (auto i = 0; i < 80; ++i) { 2495 for (auto i = 0; i < 80; ++i) {
2463 fputc('#', out_file); 2496 fputc('#', out_file);
2464 } 2497 }
2465 fputc('\n', out_file); 2498 fputc('\n', out_file);
2466 } 2499 }
2467 } 2500 }
2468 2501
2469 if (ia32_mode) { 2502 if (ia32_mode) {
2470 fprintf(out_file, "%%%%{\n" 2503 fprintf(out_file, "%%%%{\n"
2471 " machine decode_x86_32;\n" 2504 " machine decode_x86_32;\n"
2472 " alphtype unsigned char;\n" 2505 " alphtype unsigned char;\n"
2473 ""); 2506 "");
2474 } else { 2507 } else {
2475 fprintf(out_file, "END(%%%%{\n" 2508 fprintf(out_file, "%%%%{\n"
2476 " machine decode_x86_64;\n" 2509 " machine decode_x86_64;\n"
2477 " alphtype unsigned char;\n" 2510 " alphtype unsigned char;\n"
2478 ""); 2511 "");
2479 } 2512 }
2480 2513
2481 print_common_decoding(); 2514 print_common_decoding();
2482 2515
2483 if (enabled(Actions::kInstructionName)) { 2516 if (enabled(Actions::kInstructionName)) {
2484 print_name_actions(); 2517 print_name_actions();
2485 } 2518 }
2486 2519
2487 fprintf(out_file, "\n one_instruction ="); 2520 fprintf(out_file, "\n one_instruction =");
2488 2521
2489 print_one_instruction_definition(); 2522 print_one_instruction_definition();
2490 2523
2491 fprintf(out_file, ");\n" 2524 fprintf(out_file, ");\n"
2492 "}%%%%\n" 2525 "}%%%%\n"
2493 ""); 2526 "");
2494 return 0; 2527 return 0;
2495 } 2528 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698