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