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