OSDN Git Service

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