gas/
[platform/upstream/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 (FirstXmm0),
280   BITFIELD (ByteOkIntel),
281   BITFIELD (ToDword),
282   BITFIELD (ToQword),
283   BITFIELD (AddrPrefixOp0),
284   BITFIELD (IsPrefix),
285   BITFIELD (ImmExt),
286   BITFIELD (NoRex64),
287   BITFIELD (Rex64),
288   BITFIELD (Ugh),
289   BITFIELD (Drex),
290   BITFIELD (Drexv),
291   BITFIELD (Drexc),
292 };
293
294 static bitfield operand_types[] =
295 {
296   BITFIELD (Reg8),
297   BITFIELD (Reg16),
298   BITFIELD (Reg32),
299   BITFIELD (Reg64),
300   BITFIELD (FloatReg),
301   BITFIELD (RegMMX),
302   BITFIELD (RegXMM),
303   BITFIELD (Imm8),
304   BITFIELD (Imm8S),
305   BITFIELD (Imm16),
306   BITFIELD (Imm32),
307   BITFIELD (Imm32S),
308   BITFIELD (Imm64),
309   BITFIELD (Imm1),
310   BITFIELD (BaseIndex),
311   BITFIELD (Disp8),
312   BITFIELD (Disp16),
313   BITFIELD (Disp32),
314   BITFIELD (Disp32S),
315   BITFIELD (Disp64),
316   BITFIELD (InOutPortReg),
317   BITFIELD (ShiftCount),
318   BITFIELD (Control),
319   BITFIELD (Debug),
320   BITFIELD (Test),
321   BITFIELD (SReg2),
322   BITFIELD (SReg3),
323   BITFIELD (Acc),
324   BITFIELD (FloatAcc),
325   BITFIELD (JumpAbsolute),
326   BITFIELD (EsSeg),
327   BITFIELD (RegMem),
328 #ifdef OTUnused
329   BITFIELD (OTUnused),
330 #endif
331 };
332
333 static int
334 compare (const void *x, const void *y)
335 {
336   const bitfield *xp = (const bitfield *) x;
337   const bitfield *yp = (const bitfield *) y;
338   return xp->position - yp->position;
339 }
340
341 static void
342 fail (const char *message, ...)
343 {
344   va_list args;
345   
346   va_start (args, message);
347   fprintf (stderr, _("%s: Error: "), program_name);
348   vfprintf (stderr, message, args);
349   va_end (args);
350   xexit (1);
351 }
352
353 static void
354 process_copyright (FILE *fp)
355 {
356   fprintf (fp, "/* This file is automatically generated by i386-gen.  Do not edit!  */\n\
357 /* Copyright 2007  Free Software Foundation, Inc.\n\
358 \n\
359    This file is part of the GNU opcodes library.\n\
360 \n\
361    This library is free software; you can redistribute it and/or modify\n\
362    it under the terms of the GNU General Public License as published by\n\
363    the Free Software Foundation; either version 3, or (at your option)\n\
364    any later version.\n\
365 \n\
366    It is distributed in the hope that it will be useful, but WITHOUT\n\
367    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
368    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
369    License for more details.\n\
370 \n\
371    You should have received a copy of the GNU General Public License\n\
372    along with this program; if not, write to the Free Software\n\
373    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
374    MA 02110-1301, USA.  */\n");
375 }
376
377 /* Remove leading white spaces.  */
378
379 static char *
380 remove_leading_whitespaces (char *str)
381 {
382   while (ISSPACE (*str))
383     str++;
384   return str;
385 }
386
387 /* Remove trailing white spaces.  */
388
389 static void
390 remove_trailing_whitespaces (char *str)
391 {
392   size_t last = strlen (str);
393
394   if (last == 0)
395     return;
396
397   do
398     {
399       last--;
400       if (ISSPACE (str [last]))
401         str[last] = '\0';
402       else
403         break;
404     }
405   while (last != 0);
406 }
407
408 /* Find next field separated by SEP and terminate it. Return a
409    pointer to the one after it.  */
410
411 static char *
412 next_field (char *str, char sep, char **next)
413 {
414   char *p;
415
416   p = remove_leading_whitespaces (str);
417   for (str = p; *str != sep && *str != '\0'; str++);
418
419   *str = '\0';
420   remove_trailing_whitespaces (p);
421
422   *next = str + 1; 
423
424   return p;
425 }
426
427 static void
428 set_bitfield (const char *f, bitfield *array, unsigned int size)
429 {
430   unsigned int i;
431
432   if (strcmp (f, "CpuSledgehammer") == 0)
433     f= "CpuK8";
434
435   for (i = 0; i < size; i++)
436     if (strcasecmp (array[i].name, f) == 0)
437       {
438         array[i].value = 1;
439         return;
440       }
441
442   printf ("Unknown bitfield: %s\n", f);
443   abort ();
444 }
445
446 static void
447 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
448                   int macro, const char *comma, const char *indent)
449 {
450   unsigned int i;
451
452   fprintf (table, "%s{ { ", indent);
453
454   for (i = 0; i < size - 1; i++)
455     {
456       fprintf (table, "%d, ", flags[i].value);
457       if (((i + 1) % 20) == 0)
458         {
459           /* We need \\ for macro.  */
460           if (macro)
461             fprintf (table, " \\\n    %s", indent);
462           else
463             fprintf (table, "\n    %s", indent);
464         }
465     }
466
467   fprintf (table, "%d } }%s\n", flags[i].value, comma);
468 }
469
470 static void
471 process_i386_cpu_flag (FILE *table, char *flag, int macro,
472                        const char *comma, const char *indent)
473 {
474   char *str, *next, *last;
475   bitfield flags [ARRAY_SIZE (cpu_flags)];
476
477   /* Copy the default cpu flags.  */
478   memcpy (flags, cpu_flags, sizeof (cpu_flags));
479
480   if (strcasecmp (flag, "unknown") == 0)
481     {
482       unsigned int i;
483
484       /* We turn on everything except for cpu64 in case of
485          CPU_UNKNOWN_FLAGS. */
486       for (i = 0; i < ARRAY_SIZE (flags); i++)
487         if (flags[i].position != Cpu64)
488           flags[i].value = 1;
489     }
490   else if (strcmp (flag, "0"))
491     {
492       last = flag + strlen (flag);
493       for (next = flag; next && next < last; )
494         {
495           str = next_field (next, '|', &next);
496           if (str)
497             set_bitfield (str, flags, ARRAY_SIZE (flags));
498         }
499     }
500
501   output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
502                     comma, indent);
503 }
504
505 static void
506 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
507 {
508   unsigned int i;
509
510   fprintf (table, "    { ");
511
512   for (i = 0; i < size - 1; i++)
513     {
514       fprintf (table, "%d, ", modifier[i].value);
515       if (((i + 1) % 20) == 0)
516         fprintf (table, "\n      ");
517     }
518
519   fprintf (table, "%d },\n", modifier[i].value);
520 }
521
522 static void
523 process_i386_opcode_modifier (FILE *table, char *mod)
524 {
525   char *str, *next, *last;
526   bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
527
528   /* Copy the default opcode modifier.  */
529   memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
530
531   if (strcmp (mod, "0"))
532     {
533       last = mod + strlen (mod);
534       for (next = mod; next && next < last; )
535         {
536           str = next_field (next, '|', &next);
537           if (str)
538             set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
539         }
540     }
541   output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
542 }
543
544 static void
545 output_operand_type (FILE *table, bitfield *types, unsigned int size,
546                      int macro, const char *indent)
547 {
548   unsigned int i;
549
550   fprintf (table, "{ { ");
551
552   for (i = 0; i < size - 1; i++)
553     {
554       fprintf (table, "%d, ", types[i].value);
555       if (((i + 1) % 20) == 0)
556         {
557           /* We need \\ for macro.  */
558           if (macro)
559             fprintf (table, "\\\n%s", indent);
560           else
561             fprintf (table, "\n%s", indent);
562         }
563     }
564
565   fprintf (table, "%d } }", types[i].value);
566 }
567
568 static void
569 process_i386_operand_type (FILE *table, char *op, int macro,
570                            const char *indent)
571 {
572   char *str, *next, *last;
573   bitfield types [ARRAY_SIZE (operand_types)];
574
575   /* Copy the default operand type.  */
576   memcpy (types, operand_types, sizeof (types));
577
578   if (strcmp (op, "0"))
579     {
580       last = op + strlen (op);
581       for (next = op; next && next < last; )
582         {
583           str = next_field (next, '|', &next);
584           if (str)
585             set_bitfield (str, types, ARRAY_SIZE (types));
586         }
587     }
588   output_operand_type (table, types, ARRAY_SIZE (types), macro,
589                        indent);
590 }
591
592 static void
593 process_i386_opcodes (FILE *table)
594 {
595   FILE *fp = fopen ("i386-opc.tbl", "r");
596   char buf[2048];
597   unsigned int i;
598   char *str, *p, *last;
599   char *name, *operands, *base_opcode, *extension_opcode;
600   char *opcode_length;
601   char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
602
603   if (fp == NULL)
604     fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
605           xstrerror (errno));
606
607   fprintf (table, "\n/* i386 opcode table.  */\n\n");
608   fprintf (table, "const template i386_optab[] =\n{\n");
609
610   while (!feof (fp))
611     {
612       if (fgets (buf, sizeof (buf), fp) == NULL)
613         break;
614
615       p = remove_leading_whitespaces (buf);
616
617       /* Skip comments.  */
618       str = strstr (p, "//");
619       if (str != NULL)
620         str[0] = '\0';
621
622       /* Remove trailing white spaces.  */
623       remove_trailing_whitespaces (p);
624
625       switch (p[0])
626         {
627         case '#':
628           fprintf (table, "%s\n", p);
629         case '\0':
630           continue;
631           break;
632         default:
633           break;
634         }
635
636       last = p + strlen (p);
637
638       /* Find name.  */
639       name = next_field (p, ',', &str);
640
641       if (str >= last)
642         abort ();
643
644       /* Find number of operands.  */
645       operands = next_field (str, ',', &str);
646
647       if (str >= last)
648         abort ();
649
650       /* Find base_opcode.  */
651       base_opcode = next_field (str, ',', &str);
652
653       if (str >= last)
654         abort ();
655
656       /* Find extension_opcode.  */
657       extension_opcode = next_field (str, ',', &str);
658
659       if (str >= last)
660         abort ();
661
662       /* Find opcode_length.  */
663       opcode_length = next_field (str, ',', &str);
664
665       if (str >= last)
666         abort ();
667
668       /* Find cpu_flags.  */
669       cpu_flags = next_field (str, ',', &str);
670
671       if (str >= last)
672         abort ();
673
674       /* Find opcode_modifier.  */
675       opcode_modifier = next_field (str, ',', &str);
676
677       if (str >= last)
678         abort ();
679
680       /* Remove the first {.  */
681       str = remove_leading_whitespaces (str);
682       if (*str != '{')
683         abort ();
684       str = remove_leading_whitespaces (str + 1);
685
686       i = strlen (str);
687
688       /* There are at least "X}".  */
689       if (i < 2)
690         abort ();
691
692       /* Remove trailing white spaces and }. */
693       do
694         {
695           i--;
696           if (ISSPACE (str[i]) || str[i] == '}')
697             str[i] = '\0';
698           else
699             break;
700         }
701       while (i != 0);
702
703       last = str + i;
704
705       /* Find operand_types.  */
706       for (i = 0; i < ARRAY_SIZE (operand_types); i++)
707         {
708           if (str >= last)
709             {
710               operand_types [i] = NULL;
711               break;
712             }
713
714           operand_types [i] = next_field (str, ',', &str);
715           if (*operand_types[i] == '0')
716             {
717               if (i != 0)
718                 operand_types[i] = NULL;
719               break;
720             }
721         }
722
723       fprintf (table, "  { \"%s\", %s, %s, %s, %s,\n",
724                name, operands, base_opcode, extension_opcode,
725                opcode_length);
726
727       process_i386_cpu_flag (table, cpu_flags, 0, ",", "    ");
728
729       process_i386_opcode_modifier (table, opcode_modifier);
730
731       fprintf (table, "    { ");
732
733       for (i = 0; i < ARRAY_SIZE (operand_types); i++)
734         {
735           if (operand_types[i] == NULL
736               || *operand_types[i] == '0')
737             {
738               if (i == 0)
739                 process_i386_operand_type (table, "0", 0, "\t  ");
740               break;
741             }
742
743           if (i != 0)
744             fprintf (table, ",\n      ");
745
746           process_i386_operand_type (table, operand_types[i], 0,
747                                      "\t  ");
748         }
749       fprintf (table, " } },\n");
750     }
751
752   fclose (fp);
753
754   fprintf (table, "  { NULL, 0, 0, 0, 0,\n");
755
756   process_i386_cpu_flag (table, "0", 0, ",", "    ");
757
758   process_i386_opcode_modifier (table, "0");
759  
760   fprintf (table, "    { ");
761   process_i386_operand_type (table, "0", 0, "\t  ");
762   fprintf (table, " } }\n");
763
764   fprintf (table, "};\n");
765 }
766
767 static void
768 process_i386_registers (FILE *table)
769 {
770   FILE *fp = fopen ("i386-reg.tbl", "r");
771   char buf[2048];
772   char *str, *p, *last;
773   char *reg_name, *reg_type, *reg_flags, *reg_num;
774
775   if (fp == NULL)
776     fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
777           xstrerror (errno));
778
779   fprintf (table, "\n/* i386 register table.  */\n\n");
780   fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
781
782   while (!feof (fp))
783     {
784       if (fgets (buf, sizeof (buf), fp) == NULL)
785         break;
786
787       p = remove_leading_whitespaces (buf);
788
789       /* Skip comments.  */
790       str = strstr (p, "//");
791       if (str != NULL)
792         str[0] = '\0';
793
794       /* Remove trailing white spaces.  */
795       remove_trailing_whitespaces (p);
796
797       switch (p[0])
798         {
799         case '#':
800           fprintf (table, "%s\n", p);
801         case '\0':
802           continue;
803           break;
804         default:
805           break;
806         }
807
808       last = p + strlen (p);
809
810       /* Find reg_name.  */
811       reg_name = next_field (p, ',', &str);
812
813       if (str >= last)
814         abort ();
815
816       /* Find reg_type.  */
817       reg_type = next_field (str, ',', &str);
818
819       if (str >= last)
820         abort ();
821
822       /* Find reg_flags.  */
823       reg_flags = next_field (str, ',', &str);
824
825       if (str >= last)
826         abort ();
827
828       /* Find reg_num.  */
829       reg_num = next_field (str, ',', &str);
830
831       fprintf (table, "  { \"%s\",\n    ", reg_name);
832
833       process_i386_operand_type (table, reg_type, 0, "\t");
834
835       fprintf (table, ",\n    %s, %s },\n", reg_flags, reg_num);
836     }
837
838   fclose (fp);
839
840   fprintf (table, "};\n");
841
842   fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
843 }
844
845 static void
846 process_i386_initializers (void)
847 {
848   unsigned int i;
849   FILE *fp = fopen ("i386-init.h", "w");
850   char *init;
851
852   if (fp == NULL)
853     fail (_("can't create i386-init.h, errno = %s\n"),
854           xstrerror (errno));
855
856   process_copyright (fp);
857
858   for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
859     {
860       fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
861       init = xstrdup (cpu_flag_init[i].init);
862       process_i386_cpu_flag (fp, init, 1, "", "  ");
863       free (init);
864     }
865
866   for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
867     {
868       fprintf (fp, "\n\n#define %s \\\n  ", operand_type_init[i].name);
869       init = xstrdup (operand_type_init[i].init);
870       process_i386_operand_type (fp, init, 1, "      ");
871       free (init);
872     }
873   fprintf (fp, "\n");
874
875   fclose (fp);
876 }
877
878 /* Program options.  */
879 #define OPTION_SRCDIR   200
880
881 struct option long_options[] = 
882 {
883   {"srcdir",  required_argument, NULL, OPTION_SRCDIR},
884   {"debug",   no_argument,       NULL, 'd'},
885   {"version", no_argument,       NULL, 'V'},
886   {"help",    no_argument,       NULL, 'h'},
887   {0,         no_argument,       NULL, 0}
888 };
889
890 static void
891 print_version (void)
892 {
893   printf ("%s: version 1.0\n", program_name);
894   xexit (0);
895 }
896
897 static void
898 usage (FILE * stream, int status)
899 {
900   fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
901            program_name);
902   xexit (status);
903 }
904
905 int
906 main (int argc, char **argv)
907 {
908   extern int chdir (char *);
909   char *srcdir = NULL;
910   int c;
911   FILE *table;
912   
913   program_name = *argv;
914   xmalloc_set_program_name (program_name);
915
916   while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
917     switch (c)
918       {
919       case OPTION_SRCDIR:
920         srcdir = optarg;
921         break;
922       case 'V':
923       case 'v':
924         print_version ();
925         break;
926       case 'd':
927         debug = 1;
928         break;
929       case 'h':
930       case '?':
931         usage (stderr, 0);
932       default:
933       case 0:
934         break;
935       }
936
937   if (optind != argc)
938     usage (stdout, 1);
939
940   if (srcdir != NULL) 
941     if (chdir (srcdir) != 0)
942       fail (_("unable to change directory to \"%s\", errno = %s\n"),
943             srcdir, xstrerror (errno));
944
945   /* Check the unused bitfield in i386_cpu_flags.  */
946 #ifndef CpuUnused
947   c = CpuNumOfBits - CpuMax - 1;
948   if (c)
949     fail (_("%d unused bits in i386_cpu_flags.\n"), c);
950 #endif
951
952   /* Check the unused bitfield in i386_operand_type.  */
953 #ifndef OTUnused
954   c = OTNumOfBits - OTMax - 1;
955   if (c)
956     fail (_("%d unused bits in i386_operand_type.\n"), c);
957 #endif
958
959   qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
960          compare);
961
962   qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
963          sizeof (opcode_modifiers [0]), compare);
964
965   qsort (operand_types, ARRAY_SIZE (operand_types),
966          sizeof (operand_types [0]), compare);
967
968   table = fopen ("i386-tbl.h", "w");
969   if (table == NULL)
970     fail (_("can't create i386-tbl.h, errno = %s\n"),
971           xstrerror (errno));
972
973   process_copyright (table);
974
975   process_i386_opcodes (table);
976   process_i386_registers (table);
977   process_i386_initializers ();
978
979   fclose (table);
980
981   exit (0);
982 }