OSDN Git Service

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