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