1 /* Copyright (C) 2007-2020 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_BTVER1_FLAGS",
107 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
108 { "CPU_BTVER2_FLAGS",
109 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
117 "CPU_387_FLAGS|Cpu687" },
122 { "CPU_CLFLUSH_FLAGS",
126 { "CPU_SYSCALL_FLAGS",
133 "CPU_SSE_FLAGS|CpuSSE2" },
135 "CPU_SSE2_FLAGS|CpuSSE3" },
137 "CPU_SSE3_FLAGS|CpuSSSE3" },
138 { "CPU_SSE4_1_FLAGS",
139 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
140 { "CPU_SSE4_2_FLAGS",
141 "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
148 { "CPU_XSAVEOPT_FLAGS",
149 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
151 "CPU_SSE2_FLAGS|CpuAES" },
152 { "CPU_PCLMUL_FLAGS",
153 "CPU_SSE2_FLAGS|CpuPCLMUL" },
155 "CPU_AVX_FLAGS|CpuFMA" },
157 "CPU_AVX_FLAGS|CpuFMA4" },
159 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
161 "CPU_XSAVE_FLAGS|CpuLWP" },
170 { "CPU_RDTSCP_FLAGS",
174 { "CPU_FSGSBASE_FLAGS",
179 "CPU_AVX_FLAGS|CpuF16C" },
184 { "CPU_POPCNT_FLAGS",
190 { "CPU_INVPCID_FLAGS",
192 { "CPU_VMFUNC_FLAGS",
195 "CPU_MMX_FLAGS|Cpu3dnow" },
196 { "CPU_3DNOWA_FLAGS",
197 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
198 { "CPU_PADLOCK_FLAGS",
203 "CPU_SSE3_FLAGS|CpuSSE4a" },
205 "CpuLZCNT|CpuPOPCNT" },
207 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
209 "CPU_AVX_FLAGS|CpuAVX2" },
210 { "CPU_AVX512F_FLAGS",
211 "CPU_AVX2_FLAGS|CpuAVX512F" },
212 { "CPU_AVX512CD_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
214 { "CPU_AVX512ER_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
216 { "CPU_AVX512PF_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
218 { "CPU_AVX512DQ_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
220 { "CPU_AVX512BW_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
222 { "CPU_AVX512VL_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
224 { "CPU_AVX512IFMA_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
226 { "CPU_AVX512VBMI_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
228 { "CPU_AVX512_4FMAPS_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
230 { "CPU_AVX512_4VNNIW_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
232 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
234 { "CPU_AVX512_VBMI2_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
236 { "CPU_AVX512_VNNI_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
238 { "CPU_AVX512_BITALG_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
240 { "CPU_AVX512_BF16_FLAGS",
241 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
247 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
250 { "CPU_RDSEED_FLAGS",
252 { "CPU_PRFCHW_FLAGS",
257 "CPU_XSAVE_FLAGS|CpuMPX" },
259 "CPU_SSE2_FLAGS|CpuSHA" },
260 { "CPU_CLFLUSHOPT_FLAGS",
262 { "CPU_XSAVES_FLAGS",
263 "CPU_XSAVE_FLAGS|CpuXSAVES" },
264 { "CPU_XSAVEC_FLAGS",
265 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
266 { "CPU_PREFETCHWT1_FLAGS",
272 { "CPU_CLZERO_FLAGS",
274 { "CPU_MWAITX_FLAGS",
277 "CPU_XSAVE_FLAGS|CpuOSPKE" },
280 { "CPU_PTWRITE_FLAGS",
290 { "CPU_VPCLMULQDQ_FLAGS",
292 { "CPU_WBNOINVD_FLAGS",
294 { "CPU_PCONFIG_FLAGS",
296 { "CPU_WAITPKG_FLAGS",
298 { "CPU_CLDEMOTE_FLAGS",
300 { "CPU_AMX_INT8_FLAGS",
302 { "CPU_AMX_BF16_FLAGS",
304 { "CPU_AMX_TILE_FLAGS",
306 { "CPU_MOVDIRI_FLAGS",
308 { "CPU_MOVDIR64B_FLAGS",
310 { "CPU_ENQCMD_FLAGS",
312 { "CPU_SERIALIZE_FLAGS",
314 { "CPU_AVX512_VP2INTERSECT_FLAGS",
315 "CpuAVX512_VP2INTERSECT" },
320 { "CPU_MCOMMIT_FLAGS",
322 { "CPU_SEV_ES_FLAGS",
324 { "CPU_TSXLDTRK_FLAGS",
328 { "CPU_WIDEKL_FLAGS",
330 { "CPU_ANY_X87_FLAGS",
331 "CPU_ANY_287_FLAGS|Cpu8087" },
332 { "CPU_ANY_287_FLAGS",
333 "CPU_ANY_387_FLAGS|Cpu287" },
334 { "CPU_ANY_387_FLAGS",
335 "CPU_ANY_687_FLAGS|Cpu387" },
336 { "CPU_ANY_687_FLAGS",
337 "Cpu687|CpuFISTTP" },
338 { "CPU_ANY_CMOV_FLAGS",
340 { "CPU_ANY_FXSR_FLAGS",
342 { "CPU_ANY_MMX_FLAGS",
343 "CPU_3DNOWA_FLAGS" },
344 { "CPU_ANY_SSE_FLAGS",
345 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
346 { "CPU_ANY_SSE2_FLAGS",
347 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
348 { "CPU_ANY_SSE3_FLAGS",
349 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
350 { "CPU_ANY_SSSE3_FLAGS",
351 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
352 { "CPU_ANY_SSE4_1_FLAGS",
353 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
354 { "CPU_ANY_SSE4_2_FLAGS",
356 { "CPU_ANY_SSE4A_FLAGS",
358 { "CPU_ANY_AVX_FLAGS",
359 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
360 { "CPU_ANY_AVX2_FLAGS",
361 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
362 { "CPU_ANY_AVX512F_FLAGS",
363 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
364 { "CPU_ANY_AVX512CD_FLAGS",
366 { "CPU_ANY_AVX512ER_FLAGS",
368 { "CPU_ANY_AVX512PF_FLAGS",
370 { "CPU_ANY_AVX512DQ_FLAGS",
372 { "CPU_ANY_AVX512BW_FLAGS",
374 { "CPU_ANY_AVX512VL_FLAGS",
376 { "CPU_ANY_AVX512IFMA_FLAGS",
378 { "CPU_ANY_AVX512VBMI_FLAGS",
380 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
381 "CpuAVX512_4FMAPS" },
382 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
383 "CpuAVX512_4VNNIW" },
384 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
385 "CpuAVX512_VPOPCNTDQ" },
386 { "CPU_ANY_IBT_FLAGS",
388 { "CPU_ANY_SHSTK_FLAGS",
390 { "CPU_ANY_AVX512_VBMI2_FLAGS",
392 { "CPU_ANY_AVX512_VNNI_FLAGS",
394 { "CPU_ANY_AVX512_BITALG_FLAGS",
395 "CpuAVX512_BITALG" },
396 { "CPU_ANY_AVX512_BF16_FLAGS",
398 { "CPU_ANY_AMX_INT8_FLAGS",
400 { "CPU_ANY_AMX_BF16_FLAGS",
402 { "CPU_ANY_AMX_TILE_FLAGS",
403 "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" },
404 { "CPU_ANY_MOVDIRI_FLAGS",
406 { "CPU_ANY_MOVDIR64B_FLAGS",
408 { "CPU_ANY_ENQCMD_FLAGS",
410 { "CPU_ANY_SERIALIZE_FLAGS",
412 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
413 "CpuAVX512_VP2INTERSECT" },
414 { "CPU_ANY_TDX_FLAGS",
416 { "CPU_ANY_TSXLDTRK_FLAGS",
418 { "CPU_ANY_KL_FLAGS",
420 { "CPU_ANY_WIDEKL_FLAGS",
424 static initializer operand_type_init
[] =
426 { "OPERAND_TYPE_NONE",
428 { "OPERAND_TYPE_REG8",
430 { "OPERAND_TYPE_REG16",
432 { "OPERAND_TYPE_REG32",
434 { "OPERAND_TYPE_REG64",
436 { "OPERAND_TYPE_IMM1",
438 { "OPERAND_TYPE_IMM8",
440 { "OPERAND_TYPE_IMM8S",
442 { "OPERAND_TYPE_IMM16",
444 { "OPERAND_TYPE_IMM32",
446 { "OPERAND_TYPE_IMM32S",
448 { "OPERAND_TYPE_IMM64",
450 { "OPERAND_TYPE_BASEINDEX",
452 { "OPERAND_TYPE_DISP8",
454 { "OPERAND_TYPE_DISP16",
456 { "OPERAND_TYPE_DISP32",
458 { "OPERAND_TYPE_DISP32S",
460 { "OPERAND_TYPE_DISP64",
462 { "OPERAND_TYPE_INOUTPORTREG",
463 "Instance=RegD|Word" },
464 { "OPERAND_TYPE_SHIFTCOUNT",
465 "Instance=RegC|Byte" },
466 { "OPERAND_TYPE_CONTROL",
468 { "OPERAND_TYPE_TEST",
470 { "OPERAND_TYPE_DEBUG",
472 { "OPERAND_TYPE_FLOATREG",
474 { "OPERAND_TYPE_FLOATACC",
475 "Instance=Accum|Tbyte" },
476 { "OPERAND_TYPE_SREG",
478 { "OPERAND_TYPE_REGMMX",
480 { "OPERAND_TYPE_REGXMM",
481 "Class=RegSIMD|Xmmword" },
482 { "OPERAND_TYPE_REGYMM",
483 "Class=RegSIMD|Ymmword" },
484 { "OPERAND_TYPE_REGZMM",
485 "Class=RegSIMD|Zmmword" },
486 { "OPERAND_TYPE_REGTMM",
487 "Class=RegSIMD|Tmmword" },
488 { "OPERAND_TYPE_REGMASK",
490 { "OPERAND_TYPE_REGBND",
492 { "OPERAND_TYPE_ACC8",
493 "Instance=Accum|Byte" },
494 { "OPERAND_TYPE_ACC16",
495 "Instance=Accum|Word" },
496 { "OPERAND_TYPE_ACC32",
497 "Instance=Accum|Dword" },
498 { "OPERAND_TYPE_ACC64",
499 "Instance=Accum|Qword" },
500 { "OPERAND_TYPE_DISP16_32",
502 { "OPERAND_TYPE_ANYDISP",
503 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
504 { "OPERAND_TYPE_IMM16_32",
506 { "OPERAND_TYPE_IMM16_32S",
508 { "OPERAND_TYPE_IMM16_32_32S",
509 "Imm16|Imm32|Imm32S" },
510 { "OPERAND_TYPE_IMM32_64",
512 { "OPERAND_TYPE_IMM32_32S_DISP32",
513 "Imm32|Imm32S|Disp32" },
514 { "OPERAND_TYPE_IMM64_DISP64",
516 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
517 "Imm32|Imm32S|Imm64|Disp32" },
518 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
519 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
520 { "OPERAND_TYPE_ANYIMM",
521 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
524 typedef struct bitfield
531 #define BITFIELD(n) { n, 0, #n }
533 static bitfield cpu_flags
[] =
543 BITFIELD (CpuClflush
),
545 BITFIELD (CpuSYSCALL
),
550 BITFIELD (CpuFISTTP
),
556 BITFIELD (CpuSSE4_1
),
557 BITFIELD (CpuSSE4_2
),
560 BITFIELD (CpuAVX512F
),
561 BITFIELD (CpuAVX512CD
),
562 BITFIELD (CpuAVX512ER
),
563 BITFIELD (CpuAVX512PF
),
564 BITFIELD (CpuAVX512VL
),
565 BITFIELD (CpuAVX512DQ
),
566 BITFIELD (CpuAVX512BW
),
572 BITFIELD (Cpu3dnowA
),
573 BITFIELD (CpuPadLock
),
578 BITFIELD (CpuXsaveopt
),
580 BITFIELD (CpuPCLMUL
),
591 BITFIELD (CpuRdtscp
),
592 BITFIELD (CpuFSGSBase
),
597 BITFIELD (CpuPOPCNT
),
600 BITFIELD (CpuINVPCID
),
601 BITFIELD (CpuVMFUNC
),
602 BITFIELD (CpuRDSEED
),
604 BITFIELD (CpuPRFCHW
),
607 BITFIELD (CpuClflushOpt
),
608 BITFIELD (CpuXSAVES
),
609 BITFIELD (CpuXSAVEC
),
610 BITFIELD (CpuPREFETCHWT1
),
616 BITFIELD (CpuAVX512IFMA
),
617 BITFIELD (CpuAVX512VBMI
),
618 BITFIELD (CpuAVX512_4FMAPS
),
619 BITFIELD (CpuAVX512_4VNNIW
),
620 BITFIELD (CpuAVX512_VPOPCNTDQ
),
621 BITFIELD (CpuAVX512_VBMI2
),
622 BITFIELD (CpuAVX512_VNNI
),
623 BITFIELD (CpuAVX512_BITALG
),
624 BITFIELD (CpuAVX512_BF16
),
625 BITFIELD (CpuAVX512_VP2INTERSECT
),
627 BITFIELD (CpuMWAITX
),
628 BITFIELD (CpuCLZERO
),
631 BITFIELD (CpuPTWRITE
),
636 BITFIELD (CpuVPCLMULQDQ
),
637 BITFIELD (CpuWBNOINVD
),
638 BITFIELD (CpuPCONFIG
),
639 BITFIELD (CpuWAITPKG
),
640 BITFIELD (CpuCLDEMOTE
),
641 BITFIELD (CpuAMX_INT8
),
642 BITFIELD (CpuAMX_BF16
),
643 BITFIELD (CpuAMX_TILE
),
644 BITFIELD (CpuMOVDIRI
),
645 BITFIELD (CpuMOVDIR64B
),
646 BITFIELD (CpuENQCMD
),
647 BITFIELD (CpuSERIALIZE
),
649 BITFIELD (CpuMCOMMIT
),
650 BITFIELD (CpuSEV_ES
),
651 BITFIELD (CpuTSXLDTRK
),
653 BITFIELD (CpuWideKL
),
655 BITFIELD (CpuUnused
),
659 static bitfield opcode_modifiers
[] =
669 BITFIELD (CheckRegSize
),
670 BITFIELD (MnemonicSize
),
681 BITFIELD (BNDPrefixOk
),
682 BITFIELD (NoTrackPrefixOk
),
683 BITFIELD (IsLockable
),
684 BITFIELD (RegKludge
),
685 BITFIELD (Implicit1stXmm0
),
686 BITFIELD (RepPrefixOk
),
687 BITFIELD (HLEPrefixOk
),
690 BITFIELD (AddrPrefixOpReg
),
698 BITFIELD (OpcodePrefix
),
699 BITFIELD (VexSources
),
705 BITFIELD (Broadcast
),
706 BITFIELD (StaticRounding
),
708 BITFIELD (Disp8MemShift
),
709 BITFIELD (NoDefMask
),
710 BITFIELD (ImplicitQuadGroup
),
711 BITFIELD (SwapSources
),
713 BITFIELD (ATTMnemonic
),
714 BITFIELD (ATTSyntax
),
715 BITFIELD (IntelSyntax
),
719 #define CLASS(n) #n, n
721 static const struct {
723 enum operand_class value
;
724 } operand_classes
[] = {
738 #define INSTANCE(n) #n, n
740 static const struct {
742 enum operand_instance value
;
743 } operand_instances
[] = {
752 static bitfield operand_types
[] =
761 BITFIELD (BaseIndex
),
777 BITFIELD (Unspecified
),
783 static const char *filename
;
784 static i386_cpu_flags active_cpu_flags
;
785 static int active_isstring
;
787 struct template_arg
{
788 const struct template_arg
*next
;
792 struct template_instance
{
793 const struct template_instance
*next
;
795 const struct template_arg
*args
;
798 struct template_param
{
799 const struct template_param
*next
;
804 const struct template *next
;
806 const struct template_instance
*instances
;
807 const struct template_param
*params
;
810 static const struct template *templates
;
813 compare (const void *x
, const void *y
)
815 const bitfield
*xp
= (const bitfield
*) x
;
816 const bitfield
*yp
= (const bitfield
*) y
;
817 return xp
->position
- yp
->position
;
821 fail (const char *message
, ...)
825 va_start (args
, message
);
826 fprintf (stderr
, _("%s: error: "), program_name
);
827 vfprintf (stderr
, message
, args
);
833 process_copyright (FILE *fp
)
835 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
836 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
838 This file is part of the GNU opcodes library.\n\
840 This library is free software; you can redistribute it and/or modify\n\
841 it under the terms of the GNU General Public License as published by\n\
842 the Free Software Foundation; either version 3, or (at your option)\n\
843 any later version.\n\
845 It is distributed in the hope that it will be useful, but WITHOUT\n\
846 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
847 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
848 License for more details.\n\
850 You should have received a copy of the GNU General Public License\n\
851 along with this program; if not, write to the Free Software\n\
852 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
853 MA 02110-1301, USA. */\n");
856 /* Remove leading white spaces. */
859 remove_leading_whitespaces (char *str
)
861 while (ISSPACE (*str
))
866 /* Remove trailing white spaces. */
869 remove_trailing_whitespaces (char *str
)
871 size_t last
= strlen (str
);
879 if (ISSPACE (str
[last
]))
887 /* Find next field separated by SEP and terminate it. Return a
888 pointer to the one after it. */
891 next_field (char *str
, char sep
, char **next
, char *last
)
895 p
= remove_leading_whitespaces (str
);
896 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
899 remove_trailing_whitespaces (p
);
909 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
912 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
915 char *str
, *next
, *last
;
918 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
919 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
921 /* Turn on selective bits. */
922 char *init
= xstrdup (cpu_flag_init
[i
].init
);
923 last
= init
+ strlen (init
);
924 for (next
= init
; next
&& next
< last
; )
926 str
= next_field (next
, '|', &next
, last
);
928 set_bitfield (str
, array
, 1, size
, lineno
);
938 set_bitfield (char *f
, bitfield
*array
, int value
,
939 unsigned int size
, int lineno
)
943 /* Ignore empty fields; they may result from template expansions. */
947 if (strcmp (f
, "CpuFP") == 0)
949 set_bitfield("Cpu387", array
, value
, size
, lineno
);
950 set_bitfield("Cpu287", array
, value
, size
, lineno
);
953 else if (strcmp (f
, "Mmword") == 0)
955 else if (strcmp (f
, "Oword") == 0)
958 for (i
= 0; i
< size
; i
++)
959 if (strcasecmp (array
[i
].name
, f
) == 0)
961 array
[i
].value
= value
;
967 const char *v
= strchr (f
, '=');
974 for (i
= 0; i
< size
; i
++)
975 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
977 value
= strtol (v
+ 1, &end
, 0);
980 array
[i
].value
= value
;
988 /* Handle CPU_XXX_FLAGS. */
989 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
993 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
995 fail (_("unknown bitfield: %s\n"), f
);
999 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
1000 int macro
, const char *comma
, const char *indent
)
1004 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
1006 fprintf (table
, "%s{ { ", indent
);
1008 for (i
= 0; i
< size
- 1; i
++)
1010 if (((i
+ 1) % 20) != 0)
1011 fprintf (table
, "%d, ", flags
[i
].value
);
1013 fprintf (table
, "%d,", flags
[i
].value
);
1014 if (((i
+ 1) % 20) == 0)
1016 /* We need \\ for macro. */
1018 fprintf (table
, " \\\n %s", indent
);
1020 fprintf (table
, "\n %s", indent
);
1023 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
1026 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
1030 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
1031 const char *comma
, const char *indent
,
1034 char *str
, *next
, *last
;
1036 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1038 /* Copy the default cpu flags. */
1039 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1041 if (strcasecmp (flag
, "unknown") == 0)
1043 /* We turn on everything except for cpu64 in case of
1044 CPU_UNKNOWN_FLAGS. */
1045 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1046 if (flags
[i
].position
!= Cpu64
)
1049 else if (flag
[0] == '~')
1051 last
= flag
+ strlen (flag
);
1058 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1065 /* First we turn on everything except for cpu64. */
1066 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1067 if (flags
[i
].position
!= Cpu64
)
1070 /* Turn off selective bits. */
1071 for (; next
&& next
< last
; )
1073 str
= next_field (next
, '|', &next
, last
);
1075 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1078 else if (strcmp (flag
, "0"))
1080 /* Turn on selective bits. */
1081 last
= flag
+ strlen (flag
);
1082 for (next
= flag
; next
&& next
< last
; )
1084 str
= next_field (next
, '|', &next
, last
);
1086 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1090 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1095 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1099 fprintf (table
, " { ");
1101 for (i
= 0; i
< size
- 1; i
++)
1103 if (((i
+ 1) % 20) != 0)
1104 fprintf (table
, "%d, ", modifier
[i
].value
);
1106 fprintf (table
, "%d,", modifier
[i
].value
);
1107 if (((i
+ 1) % 20) == 0)
1108 fprintf (table
, "\n ");
1111 fprintf (table
, "%d },\n", modifier
[i
].value
);
1115 adjust_broadcast_modifier (char **opnd
)
1117 char *str
, *next
, *last
, *op
;
1118 int bcst_type
= INT_MAX
;
1120 /* Skip the immediate operand. */
1122 if (strcasecmp(op
, "Imm8") == 0)
1126 last
= op
+ strlen (op
);
1127 for (next
= op
; next
&& next
< last
; )
1129 str
= next_field (next
, '|', &next
, last
);
1132 if (strcasecmp(str
, "Byte") == 0)
1134 /* The smalest broadcast type, no need to check
1136 bcst_type
= BYTE_BROADCAST
;
1139 else if (strcasecmp(str
, "Word") == 0)
1141 if (bcst_type
> WORD_BROADCAST
)
1142 bcst_type
= WORD_BROADCAST
;
1144 else if (strcasecmp(str
, "Dword") == 0)
1146 if (bcst_type
> DWORD_BROADCAST
)
1147 bcst_type
= DWORD_BROADCAST
;
1149 else if (strcasecmp(str
, "Qword") == 0)
1151 if (bcst_type
> QWORD_BROADCAST
)
1152 bcst_type
= QWORD_BROADCAST
;
1158 if (bcst_type
== INT_MAX
)
1159 fail (_("unknown broadcast operand: %s\n"), op
);
1165 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1167 char *str
, *next
, *last
;
1168 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1170 active_isstring
= 0;
1172 /* Copy the default opcode modifier. */
1173 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1175 if (strcmp (mod
, "0"))
1177 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1179 last
= mod
+ strlen (mod
);
1180 for (next
= mod
; next
&& next
< last
; )
1182 str
= next_field (next
, '|', &next
, last
);
1186 if (strcasecmp(str
, "Broadcast") == 0)
1187 val
= adjust_broadcast_modifier (opnd
);
1188 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1190 if (strcasecmp(str
, "IsString") == 0)
1191 active_isstring
= 1;
1193 if (strcasecmp(str
, "W") == 0)
1196 if (strcasecmp(str
, "No_bSuf") == 0)
1198 if (strcasecmp(str
, "No_wSuf") == 0)
1200 if (strcasecmp(str
, "No_lSuf") == 0)
1202 if (strcasecmp(str
, "No_qSuf") == 0)
1207 if (have_w
&& !bwlq_suf
)
1208 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1209 if (have_w
&& !(bwlq_suf
& 1))
1210 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1212 if (have_w
&& !(bwlq_suf
& ~1))
1214 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1217 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1227 output_operand_type (FILE *table
, enum operand_class
class,
1228 enum operand_instance instance
,
1229 const bitfield
*types
, unsigned int size
,
1230 enum stage stage
, const char *indent
)
1234 fprintf (table
, "{ { %d, %d, ", class, instance
);
1236 for (i
= 0; i
< size
- 1; i
++)
1238 if (((i
+ 3) % 20) != 0)
1239 fprintf (table
, "%d, ", types
[i
].value
);
1241 fprintf (table
, "%d,", types
[i
].value
);
1242 if (((i
+ 3) % 20) == 0)
1244 /* We need \\ for macro. */
1245 if (stage
== stage_macros
)
1246 fprintf (table
, " \\\n%s", indent
);
1248 fprintf (table
, "\n%s", indent
);
1252 fprintf (table
, "%d } }", types
[i
].value
);
1256 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1257 const char *indent
, int lineno
)
1259 char *str
, *next
, *last
;
1260 enum operand_class
class = ClassNone
;
1261 enum operand_instance instance
= InstanceNone
;
1262 bitfield types
[ARRAY_SIZE (operand_types
)];
1264 /* Copy the default operand type. */
1265 memcpy (types
, operand_types
, sizeof (types
));
1267 if (strcmp (op
, "0"))
1271 last
= op
+ strlen (op
);
1272 for (next
= op
; next
&& next
< last
; )
1274 str
= next_field (next
, '|', &next
, last
);
1279 if (!strncmp(str
, "Class=", 6))
1281 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1282 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1284 class = operand_classes
[i
].value
;
1290 if (str
&& !strncmp(str
, "Instance=", 9))
1292 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1293 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1295 instance
= operand_instances
[i
].value
;
1303 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1304 if (strcasecmp(str
, "BaseIndex") == 0)
1309 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1311 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1312 if (!active_cpu_flags
.bitfield
.cpu64
1313 && !active_cpu_flags
.bitfield
.cpumpx
)
1314 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1315 if (!active_cpu_flags
.bitfield
.cpu64
)
1316 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1317 if (!active_cpu_flags
.bitfield
.cpuno64
)
1318 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1321 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1326 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1327 char *last
, int lineno
)
1330 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1331 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1333 /* Find number of operands. */
1334 operands
= next_field (str
, ',', &str
, last
);
1336 /* Find base_opcode. */
1337 base_opcode
= next_field (str
, ',', &str
, last
);
1339 /* Find extension_opcode. */
1340 extension_opcode
= next_field (str
, ',', &str
, last
);
1342 /* Find opcode_length. */
1343 opcode_length
= next_field (str
, ',', &str
, last
);
1345 /* Find cpu_flags. */
1346 cpu_flags
= next_field (str
, ',', &str
, last
);
1348 /* Find opcode_modifier. */
1349 opcode_modifier
= next_field (str
, ',', &str
, last
);
1351 /* Remove the first {. */
1352 str
= remove_leading_whitespaces (str
);
1355 str
= remove_leading_whitespaces (str
+ 1);
1359 /* There are at least "X}". */
1363 /* Remove trailing white spaces and }. */
1367 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1376 /* Find operand_types. */
1377 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1381 operand_types
[i
] = NULL
;
1385 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1386 if (*operand_types
[i
] == '0')
1389 operand_types
[i
] = NULL
;
1394 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1395 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1397 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1399 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1401 fprintf (table
, " { ");
1403 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1405 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1408 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1414 fprintf (table
, ",\n ");
1416 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1419 fprintf (table
, " } },\n");
1422 struct opcode_hash_entry
1424 struct opcode_hash_entry
*next
;
1430 /* Calculate the hash value of an opcode hash entry P. */
1433 opcode_hash_hash (const void *p
)
1435 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1436 return htab_hash_string (entry
->name
);
1439 /* Compare a string Q against an opcode hash entry P. */
1442 opcode_hash_eq (const void *p
, const void *q
)
1444 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1445 const char *name
= (const char *) q
;
1446 return strcmp (name
, entry
->name
) == 0;
1450 parse_template (char *buf
, int lineno
)
1452 char sep
, *end
, *name
;
1453 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1454 struct template_instance
*last_inst
= NULL
;
1456 buf
= remove_leading_whitespaces (buf
+ 1);
1457 end
= strchr (buf
, ':');
1459 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1461 remove_trailing_whitespaces (buf
);
1464 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1465 tmpl
->name
= xstrdup (buf
);
1467 tmpl
->params
= NULL
;
1469 struct template_param
*param
;
1471 buf
= remove_leading_whitespaces (end
);
1472 end
= strpbrk (buf
, ":,");
1474 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1478 remove_trailing_whitespaces (buf
);
1480 param
= xmalloc (sizeof (*param
));
1481 param
->name
= xstrdup (buf
);
1482 param
->next
= tmpl
->params
;
1483 tmpl
->params
= param
;
1484 } while (sep
== ':');
1486 tmpl
->instances
= NULL
;
1488 struct template_instance
*inst
;
1490 const struct template_param
*param
;
1492 buf
= remove_leading_whitespaces (end
);
1493 end
= strpbrk (buf
, ",>");
1495 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1500 inst
= xmalloc (sizeof (*inst
));
1502 cur
= next_field (buf
, ':', &next
, end
);
1503 inst
->name
= xstrdup (cur
);
1505 for (param
= tmpl
->params
; param
; param
= param
->next
)
1507 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1509 cur
= next_field (next
, ':', &next
, end
);
1511 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1512 arg
->val
= xstrdup (cur
);
1513 arg
->next
= inst
->args
;
1517 if (tmpl
->instances
)
1518 last_inst
->next
= inst
;
1520 tmpl
->instances
= inst
;
1522 } while (sep
== ',');
1524 buf
= remove_leading_whitespaces (end
);
1526 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1527 filename
, lineno
, buf
);
1529 tmpl
->next
= templates
;
1534 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1535 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1537 static unsigned int idx
, opcode_array_size
;
1538 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1539 struct opcode_hash_entry
**hash_slot
, **entry
;
1540 char *ptr1
= strchr(name
, '<'), *ptr2
;
1544 /* Get the slot in hash table. */
1545 hash_slot
= (struct opcode_hash_entry
**)
1546 htab_find_slot_with_hash (opcode_hash_table
, name
,
1547 htab_hash_string (name
),
1550 if (*hash_slot
== NULL
)
1552 /* It is the new one. Put it on opcode array. */
1553 if (idx
>= opcode_array_size
)
1555 /* Grow the opcode array when needed. */
1556 opcode_array_size
+= 1024;
1557 opcode_array
= (struct opcode_hash_entry
**)
1558 xrealloc (opcode_array
,
1559 sizeof (*opcode_array
) * opcode_array_size
);
1560 *opcode_array_p
= opcode_array
;
1563 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1564 xmalloc (sizeof (struct opcode_hash_entry
));
1565 opcode_array
[idx
]->next
= NULL
;
1566 opcode_array
[idx
]->name
= xstrdup (name
);
1567 opcode_array
[idx
]->opcode
= xstrdup (str
);
1568 opcode_array
[idx
]->lineno
= lineno
;
1569 *hash_slot
= opcode_array
[idx
];
1574 /* Append it to the existing one. */
1576 while ((*entry
) != NULL
)
1577 entry
= &(*entry
)->next
;
1578 *entry
= (struct opcode_hash_entry
*)
1579 xmalloc (sizeof (struct opcode_hash_entry
));
1580 (*entry
)->next
= NULL
;
1581 (*entry
)->name
= (*hash_slot
)->name
;
1582 (*entry
)->opcode
= xstrdup (str
);
1583 (*entry
)->lineno
= lineno
;
1586 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1587 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1590 const struct template *tmpl
;
1591 const struct template_instance
*inst
;
1594 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1595 remove_trailing_whitespaces (ptr1
);
1599 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1600 if (!strcmp(ptr1
, tmpl
->name
))
1603 fail ("reference to unknown template '%s'\n", ptr1
);
1605 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1607 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1608 char *str2
= xmalloc(2 * strlen(str
));
1611 strcpy (name2
, name
);
1612 strcat (name2
, inst
->name
);
1613 strcat (name2
, ptr2
);
1615 for (ptr1
= str2
, src
= str
; *src
; )
1617 const char *ident
= tmpl
->name
, *end
;
1618 const struct template_param
*param
;
1619 const struct template_arg
*arg
;
1621 if ((*ptr1
= *src
++) != '<')
1626 while (ISSPACE(*src
))
1628 while (*ident
&& *src
== *ident
)
1630 while (ISSPACE(*src
))
1632 if (*src
!= ':' || *ident
!= '\0')
1634 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1635 ptr1
+= ident
- tmpl
->name
;
1638 while (ISSPACE(*++src
))
1642 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1645 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1646 param
= param
->next
, arg
= arg
->next
)
1648 if (end
- src
== strlen (param
->name
)
1649 && !memcmp (src
, param
->name
, end
- src
))
1657 fail ("template '%s' has no parameter '%.*s'\n",
1658 tmpl
->name
, (int)(end
- src
), src
);
1660 while (ISSPACE(*src
))
1663 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1665 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1666 ptr1
+= strlen(arg
->val
);
1672 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1684 process_i386_opcodes (FILE *table
)
1689 char *str
, *p
, *last
, *name
;
1690 htab_t opcode_hash_table
;
1691 struct opcode_hash_entry
**opcode_array
= NULL
;
1692 int lineno
= 0, marker
= 0;
1694 filename
= "i386-opc.tbl";
1698 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1699 opcode_hash_eq
, NULL
,
1702 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1703 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1705 /* Put everything on opcode array. */
1708 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1713 p
= remove_leading_whitespaces (buf
);
1715 /* Skip comments. */
1716 str
= strstr (p
, "//");
1720 /* Remove trailing white spaces. */
1721 remove_trailing_whitespaces (p
);
1726 if (!strcmp("### MARKER ###", buf
))
1730 /* Since we ignore all included files (we only care about their
1731 #define-s here), we don't need to monitor filenames. The final
1732 line number directive is going to refer to the main source file
1737 p
= remove_leading_whitespaces (p
+ 1);
1738 if (!strncmp(p
, "line", 4))
1740 ln
= strtoul (p
, &end
, 10);
1741 if (ln
> 1 && ln
< INT_MAX
1742 && *remove_leading_whitespaces (end
) == '"')
1745 /* Ignore comments. */
1750 parse_template (p
, lineno
);
1758 last
= p
+ strlen (p
);
1761 name
= next_field (p
, ',', &str
, last
);
1763 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1767 /* Process opcode array. */
1768 for (j
= 0; j
< i
; j
++)
1770 struct opcode_hash_entry
*next
;
1772 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1776 lineno
= next
->lineno
;
1777 last
= str
+ strlen (str
);
1778 output_i386_opcode (table
, name
, str
, last
, lineno
);
1784 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1786 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1788 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1790 fprintf (table
, " { ");
1791 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1792 fprintf (table
, " } }\n");
1794 fprintf (table
, "};\n");
1798 process_i386_registers (FILE *table
)
1802 char *str
, *p
, *last
;
1803 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1804 char *dw2_32_num
, *dw2_64_num
;
1807 filename
= "i386-reg.tbl";
1808 fp
= fopen (filename
, "r");
1810 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1813 fprintf (table
, "\n/* i386 register table. */\n\n");
1814 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1818 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1823 p
= remove_leading_whitespaces (buf
);
1825 /* Skip comments. */
1826 str
= strstr (p
, "//");
1830 /* Remove trailing white spaces. */
1831 remove_trailing_whitespaces (p
);
1836 fprintf (table
, "%s\n", p
);
1844 last
= p
+ strlen (p
);
1846 /* Find reg_name. */
1847 reg_name
= next_field (p
, ',', &str
, last
);
1849 /* Find reg_type. */
1850 reg_type
= next_field (str
, ',', &str
, last
);
1852 /* Find reg_flags. */
1853 reg_flags
= next_field (str
, ',', &str
, last
);
1856 reg_num
= next_field (str
, ',', &str
, last
);
1858 fprintf (table
, " { \"%s\",\n ", reg_name
);
1860 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1863 /* Find 32-bit Dwarf2 register number. */
1864 dw2_32_num
= next_field (str
, ',', &str
, last
);
1866 /* Find 64-bit Dwarf2 register number. */
1867 dw2_64_num
= next_field (str
, ',', &str
, last
);
1869 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1870 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1875 fprintf (table
, "};\n");
1877 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1881 process_i386_initializers (void)
1884 FILE *fp
= fopen ("i386-init.h", "w");
1888 fail (_("can't create i386-init.h, errno = %s\n"),
1891 process_copyright (fp
);
1893 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1895 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1896 init
= xstrdup (cpu_flag_init
[i
].init
);
1897 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1901 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1903 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1904 init
= xstrdup (operand_type_init
[i
].init
);
1905 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1913 /* Program options. */
1914 #define OPTION_SRCDIR 200
1916 struct option long_options
[] =
1918 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1919 {"debug", no_argument
, NULL
, 'd'},
1920 {"version", no_argument
, NULL
, 'V'},
1921 {"help", no_argument
, NULL
, 'h'},
1922 {0, no_argument
, NULL
, 0}
1926 print_version (void)
1928 printf ("%s: version 1.0\n", program_name
);
1933 usage (FILE * stream
, int status
)
1935 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1941 main (int argc
, char **argv
)
1943 extern int chdir (char *);
1944 char *srcdir
= NULL
;
1946 unsigned int i
, cpumax
;
1949 program_name
= *argv
;
1950 xmalloc_set_program_name (program_name
);
1952 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1977 if (chdir (srcdir
) != 0)
1978 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1979 srcdir
, xstrerror (errno
));
1981 /* cpu_flags isn't sorted by position. */
1983 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1984 if (cpu_flags
[i
].position
> cpumax
)
1985 cpumax
= cpu_flags
[i
].position
;
1987 /* Check the unused bitfield in i386_cpu_flags. */
1989 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
1991 if ((cpumax
- 1) != CpuMax
)
1992 fail (_("CpuMax != %d!\n"), cpumax
);
1994 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
1996 if (cpumax
!= CpuMax
)
1997 fail (_("CpuMax != %d!\n"), cpumax
);
1999 c
= CpuNumOfBits
- CpuMax
- 1;
2001 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
2004 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2006 /* Check the unused bitfield in i386_operand_type. */
2008 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2011 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2014 c
= OTNumOfBits
- OTNum
;
2016 fail (_("%d unused bits in i386_operand_type.\n"), c
);
2019 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2022 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2023 sizeof (opcode_modifiers
[0]), compare
);
2025 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2026 sizeof (operand_types
[0]), compare
);
2028 table
= fopen ("i386-tbl.h", "w");
2030 fail (_("can't create i386-tbl.h, errno = %s\n"),
2033 process_copyright (table
);
2035 process_i386_opcodes (table
);
2036 process_i386_registers (table
);
2037 process_i386_initializers ();