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