Upload Tizen:Base source
[external/binutils.git] / opcodes / i386-gen.c
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|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 }