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