1 /* Copyright (C) 2007-2016 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|CpuMWAITX" },
99 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuBMI|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_BTVER1_FLAGS",
101 "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" },
102 { "CPU_BTVER2_FLAGS",
103 "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" },
111 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
112 { "CPU_CLFLUSH_FLAGS",
116 { "CPU_SYSCALL_FLAGS",
123 "CpuMMX|CpuSSE|CpuSSE2" },
125 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
127 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
128 { "CPU_SSE4_1_FLAGS",
129 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
130 { "CPU_SSE4_2_FLAGS",
131 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
132 { "CPU_ANY_SSE_FLAGS",
133 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
140 { "CPU_XSAVEOPT_FLAGS",
143 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
144 { "CPU_PCLMUL_FLAGS",
145 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
147 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
149 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
151 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
162 { "CPU_RDTSCP_FLAGS",
166 { "CPU_FSGSBASE_FLAGS",
180 { "CPU_INVPCID_FLAGS",
182 { "CPU_VMFUNC_FLAGS",
186 { "CPU_3DNOWA_FLAGS",
187 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
188 { "CPU_PADLOCK_FLAGS",
193 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
197 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
199 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
200 { "CPU_AVX512F_FLAGS",
201 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
202 { "CPU_AVX512CD_FLAGS",
203 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
204 { "CPU_AVX512ER_FLAGS",
205 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
206 { "CPU_AVX512PF_FLAGS",
207 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
208 { "CPU_ANY_AVX_FLAGS",
209 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
215 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
216 { "CPU_IAMCU_COMPAT_FLAGS",
217 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuNo64|CpuNop" },
220 { "CPU_RDSEED_FLAGS",
222 { "CPU_PRFCHW_FLAGS",
230 { "CPU_CLFLUSHOPT_FLAGS",
232 { "CPU_XSAVES_FLAGS",
234 { "CPU_XSAVEC_FLAGS",
236 { "CPU_PREFETCHWT1_FLAGS",
240 { "CPU_AVX512DQ_FLAGS",
241 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512DQ" },
242 { "CPU_AVX512BW_FLAGS",
243 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512BW" },
244 { "CPU_AVX512VL_FLAGS",
245 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VL" },
248 { "CPU_PCOMMIT_FLAGS",
250 { "CPU_AVX512IFMA_FLAGS",
251 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512IFMA" },
252 { "CPU_AVX512VBMI_FLAGS",
253 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VBMI" },
254 { "CPU_CLZERO_FLAGS",
256 { "CPU_MWAITX_FLAGS",
262 static initializer operand_type_init[] =
264 { "OPERAND_TYPE_NONE",
266 { "OPERAND_TYPE_REG8",
268 { "OPERAND_TYPE_REG16",
270 { "OPERAND_TYPE_REG32",
272 { "OPERAND_TYPE_REG64",
274 { "OPERAND_TYPE_IMM1",
276 { "OPERAND_TYPE_IMM8",
278 { "OPERAND_TYPE_IMM8S",
280 { "OPERAND_TYPE_IMM16",
282 { "OPERAND_TYPE_IMM32",
284 { "OPERAND_TYPE_IMM32S",
286 { "OPERAND_TYPE_IMM64",
288 { "OPERAND_TYPE_BASEINDEX",
290 { "OPERAND_TYPE_DISP8",
292 { "OPERAND_TYPE_DISP16",
294 { "OPERAND_TYPE_DISP32",
296 { "OPERAND_TYPE_DISP32S",
298 { "OPERAND_TYPE_DISP64",
300 { "OPERAND_TYPE_INOUTPORTREG",
302 { "OPERAND_TYPE_SHIFTCOUNT",
304 { "OPERAND_TYPE_CONTROL",
306 { "OPERAND_TYPE_TEST",
308 { "OPERAND_TYPE_DEBUG",
310 { "OPERAND_TYPE_FLOATREG",
312 { "OPERAND_TYPE_FLOATACC",
314 { "OPERAND_TYPE_SREG2",
316 { "OPERAND_TYPE_SREG3",
318 { "OPERAND_TYPE_ACC",
320 { "OPERAND_TYPE_JUMPABSOLUTE",
322 { "OPERAND_TYPE_REGMMX",
324 { "OPERAND_TYPE_REGXMM",
326 { "OPERAND_TYPE_REGYMM",
328 { "OPERAND_TYPE_REGZMM",
330 { "OPERAND_TYPE_REGMASK",
332 { "OPERAND_TYPE_ESSEG",
334 { "OPERAND_TYPE_ACC32",
336 { "OPERAND_TYPE_ACC64",
338 { "OPERAND_TYPE_INOUTPORTREG",
340 { "OPERAND_TYPE_REG16_INOUTPORTREG",
341 "Reg16|InOutPortReg" },
342 { "OPERAND_TYPE_DISP16_32",
344 { "OPERAND_TYPE_ANYDISP",
345 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
346 { "OPERAND_TYPE_IMM16_32",
348 { "OPERAND_TYPE_IMM16_32S",
350 { "OPERAND_TYPE_IMM16_32_32S",
351 "Imm16|Imm32|Imm32S" },
352 { "OPERAND_TYPE_IMM32_64",
354 { "OPERAND_TYPE_IMM32_32S_DISP32",
355 "Imm32|Imm32S|Disp32" },
356 { "OPERAND_TYPE_IMM64_DISP64",
358 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
359 "Imm32|Imm32S|Imm64|Disp32" },
360 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
361 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
362 { "OPERAND_TYPE_VEC_IMM4",
364 { "OPERAND_TYPE_REGBND",
366 { "OPERAND_TYPE_VEC_DISP8",
370 typedef struct bitfield
377 #define BITFIELD(n) { n, 0, #n }
379 static bitfield cpu_flags[] =
387 BITFIELD (CpuClflush),
389 BITFIELD (CpuSYSCALL),
394 BITFIELD (CpuFISTTP),
400 BITFIELD (CpuSSE4_1),
401 BITFIELD (CpuSSE4_2),
404 BITFIELD (CpuAVX512F),
405 BITFIELD (CpuAVX512CD),
406 BITFIELD (CpuAVX512ER),
407 BITFIELD (CpuAVX512PF),
408 BITFIELD (CpuAVX512VL),
409 BITFIELD (CpuAVX512DQ),
410 BITFIELD (CpuAVX512BW),
416 BITFIELD (Cpu3dnowA),
417 BITFIELD (CpuPadLock),
423 BITFIELD (CpuXsaveopt),
425 BITFIELD (CpuPCLMUL),
436 BITFIELD (CpuRdtscp),
437 BITFIELD (CpuFSGSBase),
444 BITFIELD (CpuINVPCID),
445 BITFIELD (CpuVMFUNC),
446 BITFIELD (CpuRDSEED),
448 BITFIELD (CpuPRFCHW),
452 BITFIELD (CpuClflushOpt),
453 BITFIELD (CpuXSAVES),
454 BITFIELD (CpuXSAVEC),
455 BITFIELD (CpuPREFETCHWT1),
458 BITFIELD (CpuPCOMMIT),
462 BITFIELD (CpuAVX512IFMA),
463 BITFIELD (CpuAVX512VBMI),
464 BITFIELD (CpuMWAITX),
465 BITFIELD (CpuCLZERO),
468 BITFIELD (CpuIntel64),
470 BITFIELD (CpuUnused),
474 static bitfield opcode_modifiers[] =
480 BITFIELD (ShortForm),
482 BITFIELD (JumpDword),
484 BITFIELD (JumpInterSegment),
491 BITFIELD (CheckRegSize),
492 BITFIELD (IgnoreSize),
493 BITFIELD (DefaultSize),
502 BITFIELD (BNDPrefixOk),
503 BITFIELD (IsLockable),
504 BITFIELD (RegKludge),
505 BITFIELD (FirstXmm0),
506 BITFIELD (Implicit1stXmm0),
507 BITFIELD (RepPrefixOk),
508 BITFIELD (HLEPrefixOk),
511 BITFIELD (AddrPrefixOp0),
520 BITFIELD (VexOpcode),
521 BITFIELD (VexSources),
522 BITFIELD (VexImmExt),
529 BITFIELD (Broadcast),
530 BITFIELD (StaticRounding),
532 BITFIELD (Disp8MemShift),
533 BITFIELD (NoDefMask),
535 BITFIELD (ATTMnemonic),
536 BITFIELD (ATTSyntax),
537 BITFIELD (IntelSyntax),
540 static bitfield operand_types[] =
559 BITFIELD (BaseIndex),
565 BITFIELD (InOutPortReg),
566 BITFIELD (ShiftCount),
574 BITFIELD (JumpAbsolute),
587 BITFIELD (Unspecified),
591 BITFIELD (Vec_Disp8),
597 static const char *filename;
600 compare (const void *x, const void *y)
602 const bitfield *xp = (const bitfield *) x;
603 const bitfield *yp = (const bitfield *) y;
604 return xp->position - yp->position;
608 fail (const char *message, ...)
612 va_start (args, message);
613 fprintf (stderr, _("%s: Error: "), program_name);
614 vfprintf (stderr, message, args);
620 process_copyright (FILE *fp)
622 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
623 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.\n\
625 This file is part of the GNU opcodes library.\n\
627 This library is free software; you can redistribute it and/or modify\n\
628 it under the terms of the GNU General Public License as published by\n\
629 the Free Software Foundation; either version 3, or (at your option)\n\
630 any later version.\n\
632 It is distributed in the hope that it will be useful, but WITHOUT\n\
633 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
634 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
635 License for more details.\n\
637 You should have received a copy of the GNU General Public License\n\
638 along with this program; if not, write to the Free Software\n\
639 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
640 MA 02110-1301, USA. */\n");
643 /* Remove leading white spaces. */
646 remove_leading_whitespaces (char *str)
648 while (ISSPACE (*str))
653 /* Remove trailing white spaces. */
656 remove_trailing_whitespaces (char *str)
658 size_t last = strlen (str);
666 if (ISSPACE (str [last]))
674 /* Find next field separated by SEP and terminate it. Return a
675 pointer to the one after it. */
678 next_field (char *str, char sep, char **next, char *last)
682 p = remove_leading_whitespaces (str);
683 for (str = p; *str != sep && *str != '\0'; str++);
686 remove_trailing_whitespaces (p);
697 set_bitfield (const char *f, bitfield *array, int value,
698 unsigned int size, int lineno)
702 if (strcmp (f, "CpuFP") == 0)
704 set_bitfield("Cpu387", array, value, size, lineno);
705 set_bitfield("Cpu287", array, value, size, lineno);
708 else if (strcmp (f, "Mmword") == 0)
710 else if (strcmp (f, "Oword") == 0)
713 for (i = 0; i < size; i++)
714 if (strcasecmp (array[i].name, f) == 0)
716 array[i].value = value;
722 const char *v = strchr (f, '=');
729 for (i = 0; i < size; i++)
730 if (strncasecmp (array[i].name, f, n) == 0)
732 value = strtol (v + 1, &end, 0);
735 array[i].value = value;
744 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
746 fail (_("Unknown bitfield: %s\n"), f);
750 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
751 int macro, const char *comma, const char *indent)
755 fprintf (table, "%s{ { ", indent);
757 for (i = 0; i < size - 1; i++)
759 if (((i + 1) % 20) != 0)
760 fprintf (table, "%d, ", flags[i].value);
762 fprintf (table, "%d,", flags[i].value);
763 if (((i + 1) % 20) == 0)
765 /* We need \\ for macro. */
767 fprintf (table, " \\\n %s", indent);
769 fprintf (table, "\n %s", indent);
773 fprintf (table, "%d } }%s\n", flags[i].value, comma);
777 process_i386_cpu_flag (FILE *table, char *flag, int macro,
778 const char *comma, const char *indent,
781 char *str, *next, *last;
783 bitfield flags [ARRAY_SIZE (cpu_flags)];
785 /* Copy the default cpu flags. */
786 memcpy (flags, cpu_flags, sizeof (cpu_flags));
788 if (strcasecmp (flag, "unknown") == 0)
790 /* We turn on everything except for cpu64 in case of
791 CPU_UNKNOWN_FLAGS. */
792 for (i = 0; i < ARRAY_SIZE (flags); i++)
793 if (flags[i].position != Cpu64)
796 else if (flag[0] == '~')
798 last = flag + strlen (flag);
805 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
812 /* First we turn on everything except for cpu64. */
813 for (i = 0; i < ARRAY_SIZE (flags); i++)
814 if (flags[i].position != Cpu64)
817 /* Turn off selective bits. */
818 for (; next && next < last; )
820 str = next_field (next, '|', &next, last);
822 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
825 else if (strcmp (flag, "0"))
827 /* Turn on selective bits. */
828 last = flag + strlen (flag);
829 for (next = flag; next && next < last; )
831 str = next_field (next, '|', &next, last);
833 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
837 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
842 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
846 fprintf (table, " { ");
848 for (i = 0; i < size - 1; i++)
850 if (((i + 1) % 20) != 0)
851 fprintf (table, "%d, ", modifier[i].value);
853 fprintf (table, "%d,", modifier[i].value);
854 if (((i + 1) % 20) == 0)
855 fprintf (table, "\n ");
858 fprintf (table, "%d },\n", modifier[i].value);
862 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
864 char *str, *next, *last;
865 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
867 /* Copy the default opcode modifier. */
868 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
870 if (strcmp (mod, "0"))
872 last = mod + strlen (mod);
873 for (next = mod; next && next < last; )
875 str = next_field (next, '|', &next, last);
877 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
881 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
885 output_operand_type (FILE *table, bitfield *types, unsigned int size,
886 int macro, const char *indent)
890 fprintf (table, "{ { ");
892 for (i = 0; i < size - 1; i++)
894 if (((i + 1) % 20) != 0)
895 fprintf (table, "%d, ", types[i].value);
897 fprintf (table, "%d,", types[i].value);
898 if (((i + 1) % 20) == 0)
900 /* We need \\ for macro. */
902 fprintf (table, " \\\n%s", indent);
904 fprintf (table, "\n%s", indent);
908 fprintf (table, "%d } }", types[i].value);
912 process_i386_operand_type (FILE *table, char *op, int macro,
913 const char *indent, int lineno)
915 char *str, *next, *last;
916 bitfield types [ARRAY_SIZE (operand_types)];
918 /* Copy the default operand type. */
919 memcpy (types, operand_types, sizeof (types));
921 if (strcmp (op, "0"))
923 last = op + strlen (op);
924 for (next = op; next && next < last; )
926 str = next_field (next, '|', &next, last);
928 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
931 output_operand_type (table, types, ARRAY_SIZE (types), macro,
936 output_i386_opcode (FILE *table, const char *name, char *str,
937 char *last, int lineno)
940 char *operands, *base_opcode, *extension_opcode, *opcode_length;
941 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
943 /* Find number of operands. */
944 operands = next_field (str, ',', &str, last);
946 /* Find base_opcode. */
947 base_opcode = next_field (str, ',', &str, last);
949 /* Find extension_opcode. */
950 extension_opcode = next_field (str, ',', &str, last);
952 /* Find opcode_length. */
953 opcode_length = next_field (str, ',', &str, last);
955 /* Find cpu_flags. */
956 cpu_flags = next_field (str, ',', &str, last);
958 /* Find opcode_modifier. */
959 opcode_modifier = next_field (str, ',', &str, last);
961 /* Remove the first {. */
962 str = remove_leading_whitespaces (str);
965 str = remove_leading_whitespaces (str + 1);
969 /* There are at least "X}". */
973 /* Remove trailing white spaces and }. */
977 if (ISSPACE (str[i]) || str[i] == '}')
986 /* Find operand_types. */
987 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
991 operand_types [i] = NULL;
995 operand_types [i] = next_field (str, ',', &str, last);
996 if (*operand_types[i] == '0')
999 operand_types[i] = NULL;
1004 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1005 name, operands, base_opcode, extension_opcode,
1008 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1010 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1012 fprintf (table, " { ");
1014 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1016 if (operand_types[i] == NULL || *operand_types[i] == '0')
1019 process_i386_operand_type (table, "0", 0, "\t ", lineno);
1024 fprintf (table, ",\n ");
1026 process_i386_operand_type (table, operand_types[i], 0,
1029 fprintf (table, " } },\n");
1032 struct opcode_hash_entry
1034 struct opcode_hash_entry *next;
1040 /* Calculate the hash value of an opcode hash entry P. */
1043 opcode_hash_hash (const void *p)
1045 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1046 return htab_hash_string (entry->name);
1049 /* Compare a string Q against an opcode hash entry P. */
1052 opcode_hash_eq (const void *p, const void *q)
1054 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1055 const char *name = (const char *) q;
1056 return strcmp (name, entry->name) == 0;
1060 process_i386_opcodes (FILE *table)
1065 char *str, *p, *last, *name;
1066 struct opcode_hash_entry **hash_slot, **entry, *next;
1067 htab_t opcode_hash_table;
1068 struct opcode_hash_entry **opcode_array;
1069 unsigned int opcode_array_size = 1024;
1072 filename = "i386-opc.tbl";
1073 fp = fopen (filename, "r");
1076 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1080 opcode_array = (struct opcode_hash_entry **)
1081 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1083 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1084 opcode_hash_eq, NULL,
1087 fprintf (table, "\n/* i386 opcode table. */\n\n");
1088 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1090 /* Put everything on opcode array. */
1093 if (fgets (buf, sizeof (buf), fp) == NULL)
1098 p = remove_leading_whitespaces (buf);
1100 /* Skip comments. */
1101 str = strstr (p, "//");
1105 /* Remove trailing white spaces. */
1106 remove_trailing_whitespaces (p);
1111 /* Ignore comments. */
1119 last = p + strlen (p);
1122 name = next_field (p, ',', &str, last);
1124 /* Get the slot in hash table. */
1125 hash_slot = (struct opcode_hash_entry **)
1126 htab_find_slot_with_hash (opcode_hash_table, name,
1127 htab_hash_string (name),
1130 if (*hash_slot == NULL)
1132 /* It is the new one. Put it on opcode array. */
1133 if (i >= opcode_array_size)
1135 /* Grow the opcode array when needed. */
1136 opcode_array_size += 1024;
1137 opcode_array = (struct opcode_hash_entry **)
1138 xrealloc (opcode_array,
1139 sizeof (*opcode_array) * opcode_array_size);
1142 opcode_array[i] = (struct opcode_hash_entry *)
1143 xmalloc (sizeof (struct opcode_hash_entry));
1144 opcode_array[i]->next = NULL;
1145 opcode_array[i]->name = xstrdup (name);
1146 opcode_array[i]->opcode = xstrdup (str);
1147 opcode_array[i]->lineno = lineno;
1148 *hash_slot = opcode_array[i];
1153 /* Append it to the existing one. */
1155 while ((*entry) != NULL)
1156 entry = &(*entry)->next;
1157 *entry = (struct opcode_hash_entry *)
1158 xmalloc (sizeof (struct opcode_hash_entry));
1159 (*entry)->next = NULL;
1160 (*entry)->name = (*hash_slot)->name;
1161 (*entry)->opcode = xstrdup (str);
1162 (*entry)->lineno = lineno;
1166 /* Process opcode array. */
1167 for (j = 0; j < i; j++)
1169 for (next = opcode_array[j]; next; next = next->next)
1173 lineno = next->lineno;
1174 last = str + strlen (str);
1175 output_i386_opcode (table, name, str, last, lineno);
1181 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1183 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1185 process_i386_opcode_modifier (table, "0", -1);
1187 fprintf (table, " { ");
1188 process_i386_operand_type (table, "0", 0, "\t ", -1);
1189 fprintf (table, " } }\n");
1191 fprintf (table, "};\n");
1195 process_i386_registers (FILE *table)
1199 char *str, *p, *last;
1200 char *reg_name, *reg_type, *reg_flags, *reg_num;
1201 char *dw2_32_num, *dw2_64_num;
1204 filename = "i386-reg.tbl";
1205 fp = fopen (filename, "r");
1207 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1210 fprintf (table, "\n/* i386 register table. */\n\n");
1211 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1215 if (fgets (buf, sizeof (buf), fp) == NULL)
1220 p = remove_leading_whitespaces (buf);
1222 /* Skip comments. */
1223 str = strstr (p, "//");
1227 /* Remove trailing white spaces. */
1228 remove_trailing_whitespaces (p);
1233 fprintf (table, "%s\n", p);
1241 last = p + strlen (p);
1243 /* Find reg_name. */
1244 reg_name = next_field (p, ',', &str, last);
1246 /* Find reg_type. */
1247 reg_type = next_field (str, ',', &str, last);
1249 /* Find reg_flags. */
1250 reg_flags = next_field (str, ',', &str, last);
1253 reg_num = next_field (str, ',', &str, last);
1255 fprintf (table, " { \"%s\",\n ", reg_name);
1257 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1259 /* Find 32-bit Dwarf2 register number. */
1260 dw2_32_num = next_field (str, ',', &str, last);
1262 /* Find 64-bit Dwarf2 register number. */
1263 dw2_64_num = next_field (str, ',', &str, last);
1265 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1266 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1271 fprintf (table, "};\n");
1273 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1277 process_i386_initializers (void)
1280 FILE *fp = fopen ("i386-init.h", "w");
1284 fail (_("can't create i386-init.h, errno = %s\n"),
1287 process_copyright (fp);
1289 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1291 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1292 init = xstrdup (cpu_flag_init[i].init);
1293 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1297 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1299 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1300 init = xstrdup (operand_type_init[i].init);
1301 process_i386_operand_type (fp, init, 1, " ", -1);
1309 /* Program options. */
1310 #define OPTION_SRCDIR 200
1312 struct option long_options[] =
1314 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1315 {"debug", no_argument, NULL, 'd'},
1316 {"version", no_argument, NULL, 'V'},
1317 {"help", no_argument, NULL, 'h'},
1318 {0, no_argument, NULL, 0}
1322 print_version (void)
1324 printf ("%s: version 1.0\n", program_name);
1329 usage (FILE * stream, int status)
1331 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1337 main (int argc, char **argv)
1339 extern int chdir (char *);
1340 char *srcdir = NULL;
1344 program_name = *argv;
1345 xmalloc_set_program_name (program_name);
1347 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1372 if (chdir (srcdir) != 0)
1373 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1374 srcdir, xstrerror (errno));
1376 /* Check the unused bitfield in i386_cpu_flags. */
1378 c = CpuNumOfBits - CpuMax - 1;
1380 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1383 /* Check the unused bitfield in i386_operand_type. */
1385 c = OTNumOfBits - OTMax - 1;
1387 fail (_("%d unused bits in i386_operand_type.\n"), c);
1390 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1393 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1394 sizeof (opcode_modifiers [0]), compare);
1396 qsort (operand_types, ARRAY_SIZE (operand_types),
1397 sizeof (operand_types [0]), compare);
1399 table = fopen ("i386-tbl.h", "w");
1401 fail (_("can't create i386-tbl.h, errno = %s\n"),
1404 process_copyright (table);
1406 process_i386_opcodes (table);
1407 process_i386_registers (table);
1408 process_i386_initializers ();