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