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