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