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