xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/i386-gen.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1 /* Copyright (C) 2007-2022 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 /* Build-time checks are preferrable over runtime ones.  Use this construct
34    in preference where possible.  */
35 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
36 
37 static const char *program_name = NULL;
38 static int debug = 0;
39 
40 typedef struct initializer
41 {
42   const char *name;
43   const char *init;
44 } initializer;
45 
46 static initializer cpu_flag_init[] =
47 {
48   { "CPU_UNKNOWN_FLAGS",
49     "~CpuIAMCU" },
50   { "CPU_GENERIC32_FLAGS",
51     "Cpu186|Cpu286|Cpu386" },
52   { "CPU_GENERIC64_FLAGS",
53     "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
54   { "CPU_NONE_FLAGS",
55    "0" },
56   { "CPU_I186_FLAGS",
57     "Cpu186" },
58   { "CPU_I286_FLAGS",
59     "CPU_I186_FLAGS|Cpu286" },
60   { "CPU_I386_FLAGS",
61     "CPU_I286_FLAGS|Cpu386" },
62   { "CPU_I486_FLAGS",
63     "CPU_I386_FLAGS|Cpu486" },
64   { "CPU_I586_FLAGS",
65     "CPU_I486_FLAGS|Cpu387|Cpu586" },
66   { "CPU_I686_FLAGS",
67     "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
68   { "CPU_PENTIUMPRO_FLAGS",
69     "CPU_I686_FLAGS|CpuNop" },
70   { "CPU_P2_FLAGS",
71     "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
72   { "CPU_P3_FLAGS",
73     "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
74   { "CPU_P4_FLAGS",
75     "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
76   { "CPU_NOCONA_FLAGS",
77     "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
78   { "CPU_CORE_FLAGS",
79     "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
80   { "CPU_CORE2_FLAGS",
81     "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
82   { "CPU_COREI7_FLAGS",
83     "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
84   { "CPU_K6_FLAGS",
85     "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
86   { "CPU_K6_2_FLAGS",
87     "CPU_K6_FLAGS|Cpu3dnow" },
88   { "CPU_ATHLON_FLAGS",
89     "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
90   { "CPU_K8_FLAGS",
91     "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
92   { "CPU_AMDFAM10_FLAGS",
93     "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuLZCNT|CpuPOPCNT" },
94   { "CPU_BDVER1_FLAGS",
95     "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuLZCNT|CpuPOPCNT|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW" },
96   { "CPU_BDVER2_FLAGS",
97     "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
98   { "CPU_BDVER3_FLAGS",
99     "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
100   { "CPU_BDVER4_FLAGS",
101     "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
102   { "CPU_ZNVER1_FLAGS",
103     "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
104   { "CPU_ZNVER2_FLAGS",
105     "CPU_ZNVER1_FLAGS|CpuCLWB|CpuRDPID|CpuRDPRU|CpuMCOMMIT|CpuWBNOINVD" },
106   { "CPU_ZNVER3_FLAGS",
107     "CPU_ZNVER2_FLAGS|CpuINVLPGB|CpuTLBSYNC|CpuVAES|CpuVPCLMULQDQ|CpuINVPCID|CpuSNP|CpuOSPKE" },
108   { "CPU_BTVER1_FLAGS",
109     "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
110   { "CPU_BTVER2_FLAGS",
111     "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
112   { "CPU_8087_FLAGS",
113     "Cpu8087" },
114   { "CPU_287_FLAGS",
115     "Cpu287" },
116   { "CPU_387_FLAGS",
117     "Cpu387" },
118   { "CPU_687_FLAGS",
119     "CPU_387_FLAGS|Cpu687" },
120   { "CPU_CMOV_FLAGS",
121     "CpuCMOV" },
122   { "CPU_FXSR_FLAGS",
123     "CpuFXSR" },
124   { "CPU_CLFLUSH_FLAGS",
125     "CpuClflush" },
126   { "CPU_NOP_FLAGS",
127     "CpuNop" },
128   { "CPU_SYSCALL_FLAGS",
129     "CpuSYSCALL" },
130   { "CPU_MMX_FLAGS",
131     "CpuMMX" },
132   { "CPU_SSE_FLAGS",
133     "CpuSSE" },
134   { "CPU_SSE2_FLAGS",
135     "CPU_SSE_FLAGS|CpuSSE2" },
136   { "CPU_SSE3_FLAGS",
137     "CPU_SSE2_FLAGS|CpuSSE3" },
138   { "CPU_SSSE3_FLAGS",
139     "CPU_SSE3_FLAGS|CpuSSSE3" },
140   { "CPU_SSE4_1_FLAGS",
141     "CPU_SSSE3_FLAGS|CpuSSE4_1" },
142   { "CPU_SSE4_2_FLAGS",
143     "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
144   { "CPU_VMX_FLAGS",
145     "CpuVMX" },
146   { "CPU_SMX_FLAGS",
147     "CpuSMX" },
148   { "CPU_XSAVE_FLAGS",
149     "CpuXsave" },
150   { "CPU_XSAVEOPT_FLAGS",
151     "CPU_XSAVE_FLAGS|CpuXsaveopt" },
152   { "CPU_AES_FLAGS",
153     "CPU_SSE2_FLAGS|CpuAES" },
154   { "CPU_PCLMUL_FLAGS",
155     "CPU_SSE2_FLAGS|CpuPCLMUL" },
156   { "CPU_FMA_FLAGS",
157     "CPU_AVX_FLAGS|CpuFMA" },
158   { "CPU_FMA4_FLAGS",
159     "CPU_AVX_FLAGS|CpuFMA4" },
160   { "CPU_XOP_FLAGS",
161     "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
162   { "CPU_LWP_FLAGS",
163     "CPU_XSAVE_FLAGS|CpuLWP" },
164   { "CPU_BMI_FLAGS",
165     "CpuBMI" },
166   { "CPU_TBM_FLAGS",
167     "CpuTBM" },
168   { "CPU_MOVBE_FLAGS",
169     "CpuMovbe" },
170   { "CPU_CX16_FLAGS",
171     "CpuCX16" },
172   { "CPU_RDTSCP_FLAGS",
173     "CpuRdtscp" },
174   { "CPU_EPT_FLAGS",
175     "CpuEPT" },
176   { "CPU_FSGSBASE_FLAGS",
177     "CpuFSGSBase" },
178   { "CPU_RDRND_FLAGS",
179     "CpuRdRnd" },
180   { "CPU_F16C_FLAGS",
181     "CPU_AVX_FLAGS|CpuF16C" },
182   { "CPU_BMI2_FLAGS",
183     "CpuBMI2" },
184   { "CPU_LZCNT_FLAGS",
185     "CpuLZCNT" },
186   { "CPU_POPCNT_FLAGS",
187     "CpuPOPCNT" },
188   { "CPU_HLE_FLAGS",
189     "CpuHLE" },
190   { "CPU_RTM_FLAGS",
191     "CpuRTM" },
192   { "CPU_INVPCID_FLAGS",
193     "CpuINVPCID" },
194   { "CPU_VMFUNC_FLAGS",
195     "CpuVMFUNC" },
196   { "CPU_3DNOW_FLAGS",
197     "CPU_MMX_FLAGS|Cpu3dnow" },
198   { "CPU_3DNOWA_FLAGS",
199     "CPU_3DNOW_FLAGS|Cpu3dnowA" },
200   { "CPU_PADLOCK_FLAGS",
201     "CpuPadLock" },
202   { "CPU_SVME_FLAGS",
203     "CpuSVME" },
204   { "CPU_SSE4A_FLAGS",
205     "CPU_SSE3_FLAGS|CpuSSE4a" },
206   { "CPU_ABM_FLAGS",
207     "CpuLZCNT|CpuPOPCNT" },
208   { "CPU_AVX_FLAGS",
209     "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
210   { "CPU_AVX2_FLAGS",
211     "CPU_AVX_FLAGS|CpuAVX2" },
212   { "CPU_AVX_VNNI_FLAGS",
213     "CPU_AVX2_FLAGS|CpuAVX_VNNI" },
214   { "CPU_AVX512F_FLAGS",
215     "CPU_AVX2_FLAGS|CpuAVX512F" },
216   { "CPU_AVX512CD_FLAGS",
217     "CPU_AVX512F_FLAGS|CpuAVX512CD" },
218   { "CPU_AVX512ER_FLAGS",
219     "CPU_AVX512F_FLAGS|CpuAVX512ER" },
220   { "CPU_AVX512PF_FLAGS",
221     "CPU_AVX512F_FLAGS|CpuAVX512PF" },
222   { "CPU_AVX512DQ_FLAGS",
223     "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
224   { "CPU_AVX512BW_FLAGS",
225     "CPU_AVX512F_FLAGS|CpuAVX512BW" },
226   { "CPU_AVX512VL_FLAGS",
227     "CPU_AVX512F_FLAGS|CpuAVX512VL" },
228   { "CPU_AVX512IFMA_FLAGS",
229     "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
230   { "CPU_AVX512VBMI_FLAGS",
231     "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
232   { "CPU_AVX512_4FMAPS_FLAGS",
233     "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
234   { "CPU_AVX512_4VNNIW_FLAGS",
235     "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
236   { "CPU_AVX512_VPOPCNTDQ_FLAGS",
237     "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
238   { "CPU_AVX512_VBMI2_FLAGS",
239     "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
240   { "CPU_AVX512_VNNI_FLAGS",
241     "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
242   { "CPU_AVX512_BITALG_FLAGS",
243     "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
244   { "CPU_AVX512_BF16_FLAGS",
245     "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
246   { "CPU_AVX512_FP16_FLAGS",
247     "CPU_AVX512BW_FLAGS|CpuAVX512_FP16" },
248   { "CPU_IAMCU_FLAGS",
249     "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuIAMCU" },
250   { "CPU_ADX_FLAGS",
251     "CpuADX" },
252   { "CPU_RDSEED_FLAGS",
253     "CpuRdSeed" },
254   { "CPU_PRFCHW_FLAGS",
255     "CpuPRFCHW" },
256   { "CPU_SMAP_FLAGS",
257     "CpuSMAP" },
258   { "CPU_MPX_FLAGS",
259     "CPU_XSAVE_FLAGS|CpuMPX" },
260   { "CPU_SHA_FLAGS",
261     "CPU_SSE2_FLAGS|CpuSHA" },
262   { "CPU_CLFLUSHOPT_FLAGS",
263     "CpuClflushOpt" },
264   { "CPU_XSAVES_FLAGS",
265     "CPU_XSAVE_FLAGS|CpuXSAVES" },
266   { "CPU_XSAVEC_FLAGS",
267     "CPU_XSAVE_FLAGS|CpuXSAVEC" },
268   { "CPU_PREFETCHWT1_FLAGS",
269     "CpuPREFETCHWT1" },
270   { "CPU_SE1_FLAGS",
271     "CpuSE1" },
272   { "CPU_CLWB_FLAGS",
273     "CpuCLWB" },
274   { "CPU_CLZERO_FLAGS",
275     "CpuCLZERO" },
276   { "CPU_MWAITX_FLAGS",
277     "CpuMWAITX" },
278   { "CPU_OSPKE_FLAGS",
279     "CPU_XSAVE_FLAGS|CpuOSPKE" },
280   { "CPU_RDPID_FLAGS",
281     "CpuRDPID" },
282   { "CPU_PTWRITE_FLAGS",
283     "CpuPTWRITE" },
284   { "CPU_IBT_FLAGS",
285     "CpuIBT" },
286   { "CPU_SHSTK_FLAGS",
287     "CpuSHSTK" },
288   { "CPU_GFNI_FLAGS",
289     "CpuGFNI" },
290   { "CPU_VAES_FLAGS",
291     "CpuVAES" },
292   { "CPU_VPCLMULQDQ_FLAGS",
293     "CpuVPCLMULQDQ" },
294   { "CPU_WBNOINVD_FLAGS",
295     "CpuWBNOINVD" },
296   { "CPU_PCONFIG_FLAGS",
297     "CpuPCONFIG" },
298   { "CPU_WAITPKG_FLAGS",
299     "CpuWAITPKG" },
300   { "CPU_UINTR_FLAGS",
301     "CpuUINTR" },
302   { "CPU_CLDEMOTE_FLAGS",
303     "CpuCLDEMOTE" },
304   { "CPU_AMX_INT8_FLAGS",
305     "CpuAMX_INT8" },
306   { "CPU_AMX_BF16_FLAGS",
307     "CpuAMX_BF16" },
308   { "CPU_AMX_TILE_FLAGS",
309     "CpuAMX_TILE" },
310   { "CPU_MOVDIRI_FLAGS",
311     "CpuMOVDIRI" },
312   { "CPU_MOVDIR64B_FLAGS",
313     "CpuMOVDIR64B" },
314   { "CPU_ENQCMD_FLAGS",
315     "CpuENQCMD" },
316   { "CPU_SERIALIZE_FLAGS",
317     "CpuSERIALIZE" },
318   { "CPU_AVX512_VP2INTERSECT_FLAGS",
319     "CpuAVX512_VP2INTERSECT" },
320   { "CPU_TDX_FLAGS",
321     "CpuTDX" },
322   { "CPU_RDPRU_FLAGS",
323     "CpuRDPRU" },
324   { "CPU_MCOMMIT_FLAGS",
325     "CpuMCOMMIT" },
326   { "CPU_SEV_ES_FLAGS",
327     "CpuSEV_ES" },
328   { "CPU_TSXLDTRK_FLAGS",
329     "CpuTSXLDTRK"},
330   { "CPU_KL_FLAGS",
331     "CpuKL" },
332   { "CPU_WIDEKL_FLAGS",
333     "CpuWideKL" },
334   { "CPU_HRESET_FLAGS",
335     "CpuHRESET"},
336   { "CPU_INVLPGB_FLAGS",
337     "CpuINVLPGB" },
338   { "CPU_TLBSYNC_FLAGS",
339     "CpuTLBSYNC" },
340   { "CPU_SNP_FLAGS",
341     "CpuSNP" },
342   { "CPU_ANY_X87_FLAGS",
343     "CPU_ANY_287_FLAGS|Cpu8087" },
344   { "CPU_ANY_287_FLAGS",
345     "CPU_ANY_387_FLAGS|Cpu287" },
346   { "CPU_ANY_387_FLAGS",
347     "CPU_ANY_687_FLAGS|Cpu387" },
348   { "CPU_ANY_687_FLAGS",
349     "Cpu687|CpuFISTTP" },
350   { "CPU_ANY_CMOV_FLAGS",
351     "CpuCMOV" },
352   { "CPU_ANY_FXSR_FLAGS",
353     "CpuFXSR" },
354   { "CPU_ANY_MMX_FLAGS",
355     "CPU_3DNOWA_FLAGS" },
356   { "CPU_ANY_SSE_FLAGS",
357     "CPU_ANY_SSE2_FLAGS|CpuSSE" },
358   { "CPU_ANY_SSE2_FLAGS",
359     "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
360   { "CPU_ANY_SSE3_FLAGS",
361     "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
362   { "CPU_ANY_SSSE3_FLAGS",
363     "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
364   { "CPU_ANY_SSE4_1_FLAGS",
365     "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
366   { "CPU_ANY_SSE4_2_FLAGS",
367     "CpuSSE4_2" },
368   { "CPU_ANY_SSE4A_FLAGS",
369     "CpuSSE4a" },
370   { "CPU_ANY_AVX_FLAGS",
371     "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
372   { "CPU_ANY_AVX2_FLAGS",
373     "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
374   { "CPU_ANY_AVX512F_FLAGS",
375     "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CPU_ANY_AVX512BW_FLAGS|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
376   { "CPU_ANY_AVX512CD_FLAGS",
377     "CpuAVX512CD" },
378   { "CPU_ANY_AVX512ER_FLAGS",
379     "CpuAVX512ER" },
380   { "CPU_ANY_AVX512PF_FLAGS",
381     "CpuAVX512PF" },
382   { "CPU_ANY_AVX512DQ_FLAGS",
383     "CpuAVX512DQ" },
384   { "CPU_ANY_AVX512BW_FLAGS",
385     "CpuAVX512BW|CPU_ANY_AVX512_FP16_FLAGS" },
386   { "CPU_ANY_AVX512VL_FLAGS",
387     "CpuAVX512VL" },
388   { "CPU_ANY_AVX512IFMA_FLAGS",
389     "CpuAVX512IFMA" },
390   { "CPU_ANY_AVX512VBMI_FLAGS",
391     "CpuAVX512VBMI" },
392   { "CPU_ANY_AVX512_4FMAPS_FLAGS",
393     "CpuAVX512_4FMAPS" },
394   { "CPU_ANY_AVX512_4VNNIW_FLAGS",
395     "CpuAVX512_4VNNIW" },
396   { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
397     "CpuAVX512_VPOPCNTDQ" },
398   { "CPU_ANY_IBT_FLAGS",
399     "CpuIBT" },
400   { "CPU_ANY_SHSTK_FLAGS",
401     "CpuSHSTK" },
402   { "CPU_ANY_AVX512_VBMI2_FLAGS",
403     "CpuAVX512_VBMI2" },
404   { "CPU_ANY_AVX512_VNNI_FLAGS",
405     "CpuAVX512_VNNI" },
406   { "CPU_ANY_AVX512_BITALG_FLAGS",
407     "CpuAVX512_BITALG" },
408   { "CPU_ANY_AVX512_BF16_FLAGS",
409     "CpuAVX512_BF16" },
410   { "CPU_ANY_AMX_INT8_FLAGS",
411     "CpuAMX_INT8" },
412   { "CPU_ANY_AMX_BF16_FLAGS",
413     "CpuAMX_BF16" },
414   { "CPU_ANY_AMX_TILE_FLAGS",
415     "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" },
416   { "CPU_ANY_AVX_VNNI_FLAGS",
417     "CpuAVX_VNNI" },
418   { "CPU_ANY_MOVDIRI_FLAGS",
419     "CpuMOVDIRI" },
420   { "CPU_ANY_UINTR_FLAGS",
421     "CpuUINTR" },
422   { "CPU_ANY_MOVDIR64B_FLAGS",
423     "CpuMOVDIR64B" },
424   { "CPU_ANY_ENQCMD_FLAGS",
425     "CpuENQCMD" },
426   { "CPU_ANY_SERIALIZE_FLAGS",
427     "CpuSERIALIZE" },
428   { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
429     "CpuAVX512_VP2INTERSECT" },
430   { "CPU_ANY_TDX_FLAGS",
431     "CpuTDX" },
432   { "CPU_ANY_TSXLDTRK_FLAGS",
433     "CpuTSXLDTRK" },
434   { "CPU_ANY_KL_FLAGS",
435     "CpuKL|CpuWideKL" },
436   { "CPU_ANY_WIDEKL_FLAGS",
437     "CpuWideKL" },
438   { "CPU_ANY_HRESET_FLAGS",
439     "CpuHRESET" },
440   { "CPU_ANY_AVX512_FP16_FLAGS",
441     "CpuAVX512_FP16" },
442 };
443 
444 static initializer operand_type_init[] =
445 {
446   { "OPERAND_TYPE_NONE",
447     "0" },
448   { "OPERAND_TYPE_REG8",
449     "Class=Reg|Byte" },
450   { "OPERAND_TYPE_REG16",
451     "Class=Reg|Word" },
452   { "OPERAND_TYPE_REG32",
453     "Class=Reg|Dword" },
454   { "OPERAND_TYPE_REG64",
455     "Class=Reg|Qword" },
456   { "OPERAND_TYPE_IMM1",
457     "Imm1" },
458   { "OPERAND_TYPE_IMM8",
459     "Imm8" },
460   { "OPERAND_TYPE_IMM8S",
461     "Imm8S" },
462   { "OPERAND_TYPE_IMM16",
463     "Imm16" },
464   { "OPERAND_TYPE_IMM32",
465     "Imm32" },
466   { "OPERAND_TYPE_IMM32S",
467     "Imm32S" },
468   { "OPERAND_TYPE_IMM64",
469     "Imm64" },
470   { "OPERAND_TYPE_BASEINDEX",
471     "BaseIndex" },
472   { "OPERAND_TYPE_DISP8",
473     "Disp8" },
474   { "OPERAND_TYPE_DISP16",
475     "Disp16" },
476   { "OPERAND_TYPE_DISP32",
477     "Disp32" },
478   { "OPERAND_TYPE_DISP64",
479     "Disp64" },
480   { "OPERAND_TYPE_INOUTPORTREG",
481     "Instance=RegD|Word" },
482   { "OPERAND_TYPE_SHIFTCOUNT",
483     "Instance=RegC|Byte" },
484   { "OPERAND_TYPE_CONTROL",
485     "Class=RegCR" },
486   { "OPERAND_TYPE_TEST",
487     "Class=RegTR" },
488   { "OPERAND_TYPE_DEBUG",
489     "Class=RegDR" },
490   { "OPERAND_TYPE_FLOATREG",
491     "Class=Reg|Tbyte" },
492   { "OPERAND_TYPE_FLOATACC",
493     "Instance=Accum|Tbyte" },
494   { "OPERAND_TYPE_SREG",
495     "Class=SReg" },
496   { "OPERAND_TYPE_REGMMX",
497     "Class=RegMMX" },
498   { "OPERAND_TYPE_REGXMM",
499     "Class=RegSIMD|Xmmword" },
500   { "OPERAND_TYPE_REGYMM",
501     "Class=RegSIMD|Ymmword" },
502   { "OPERAND_TYPE_REGZMM",
503     "Class=RegSIMD|Zmmword" },
504   { "OPERAND_TYPE_REGTMM",
505     "Class=RegSIMD|Tmmword" },
506   { "OPERAND_TYPE_REGMASK",
507     "Class=RegMask" },
508   { "OPERAND_TYPE_REGBND",
509     "Class=RegBND" },
510   { "OPERAND_TYPE_ACC8",
511     "Instance=Accum|Byte" },
512   { "OPERAND_TYPE_ACC16",
513     "Instance=Accum|Word" },
514   { "OPERAND_TYPE_ACC32",
515     "Instance=Accum|Dword" },
516   { "OPERAND_TYPE_ACC64",
517     "Instance=Accum|Qword" },
518   { "OPERAND_TYPE_DISP16_32",
519     "Disp16|Disp32" },
520   { "OPERAND_TYPE_ANYDISP",
521     "Disp8|Disp16|Disp32|Disp64" },
522   { "OPERAND_TYPE_IMM16_32",
523     "Imm16|Imm32" },
524   { "OPERAND_TYPE_IMM16_32S",
525     "Imm16|Imm32S" },
526   { "OPERAND_TYPE_IMM16_32_32S",
527     "Imm16|Imm32|Imm32S" },
528   { "OPERAND_TYPE_IMM32_64",
529     "Imm32|Imm64" },
530   { "OPERAND_TYPE_IMM32_32S_DISP32",
531     "Imm32|Imm32S|Disp32" },
532   { "OPERAND_TYPE_IMM64_DISP64",
533     "Imm64|Disp64" },
534   { "OPERAND_TYPE_IMM32_32S_64_DISP32",
535     "Imm32|Imm32S|Imm64|Disp32" },
536   { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
537     "Imm32|Imm32S|Imm64|Disp32|Disp64" },
538   { "OPERAND_TYPE_ANYIMM",
539     "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
540 };
541 
542 typedef struct bitfield
543 {
544   int position;
545   int value;
546   const char *name;
547 } bitfield;
548 
549 #define BITFIELD(n) { n, 0, #n }
550 
551 static bitfield cpu_flags[] =
552 {
553   BITFIELD (Cpu186),
554   BITFIELD (Cpu286),
555   BITFIELD (Cpu386),
556   BITFIELD (Cpu486),
557   BITFIELD (Cpu586),
558   BITFIELD (Cpu686),
559   BITFIELD (CpuCMOV),
560   BITFIELD (CpuFXSR),
561   BITFIELD (CpuClflush),
562   BITFIELD (CpuNop),
563   BITFIELD (CpuSYSCALL),
564   BITFIELD (Cpu8087),
565   BITFIELD (Cpu287),
566   BITFIELD (Cpu387),
567   BITFIELD (Cpu687),
568   BITFIELD (CpuFISTTP),
569   BITFIELD (CpuMMX),
570   BITFIELD (CpuSSE),
571   BITFIELD (CpuSSE2),
572   BITFIELD (CpuSSE3),
573   BITFIELD (CpuSSSE3),
574   BITFIELD (CpuSSE4_1),
575   BITFIELD (CpuSSE4_2),
576   BITFIELD (CpuAVX),
577   BITFIELD (CpuAVX2),
578   BITFIELD (CpuAVX512F),
579   BITFIELD (CpuAVX512CD),
580   BITFIELD (CpuAVX512ER),
581   BITFIELD (CpuAVX512PF),
582   BITFIELD (CpuAVX512VL),
583   BITFIELD (CpuAVX512DQ),
584   BITFIELD (CpuAVX512BW),
585   BITFIELD (CpuIAMCU),
586   BITFIELD (CpuSSE4a),
587   BITFIELD (Cpu3dnow),
588   BITFIELD (Cpu3dnowA),
589   BITFIELD (CpuPadLock),
590   BITFIELD (CpuSVME),
591   BITFIELD (CpuVMX),
592   BITFIELD (CpuSMX),
593   BITFIELD (CpuXsave),
594   BITFIELD (CpuXsaveopt),
595   BITFIELD (CpuAES),
596   BITFIELD (CpuPCLMUL),
597   BITFIELD (CpuFMA),
598   BITFIELD (CpuFMA4),
599   BITFIELD (CpuXOP),
600   BITFIELD (CpuLWP),
601   BITFIELD (CpuBMI),
602   BITFIELD (CpuTBM),
603   BITFIELD (CpuLM),
604   BITFIELD (CpuMovbe),
605   BITFIELD (CpuCX16),
606   BITFIELD (CpuEPT),
607   BITFIELD (CpuRdtscp),
608   BITFIELD (CpuFSGSBase),
609   BITFIELD (CpuRdRnd),
610   BITFIELD (CpuF16C),
611   BITFIELD (CpuBMI2),
612   BITFIELD (CpuLZCNT),
613   BITFIELD (CpuPOPCNT),
614   BITFIELD (CpuHLE),
615   BITFIELD (CpuRTM),
616   BITFIELD (CpuINVPCID),
617   BITFIELD (CpuVMFUNC),
618   BITFIELD (CpuRDSEED),
619   BITFIELD (CpuADX),
620   BITFIELD (CpuPRFCHW),
621   BITFIELD (CpuSMAP),
622   BITFIELD (CpuSHA),
623   BITFIELD (CpuClflushOpt),
624   BITFIELD (CpuXSAVES),
625   BITFIELD (CpuXSAVEC),
626   BITFIELD (CpuPREFETCHWT1),
627   BITFIELD (CpuSE1),
628   BITFIELD (CpuCLWB),
629   BITFIELD (CpuMPX),
630   BITFIELD (CpuAVX512IFMA),
631   BITFIELD (CpuAVX512VBMI),
632   BITFIELD (CpuAVX512_4FMAPS),
633   BITFIELD (CpuAVX512_4VNNIW),
634   BITFIELD (CpuAVX512_VPOPCNTDQ),
635   BITFIELD (CpuAVX512_VBMI2),
636   BITFIELD (CpuAVX512_VNNI),
637   BITFIELD (CpuAVX512_BITALG),
638   BITFIELD (CpuAVX512_BF16),
639   BITFIELD (CpuAVX512_VP2INTERSECT),
640   BITFIELD (CpuTDX),
641   BITFIELD (CpuAVX_VNNI),
642   BITFIELD (CpuAVX512_FP16),
643   BITFIELD (CpuMWAITX),
644   BITFIELD (CpuCLZERO),
645   BITFIELD (CpuOSPKE),
646   BITFIELD (CpuRDPID),
647   BITFIELD (CpuPTWRITE),
648   BITFIELD (CpuIBT),
649   BITFIELD (CpuSHSTK),
650   BITFIELD (CpuGFNI),
651   BITFIELD (CpuVAES),
652   BITFIELD (CpuVPCLMULQDQ),
653   BITFIELD (CpuWBNOINVD),
654   BITFIELD (CpuPCONFIG),
655   BITFIELD (CpuWAITPKG),
656   BITFIELD (CpuUINTR),
657   BITFIELD (CpuCLDEMOTE),
658   BITFIELD (CpuAMX_INT8),
659   BITFIELD (CpuAMX_BF16),
660   BITFIELD (CpuAMX_TILE),
661   BITFIELD (CpuMOVDIRI),
662   BITFIELD (CpuMOVDIR64B),
663   BITFIELD (CpuENQCMD),
664   BITFIELD (CpuSERIALIZE),
665   BITFIELD (CpuRDPRU),
666   BITFIELD (CpuMCOMMIT),
667   BITFIELD (CpuSEV_ES),
668   BITFIELD (CpuTSXLDTRK),
669   BITFIELD (CpuKL),
670   BITFIELD (CpuWideKL),
671   BITFIELD (CpuHRESET),
672   BITFIELD (CpuINVLPGB),
673   BITFIELD (CpuTLBSYNC),
674   BITFIELD (CpuSNP),
675   BITFIELD (Cpu64),
676   BITFIELD (CpuNo64),
677 #ifdef CpuUnused
678   BITFIELD (CpuUnused),
679 #endif
680 };
681 
682 static bitfield opcode_modifiers[] =
683 {
684   BITFIELD (D),
685   BITFIELD (W),
686   BITFIELD (Load),
687   BITFIELD (Modrm),
688   BITFIELD (Jump),
689   BITFIELD (FloatMF),
690   BITFIELD (FloatR),
691   BITFIELD (Size),
692   BITFIELD (CheckRegSize),
693   BITFIELD (DistinctDest),
694   BITFIELD (MnemonicSize),
695   BITFIELD (Anysize),
696   BITFIELD (No_bSuf),
697   BITFIELD (No_wSuf),
698   BITFIELD (No_lSuf),
699   BITFIELD (No_sSuf),
700   BITFIELD (No_qSuf),
701   BITFIELD (No_ldSuf),
702   BITFIELD (FWait),
703   BITFIELD (IsString),
704   BITFIELD (RegMem),
705   BITFIELD (BNDPrefixOk),
706   BITFIELD (RegKludge),
707   BITFIELD (Implicit1stXmm0),
708   BITFIELD (PrefixOk),
709   BITFIELD (ToDword),
710   BITFIELD (ToQword),
711   BITFIELD (AddrPrefixOpReg),
712   BITFIELD (IsPrefix),
713   BITFIELD (ImmExt),
714   BITFIELD (NoRex64),
715   BITFIELD (Ugh),
716   BITFIELD (PseudoVexPrefix),
717   BITFIELD (Vex),
718   BITFIELD (VexVVVV),
719   BITFIELD (VexW),
720   BITFIELD (OpcodeSpace),
721   BITFIELD (OpcodePrefix),
722   BITFIELD (VexSources),
723   BITFIELD (SIB),
724   BITFIELD (SSE2AVX),
725   BITFIELD (EVex),
726   BITFIELD (Masking),
727   BITFIELD (Broadcast),
728   BITFIELD (StaticRounding),
729   BITFIELD (SAE),
730   BITFIELD (Disp8MemShift),
731   BITFIELD (NoDefMask),
732   BITFIELD (ImplicitQuadGroup),
733   BITFIELD (SwapSources),
734   BITFIELD (Optimize),
735   BITFIELD (ATTMnemonic),
736   BITFIELD (ATTSyntax),
737   BITFIELD (IntelSyntax),
738   BITFIELD (ISA64),
739 };
740 
741 #define CLASS(n) #n, n
742 
743 static const struct {
744   const char *name;
745   enum operand_class value;
746 } operand_classes[] = {
747   CLASS (Reg),
748   CLASS (SReg),
749   CLASS (RegCR),
750   CLASS (RegDR),
751   CLASS (RegTR),
752   CLASS (RegMMX),
753   CLASS (RegSIMD),
754   CLASS (RegMask),
755   CLASS (RegBND),
756 };
757 
758 #undef CLASS
759 
760 #define INSTANCE(n) #n, n
761 
762 static const struct {
763   const char *name;
764   enum operand_instance value;
765 } operand_instances[] = {
766     INSTANCE (Accum),
767     INSTANCE (RegC),
768     INSTANCE (RegD),
769     INSTANCE (RegB),
770 };
771 
772 #undef INSTANCE
773 
774 static bitfield operand_types[] =
775 {
776   BITFIELD (Imm1),
777   BITFIELD (Imm8),
778   BITFIELD (Imm8S),
779   BITFIELD (Imm16),
780   BITFIELD (Imm32),
781   BITFIELD (Imm32S),
782   BITFIELD (Imm64),
783   BITFIELD (BaseIndex),
784   BITFIELD (Disp8),
785   BITFIELD (Disp16),
786   BITFIELD (Disp32),
787   BITFIELD (Disp64),
788   BITFIELD (Byte),
789   BITFIELD (Word),
790   BITFIELD (Dword),
791   BITFIELD (Fword),
792   BITFIELD (Qword),
793   BITFIELD (Tbyte),
794   BITFIELD (Xmmword),
795   BITFIELD (Ymmword),
796   BITFIELD (Zmmword),
797   BITFIELD (Tmmword),
798   BITFIELD (Unspecified),
799 #ifdef OTUnused
800   BITFIELD (OTUnused),
801 #endif
802 };
803 
804 static const char *filename;
805 static i386_cpu_flags active_cpu_flags;
806 static int active_isstring;
807 
808 struct template_arg {
809   const struct template_arg *next;
810   const char *val;
811 };
812 
813 struct template_instance {
814   const struct template_instance *next;
815   const char *name;
816   const struct template_arg *args;
817 };
818 
819 struct template_param {
820   const struct template_param *next;
821   const char *name;
822 };
823 
824 struct template {
825   const struct template *next;
826   const char *name;
827   const struct template_instance *instances;
828   const struct template_param *params;
829 };
830 
831 static const struct template *templates;
832 
833 static int
compare(const void * x,const void * y)834 compare (const void *x, const void *y)
835 {
836   const bitfield *xp = (const bitfield *) x;
837   const bitfield *yp = (const bitfield *) y;
838   return xp->position - yp->position;
839 }
840 
841 static void
fail(const char * message,...)842 fail (const char *message, ...)
843 {
844   va_list args;
845 
846   va_start (args, message);
847   fprintf (stderr, _("%s: error: "), program_name);
848   vfprintf (stderr, message, args);
849   va_end (args);
850   xexit (1);
851 }
852 
853 static void
process_copyright(FILE * fp)854 process_copyright (FILE *fp)
855 {
856   fprintf (fp, "/* This file is automatically generated by i386-gen.  Do not edit!  */\n\
857 /* Copyright (C) 2007-2022 Free Software Foundation, Inc.\n\
858 \n\
859    This file is part of the GNU opcodes library.\n\
860 \n\
861    This library is free software; you can redistribute it and/or modify\n\
862    it under the terms of the GNU General Public License as published by\n\
863    the Free Software Foundation; either version 3, or (at your option)\n\
864    any later version.\n\
865 \n\
866    It is distributed in the hope that it will be useful, but WITHOUT\n\
867    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
868    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
869    License for more details.\n\
870 \n\
871    You should have received a copy of the GNU General Public License\n\
872    along with this program; if not, write to the Free Software\n\
873    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
874    MA 02110-1301, USA.  */\n");
875 }
876 
877 /* Remove leading white spaces.  */
878 
879 static char *
remove_leading_whitespaces(char * str)880 remove_leading_whitespaces (char *str)
881 {
882   while (ISSPACE (*str))
883     str++;
884   return str;
885 }
886 
887 /* Remove trailing white spaces.  */
888 
889 static void
remove_trailing_whitespaces(char * str)890 remove_trailing_whitespaces (char *str)
891 {
892   size_t last = strlen (str);
893 
894   if (last == 0)
895     return;
896 
897   do
898     {
899       last--;
900       if (ISSPACE (str [last]))
901 	str[last] = '\0';
902       else
903 	break;
904     }
905   while (last != 0);
906 }
907 
908 /* Find next field separated by SEP and terminate it. Return a
909    pointer to the one after it.  */
910 
911 static char *
next_field(char * str,char sep,char ** next,char * last)912 next_field (char *str, char sep, char **next, char *last)
913 {
914   char *p;
915 
916   p = remove_leading_whitespaces (str);
917   for (str = p; *str != sep && *str != '\0'; str++);
918 
919   *str = '\0';
920   remove_trailing_whitespaces (p);
921 
922   *next = str + 1;
923 
924   if (p >= last)
925     abort ();
926 
927   return p;
928 }
929 
930 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
931 
932 static int
set_bitfield_from_cpu_flag_init(char * f,bitfield * array,unsigned int size,int lineno)933 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
934 				 int lineno)
935 {
936   char *str, *next, *last;
937   unsigned int i;
938 
939   for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
940     if (strcmp (cpu_flag_init[i].name, f) == 0)
941       {
942 	/* Turn on selective bits.  */
943 	char *init = xstrdup (cpu_flag_init[i].init);
944 	last = init + strlen (init);
945 	for (next = init; next && next < last; )
946 	  {
947 	    str = next_field (next, '|', &next, last);
948 	    if (str)
949 	      set_bitfield (str, array, 1, size, lineno);
950 	  }
951 	free (init);
952 	return 0;
953       }
954 
955   return -1;
956 }
957 
958 static void
set_bitfield(char * f,bitfield * array,int value,unsigned int size,int lineno)959 set_bitfield (char *f, bitfield *array, int value,
960 	      unsigned int size, int lineno)
961 {
962   unsigned int i;
963 
964   /* Ignore empty fields; they may result from template expansions.  */
965   if (*f == '\0')
966     return;
967 
968   for (i = 0; i < size; i++)
969     if (strcasecmp (array[i].name, f) == 0)
970       {
971 	array[i].value = value;
972 	return;
973       }
974 
975   if (value)
976     {
977       const char *v = strchr (f, '=');
978 
979       if (v)
980 	{
981 	  size_t n = v - f;
982 	  char *end;
983 
984 	  for (i = 0; i < size; i++)
985 	    if (strncasecmp (array[i].name, f, n) == 0)
986 	      {
987 		value = strtol (v + 1, &end, 0);
988 		if (*end == '\0')
989 		  {
990 		    array[i].value = value;
991 		    return;
992 		  }
993 		break;
994 	      }
995 	}
996     }
997 
998   /* Handle CPU_XXX_FLAGS.  */
999   if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1000     return;
1001 
1002   if (lineno != -1)
1003     fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
1004   else
1005     fail (_("unknown bitfield: %s\n"), f);
1006 }
1007 
1008 static void
output_cpu_flags(FILE * table,bitfield * flags,unsigned int size,int macro,const char * comma,const char * indent)1009 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
1010 		  int macro, const char *comma, const char *indent)
1011 {
1012   unsigned int i;
1013 
1014   memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
1015 
1016   fprintf (table, "%s{ { ", indent);
1017 
1018   for (i = 0; i < size - 1; i++)
1019     {
1020       if (((i + 1) % 20) != 0)
1021 	fprintf (table, "%d, ", flags[i].value);
1022       else
1023 	fprintf (table, "%d,", flags[i].value);
1024       if (((i + 1) % 20) == 0)
1025 	{
1026 	  /* We need \\ for macro.  */
1027 	  if (macro)
1028 	    fprintf (table, " \\\n    %s", indent);
1029 	  else
1030 	    fprintf (table, "\n    %s", indent);
1031 	}
1032       if (flags[i].value)
1033 	active_cpu_flags.array[i / 32] |= 1U << (i % 32);
1034     }
1035 
1036   fprintf (table, "%d } }%s\n", flags[i].value, comma);
1037 }
1038 
1039 static void
process_i386_cpu_flag(FILE * table,char * flag,int macro,const char * comma,const char * indent,int lineno)1040 process_i386_cpu_flag (FILE *table, char *flag, int macro,
1041 		       const char *comma, const char *indent,
1042 		       int lineno)
1043 {
1044   char *str, *next = flag, *last;
1045   unsigned int i;
1046   int value = 1;
1047   bitfield flags [ARRAY_SIZE (cpu_flags)];
1048 
1049   /* Copy the default cpu flags.  */
1050   memcpy (flags, cpu_flags, sizeof (cpu_flags));
1051 
1052   if (flag[0] == '~')
1053     {
1054       last = flag + strlen (flag);
1055 
1056       if (flag[1] == '(')
1057 	{
1058 	  last -= 1;
1059 	  next = flag + 2;
1060 	  if (*last != ')')
1061 	    fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
1062 		  lineno, flag);
1063 	  *last = '\0';
1064 	}
1065       else
1066 	next = flag + 1;
1067 
1068       /* First we turn on everything except for cpu64, cpuno64, and - if
1069          present - the padding field.  */
1070       for (i = 0; i < ARRAY_SIZE (flags); i++)
1071 	if (flags[i].position < Cpu64)
1072 	  flags[i].value = 1;
1073 
1074       /* Turn off selective bits.  */
1075       value = 0;
1076     }
1077 
1078   if (strcmp (flag, "0"))
1079     {
1080       /* Turn on/off selective bits.  */
1081       last = flag + strlen (flag);
1082       for (; next && next < last; )
1083 	{
1084 	  str = next_field (next, '|', &next, last);
1085 	  if (str)
1086 	    set_bitfield (str, flags, value, ARRAY_SIZE (flags), lineno);
1087 	}
1088     }
1089 
1090   output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1091 		    comma, indent);
1092 }
1093 
1094 static void
output_opcode_modifier(FILE * table,bitfield * modifier,unsigned int size)1095 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1096 {
1097   unsigned int i;
1098 
1099   fprintf (table, "    { ");
1100 
1101   for (i = 0; i < size - 1; i++)
1102     {
1103       if (((i + 1) % 20) != 0)
1104         fprintf (table, "%d, ", modifier[i].value);
1105       else
1106         fprintf (table, "%d,", modifier[i].value);
1107       if (((i + 1) % 20) == 0)
1108 	fprintf (table, "\n      ");
1109     }
1110 
1111   fprintf (table, "%d },\n", modifier[i].value);
1112 }
1113 
1114 static int
adjust_broadcast_modifier(char ** opnd)1115 adjust_broadcast_modifier (char **opnd)
1116 {
1117   char *str, *next, *last, *op;
1118   int bcst_type = INT_MAX;
1119 
1120   /* Skip the immediate operand.  */
1121   op = opnd[0];
1122   if (strcasecmp(op, "Imm8") == 0)
1123     op = opnd[1];
1124 
1125   op = xstrdup (op);
1126   last = op + strlen (op);
1127   for (next = op; next && next < last; )
1128     {
1129       str = next_field (next, '|', &next, last);
1130       if (str)
1131 	{
1132 	  if (strcasecmp(str, "Byte") == 0)
1133 	    {
1134 	      /* The smalest broadcast type, no need to check
1135 		 further.  */
1136 	      bcst_type = BYTE_BROADCAST;
1137 	      break;
1138 	    }
1139 	  else if (strcasecmp(str, "Word") == 0)
1140 	    {
1141 	      if (bcst_type > WORD_BROADCAST)
1142 		bcst_type = WORD_BROADCAST;
1143 	    }
1144 	  else if (strcasecmp(str, "Dword") == 0)
1145 	    {
1146 	      if (bcst_type > DWORD_BROADCAST)
1147 		bcst_type = DWORD_BROADCAST;
1148 	    }
1149 	  else if (strcasecmp(str, "Qword") == 0)
1150 	    {
1151 	      if (bcst_type > QWORD_BROADCAST)
1152 		bcst_type = QWORD_BROADCAST;
1153 	    }
1154 	}
1155     }
1156   free (op);
1157 
1158   if (bcst_type == INT_MAX)
1159     fail (_("unknown broadcast operand: %s\n"), op);
1160 
1161   return bcst_type;
1162 }
1163 
1164 static void
process_i386_opcode_modifier(FILE * table,char * mod,unsigned int space,unsigned int prefix,char ** opnd,int lineno)1165 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1166 			      unsigned int prefix, char **opnd, int lineno)
1167 {
1168   char *str, *next, *last;
1169   bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1170 
1171   active_isstring = 0;
1172 
1173   /* Copy the default opcode modifier.  */
1174   memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1175 
1176   if (strcmp (mod, "0"))
1177     {
1178       unsigned int have_w = 0, bwlq_suf = 0xf;
1179 
1180       last = mod + strlen (mod);
1181       for (next = mod; next && next < last; )
1182 	{
1183 	  str = next_field (next, '|', &next, last);
1184 	  if (str)
1185 	    {
1186 	      int val = 1;
1187 	      if (strcasecmp(str, "Broadcast") == 0)
1188 		val = adjust_broadcast_modifier (opnd);
1189 
1190 	      set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1191 			    lineno);
1192 	      if (strcasecmp(str, "IsString") == 0)
1193 		active_isstring = 1;
1194 
1195 	      if (strcasecmp(str, "W") == 0)
1196 		have_w = 1;
1197 
1198 	      if (strcasecmp(str, "No_bSuf") == 0)
1199 		bwlq_suf &= ~1;
1200 	      if (strcasecmp(str, "No_wSuf") == 0)
1201 		bwlq_suf &= ~2;
1202 	      if (strcasecmp(str, "No_lSuf") == 0)
1203 		bwlq_suf &= ~4;
1204 	      if (strcasecmp(str, "No_qSuf") == 0)
1205 		bwlq_suf &= ~8;
1206 	    }
1207 	}
1208 
1209       if (space)
1210 	{
1211 	  if (!modifiers[OpcodeSpace].value)
1212 	    modifiers[OpcodeSpace].value = space;
1213 	  else if (modifiers[OpcodeSpace].value != space)
1214 	    fail (_("%s:%d: Conflicting opcode space specifications\n"),
1215 		  filename, lineno);
1216 	  else
1217 	    fprintf (stderr,
1218 		     _("%s:%d: Warning: redundant opcode space specification\n"),
1219 		     filename, lineno);
1220 	}
1221 
1222       if (prefix)
1223 	{
1224 	  if (!modifiers[OpcodePrefix].value)
1225 	    modifiers[OpcodePrefix].value = prefix;
1226 	  else if (modifiers[OpcodePrefix].value != prefix)
1227 	    fail (_("%s:%d: Conflicting prefix specifications\n"),
1228 		  filename, lineno);
1229 	  else
1230 	    fprintf (stderr,
1231 		     _("%s:%d: Warning: redundant prefix specification\n"),
1232 		     filename, lineno);
1233 	}
1234 
1235       if (have_w && !bwlq_suf)
1236 	fail ("%s: %d: stray W modifier\n", filename, lineno);
1237       if (have_w && !(bwlq_suf & 1))
1238 	fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1239 		 filename, lineno);
1240       if (have_w && !(bwlq_suf & ~1))
1241 	fprintf (stderr,
1242 		 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1243 		 filename, lineno);
1244     }
1245   output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1246 }
1247 
1248 enum stage {
1249   stage_macros,
1250   stage_opcodes,
1251   stage_registers,
1252 };
1253 
1254 static void
output_operand_type(FILE * table,enum operand_class class,enum operand_instance instance,const bitfield * types,unsigned int size,enum stage stage,const char * indent)1255 output_operand_type (FILE *table, enum operand_class class,
1256 		     enum operand_instance instance,
1257 		     const bitfield *types, unsigned int size,
1258 		     enum stage stage, const char *indent)
1259 {
1260   unsigned int i;
1261 
1262   fprintf (table, "{ { %d, %d, ", class, instance);
1263 
1264   for (i = 0; i < size - 1; i++)
1265     {
1266       if (((i + 3) % 20) != 0)
1267 	fprintf (table, "%d, ", types[i].value);
1268       else
1269 	fprintf (table, "%d,", types[i].value);
1270       if (((i + 3) % 20) == 0)
1271 	{
1272 	  /* We need \\ for macro.  */
1273 	  if (stage == stage_macros)
1274 	    fprintf (table, " \\\n%s", indent);
1275 	  else
1276 	    fprintf (table, "\n%s", indent);
1277 	}
1278     }
1279 
1280   fprintf (table, "%d } }", types[i].value);
1281 }
1282 
1283 static void
process_i386_operand_type(FILE * table,char * op,enum stage stage,const char * indent,int lineno)1284 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1285 			   const char *indent, int lineno)
1286 {
1287   char *str, *next, *last;
1288   enum operand_class class = ClassNone;
1289   enum operand_instance instance = InstanceNone;
1290   bitfield types [ARRAY_SIZE (operand_types)];
1291 
1292   /* Copy the default operand type.  */
1293   memcpy (types, operand_types, sizeof (types));
1294 
1295   if (strcmp (op, "0"))
1296     {
1297       int baseindex = 0;
1298 
1299       last = op + strlen (op);
1300       for (next = op; next && next < last; )
1301 	{
1302 	  str = next_field (next, '|', &next, last);
1303 	  if (str)
1304 	    {
1305 	      unsigned int i;
1306 
1307 	      if (!strncmp(str, "Class=", 6))
1308 		{
1309 		  for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1310 		    if (!strcmp(str + 6, operand_classes[i].name))
1311 		      {
1312 			class = operand_classes[i].value;
1313 			str = NULL;
1314 			break;
1315 		      }
1316 		}
1317 
1318 	      if (str && !strncmp(str, "Instance=", 9))
1319 		{
1320 		  for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1321 		    if (!strcmp(str + 9, operand_instances[i].name))
1322 		      {
1323 			instance = operand_instances[i].value;
1324 			str = NULL;
1325 			break;
1326 		      }
1327 		}
1328 	    }
1329 	  if (str)
1330 	    {
1331 	      set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1332 	      if (strcasecmp(str, "BaseIndex") == 0)
1333 		baseindex = 1;
1334 	    }
1335 	}
1336 
1337       if (stage == stage_opcodes && baseindex && !active_isstring)
1338 	{
1339 	  set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1340 	  if (!active_cpu_flags.bitfield.cpu64
1341 	      && !active_cpu_flags.bitfield.cpumpx)
1342 	    set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1343 	  set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1344 	}
1345     }
1346   output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1347 		       stage, indent);
1348 }
1349 
1350 static void
output_i386_opcode(FILE * table,const char * name,char * str,char * last,int lineno)1351 output_i386_opcode (FILE *table, const char *name, char *str,
1352 		    char *last, int lineno)
1353 {
1354   unsigned int i, length, prefix = 0, space = 0;
1355   char *base_opcode, *extension_opcode, *end;
1356   char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1357   unsigned long long opcode;
1358 
1359   /* Find base_opcode.  */
1360   base_opcode = next_field (str, ',', &str, last);
1361 
1362   /* Find extension_opcode.  */
1363   extension_opcode = next_field (str, ',', &str, last);
1364 
1365   /* Find cpu_flags.  */
1366   cpu_flags = next_field (str, ',', &str, last);
1367 
1368   /* Find opcode_modifier.  */
1369   opcode_modifier = next_field (str, ',', &str, last);
1370 
1371   /* Remove the first {.  */
1372   str = remove_leading_whitespaces (str);
1373   if (*str != '{')
1374     abort ();
1375   str = remove_leading_whitespaces (str + 1);
1376   remove_trailing_whitespaces (str);
1377 
1378   /* Remove } and trailing white space. */
1379   i = strlen (str);
1380   if (!i || str[i - 1] != '}')
1381     abort ();
1382   str[--i] = '\0';
1383   remove_trailing_whitespaces (str);
1384 
1385   if (!*str)
1386     operand_types [i = 0] = NULL;
1387   else
1388     {
1389       last = str + strlen (str);
1390 
1391       /* Find operand_types.  */
1392       for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1393 	{
1394 	  if (str >= last)
1395 	    {
1396 	      operand_types [i] = NULL;
1397 	      break;
1398 	    }
1399 
1400 	  operand_types [i] = next_field (str, ',', &str, last);
1401 	}
1402     }
1403 
1404   opcode = strtoull (base_opcode, &end, 0);
1405 
1406   /* Determine opcode length.  */
1407   for (length = 1; length < 8; ++length)
1408     if (!(opcode >> (8 * length)))
1409        break;
1410 
1411   /* Transform prefixes encoded in the opcode into opcode modifier
1412      representation.  */
1413   if (length > 1)
1414     {
1415       switch (opcode >> (8 * length - 8))
1416 	{
1417 	case 0x66: prefix = PREFIX_0X66; break;
1418 	case 0xF3: prefix = PREFIX_0XF3; break;
1419 	case 0xF2: prefix = PREFIX_0XF2; break;
1420 	}
1421 
1422       if (prefix)
1423 	opcode &= (1ULL << (8 * --length)) - 1;
1424     }
1425 
1426   /* Transform opcode space encoded in the opcode into opcode modifier
1427      representation.  */
1428   if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1429     {
1430       switch ((opcode >> (8 * length - 16)) & 0xff)
1431 	{
1432 	default:   space = SPACE_0F;   break;
1433 	case 0x38: space = SPACE_0F38; break;
1434 	case 0x3A: space = SPACE_0F3A; break;
1435 	}
1436 
1437       if (space != SPACE_0F && --length == 1)
1438 	fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1439 	      filename, lineno, name);
1440       opcode &= (1ULL << (8 * --length)) - 1;
1441     }
1442 
1443   if (length > 2)
1444     fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1445 	  filename, lineno, name, 2 * length, opcode);
1446 
1447   fprintf (table, "  { \"%s\", 0x%0*llx%s, %s, %lu,\n",
1448 	   name, 2 * (int)length, opcode, end, extension_opcode, i);
1449 
1450   process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1451 				operand_types, lineno);
1452 
1453   process_i386_cpu_flag (table, cpu_flags, 0, ",", "    ", lineno);
1454 
1455   fprintf (table, "    { ");
1456 
1457   for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1458     {
1459       if (!operand_types[i])
1460 	{
1461 	  if (i == 0)
1462 	    process_i386_operand_type (table, "0", stage_opcodes, "\t  ",
1463 				       lineno);
1464 	  break;
1465 	}
1466 
1467       if (i != 0)
1468 	fprintf (table, ",\n      ");
1469 
1470       process_i386_operand_type (table, operand_types[i], stage_opcodes,
1471 				 "\t  ", lineno);
1472     }
1473   fprintf (table, " } },\n");
1474 }
1475 
1476 struct opcode_hash_entry
1477 {
1478   struct opcode_hash_entry *next;
1479   char *name;
1480   char *opcode;
1481   int lineno;
1482 };
1483 
1484 /* Calculate the hash value of an opcode hash entry P.  */
1485 
1486 static hashval_t
opcode_hash_hash(const void * p)1487 opcode_hash_hash (const void *p)
1488 {
1489   struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1490   return htab_hash_string (entry->name);
1491 }
1492 
1493 /* Compare a string Q against an opcode hash entry P.  */
1494 
1495 static int
opcode_hash_eq(const void * p,const void * q)1496 opcode_hash_eq (const void *p, const void *q)
1497 {
1498   struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1499   const char *name = (const char *) q;
1500   return strcmp (name, entry->name) == 0;
1501 }
1502 
1503 static void
parse_template(char * buf,int lineno)1504 parse_template (char *buf, int lineno)
1505 {
1506   char sep, *end, *name;
1507   struct template *tmpl = xmalloc (sizeof (*tmpl));
1508   struct template_instance *last_inst = NULL;
1509 
1510   buf = remove_leading_whitespaces (buf + 1);
1511   end = strchr (buf, ':');
1512   if (end == NULL)
1513     fail ("%s: %d: missing ':'\n", filename, lineno);
1514   *end++ = '\0';
1515   remove_trailing_whitespaces (buf);
1516 
1517   if (*buf == '\0')
1518     fail ("%s: %d: missing template identifier\n", filename, lineno);
1519   tmpl->name = xstrdup (buf);
1520 
1521   tmpl->params = NULL;
1522   do {
1523       struct template_param *param;
1524 
1525       buf = remove_leading_whitespaces (end);
1526       end = strpbrk (buf, ":,");
1527       if (end == NULL)
1528         fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1529 
1530       sep = *end;
1531       *end++ = '\0';
1532       remove_trailing_whitespaces (buf);
1533 
1534       param = xmalloc (sizeof (*param));
1535       param->name = xstrdup (buf);
1536       param->next = tmpl->params;
1537       tmpl->params = param;
1538   } while (sep == ':');
1539 
1540   tmpl->instances = NULL;
1541   do {
1542       struct template_instance *inst;
1543       char *cur, *next;
1544       const struct template_param *param;
1545 
1546       buf = remove_leading_whitespaces (end);
1547       end = strpbrk (buf, ",>");
1548       if (end == NULL)
1549         fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1550 
1551       sep = *end;
1552       *end++ = '\0';
1553 
1554       inst = xmalloc (sizeof (*inst));
1555       inst->next = NULL;
1556       inst->args = NULL;
1557 
1558       cur = next_field (buf, ':', &next, end);
1559       inst->name = *cur != '$' ? xstrdup (cur) : "";
1560 
1561       for (param = tmpl->params; param; param = param->next)
1562 	{
1563 	  struct template_arg *arg = xmalloc (sizeof (*arg));
1564 
1565 	  cur = next_field (next, ':', &next, end);
1566 	  if (next > end)
1567 	    fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1568 	  arg->val = xstrdup (cur);
1569 	  arg->next = inst->args;
1570 	  inst->args = arg;
1571 	}
1572 
1573       if (tmpl->instances)
1574 	last_inst->next = inst;
1575       else
1576 	tmpl->instances = inst;
1577       last_inst = inst;
1578   } while (sep == ',');
1579 
1580   buf = remove_leading_whitespaces (end);
1581   if (*buf)
1582     fprintf(stderr, "%s: %d: excess characters '%s'\n",
1583 	    filename, lineno, buf);
1584 
1585   tmpl->next = templates;
1586   templates = tmpl;
1587 }
1588 
1589 static unsigned int
expand_templates(char * name,const char * str,htab_t opcode_hash_table,struct opcode_hash_entry *** opcode_array_p,int lineno)1590 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1591 		  struct opcode_hash_entry ***opcode_array_p, int lineno)
1592 {
1593   static unsigned int idx, opcode_array_size;
1594   struct opcode_hash_entry **opcode_array = *opcode_array_p;
1595   struct opcode_hash_entry **hash_slot, **entry;
1596   char *ptr1 = strchr(name, '<'), *ptr2;
1597 
1598   if (ptr1 == NULL)
1599     {
1600       /* Get the slot in hash table.  */
1601       hash_slot = (struct opcode_hash_entry **)
1602 	htab_find_slot_with_hash (opcode_hash_table, name,
1603 				  htab_hash_string (name),
1604 				  INSERT);
1605 
1606       if (*hash_slot == NULL)
1607 	{
1608 	  /* It is the new one.  Put it on opcode array.  */
1609 	  if (idx >= opcode_array_size)
1610 	    {
1611 	      /* Grow the opcode array when needed.  */
1612 	      opcode_array_size += 1024;
1613 	      opcode_array = (struct opcode_hash_entry **)
1614 		xrealloc (opcode_array,
1615 			  sizeof (*opcode_array) * opcode_array_size);
1616 		*opcode_array_p = opcode_array;
1617 	    }
1618 
1619 	  opcode_array[idx] = (struct opcode_hash_entry *)
1620 	    xmalloc (sizeof (struct opcode_hash_entry));
1621 	  opcode_array[idx]->next = NULL;
1622 	  opcode_array[idx]->name = xstrdup (name);
1623 	  opcode_array[idx]->opcode = xstrdup (str);
1624 	  opcode_array[idx]->lineno = lineno;
1625 	  *hash_slot = opcode_array[idx];
1626 	  idx++;
1627 	}
1628       else
1629 	{
1630 	  /* Append it to the existing one.  */
1631 	  entry = hash_slot;
1632 	  while ((*entry) != NULL)
1633 	    entry = &(*entry)->next;
1634 	  *entry = (struct opcode_hash_entry *)
1635 	    xmalloc (sizeof (struct opcode_hash_entry));
1636 	  (*entry)->next = NULL;
1637 	  (*entry)->name = (*hash_slot)->name;
1638 	  (*entry)->opcode = xstrdup (str);
1639 	  (*entry)->lineno = lineno;
1640 	}
1641     }
1642   else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1643     fail ("%s: %d: missing '>'\n", filename, lineno);
1644   else
1645     {
1646       const struct template *tmpl;
1647       const struct template_instance *inst;
1648 
1649       *ptr1 = '\0';
1650       ptr1 = remove_leading_whitespaces (ptr1 + 1);
1651       remove_trailing_whitespaces (ptr1);
1652 
1653       *ptr2++ = '\0';
1654 
1655       for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1656 	if (!strcmp(ptr1, tmpl->name))
1657 	  break;
1658       if (!tmpl)
1659 	fail ("reference to unknown template '%s'\n", ptr1);
1660 
1661       for (inst = tmpl->instances; inst; inst = inst->next)
1662 	{
1663 	  char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1664 	  char *str2 = xmalloc(2 * strlen(str));
1665 	  const char *src;
1666 
1667 	  strcpy (name2, name);
1668 	  strcat (name2, inst->name);
1669 	  strcat (name2, ptr2);
1670 
1671 	  for (ptr1 = str2, src = str; *src; )
1672 	    {
1673 	      const char *ident = tmpl->name, *end;
1674 	      const struct template_param *param;
1675 	      const struct template_arg *arg;
1676 
1677 	      if ((*ptr1 = *src++) != '<')
1678 		{
1679 		  ++ptr1;
1680 		  continue;
1681 		}
1682 	      while (ISSPACE(*src))
1683 		++src;
1684 	      while (*ident && *src == *ident)
1685 		++src, ++ident;
1686 	      while (ISSPACE(*src))
1687 		++src;
1688 	      if (*src != ':' || *ident != '\0')
1689 		{
1690 		  memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1691 		  ptr1 += ident - tmpl->name;
1692 		  continue;
1693 		}
1694 	      while (ISSPACE(*++src))
1695 		;
1696 
1697 	      end = src;
1698 	      while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1699 		++end;
1700 
1701 	      for (param = tmpl->params, arg = inst->args; param;
1702 		   param = param->next, arg = arg->next)
1703 		{
1704 		  if (end - src == strlen (param->name)
1705 		      && !memcmp (src, param->name, end - src))
1706 		    {
1707 		      src = end;
1708 		      break;
1709 		    }
1710 		}
1711 
1712 	      if (param == NULL)
1713 		fail ("template '%s' has no parameter '%.*s'\n",
1714 		      tmpl->name, (int)(end - src), src);
1715 
1716 	      while (ISSPACE(*src))
1717 		++src;
1718 	      if (*src != '>')
1719 		fail ("%s: %d: missing '>'\n", filename, lineno);
1720 
1721 	      memcpy(ptr1, arg->val, strlen(arg->val));
1722 	      ptr1 += strlen(arg->val);
1723 	      ++src;
1724 	    }
1725 
1726 	  *ptr1 = '\0';
1727 
1728 	  expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1729 			    lineno);
1730 
1731 	  free (str2);
1732 	  free (name2);
1733 	}
1734     }
1735 
1736   return idx;
1737 }
1738 
1739 static void
process_i386_opcodes(FILE * table)1740 process_i386_opcodes (FILE *table)
1741 {
1742   FILE *fp;
1743   char buf[2048];
1744   unsigned int i, j;
1745   char *str, *p, *last, *name;
1746   htab_t opcode_hash_table;
1747   struct opcode_hash_entry **opcode_array = NULL;
1748   int lineno = 0, marker = 0;
1749 
1750   filename = "i386-opc.tbl";
1751   fp = stdin;
1752 
1753   i = 0;
1754   opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1755 					 opcode_hash_eq, NULL,
1756 					 xcalloc, free);
1757 
1758   fprintf (table, "\n/* i386 opcode table.  */\n\n");
1759   fprintf (table, "const insn_template i386_optab[] =\n{\n");
1760 
1761   /* Put everything on opcode array.  */
1762   while (!feof (fp))
1763     {
1764       if (fgets (buf, sizeof (buf), fp) == NULL)
1765 	break;
1766 
1767       lineno++;
1768 
1769       p = remove_leading_whitespaces (buf);
1770 
1771       /* Skip comments.  */
1772       str = strstr (p, "//");
1773       if (str != NULL)
1774 	str[0] = '\0';
1775 
1776       /* Remove trailing white spaces.  */
1777       remove_trailing_whitespaces (p);
1778 
1779       switch (p[0])
1780 	{
1781 	case '#':
1782 	  if (!strcmp("### MARKER ###", buf))
1783 	    marker = 1;
1784 	  else
1785 	    {
1786 	      /* Since we ignore all included files (we only care about their
1787 		 #define-s here), we don't need to monitor filenames.  The final
1788 		 line number directive is going to refer to the main source file
1789 		 again.  */
1790 	      char *end;
1791 	      unsigned long ln;
1792 
1793 	      p = remove_leading_whitespaces (p + 1);
1794 	      if (!strncmp(p, "line", 4))
1795 		p += 4;
1796 	      ln = strtoul (p, &end, 10);
1797 	      if (ln > 1 && ln < INT_MAX
1798 		  && *remove_leading_whitespaces (end) == '"')
1799 		lineno = ln - 1;
1800 	    }
1801 	  /* Ignore comments.  */
1802 	case '\0':
1803 	  continue;
1804 	  break;
1805 	case '<':
1806 	  parse_template (p, lineno);
1807 	  continue;
1808 	default:
1809 	  if (!marker)
1810 	    continue;
1811 	  break;
1812 	}
1813 
1814       last = p + strlen (p);
1815 
1816       /* Find name.  */
1817       name = next_field (p, ',', &str, last);
1818 
1819       i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1820 			    lineno);
1821     }
1822 
1823   /* Process opcode array.  */
1824   for (j = 0; j < i; j++)
1825     {
1826       struct opcode_hash_entry *next;
1827 
1828       for (next = opcode_array[j]; next; next = next->next)
1829 	{
1830 	  name = next->name;
1831 	  str = next->opcode;
1832 	  lineno = next->lineno;
1833 	  last = str + strlen (str);
1834 	  output_i386_opcode (table, name, str, last, lineno);
1835 	}
1836     }
1837 
1838   fclose (fp);
1839 
1840   fprintf (table, "  { NULL, 0, 0, 0,\n");
1841 
1842   process_i386_opcode_modifier (table, "0", 0, 0, NULL, -1);
1843 
1844   process_i386_cpu_flag (table, "0", 0, ",", "    ", -1);
1845 
1846   fprintf (table, "    { ");
1847   process_i386_operand_type (table, "0", stage_opcodes, "\t  ", -1);
1848   fprintf (table, " } }\n");
1849 
1850   fprintf (table, "};\n");
1851 }
1852 
1853 static void
process_i386_registers(FILE * table)1854 process_i386_registers (FILE *table)
1855 {
1856   FILE *fp;
1857   char buf[2048];
1858   char *str, *p, *last;
1859   char *reg_name, *reg_type, *reg_flags, *reg_num;
1860   char *dw2_32_num, *dw2_64_num;
1861   int lineno = 0;
1862 
1863   filename = "i386-reg.tbl";
1864   fp = fopen (filename, "r");
1865   if (fp == NULL)
1866     fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1867 	  xstrerror (errno));
1868 
1869   fprintf (table, "\n/* i386 register table.  */\n\n");
1870   fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1871 
1872   while (!feof (fp))
1873     {
1874       if (fgets (buf, sizeof (buf), fp) == NULL)
1875 	break;
1876 
1877       lineno++;
1878 
1879       p = remove_leading_whitespaces (buf);
1880 
1881       /* Skip comments.  */
1882       str = strstr (p, "//");
1883       if (str != NULL)
1884 	str[0] = '\0';
1885 
1886       /* Remove trailing white spaces.  */
1887       remove_trailing_whitespaces (p);
1888 
1889       switch (p[0])
1890 	{
1891 	case '#':
1892 	  fprintf (table, "%s\n", p);
1893 	case '\0':
1894 	  continue;
1895 	  break;
1896 	default:
1897 	  break;
1898 	}
1899 
1900       last = p + strlen (p);
1901 
1902       /* Find reg_name.  */
1903       reg_name = next_field (p, ',', &str, last);
1904 
1905       /* Find reg_type.  */
1906       reg_type = next_field (str, ',', &str, last);
1907 
1908       /* Find reg_flags.  */
1909       reg_flags = next_field (str, ',', &str, last);
1910 
1911       /* Find reg_num.  */
1912       reg_num = next_field (str, ',', &str, last);
1913 
1914       fprintf (table, "  { \"%s\",\n    ", reg_name);
1915 
1916       process_i386_operand_type (table, reg_type, stage_registers, "\t",
1917 				 lineno);
1918 
1919       /* Find 32-bit Dwarf2 register number.  */
1920       dw2_32_num = next_field (str, ',', &str, last);
1921 
1922       /* Find 64-bit Dwarf2 register number.  */
1923       dw2_64_num = next_field (str, ',', &str, last);
1924 
1925       fprintf (table, ",\n    %s, %s, { %s, %s } },\n",
1926 	       reg_flags, reg_num, dw2_32_num, dw2_64_num);
1927     }
1928 
1929   fclose (fp);
1930 
1931   fprintf (table, "};\n");
1932 
1933   fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1934 }
1935 
1936 static void
process_i386_initializers(void)1937 process_i386_initializers (void)
1938 {
1939   unsigned int i;
1940   FILE *fp = fopen ("i386-init.h", "w");
1941   char *init;
1942 
1943   if (fp == NULL)
1944     fail (_("can't create i386-init.h, errno = %s\n"),
1945 	  xstrerror (errno));
1946 
1947   process_copyright (fp);
1948 
1949   for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1950     {
1951       fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1952       init = xstrdup (cpu_flag_init[i].init);
1953       process_i386_cpu_flag (fp, init, 1, "", "  ", -1);
1954       free (init);
1955     }
1956 
1957   for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1958     {
1959       fprintf (fp, "\n\n#define %s \\\n  ", operand_type_init[i].name);
1960       init = xstrdup (operand_type_init[i].init);
1961       process_i386_operand_type (fp, init, stage_macros, "      ", -1);
1962       free (init);
1963     }
1964   fprintf (fp, "\n");
1965 
1966   fclose (fp);
1967 }
1968 
1969 /* Program options.  */
1970 #define OPTION_SRCDIR	200
1971 
1972 struct option long_options[] =
1973 {
1974   {"srcdir",  required_argument, NULL, OPTION_SRCDIR},
1975   {"debug",   no_argument,       NULL, 'd'},
1976   {"version", no_argument,       NULL, 'V'},
1977   {"help",    no_argument,       NULL, 'h'},
1978   {0,         no_argument,       NULL, 0}
1979 };
1980 
1981 static void
print_version(void)1982 print_version (void)
1983 {
1984   printf ("%s: version 1.0\n", program_name);
1985   xexit (0);
1986 }
1987 
1988 static void
usage(FILE * stream,int status)1989 usage (FILE * stream, int status)
1990 {
1991   fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1992 	   program_name);
1993   xexit (status);
1994 }
1995 
1996 int
main(int argc,char ** argv)1997 main (int argc, char **argv)
1998 {
1999   extern int chdir (char *);
2000   char *srcdir = NULL;
2001   int c;
2002   unsigned int i, cpumax;
2003   FILE *table;
2004 
2005   program_name = *argv;
2006   xmalloc_set_program_name (program_name);
2007 
2008   while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2009     switch (c)
2010       {
2011       case OPTION_SRCDIR:
2012 	srcdir = optarg;
2013 	break;
2014       case 'V':
2015       case 'v':
2016 	print_version ();
2017 	break;
2018       case 'd':
2019 	debug = 1;
2020 	break;
2021       case 'h':
2022       case '?':
2023 	usage (stderr, 0);
2024       default:
2025       case 0:
2026 	break;
2027       }
2028 
2029   if (optind != argc)
2030     usage (stdout, 1);
2031 
2032   if (srcdir != NULL)
2033     if (chdir (srcdir) != 0)
2034       fail (_("unable to change directory to \"%s\", errno = %s\n"),
2035 	    srcdir, xstrerror (errno));
2036 
2037   /* cpu_flags isn't sorted by position.  */
2038   cpumax = 0;
2039   for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2040     if (cpu_flags[i].position > cpumax)
2041       cpumax = cpu_flags[i].position;
2042 
2043   /* Check the unused bitfield in i386_cpu_flags.  */
2044 #ifdef CpuUnused
2045   static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2046 
2047   if ((cpumax - 1) != CpuMax)
2048     fail (_("CpuMax != %d!\n"), cpumax);
2049 #else
2050   static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2051 
2052   if (cpumax != CpuMax)
2053     fail (_("CpuMax != %d!\n"), cpumax);
2054 
2055   c = CpuNumOfBits - CpuMax - 1;
2056   if (c)
2057     fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2058 #endif
2059 
2060   static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2061 
2062   /* Check the unused bitfield in i386_operand_type.  */
2063 #ifdef OTUnused
2064   static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2065 		 == OTNum + 1);
2066 #else
2067   static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2068 		 == OTNum);
2069 
2070   c = OTNumOfBits - OTNum;
2071   if (c)
2072     fail (_("%d unused bits in i386_operand_type.\n"), c);
2073 #endif
2074 
2075   qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2076 	 compare);
2077 
2078   qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2079 	 sizeof (opcode_modifiers [0]), compare);
2080 
2081   qsort (operand_types, ARRAY_SIZE (operand_types),
2082 	 sizeof (operand_types [0]), compare);
2083 
2084   table = fopen ("i386-tbl.h", "w");
2085   if (table == NULL)
2086     fail (_("can't create i386-tbl.h, errno = %s\n"),
2087 	  xstrerror (errno));
2088 
2089   process_copyright (table);
2090 
2091   process_i386_opcodes (table);
2092   process_i386_registers (table);
2093   process_i386_initializers ();
2094 
2095   fclose (table);
2096 
2097   exit (0);
2098 }
2099