OSDN Git Service

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