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