1 /* Copyright (C) 2007-2021 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" },
251 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
254 { "CPU_RDSEED_FLAGS",
256 { "CPU_PRFCHW_FLAGS",
261 "CPU_XSAVE_FLAGS|CpuMPX" },
263 "CPU_SSE2_FLAGS|CpuSHA" },
264 { "CPU_CLFLUSHOPT_FLAGS",
266 { "CPU_XSAVES_FLAGS",
267 "CPU_XSAVE_FLAGS|CpuXSAVES" },
268 { "CPU_XSAVEC_FLAGS",
269 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
270 { "CPU_PREFETCHWT1_FLAGS",
276 { "CPU_CLZERO_FLAGS",
278 { "CPU_MWAITX_FLAGS",
281 "CPU_XSAVE_FLAGS|CpuOSPKE" },
284 { "CPU_PTWRITE_FLAGS",
294 { "CPU_VPCLMULQDQ_FLAGS",
296 { "CPU_WBNOINVD_FLAGS",
298 { "CPU_PCONFIG_FLAGS",
300 { "CPU_WAITPKG_FLAGS",
304 { "CPU_CLDEMOTE_FLAGS",
306 { "CPU_AMX_INT8_FLAGS",
308 { "CPU_AMX_BF16_FLAGS",
310 { "CPU_AMX_TILE_FLAGS",
312 { "CPU_MOVDIRI_FLAGS",
314 { "CPU_MOVDIR64B_FLAGS",
316 { "CPU_ENQCMD_FLAGS",
318 { "CPU_SERIALIZE_FLAGS",
320 { "CPU_AVX512_VP2INTERSECT_FLAGS",
321 "CpuAVX512_VP2INTERSECT" },
326 { "CPU_MCOMMIT_FLAGS",
328 { "CPU_SEV_ES_FLAGS",
330 { "CPU_TSXLDTRK_FLAGS",
334 { "CPU_WIDEKL_FLAGS",
336 { "CPU_HRESET_FLAGS",
338 { "CPU_INVLPGB_FLAGS",
340 { "CPU_TLBSYNC_FLAGS",
344 { "CPU_ANY_X87_FLAGS",
345 "CPU_ANY_287_FLAGS|Cpu8087" },
346 { "CPU_ANY_287_FLAGS",
347 "CPU_ANY_387_FLAGS|Cpu287" },
348 { "CPU_ANY_387_FLAGS",
349 "CPU_ANY_687_FLAGS|Cpu387" },
350 { "CPU_ANY_687_FLAGS",
351 "Cpu687|CpuFISTTP" },
352 { "CPU_ANY_CMOV_FLAGS",
354 { "CPU_ANY_FXSR_FLAGS",
356 { "CPU_ANY_MMX_FLAGS",
357 "CPU_3DNOWA_FLAGS" },
358 { "CPU_ANY_SSE_FLAGS",
359 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
360 { "CPU_ANY_SSE2_FLAGS",
361 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
362 { "CPU_ANY_SSE3_FLAGS",
363 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
364 { "CPU_ANY_SSSE3_FLAGS",
365 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
366 { "CPU_ANY_SSE4_1_FLAGS",
367 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
368 { "CPU_ANY_SSE4_2_FLAGS",
370 { "CPU_ANY_SSE4A_FLAGS",
372 { "CPU_ANY_AVX_FLAGS",
373 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
374 { "CPU_ANY_AVX2_FLAGS",
375 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
376 { "CPU_ANY_AVX512F_FLAGS",
377 "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" },
378 { "CPU_ANY_AVX512CD_FLAGS",
380 { "CPU_ANY_AVX512ER_FLAGS",
382 { "CPU_ANY_AVX512PF_FLAGS",
384 { "CPU_ANY_AVX512DQ_FLAGS",
386 { "CPU_ANY_AVX512BW_FLAGS",
388 { "CPU_ANY_AVX512VL_FLAGS",
390 { "CPU_ANY_AVX512IFMA_FLAGS",
392 { "CPU_ANY_AVX512VBMI_FLAGS",
394 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
395 "CpuAVX512_4FMAPS" },
396 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
397 "CpuAVX512_4VNNIW" },
398 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
399 "CpuAVX512_VPOPCNTDQ" },
400 { "CPU_ANY_IBT_FLAGS",
402 { "CPU_ANY_SHSTK_FLAGS",
404 { "CPU_ANY_AVX512_VBMI2_FLAGS",
406 { "CPU_ANY_AVX512_VNNI_FLAGS",
408 { "CPU_ANY_AVX512_BITALG_FLAGS",
409 "CpuAVX512_BITALG" },
410 { "CPU_ANY_AVX512_BF16_FLAGS",
412 { "CPU_ANY_AMX_INT8_FLAGS",
414 { "CPU_ANY_AMX_BF16_FLAGS",
416 { "CPU_ANY_AMX_TILE_FLAGS",
417 "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" },
418 { "CPU_ANY_AVX_VNNI_FLAGS",
420 { "CPU_ANY_MOVDIRI_FLAGS",
422 { "CPU_ANY_UINTR_FLAGS",
424 { "CPU_ANY_MOVDIR64B_FLAGS",
426 { "CPU_ANY_ENQCMD_FLAGS",
428 { "CPU_ANY_SERIALIZE_FLAGS",
430 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
431 "CpuAVX512_VP2INTERSECT" },
432 { "CPU_ANY_TDX_FLAGS",
434 { "CPU_ANY_TSXLDTRK_FLAGS",
436 { "CPU_ANY_KL_FLAGS",
438 { "CPU_ANY_WIDEKL_FLAGS",
440 { "CPU_ANY_HRESET_FLAGS",
444 static initializer operand_type_init
[] =
446 { "OPERAND_TYPE_NONE",
448 { "OPERAND_TYPE_REG8",
450 { "OPERAND_TYPE_REG16",
452 { "OPERAND_TYPE_REG32",
454 { "OPERAND_TYPE_REG64",
456 { "OPERAND_TYPE_IMM1",
458 { "OPERAND_TYPE_IMM8",
460 { "OPERAND_TYPE_IMM8S",
462 { "OPERAND_TYPE_IMM16",
464 { "OPERAND_TYPE_IMM32",
466 { "OPERAND_TYPE_IMM32S",
468 { "OPERAND_TYPE_IMM64",
470 { "OPERAND_TYPE_BASEINDEX",
472 { "OPERAND_TYPE_DISP8",
474 { "OPERAND_TYPE_DISP16",
476 { "OPERAND_TYPE_DISP32",
478 { "OPERAND_TYPE_DISP32S",
480 { "OPERAND_TYPE_DISP64",
482 { "OPERAND_TYPE_INOUTPORTREG",
483 "Instance=RegD|Word" },
484 { "OPERAND_TYPE_SHIFTCOUNT",
485 "Instance=RegC|Byte" },
486 { "OPERAND_TYPE_CONTROL",
488 { "OPERAND_TYPE_TEST",
490 { "OPERAND_TYPE_DEBUG",
492 { "OPERAND_TYPE_FLOATREG",
494 { "OPERAND_TYPE_FLOATACC",
495 "Instance=Accum|Tbyte" },
496 { "OPERAND_TYPE_SREG",
498 { "OPERAND_TYPE_REGMMX",
500 { "OPERAND_TYPE_REGXMM",
501 "Class=RegSIMD|Xmmword" },
502 { "OPERAND_TYPE_REGYMM",
503 "Class=RegSIMD|Ymmword" },
504 { "OPERAND_TYPE_REGZMM",
505 "Class=RegSIMD|Zmmword" },
506 { "OPERAND_TYPE_REGTMM",
507 "Class=RegSIMD|Tmmword" },
508 { "OPERAND_TYPE_REGMASK",
510 { "OPERAND_TYPE_REGBND",
512 { "OPERAND_TYPE_ACC8",
513 "Instance=Accum|Byte" },
514 { "OPERAND_TYPE_ACC16",
515 "Instance=Accum|Word" },
516 { "OPERAND_TYPE_ACC32",
517 "Instance=Accum|Dword" },
518 { "OPERAND_TYPE_ACC64",
519 "Instance=Accum|Qword" },
520 { "OPERAND_TYPE_DISP16_32",
522 { "OPERAND_TYPE_ANYDISP",
523 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
524 { "OPERAND_TYPE_IMM16_32",
526 { "OPERAND_TYPE_IMM16_32S",
528 { "OPERAND_TYPE_IMM16_32_32S",
529 "Imm16|Imm32|Imm32S" },
530 { "OPERAND_TYPE_IMM32_64",
532 { "OPERAND_TYPE_IMM32_32S_DISP32",
533 "Imm32|Imm32S|Disp32" },
534 { "OPERAND_TYPE_IMM64_DISP64",
536 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
537 "Imm32|Imm32S|Imm64|Disp32" },
538 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
539 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
540 { "OPERAND_TYPE_ANYIMM",
541 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
544 typedef struct bitfield
551 #define BITFIELD(n) { n, 0, #n }
553 static bitfield cpu_flags
[] =
563 BITFIELD (CpuClflush
),
565 BITFIELD (CpuSYSCALL
),
570 BITFIELD (CpuFISTTP
),
576 BITFIELD (CpuSSE4_1
),
577 BITFIELD (CpuSSE4_2
),
580 BITFIELD (CpuAVX512F
),
581 BITFIELD (CpuAVX512CD
),
582 BITFIELD (CpuAVX512ER
),
583 BITFIELD (CpuAVX512PF
),
584 BITFIELD (CpuAVX512VL
),
585 BITFIELD (CpuAVX512DQ
),
586 BITFIELD (CpuAVX512BW
),
592 BITFIELD (Cpu3dnowA
),
593 BITFIELD (CpuPadLock
),
598 BITFIELD (CpuXsaveopt
),
600 BITFIELD (CpuPCLMUL
),
611 BITFIELD (CpuRdtscp
),
612 BITFIELD (CpuFSGSBase
),
617 BITFIELD (CpuPOPCNT
),
620 BITFIELD (CpuINVPCID
),
621 BITFIELD (CpuVMFUNC
),
622 BITFIELD (CpuRDSEED
),
624 BITFIELD (CpuPRFCHW
),
627 BITFIELD (CpuClflushOpt
),
628 BITFIELD (CpuXSAVES
),
629 BITFIELD (CpuXSAVEC
),
630 BITFIELD (CpuPREFETCHWT1
),
636 BITFIELD (CpuAVX512IFMA
),
637 BITFIELD (CpuAVX512VBMI
),
638 BITFIELD (CpuAVX512_4FMAPS
),
639 BITFIELD (CpuAVX512_4VNNIW
),
640 BITFIELD (CpuAVX512_VPOPCNTDQ
),
641 BITFIELD (CpuAVX512_VBMI2
),
642 BITFIELD (CpuAVX512_VNNI
),
643 BITFIELD (CpuAVX512_BITALG
),
644 BITFIELD (CpuAVX512_BF16
),
645 BITFIELD (CpuAVX512_VP2INTERSECT
),
647 BITFIELD (CpuAVX_VNNI
),
648 BITFIELD (CpuMWAITX
),
649 BITFIELD (CpuCLZERO
),
652 BITFIELD (CpuPTWRITE
),
657 BITFIELD (CpuVPCLMULQDQ
),
658 BITFIELD (CpuWBNOINVD
),
659 BITFIELD (CpuPCONFIG
),
660 BITFIELD (CpuWAITPKG
),
662 BITFIELD (CpuCLDEMOTE
),
663 BITFIELD (CpuAMX_INT8
),
664 BITFIELD (CpuAMX_BF16
),
665 BITFIELD (CpuAMX_TILE
),
666 BITFIELD (CpuMOVDIRI
),
667 BITFIELD (CpuMOVDIR64B
),
668 BITFIELD (CpuENQCMD
),
669 BITFIELD (CpuSERIALIZE
),
671 BITFIELD (CpuMCOMMIT
),
672 BITFIELD (CpuSEV_ES
),
673 BITFIELD (CpuTSXLDTRK
),
675 BITFIELD (CpuWideKL
),
676 BITFIELD (CpuHRESET
),
677 BITFIELD (CpuINVLPGB
),
678 BITFIELD (CpuTLBSYNC
),
681 BITFIELD (CpuUnused
),
685 static bitfield opcode_modifiers
[] =
695 BITFIELD (CheckRegSize
),
696 BITFIELD (MnemonicSize
),
707 BITFIELD (BNDPrefixOk
),
708 BITFIELD (RegKludge
),
709 BITFIELD (Implicit1stXmm0
),
713 BITFIELD (AddrPrefixOpReg
),
718 BITFIELD (PseudoVexPrefix
),
722 BITFIELD (OpcodeSpace
),
723 BITFIELD (OpcodePrefix
),
724 BITFIELD (VexSources
),
730 BITFIELD (Broadcast
),
731 BITFIELD (StaticRounding
),
733 BITFIELD (Disp8MemShift
),
734 BITFIELD (NoDefMask
),
735 BITFIELD (ImplicitQuadGroup
),
736 BITFIELD (SwapSources
),
738 BITFIELD (ATTMnemonic
),
739 BITFIELD (ATTSyntax
),
740 BITFIELD (IntelSyntax
),
744 #define CLASS(n) #n, n
746 static const struct {
748 enum operand_class value
;
749 } operand_classes
[] = {
763 #define INSTANCE(n) #n, n
765 static const struct {
767 enum operand_instance value
;
768 } operand_instances
[] = {
777 static bitfield operand_types
[] =
786 BITFIELD (BaseIndex
),
802 BITFIELD (Unspecified
),
808 static const char *filename
;
809 static i386_cpu_flags active_cpu_flags
;
810 static int active_isstring
;
812 struct template_arg
{
813 const struct template_arg
*next
;
817 struct template_instance
{
818 const struct template_instance
*next
;
820 const struct template_arg
*args
;
823 struct template_param
{
824 const struct template_param
*next
;
829 const struct template *next
;
831 const struct template_instance
*instances
;
832 const struct template_param
*params
;
835 static const struct template *templates
;
838 compare (const void *x
, const void *y
)
840 const bitfield
*xp
= (const bitfield
*) x
;
841 const bitfield
*yp
= (const bitfield
*) y
;
842 return xp
->position
- yp
->position
;
846 fail (const char *message
, ...)
850 va_start (args
, message
);
851 fprintf (stderr
, _("%s: error: "), program_name
);
852 vfprintf (stderr
, message
, args
);
858 process_copyright (FILE *fp
)
860 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
861 /* Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\
863 This file is part of the GNU opcodes library.\n\
865 This library is free software; you can redistribute it and/or modify\n\
866 it under the terms of the GNU General Public License as published by\n\
867 the Free Software Foundation; either version 3, or (at your option)\n\
868 any later version.\n\
870 It is distributed in the hope that it will be useful, but WITHOUT\n\
871 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
872 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
873 License for more details.\n\
875 You should have received a copy of the GNU General Public License\n\
876 along with this program; if not, write to the Free Software\n\
877 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
878 MA 02110-1301, USA. */\n");
881 /* Remove leading white spaces. */
884 remove_leading_whitespaces (char *str
)
886 while (ISSPACE (*str
))
891 /* Remove trailing white spaces. */
894 remove_trailing_whitespaces (char *str
)
896 size_t last
= strlen (str
);
904 if (ISSPACE (str
[last
]))
912 /* Find next field separated by SEP and terminate it. Return a
913 pointer to the one after it. */
916 next_field (char *str
, char sep
, char **next
, char *last
)
920 p
= remove_leading_whitespaces (str
);
921 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
924 remove_trailing_whitespaces (p
);
934 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
937 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
940 char *str
, *next
, *last
;
943 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
944 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
946 /* Turn on selective bits. */
947 char *init
= xstrdup (cpu_flag_init
[i
].init
);
948 last
= init
+ strlen (init
);
949 for (next
= init
; next
&& next
< last
; )
951 str
= next_field (next
, '|', &next
, last
);
953 set_bitfield (str
, array
, 1, size
, lineno
);
963 set_bitfield (char *f
, bitfield
*array
, int value
,
964 unsigned int size
, int lineno
)
968 /* Ignore empty fields; they may result from template expansions. */
972 for (i
= 0; i
< size
; i
++)
973 if (strcasecmp (array
[i
].name
, f
) == 0)
975 array
[i
].value
= value
;
981 const char *v
= strchr (f
, '=');
988 for (i
= 0; i
< size
; i
++)
989 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
991 value
= strtol (v
+ 1, &end
, 0);
994 array
[i
].value
= value
;
1002 /* Handle CPU_XXX_FLAGS. */
1003 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
1007 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
1009 fail (_("unknown bitfield: %s\n"), f
);
1013 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
1014 int macro
, const char *comma
, const char *indent
)
1018 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
1020 fprintf (table
, "%s{ { ", indent
);
1022 for (i
= 0; i
< size
- 1; i
++)
1024 if (((i
+ 1) % 20) != 0)
1025 fprintf (table
, "%d, ", flags
[i
].value
);
1027 fprintf (table
, "%d,", flags
[i
].value
);
1028 if (((i
+ 1) % 20) == 0)
1030 /* We need \\ for macro. */
1032 fprintf (table
, " \\\n %s", indent
);
1034 fprintf (table
, "\n %s", indent
);
1037 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
1040 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
1044 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
1045 const char *comma
, const char *indent
,
1048 char *str
, *next
, *last
;
1050 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1052 /* Copy the default cpu flags. */
1053 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1055 if (strcasecmp (flag
, "unknown") == 0)
1057 /* We turn on everything except for cpu64 in case of
1058 CPU_UNKNOWN_FLAGS. */
1059 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1060 if (flags
[i
].position
!= Cpu64
)
1063 else if (flag
[0] == '~')
1065 last
= flag
+ strlen (flag
);
1072 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1079 /* First we turn on everything except for cpu64. */
1080 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1081 if (flags
[i
].position
!= Cpu64
)
1084 /* Turn off selective bits. */
1085 for (; next
&& next
< last
; )
1087 str
= next_field (next
, '|', &next
, last
);
1089 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1092 else if (strcmp (flag
, "0"))
1094 /* Turn on selective bits. */
1095 last
= flag
+ strlen (flag
);
1096 for (next
= flag
; next
&& next
< last
; )
1098 str
= next_field (next
, '|', &next
, last
);
1100 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1104 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1109 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1113 fprintf (table
, " { ");
1115 for (i
= 0; i
< size
- 1; i
++)
1117 if (((i
+ 1) % 20) != 0)
1118 fprintf (table
, "%d, ", modifier
[i
].value
);
1120 fprintf (table
, "%d,", modifier
[i
].value
);
1121 if (((i
+ 1) % 20) == 0)
1122 fprintf (table
, "\n ");
1125 fprintf (table
, "%d },\n", modifier
[i
].value
);
1129 adjust_broadcast_modifier (char **opnd
)
1131 char *str
, *next
, *last
, *op
;
1132 int bcst_type
= INT_MAX
;
1134 /* Skip the immediate operand. */
1136 if (strcasecmp(op
, "Imm8") == 0)
1140 last
= op
+ strlen (op
);
1141 for (next
= op
; next
&& next
< last
; )
1143 str
= next_field (next
, '|', &next
, last
);
1146 if (strcasecmp(str
, "Byte") == 0)
1148 /* The smalest broadcast type, no need to check
1150 bcst_type
= BYTE_BROADCAST
;
1153 else if (strcasecmp(str
, "Word") == 0)
1155 if (bcst_type
> WORD_BROADCAST
)
1156 bcst_type
= WORD_BROADCAST
;
1158 else if (strcasecmp(str
, "Dword") == 0)
1160 if (bcst_type
> DWORD_BROADCAST
)
1161 bcst_type
= DWORD_BROADCAST
;
1163 else if (strcasecmp(str
, "Qword") == 0)
1165 if (bcst_type
> QWORD_BROADCAST
)
1166 bcst_type
= QWORD_BROADCAST
;
1172 if (bcst_type
== INT_MAX
)
1173 fail (_("unknown broadcast operand: %s\n"), op
);
1179 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1181 char *str
, *next
, *last
;
1182 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1183 unsigned int regular_encoding
= 1;
1185 active_isstring
= 0;
1187 /* Copy the default opcode modifier. */
1188 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1190 if (strcmp (mod
, "0"))
1192 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1194 last
= mod
+ strlen (mod
);
1195 for (next
= mod
; next
&& next
< last
; )
1197 str
= next_field (next
, '|', &next
, last
);
1201 if (strcasecmp(str
, "Broadcast") == 0)
1203 val
= adjust_broadcast_modifier (opnd
);
1204 regular_encoding
= 0;
1206 else if (strcasecmp(str
, "Vex") == 0
1207 || strncasecmp(str
, "Vex=", 4) == 0
1208 || strcasecmp(str
, "EVex") == 0
1209 || strncasecmp(str
, "EVex=", 5) == 0
1210 || strncasecmp(str
, "Disp8MemShift=", 14) == 0
1211 || strncasecmp(str
, "Masking=", 8) == 0
1212 || strcasecmp(str
, "SAE") == 0)
1213 regular_encoding
= 0;
1215 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1217 if (strcasecmp(str
, "IsString") == 0)
1218 active_isstring
= 1;
1220 if (strcasecmp(str
, "W") == 0)
1223 if (strcasecmp(str
, "No_bSuf") == 0)
1225 if (strcasecmp(str
, "No_wSuf") == 0)
1227 if (strcasecmp(str
, "No_lSuf") == 0)
1229 if (strcasecmp(str
, "No_qSuf") == 0)
1234 if (have_w
&& !bwlq_suf
)
1235 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1236 if (have_w
&& !(bwlq_suf
& 1))
1237 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1239 if (have_w
&& !(bwlq_suf
& ~1))
1241 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1244 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1246 return regular_encoding
;
1256 output_operand_type (FILE *table
, enum operand_class
class,
1257 enum operand_instance instance
,
1258 const bitfield
*types
, unsigned int size
,
1259 enum stage stage
, const char *indent
)
1263 fprintf (table
, "{ { %d, %d, ", class, instance
);
1265 for (i
= 0; i
< size
- 1; i
++)
1267 if (((i
+ 3) % 20) != 0)
1268 fprintf (table
, "%d, ", types
[i
].value
);
1270 fprintf (table
, "%d,", types
[i
].value
);
1271 if (((i
+ 3) % 20) == 0)
1273 /* We need \\ for macro. */
1274 if (stage
== stage_macros
)
1275 fprintf (table
, " \\\n%s", indent
);
1277 fprintf (table
, "\n%s", indent
);
1281 fprintf (table
, "%d } }", types
[i
].value
);
1285 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1286 const char *indent
, int lineno
)
1288 char *str
, *next
, *last
;
1289 enum operand_class
class = ClassNone
;
1290 enum operand_instance instance
= InstanceNone
;
1291 bitfield types
[ARRAY_SIZE (operand_types
)];
1293 /* Copy the default operand type. */
1294 memcpy (types
, operand_types
, sizeof (types
));
1296 if (strcmp (op
, "0"))
1300 last
= op
+ strlen (op
);
1301 for (next
= op
; next
&& next
< last
; )
1303 str
= next_field (next
, '|', &next
, last
);
1308 if (!strncmp(str
, "Class=", 6))
1310 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1311 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1313 class = operand_classes
[i
].value
;
1319 if (str
&& !strncmp(str
, "Instance=", 9))
1321 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1322 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1324 instance
= operand_instances
[i
].value
;
1332 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1333 if (strcasecmp(str
, "BaseIndex") == 0)
1338 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1340 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1341 if (!active_cpu_flags
.bitfield
.cpu64
1342 && !active_cpu_flags
.bitfield
.cpumpx
)
1343 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1344 if (!active_cpu_flags
.bitfield
.cpu64
)
1345 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1346 if (!active_cpu_flags
.bitfield
.cpuno64
)
1347 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1350 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1355 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1356 char *last
, int lineno
)
1359 char *base_opcode
, *extension_opcode
, *opcode_length
;
1360 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1362 /* Find base_opcode. */
1363 base_opcode
= next_field (str
, ',', &str
, last
);
1365 /* Find extension_opcode. */
1366 extension_opcode
= next_field (str
, ',', &str
, last
);
1368 /* Find opcode_length. */
1369 opcode_length
= next_field (str
, ',', &str
, last
);
1371 /* Find cpu_flags. */
1372 cpu_flags
= next_field (str
, ',', &str
, last
);
1374 /* Find opcode_modifier. */
1375 opcode_modifier
= next_field (str
, ',', &str
, last
);
1377 /* Remove the first {. */
1378 str
= remove_leading_whitespaces (str
);
1381 str
= remove_leading_whitespaces (str
+ 1);
1382 remove_trailing_whitespaces (str
);
1384 /* Remove } and trailing white space. */
1386 if (!i
|| str
[i
- 1] != '}')
1389 remove_trailing_whitespaces (str
);
1392 operand_types
[i
= 0] = NULL
;
1395 last
= str
+ strlen (str
);
1397 /* Find operand_types. */
1398 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1402 operand_types
[i
] = NULL
;
1406 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1410 fprintf (table
, " { \"%s\", %s, %s, %s, %u,\n",
1411 name
, base_opcode
, extension_opcode
, opcode_length
, i
);
1413 if (process_i386_opcode_modifier (table
, opcode_modifier
,
1414 operand_types
, lineno
))
1417 unsigned long int length
= strtoul (opcode_length
, &end
, 0);
1418 unsigned long int opcode
= strtoul (base_opcode
, &end
, 0);
1424 if ((opcode
>> 24) != 0)
1425 fail (_("%s: %s: (base_opcode >> 24) != 0: %s\n"),
1426 filename
, name
, base_opcode
);
1429 if ((opcode
>> 16) != 0)
1430 fail (_("%s: %s: (base_opcode >> 16) != 0: %s\n"),
1431 filename
, name
, base_opcode
);
1434 if ((opcode
>> 8) != 0)
1435 fail (_("%s: %s: (base_opcode >> 8) != 0: %s\n"),
1436 filename
, name
, base_opcode
);
1440 fail (_("%s: %s: base_opcode != 0: %s\n"),
1441 filename
, name
, base_opcode
);
1444 fail (_("%s: %s: invalid opcode length: %s\n"),
1445 filename
, name
, opcode_length
);
1450 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1452 fprintf (table
, " { ");
1454 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1456 if (!operand_types
[i
])
1459 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1465 fprintf (table
, ",\n ");
1467 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1470 fprintf (table
, " } },\n");
1473 struct opcode_hash_entry
1475 struct opcode_hash_entry
*next
;
1481 /* Calculate the hash value of an opcode hash entry P. */
1484 opcode_hash_hash (const void *p
)
1486 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1487 return htab_hash_string (entry
->name
);
1490 /* Compare a string Q against an opcode hash entry P. */
1493 opcode_hash_eq (const void *p
, const void *q
)
1495 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1496 const char *name
= (const char *) q
;
1497 return strcmp (name
, entry
->name
) == 0;
1501 parse_template (char *buf
, int lineno
)
1503 char sep
, *end
, *name
;
1504 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1505 struct template_instance
*last_inst
= NULL
;
1507 buf
= remove_leading_whitespaces (buf
+ 1);
1508 end
= strchr (buf
, ':');
1510 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1512 remove_trailing_whitespaces (buf
);
1515 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1516 tmpl
->name
= xstrdup (buf
);
1518 tmpl
->params
= NULL
;
1520 struct template_param
*param
;
1522 buf
= remove_leading_whitespaces (end
);
1523 end
= strpbrk (buf
, ":,");
1525 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1529 remove_trailing_whitespaces (buf
);
1531 param
= xmalloc (sizeof (*param
));
1532 param
->name
= xstrdup (buf
);
1533 param
->next
= tmpl
->params
;
1534 tmpl
->params
= param
;
1535 } while (sep
== ':');
1537 tmpl
->instances
= NULL
;
1539 struct template_instance
*inst
;
1541 const struct template_param
*param
;
1543 buf
= remove_leading_whitespaces (end
);
1544 end
= strpbrk (buf
, ",>");
1546 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1551 inst
= xmalloc (sizeof (*inst
));
1555 cur
= next_field (buf
, ':', &next
, end
);
1556 inst
->name
= xstrdup (cur
);
1558 for (param
= tmpl
->params
; param
; param
= param
->next
)
1560 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1562 cur
= next_field (next
, ':', &next
, end
);
1564 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1565 arg
->val
= xstrdup (cur
);
1566 arg
->next
= inst
->args
;
1570 if (tmpl
->instances
)
1571 last_inst
->next
= inst
;
1573 tmpl
->instances
= inst
;
1575 } while (sep
== ',');
1577 buf
= remove_leading_whitespaces (end
);
1579 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1580 filename
, lineno
, buf
);
1582 tmpl
->next
= templates
;
1587 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1588 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1590 static unsigned int idx
, opcode_array_size
;
1591 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1592 struct opcode_hash_entry
**hash_slot
, **entry
;
1593 char *ptr1
= strchr(name
, '<'), *ptr2
;
1597 /* Get the slot in hash table. */
1598 hash_slot
= (struct opcode_hash_entry
**)
1599 htab_find_slot_with_hash (opcode_hash_table
, name
,
1600 htab_hash_string (name
),
1603 if (*hash_slot
== NULL
)
1605 /* It is the new one. Put it on opcode array. */
1606 if (idx
>= opcode_array_size
)
1608 /* Grow the opcode array when needed. */
1609 opcode_array_size
+= 1024;
1610 opcode_array
= (struct opcode_hash_entry
**)
1611 xrealloc (opcode_array
,
1612 sizeof (*opcode_array
) * opcode_array_size
);
1613 *opcode_array_p
= opcode_array
;
1616 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1617 xmalloc (sizeof (struct opcode_hash_entry
));
1618 opcode_array
[idx
]->next
= NULL
;
1619 opcode_array
[idx
]->name
= xstrdup (name
);
1620 opcode_array
[idx
]->opcode
= xstrdup (str
);
1621 opcode_array
[idx
]->lineno
= lineno
;
1622 *hash_slot
= opcode_array
[idx
];
1627 /* Append it to the existing one. */
1629 while ((*entry
) != NULL
)
1630 entry
= &(*entry
)->next
;
1631 *entry
= (struct opcode_hash_entry
*)
1632 xmalloc (sizeof (struct opcode_hash_entry
));
1633 (*entry
)->next
= NULL
;
1634 (*entry
)->name
= (*hash_slot
)->name
;
1635 (*entry
)->opcode
= xstrdup (str
);
1636 (*entry
)->lineno
= lineno
;
1639 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1640 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1643 const struct template *tmpl
;
1644 const struct template_instance
*inst
;
1647 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1648 remove_trailing_whitespaces (ptr1
);
1652 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1653 if (!strcmp(ptr1
, tmpl
->name
))
1656 fail ("reference to unknown template '%s'\n", ptr1
);
1658 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1660 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1661 char *str2
= xmalloc(2 * strlen(str
));
1664 strcpy (name2
, name
);
1665 strcat (name2
, inst
->name
);
1666 strcat (name2
, ptr2
);
1668 for (ptr1
= str2
, src
= str
; *src
; )
1670 const char *ident
= tmpl
->name
, *end
;
1671 const struct template_param
*param
;
1672 const struct template_arg
*arg
;
1674 if ((*ptr1
= *src
++) != '<')
1679 while (ISSPACE(*src
))
1681 while (*ident
&& *src
== *ident
)
1683 while (ISSPACE(*src
))
1685 if (*src
!= ':' || *ident
!= '\0')
1687 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1688 ptr1
+= ident
- tmpl
->name
;
1691 while (ISSPACE(*++src
))
1695 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1698 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1699 param
= param
->next
, arg
= arg
->next
)
1701 if (end
- src
== strlen (param
->name
)
1702 && !memcmp (src
, param
->name
, end
- src
))
1710 fail ("template '%s' has no parameter '%.*s'\n",
1711 tmpl
->name
, (int)(end
- src
), src
);
1713 while (ISSPACE(*src
))
1716 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1718 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1719 ptr1
+= strlen(arg
->val
);
1725 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1737 process_i386_opcodes (FILE *table
)
1742 char *str
, *p
, *last
, *name
;
1743 htab_t opcode_hash_table
;
1744 struct opcode_hash_entry
**opcode_array
= NULL
;
1745 int lineno
= 0, marker
= 0;
1747 filename
= "i386-opc.tbl";
1751 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1752 opcode_hash_eq
, NULL
,
1755 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1756 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1758 /* Put everything on opcode array. */
1761 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1766 p
= remove_leading_whitespaces (buf
);
1768 /* Skip comments. */
1769 str
= strstr (p
, "//");
1773 /* Remove trailing white spaces. */
1774 remove_trailing_whitespaces (p
);
1779 if (!strcmp("### MARKER ###", buf
))
1783 /* Since we ignore all included files (we only care about their
1784 #define-s here), we don't need to monitor filenames. The final
1785 line number directive is going to refer to the main source file
1790 p
= remove_leading_whitespaces (p
+ 1);
1791 if (!strncmp(p
, "line", 4))
1793 ln
= strtoul (p
, &end
, 10);
1794 if (ln
> 1 && ln
< INT_MAX
1795 && *remove_leading_whitespaces (end
) == '"')
1798 /* Ignore comments. */
1803 parse_template (p
, lineno
);
1811 last
= p
+ strlen (p
);
1814 name
= next_field (p
, ',', &str
, last
);
1816 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1820 /* Process opcode array. */
1821 for (j
= 0; j
< i
; j
++)
1823 struct opcode_hash_entry
*next
;
1825 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1829 lineno
= next
->lineno
;
1830 last
= str
+ strlen (str
);
1831 output_i386_opcode (table
, name
, str
, last
, lineno
);
1837 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1839 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1841 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1843 fprintf (table
, " { ");
1844 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1845 fprintf (table
, " } }\n");
1847 fprintf (table
, "};\n");
1851 process_i386_registers (FILE *table
)
1855 char *str
, *p
, *last
;
1856 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1857 char *dw2_32_num
, *dw2_64_num
;
1860 filename
= "i386-reg.tbl";
1861 fp
= fopen (filename
, "r");
1863 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1866 fprintf (table
, "\n/* i386 register table. */\n\n");
1867 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1871 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1876 p
= remove_leading_whitespaces (buf
);
1878 /* Skip comments. */
1879 str
= strstr (p
, "//");
1883 /* Remove trailing white spaces. */
1884 remove_trailing_whitespaces (p
);
1889 fprintf (table
, "%s\n", p
);
1897 last
= p
+ strlen (p
);
1899 /* Find reg_name. */
1900 reg_name
= next_field (p
, ',', &str
, last
);
1902 /* Find reg_type. */
1903 reg_type
= next_field (str
, ',', &str
, last
);
1905 /* Find reg_flags. */
1906 reg_flags
= next_field (str
, ',', &str
, last
);
1909 reg_num
= next_field (str
, ',', &str
, last
);
1911 fprintf (table
, " { \"%s\",\n ", reg_name
);
1913 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1916 /* Find 32-bit Dwarf2 register number. */
1917 dw2_32_num
= next_field (str
, ',', &str
, last
);
1919 /* Find 64-bit Dwarf2 register number. */
1920 dw2_64_num
= next_field (str
, ',', &str
, last
);
1922 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1923 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1928 fprintf (table
, "};\n");
1930 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1934 process_i386_initializers (void)
1937 FILE *fp
= fopen ("i386-init.h", "w");
1941 fail (_("can't create i386-init.h, errno = %s\n"),
1944 process_copyright (fp
);
1946 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1948 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1949 init
= xstrdup (cpu_flag_init
[i
].init
);
1950 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1954 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1956 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1957 init
= xstrdup (operand_type_init
[i
].init
);
1958 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1966 /* Program options. */
1967 #define OPTION_SRCDIR 200
1969 struct option long_options
[] =
1971 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1972 {"debug", no_argument
, NULL
, 'd'},
1973 {"version", no_argument
, NULL
, 'V'},
1974 {"help", no_argument
, NULL
, 'h'},
1975 {0, no_argument
, NULL
, 0}
1979 print_version (void)
1981 printf ("%s: version 1.0\n", program_name
);
1986 usage (FILE * stream
, int status
)
1988 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1994 main (int argc
, char **argv
)
1996 extern int chdir (char *);
1997 char *srcdir
= NULL
;
1999 unsigned int i
, cpumax
;
2002 program_name
= *argv
;
2003 xmalloc_set_program_name (program_name
);
2005 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2030 if (chdir (srcdir
) != 0)
2031 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2032 srcdir
, xstrerror (errno
));
2034 /* cpu_flags isn't sorted by position. */
2036 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2037 if (cpu_flags
[i
].position
> cpumax
)
2038 cpumax
= cpu_flags
[i
].position
;
2040 /* Check the unused bitfield in i386_cpu_flags. */
2042 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2044 if ((cpumax
- 1) != CpuMax
)
2045 fail (_("CpuMax != %d!\n"), cpumax
);
2047 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2049 if (cpumax
!= CpuMax
)
2050 fail (_("CpuMax != %d!\n"), cpumax
);
2052 c
= CpuNumOfBits
- CpuMax
- 1;
2054 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
2057 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2059 /* Check the unused bitfield in i386_operand_type. */
2061 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2064 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2067 c
= OTNumOfBits
- OTNum
;
2069 fail (_("%d unused bits in i386_operand_type.\n"), c
);
2072 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2075 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2076 sizeof (opcode_modifiers
[0]), compare
);
2078 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2079 sizeof (operand_types
[0]), compare
);
2081 table
= fopen ("i386-tbl.h", "w");
2083 fail (_("can't create i386-tbl.h, errno = %s\n"),
2086 process_copyright (table
);
2088 process_i386_opcodes (table
);
2089 process_i386_registers (table
);
2090 process_i386_initializers ();