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
, unsigned int space
,
1180 unsigned int prefix
, char **opnd
, int lineno
)
1182 char *str
, *next
, *last
;
1183 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
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)
1202 val
= adjust_broadcast_modifier (opnd
);
1204 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1206 if (strcasecmp(str
, "IsString") == 0)
1207 active_isstring
= 1;
1209 if (strcasecmp(str
, "W") == 0)
1212 if (strcasecmp(str
, "No_bSuf") == 0)
1214 if (strcasecmp(str
, "No_wSuf") == 0)
1216 if (strcasecmp(str
, "No_lSuf") == 0)
1218 if (strcasecmp(str
, "No_qSuf") == 0)
1225 if (!modifiers
[OpcodeSpace
].value
)
1226 modifiers
[OpcodeSpace
].value
= space
;
1227 else if (modifiers
[OpcodeSpace
].value
!= space
)
1228 fail (_("%s:%d: Conflicting opcode space specifications\n"),
1232 _("%s:%d: Warning: redundant opcode space specification\n"),
1238 if (!modifiers
[OpcodePrefix
].value
)
1239 modifiers
[OpcodePrefix
].value
= prefix
;
1240 else if (modifiers
[OpcodePrefix
].value
!= prefix
)
1241 fail (_("%s:%d: Conflicting prefix specifications\n"),
1245 _("%s:%d: Warning: redundant prefix specification\n"),
1249 if (have_w
&& !bwlq_suf
)
1250 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1251 if (have_w
&& !(bwlq_suf
& 1))
1252 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1254 if (have_w
&& !(bwlq_suf
& ~1))
1256 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1259 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1269 output_operand_type (FILE *table
, enum operand_class
class,
1270 enum operand_instance instance
,
1271 const bitfield
*types
, unsigned int size
,
1272 enum stage stage
, const char *indent
)
1276 fprintf (table
, "{ { %d, %d, ", class, instance
);
1278 for (i
= 0; i
< size
- 1; i
++)
1280 if (((i
+ 3) % 20) != 0)
1281 fprintf (table
, "%d, ", types
[i
].value
);
1283 fprintf (table
, "%d,", types
[i
].value
);
1284 if (((i
+ 3) % 20) == 0)
1286 /* We need \\ for macro. */
1287 if (stage
== stage_macros
)
1288 fprintf (table
, " \\\n%s", indent
);
1290 fprintf (table
, "\n%s", indent
);
1294 fprintf (table
, "%d } }", types
[i
].value
);
1298 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1299 const char *indent
, int lineno
)
1301 char *str
, *next
, *last
;
1302 enum operand_class
class = ClassNone
;
1303 enum operand_instance instance
= InstanceNone
;
1304 bitfield types
[ARRAY_SIZE (operand_types
)];
1306 /* Copy the default operand type. */
1307 memcpy (types
, operand_types
, sizeof (types
));
1309 if (strcmp (op
, "0"))
1313 last
= op
+ strlen (op
);
1314 for (next
= op
; next
&& next
< last
; )
1316 str
= next_field (next
, '|', &next
, last
);
1321 if (!strncmp(str
, "Class=", 6))
1323 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1324 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1326 class = operand_classes
[i
].value
;
1332 if (str
&& !strncmp(str
, "Instance=", 9))
1334 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1335 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1337 instance
= operand_instances
[i
].value
;
1345 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1346 if (strcasecmp(str
, "BaseIndex") == 0)
1351 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1353 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1354 if (!active_cpu_flags
.bitfield
.cpu64
1355 && !active_cpu_flags
.bitfield
.cpumpx
)
1356 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1357 if (!active_cpu_flags
.bitfield
.cpu64
)
1358 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1359 if (!active_cpu_flags
.bitfield
.cpuno64
)
1360 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1363 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1368 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1369 char *last
, int lineno
)
1371 unsigned int i
, length
, prefix
= 0, space
= 0;
1372 char *base_opcode
, *extension_opcode
, *end
;
1373 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1374 unsigned long long opcode
;
1376 /* Find base_opcode. */
1377 base_opcode
= next_field (str
, ',', &str
, last
);
1379 /* Find extension_opcode. */
1380 extension_opcode
= next_field (str
, ',', &str
, last
);
1382 /* Find cpu_flags. */
1383 cpu_flags
= next_field (str
, ',', &str
, last
);
1385 /* Find opcode_modifier. */
1386 opcode_modifier
= next_field (str
, ',', &str
, last
);
1388 /* Remove the first {. */
1389 str
= remove_leading_whitespaces (str
);
1392 str
= remove_leading_whitespaces (str
+ 1);
1393 remove_trailing_whitespaces (str
);
1395 /* Remove } and trailing white space. */
1397 if (!i
|| str
[i
- 1] != '}')
1400 remove_trailing_whitespaces (str
);
1403 operand_types
[i
= 0] = NULL
;
1406 last
= str
+ strlen (str
);
1408 /* Find operand_types. */
1409 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1413 operand_types
[i
] = NULL
;
1417 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1421 opcode
= strtoull (base_opcode
, &end
, 0);
1423 /* Determine opcode length. */
1424 for (length
= 1; length
< 8; ++length
)
1425 if (!(opcode
>> (8 * length
)))
1428 /* Transform prefixes encoded in the opcode into opcode modifier
1432 switch (opcode
>> (8 * length
- 8))
1434 case 0x66: prefix
= PREFIX_0X66
; break;
1435 case 0xF3: prefix
= PREFIX_0XF3
; break;
1436 case 0xF2: prefix
= PREFIX_0XF2
; break;
1440 opcode
&= (1ULL << (8 * --length
)) - 1;
1443 /* Transform opcode space encoded in the opcode into opcode modifier
1445 if (length
> 1 && (opcode
>> (8 * length
- 8)) == 0xf)
1447 switch ((opcode
>> (8 * length
- 16)) & 0xff)
1449 default: space
= SPACE_0F
; break;
1450 case 0x38: space
= SPACE_0F38
; break;
1451 case 0x3A: space
= SPACE_0F3A
; break;
1454 if (space
!= SPACE_0F
&& --length
== 1)
1455 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1456 filename
, lineno
, name
);
1457 opcode
&= (1ULL << (8 * --length
)) - 1;
1461 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1462 filename
, lineno
, name
, 2 * length
, opcode
);
1464 fprintf (table
, " { \"%s\", 0x%0*llx%s, %s, %lu,\n",
1465 name
, 2 * (int)length
, opcode
, end
, extension_opcode
, i
);
1467 process_i386_opcode_modifier (table
, opcode_modifier
, space
, prefix
,
1468 operand_types
, lineno
);
1470 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1472 fprintf (table
, " { ");
1474 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1476 if (!operand_types
[i
])
1479 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1485 fprintf (table
, ",\n ");
1487 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1490 fprintf (table
, " } },\n");
1493 struct opcode_hash_entry
1495 struct opcode_hash_entry
*next
;
1501 /* Calculate the hash value of an opcode hash entry P. */
1504 opcode_hash_hash (const void *p
)
1506 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1507 return htab_hash_string (entry
->name
);
1510 /* Compare a string Q against an opcode hash entry P. */
1513 opcode_hash_eq (const void *p
, const void *q
)
1515 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1516 const char *name
= (const char *) q
;
1517 return strcmp (name
, entry
->name
) == 0;
1521 parse_template (char *buf
, int lineno
)
1523 char sep
, *end
, *name
;
1524 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1525 struct template_instance
*last_inst
= NULL
;
1527 buf
= remove_leading_whitespaces (buf
+ 1);
1528 end
= strchr (buf
, ':');
1530 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1532 remove_trailing_whitespaces (buf
);
1535 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1536 tmpl
->name
= xstrdup (buf
);
1538 tmpl
->params
= NULL
;
1540 struct template_param
*param
;
1542 buf
= remove_leading_whitespaces (end
);
1543 end
= strpbrk (buf
, ":,");
1545 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1549 remove_trailing_whitespaces (buf
);
1551 param
= xmalloc (sizeof (*param
));
1552 param
->name
= xstrdup (buf
);
1553 param
->next
= tmpl
->params
;
1554 tmpl
->params
= param
;
1555 } while (sep
== ':');
1557 tmpl
->instances
= NULL
;
1559 struct template_instance
*inst
;
1561 const struct template_param
*param
;
1563 buf
= remove_leading_whitespaces (end
);
1564 end
= strpbrk (buf
, ",>");
1566 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1571 inst
= xmalloc (sizeof (*inst
));
1575 cur
= next_field (buf
, ':', &next
, end
);
1576 inst
->name
= *cur
!= '$' ? xstrdup (cur
) : "";
1578 for (param
= tmpl
->params
; param
; param
= param
->next
)
1580 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1582 cur
= next_field (next
, ':', &next
, end
);
1584 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1585 arg
->val
= xstrdup (cur
);
1586 arg
->next
= inst
->args
;
1590 if (tmpl
->instances
)
1591 last_inst
->next
= inst
;
1593 tmpl
->instances
= inst
;
1595 } while (sep
== ',');
1597 buf
= remove_leading_whitespaces (end
);
1599 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1600 filename
, lineno
, buf
);
1602 tmpl
->next
= templates
;
1607 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1608 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1610 static unsigned int idx
, opcode_array_size
;
1611 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1612 struct opcode_hash_entry
**hash_slot
, **entry
;
1613 char *ptr1
= strchr(name
, '<'), *ptr2
;
1617 /* Get the slot in hash table. */
1618 hash_slot
= (struct opcode_hash_entry
**)
1619 htab_find_slot_with_hash (opcode_hash_table
, name
,
1620 htab_hash_string (name
),
1623 if (*hash_slot
== NULL
)
1625 /* It is the new one. Put it on opcode array. */
1626 if (idx
>= opcode_array_size
)
1628 /* Grow the opcode array when needed. */
1629 opcode_array_size
+= 1024;
1630 opcode_array
= (struct opcode_hash_entry
**)
1631 xrealloc (opcode_array
,
1632 sizeof (*opcode_array
) * opcode_array_size
);
1633 *opcode_array_p
= opcode_array
;
1636 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1637 xmalloc (sizeof (struct opcode_hash_entry
));
1638 opcode_array
[idx
]->next
= NULL
;
1639 opcode_array
[idx
]->name
= xstrdup (name
);
1640 opcode_array
[idx
]->opcode
= xstrdup (str
);
1641 opcode_array
[idx
]->lineno
= lineno
;
1642 *hash_slot
= opcode_array
[idx
];
1647 /* Append it to the existing one. */
1649 while ((*entry
) != NULL
)
1650 entry
= &(*entry
)->next
;
1651 *entry
= (struct opcode_hash_entry
*)
1652 xmalloc (sizeof (struct opcode_hash_entry
));
1653 (*entry
)->next
= NULL
;
1654 (*entry
)->name
= (*hash_slot
)->name
;
1655 (*entry
)->opcode
= xstrdup (str
);
1656 (*entry
)->lineno
= lineno
;
1659 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1660 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1663 const struct template *tmpl
;
1664 const struct template_instance
*inst
;
1667 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1668 remove_trailing_whitespaces (ptr1
);
1672 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1673 if (!strcmp(ptr1
, tmpl
->name
))
1676 fail ("reference to unknown template '%s'\n", ptr1
);
1678 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1680 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1681 char *str2
= xmalloc(2 * strlen(str
));
1684 strcpy (name2
, name
);
1685 strcat (name2
, inst
->name
);
1686 strcat (name2
, ptr2
);
1688 for (ptr1
= str2
, src
= str
; *src
; )
1690 const char *ident
= tmpl
->name
, *end
;
1691 const struct template_param
*param
;
1692 const struct template_arg
*arg
;
1694 if ((*ptr1
= *src
++) != '<')
1699 while (ISSPACE(*src
))
1701 while (*ident
&& *src
== *ident
)
1703 while (ISSPACE(*src
))
1705 if (*src
!= ':' || *ident
!= '\0')
1707 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1708 ptr1
+= ident
- tmpl
->name
;
1711 while (ISSPACE(*++src
))
1715 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1718 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1719 param
= param
->next
, arg
= arg
->next
)
1721 if (end
- src
== strlen (param
->name
)
1722 && !memcmp (src
, param
->name
, end
- src
))
1730 fail ("template '%s' has no parameter '%.*s'\n",
1731 tmpl
->name
, (int)(end
- src
), src
);
1733 while (ISSPACE(*src
))
1736 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1738 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1739 ptr1
+= strlen(arg
->val
);
1745 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1757 process_i386_opcodes (FILE *table
)
1762 char *str
, *p
, *last
, *name
;
1763 htab_t opcode_hash_table
;
1764 struct opcode_hash_entry
**opcode_array
= NULL
;
1765 int lineno
= 0, marker
= 0;
1767 filename
= "i386-opc.tbl";
1771 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1772 opcode_hash_eq
, NULL
,
1775 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1776 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1778 /* Put everything on opcode array. */
1781 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1786 p
= remove_leading_whitespaces (buf
);
1788 /* Skip comments. */
1789 str
= strstr (p
, "//");
1793 /* Remove trailing white spaces. */
1794 remove_trailing_whitespaces (p
);
1799 if (!strcmp("### MARKER ###", buf
))
1803 /* Since we ignore all included files (we only care about their
1804 #define-s here), we don't need to monitor filenames. The final
1805 line number directive is going to refer to the main source file
1810 p
= remove_leading_whitespaces (p
+ 1);
1811 if (!strncmp(p
, "line", 4))
1813 ln
= strtoul (p
, &end
, 10);
1814 if (ln
> 1 && ln
< INT_MAX
1815 && *remove_leading_whitespaces (end
) == '"')
1818 /* Ignore comments. */
1823 parse_template (p
, lineno
);
1831 last
= p
+ strlen (p
);
1834 name
= next_field (p
, ',', &str
, last
);
1836 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1840 /* Process opcode array. */
1841 for (j
= 0; j
< i
; j
++)
1843 struct opcode_hash_entry
*next
;
1845 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1849 lineno
= next
->lineno
;
1850 last
= str
+ strlen (str
);
1851 output_i386_opcode (table
, name
, str
, last
, lineno
);
1857 fprintf (table
, " { NULL, 0, 0, 0,\n");
1859 process_i386_opcode_modifier (table
, "0", 0, 0, NULL
, -1);
1861 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1863 fprintf (table
, " { ");
1864 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1865 fprintf (table
, " } }\n");
1867 fprintf (table
, "};\n");
1871 process_i386_registers (FILE *table
)
1875 char *str
, *p
, *last
;
1876 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1877 char *dw2_32_num
, *dw2_64_num
;
1880 filename
= "i386-reg.tbl";
1881 fp
= fopen (filename
, "r");
1883 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1886 fprintf (table
, "\n/* i386 register table. */\n\n");
1887 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1891 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1896 p
= remove_leading_whitespaces (buf
);
1898 /* Skip comments. */
1899 str
= strstr (p
, "//");
1903 /* Remove trailing white spaces. */
1904 remove_trailing_whitespaces (p
);
1909 fprintf (table
, "%s\n", p
);
1917 last
= p
+ strlen (p
);
1919 /* Find reg_name. */
1920 reg_name
= next_field (p
, ',', &str
, last
);
1922 /* Find reg_type. */
1923 reg_type
= next_field (str
, ',', &str
, last
);
1925 /* Find reg_flags. */
1926 reg_flags
= next_field (str
, ',', &str
, last
);
1929 reg_num
= next_field (str
, ',', &str
, last
);
1931 fprintf (table
, " { \"%s\",\n ", reg_name
);
1933 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1936 /* Find 32-bit Dwarf2 register number. */
1937 dw2_32_num
= next_field (str
, ',', &str
, last
);
1939 /* Find 64-bit Dwarf2 register number. */
1940 dw2_64_num
= next_field (str
, ',', &str
, last
);
1942 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1943 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1948 fprintf (table
, "};\n");
1950 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1954 process_i386_initializers (void)
1957 FILE *fp
= fopen ("i386-init.h", "w");
1961 fail (_("can't create i386-init.h, errno = %s\n"),
1964 process_copyright (fp
);
1966 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1968 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1969 init
= xstrdup (cpu_flag_init
[i
].init
);
1970 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1974 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1976 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1977 init
= xstrdup (operand_type_init
[i
].init
);
1978 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1986 /* Program options. */
1987 #define OPTION_SRCDIR 200
1989 struct option long_options
[] =
1991 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1992 {"debug", no_argument
, NULL
, 'd'},
1993 {"version", no_argument
, NULL
, 'V'},
1994 {"help", no_argument
, NULL
, 'h'},
1995 {0, no_argument
, NULL
, 0}
1999 print_version (void)
2001 printf ("%s: version 1.0\n", program_name
);
2006 usage (FILE * stream
, int status
)
2008 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2014 main (int argc
, char **argv
)
2016 extern int chdir (char *);
2017 char *srcdir
= NULL
;
2019 unsigned int i
, cpumax
;
2022 program_name
= *argv
;
2023 xmalloc_set_program_name (program_name
);
2025 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2050 if (chdir (srcdir
) != 0)
2051 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2052 srcdir
, xstrerror (errno
));
2054 /* cpu_flags isn't sorted by position. */
2056 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2057 if (cpu_flags
[i
].position
> cpumax
)
2058 cpumax
= cpu_flags
[i
].position
;
2060 /* Check the unused bitfield in i386_cpu_flags. */
2062 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2064 if ((cpumax
- 1) != CpuMax
)
2065 fail (_("CpuMax != %d!\n"), cpumax
);
2067 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2069 if (cpumax
!= CpuMax
)
2070 fail (_("CpuMax != %d!\n"), cpumax
);
2072 c
= CpuNumOfBits
- CpuMax
- 1;
2074 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
2077 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2079 /* Check the unused bitfield in i386_operand_type. */
2081 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2084 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2087 c
= OTNumOfBits
- OTNum
;
2089 fail (_("%d unused bits in i386_operand_type.\n"), c
);
2092 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2095 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2096 sizeof (opcode_modifiers
[0]), compare
);
2098 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2099 sizeof (operand_types
[0]), compare
);
2101 table
= fopen ("i386-tbl.h", "w");
2103 fail (_("can't create i386-tbl.h, errno = %s\n"),
2106 process_copyright (table
);
2108 process_i386_opcodes (table
);
2109 process_i386_registers (table
);
2110 process_i386_initializers ();