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