1 /* Copyright (C) 2007-2022 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 /* Build-time checks are preferrable over runtime ones. Use this construct
34 in preference where possible. */
35 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
37 static const char *program_name = NULL;
40 typedef struct initializer
46 static initializer cpu_flag_init[] =
48 { "CPU_UNKNOWN_FLAGS",
49 "~(CpuL1OM|CpuK1OM)" },
50 { "CPU_GENERIC32_FLAGS",
51 "Cpu186|Cpu286|Cpu386" },
52 { "CPU_GENERIC64_FLAGS",
53 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
59 "CPU_I186_FLAGS|Cpu286" },
61 "CPU_I286_FLAGS|Cpu386" },
63 "CPU_I386_FLAGS|Cpu486" },
65 "CPU_I486_FLAGS|Cpu387|Cpu586" },
67 "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
68 { "CPU_PENTIUMPRO_FLAGS",
69 "CPU_I686_FLAGS|CpuNop" },
71 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
73 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
75 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
77 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
79 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
81 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
83 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
87 "CPU_K6_FLAGS|Cpu3dnow" },
89 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
91 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
92 { "CPU_AMDFAM10_FLAGS",
93 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuLZCNT|CpuPOPCNT" },
95 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuLZCNT|CpuPOPCNT|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW" },
97 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
99 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
100 { "CPU_BDVER4_FLAGS",
101 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
102 { "CPU_ZNVER1_FLAGS",
103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
104 { "CPU_ZNVER2_FLAGS",
105 "CPU_ZNVER1_FLAGS|CpuCLWB|CpuRDPID|CpuRDPRU|CpuMCOMMIT|CpuWBNOINVD" },
106 { "CPU_ZNVER3_FLAGS",
107 "CPU_ZNVER2_FLAGS|CpuINVLPGB|CpuTLBSYNC|CpuVAES|CpuVPCLMULQDQ|CpuINVPCID|CpuSNP|CpuOSPKE" },
108 { "CPU_BTVER1_FLAGS",
109 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
110 { "CPU_BTVER2_FLAGS",
111 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
119 "CPU_387_FLAGS|Cpu687" },
124 { "CPU_CLFLUSH_FLAGS",
128 { "CPU_SYSCALL_FLAGS",
135 "CPU_SSE_FLAGS|CpuSSE2" },
137 "CPU_SSE2_FLAGS|CpuSSE3" },
139 "CPU_SSE3_FLAGS|CpuSSSE3" },
140 { "CPU_SSE4_1_FLAGS",
141 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
142 { "CPU_SSE4_2_FLAGS",
143 "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
150 { "CPU_XSAVEOPT_FLAGS",
151 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
153 "CPU_SSE2_FLAGS|CpuAES" },
154 { "CPU_PCLMUL_FLAGS",
155 "CPU_SSE2_FLAGS|CpuPCLMUL" },
157 "CPU_AVX_FLAGS|CpuFMA" },
159 "CPU_AVX_FLAGS|CpuFMA4" },
161 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
163 "CPU_XSAVE_FLAGS|CpuLWP" },
172 { "CPU_RDTSCP_FLAGS",
176 { "CPU_FSGSBASE_FLAGS",
181 "CPU_AVX_FLAGS|CpuF16C" },
186 { "CPU_POPCNT_FLAGS",
192 { "CPU_INVPCID_FLAGS",
194 { "CPU_VMFUNC_FLAGS",
197 "CPU_MMX_FLAGS|Cpu3dnow" },
198 { "CPU_3DNOWA_FLAGS",
199 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
200 { "CPU_PADLOCK_FLAGS",
205 "CPU_SSE3_FLAGS|CpuSSE4a" },
207 "CpuLZCNT|CpuPOPCNT" },
209 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
211 "CPU_AVX_FLAGS|CpuAVX2" },
212 { "CPU_AVX_VNNI_FLAGS",
213 "CPU_AVX2_FLAGS|CpuAVX_VNNI" },
214 { "CPU_AVX512F_FLAGS",
215 "CPU_AVX2_FLAGS|CpuAVX512F" },
216 { "CPU_AVX512CD_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
218 { "CPU_AVX512ER_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
220 { "CPU_AVX512PF_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
222 { "CPU_AVX512DQ_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
224 { "CPU_AVX512BW_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
226 { "CPU_AVX512VL_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
228 { "CPU_AVX512IFMA_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
230 { "CPU_AVX512VBMI_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
232 { "CPU_AVX512_4FMAPS_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
234 { "CPU_AVX512_4VNNIW_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
236 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
238 { "CPU_AVX512_VBMI2_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
240 { "CPU_AVX512_VNNI_FLAGS",
241 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
242 { "CPU_AVX512_BITALG_FLAGS",
243 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
244 { "CPU_AVX512_BF16_FLAGS",
245 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
246 { "CPU_AVX512_FP16_FLAGS",
247 "CPU_AVX512BW_FLAGS|CpuAVX512_FP16" },
253 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
256 { "CPU_RDSEED_FLAGS",
258 { "CPU_PRFCHW_FLAGS",
263 "CPU_XSAVE_FLAGS|CpuMPX" },
265 "CPU_SSE2_FLAGS|CpuSHA" },
266 { "CPU_CLFLUSHOPT_FLAGS",
268 { "CPU_XSAVES_FLAGS",
269 "CPU_XSAVE_FLAGS|CpuXSAVES" },
270 { "CPU_XSAVEC_FLAGS",
271 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
272 { "CPU_PREFETCHWT1_FLAGS",
278 { "CPU_CLZERO_FLAGS",
280 { "CPU_MWAITX_FLAGS",
283 "CPU_XSAVE_FLAGS|CpuOSPKE" },
286 { "CPU_PTWRITE_FLAGS",
296 { "CPU_VPCLMULQDQ_FLAGS",
298 { "CPU_WBNOINVD_FLAGS",
300 { "CPU_PCONFIG_FLAGS",
302 { "CPU_WAITPKG_FLAGS",
306 { "CPU_CLDEMOTE_FLAGS",
308 { "CPU_AMX_INT8_FLAGS",
310 { "CPU_AMX_BF16_FLAGS",
312 { "CPU_AMX_TILE_FLAGS",
314 { "CPU_MOVDIRI_FLAGS",
316 { "CPU_MOVDIR64B_FLAGS",
318 { "CPU_ENQCMD_FLAGS",
320 { "CPU_SERIALIZE_FLAGS",
322 { "CPU_AVX512_VP2INTERSECT_FLAGS",
323 "CpuAVX512_VP2INTERSECT" },
328 { "CPU_MCOMMIT_FLAGS",
330 { "CPU_SEV_ES_FLAGS",
332 { "CPU_TSXLDTRK_FLAGS",
336 { "CPU_WIDEKL_FLAGS",
338 { "CPU_HRESET_FLAGS",
340 { "CPU_INVLPGB_FLAGS",
342 { "CPU_TLBSYNC_FLAGS",
346 { "CPU_ANY_X87_FLAGS",
347 "CPU_ANY_287_FLAGS|Cpu8087" },
348 { "CPU_ANY_287_FLAGS",
349 "CPU_ANY_387_FLAGS|Cpu287" },
350 { "CPU_ANY_387_FLAGS",
351 "CPU_ANY_687_FLAGS|Cpu387" },
352 { "CPU_ANY_687_FLAGS",
353 "Cpu687|CpuFISTTP" },
354 { "CPU_ANY_CMOV_FLAGS",
356 { "CPU_ANY_FXSR_FLAGS",
358 { "CPU_ANY_MMX_FLAGS",
359 "CPU_3DNOWA_FLAGS" },
360 { "CPU_ANY_SSE_FLAGS",
361 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
362 { "CPU_ANY_SSE2_FLAGS",
363 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
364 { "CPU_ANY_SSE3_FLAGS",
365 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
366 { "CPU_ANY_SSSE3_FLAGS",
367 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
368 { "CPU_ANY_SSE4_1_FLAGS",
369 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
370 { "CPU_ANY_SSE4_2_FLAGS",
372 { "CPU_ANY_SSE4A_FLAGS",
374 { "CPU_ANY_AVX_FLAGS",
375 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
376 { "CPU_ANY_AVX2_FLAGS",
377 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
378 { "CPU_ANY_AVX512F_FLAGS",
379 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CPU_ANY_AVX512BW_FLAGS|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
380 { "CPU_ANY_AVX512CD_FLAGS",
382 { "CPU_ANY_AVX512ER_FLAGS",
384 { "CPU_ANY_AVX512PF_FLAGS",
386 { "CPU_ANY_AVX512DQ_FLAGS",
388 { "CPU_ANY_AVX512BW_FLAGS",
389 "CpuAVX512BW|CPU_ANY_AVX512_FP16_FLAGS" },
390 { "CPU_ANY_AVX512VL_FLAGS",
392 { "CPU_ANY_AVX512IFMA_FLAGS",
394 { "CPU_ANY_AVX512VBMI_FLAGS",
396 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
397 "CpuAVX512_4FMAPS" },
398 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
399 "CpuAVX512_4VNNIW" },
400 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
401 "CpuAVX512_VPOPCNTDQ" },
402 { "CPU_ANY_IBT_FLAGS",
404 { "CPU_ANY_SHSTK_FLAGS",
406 { "CPU_ANY_AVX512_VBMI2_FLAGS",
408 { "CPU_ANY_AVX512_VNNI_FLAGS",
410 { "CPU_ANY_AVX512_BITALG_FLAGS",
411 "CpuAVX512_BITALG" },
412 { "CPU_ANY_AVX512_BF16_FLAGS",
414 { "CPU_ANY_AMX_INT8_FLAGS",
416 { "CPU_ANY_AMX_BF16_FLAGS",
418 { "CPU_ANY_AMX_TILE_FLAGS",
419 "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" },
420 { "CPU_ANY_AVX_VNNI_FLAGS",
422 { "CPU_ANY_MOVDIRI_FLAGS",
424 { "CPU_ANY_UINTR_FLAGS",
426 { "CPU_ANY_MOVDIR64B_FLAGS",
428 { "CPU_ANY_ENQCMD_FLAGS",
430 { "CPU_ANY_SERIALIZE_FLAGS",
432 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
433 "CpuAVX512_VP2INTERSECT" },
434 { "CPU_ANY_TDX_FLAGS",
436 { "CPU_ANY_TSXLDTRK_FLAGS",
438 { "CPU_ANY_KL_FLAGS",
440 { "CPU_ANY_WIDEKL_FLAGS",
442 { "CPU_ANY_HRESET_FLAGS",
444 { "CPU_ANY_AVX512_FP16_FLAGS",
448 static initializer operand_type_init[] =
450 { "OPERAND_TYPE_NONE",
452 { "OPERAND_TYPE_REG8",
454 { "OPERAND_TYPE_REG16",
456 { "OPERAND_TYPE_REG32",
458 { "OPERAND_TYPE_REG64",
460 { "OPERAND_TYPE_IMM1",
462 { "OPERAND_TYPE_IMM8",
464 { "OPERAND_TYPE_IMM8S",
466 { "OPERAND_TYPE_IMM16",
468 { "OPERAND_TYPE_IMM32",
470 { "OPERAND_TYPE_IMM32S",
472 { "OPERAND_TYPE_IMM64",
474 { "OPERAND_TYPE_BASEINDEX",
476 { "OPERAND_TYPE_DISP8",
478 { "OPERAND_TYPE_DISP16",
480 { "OPERAND_TYPE_DISP32",
482 { "OPERAND_TYPE_DISP32S",
484 { "OPERAND_TYPE_DISP64",
486 { "OPERAND_TYPE_INOUTPORTREG",
487 "Instance=RegD|Word" },
488 { "OPERAND_TYPE_SHIFTCOUNT",
489 "Instance=RegC|Byte" },
490 { "OPERAND_TYPE_CONTROL",
492 { "OPERAND_TYPE_TEST",
494 { "OPERAND_TYPE_DEBUG",
496 { "OPERAND_TYPE_FLOATREG",
498 { "OPERAND_TYPE_FLOATACC",
499 "Instance=Accum|Tbyte" },
500 { "OPERAND_TYPE_SREG",
502 { "OPERAND_TYPE_REGMMX",
504 { "OPERAND_TYPE_REGXMM",
505 "Class=RegSIMD|Xmmword" },
506 { "OPERAND_TYPE_REGYMM",
507 "Class=RegSIMD|Ymmword" },
508 { "OPERAND_TYPE_REGZMM",
509 "Class=RegSIMD|Zmmword" },
510 { "OPERAND_TYPE_REGTMM",
511 "Class=RegSIMD|Tmmword" },
512 { "OPERAND_TYPE_REGMASK",
514 { "OPERAND_TYPE_REGBND",
516 { "OPERAND_TYPE_ACC8",
517 "Instance=Accum|Byte" },
518 { "OPERAND_TYPE_ACC16",
519 "Instance=Accum|Word" },
520 { "OPERAND_TYPE_ACC32",
521 "Instance=Accum|Dword" },
522 { "OPERAND_TYPE_ACC64",
523 "Instance=Accum|Qword" },
524 { "OPERAND_TYPE_DISP16_32",
526 { "OPERAND_TYPE_ANYDISP",
527 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
528 { "OPERAND_TYPE_IMM16_32",
530 { "OPERAND_TYPE_IMM16_32S",
532 { "OPERAND_TYPE_IMM16_32_32S",
533 "Imm16|Imm32|Imm32S" },
534 { "OPERAND_TYPE_IMM32_64",
536 { "OPERAND_TYPE_IMM32_32S_DISP32",
537 "Imm32|Imm32S|Disp32" },
538 { "OPERAND_TYPE_IMM64_DISP64",
540 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
541 "Imm32|Imm32S|Imm64|Disp32" },
542 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
543 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
544 { "OPERAND_TYPE_ANYIMM",
545 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
548 typedef struct bitfield
555 #define BITFIELD(n) { n, 0, #n }
557 static bitfield cpu_flags[] =
567 BITFIELD (CpuClflush),
569 BITFIELD (CpuSYSCALL),
574 BITFIELD (CpuFISTTP),
580 BITFIELD (CpuSSE4_1),
581 BITFIELD (CpuSSE4_2),
584 BITFIELD (CpuAVX512F),
585 BITFIELD (CpuAVX512CD),
586 BITFIELD (CpuAVX512ER),
587 BITFIELD (CpuAVX512PF),
588 BITFIELD (CpuAVX512VL),
589 BITFIELD (CpuAVX512DQ),
590 BITFIELD (CpuAVX512BW),
596 BITFIELD (Cpu3dnowA),
597 BITFIELD (CpuPadLock),
602 BITFIELD (CpuXsaveopt),
604 BITFIELD (CpuPCLMUL),
615 BITFIELD (CpuRdtscp),
616 BITFIELD (CpuFSGSBase),
621 BITFIELD (CpuPOPCNT),
624 BITFIELD (CpuINVPCID),
625 BITFIELD (CpuVMFUNC),
626 BITFIELD (CpuRDSEED),
628 BITFIELD (CpuPRFCHW),
631 BITFIELD (CpuClflushOpt),
632 BITFIELD (CpuXSAVES),
633 BITFIELD (CpuXSAVEC),
634 BITFIELD (CpuPREFETCHWT1),
640 BITFIELD (CpuAVX512IFMA),
641 BITFIELD (CpuAVX512VBMI),
642 BITFIELD (CpuAVX512_4FMAPS),
643 BITFIELD (CpuAVX512_4VNNIW),
644 BITFIELD (CpuAVX512_VPOPCNTDQ),
645 BITFIELD (CpuAVX512_VBMI2),
646 BITFIELD (CpuAVX512_VNNI),
647 BITFIELD (CpuAVX512_BITALG),
648 BITFIELD (CpuAVX512_BF16),
649 BITFIELD (CpuAVX512_VP2INTERSECT),
651 BITFIELD (CpuAVX_VNNI),
652 BITFIELD (CpuAVX512_FP16),
653 BITFIELD (CpuMWAITX),
654 BITFIELD (CpuCLZERO),
657 BITFIELD (CpuPTWRITE),
662 BITFIELD (CpuVPCLMULQDQ),
663 BITFIELD (CpuWBNOINVD),
664 BITFIELD (CpuPCONFIG),
665 BITFIELD (CpuWAITPKG),
667 BITFIELD (CpuCLDEMOTE),
668 BITFIELD (CpuAMX_INT8),
669 BITFIELD (CpuAMX_BF16),
670 BITFIELD (CpuAMX_TILE),
671 BITFIELD (CpuMOVDIRI),
672 BITFIELD (CpuMOVDIR64B),
673 BITFIELD (CpuENQCMD),
674 BITFIELD (CpuSERIALIZE),
676 BITFIELD (CpuMCOMMIT),
677 BITFIELD (CpuSEV_ES),
678 BITFIELD (CpuTSXLDTRK),
680 BITFIELD (CpuWideKL),
681 BITFIELD (CpuHRESET),
682 BITFIELD (CpuINVLPGB),
683 BITFIELD (CpuTLBSYNC),
686 BITFIELD (CpuUnused),
690 static bitfield opcode_modifiers[] =
700 BITFIELD (CheckRegSize),
701 BITFIELD (DistinctDest),
702 BITFIELD (MnemonicSize),
713 BITFIELD (BNDPrefixOk),
714 BITFIELD (RegKludge),
715 BITFIELD (Implicit1stXmm0),
719 BITFIELD (AddrPrefixOpReg),
724 BITFIELD (PseudoVexPrefix),
728 BITFIELD (OpcodeSpace),
729 BITFIELD (OpcodePrefix),
730 BITFIELD (VexSources),
736 BITFIELD (Broadcast),
737 BITFIELD (StaticRounding),
739 BITFIELD (Disp8MemShift),
740 BITFIELD (NoDefMask),
741 BITFIELD (ImplicitQuadGroup),
742 BITFIELD (SwapSources),
744 BITFIELD (ATTMnemonic),
745 BITFIELD (ATTSyntax),
746 BITFIELD (IntelSyntax),
750 #define CLASS(n) #n, n
752 static const struct {
754 enum operand_class value;
755 } operand_classes[] = {
769 #define INSTANCE(n) #n, n
771 static const struct {
773 enum operand_instance value;
774 } operand_instances[] = {
783 static bitfield operand_types[] =
792 BITFIELD (BaseIndex),
808 BITFIELD (Unspecified),
814 static const char *filename;
815 static i386_cpu_flags active_cpu_flags;
816 static int active_isstring;
818 struct template_arg {
819 const struct template_arg *next;
823 struct template_instance {
824 const struct template_instance *next;
826 const struct template_arg *args;
829 struct template_param {
830 const struct template_param *next;
835 const struct template *next;
837 const struct template_instance *instances;
838 const struct template_param *params;
841 static const struct template *templates;
844 compare (const void *x, const void *y)
846 const bitfield *xp = (const bitfield *) x;
847 const bitfield *yp = (const bitfield *) y;
848 return xp->position - yp->position;
852 fail (const char *message, ...)
856 va_start (args, message);
857 fprintf (stderr, _("%s: error: "), program_name);
858 vfprintf (stderr, message, args);
864 process_copyright (FILE *fp)
866 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
867 /* Copyright (C) 2007-2022 Free Software Foundation, Inc.\n\
869 This file is part of the GNU opcodes library.\n\
871 This library is free software; you can redistribute it and/or modify\n\
872 it under the terms of the GNU General Public License as published by\n\
873 the Free Software Foundation; either version 3, or (at your option)\n\
874 any later version.\n\
876 It is distributed in the hope that it will be useful, but WITHOUT\n\
877 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
878 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
879 License for more details.\n\
881 You should have received a copy of the GNU General Public License\n\
882 along with this program; if not, write to the Free Software\n\
883 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
884 MA 02110-1301, USA. */\n");
887 /* Remove leading white spaces. */
890 remove_leading_whitespaces (char *str)
892 while (ISSPACE (*str))
897 /* Remove trailing white spaces. */
900 remove_trailing_whitespaces (char *str)
902 size_t last = strlen (str);
910 if (ISSPACE (str [last]))
918 /* Find next field separated by SEP and terminate it. Return a
919 pointer to the one after it. */
922 next_field (char *str, char sep, char **next, char *last)
926 p = remove_leading_whitespaces (str);
927 for (str = p; *str != sep && *str != '\0'; str++);
930 remove_trailing_whitespaces (p);
940 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
943 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
946 char *str, *next, *last;
949 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
950 if (strcmp (cpu_flag_init[i].name, f) == 0)
952 /* Turn on selective bits. */
953 char *init = xstrdup (cpu_flag_init[i].init);
954 last = init + strlen (init);
955 for (next = init; next && next < last; )
957 str = next_field (next, '|', &next, last);
959 set_bitfield (str, array, 1, size, lineno);
969 set_bitfield (char *f, bitfield *array, int value,
970 unsigned int size, int lineno)
974 /* Ignore empty fields; they may result from template expansions. */
978 for (i = 0; i < size; i++)
979 if (strcasecmp (array[i].name, f) == 0)
981 array[i].value = value;
987 const char *v = strchr (f, '=');
994 for (i = 0; i < size; i++)
995 if (strncasecmp (array[i].name, f, n) == 0)
997 value = strtol (v + 1, &end, 0);
1000 array[i].value = value;
1008 /* Handle CPU_XXX_FLAGS. */
1009 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1013 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
1015 fail (_("unknown bitfield: %s\n"), f);
1019 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
1020 int macro, const char *comma, const char *indent)
1024 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
1026 fprintf (table, "%s{ { ", indent);
1028 for (i = 0; i < size - 1; i++)
1030 if (((i + 1) % 20) != 0)
1031 fprintf (table, "%d, ", flags[i].value);
1033 fprintf (table, "%d,", flags[i].value);
1034 if (((i + 1) % 20) == 0)
1036 /* We need \\ for macro. */
1038 fprintf (table, " \\\n %s", indent);
1040 fprintf (table, "\n %s", indent);
1043 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
1046 fprintf (table, "%d } }%s\n", flags[i].value, comma);
1050 process_i386_cpu_flag (FILE *table, char *flag, int macro,
1051 const char *comma, const char *indent,
1054 char *str, *next, *last;
1056 bitfield flags [ARRAY_SIZE (cpu_flags)];
1058 /* Copy the default cpu flags. */
1059 memcpy (flags, cpu_flags, sizeof (cpu_flags));
1061 if (strcasecmp (flag, "unknown") == 0)
1063 /* We turn on everything except for cpu64 in case of
1064 CPU_UNKNOWN_FLAGS. */
1065 for (i = 0; i < ARRAY_SIZE (flags); i++)
1066 if (flags[i].position != Cpu64)
1069 else if (flag[0] == '~')
1071 last = flag + strlen (flag);
1078 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
1085 /* First we turn on everything except for cpu64. */
1086 for (i = 0; i < ARRAY_SIZE (flags); i++)
1087 if (flags[i].position != Cpu64)
1090 /* Turn off selective bits. */
1091 for (; next && next < last; )
1093 str = next_field (next, '|', &next, last);
1095 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1098 else if (strcmp (flag, "0"))
1100 /* Turn on selective bits. */
1101 last = flag + strlen (flag);
1102 for (next = flag; next && next < last; )
1104 str = next_field (next, '|', &next, last);
1106 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1110 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1115 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1119 fprintf (table, " { ");
1121 for (i = 0; i < size - 1; i++)
1123 if (((i + 1) % 20) != 0)
1124 fprintf (table, "%d, ", modifier[i].value);
1126 fprintf (table, "%d,", modifier[i].value);
1127 if (((i + 1) % 20) == 0)
1128 fprintf (table, "\n ");
1131 fprintf (table, "%d },\n", modifier[i].value);
1135 adjust_broadcast_modifier (char **opnd)
1137 char *str, *next, *last, *op;
1138 int bcst_type = INT_MAX;
1140 /* Skip the immediate operand. */
1142 if (strcasecmp(op, "Imm8") == 0)
1146 last = op + strlen (op);
1147 for (next = op; next && next < last; )
1149 str = next_field (next, '|', &next, last);
1152 if (strcasecmp(str, "Byte") == 0)
1154 /* The smalest broadcast type, no need to check
1156 bcst_type = BYTE_BROADCAST;
1159 else if (strcasecmp(str, "Word") == 0)
1161 if (bcst_type > WORD_BROADCAST)
1162 bcst_type = WORD_BROADCAST;
1164 else if (strcasecmp(str, "Dword") == 0)
1166 if (bcst_type > DWORD_BROADCAST)
1167 bcst_type = DWORD_BROADCAST;
1169 else if (strcasecmp(str, "Qword") == 0)
1171 if (bcst_type > QWORD_BROADCAST)
1172 bcst_type = QWORD_BROADCAST;
1178 if (bcst_type == INT_MAX)
1179 fail (_("unknown broadcast operand: %s\n"), op);
1185 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1186 unsigned int prefix, char **opnd, int lineno)
1188 char *str, *next, *last;
1189 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1191 active_isstring = 0;
1193 /* Copy the default opcode modifier. */
1194 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1196 if (strcmp (mod, "0"))
1198 unsigned int have_w = 0, bwlq_suf = 0xf;
1200 last = mod + strlen (mod);
1201 for (next = mod; next && next < last; )
1203 str = next_field (next, '|', &next, last);
1207 if (strcasecmp(str, "Broadcast") == 0)
1208 val = adjust_broadcast_modifier (opnd);
1210 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1212 if (strcasecmp(str, "IsString") == 0)
1213 active_isstring = 1;
1215 if (strcasecmp(str, "W") == 0)
1218 if (strcasecmp(str, "No_bSuf") == 0)
1220 if (strcasecmp(str, "No_wSuf") == 0)
1222 if (strcasecmp(str, "No_lSuf") == 0)
1224 if (strcasecmp(str, "No_qSuf") == 0)
1231 if (!modifiers[OpcodeSpace].value)
1232 modifiers[OpcodeSpace].value = space;
1233 else if (modifiers[OpcodeSpace].value != space)
1234 fail (_("%s:%d: Conflicting opcode space specifications\n"),
1238 _("%s:%d: Warning: redundant opcode space specification\n"),
1244 if (!modifiers[OpcodePrefix].value)
1245 modifiers[OpcodePrefix].value = prefix;
1246 else if (modifiers[OpcodePrefix].value != prefix)
1247 fail (_("%s:%d: Conflicting prefix specifications\n"),
1251 _("%s:%d: Warning: redundant prefix specification\n"),
1255 if (have_w && !bwlq_suf)
1256 fail ("%s: %d: stray W modifier\n", filename, lineno);
1257 if (have_w && !(bwlq_suf & 1))
1258 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1260 if (have_w && !(bwlq_suf & ~1))
1262 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1265 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1275 output_operand_type (FILE *table, enum operand_class class,
1276 enum operand_instance instance,
1277 const bitfield *types, unsigned int size,
1278 enum stage stage, const char *indent)
1282 fprintf (table, "{ { %d, %d, ", class, instance);
1284 for (i = 0; i < size - 1; i++)
1286 if (((i + 3) % 20) != 0)
1287 fprintf (table, "%d, ", types[i].value);
1289 fprintf (table, "%d,", types[i].value);
1290 if (((i + 3) % 20) == 0)
1292 /* We need \\ for macro. */
1293 if (stage == stage_macros)
1294 fprintf (table, " \\\n%s", indent);
1296 fprintf (table, "\n%s", indent);
1300 fprintf (table, "%d } }", types[i].value);
1304 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1305 const char *indent, int lineno)
1307 char *str, *next, *last;
1308 enum operand_class class = ClassNone;
1309 enum operand_instance instance = InstanceNone;
1310 bitfield types [ARRAY_SIZE (operand_types)];
1312 /* Copy the default operand type. */
1313 memcpy (types, operand_types, sizeof (types));
1315 if (strcmp (op, "0"))
1319 last = op + strlen (op);
1320 for (next = op; next && next < last; )
1322 str = next_field (next, '|', &next, last);
1327 if (!strncmp(str, "Class=", 6))
1329 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1330 if (!strcmp(str + 6, operand_classes[i].name))
1332 class = operand_classes[i].value;
1338 if (str && !strncmp(str, "Instance=", 9))
1340 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1341 if (!strcmp(str + 9, operand_instances[i].name))
1343 instance = operand_instances[i].value;
1351 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1352 if (strcasecmp(str, "BaseIndex") == 0)
1357 if (stage == stage_opcodes && baseindex && !active_isstring)
1359 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1360 if (!active_cpu_flags.bitfield.cpu64
1361 && !active_cpu_flags.bitfield.cpumpx)
1362 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1363 if (!active_cpu_flags.bitfield.cpu64)
1364 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1365 if (!active_cpu_flags.bitfield.cpuno64)
1366 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1369 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1374 output_i386_opcode (FILE *table, const char *name, char *str,
1375 char *last, int lineno)
1377 unsigned int i, length, prefix = 0, space = 0;
1378 char *base_opcode, *extension_opcode, *end;
1379 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1380 unsigned long long opcode;
1382 /* Find base_opcode. */
1383 base_opcode = next_field (str, ',', &str, last);
1385 /* Find extension_opcode. */
1386 extension_opcode = next_field (str, ',', &str, last);
1388 /* Find cpu_flags. */
1389 cpu_flags = next_field (str, ',', &str, last);
1391 /* Find opcode_modifier. */
1392 opcode_modifier = next_field (str, ',', &str, last);
1394 /* Remove the first {. */
1395 str = remove_leading_whitespaces (str);
1398 str = remove_leading_whitespaces (str + 1);
1399 remove_trailing_whitespaces (str);
1401 /* Remove } and trailing white space. */
1403 if (!i || str[i - 1] != '}')
1406 remove_trailing_whitespaces (str);
1409 operand_types [i = 0] = NULL;
1412 last = str + strlen (str);
1414 /* Find operand_types. */
1415 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1419 operand_types [i] = NULL;
1423 operand_types [i] = next_field (str, ',', &str, last);
1427 opcode = strtoull (base_opcode, &end, 0);
1429 /* Determine opcode length. */
1430 for (length = 1; length < 8; ++length)
1431 if (!(opcode >> (8 * length)))
1434 /* Transform prefixes encoded in the opcode into opcode modifier
1438 switch (opcode >> (8 * length - 8))
1440 case 0x66: prefix = PREFIX_0X66; break;
1441 case 0xF3: prefix = PREFIX_0XF3; break;
1442 case 0xF2: prefix = PREFIX_0XF2; break;
1446 opcode &= (1ULL << (8 * --length)) - 1;
1449 /* Transform opcode space encoded in the opcode into opcode modifier
1451 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1453 switch ((opcode >> (8 * length - 16)) & 0xff)
1455 default: space = SPACE_0F; break;
1456 case 0x38: space = SPACE_0F38; break;
1457 case 0x3A: space = SPACE_0F3A; break;
1460 if (space != SPACE_0F && --length == 1)
1461 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1462 filename, lineno, name);
1463 opcode &= (1ULL << (8 * --length)) - 1;
1467 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1468 filename, lineno, name, 2 * length, opcode);
1470 fprintf (table, " { \"%s\", 0x%0*llx%s, %s, %lu,\n",
1471 name, 2 * (int)length, opcode, end, extension_opcode, i);
1473 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1474 operand_types, lineno);
1476 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1478 fprintf (table, " { ");
1480 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1482 if (!operand_types[i])
1485 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1491 fprintf (table, ",\n ");
1493 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1496 fprintf (table, " } },\n");
1499 struct opcode_hash_entry
1501 struct opcode_hash_entry *next;
1507 /* Calculate the hash value of an opcode hash entry P. */
1510 opcode_hash_hash (const void *p)
1512 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1513 return htab_hash_string (entry->name);
1516 /* Compare a string Q against an opcode hash entry P. */
1519 opcode_hash_eq (const void *p, const void *q)
1521 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1522 const char *name = (const char *) q;
1523 return strcmp (name, entry->name) == 0;
1527 parse_template (char *buf, int lineno)
1529 char sep, *end, *name;
1530 struct template *tmpl = xmalloc (sizeof (*tmpl));
1531 struct template_instance *last_inst = NULL;
1533 buf = remove_leading_whitespaces (buf + 1);
1534 end = strchr (buf, ':');
1536 fail ("%s: %d: missing ':'\n", filename, lineno);
1538 remove_trailing_whitespaces (buf);
1541 fail ("%s: %d: missing template identifier\n", filename, lineno);
1542 tmpl->name = xstrdup (buf);
1544 tmpl->params = NULL;
1546 struct template_param *param;
1548 buf = remove_leading_whitespaces (end);
1549 end = strpbrk (buf, ":,");
1551 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1555 remove_trailing_whitespaces (buf);
1557 param = xmalloc (sizeof (*param));
1558 param->name = xstrdup (buf);
1559 param->next = tmpl->params;
1560 tmpl->params = param;
1561 } while (sep == ':');
1563 tmpl->instances = NULL;
1565 struct template_instance *inst;
1567 const struct template_param *param;
1569 buf = remove_leading_whitespaces (end);
1570 end = strpbrk (buf, ",>");
1572 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1577 inst = xmalloc (sizeof (*inst));
1581 cur = next_field (buf, ':', &next, end);
1582 inst->name = *cur != '$' ? xstrdup (cur) : "";
1584 for (param = tmpl->params; param; param = param->next)
1586 struct template_arg *arg = xmalloc (sizeof (*arg));
1588 cur = next_field (next, ':', &next, end);
1590 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1591 arg->val = xstrdup (cur);
1592 arg->next = inst->args;
1596 if (tmpl->instances)
1597 last_inst->next = inst;
1599 tmpl->instances = inst;
1601 } while (sep == ',');
1603 buf = remove_leading_whitespaces (end);
1605 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1606 filename, lineno, buf);
1608 tmpl->next = templates;
1613 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1614 struct opcode_hash_entry ***opcode_array_p, int lineno)
1616 static unsigned int idx, opcode_array_size;
1617 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1618 struct opcode_hash_entry **hash_slot, **entry;
1619 char *ptr1 = strchr(name, '<'), *ptr2;
1623 /* Get the slot in hash table. */
1624 hash_slot = (struct opcode_hash_entry **)
1625 htab_find_slot_with_hash (opcode_hash_table, name,
1626 htab_hash_string (name),
1629 if (*hash_slot == NULL)
1631 /* It is the new one. Put it on opcode array. */
1632 if (idx >= opcode_array_size)
1634 /* Grow the opcode array when needed. */
1635 opcode_array_size += 1024;
1636 opcode_array = (struct opcode_hash_entry **)
1637 xrealloc (opcode_array,
1638 sizeof (*opcode_array) * opcode_array_size);
1639 *opcode_array_p = opcode_array;
1642 opcode_array[idx] = (struct opcode_hash_entry *)
1643 xmalloc (sizeof (struct opcode_hash_entry));
1644 opcode_array[idx]->next = NULL;
1645 opcode_array[idx]->name = xstrdup (name);
1646 opcode_array[idx]->opcode = xstrdup (str);
1647 opcode_array[idx]->lineno = lineno;
1648 *hash_slot = opcode_array[idx];
1653 /* Append it to the existing one. */
1655 while ((*entry) != NULL)
1656 entry = &(*entry)->next;
1657 *entry = (struct opcode_hash_entry *)
1658 xmalloc (sizeof (struct opcode_hash_entry));
1659 (*entry)->next = NULL;
1660 (*entry)->name = (*hash_slot)->name;
1661 (*entry)->opcode = xstrdup (str);
1662 (*entry)->lineno = lineno;
1665 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1666 fail ("%s: %d: missing '>'\n", filename, lineno);
1669 const struct template *tmpl;
1670 const struct template_instance *inst;
1673 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1674 remove_trailing_whitespaces (ptr1);
1678 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1679 if (!strcmp(ptr1, tmpl->name))
1682 fail ("reference to unknown template '%s'\n", ptr1);
1684 for (inst = tmpl->instances; inst; inst = inst->next)
1686 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1687 char *str2 = xmalloc(2 * strlen(str));
1690 strcpy (name2, name);
1691 strcat (name2, inst->name);
1692 strcat (name2, ptr2);
1694 for (ptr1 = str2, src = str; *src; )
1696 const char *ident = tmpl->name, *end;
1697 const struct template_param *param;
1698 const struct template_arg *arg;
1700 if ((*ptr1 = *src++) != '<')
1705 while (ISSPACE(*src))
1707 while (*ident && *src == *ident)
1709 while (ISSPACE(*src))
1711 if (*src != ':' || *ident != '\0')
1713 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1714 ptr1 += ident - tmpl->name;
1717 while (ISSPACE(*++src))
1721 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1724 for (param = tmpl->params, arg = inst->args; param;
1725 param = param->next, arg = arg->next)
1727 if (end - src == strlen (param->name)
1728 && !memcmp (src, param->name, end - src))
1736 fail ("template '%s' has no parameter '%.*s'\n",
1737 tmpl->name, (int)(end - src), src);
1739 while (ISSPACE(*src))
1742 fail ("%s: %d: missing '>'\n", filename, lineno);
1744 memcpy(ptr1, arg->val, strlen(arg->val));
1745 ptr1 += strlen(arg->val);
1751 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1763 process_i386_opcodes (FILE *table)
1768 char *str, *p, *last, *name;
1769 htab_t opcode_hash_table;
1770 struct opcode_hash_entry **opcode_array = NULL;
1771 int lineno = 0, marker = 0;
1773 filename = "i386-opc.tbl";
1777 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1778 opcode_hash_eq, NULL,
1781 fprintf (table, "\n/* i386 opcode table. */\n\n");
1782 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1784 /* Put everything on opcode array. */
1787 if (fgets (buf, sizeof (buf), fp) == NULL)
1792 p = remove_leading_whitespaces (buf);
1794 /* Skip comments. */
1795 str = strstr (p, "//");
1799 /* Remove trailing white spaces. */
1800 remove_trailing_whitespaces (p);
1805 if (!strcmp("### MARKER ###", buf))
1809 /* Since we ignore all included files (we only care about their
1810 #define-s here), we don't need to monitor filenames. The final
1811 line number directive is going to refer to the main source file
1816 p = remove_leading_whitespaces (p + 1);
1817 if (!strncmp(p, "line", 4))
1819 ln = strtoul (p, &end, 10);
1820 if (ln > 1 && ln < INT_MAX
1821 && *remove_leading_whitespaces (end) == '"')
1824 /* Ignore comments. */
1829 parse_template (p, lineno);
1837 last = p + strlen (p);
1840 name = next_field (p, ',', &str, last);
1842 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1846 /* Process opcode array. */
1847 for (j = 0; j < i; j++)
1849 struct opcode_hash_entry *next;
1851 for (next = opcode_array[j]; next; next = next->next)
1855 lineno = next->lineno;
1856 last = str + strlen (str);
1857 output_i386_opcode (table, name, str, last, lineno);
1863 fprintf (table, " { NULL, 0, 0, 0,\n");
1865 process_i386_opcode_modifier (table, "0", 0, 0, NULL, -1);
1867 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1869 fprintf (table, " { ");
1870 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1871 fprintf (table, " } }\n");
1873 fprintf (table, "};\n");
1877 process_i386_registers (FILE *table)
1881 char *str, *p, *last;
1882 char *reg_name, *reg_type, *reg_flags, *reg_num;
1883 char *dw2_32_num, *dw2_64_num;
1886 filename = "i386-reg.tbl";
1887 fp = fopen (filename, "r");
1889 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1892 fprintf (table, "\n/* i386 register table. */\n\n");
1893 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1897 if (fgets (buf, sizeof (buf), fp) == NULL)
1902 p = remove_leading_whitespaces (buf);
1904 /* Skip comments. */
1905 str = strstr (p, "//");
1909 /* Remove trailing white spaces. */
1910 remove_trailing_whitespaces (p);
1915 fprintf (table, "%s\n", p);
1923 last = p + strlen (p);
1925 /* Find reg_name. */
1926 reg_name = next_field (p, ',', &str, last);
1928 /* Find reg_type. */
1929 reg_type = next_field (str, ',', &str, last);
1931 /* Find reg_flags. */
1932 reg_flags = next_field (str, ',', &str, last);
1935 reg_num = next_field (str, ',', &str, last);
1937 fprintf (table, " { \"%s\",\n ", reg_name);
1939 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1942 /* Find 32-bit Dwarf2 register number. */
1943 dw2_32_num = next_field (str, ',', &str, last);
1945 /* Find 64-bit Dwarf2 register number. */
1946 dw2_64_num = next_field (str, ',', &str, last);
1948 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1949 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1954 fprintf (table, "};\n");
1956 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1960 process_i386_initializers (void)
1963 FILE *fp = fopen ("i386-init.h", "w");
1967 fail (_("can't create i386-init.h, errno = %s\n"),
1970 process_copyright (fp);
1972 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1974 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1975 init = xstrdup (cpu_flag_init[i].init);
1976 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1980 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1982 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1983 init = xstrdup (operand_type_init[i].init);
1984 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1992 /* Program options. */
1993 #define OPTION_SRCDIR 200
1995 struct option long_options[] =
1997 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1998 {"debug", no_argument, NULL, 'd'},
1999 {"version", no_argument, NULL, 'V'},
2000 {"help", no_argument, NULL, 'h'},
2001 {0, no_argument, NULL, 0}
2005 print_version (void)
2007 printf ("%s: version 1.0\n", program_name);
2012 usage (FILE * stream, int status)
2014 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2020 main (int argc, char **argv)
2022 extern int chdir (char *);
2023 char *srcdir = NULL;
2025 unsigned int i, cpumax;
2028 program_name = *argv;
2029 xmalloc_set_program_name (program_name);
2031 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2056 if (chdir (srcdir) != 0)
2057 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2058 srcdir, xstrerror (errno));
2060 /* cpu_flags isn't sorted by position. */
2062 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2063 if (cpu_flags[i].position > cpumax)
2064 cpumax = cpu_flags[i].position;
2066 /* Check the unused bitfield in i386_cpu_flags. */
2068 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2070 if ((cpumax - 1) != CpuMax)
2071 fail (_("CpuMax != %d!\n"), cpumax);
2073 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2075 if (cpumax != CpuMax)
2076 fail (_("CpuMax != %d!\n"), cpumax);
2078 c = CpuNumOfBits - CpuMax - 1;
2080 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2083 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2085 /* Check the unused bitfield in i386_operand_type. */
2087 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2090 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2093 c = OTNumOfBits - OTNum;
2095 fail (_("%d unused bits in i386_operand_type.\n"), c);
2098 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2101 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2102 sizeof (opcode_modifiers [0]), compare);
2104 qsort (operand_types, ARRAY_SIZE (operand_types),
2105 sizeof (operand_types [0]), compare);
2107 table = fopen ("i386-tbl.h", "w");
2109 fail (_("can't create i386-tbl.h, errno = %s\n"),
2112 process_copyright (table);
2114 process_i386_opcodes (table);
2115 process_i386_registers (table);
2116 process_i386_initializers ();