OSDN Git Service

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