]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/i386-gen.c
x86: make RegMem an opcode modifier
[thirdparty/binutils-gdb.git] / opcodes / i386-gen.c
CommitLineData
82704155 1/* Copyright (C) 2007-2019 Free Software Foundation, Inc.
40b8e679 2
9b201bb5 3 This file is part of the GNU opcodes library.
40b8e679 4
9b201bb5 5 This library is free software; you can redistribute it and/or modify
40b8e679 6 it under the terms of the GNU General Public License as published by
9b201bb5
NC
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
40b8e679 9
9b201bb5
NC
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
40b8e679
L
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
9b201bb5
NC
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
40b8e679 19
40fb9820 20#include "sysdep.h"
40b8e679 21#include <stdio.h>
40b8e679
L
22#include <errno.h>
23#include "getopt.h"
24#include "libiberty.h"
c587b3f9 25#include "hashtab.h"
40b8e679
L
26#include "safe-ctype.h"
27
28#include "i386-opc.h"
29
30#include <libintl.h>
31#define _(String) gettext (String)
32
33static const char *program_name = NULL;
34static int debug = 0;
35
40fb9820
L
36typedef struct initializer
37{
38 const char *name;
39 const char *init;
40} initializer;
41
8acd5377 42static initializer cpu_flag_init[] =
40fb9820
L
43{
44 { "CPU_UNKNOWN_FLAGS",
7a9068fe 45 "~(CpuL1OM|CpuK1OM)" },
40fb9820
L
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
29c048b6 48 { "CPU_GENERIC64_FLAGS",
1848e567 49 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
40fb9820
L
50 { "CPU_NONE_FLAGS",
51 "0" },
52 { "CPU_I186_FLAGS",
53 "Cpu186" },
54 { "CPU_I286_FLAGS",
1848e567 55 "CPU_I186_FLAGS|Cpu286" },
40fb9820 56 { "CPU_I386_FLAGS",
1848e567 57 "CPU_I286_FLAGS|Cpu386" },
40fb9820 58 { "CPU_I486_FLAGS",
1848e567 59 "CPU_I386_FLAGS|Cpu486" },
40fb9820 60 { "CPU_I586_FLAGS",
0e0eea78 61 "CPU_I486_FLAGS|Cpu387|Cpu586" },
40fb9820 62 { "CPU_I686_FLAGS",
d871f3f4 63 "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
22109423 64 { "CPU_PENTIUMPRO_FLAGS",
1848e567 65 "CPU_I686_FLAGS|CpuNop" },
40fb9820 66 { "CPU_P2_FLAGS",
1848e567 67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
40fb9820 68 { "CPU_P3_FLAGS",
1848e567 69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
40fb9820 70 { "CPU_P4_FLAGS",
1848e567 71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
40fb9820 72 { "CPU_NOCONA_FLAGS",
1848e567 73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
40fb9820 74 { "CPU_CORE_FLAGS",
1848e567 75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
40fb9820 76 { "CPU_CORE2_FLAGS",
1848e567 77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
bd5295b2 78 { "CPU_COREI7_FLAGS",
1848e567 79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
40fb9820 80 { "CPU_K6_FLAGS",
1848e567 81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
40fb9820 82 { "CPU_K6_2_FLAGS",
1848e567 83 "CPU_K6_FLAGS|Cpu3dnow" },
40fb9820 84 { "CPU_ATHLON_FLAGS",
1848e567 85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
40fb9820 86 { "CPU_K8_FLAGS",
1848e567 87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
40fb9820 88 { "CPU_AMDFAM10_FLAGS",
1848e567 89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
68339fdf 90 { "CPU_BDVER1_FLAGS",
59ef5df4 91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
4cab4add 92 { "CPU_BDVER2_FLAGS",
1848e567 93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
5e5c50d3 94 { "CPU_BDVER3_FLAGS",
1848e567 95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
c7b0bd56 96 { "CPU_BDVER4_FLAGS",
1848e567 97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
029f3522 98 { "CPU_ZNVER1_FLAGS",
59ef5df4 99 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
a9660a6f
AP
100 { "CPU_ZNVER2_FLAGS",
101 "CPU_ZNVER1_FLAGS|CpuRDPID|CpuWBNOINVD|CpuCLWB" },
7b458c12 102 { "CPU_BTVER1_FLAGS",
1848e567 103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
7b458c12 104 { "CPU_BTVER2_FLAGS",
59ef5df4 105 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
309d3373
JB
106 { "CPU_8087_FLAGS",
107 "Cpu8087" },
108 { "CPU_287_FLAGS",
0e0eea78 109 "Cpu287" },
309d3373 110 { "CPU_387_FLAGS",
0e0eea78 111 "Cpu387" },
1848e567
L
112 { "CPU_687_FLAGS",
113 "CPU_387_FLAGS|Cpu687" },
d871f3f4
L
114 { "CPU_CMOV_FLAGS",
115 "CpuCMOV" },
116 { "CPU_FXSR_FLAGS",
117 "CpuFXSR" },
bd5295b2
L
118 { "CPU_CLFLUSH_FLAGS",
119 "CpuClflush" },
22109423
L
120 { "CPU_NOP_FLAGS",
121 "CpuNop" },
bd5295b2
L
122 { "CPU_SYSCALL_FLAGS",
123 "CpuSYSCALL" },
40fb9820 124 { "CPU_MMX_FLAGS",
6e041cf4 125 "CpuMMX" },
40fb9820 126 { "CPU_SSE_FLAGS",
6e041cf4 127 "CpuSSE" },
40fb9820 128 { "CPU_SSE2_FLAGS",
1848e567 129 "CPU_SSE_FLAGS|CpuSSE2" },
40fb9820 130 { "CPU_SSE3_FLAGS",
1848e567 131 "CPU_SSE2_FLAGS|CpuSSE3" },
40fb9820 132 { "CPU_SSSE3_FLAGS",
1848e567 133 "CPU_SSE3_FLAGS|CpuSSSE3" },
40fb9820 134 { "CPU_SSE4_1_FLAGS",
1848e567 135 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
40fb9820 136 { "CPU_SSE4_2_FLAGS",
1848e567 137 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
6305a203
L
138 { "CPU_VMX_FLAGS",
139 "CpuVMX" },
140 { "CPU_SMX_FLAGS",
141 "CpuSMX" },
f03fe4c1
L
142 { "CPU_XSAVE_FLAGS",
143 "CpuXsave" },
c7b8aa3a 144 { "CPU_XSAVEOPT_FLAGS",
1848e567 145 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
c0f3af97 146 { "CPU_AES_FLAGS",
1848e567 147 "CPU_SSE2_FLAGS|CpuAES" },
594ab6a3 148 { "CPU_PCLMUL_FLAGS",
1848e567 149 "CPU_SSE2_FLAGS|CpuPCLMUL" },
c0f3af97 150 { "CPU_FMA_FLAGS",
1848e567 151 "CPU_AVX_FLAGS|CpuFMA" },
922d8de8 152 { "CPU_FMA4_FLAGS",
1848e567 153 "CPU_AVX_FLAGS|CpuFMA4" },
5dd85c99 154 { "CPU_XOP_FLAGS",
1848e567 155 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
f88c9eb0 156 { "CPU_LWP_FLAGS",
59ef5df4 157 "CPU_XSAVE_FLAGS|CpuLWP" },
f12dc422
L
158 { "CPU_BMI_FLAGS",
159 "CpuBMI" },
2a2a0f38
QN
160 { "CPU_TBM_FLAGS",
161 "CpuTBM" },
f1f8f695
L
162 { "CPU_MOVBE_FLAGS",
163 "CpuMovbe" },
60aa667e
L
164 { "CPU_CX16_FLAGS",
165 "CpuCX16" },
1b7f3fb0
L
166 { "CPU_RDTSCP_FLAGS",
167 "CpuRdtscp" },
f1f8f695
L
168 { "CPU_EPT_FLAGS",
169 "CpuEPT" },
c7b8aa3a
L
170 { "CPU_FSGSBASE_FLAGS",
171 "CpuFSGSBase" },
172 { "CPU_RDRND_FLAGS",
173 "CpuRdRnd" },
174 { "CPU_F16C_FLAGS",
1848e567 175 "CPU_AVX_FLAGS|CpuF16C" },
6c30d220
L
176 { "CPU_BMI2_FLAGS",
177 "CpuBMI2" },
178 { "CPU_LZCNT_FLAGS",
179 "CpuLZCNT" },
42164a71
L
180 { "CPU_HLE_FLAGS",
181 "CpuHLE" },
182 { "CPU_RTM_FLAGS",
183 "CpuRTM" },
6c30d220
L
184 { "CPU_INVPCID_FLAGS",
185 "CpuINVPCID" },
8729a6f6
L
186 { "CPU_VMFUNC_FLAGS",
187 "CpuVMFUNC" },
40fb9820 188 { "CPU_3DNOW_FLAGS",
1848e567 189 "CPU_MMX_FLAGS|Cpu3dnow" },
40fb9820 190 { "CPU_3DNOWA_FLAGS",
1848e567 191 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
40fb9820
L
192 { "CPU_PADLOCK_FLAGS",
193 "CpuPadLock" },
194 { "CPU_SVME_FLAGS",
195 "CpuSVME" },
196 { "CPU_SSE4A_FLAGS",
1848e567 197 "CPU_SSE3_FLAGS|CpuSSE4a" },
40fb9820 198 { "CPU_ABM_FLAGS",
3629bb00 199 "CpuABM" },
c0f3af97 200 { "CPU_AVX_FLAGS",
59ef5df4 201 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
6c30d220 202 { "CPU_AVX2_FLAGS",
1848e567 203 "CPU_AVX_FLAGS|CpuAVX2" },
43234a1e 204 { "CPU_AVX512F_FLAGS",
e951d5ca 205 "CPU_AVX2_FLAGS|CpuAVX512F" },
43234a1e 206 { "CPU_AVX512CD_FLAGS",
1848e567 207 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
43234a1e 208 { "CPU_AVX512ER_FLAGS",
1848e567 209 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
43234a1e 210 { "CPU_AVX512PF_FLAGS",
1848e567 211 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
f3ad7637 212 { "CPU_AVX512DQ_FLAGS",
1848e567 213 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
f3ad7637 214 { "CPU_AVX512BW_FLAGS",
1848e567 215 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
f3ad7637 216 { "CPU_AVX512VL_FLAGS",
6e041cf4 217 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
f3ad7637 218 { "CPU_AVX512IFMA_FLAGS",
1848e567 219 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
f3ad7637 220 { "CPU_AVX512VBMI_FLAGS",
1848e567 221 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
920d2ddc
IT
222 { "CPU_AVX512_4FMAPS_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
47acf0bd
IT
224 { "CPU_AVX512_4VNNIW_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
620214f7
IT
226 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
53467f57
IT
228 { "CPU_AVX512_VBMI2_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
8cfcb765
IT
230 { "CPU_AVX512_VNNI_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
ee6872be
IT
232 { "CPU_AVX512_BITALG_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
d6aab7a1
XG
234 { "CPU_AVX512_BF16_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
8a9036a4
L
236 { "CPU_L1OM_FLAGS",
237 "unknown" },
7a9068fe
L
238 { "CPU_K1OM_FLAGS",
239 "unknown" },
7b6d09fb
L
240 { "CPU_IAMCU_FLAGS",
241 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
e2e1fcde
L
242 { "CPU_ADX_FLAGS",
243 "CpuADX" },
244 { "CPU_RDSEED_FLAGS",
245 "CpuRdSeed" },
246 { "CPU_PRFCHW_FLAGS",
247 "CpuPRFCHW" },
5c111e37
L
248 { "CPU_SMAP_FLAGS",
249 "CpuSMAP" },
7e8b059b 250 { "CPU_MPX_FLAGS",
59ef5df4 251 "CPU_XSAVE_FLAGS|CpuMPX" },
a0046408 252 { "CPU_SHA_FLAGS",
1848e567 253 "CPU_SSE2_FLAGS|CpuSHA" },
963f3586
IT
254 { "CPU_CLFLUSHOPT_FLAGS",
255 "CpuClflushOpt" },
256 { "CPU_XSAVES_FLAGS",
1848e567 257 "CPU_XSAVE_FLAGS|CpuXSAVES" },
963f3586 258 { "CPU_XSAVEC_FLAGS",
1848e567 259 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
dcf893b5
IT
260 { "CPU_PREFETCHWT1_FLAGS",
261 "CpuPREFETCHWT1" },
2cf200a4
IT
262 { "CPU_SE1_FLAGS",
263 "CpuSE1" },
c5e7287a
IT
264 { "CPU_CLWB_FLAGS",
265 "CpuCLWB" },
029f3522
GG
266 { "CPU_CLZERO_FLAGS",
267 "CpuCLZERO" },
9916071f
AP
268 { "CPU_MWAITX_FLAGS",
269 "CpuMWAITX" },
8eab4136 270 { "CPU_OSPKE_FLAGS",
59ef5df4 271 "CPU_XSAVE_FLAGS|CpuOSPKE" },
8bc52696 272 { "CPU_RDPID_FLAGS",
1848e567 273 "CpuRDPID" },
6b40c462
L
274 { "CPU_PTWRITE_FLAGS",
275 "CpuPTWRITE" },
d777820b
IT
276 { "CPU_IBT_FLAGS",
277 "CpuIBT" },
278 { "CPU_SHSTK_FLAGS",
279 "CpuSHSTK" },
48521003
IT
280 { "CPU_GFNI_FLAGS",
281 "CpuGFNI" },
8dcf1fad
IT
282 { "CPU_VAES_FLAGS",
283 "CpuVAES" },
ff1982d5
IT
284 { "CPU_VPCLMULQDQ_FLAGS",
285 "CpuVPCLMULQDQ" },
3233d7d0
IT
286 { "CPU_WBNOINVD_FLAGS",
287 "CpuWBNOINVD" },
be3a8dca
IT
288 { "CPU_PCONFIG_FLAGS",
289 "CpuPCONFIG" },
de89d0a3
IT
290 { "CPU_WAITPKG_FLAGS",
291 "CpuWAITPKG" },
c48935d7
IT
292 { "CPU_CLDEMOTE_FLAGS",
293 "CpuCLDEMOTE" },
c0a30a9f
L
294 { "CPU_MOVDIRI_FLAGS",
295 "CpuMOVDIRI" },
296 { "CPU_MOVDIR64B_FLAGS",
297 "CpuMOVDIR64B" },
5d79adc4
L
298 { "CPU_ENQCMD_FLAGS",
299 "CpuENQCMD" },
9186c494
L
300 { "CPU_AVX512_VP2INTERSECT_FLAGS",
301 "CpuAVX512_VP2INTERSECT" },
1848e567
L
302 { "CPU_ANY_X87_FLAGS",
303 "CPU_ANY_287_FLAGS|Cpu8087" },
304 { "CPU_ANY_287_FLAGS",
305 "CPU_ANY_387_FLAGS|Cpu287" },
306 { "CPU_ANY_387_FLAGS",
307 "CPU_ANY_687_FLAGS|Cpu387" },
308 { "CPU_ANY_687_FLAGS",
309 "Cpu687|CpuFISTTP" },
d871f3f4
L
310 { "CPU_ANY_CMOV_FLAGS",
311 "CpuCMOV" },
312 { "CPU_ANY_FXSR_FLAGS",
313 "CpuFXSR" },
1848e567
L
314 { "CPU_ANY_MMX_FLAGS",
315 "CPU_3DNOWA_FLAGS" },
316 { "CPU_ANY_SSE_FLAGS",
317 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
318 { "CPU_ANY_SSE2_FLAGS",
319 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
320 { "CPU_ANY_SSE3_FLAGS",
321 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
322 { "CPU_ANY_SSSE3_FLAGS",
323 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
324 { "CPU_ANY_SSE4_1_FLAGS",
325 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
326 { "CPU_ANY_SSE4_2_FLAGS",
327 "CpuSSE4_2" },
328 { "CPU_ANY_AVX_FLAGS",
329 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
330 { "CPU_ANY_AVX2_FLAGS",
89199bb5 331 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
144b71e2 332 { "CPU_ANY_AVX512F_FLAGS",
9186c494 333 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
144b71e2
L
334 { "CPU_ANY_AVX512CD_FLAGS",
335 "CpuAVX512CD" },
336 { "CPU_ANY_AVX512ER_FLAGS",
337 "CpuAVX512ER" },
338 { "CPU_ANY_AVX512PF_FLAGS",
339 "CpuAVX512PF" },
340 { "CPU_ANY_AVX512DQ_FLAGS",
341 "CpuAVX512DQ" },
342 { "CPU_ANY_AVX512BW_FLAGS",
343 "CpuAVX512BW" },
344 { "CPU_ANY_AVX512VL_FLAGS",
345 "CpuAVX512VL" },
346 { "CPU_ANY_AVX512IFMA_FLAGS",
347 "CpuAVX512IFMA" },
348 { "CPU_ANY_AVX512VBMI_FLAGS",
349 "CpuAVX512VBMI" },
920d2ddc
IT
350 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
351 "CpuAVX512_4FMAPS" },
47acf0bd
IT
352 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
353 "CpuAVX512_4VNNIW" },
620214f7
IT
354 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
355 "CpuAVX512_VPOPCNTDQ" },
d777820b
IT
356 { "CPU_ANY_IBT_FLAGS",
357 "CpuIBT" },
358 { "CPU_ANY_SHSTK_FLAGS",
359 "CpuSHSTK" },
53467f57
IT
360 { "CPU_ANY_AVX512_VBMI2_FLAGS",
361 "CpuAVX512_VBMI2" },
8cfcb765
IT
362 { "CPU_ANY_AVX512_VNNI_FLAGS",
363 "CpuAVX512_VNNI" },
ee6872be
IT
364 { "CPU_ANY_AVX512_BITALG_FLAGS",
365 "CpuAVX512_BITALG" },
d6aab7a1
XG
366 { "CPU_ANY_AVX512_BF16_FLAGS",
367 "CpuAVX512_BF16" },
c0a30a9f
L
368 { "CPU_ANY_MOVDIRI_FLAGS",
369 "CpuMOVDIRI" },
370 { "CPU_ANY_MOVDIR64B_FLAGS",
371 "CpuMOVDIR64B" },
5d79adc4
L
372 { "CPU_ANY_ENQCMD_FLAGS",
373 "CpuENQCMD" },
9186c494
L
374 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
375 "CpuAVX512_VP2INTERSECT" },
40fb9820
L
376};
377
dc821c5f
JB
378static const initializer operand_type_shorthands[] =
379{
380 { "Reg8", "Reg|Byte" },
381 { "Reg16", "Reg|Word" },
382 { "Reg32", "Reg|Dword" },
383 { "Reg64", "Reg|Qword" },
ca0d63fe
JB
384 { "FloatAcc", "Acc|Tbyte" },
385 { "FloatReg", "Reg|Tbyte" },
1b54b8d7
JB
386 { "RegXMM", "RegSIMD|Xmmword" },
387 { "RegYMM", "RegSIMD|Ymmword" },
388 { "RegZMM", "RegSIMD|Zmmword" },
dc821c5f
JB
389};
390
8acd5377 391static initializer operand_type_init[] =
40fb9820
L
392{
393 { "OPERAND_TYPE_NONE",
394 "0" },
395 { "OPERAND_TYPE_REG8",
396 "Reg8" },
397 { "OPERAND_TYPE_REG16",
398 "Reg16" },
399 { "OPERAND_TYPE_REG32",
400 "Reg32" },
401 { "OPERAND_TYPE_REG64",
402 "Reg64" },
403 { "OPERAND_TYPE_IMM1",
404 "Imm1" },
405 { "OPERAND_TYPE_IMM8",
406 "Imm8" },
407 { "OPERAND_TYPE_IMM8S",
408 "Imm8S" },
409 { "OPERAND_TYPE_IMM16",
410 "Imm16" },
411 { "OPERAND_TYPE_IMM32",
412 "Imm32" },
413 { "OPERAND_TYPE_IMM32S",
414 "Imm32S" },
415 { "OPERAND_TYPE_IMM64",
416 "Imm64" },
417 { "OPERAND_TYPE_BASEINDEX",
418 "BaseIndex" },
419 { "OPERAND_TYPE_DISP8",
420 "Disp8" },
421 { "OPERAND_TYPE_DISP16",
422 "Disp16" },
423 { "OPERAND_TYPE_DISP32",
424 "Disp32" },
425 { "OPERAND_TYPE_DISP32S",
426 "Disp32S" },
427 { "OPERAND_TYPE_DISP64",
428 "Disp64" },
429 { "OPERAND_TYPE_INOUTPORTREG",
430 "InOutPortReg" },
431 { "OPERAND_TYPE_SHIFTCOUNT",
432 "ShiftCount" },
433 { "OPERAND_TYPE_CONTROL",
434 "Control" },
435 { "OPERAND_TYPE_TEST",
436 "Test" },
437 { "OPERAND_TYPE_DEBUG",
2c703856 438 "Debug" },
40fb9820
L
439 { "OPERAND_TYPE_FLOATREG",
440 "FloatReg" },
441 { "OPERAND_TYPE_FLOATACC",
442 "FloatAcc" },
21df382b
JB
443 { "OPERAND_TYPE_SREG",
444 "SReg" },
40fb9820
L
445 { "OPERAND_TYPE_JUMPABSOLUTE",
446 "JumpAbsolute" },
447 { "OPERAND_TYPE_REGMMX",
448 "RegMMX" },
449 { "OPERAND_TYPE_REGXMM",
450 "RegXMM" },
1508bbf5
JB
451 { "OPERAND_TYPE_REGYMM",
452 "RegYMM" },
453 { "OPERAND_TYPE_REGZMM",
454 "RegZMM" },
43234a1e
L
455 { "OPERAND_TYPE_REGMASK",
456 "RegMask" },
40fb9820
L
457 { "OPERAND_TYPE_ESSEG",
458 "EsSeg" },
2c703856
JB
459 { "OPERAND_TYPE_ACC8",
460 "Acc|Byte" },
461 { "OPERAND_TYPE_ACC16",
462 "Acc|Word" },
40fb9820 463 { "OPERAND_TYPE_ACC32",
2c703856 464 "Acc|Dword" },
40fb9820 465 { "OPERAND_TYPE_ACC64",
2c703856 466 "Acc|Qword" },
40fb9820
L
467 { "OPERAND_TYPE_DISP16_32",
468 "Disp16|Disp32" },
469 { "OPERAND_TYPE_ANYDISP",
470 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
471 { "OPERAND_TYPE_IMM16_32",
472 "Imm16|Imm32" },
473 { "OPERAND_TYPE_IMM16_32S",
474 "Imm16|Imm32S" },
475 { "OPERAND_TYPE_IMM16_32_32S",
476 "Imm16|Imm32|Imm32S" },
2f81ff92
L
477 { "OPERAND_TYPE_IMM32_64",
478 "Imm32|Imm64" },
40fb9820
L
479 { "OPERAND_TYPE_IMM32_32S_DISP32",
480 "Imm32|Imm32S|Disp32" },
481 { "OPERAND_TYPE_IMM64_DISP64",
482 "Imm64|Disp64" },
483 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
484 "Imm32|Imm32S|Imm64|Disp32" },
485 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
486 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
7e8b059b
L
487 { "OPERAND_TYPE_REGBND",
488 "RegBND" },
40fb9820
L
489};
490
491typedef struct bitfield
492{
493 int position;
494 int value;
495 const char *name;
496} bitfield;
497
498#define BITFIELD(n) { n, 0, #n }
499
500static bitfield cpu_flags[] =
501{
502 BITFIELD (Cpu186),
503 BITFIELD (Cpu286),
504 BITFIELD (Cpu386),
505 BITFIELD (Cpu486),
506 BITFIELD (Cpu586),
507 BITFIELD (Cpu686),
d871f3f4
L
508 BITFIELD (CpuCMOV),
509 BITFIELD (CpuFXSR),
bd5295b2 510 BITFIELD (CpuClflush),
22109423 511 BITFIELD (CpuNop),
bd5295b2 512 BITFIELD (CpuSYSCALL),
309d3373
JB
513 BITFIELD (Cpu8087),
514 BITFIELD (Cpu287),
515 BITFIELD (Cpu387),
516 BITFIELD (Cpu687),
517 BITFIELD (CpuFISTTP),
40fb9820 518 BITFIELD (CpuMMX),
40fb9820
L
519 BITFIELD (CpuSSE),
520 BITFIELD (CpuSSE2),
521 BITFIELD (CpuSSE3),
522 BITFIELD (CpuSSSE3),
523 BITFIELD (CpuSSE4_1),
524 BITFIELD (CpuSSE4_2),
c0f3af97 525 BITFIELD (CpuAVX),
6c30d220 526 BITFIELD (CpuAVX2),
43234a1e
L
527 BITFIELD (CpuAVX512F),
528 BITFIELD (CpuAVX512CD),
529 BITFIELD (CpuAVX512ER),
530 BITFIELD (CpuAVX512PF),
b28d1bda 531 BITFIELD (CpuAVX512VL),
90a915bf 532 BITFIELD (CpuAVX512DQ),
1ba585e8 533 BITFIELD (CpuAVX512BW),
8a9036a4 534 BITFIELD (CpuL1OM),
7a9068fe 535 BITFIELD (CpuK1OM),
7b6d09fb 536 BITFIELD (CpuIAMCU),
40fb9820
L
537 BITFIELD (CpuSSE4a),
538 BITFIELD (Cpu3dnow),
539 BITFIELD (Cpu3dnowA),
540 BITFIELD (CpuPadLock),
541 BITFIELD (CpuSVME),
542 BITFIELD (CpuVMX),
47dd174c 543 BITFIELD (CpuSMX),
40fb9820 544 BITFIELD (CpuABM),
475a2301 545 BITFIELD (CpuXsave),
c7b8aa3a 546 BITFIELD (CpuXsaveopt),
c0f3af97 547 BITFIELD (CpuAES),
594ab6a3 548 BITFIELD (CpuPCLMUL),
c0f3af97 549 BITFIELD (CpuFMA),
f88c9eb0 550 BITFIELD (CpuFMA4),
5dd85c99 551 BITFIELD (CpuXOP),
f88c9eb0 552 BITFIELD (CpuLWP),
f12dc422 553 BITFIELD (CpuBMI),
2a2a0f38 554 BITFIELD (CpuTBM),
c0f3af97 555 BITFIELD (CpuLM),
f1f8f695 556 BITFIELD (CpuMovbe),
60aa667e 557 BITFIELD (CpuCX16),
f1f8f695 558 BITFIELD (CpuEPT),
1b7f3fb0 559 BITFIELD (CpuRdtscp),
c7b8aa3a
L
560 BITFIELD (CpuFSGSBase),
561 BITFIELD (CpuRdRnd),
562 BITFIELD (CpuF16C),
6c30d220
L
563 BITFIELD (CpuBMI2),
564 BITFIELD (CpuLZCNT),
42164a71
L
565 BITFIELD (CpuHLE),
566 BITFIELD (CpuRTM),
6c30d220 567 BITFIELD (CpuINVPCID),
8729a6f6 568 BITFIELD (CpuVMFUNC),
e2e1fcde
L
569 BITFIELD (CpuRDSEED),
570 BITFIELD (CpuADX),
571 BITFIELD (CpuPRFCHW),
5c111e37 572 BITFIELD (CpuSMAP),
a0046408 573 BITFIELD (CpuSHA),
963f3586
IT
574 BITFIELD (CpuClflushOpt),
575 BITFIELD (CpuXSAVES),
576 BITFIELD (CpuXSAVEC),
dcf893b5 577 BITFIELD (CpuPREFETCHWT1),
2cf200a4 578 BITFIELD (CpuSE1),
c5e7287a 579 BITFIELD (CpuCLWB),
40fb9820
L
580 BITFIELD (Cpu64),
581 BITFIELD (CpuNo64),
7e8b059b 582 BITFIELD (CpuMPX),
2cc1b5aa 583 BITFIELD (CpuAVX512IFMA),
14f195c9 584 BITFIELD (CpuAVX512VBMI),
920d2ddc 585 BITFIELD (CpuAVX512_4FMAPS),
47acf0bd 586 BITFIELD (CpuAVX512_4VNNIW),
620214f7 587 BITFIELD (CpuAVX512_VPOPCNTDQ),
53467f57 588 BITFIELD (CpuAVX512_VBMI2),
8cfcb765 589 BITFIELD (CpuAVX512_VNNI),
ee6872be 590 BITFIELD (CpuAVX512_BITALG),
d6aab7a1 591 BITFIELD (CpuAVX512_BF16),
9186c494 592 BITFIELD (CpuAVX512_VP2INTERSECT),
9916071f 593 BITFIELD (CpuMWAITX),
029f3522 594 BITFIELD (CpuCLZERO),
8eab4136 595 BITFIELD (CpuOSPKE),
8bc52696 596 BITFIELD (CpuRDPID),
6b40c462 597 BITFIELD (CpuPTWRITE),
d777820b
IT
598 BITFIELD (CpuIBT),
599 BITFIELD (CpuSHSTK),
48521003 600 BITFIELD (CpuGFNI),
8dcf1fad 601 BITFIELD (CpuVAES),
ff1982d5 602 BITFIELD (CpuVPCLMULQDQ),
3233d7d0 603 BITFIELD (CpuWBNOINVD),
be3a8dca 604 BITFIELD (CpuPCONFIG),
de89d0a3 605 BITFIELD (CpuWAITPKG),
c48935d7 606 BITFIELD (CpuCLDEMOTE),
c0a30a9f
L
607 BITFIELD (CpuMOVDIRI),
608 BITFIELD (CpuMOVDIR64B),
5d79adc4 609 BITFIELD (CpuENQCMD),
40fb9820
L
610#ifdef CpuUnused
611 BITFIELD (CpuUnused),
612#endif
613};
614
615static bitfield opcode_modifiers[] =
616{
617 BITFIELD (D),
618 BITFIELD (W),
86fa6981 619 BITFIELD (Load),
40fb9820
L
620 BITFIELD (Modrm),
621 BITFIELD (ShortForm),
622 BITFIELD (Jump),
623 BITFIELD (JumpDword),
624 BITFIELD (JumpByte),
625 BITFIELD (JumpInterSegment),
626 BITFIELD (FloatMF),
627 BITFIELD (FloatR),
673fe0f0 628 BITFIELD (Size),
56ffb741 629 BITFIELD (CheckRegSize),
40fb9820
L
630 BITFIELD (IgnoreSize),
631 BITFIELD (DefaultSize),
632 BITFIELD (No_bSuf),
633 BITFIELD (No_wSuf),
634 BITFIELD (No_lSuf),
635 BITFIELD (No_sSuf),
636 BITFIELD (No_qSuf),
7ce189b3 637 BITFIELD (No_ldSuf),
40fb9820
L
638 BITFIELD (FWait),
639 BITFIELD (IsString),
dfd69174 640 BITFIELD (RegMem),
7e8b059b 641 BITFIELD (BNDPrefixOk),
04ef582a 642 BITFIELD (NoTrackPrefixOk),
c32fa91d 643 BITFIELD (IsLockable),
40fb9820 644 BITFIELD (RegKludge),
c0f3af97 645 BITFIELD (Implicit1stXmm0),
29c048b6 646 BITFIELD (RepPrefixOk),
42164a71 647 BITFIELD (HLEPrefixOk),
ca61edf2
L
648 BITFIELD (ToDword),
649 BITFIELD (ToQword),
75c0a438 650 BITFIELD (AddrPrefixOpReg),
40fb9820
L
651 BITFIELD (IsPrefix),
652 BITFIELD (ImmExt),
653 BITFIELD (NoRex64),
654 BITFIELD (Rex64),
655 BITFIELD (Ugh),
c0f3af97 656 BITFIELD (Vex),
2426c15f 657 BITFIELD (VexVVVV),
1ef99a7b 658 BITFIELD (VexW),
7f399153 659 BITFIELD (VexOpcode),
8cd7925b 660 BITFIELD (VexSources),
6c30d220 661 BITFIELD (VecSIB),
c0f3af97 662 BITFIELD (SSE2AVX),
81f8a913 663 BITFIELD (NoAVX),
43234a1e
L
664 BITFIELD (EVex),
665 BITFIELD (Masking),
43234a1e
L
666 BITFIELD (Broadcast),
667 BITFIELD (StaticRounding),
668 BITFIELD (SAE),
669 BITFIELD (Disp8MemShift),
670 BITFIELD (NoDefMask),
920d2ddc 671 BITFIELD (ImplicitQuadGroup),
b6f8c7c4 672 BITFIELD (Optimize),
1efbbeb4 673 BITFIELD (ATTMnemonic),
e1d4d893 674 BITFIELD (ATTSyntax),
5c07affc 675 BITFIELD (IntelSyntax),
e92bae62
L
676 BITFIELD (AMD64),
677 BITFIELD (Intel64),
40fb9820
L
678};
679
680static bitfield operand_types[] =
681{
dc821c5f 682 BITFIELD (Reg),
40fb9820 683 BITFIELD (RegMMX),
1b54b8d7 684 BITFIELD (RegSIMD),
43234a1e 685 BITFIELD (RegMask),
94ff3a50 686 BITFIELD (Imm1),
40fb9820
L
687 BITFIELD (Imm8),
688 BITFIELD (Imm8S),
689 BITFIELD (Imm16),
690 BITFIELD (Imm32),
691 BITFIELD (Imm32S),
692 BITFIELD (Imm64),
40fb9820
L
693 BITFIELD (BaseIndex),
694 BITFIELD (Disp8),
695 BITFIELD (Disp16),
696 BITFIELD (Disp32),
697 BITFIELD (Disp32S),
698 BITFIELD (Disp64),
699 BITFIELD (InOutPortReg),
700 BITFIELD (ShiftCount),
701 BITFIELD (Control),
702 BITFIELD (Debug),
703 BITFIELD (Test),
21df382b 704 BITFIELD (SReg),
40fb9820 705 BITFIELD (Acc),
40fb9820
L
706 BITFIELD (JumpAbsolute),
707 BITFIELD (EsSeg),
7d5e4556
L
708 BITFIELD (Byte),
709 BITFIELD (Word),
710 BITFIELD (Dword),
711 BITFIELD (Fword),
712 BITFIELD (Qword),
713 BITFIELD (Tbyte),
714 BITFIELD (Xmmword),
c0f3af97 715 BITFIELD (Ymmword),
43234a1e 716 BITFIELD (Zmmword),
7d5e4556
L
717 BITFIELD (Unspecified),
718 BITFIELD (Anysize),
7e8b059b 719 BITFIELD (RegBND),
40fb9820
L
720#ifdef OTUnused
721 BITFIELD (OTUnused),
722#endif
723};
724
3d4d5afa 725static const char *filename;
7ac20022
JB
726static i386_cpu_flags active_cpu_flags;
727static int active_isstring;
3d4d5afa 728
40fb9820
L
729static int
730compare (const void *x, const void *y)
731{
732 const bitfield *xp = (const bitfield *) x;
733 const bitfield *yp = (const bitfield *) y;
734 return xp->position - yp->position;
735}
736
40b8e679
L
737static void
738fail (const char *message, ...)
739{
740 va_list args;
29c048b6 741
40b8e679 742 va_start (args, message);
a6743a54 743 fprintf (stderr, _("%s: error: "), program_name);
40b8e679
L
744 vfprintf (stderr, message, args);
745 va_end (args);
746 xexit (1);
747}
748
72ffa0fb
L
749static void
750process_copyright (FILE *fp)
751{
752 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
82704155 753/* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
72ffa0fb
L
754\n\
755 This file is part of the GNU opcodes library.\n\
756\n\
757 This library is free software; you can redistribute it and/or modify\n\
758 it under the terms of the GNU General Public License as published by\n\
759 the Free Software Foundation; either version 3, or (at your option)\n\
760 any later version.\n\
761\n\
762 It is distributed in the hope that it will be useful, but WITHOUT\n\
763 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
764 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
765 License for more details.\n\
766\n\
767 You should have received a copy of the GNU General Public License\n\
768 along with this program; if not, write to the Free Software\n\
769 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
770 MA 02110-1301, USA. */\n");
771}
772
40b8e679
L
773/* Remove leading white spaces. */
774
775static char *
776remove_leading_whitespaces (char *str)
777{
778 while (ISSPACE (*str))
779 str++;
780 return str;
781}
782
783/* Remove trailing white spaces. */
784
785static void
786remove_trailing_whitespaces (char *str)
787{
788 size_t last = strlen (str);
789
790 if (last == 0)
791 return;
792
793 do
794 {
795 last--;
796 if (ISSPACE (str [last]))
797 str[last] = '\0';
798 else
799 break;
800 }
801 while (last != 0);
802}
803
93b1ec2c 804/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
805 pointer to the one after it. */
806
807static char *
c587b3f9 808next_field (char *str, char sep, char **next, char *last)
40b8e679
L
809{
810 char *p;
811
812 p = remove_leading_whitespaces (str);
93b1ec2c 813 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
814
815 *str = '\0';
816 remove_trailing_whitespaces (p);
817
29c048b6 818 *next = str + 1;
40b8e679 819
c587b3f9
L
820 if (p >= last)
821 abort ();
822
40b8e679
L
823 return p;
824}
825
1848e567
L
826static void set_bitfield (char *, bitfield *, int, unsigned int, int);
827
828static int
dc821c5f
JB
829set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
830 int lineno)
1848e567
L
831{
832 char *str, *next, *last;
833 unsigned int i;
834
835 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
836 if (strcmp (cpu_flag_init[i].name, f) == 0)
837 {
838 /* Turn on selective bits. */
839 char *init = xstrdup (cpu_flag_init[i].init);
840 last = init + strlen (init);
841 for (next = init; next && next < last; )
842 {
843 str = next_field (next, '|', &next, last);
844 if (str)
845 set_bitfield (str, array, 1, size, lineno);
846 }
847 free (init);
848 return 0;
849 }
850
dc821c5f
JB
851 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
852 if (strcmp (operand_type_shorthands[i].name, f) == 0)
853 {
854 /* Turn on selective bits. */
855 char *init = xstrdup (operand_type_shorthands[i].init);
856 last = init + strlen (init);
857 for (next = init; next && next < last; )
858 {
859 str = next_field (next, '|', &next, last);
860 if (str)
861 set_bitfield (str, array, 1, size, lineno);
862 }
863 free (init);
864 return 0;
865 }
866
1848e567
L
867 return -1;
868}
869
40fb9820 870static void
1848e567 871set_bitfield (char *f, bitfield *array, int value,
8a9036a4 872 unsigned int size, int lineno)
40fb9820
L
873{
874 unsigned int i;
875
309d3373
JB
876 if (strcmp (f, "CpuFP") == 0)
877 {
8a9036a4
L
878 set_bitfield("Cpu387", array, value, size, lineno);
879 set_bitfield("Cpu287", array, value, size, lineno);
309d3373
JB
880 f = "Cpu8087";
881 }
882 else if (strcmp (f, "Mmword") == 0)
7d5e4556
L
883 f= "Qword";
884 else if (strcmp (f, "Oword") == 0)
885 f= "Xmmword";
40fb9820
L
886
887 for (i = 0; i < size; i++)
888 if (strcasecmp (array[i].name, f) == 0)
889 {
8a9036a4 890 array[i].value = value;
40fb9820
L
891 return;
892 }
893
2bf05e57
L
894 if (value)
895 {
896 const char *v = strchr (f, '=');
897
898 if (v)
899 {
900 size_t n = v - f;
901 char *end;
902
903 for (i = 0; i < size; i++)
904 if (strncasecmp (array[i].name, f, n) == 0)
905 {
906 value = strtol (v + 1, &end, 0);
907 if (*end == '\0')
908 {
909 array[i].value = value;
910 return;
911 }
912 break;
913 }
914 }
915 }
916
dc821c5f
JB
917 /* Handle shorthands. */
918 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
1848e567
L
919 return;
920
bd5295b2 921 if (lineno != -1)
a6743a54 922 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
bd5295b2 923 else
a6743a54 924 fail (_("unknown bitfield: %s\n"), f);
40fb9820
L
925}
926
927static void
928output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
929 int macro, const char *comma, const char *indent)
930{
931 unsigned int i;
932
7ac20022
JB
933 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
934
40fb9820
L
935 fprintf (table, "%s{ { ", indent);
936
937 for (i = 0; i < size - 1; i++)
938 {
10632b79
L
939 if (((i + 1) % 20) != 0)
940 fprintf (table, "%d, ", flags[i].value);
941 else
942 fprintf (table, "%d,", flags[i].value);
40fb9820
L
943 if (((i + 1) % 20) == 0)
944 {
945 /* We need \\ for macro. */
946 if (macro)
947 fprintf (table, " \\\n %s", indent);
948 else
949 fprintf (table, "\n %s", indent);
950 }
7ac20022
JB
951 if (flags[i].value)
952 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
953 }
954
955 fprintf (table, "%d } }%s\n", flags[i].value, comma);
956}
957
958static void
959process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
960 const char *comma, const char *indent,
961 int lineno)
40fb9820
L
962{
963 char *str, *next, *last;
8a9036a4 964 unsigned int i;
40fb9820
L
965 bitfield flags [ARRAY_SIZE (cpu_flags)];
966
967 /* Copy the default cpu flags. */
968 memcpy (flags, cpu_flags, sizeof (cpu_flags));
969
970 if (strcasecmp (flag, "unknown") == 0)
971 {
40fb9820 972 /* We turn on everything except for cpu64 in case of
8a9036a4
L
973 CPU_UNKNOWN_FLAGS. */
974 for (i = 0; i < ARRAY_SIZE (flags); i++)
975 if (flags[i].position != Cpu64)
976 flags[i].value = 1;
977 }
978 else if (flag[0] == '~')
979 {
980 last = flag + strlen (flag);
981
982 if (flag[1] == '(')
983 {
984 last -= 1;
985 next = flag + 2;
986 if (*last != ')')
a6743a54 987 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
8a9036a4
L
988 lineno, flag);
989 *last = '\0';
990 }
991 else
992 next = flag + 1;
993
994 /* First we turn on everything except for cpu64. */
40fb9820
L
995 for (i = 0; i < ARRAY_SIZE (flags); i++)
996 if (flags[i].position != Cpu64)
997 flags[i].value = 1;
8a9036a4
L
998
999 /* Turn off selective bits. */
1000 for (; next && next < last; )
1001 {
1002 str = next_field (next, '|', &next, last);
1003 if (str)
1004 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1005 }
40fb9820
L
1006 }
1007 else if (strcmp (flag, "0"))
1008 {
8a9036a4 1009 /* Turn on selective bits. */
40fb9820
L
1010 last = flag + strlen (flag);
1011 for (next = flag; next && next < last; )
1012 {
c587b3f9 1013 str = next_field (next, '|', &next, last);
40fb9820 1014 if (str)
8a9036a4 1015 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
1016 }
1017 }
1018
1019 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1020 comma, indent);
1021}
1022
1023static void
1024output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1025{
1026 unsigned int i;
1027
1028 fprintf (table, " { ");
1029
1030 for (i = 0; i < size - 1; i++)
1031 {
10632b79
L
1032 if (((i + 1) % 20) != 0)
1033 fprintf (table, "%d, ", modifier[i].value);
1034 else
1035 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1036 if (((i + 1) % 20) == 0)
1037 fprintf (table, "\n ");
1038 }
1039
1040 fprintf (table, "%d },\n", modifier[i].value);
1041}
1042
4a1b91ea
L
1043static int
1044adjust_broadcast_modifier (char **opnd)
1045{
1046 char *str, *next, *last, *op;
1047 int bcst_type = INT_MAX;
1048
1049 /* Skip the immediate operand. */
1050 op = opnd[0];
1051 if (strcasecmp(op, "Imm8") == 0)
1052 op = opnd[1];
1053
1054 op = xstrdup (op);
1055 last = op + strlen (op);
1056 for (next = op; next && next < last; )
1057 {
1058 str = next_field (next, '|', &next, last);
1059 if (str)
1060 {
1061 if (strcasecmp(str, "Byte") == 0)
1062 {
1063 /* The smalest broadcast type, no need to check
1064 further. */
1065 bcst_type = BYTE_BROADCAST;
1066 break;
1067 }
1068 else if (strcasecmp(str, "Word") == 0)
1069 {
1070 if (bcst_type > WORD_BROADCAST)
1071 bcst_type = WORD_BROADCAST;
1072 }
1073 else if (strcasecmp(str, "Dword") == 0)
1074 {
1075 if (bcst_type > DWORD_BROADCAST)
1076 bcst_type = DWORD_BROADCAST;
1077 }
1078 else if (strcasecmp(str, "Qword") == 0)
1079 {
1080 if (bcst_type > QWORD_BROADCAST)
1081 bcst_type = QWORD_BROADCAST;
1082 }
1083 }
1084 }
1085 free (op);
1086
1087 if (bcst_type == INT_MAX)
1088 fail (_("unknown broadcast operand: %s\n"), op);
1089
1090 return bcst_type;
1091}
1092
40fb9820 1093static void
4a1b91ea 1094process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
40fb9820
L
1095{
1096 char *str, *next, *last;
1097 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1098
7ac20022
JB
1099 active_isstring = 0;
1100
40fb9820
L
1101 /* Copy the default opcode modifier. */
1102 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1103
1104 if (strcmp (mod, "0"))
1105 {
1106 last = mod + strlen (mod);
1107 for (next = mod; next && next < last; )
1108 {
c587b3f9 1109 str = next_field (next, '|', &next, last);
40fb9820 1110 if (str)
7ac20022 1111 {
4a1b91ea
L
1112 int val = 1;
1113 if (strcasecmp(str, "Broadcast") == 0)
1114 val = adjust_broadcast_modifier (opnd);
1115 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
8a9036a4 1116 lineno);
7ac20022
JB
1117 if (strcasecmp(str, "IsString") == 0)
1118 active_isstring = 1;
1119 }
40fb9820
L
1120 }
1121 }
1122 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1123}
1124
7ac20022
JB
1125enum stage {
1126 stage_macros,
1127 stage_opcodes,
1128 stage_registers,
1129};
1130
40fb9820
L
1131static void
1132output_operand_type (FILE *table, bitfield *types, unsigned int size,
7ac20022 1133 enum stage stage, const char *indent)
40fb9820
L
1134{
1135 unsigned int i;
1136
1137 fprintf (table, "{ { ");
1138
1139 for (i = 0; i < size - 1; i++)
1140 {
10632b79
L
1141 if (((i + 1) % 20) != 0)
1142 fprintf (table, "%d, ", types[i].value);
1143 else
1144 fprintf (table, "%d,", types[i].value);
40fb9820
L
1145 if (((i + 1) % 20) == 0)
1146 {
1147 /* We need \\ for macro. */
7ac20022 1148 if (stage == stage_macros)
10632b79 1149 fprintf (table, " \\\n%s", indent);
40fb9820
L
1150 else
1151 fprintf (table, "\n%s", indent);
1152 }
1153 }
1154
1155 fprintf (table, "%d } }", types[i].value);
1156}
1157
1158static void
7ac20022 1159process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1160 const char *indent, int lineno)
40fb9820
L
1161{
1162 char *str, *next, *last;
1163 bitfield types [ARRAY_SIZE (operand_types)];
1164
1165 /* Copy the default operand type. */
1166 memcpy (types, operand_types, sizeof (types));
1167
1168 if (strcmp (op, "0"))
1169 {
7ac20022
JB
1170 int baseindex = 0;
1171
40fb9820
L
1172 last = op + strlen (op);
1173 for (next = op; next && next < last; )
1174 {
c587b3f9 1175 str = next_field (next, '|', &next, last);
40fb9820 1176 if (str)
7ac20022
JB
1177 {
1178 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1179 if (strcasecmp(str, "BaseIndex") == 0)
1180 baseindex = 1;
1181 }
1182 }
1183
1184 if (stage == stage_opcodes && baseindex && !active_isstring)
1185 {
1186 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1187 if (!active_cpu_flags.bitfield.cpu64
1188 && !active_cpu_flags.bitfield.cpumpx)
1189 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1190 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1191 if (!active_cpu_flags.bitfield.cpuno64)
1192 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1193 }
1194 }
7ac20022 1195 output_operand_type (table, types, ARRAY_SIZE (types), stage,
40fb9820
L
1196 indent);
1197}
1198
c587b3f9
L
1199static void
1200output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1201 char *last, int lineno)
c587b3f9
L
1202{
1203 unsigned int i;
1204 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1205 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1206
1207 /* Find number of operands. */
1208 operands = next_field (str, ',', &str, last);
1209
1210 /* Find base_opcode. */
1211 base_opcode = next_field (str, ',', &str, last);
1212
1213 /* Find extension_opcode. */
1214 extension_opcode = next_field (str, ',', &str, last);
1215
1216 /* Find opcode_length. */
1217 opcode_length = next_field (str, ',', &str, last);
1218
1219 /* Find cpu_flags. */
1220 cpu_flags = next_field (str, ',', &str, last);
1221
1222 /* Find opcode_modifier. */
1223 opcode_modifier = next_field (str, ',', &str, last);
1224
1225 /* Remove the first {. */
1226 str = remove_leading_whitespaces (str);
1227 if (*str != '{')
1228 abort ();
1229 str = remove_leading_whitespaces (str + 1);
1230
1231 i = strlen (str);
1232
1233 /* There are at least "X}". */
1234 if (i < 2)
1235 abort ();
1236
1237 /* Remove trailing white spaces and }. */
1238 do
1239 {
1240 i--;
1241 if (ISSPACE (str[i]) || str[i] == '}')
1242 str[i] = '\0';
1243 else
1244 break;
1245 }
1246 while (i != 0);
1247
1248 last = str + i;
1249
1250 /* Find operand_types. */
1251 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1252 {
1253 if (str >= last)
1254 {
1255 operand_types [i] = NULL;
1256 break;
1257 }
1258
1259 operand_types [i] = next_field (str, ',', &str, last);
1260 if (*operand_types[i] == '0')
1261 {
1262 if (i != 0)
1263 operand_types[i] = NULL;
1264 break;
1265 }
1266 }
1267
1268 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1269 name, operands, base_opcode, extension_opcode,
1270 opcode_length);
1271
bd5295b2 1272 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
c587b3f9 1273
4a1b91ea 1274 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
c587b3f9
L
1275
1276 fprintf (table, " { ");
1277
1278 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1279 {
1280 if (operand_types[i] == NULL || *operand_types[i] == '0')
1281 {
1282 if (i == 0)
7ac20022
JB
1283 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1284 lineno);
c587b3f9
L
1285 break;
1286 }
1287
1288 if (i != 0)
1289 fprintf (table, ",\n ");
1290
7ac20022 1291 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1292 "\t ", lineno);
c587b3f9
L
1293 }
1294 fprintf (table, " } },\n");
1295}
1296
1297struct opcode_hash_entry
1298{
1299 struct opcode_hash_entry *next;
1300 char *name;
1301 char *opcode;
bd5295b2 1302 int lineno;
c587b3f9
L
1303};
1304
1305/* Calculate the hash value of an opcode hash entry P. */
1306
1307static hashval_t
1308opcode_hash_hash (const void *p)
1309{
1310 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1311 return htab_hash_string (entry->name);
1312}
1313
1314/* Compare a string Q against an opcode hash entry P. */
1315
1316static int
1317opcode_hash_eq (const void *p, const void *q)
1318{
1319 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1320 const char *name = (const char *) q;
1321 return strcmp (name, entry->name) == 0;
1322}
1323
40b8e679 1324static void
72ffa0fb 1325process_i386_opcodes (FILE *table)
40b8e679 1326{
3d4d5afa 1327 FILE *fp;
40b8e679 1328 char buf[2048];
c587b3f9
L
1329 unsigned int i, j;
1330 char *str, *p, *last, *name;
1331 struct opcode_hash_entry **hash_slot, **entry, *next;
1332 htab_t opcode_hash_table;
1333 struct opcode_hash_entry **opcode_array;
1334 unsigned int opcode_array_size = 1024;
c30be56e 1335 int lineno = 0, marker = 0;
40b8e679 1336
3d4d5afa 1337 filename = "i386-opc.tbl";
c30be56e 1338 fp = stdin;
40b8e679 1339
c587b3f9
L
1340 i = 0;
1341 opcode_array = (struct opcode_hash_entry **)
1342 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1343
1344 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1345 opcode_hash_eq, NULL,
1346 xcalloc, free);
1347
34edb9ad 1348 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1349 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1350
c587b3f9 1351 /* Put everything on opcode array. */
40b8e679
L
1352 while (!feof (fp))
1353 {
1354 if (fgets (buf, sizeof (buf), fp) == NULL)
1355 break;
1356
3d4d5afa
L
1357 lineno++;
1358
40b8e679
L
1359 p = remove_leading_whitespaces (buf);
1360
1361 /* Skip comments. */
1362 str = strstr (p, "//");
1363 if (str != NULL)
1364 str[0] = '\0';
1365
1366 /* Remove trailing white spaces. */
1367 remove_trailing_whitespaces (p);
1368
1369 switch (p[0])
1370 {
1371 case '#':
c30be56e
JB
1372 if (!strcmp("### MARKER ###", buf))
1373 marker = 1;
1374 else
1375 {
1376 /* Since we ignore all included files (we only care about their
1377 #define-s here), we don't need to monitor filenames. The final
1378 line number directive is going to refer to the main source file
1379 again. */
1380 char *end;
1381 unsigned long ln;
1382
1383 p = remove_leading_whitespaces (p + 1);
1384 if (!strncmp(p, "line", 4))
1385 p += 4;
1386 ln = strtoul (p, &end, 10);
1387 if (ln > 1 && ln < INT_MAX
1388 && *remove_leading_whitespaces (end) == '"')
1389 lineno = ln - 1;
1390 }
c587b3f9 1391 /* Ignore comments. */
40b8e679
L
1392 case '\0':
1393 continue;
1394 break;
1395 default:
c30be56e
JB
1396 if (!marker)
1397 continue;
40b8e679
L
1398 break;
1399 }
1400
1401 last = p + strlen (p);
1402
1403 /* Find name. */
c587b3f9 1404 name = next_field (p, ',', &str, last);
40b8e679 1405
c587b3f9
L
1406 /* Get the slot in hash table. */
1407 hash_slot = (struct opcode_hash_entry **)
1408 htab_find_slot_with_hash (opcode_hash_table, name,
1409 htab_hash_string (name),
1410 INSERT);
40b8e679 1411
c587b3f9 1412 if (*hash_slot == NULL)
40b8e679 1413 {
c587b3f9
L
1414 /* It is the new one. Put it on opcode array. */
1415 if (i >= opcode_array_size)
40b8e679 1416 {
c587b3f9
L
1417 /* Grow the opcode array when needed. */
1418 opcode_array_size += 1024;
1419 opcode_array = (struct opcode_hash_entry **)
1420 xrealloc (opcode_array,
1421 sizeof (*opcode_array) * opcode_array_size);
40b8e679
L
1422 }
1423
c587b3f9
L
1424 opcode_array[i] = (struct opcode_hash_entry *)
1425 xmalloc (sizeof (struct opcode_hash_entry));
1426 opcode_array[i]->next = NULL;
1427 opcode_array[i]->name = xstrdup (name);
1428 opcode_array[i]->opcode = xstrdup (str);
bd5295b2 1429 opcode_array[i]->lineno = lineno;
c587b3f9
L
1430 *hash_slot = opcode_array[i];
1431 i++;
40b8e679 1432 }
c587b3f9 1433 else
40b8e679 1434 {
c587b3f9
L
1435 /* Append it to the existing one. */
1436 entry = hash_slot;
1437 while ((*entry) != NULL)
1438 entry = &(*entry)->next;
1439 *entry = (struct opcode_hash_entry *)
1440 xmalloc (sizeof (struct opcode_hash_entry));
1441 (*entry)->next = NULL;
1442 (*entry)->name = (*hash_slot)->name;
1443 (*entry)->opcode = xstrdup (str);
bd5295b2 1444 (*entry)->lineno = lineno;
c587b3f9
L
1445 }
1446 }
40b8e679 1447
c587b3f9
L
1448 /* Process opcode array. */
1449 for (j = 0; j < i; j++)
1450 {
1451 for (next = opcode_array[j]; next; next = next->next)
1452 {
1453 name = next->name;
1454 str = next->opcode;
bd5295b2 1455 lineno = next->lineno;
c587b3f9 1456 last = str + strlen (str);
bd5295b2 1457 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1458 }
40b8e679
L
1459 }
1460
34edb9ad
L
1461 fclose (fp);
1462
4dffcebc 1463 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1464
bd5295b2 1465 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
40fb9820 1466
4a1b91ea 1467 process_i386_opcode_modifier (table, "0", NULL, -1);
29c048b6 1468
40fb9820 1469 fprintf (table, " { ");
7ac20022 1470 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1471 fprintf (table, " } }\n");
1472
34edb9ad 1473 fprintf (table, "};\n");
40b8e679
L
1474}
1475
1476static void
72ffa0fb 1477process_i386_registers (FILE *table)
40b8e679 1478{
3d4d5afa 1479 FILE *fp;
40b8e679
L
1480 char buf[2048];
1481 char *str, *p, *last;
1482 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1483 char *dw2_32_num, *dw2_64_num;
bd5295b2 1484 int lineno = 0;
40b8e679 1485
3d4d5afa
L
1486 filename = "i386-reg.tbl";
1487 fp = fopen (filename, "r");
40b8e679 1488 if (fp == NULL)
34edb9ad 1489 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1490 xstrerror (errno));
40b8e679 1491
34edb9ad
L
1492 fprintf (table, "\n/* i386 register table. */\n\n");
1493 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1494
1495 while (!feof (fp))
1496 {
1497 if (fgets (buf, sizeof (buf), fp) == NULL)
1498 break;
1499
3d4d5afa
L
1500 lineno++;
1501
40b8e679
L
1502 p = remove_leading_whitespaces (buf);
1503
1504 /* Skip comments. */
1505 str = strstr (p, "//");
1506 if (str != NULL)
1507 str[0] = '\0';
1508
1509 /* Remove trailing white spaces. */
1510 remove_trailing_whitespaces (p);
1511
1512 switch (p[0])
1513 {
1514 case '#':
34edb9ad 1515 fprintf (table, "%s\n", p);
40b8e679
L
1516 case '\0':
1517 continue;
1518 break;
1519 default:
1520 break;
1521 }
1522
1523 last = p + strlen (p);
1524
1525 /* Find reg_name. */
c587b3f9 1526 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1527
1528 /* Find reg_type. */
c587b3f9 1529 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1530
1531 /* Find reg_flags. */
c587b3f9 1532 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1533
1534 /* Find reg_num. */
c587b3f9 1535 reg_num = next_field (str, ',', &str, last);
a60de03c 1536
40fb9820
L
1537 fprintf (table, " { \"%s\",\n ", reg_name);
1538
7ac20022
JB
1539 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1540 lineno);
40fb9820 1541
a60de03c 1542 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1543 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1544
1545 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1546 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1547
1548 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1549 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1550 }
1551
34edb9ad
L
1552 fclose (fp);
1553
1554 fprintf (table, "};\n");
40b8e679 1555
34edb9ad 1556 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1557}
1558
40fb9820
L
1559static void
1560process_i386_initializers (void)
1561{
1562 unsigned int i;
1563 FILE *fp = fopen ("i386-init.h", "w");
1564 char *init;
1565
1566 if (fp == NULL)
1567 fail (_("can't create i386-init.h, errno = %s\n"),
1568 xstrerror (errno));
1569
1570 process_copyright (fp);
1571
1572 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1573 {
1574 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1575 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1576 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1577 free (init);
1578 }
1579
1580 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1581 {
1582 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1583 init = xstrdup (operand_type_init[i].init);
7ac20022 1584 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1585 free (init);
1586 }
1587 fprintf (fp, "\n");
1588
1589 fclose (fp);
1590}
1591
40b8e679
L
1592/* Program options. */
1593#define OPTION_SRCDIR 200
1594
29c048b6 1595struct option long_options[] =
40b8e679
L
1596{
1597 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1598 {"debug", no_argument, NULL, 'd'},
1599 {"version", no_argument, NULL, 'V'},
1600 {"help", no_argument, NULL, 'h'},
1601 {0, no_argument, NULL, 0}
1602};
1603
1604static void
1605print_version (void)
1606{
1607 printf ("%s: version 1.0\n", program_name);
1608 xexit (0);
1609}
1610
1611static void
1612usage (FILE * stream, int status)
1613{
1614 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1615 program_name);
1616 xexit (status);
1617}
1618
1619int
1620main (int argc, char **argv)
1621{
1622 extern int chdir (char *);
1623 char *srcdir = NULL;
8b40d594 1624 int c;
e92bae62 1625 unsigned int i, cpumax;
72ffa0fb 1626 FILE *table;
29c048b6 1627
40b8e679
L
1628 program_name = *argv;
1629 xmalloc_set_program_name (program_name);
1630
1631 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1632 switch (c)
1633 {
1634 case OPTION_SRCDIR:
1635 srcdir = optarg;
1636 break;
1637 case 'V':
1638 case 'v':
1639 print_version ();
1640 break;
1641 case 'd':
1642 debug = 1;
1643 break;
1644 case 'h':
1645 case '?':
1646 usage (stderr, 0);
1647 default:
1648 case 0:
1649 break;
1650 }
1651
1652 if (optind != argc)
1653 usage (stdout, 1);
1654
29c048b6 1655 if (srcdir != NULL)
40b8e679
L
1656 if (chdir (srcdir) != 0)
1657 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1658 srcdir, xstrerror (errno));
1659
e92bae62
L
1660 /* cpu_flags isn't sorted by position. */
1661 cpumax = 0;
1662 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1663 if (cpu_flags[i].position > cpumax)
1664 cpumax = cpu_flags[i].position;
1665
40fb9820 1666 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 1667#ifdef CpuUnused
e92bae62
L
1668 if ((cpumax - 1) != CpuMax)
1669 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1670#else
e92bae62
L
1671 if (cpumax != CpuMax)
1672 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1673
8b40d594
L
1674 c = CpuNumOfBits - CpuMax - 1;
1675 if (c)
1676 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1677#endif
1678
1679 /* Check the unused bitfield in i386_operand_type. */
1680#ifndef OTUnused
8b40d594
L
1681 c = OTNumOfBits - OTMax - 1;
1682 if (c)
1683 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1684#endif
1685
1686 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1687 compare);
1688
1689 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1690 sizeof (opcode_modifiers [0]), compare);
1691
1692 qsort (operand_types, ARRAY_SIZE (operand_types),
1693 sizeof (operand_types [0]), compare);
40b8e679 1694
34edb9ad
L
1695 table = fopen ("i386-tbl.h", "w");
1696 if (table == NULL)
40fb9820
L
1697 fail (_("can't create i386-tbl.h, errno = %s\n"),
1698 xstrerror (errno));
34edb9ad 1699
72ffa0fb 1700 process_copyright (table);
40b8e679 1701
72ffa0fb
L
1702 process_i386_opcodes (table);
1703 process_i386_registers (table);
40fb9820 1704 process_i386_initializers ();
40b8e679 1705
34edb9ad
L
1706 fclose (table);
1707
40b8e679
L
1708 exit (0);
1709}