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