Add {vex3} and {vex2} prefixes by analogy with {evex}
[platform/upstream/nasm.git] / insns-iflags.pl
1 #!/usr/bin/perl
2 ## --------------------------------------------------------------------------
3 ##
4 ##   Copyright 1996-2013 The NASM Authors - All Rights Reserved
5 ##   See the file AUTHORS included with the NASM distribution for
6 ##   the specific copyright holders.
7 ##
8 ##   Redistribution and use in source and binary forms, with or without
9 ##   modification, are permitted provided that the following
10 ##   conditions are met:
11 ##
12 ##   * Redistributions of source code must retain the above copyright
13 ##     notice, this list of conditions and the following disclaimer.
14 ##   * Redistributions in binary form must reproduce the above
15 ##     copyright notice, this list of conditions and the following
16 ##     disclaimer in the documentation and/or other materials provided
17 ##     with the distribution.
18 ##
19 ##     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
20 ##     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
21 ##     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 ##     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 ##     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 ##     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 ##     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 ##     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 ##     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 ##     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 ##     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 ##     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31 ##     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 ##
33 ## --------------------------------------------------------------------------
34
35 #
36 # Instruction template flags. These specify which processor
37 # targets the instruction is eligible for, whether it is
38 # privileged or undocumented, and also specify extra error
39 # checking on the matching of the instruction.
40 #
41 # IF_SM stands for Size Match: any operand whose size is not
42 # explicitly specified by the template is `really' intended to be
43 # the same size as the first size-specified operand.
44 # Non-specification is tolerated in the input instruction, but
45 # _wrong_ specification is not.
46 #
47 # IF_SM2 invokes Size Match on only the first _two_ operands, for
48 # three-operand instructions such as SHLD: it implies that the
49 # first two operands must match in size, but that the third is
50 # required to be _unspecified_.
51 #
52 # IF_SB invokes Size Byte: operands with unspecified size in the
53 # template are really bytes, and so no non-byte specification in
54 # the input instruction will be tolerated. IF_SW similarly invokes
55 # Size Word, and IF_SD invokes Size Doubleword.
56 #
57 # (The default state if neither IF_SM nor IF_SM2 is specified is
58 # that any operand with unspecified size in the template is
59 # required to have unspecified size in the instruction too...)
60 #
61 # iflag_t is defined to store these flags.
62 #
63 # The order does matter here. We use some predefined masks to quick test
64 # for a set of flags, so be careful moving bits (and
65 # don't forget to update C code generation then).
66 #
67 my %insns_flag_bit = (
68     #
69     # dword bound, index 0 - specific flags
70     #
71     "SM"                => [  0, "Size match"],
72     "SM2"               => [  1, "Size match first two operands"],
73     "SB"                => [  2, "Unsized operands can't be non-byte"],
74     "SW"                => [  3, "Unsized operands can't be non-word"],
75     "SD"                => [  4, "Unsized operands can't be non-dword"],
76     "SQ"                => [  5, "Unsized operands can't be non-qword"],
77     "SO"                => [  6, "Unsized operands can't be non-oword"],
78     "SY"                => [  7, "Unsized operands can't be non-yword"],
79     "SZ"                => [  8, "Unsized operands can't be non-zword"],
80     "SIZE"              => [  9, "Unsized operands must match the bitsize"],
81     "SX"                => [ 10, "Unsized operands not allowed"],
82     "AR0"               => [ 11, "SB, SW, SD applies to argument 0"],
83     "AR1"               => [ 12, "SB, SW, SD applies to argument 1"],
84     "AR2"               => [ 13, "SB, SW, SD applies to argument 2"],
85     "AR3"               => [ 14, "SB, SW, SD applies to argument 3"],
86     "AR4"               => [ 15, "SB, SW, SD applies to argument 4"],
87     "OPT"               => [ 16, "Optimizing assembly only"],
88
89     #
90     # dword bound, index 1 - instruction filtering flags
91     #
92     "PRIV"              => [ 32, "Privileged instruction"],
93     "SMM"               => [ 33, "Only valid in SMM"],
94     "PROT"              => [ 34, "Protected mode only"],
95     "LOCK"              => [ 35, "Lockable if operand 0 is memory"],
96     "NOLONG"            => [ 36, "Not available in long mode"],
97     "LONG"              => [ 37, "Long mode"],
98     "NOHLE"             => [ 38, "HLE prefixes forbidden"],
99     "MIB"               => [ 39, "disassemble with split EA"],
100     "BND"               => [ 40, "BND (0xF2) prefix available"],
101     "UNDOC"             => [ 41, "Undocumented"],
102     "HLE"               => [ 42, "HLE prefixed"],
103     "FPU"               => [ 43, "FPU"],
104     "MMX"               => [ 44, "MMX"],
105     "3DNOW"             => [ 45, "3DNow!"],
106     "SSE"               => [ 46, "SSE (KNI, MMX2)"],
107     "SSE2"              => [ 47, "SSE2"],
108     "SSE3"              => [ 48, "SSE3 (PNI)"],
109     "VMX"               => [ 49, "VMX"],
110     "SSSE3"             => [ 50, "SSSE3"],
111     "SSE4A"             => [ 51, "AMD SSE4a"],
112     "SSE41"             => [ 52, "SSE4.1"],
113     "SSE42"             => [ 53, "SSE4.2"],
114     "SSE5"              => [ 54, "SSE5"],
115     "AVX"               => [ 55, "AVX (128b)"],
116     "AVX2"              => [ 56, "AVX2 (256b)"],
117     "FMA"               => [ 57, ""],
118     "BMI1"              => [ 58, ""],
119     "BMI2"              => [ 59, ""],
120     "TBM"               => [ 60, ""],
121     "RTM"               => [ 61, ""],
122     "INVPCID"           => [ 62, ""],
123
124     #
125     # dword bound, index 2 - instruction filtering flags
126     #
127     "AVX512"            => [ 64, "AVX-512F (512b)"],
128     "AVX512CD"          => [ 65, "AVX-512 Conflict Detection"],
129     "AVX512ER"          => [ 66, "AVX-512 Exponential and Reciprocal"],
130     "AVX512PF"          => [ 67, "AVX-512 Prefetch"],
131     "MPX"               => [ 68 ,"MPX"],
132     "SHA"               => [ 69 ,"SHA"],
133     "PREFETCHWT1"       => [ 70 ,"PREFETCHWT1"],
134     "VEX"               => [ 94, "VEX or XOP encoded instruction"],
135     "EVEX"              => [ 95, "EVEX encoded instruction"],
136
137     #
138     # dword bound, index 3 - cpu type flags
139     #
140     # The CYRIX and AMD flags should have the highest bit values; the
141     # disassembler selection algorithm depends on it.
142     #
143     "8086"              => [ 96, "8086"],
144     "186"               => [ 97, "186+"],
145     "286"               => [ 98, "286+"],
146     "386"               => [ 99, "386+"],
147     "486"               => [100, "486+"],
148     "PENT"              => [101, "Pentium"],
149     "P6"                => [102, "P6"],
150     "KATMAI"            => [103, "Katmai"],
151     "WILLAMETTE"        => [104, "Willamette"],
152     "PRESCOTT"          => [105, "Prescott"],
153     "X86_64"            => [106, "x86-64 (long or legacy mode)"],
154     "NEHALEM"           => [107, "Nehalem"],
155     "WESTMERE"          => [108, "Westmere"],
156     "SANDYBRIDGE"       => [109, "Sandy Bridge"],
157     "FUTURE"            => [110, "Future processor (not yet disclosed)"],
158     "IA64"              => [111, "IA64 (in x86 mode)"],
159     "CYRIX"             => [126, "Cyrix-specific"],
160     "AMD"               => [127, "AMD-specific"],
161 );
162
163 my %insns_flag_hash = ();
164 my @insns_flag_values = ();
165 my $iflag_words;
166
167 sub get_flag_words() {
168     my $max = -1;
169
170     foreach my $key (keys(%insns_flag_bit)) {
171         if (${$insns_flag_bit{$key}}[0] > $max) {
172             $max = ${$insns_flag_bit{$key}}[0];
173         }
174     }
175
176     return int($max/32)+1;
177 }
178
179 sub insns_flag_index(@) {
180     return undef if $_[0] eq "ignore";
181
182     my @prekey = sort(@_);
183     my $key = join("", @prekey);
184
185     if (not defined($insns_flag_hash{$key})) {
186         my @newkey = (0) x $iflag_words;
187
188         for my $i (@prekey) {
189             die "No key for $i\n" if not defined($insns_flag_bit{$i});
190             $newkey[$insns_flag_bit{$i}[0]/32] |=
191                 (1 << ($insns_flag_bit{$i}[0] % 32));
192         }
193
194         my $str = join(',', map { sprintf("UINT32_C(0x%08x)",$_) } @newkey);
195         
196         push @insns_flag_values, $str;
197         $insns_flag_hash{$key} = $#insns_flag_values;
198     }
199
200     return $insns_flag_hash{$key};
201 }
202
203 sub write_iflaggen_h() {
204     print STDERR "Writing iflaggen.h ...\n";
205
206     open(N, ">iflaggen.h") or die "$0: $!\n";
207
208     print N "/* This file is auto-generated. Don't edit. */\n";
209     print N "#ifndef NASM_IFLAGGEN_H\n";
210     print N "#define NASM_IFLAGGEN_H 1\n\n";
211
212     foreach my $key (sort { $insns_flag_bit{$a}[0] <=> $insns_flag_bit{$b}[0] } keys(%insns_flag_bit)) {
213         print N sprintf("#define IF_%-16s %3d /* %-64s */\n",
214             $key, $insns_flag_bit{$key}[0], $insns_flag_bit{$key}[1]);
215     }
216
217     print N "\n";
218     print N "typedef struct {\n";
219     printf N "    uint32_t field[%d];\n", $iflag_words;
220     print N "} iflag_t;\n";
221
222     print N "\n";
223     printf N "extern const iflag_t insns_flags[%d];\n\n",
224         $#insns_flag_values + 1;
225
226     print N "#endif /* NASM_IFLAGGEN_H */\n";
227     close N;
228 }
229
230 sub write_iflag_c() {
231     print STDERR "Writing iflag.c ...\n";
232
233     open N, ">iflag.c";
234
235     print N "/* This file is auto-generated. Don't edit. */\n";
236     print N "#include \"iflag.h\"\n\n";
237     print N "/* Global flags referenced from instruction templates */\n";
238     printf N "const iflag_t insns_flags[%d] = {\n",
239         $#insns_flag_values + 1;
240     foreach my $i (0 .. $#insns_flag_values) {
241         print N sprintf("    /* %4d */ {{ %s }},\n", $i, $insns_flag_values[$i]);
242     }
243     print N "};\n\n";
244     close N;
245 }
246
247 $iflag_words = get_flag_words();
248
249 1;