1 /* Copyright (C) 2007-2014 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
24 #include "libiberty.h"
26 #include "safe-ctype.h"
31 #define _(String) gettext (String)
33 static const char *program_name = NULL;
36 typedef struct initializer
42 static initializer cpu_flag_init[] =
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
57 "Cpu186|Cpu286|Cpu386" },
59 "Cpu186|Cpu286|Cpu386|Cpu486" },
61 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
63 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
67 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
69 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
71 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
73 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM|CpuCX16" },
75 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuCX16" },
77 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM|CpuCX16" },
79 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM|CpuCX16" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
83 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
87 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
91 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
95 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase" },
97 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd" },
99 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
100 { "CPU_BTVER2_FLAGS",
101 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuSSE4_1|CpuSSE4_2|CpuABM|CpuLM|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
109 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
110 { "CPU_CLFLUSH_FLAGS",
114 { "CPU_SYSCALL_FLAGS",
121 "CpuMMX|CpuSSE|CpuSSE2" },
123 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
125 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
126 { "CPU_SSE4_1_FLAGS",
127 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
128 { "CPU_SSE4_2_FLAGS",
129 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
130 { "CPU_ANY_SSE_FLAGS",
131 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
138 { "CPU_XSAVEOPT_FLAGS",
141 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
145 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
147 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
149 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
160 { "CPU_RDTSCP_FLAGS",
164 { "CPU_FSGSBASE_FLAGS",
178 { "CPU_INVPCID_FLAGS",
180 { "CPU_VMFUNC_FLAGS",
184 { "CPU_3DNOWA_FLAGS",
185 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
191 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
195 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
197 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
198 { "CPU_AVX512F_FLAGS",
199 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
200 { "CPU_AVX512CD_FLAGS",
201 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
202 { "CPU_AVX512ER_FLAGS",
203 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
204 { "CPU_AVX512PF_FLAGS",
205 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
206 { "CPU_ANY_AVX_FLAGS",
207 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
214 { "CPU_RDSEED_FLAGS",
216 { "CPU_PRFCHW_FLAGS",
224 { "CPU_CLFLUSHOPT_FLAGS",
226 { "CPU_XSAVES_FLAGS",
228 { "CPU_XSAVEC_FLAGS",
230 { "CPU_PREFETCHWT1_FLAGS",
234 { "CPU_AVX512DQ_FLAGS",
235 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512DQ" },
236 { "CPU_AVX512BW_FLAGS",
237 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512BW" },
238 { "CPU_AVX512VL_FLAGS",
239 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VL" },
242 { "CPU_PCOMMIT_FLAGS",
246 static initializer operand_type_init[] =
248 { "OPERAND_TYPE_NONE",
250 { "OPERAND_TYPE_REG8",
252 { "OPERAND_TYPE_REG16",
254 { "OPERAND_TYPE_REG32",
256 { "OPERAND_TYPE_REG64",
258 { "OPERAND_TYPE_IMM1",
260 { "OPERAND_TYPE_IMM8",
262 { "OPERAND_TYPE_IMM8S",
264 { "OPERAND_TYPE_IMM16",
266 { "OPERAND_TYPE_IMM32",
268 { "OPERAND_TYPE_IMM32S",
270 { "OPERAND_TYPE_IMM64",
272 { "OPERAND_TYPE_BASEINDEX",
274 { "OPERAND_TYPE_DISP8",
276 { "OPERAND_TYPE_DISP16",
278 { "OPERAND_TYPE_DISP32",
280 { "OPERAND_TYPE_DISP32S",
282 { "OPERAND_TYPE_DISP64",
284 { "OPERAND_TYPE_INOUTPORTREG",
286 { "OPERAND_TYPE_SHIFTCOUNT",
288 { "OPERAND_TYPE_CONTROL",
290 { "OPERAND_TYPE_TEST",
292 { "OPERAND_TYPE_DEBUG",
294 { "OPERAND_TYPE_FLOATREG",
296 { "OPERAND_TYPE_FLOATACC",
298 { "OPERAND_TYPE_SREG2",
300 { "OPERAND_TYPE_SREG3",
302 { "OPERAND_TYPE_ACC",
304 { "OPERAND_TYPE_JUMPABSOLUTE",
306 { "OPERAND_TYPE_REGMMX",
308 { "OPERAND_TYPE_REGXMM",
310 { "OPERAND_TYPE_REGYMM",
312 { "OPERAND_TYPE_REGZMM",
314 { "OPERAND_TYPE_REGMASK",
316 { "OPERAND_TYPE_ESSEG",
318 { "OPERAND_TYPE_ACC32",
320 { "OPERAND_TYPE_ACC64",
322 { "OPERAND_TYPE_INOUTPORTREG",
324 { "OPERAND_TYPE_REG16_INOUTPORTREG",
325 "Reg16|InOutPortReg" },
326 { "OPERAND_TYPE_DISP16_32",
328 { "OPERAND_TYPE_ANYDISP",
329 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
330 { "OPERAND_TYPE_IMM16_32",
332 { "OPERAND_TYPE_IMM16_32S",
334 { "OPERAND_TYPE_IMM16_32_32S",
335 "Imm16|Imm32|Imm32S" },
336 { "OPERAND_TYPE_IMM32_64",
338 { "OPERAND_TYPE_IMM32_32S_DISP32",
339 "Imm32|Imm32S|Disp32" },
340 { "OPERAND_TYPE_IMM64_DISP64",
342 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
343 "Imm32|Imm32S|Imm64|Disp32" },
344 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
345 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
346 { "OPERAND_TYPE_VEC_IMM4",
348 { "OPERAND_TYPE_REGBND",
350 { "OPERAND_TYPE_VEC_DISP8",
354 typedef struct bitfield
361 #define BITFIELD(n) { n, 0, #n }
363 static bitfield cpu_flags[] =
371 BITFIELD (CpuClflush),
373 BITFIELD (CpuSYSCALL),
378 BITFIELD (CpuFISTTP),
384 BITFIELD (CpuSSE4_1),
385 BITFIELD (CpuSSE4_2),
388 BITFIELD (CpuAVX512F),
389 BITFIELD (CpuAVX512CD),
390 BITFIELD (CpuAVX512ER),
391 BITFIELD (CpuAVX512PF),
392 BITFIELD (CpuAVX512VL),
393 BITFIELD (CpuAVX512DQ),
394 BITFIELD (CpuAVX512BW),
399 BITFIELD (Cpu3dnowA),
400 BITFIELD (CpuPadLock),
406 BITFIELD (CpuXsaveopt),
408 BITFIELD (CpuPCLMUL),
419 BITFIELD (CpuRdtscp),
420 BITFIELD (CpuFSGSBase),
427 BITFIELD (CpuINVPCID),
428 BITFIELD (CpuVMFUNC),
429 BITFIELD (CpuRDSEED),
431 BITFIELD (CpuPRFCHW),
435 BITFIELD (CpuClflushOpt),
436 BITFIELD (CpuXSAVES),
437 BITFIELD (CpuXSAVEC),
438 BITFIELD (CpuPREFETCHWT1),
441 BITFIELD (CpuPCOMMIT),
446 BITFIELD (CpuUnused),
450 static bitfield opcode_modifiers[] =
456 BITFIELD (ShortForm),
458 BITFIELD (JumpDword),
460 BITFIELD (JumpInterSegment),
467 BITFIELD (CheckRegSize),
468 BITFIELD (IgnoreSize),
469 BITFIELD (DefaultSize),
478 BITFIELD (BNDPrefixOk),
479 BITFIELD (IsLockable),
480 BITFIELD (RegKludge),
481 BITFIELD (FirstXmm0),
482 BITFIELD (Implicit1stXmm0),
483 BITFIELD (RepPrefixOk),
484 BITFIELD (HLEPrefixOk),
487 BITFIELD (AddrPrefixOp0),
496 BITFIELD (VexOpcode),
497 BITFIELD (VexSources),
498 BITFIELD (VexImmExt),
505 BITFIELD (Broadcast),
506 BITFIELD (StaticRounding),
508 BITFIELD (Disp8MemShift),
509 BITFIELD (NoDefMask),
511 BITFIELD (ATTMnemonic),
512 BITFIELD (ATTSyntax),
513 BITFIELD (IntelSyntax),
516 static bitfield operand_types[] =
535 BITFIELD (BaseIndex),
541 BITFIELD (InOutPortReg),
542 BITFIELD (ShiftCount),
550 BITFIELD (JumpAbsolute),
563 BITFIELD (Unspecified),
567 BITFIELD (Vec_Disp8),
573 static const char *filename;
576 compare (const void *x, const void *y)
578 const bitfield *xp = (const bitfield *) x;
579 const bitfield *yp = (const bitfield *) y;
580 return xp->position - yp->position;
584 fail (const char *message, ...)
588 va_start (args, message);
589 fprintf (stderr, _("%s: Error: "), program_name);
590 vfprintf (stderr, message, args);
596 process_copyright (FILE *fp)
598 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
599 /* Copyright (C) 2007-2014 Free Software Foundation, Inc.\n\
601 This file is part of the GNU opcodes library.\n\
603 This library is free software; you can redistribute it and/or modify\n\
604 it under the terms of the GNU General Public License as published by\n\
605 the Free Software Foundation; either version 3, or (at your option)\n\
606 any later version.\n\
608 It is distributed in the hope that it will be useful, but WITHOUT\n\
609 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
610 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
611 License for more details.\n\
613 You should have received a copy of the GNU General Public License\n\
614 along with this program; if not, write to the Free Software\n\
615 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
616 MA 02110-1301, USA. */\n");
619 /* Remove leading white spaces. */
622 remove_leading_whitespaces (char *str)
624 while (ISSPACE (*str))
629 /* Remove trailing white spaces. */
632 remove_trailing_whitespaces (char *str)
634 size_t last = strlen (str);
642 if (ISSPACE (str [last]))
650 /* Find next field separated by SEP and terminate it. Return a
651 pointer to the one after it. */
654 next_field (char *str, char sep, char **next, char *last)
658 p = remove_leading_whitespaces (str);
659 for (str = p; *str != sep && *str != '\0'; str++);
662 remove_trailing_whitespaces (p);
673 set_bitfield (const char *f, bitfield *array, int value,
674 unsigned int size, int lineno)
678 if (strcmp (f, "CpuFP") == 0)
680 set_bitfield("Cpu387", array, value, size, lineno);
681 set_bitfield("Cpu287", array, value, size, lineno);
684 else if (strcmp (f, "Mmword") == 0)
686 else if (strcmp (f, "Oword") == 0)
689 for (i = 0; i < size; i++)
690 if (strcasecmp (array[i].name, f) == 0)
692 array[i].value = value;
698 const char *v = strchr (f, '=');
705 for (i = 0; i < size; i++)
706 if (strncasecmp (array[i].name, f, n) == 0)
708 value = strtol (v + 1, &end, 0);
711 array[i].value = value;
720 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
722 fail (_("Unknown bitfield: %s\n"), f);
726 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
727 int macro, const char *comma, const char *indent)
731 fprintf (table, "%s{ { ", indent);
733 for (i = 0; i < size - 1; i++)
735 if (((i + 1) % 20) != 0)
736 fprintf (table, "%d, ", flags[i].value);
738 fprintf (table, "%d,", flags[i].value);
739 if (((i + 1) % 20) == 0)
741 /* We need \\ for macro. */
743 fprintf (table, " \\\n %s", indent);
745 fprintf (table, "\n %s", indent);
749 fprintf (table, "%d } }%s\n", flags[i].value, comma);
753 process_i386_cpu_flag (FILE *table, char *flag, int macro,
754 const char *comma, const char *indent,
757 char *str, *next, *last;
759 bitfield flags [ARRAY_SIZE (cpu_flags)];
761 /* Copy the default cpu flags. */
762 memcpy (flags, cpu_flags, sizeof (cpu_flags));
764 if (strcasecmp (flag, "unknown") == 0)
766 /* We turn on everything except for cpu64 in case of
767 CPU_UNKNOWN_FLAGS. */
768 for (i = 0; i < ARRAY_SIZE (flags); i++)
769 if (flags[i].position != Cpu64)
772 else if (flag[0] == '~')
774 last = flag + strlen (flag);
781 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
788 /* First we turn on everything except for cpu64. */
789 for (i = 0; i < ARRAY_SIZE (flags); i++)
790 if (flags[i].position != Cpu64)
793 /* Turn off selective bits. */
794 for (; next && next < last; )
796 str = next_field (next, '|', &next, last);
798 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
801 else if (strcmp (flag, "0"))
803 /* Turn on selective bits. */
804 last = flag + strlen (flag);
805 for (next = flag; next && next < last; )
807 str = next_field (next, '|', &next, last);
809 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
813 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
818 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
822 fprintf (table, " { ");
824 for (i = 0; i < size - 1; i++)
826 if (((i + 1) % 20) != 0)
827 fprintf (table, "%d, ", modifier[i].value);
829 fprintf (table, "%d,", modifier[i].value);
830 if (((i + 1) % 20) == 0)
831 fprintf (table, "\n ");
834 fprintf (table, "%d },\n", modifier[i].value);
838 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
840 char *str, *next, *last;
841 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
843 /* Copy the default opcode modifier. */
844 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
846 if (strcmp (mod, "0"))
848 last = mod + strlen (mod);
849 for (next = mod; next && next < last; )
851 str = next_field (next, '|', &next, last);
853 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
857 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
861 output_operand_type (FILE *table, bitfield *types, unsigned int size,
862 int macro, const char *indent)
866 fprintf (table, "{ { ");
868 for (i = 0; i < size - 1; i++)
870 if (((i + 1) % 20) != 0)
871 fprintf (table, "%d, ", types[i].value);
873 fprintf (table, "%d,", types[i].value);
874 if (((i + 1) % 20) == 0)
876 /* We need \\ for macro. */
878 fprintf (table, " \\\n%s", indent);
880 fprintf (table, "\n%s", indent);
884 fprintf (table, "%d } }", types[i].value);
888 process_i386_operand_type (FILE *table, char *op, int macro,
889 const char *indent, int lineno)
891 char *str, *next, *last;
892 bitfield types [ARRAY_SIZE (operand_types)];
894 /* Copy the default operand type. */
895 memcpy (types, operand_types, sizeof (types));
897 if (strcmp (op, "0"))
899 last = op + strlen (op);
900 for (next = op; next && next < last; )
902 str = next_field (next, '|', &next, last);
904 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
907 output_operand_type (table, types, ARRAY_SIZE (types), macro,
912 output_i386_opcode (FILE *table, const char *name, char *str,
913 char *last, int lineno)
916 char *operands, *base_opcode, *extension_opcode, *opcode_length;
917 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
919 /* Find number of operands. */
920 operands = next_field (str, ',', &str, last);
922 /* Find base_opcode. */
923 base_opcode = next_field (str, ',', &str, last);
925 /* Find extension_opcode. */
926 extension_opcode = next_field (str, ',', &str, last);
928 /* Find opcode_length. */
929 opcode_length = next_field (str, ',', &str, last);
931 /* Find cpu_flags. */
932 cpu_flags = next_field (str, ',', &str, last);
934 /* Find opcode_modifier. */
935 opcode_modifier = next_field (str, ',', &str, last);
937 /* Remove the first {. */
938 str = remove_leading_whitespaces (str);
941 str = remove_leading_whitespaces (str + 1);
945 /* There are at least "X}". */
949 /* Remove trailing white spaces and }. */
953 if (ISSPACE (str[i]) || str[i] == '}')
962 /* Find operand_types. */
963 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
967 operand_types [i] = NULL;
971 operand_types [i] = next_field (str, ',', &str, last);
972 if (*operand_types[i] == '0')
975 operand_types[i] = NULL;
980 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
981 name, operands, base_opcode, extension_opcode,
984 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
986 process_i386_opcode_modifier (table, opcode_modifier, lineno);
988 fprintf (table, " { ");
990 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
992 if (operand_types[i] == NULL || *operand_types[i] == '0')
995 process_i386_operand_type (table, "0", 0, "\t ", lineno);
1000 fprintf (table, ",\n ");
1002 process_i386_operand_type (table, operand_types[i], 0,
1005 fprintf (table, " } },\n");
1008 struct opcode_hash_entry
1010 struct opcode_hash_entry *next;
1016 /* Calculate the hash value of an opcode hash entry P. */
1019 opcode_hash_hash (const void *p)
1021 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1022 return htab_hash_string (entry->name);
1025 /* Compare a string Q against an opcode hash entry P. */
1028 opcode_hash_eq (const void *p, const void *q)
1030 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1031 const char *name = (const char *) q;
1032 return strcmp (name, entry->name) == 0;
1036 process_i386_opcodes (FILE *table)
1041 char *str, *p, *last, *name;
1042 struct opcode_hash_entry **hash_slot, **entry, *next;
1043 htab_t opcode_hash_table;
1044 struct opcode_hash_entry **opcode_array;
1045 unsigned int opcode_array_size = 1024;
1048 filename = "i386-opc.tbl";
1049 fp = fopen (filename, "r");
1052 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1056 opcode_array = (struct opcode_hash_entry **)
1057 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1059 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1060 opcode_hash_eq, NULL,
1063 fprintf (table, "\n/* i386 opcode table. */\n\n");
1064 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1066 /* Put everything on opcode array. */
1069 if (fgets (buf, sizeof (buf), fp) == NULL)
1074 p = remove_leading_whitespaces (buf);
1076 /* Skip comments. */
1077 str = strstr (p, "//");
1081 /* Remove trailing white spaces. */
1082 remove_trailing_whitespaces (p);
1087 /* Ignore comments. */
1095 last = p + strlen (p);
1098 name = next_field (p, ',', &str, last);
1100 /* Get the slot in hash table. */
1101 hash_slot = (struct opcode_hash_entry **)
1102 htab_find_slot_with_hash (opcode_hash_table, name,
1103 htab_hash_string (name),
1106 if (*hash_slot == NULL)
1108 /* It is the new one. Put it on opcode array. */
1109 if (i >= opcode_array_size)
1111 /* Grow the opcode array when needed. */
1112 opcode_array_size += 1024;
1113 opcode_array = (struct opcode_hash_entry **)
1114 xrealloc (opcode_array,
1115 sizeof (*opcode_array) * opcode_array_size);
1118 opcode_array[i] = (struct opcode_hash_entry *)
1119 xmalloc (sizeof (struct opcode_hash_entry));
1120 opcode_array[i]->next = NULL;
1121 opcode_array[i]->name = xstrdup (name);
1122 opcode_array[i]->opcode = xstrdup (str);
1123 opcode_array[i]->lineno = lineno;
1124 *hash_slot = opcode_array[i];
1129 /* Append it to the existing one. */
1131 while ((*entry) != NULL)
1132 entry = &(*entry)->next;
1133 *entry = (struct opcode_hash_entry *)
1134 xmalloc (sizeof (struct opcode_hash_entry));
1135 (*entry)->next = NULL;
1136 (*entry)->name = (*hash_slot)->name;
1137 (*entry)->opcode = xstrdup (str);
1138 (*entry)->lineno = lineno;
1142 /* Process opcode array. */
1143 for (j = 0; j < i; j++)
1145 for (next = opcode_array[j]; next; next = next->next)
1149 lineno = next->lineno;
1150 last = str + strlen (str);
1151 output_i386_opcode (table, name, str, last, lineno);
1157 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1159 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1161 process_i386_opcode_modifier (table, "0", -1);
1163 fprintf (table, " { ");
1164 process_i386_operand_type (table, "0", 0, "\t ", -1);
1165 fprintf (table, " } }\n");
1167 fprintf (table, "};\n");
1171 process_i386_registers (FILE *table)
1175 char *str, *p, *last;
1176 char *reg_name, *reg_type, *reg_flags, *reg_num;
1177 char *dw2_32_num, *dw2_64_num;
1180 filename = "i386-reg.tbl";
1181 fp = fopen (filename, "r");
1183 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1186 fprintf (table, "\n/* i386 register table. */\n\n");
1187 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1191 if (fgets (buf, sizeof (buf), fp) == NULL)
1196 p = remove_leading_whitespaces (buf);
1198 /* Skip comments. */
1199 str = strstr (p, "//");
1203 /* Remove trailing white spaces. */
1204 remove_trailing_whitespaces (p);
1209 fprintf (table, "%s\n", p);
1217 last = p + strlen (p);
1219 /* Find reg_name. */
1220 reg_name = next_field (p, ',', &str, last);
1222 /* Find reg_type. */
1223 reg_type = next_field (str, ',', &str, last);
1225 /* Find reg_flags. */
1226 reg_flags = next_field (str, ',', &str, last);
1229 reg_num = next_field (str, ',', &str, last);
1231 fprintf (table, " { \"%s\",\n ", reg_name);
1233 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1235 /* Find 32-bit Dwarf2 register number. */
1236 dw2_32_num = next_field (str, ',', &str, last);
1238 /* Find 64-bit Dwarf2 register number. */
1239 dw2_64_num = next_field (str, ',', &str, last);
1241 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1242 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1247 fprintf (table, "};\n");
1249 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1253 process_i386_initializers (void)
1256 FILE *fp = fopen ("i386-init.h", "w");
1260 fail (_("can't create i386-init.h, errno = %s\n"),
1263 process_copyright (fp);
1265 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1267 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1268 init = xstrdup (cpu_flag_init[i].init);
1269 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1273 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1275 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1276 init = xstrdup (operand_type_init[i].init);
1277 process_i386_operand_type (fp, init, 1, " ", -1);
1285 /* Program options. */
1286 #define OPTION_SRCDIR 200
1288 struct option long_options[] =
1290 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1291 {"debug", no_argument, NULL, 'd'},
1292 {"version", no_argument, NULL, 'V'},
1293 {"help", no_argument, NULL, 'h'},
1294 {0, no_argument, NULL, 0}
1298 print_version (void)
1300 printf ("%s: version 1.0\n", program_name);
1305 usage (FILE * stream, int status)
1307 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1313 main (int argc, char **argv)
1315 extern int chdir (char *);
1316 char *srcdir = NULL;
1320 program_name = *argv;
1321 xmalloc_set_program_name (program_name);
1323 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1348 if (chdir (srcdir) != 0)
1349 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1350 srcdir, xstrerror (errno));
1352 /* Check the unused bitfield in i386_cpu_flags. */
1354 c = CpuNumOfBits - CpuMax - 1;
1356 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1359 /* Check the unused bitfield in i386_operand_type. */
1361 c = OTNumOfBits - OTMax - 1;
1363 fail (_("%d unused bits in i386_operand_type.\n"), c);
1366 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1369 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1370 sizeof (opcode_modifiers [0]), compare);
1372 qsort (operand_types, ARRAY_SIZE (operand_types),
1373 sizeof (operand_types [0]), compare);
1375 table = fopen ("i386-tbl.h", "w");
1377 fail (_("can't create i386-tbl.h, errno = %s\n"),
1380 process_copyright (table);
1382 process_i386_opcodes (table);
1383 process_i386_registers (table);
1384 process_i386_initializers ();