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