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 (NoTrackPrefixOk
),
709 BITFIELD (IsLockable
),
710 BITFIELD (RegKludge
),
711 BITFIELD (Implicit1stXmm0
),
712 BITFIELD (RepPrefixOk
),
713 BITFIELD (HLEPrefixOk
),
716 BITFIELD (AddrPrefixOpReg
),
721 BITFIELD (PseudoVexPrefix
),
725 BITFIELD (OpcodePrefix
),
726 BITFIELD (VexSources
),
732 BITFIELD (Broadcast
),
733 BITFIELD (StaticRounding
),
735 BITFIELD (Disp8MemShift
),
736 BITFIELD (NoDefMask
),
737 BITFIELD (ImplicitQuadGroup
),
738 BITFIELD (SwapSources
),
740 BITFIELD (ATTMnemonic
),
741 BITFIELD (ATTSyntax
),
742 BITFIELD (IntelSyntax
),
746 #define CLASS(n) #n, n
748 static const struct {
750 enum operand_class value
;
751 } operand_classes
[] = {
765 #define INSTANCE(n) #n, n
767 static const struct {
769 enum operand_instance value
;
770 } operand_instances
[] = {
779 static bitfield operand_types
[] =
788 BITFIELD (BaseIndex
),
804 BITFIELD (Unspecified
),
810 static const char *filename
;
811 static i386_cpu_flags active_cpu_flags
;
812 static int active_isstring
;
814 struct template_arg
{
815 const struct template_arg
*next
;
819 struct template_instance
{
820 const struct template_instance
*next
;
822 const struct template_arg
*args
;
825 struct template_param
{
826 const struct template_param
*next
;
831 const struct template *next
;
833 const struct template_instance
*instances
;
834 const struct template_param
*params
;
837 static const struct template *templates
;
840 compare (const void *x
, const void *y
)
842 const bitfield
*xp
= (const bitfield
*) x
;
843 const bitfield
*yp
= (const bitfield
*) y
;
844 return xp
->position
- yp
->position
;
848 fail (const char *message
, ...)
852 va_start (args
, message
);
853 fprintf (stderr
, _("%s: error: "), program_name
);
854 vfprintf (stderr
, message
, args
);
860 process_copyright (FILE *fp
)
862 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
863 /* Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\
865 This file is part of the GNU opcodes library.\n\
867 This library is free software; you can redistribute it and/or modify\n\
868 it under the terms of the GNU General Public License as published by\n\
869 the Free Software Foundation; either version 3, or (at your option)\n\
870 any later version.\n\
872 It is distributed in the hope that it will be useful, but WITHOUT\n\
873 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
874 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
875 License for more details.\n\
877 You should have received a copy of the GNU General Public License\n\
878 along with this program; if not, write to the Free Software\n\
879 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
880 MA 02110-1301, USA. */\n");
883 /* Remove leading white spaces. */
886 remove_leading_whitespaces (char *str
)
888 while (ISSPACE (*str
))
893 /* Remove trailing white spaces. */
896 remove_trailing_whitespaces (char *str
)
898 size_t last
= strlen (str
);
906 if (ISSPACE (str
[last
]))
914 /* Find next field separated by SEP and terminate it. Return a
915 pointer to the one after it. */
918 next_field (char *str
, char sep
, char **next
, char *last
)
922 p
= remove_leading_whitespaces (str
);
923 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
926 remove_trailing_whitespaces (p
);
936 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
939 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
942 char *str
, *next
, *last
;
945 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
946 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
948 /* Turn on selective bits. */
949 char *init
= xstrdup (cpu_flag_init
[i
].init
);
950 last
= init
+ strlen (init
);
951 for (next
= init
; next
&& next
< last
; )
953 str
= next_field (next
, '|', &next
, last
);
955 set_bitfield (str
, array
, 1, size
, lineno
);
965 set_bitfield (char *f
, bitfield
*array
, int value
,
966 unsigned int size
, int lineno
)
970 /* Ignore empty fields; they may result from template expansions. */
974 if (strcmp (f
, "CpuFP") == 0)
976 set_bitfield("Cpu387", array
, value
, size
, lineno
);
977 set_bitfield("Cpu287", array
, value
, size
, lineno
);
980 else if (strcmp (f
, "Mmword") == 0)
982 else if (strcmp (f
, "Oword") == 0)
985 for (i
= 0; i
< size
; i
++)
986 if (strcasecmp (array
[i
].name
, f
) == 0)
988 array
[i
].value
= value
;
994 const char *v
= strchr (f
, '=');
1001 for (i
= 0; i
< size
; i
++)
1002 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
1004 value
= strtol (v
+ 1, &end
, 0);
1007 array
[i
].value
= value
;
1015 /* Handle CPU_XXX_FLAGS. */
1016 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
1020 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
1022 fail (_("unknown bitfield: %s\n"), f
);
1026 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
1027 int macro
, const char *comma
, const char *indent
)
1031 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
1033 fprintf (table
, "%s{ { ", indent
);
1035 for (i
= 0; i
< size
- 1; i
++)
1037 if (((i
+ 1) % 20) != 0)
1038 fprintf (table
, "%d, ", flags
[i
].value
);
1040 fprintf (table
, "%d,", flags
[i
].value
);
1041 if (((i
+ 1) % 20) == 0)
1043 /* We need \\ for macro. */
1045 fprintf (table
, " \\\n %s", indent
);
1047 fprintf (table
, "\n %s", indent
);
1050 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
1053 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
1057 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
1058 const char *comma
, const char *indent
,
1061 char *str
, *next
, *last
;
1063 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1065 /* Copy the default cpu flags. */
1066 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1068 if (strcasecmp (flag
, "unknown") == 0)
1070 /* We turn on everything except for cpu64 in case of
1071 CPU_UNKNOWN_FLAGS. */
1072 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1073 if (flags
[i
].position
!= Cpu64
)
1076 else if (flag
[0] == '~')
1078 last
= flag
+ strlen (flag
);
1085 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1092 /* First we turn on everything except for cpu64. */
1093 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1094 if (flags
[i
].position
!= Cpu64
)
1097 /* Turn off selective bits. */
1098 for (; next
&& next
< last
; )
1100 str
= next_field (next
, '|', &next
, last
);
1102 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1105 else if (strcmp (flag
, "0"))
1107 /* Turn on selective bits. */
1108 last
= flag
+ strlen (flag
);
1109 for (next
= flag
; next
&& next
< last
; )
1111 str
= next_field (next
, '|', &next
, last
);
1113 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1117 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1122 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1126 fprintf (table
, " { ");
1128 for (i
= 0; i
< size
- 1; i
++)
1130 if (((i
+ 1) % 20) != 0)
1131 fprintf (table
, "%d, ", modifier
[i
].value
);
1133 fprintf (table
, "%d,", modifier
[i
].value
);
1134 if (((i
+ 1) % 20) == 0)
1135 fprintf (table
, "\n ");
1138 fprintf (table
, "%d },\n", modifier
[i
].value
);
1142 adjust_broadcast_modifier (char **opnd
)
1144 char *str
, *next
, *last
, *op
;
1145 int bcst_type
= INT_MAX
;
1147 /* Skip the immediate operand. */
1149 if (strcasecmp(op
, "Imm8") == 0)
1153 last
= op
+ strlen (op
);
1154 for (next
= op
; next
&& next
< last
; )
1156 str
= next_field (next
, '|', &next
, last
);
1159 if (strcasecmp(str
, "Byte") == 0)
1161 /* The smalest broadcast type, no need to check
1163 bcst_type
= BYTE_BROADCAST
;
1166 else if (strcasecmp(str
, "Word") == 0)
1168 if (bcst_type
> WORD_BROADCAST
)
1169 bcst_type
= WORD_BROADCAST
;
1171 else if (strcasecmp(str
, "Dword") == 0)
1173 if (bcst_type
> DWORD_BROADCAST
)
1174 bcst_type
= DWORD_BROADCAST
;
1176 else if (strcasecmp(str
, "Qword") == 0)
1178 if (bcst_type
> QWORD_BROADCAST
)
1179 bcst_type
= QWORD_BROADCAST
;
1185 if (bcst_type
== INT_MAX
)
1186 fail (_("unknown broadcast operand: %s\n"), op
);
1192 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1194 char *str
, *next
, *last
;
1195 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1196 unsigned int regular_encoding
= 1;
1198 active_isstring
= 0;
1200 /* Copy the default opcode modifier. */
1201 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1203 if (strcmp (mod
, "0"))
1205 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1207 last
= mod
+ strlen (mod
);
1208 for (next
= mod
; next
&& next
< last
; )
1210 str
= next_field (next
, '|', &next
, last
);
1214 if (strcasecmp(str
, "Broadcast") == 0)
1216 val
= adjust_broadcast_modifier (opnd
);
1217 regular_encoding
= 0;
1219 else if (strcasecmp(str
, "Vex") == 0
1220 || strncasecmp(str
, "Vex=", 4) == 0
1221 || strcasecmp(str
, "EVex") == 0
1222 || strncasecmp(str
, "EVex=", 5) == 0
1223 || strncasecmp(str
, "Disp8MemShift=", 14) == 0
1224 || strncasecmp(str
, "Masking=", 8) == 0
1225 || strcasecmp(str
, "SAE") == 0
1226 || strcasecmp(str
, "IsPrefix") == 0)
1227 regular_encoding
= 0;
1229 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1231 if (strcasecmp(str
, "IsString") == 0)
1232 active_isstring
= 1;
1234 if (strcasecmp(str
, "W") == 0)
1237 if (strcasecmp(str
, "No_bSuf") == 0)
1239 if (strcasecmp(str
, "No_wSuf") == 0)
1241 if (strcasecmp(str
, "No_lSuf") == 0)
1243 if (strcasecmp(str
, "No_qSuf") == 0)
1248 if (have_w
&& !bwlq_suf
)
1249 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1250 if (have_w
&& !(bwlq_suf
& 1))
1251 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1253 if (have_w
&& !(bwlq_suf
& ~1))
1255 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1258 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1260 return regular_encoding
;
1270 output_operand_type (FILE *table
, enum operand_class
class,
1271 enum operand_instance instance
,
1272 const bitfield
*types
, unsigned int size
,
1273 enum stage stage
, const char *indent
)
1277 fprintf (table
, "{ { %d, %d, ", class, instance
);
1279 for (i
= 0; i
< size
- 1; i
++)
1281 if (((i
+ 3) % 20) != 0)
1282 fprintf (table
, "%d, ", types
[i
].value
);
1284 fprintf (table
, "%d,", types
[i
].value
);
1285 if (((i
+ 3) % 20) == 0)
1287 /* We need \\ for macro. */
1288 if (stage
== stage_macros
)
1289 fprintf (table
, " \\\n%s", indent
);
1291 fprintf (table
, "\n%s", indent
);
1295 fprintf (table
, "%d } }", types
[i
].value
);
1299 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1300 const char *indent
, int lineno
)
1302 char *str
, *next
, *last
;
1303 enum operand_class
class = ClassNone
;
1304 enum operand_instance instance
= InstanceNone
;
1305 bitfield types
[ARRAY_SIZE (operand_types
)];
1307 /* Copy the default operand type. */
1308 memcpy (types
, operand_types
, sizeof (types
));
1310 if (strcmp (op
, "0"))
1314 last
= op
+ strlen (op
);
1315 for (next
= op
; next
&& next
< last
; )
1317 str
= next_field (next
, '|', &next
, last
);
1322 if (!strncmp(str
, "Class=", 6))
1324 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1325 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1327 class = operand_classes
[i
].value
;
1333 if (str
&& !strncmp(str
, "Instance=", 9))
1335 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1336 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1338 instance
= operand_instances
[i
].value
;
1346 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1347 if (strcasecmp(str
, "BaseIndex") == 0)
1352 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1354 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1355 if (!active_cpu_flags
.bitfield
.cpu64
1356 && !active_cpu_flags
.bitfield
.cpumpx
)
1357 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1358 if (!active_cpu_flags
.bitfield
.cpu64
)
1359 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1360 if (!active_cpu_flags
.bitfield
.cpuno64
)
1361 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1364 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1369 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1370 char *last
, int lineno
)
1373 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1374 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1376 /* Find number of operands. */
1377 operands
= next_field (str
, ',', &str
, last
);
1379 /* Find base_opcode. */
1380 base_opcode
= next_field (str
, ',', &str
, last
);
1382 /* Find extension_opcode. */
1383 extension_opcode
= next_field (str
, ',', &str
, last
);
1385 /* Find opcode_length. */
1386 opcode_length
= next_field (str
, ',', &str
, last
);
1388 /* Find cpu_flags. */
1389 cpu_flags
= next_field (str
, ',', &str
, last
);
1391 /* Find opcode_modifier. */
1392 opcode_modifier
= next_field (str
, ',', &str
, last
);
1394 /* Remove the first {. */
1395 str
= remove_leading_whitespaces (str
);
1398 str
= remove_leading_whitespaces (str
+ 1);
1402 /* There are at least "X}". */
1406 /* Remove trailing white spaces and }. */
1410 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1419 /* Find operand_types. */
1420 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1424 operand_types
[i
] = NULL
;
1428 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1429 if (*operand_types
[i
] == '0')
1432 operand_types
[i
] = NULL
;
1437 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1438 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1440 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1442 if (process_i386_opcode_modifier (table
, opcode_modifier
,
1443 operand_types
, lineno
))
1446 unsigned long int length
= strtoul (opcode_length
, &end
, 0);
1447 unsigned long int opcode
= strtoul (base_opcode
, &end
, 0);
1453 if ((opcode
>> 24) != 0)
1454 fail (_("%s: %s: (base_opcode >> 24) != 0: %s\n"),
1455 filename
, name
, base_opcode
);
1458 if ((opcode
>> 16) != 0)
1459 fail (_("%s: %s: (base_opcode >> 16) != 0: %s\n"),
1460 filename
, name
, base_opcode
);
1463 if ((opcode
>> 8) != 0)
1464 fail (_("%s: %s: (base_opcode >> 8) != 0: %s\n"),
1465 filename
, name
, base_opcode
);
1469 fail (_("%s: %s: base_opcode != 0: %s\n"),
1470 filename
, name
, base_opcode
);
1473 fail (_("%s: %s: invalid opcode length: %s\n"),
1474 filename
, name
, opcode_length
);
1479 fprintf (table
, " { ");
1481 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1483 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1486 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1492 fprintf (table
, ",\n ");
1494 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1497 fprintf (table
, " } },\n");
1500 struct opcode_hash_entry
1502 struct opcode_hash_entry
*next
;
1508 /* Calculate the hash value of an opcode hash entry P. */
1511 opcode_hash_hash (const void *p
)
1513 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1514 return htab_hash_string (entry
->name
);
1517 /* Compare a string Q against an opcode hash entry P. */
1520 opcode_hash_eq (const void *p
, const void *q
)
1522 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1523 const char *name
= (const char *) q
;
1524 return strcmp (name
, entry
->name
) == 0;
1528 parse_template (char *buf
, int lineno
)
1530 char sep
, *end
, *name
;
1531 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1532 struct template_instance
*last_inst
= NULL
;
1534 buf
= remove_leading_whitespaces (buf
+ 1);
1535 end
= strchr (buf
, ':');
1537 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1539 remove_trailing_whitespaces (buf
);
1542 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1543 tmpl
->name
= xstrdup (buf
);
1545 tmpl
->params
= NULL
;
1547 struct template_param
*param
;
1549 buf
= remove_leading_whitespaces (end
);
1550 end
= strpbrk (buf
, ":,");
1552 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1556 remove_trailing_whitespaces (buf
);
1558 param
= xmalloc (sizeof (*param
));
1559 param
->name
= xstrdup (buf
);
1560 param
->next
= tmpl
->params
;
1561 tmpl
->params
= param
;
1562 } while (sep
== ':');
1564 tmpl
->instances
= NULL
;
1566 struct template_instance
*inst
;
1568 const struct template_param
*param
;
1570 buf
= remove_leading_whitespaces (end
);
1571 end
= strpbrk (buf
, ",>");
1573 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1578 inst
= xmalloc (sizeof (*inst
));
1580 cur
= next_field (buf
, ':', &next
, end
);
1581 inst
->name
= xstrdup (cur
);
1583 for (param
= tmpl
->params
; param
; param
= param
->next
)
1585 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1587 cur
= next_field (next
, ':', &next
, end
);
1589 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1590 arg
->val
= xstrdup (cur
);
1591 arg
->next
= inst
->args
;
1595 if (tmpl
->instances
)
1596 last_inst
->next
= inst
;
1598 tmpl
->instances
= inst
;
1600 } while (sep
== ',');
1602 buf
= remove_leading_whitespaces (end
);
1604 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1605 filename
, lineno
, buf
);
1607 tmpl
->next
= templates
;
1612 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1613 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1615 static unsigned int idx
, opcode_array_size
;
1616 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1617 struct opcode_hash_entry
**hash_slot
, **entry
;
1618 char *ptr1
= strchr(name
, '<'), *ptr2
;
1622 /* Get the slot in hash table. */
1623 hash_slot
= (struct opcode_hash_entry
**)
1624 htab_find_slot_with_hash (opcode_hash_table
, name
,
1625 htab_hash_string (name
),
1628 if (*hash_slot
== NULL
)
1630 /* It is the new one. Put it on opcode array. */
1631 if (idx
>= opcode_array_size
)
1633 /* Grow the opcode array when needed. */
1634 opcode_array_size
+= 1024;
1635 opcode_array
= (struct opcode_hash_entry
**)
1636 xrealloc (opcode_array
,
1637 sizeof (*opcode_array
) * opcode_array_size
);
1638 *opcode_array_p
= opcode_array
;
1641 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1642 xmalloc (sizeof (struct opcode_hash_entry
));
1643 opcode_array
[idx
]->next
= NULL
;
1644 opcode_array
[idx
]->name
= xstrdup (name
);
1645 opcode_array
[idx
]->opcode
= xstrdup (str
);
1646 opcode_array
[idx
]->lineno
= lineno
;
1647 *hash_slot
= opcode_array
[idx
];
1652 /* Append it to the existing one. */
1654 while ((*entry
) != NULL
)
1655 entry
= &(*entry
)->next
;
1656 *entry
= (struct opcode_hash_entry
*)
1657 xmalloc (sizeof (struct opcode_hash_entry
));
1658 (*entry
)->next
= NULL
;
1659 (*entry
)->name
= (*hash_slot
)->name
;
1660 (*entry
)->opcode
= xstrdup (str
);
1661 (*entry
)->lineno
= lineno
;
1664 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1665 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1668 const struct template *tmpl
;
1669 const struct template_instance
*inst
;
1672 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1673 remove_trailing_whitespaces (ptr1
);
1677 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1678 if (!strcmp(ptr1
, tmpl
->name
))
1681 fail ("reference to unknown template '%s'\n", ptr1
);
1683 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1685 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1686 char *str2
= xmalloc(2 * strlen(str
));
1689 strcpy (name2
, name
);
1690 strcat (name2
, inst
->name
);
1691 strcat (name2
, ptr2
);
1693 for (ptr1
= str2
, src
= str
; *src
; )
1695 const char *ident
= tmpl
->name
, *end
;
1696 const struct template_param
*param
;
1697 const struct template_arg
*arg
;
1699 if ((*ptr1
= *src
++) != '<')
1704 while (ISSPACE(*src
))
1706 while (*ident
&& *src
== *ident
)
1708 while (ISSPACE(*src
))
1710 if (*src
!= ':' || *ident
!= '\0')
1712 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1713 ptr1
+= ident
- tmpl
->name
;
1716 while (ISSPACE(*++src
))
1720 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1723 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1724 param
= param
->next
, arg
= arg
->next
)
1726 if (end
- src
== strlen (param
->name
)
1727 && !memcmp (src
, param
->name
, end
- src
))
1735 fail ("template '%s' has no parameter '%.*s'\n",
1736 tmpl
->name
, (int)(end
- src
), src
);
1738 while (ISSPACE(*src
))
1741 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1743 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1744 ptr1
+= strlen(arg
->val
);
1750 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1762 process_i386_opcodes (FILE *table
)
1767 char *str
, *p
, *last
, *name
;
1768 htab_t opcode_hash_table
;
1769 struct opcode_hash_entry
**opcode_array
= NULL
;
1770 int lineno
= 0, marker
= 0;
1772 filename
= "i386-opc.tbl";
1776 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1777 opcode_hash_eq
, NULL
,
1780 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1781 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1783 /* Put everything on opcode array. */
1786 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1791 p
= remove_leading_whitespaces (buf
);
1793 /* Skip comments. */
1794 str
= strstr (p
, "//");
1798 /* Remove trailing white spaces. */
1799 remove_trailing_whitespaces (p
);
1804 if (!strcmp("### MARKER ###", buf
))
1808 /* Since we ignore all included files (we only care about their
1809 #define-s here), we don't need to monitor filenames. The final
1810 line number directive is going to refer to the main source file
1815 p
= remove_leading_whitespaces (p
+ 1);
1816 if (!strncmp(p
, "line", 4))
1818 ln
= strtoul (p
, &end
, 10);
1819 if (ln
> 1 && ln
< INT_MAX
1820 && *remove_leading_whitespaces (end
) == '"')
1823 /* Ignore comments. */
1828 parse_template (p
, lineno
);
1836 last
= p
+ strlen (p
);
1839 name
= next_field (p
, ',', &str
, last
);
1841 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1845 /* Process opcode array. */
1846 for (j
= 0; j
< i
; j
++)
1848 struct opcode_hash_entry
*next
;
1850 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1854 lineno
= next
->lineno
;
1855 last
= str
+ strlen (str
);
1856 output_i386_opcode (table
, name
, str
, last
, lineno
);
1862 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1864 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1866 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1868 fprintf (table
, " { ");
1869 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1870 fprintf (table
, " } }\n");
1872 fprintf (table
, "};\n");
1876 process_i386_registers (FILE *table
)
1880 char *str
, *p
, *last
;
1881 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1882 char *dw2_32_num
, *dw2_64_num
;
1885 filename
= "i386-reg.tbl";
1886 fp
= fopen (filename
, "r");
1888 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1891 fprintf (table
, "\n/* i386 register table. */\n\n");
1892 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1896 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1901 p
= remove_leading_whitespaces (buf
);
1903 /* Skip comments. */
1904 str
= strstr (p
, "//");
1908 /* Remove trailing white spaces. */
1909 remove_trailing_whitespaces (p
);
1914 fprintf (table
, "%s\n", p
);
1922 last
= p
+ strlen (p
);
1924 /* Find reg_name. */
1925 reg_name
= next_field (p
, ',', &str
, last
);
1927 /* Find reg_type. */
1928 reg_type
= next_field (str
, ',', &str
, last
);
1930 /* Find reg_flags. */
1931 reg_flags
= next_field (str
, ',', &str
, last
);
1934 reg_num
= next_field (str
, ',', &str
, last
);
1936 fprintf (table
, " { \"%s\",\n ", reg_name
);
1938 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1941 /* Find 32-bit Dwarf2 register number. */
1942 dw2_32_num
= next_field (str
, ',', &str
, last
);
1944 /* Find 64-bit Dwarf2 register number. */
1945 dw2_64_num
= next_field (str
, ',', &str
, last
);
1947 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1948 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1953 fprintf (table
, "};\n");
1955 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1959 process_i386_initializers (void)
1962 FILE *fp
= fopen ("i386-init.h", "w");
1966 fail (_("can't create i386-init.h, errno = %s\n"),
1969 process_copyright (fp
);
1971 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1973 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1974 init
= xstrdup (cpu_flag_init
[i
].init
);
1975 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1979 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1981 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1982 init
= xstrdup (operand_type_init
[i
].init
);
1983 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1991 /* Program options. */
1992 #define OPTION_SRCDIR 200
1994 struct option long_options
[] =
1996 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1997 {"debug", no_argument
, NULL
, 'd'},
1998 {"version", no_argument
, NULL
, 'V'},
1999 {"help", no_argument
, NULL
, 'h'},
2000 {0, no_argument
, NULL
, 0}
2004 print_version (void)
2006 printf ("%s: version 1.0\n", program_name
);
2011 usage (FILE * stream
, int status
)
2013 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2019 main (int argc
, char **argv
)
2021 extern int chdir (char *);
2022 char *srcdir
= NULL
;
2024 unsigned int i
, cpumax
;
2027 program_name
= *argv
;
2028 xmalloc_set_program_name (program_name
);
2030 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2055 if (chdir (srcdir
) != 0)
2056 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2057 srcdir
, xstrerror (errno
));
2059 /* cpu_flags isn't sorted by position. */
2061 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2062 if (cpu_flags
[i
].position
> cpumax
)
2063 cpumax
= cpu_flags
[i
].position
;
2065 /* Check the unused bitfield in i386_cpu_flags. */
2067 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2069 if ((cpumax
- 1) != CpuMax
)
2070 fail (_("CpuMax != %d!\n"), cpumax
);
2072 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2074 if (cpumax
!= CpuMax
)
2075 fail (_("CpuMax != %d!\n"), cpumax
);
2077 c
= CpuNumOfBits
- CpuMax
- 1;
2079 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
2082 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2084 /* Check the unused bitfield in i386_operand_type. */
2086 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2089 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2092 c
= OTNumOfBits
- OTNum
;
2094 fail (_("%d unused bits in i386_operand_type.\n"), c
);
2097 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2100 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2101 sizeof (opcode_modifiers
[0]), compare
);
2103 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2104 sizeof (operand_types
[0]), compare
);
2106 table
= fopen ("i386-tbl.h", "w");
2108 fail (_("can't create i386-tbl.h, errno = %s\n"),
2111 process_copyright (table
);
2113 process_i386_opcodes (table
);
2114 process_i386_registers (table
);
2115 process_i386_initializers ();