OSDN Git Service

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