OSDN Git Service

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