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