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