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