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