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 for (i
= 0; i
< size
; i
++)
975 if (strcasecmp (array
[i
].name
, f
) == 0)
977 array
[i
].value
= value
;
983 const char *v
= strchr (f
, '=');
990 for (i
= 0; i
< size
; i
++)
991 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
993 value
= strtol (v
+ 1, &end
, 0);
996 array
[i
].value
= value
;
1004 /* Handle CPU_XXX_FLAGS. */
1005 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
1009 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
1011 fail (_("unknown bitfield: %s\n"), f
);
1015 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
1016 int macro
, const char *comma
, const char *indent
)
1020 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
1022 fprintf (table
, "%s{ { ", indent
);
1024 for (i
= 0; i
< size
- 1; i
++)
1026 if (((i
+ 1) % 20) != 0)
1027 fprintf (table
, "%d, ", flags
[i
].value
);
1029 fprintf (table
, "%d,", flags
[i
].value
);
1030 if (((i
+ 1) % 20) == 0)
1032 /* We need \\ for macro. */
1034 fprintf (table
, " \\\n %s", indent
);
1036 fprintf (table
, "\n %s", indent
);
1039 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
1042 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
1046 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
1047 const char *comma
, const char *indent
,
1050 char *str
, *next
, *last
;
1052 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1054 /* Copy the default cpu flags. */
1055 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1057 if (strcasecmp (flag
, "unknown") == 0)
1059 /* We turn on everything except for cpu64 in case of
1060 CPU_UNKNOWN_FLAGS. */
1061 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1062 if (flags
[i
].position
!= Cpu64
)
1065 else if (flag
[0] == '~')
1067 last
= flag
+ strlen (flag
);
1074 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1081 /* First we turn on everything except for cpu64. */
1082 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1083 if (flags
[i
].position
!= Cpu64
)
1086 /* Turn off selective bits. */
1087 for (; next
&& next
< last
; )
1089 str
= next_field (next
, '|', &next
, last
);
1091 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1094 else if (strcmp (flag
, "0"))
1096 /* Turn on selective bits. */
1097 last
= flag
+ strlen (flag
);
1098 for (next
= flag
; next
&& next
< last
; )
1100 str
= next_field (next
, '|', &next
, last
);
1102 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1106 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1111 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1115 fprintf (table
, " { ");
1117 for (i
= 0; i
< size
- 1; i
++)
1119 if (((i
+ 1) % 20) != 0)
1120 fprintf (table
, "%d, ", modifier
[i
].value
);
1122 fprintf (table
, "%d,", modifier
[i
].value
);
1123 if (((i
+ 1) % 20) == 0)
1124 fprintf (table
, "\n ");
1127 fprintf (table
, "%d },\n", modifier
[i
].value
);
1131 adjust_broadcast_modifier (char **opnd
)
1133 char *str
, *next
, *last
, *op
;
1134 int bcst_type
= INT_MAX
;
1136 /* Skip the immediate operand. */
1138 if (strcasecmp(op
, "Imm8") == 0)
1142 last
= op
+ strlen (op
);
1143 for (next
= op
; next
&& next
< last
; )
1145 str
= next_field (next
, '|', &next
, last
);
1148 if (strcasecmp(str
, "Byte") == 0)
1150 /* The smalest broadcast type, no need to check
1152 bcst_type
= BYTE_BROADCAST
;
1155 else if (strcasecmp(str
, "Word") == 0)
1157 if (bcst_type
> WORD_BROADCAST
)
1158 bcst_type
= WORD_BROADCAST
;
1160 else if (strcasecmp(str
, "Dword") == 0)
1162 if (bcst_type
> DWORD_BROADCAST
)
1163 bcst_type
= DWORD_BROADCAST
;
1165 else if (strcasecmp(str
, "Qword") == 0)
1167 if (bcst_type
> QWORD_BROADCAST
)
1168 bcst_type
= QWORD_BROADCAST
;
1174 if (bcst_type
== INT_MAX
)
1175 fail (_("unknown broadcast operand: %s\n"), op
);
1181 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1183 char *str
, *next
, *last
;
1184 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1185 unsigned int regular_encoding
= 1;
1187 active_isstring
= 0;
1189 /* Copy the default opcode modifier. */
1190 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1192 if (strcmp (mod
, "0"))
1194 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1196 last
= mod
+ strlen (mod
);
1197 for (next
= mod
; next
&& next
< last
; )
1199 str
= next_field (next
, '|', &next
, last
);
1203 if (strcasecmp(str
, "Broadcast") == 0)
1205 val
= adjust_broadcast_modifier (opnd
);
1206 regular_encoding
= 0;
1208 else if (strcasecmp(str
, "Vex") == 0
1209 || strncasecmp(str
, "Vex=", 4) == 0
1210 || strcasecmp(str
, "EVex") == 0
1211 || strncasecmp(str
, "EVex=", 5) == 0
1212 || strncasecmp(str
, "Disp8MemShift=", 14) == 0
1213 || strncasecmp(str
, "Masking=", 8) == 0
1214 || strcasecmp(str
, "SAE") == 0
1215 || strcasecmp(str
, "IsPrefix") == 0)
1216 regular_encoding
= 0;
1218 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1220 if (strcasecmp(str
, "IsString") == 0)
1221 active_isstring
= 1;
1223 if (strcasecmp(str
, "W") == 0)
1226 if (strcasecmp(str
, "No_bSuf") == 0)
1228 if (strcasecmp(str
, "No_wSuf") == 0)
1230 if (strcasecmp(str
, "No_lSuf") == 0)
1232 if (strcasecmp(str
, "No_qSuf") == 0)
1237 if (have_w
&& !bwlq_suf
)
1238 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1239 if (have_w
&& !(bwlq_suf
& 1))
1240 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1242 if (have_w
&& !(bwlq_suf
& ~1))
1244 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1247 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1249 return regular_encoding
;
1259 output_operand_type (FILE *table
, enum operand_class
class,
1260 enum operand_instance instance
,
1261 const bitfield
*types
, unsigned int size
,
1262 enum stage stage
, const char *indent
)
1266 fprintf (table
, "{ { %d, %d, ", class, instance
);
1268 for (i
= 0; i
< size
- 1; i
++)
1270 if (((i
+ 3) % 20) != 0)
1271 fprintf (table
, "%d, ", types
[i
].value
);
1273 fprintf (table
, "%d,", types
[i
].value
);
1274 if (((i
+ 3) % 20) == 0)
1276 /* We need \\ for macro. */
1277 if (stage
== stage_macros
)
1278 fprintf (table
, " \\\n%s", indent
);
1280 fprintf (table
, "\n%s", indent
);
1284 fprintf (table
, "%d } }", types
[i
].value
);
1288 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1289 const char *indent
, int lineno
)
1291 char *str
, *next
, *last
;
1292 enum operand_class
class = ClassNone
;
1293 enum operand_instance instance
= InstanceNone
;
1294 bitfield types
[ARRAY_SIZE (operand_types
)];
1296 /* Copy the default operand type. */
1297 memcpy (types
, operand_types
, sizeof (types
));
1299 if (strcmp (op
, "0"))
1303 last
= op
+ strlen (op
);
1304 for (next
= op
; next
&& next
< last
; )
1306 str
= next_field (next
, '|', &next
, last
);
1311 if (!strncmp(str
, "Class=", 6))
1313 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1314 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1316 class = operand_classes
[i
].value
;
1322 if (str
&& !strncmp(str
, "Instance=", 9))
1324 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1325 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1327 instance
= operand_instances
[i
].value
;
1335 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1336 if (strcasecmp(str
, "BaseIndex") == 0)
1341 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1343 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1344 if (!active_cpu_flags
.bitfield
.cpu64
1345 && !active_cpu_flags
.bitfield
.cpumpx
)
1346 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1347 if (!active_cpu_flags
.bitfield
.cpu64
)
1348 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1349 if (!active_cpu_flags
.bitfield
.cpuno64
)
1350 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1353 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1358 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1359 char *last
, int lineno
)
1362 char *base_opcode
, *extension_opcode
, *opcode_length
;
1363 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1365 /* Find base_opcode. */
1366 base_opcode
= next_field (str
, ',', &str
, last
);
1368 /* Find extension_opcode. */
1369 extension_opcode
= next_field (str
, ',', &str
, last
);
1371 /* Find opcode_length. */
1372 opcode_length
= next_field (str
, ',', &str
, last
);
1374 /* Find cpu_flags. */
1375 cpu_flags
= next_field (str
, ',', &str
, last
);
1377 /* Find opcode_modifier. */
1378 opcode_modifier
= next_field (str
, ',', &str
, last
);
1380 /* Remove the first {. */
1381 str
= remove_leading_whitespaces (str
);
1384 str
= remove_leading_whitespaces (str
+ 1);
1385 remove_trailing_whitespaces (str
);
1387 /* Remove } and trailing white space. */
1389 if (!i
|| str
[i
- 1] != '}')
1392 remove_trailing_whitespaces (str
);
1395 operand_types
[i
= 0] = NULL
;
1398 last
= str
+ strlen (str
);
1400 /* Find operand_types. */
1401 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1405 operand_types
[i
] = NULL
;
1409 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1413 fprintf (table
, " { \"%s\", %s, %s, %s, %u,\n",
1414 name
, base_opcode
, extension_opcode
, opcode_length
, i
);
1416 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1418 if (process_i386_opcode_modifier (table
, opcode_modifier
,
1419 operand_types
, lineno
))
1422 unsigned long int length
= strtoul (opcode_length
, &end
, 0);
1423 unsigned long int opcode
= strtoul (base_opcode
, &end
, 0);
1429 if ((opcode
>> 24) != 0)
1430 fail (_("%s: %s: (base_opcode >> 24) != 0: %s\n"),
1431 filename
, name
, base_opcode
);
1434 if ((opcode
>> 16) != 0)
1435 fail (_("%s: %s: (base_opcode >> 16) != 0: %s\n"),
1436 filename
, name
, base_opcode
);
1439 if ((opcode
>> 8) != 0)
1440 fail (_("%s: %s: (base_opcode >> 8) != 0: %s\n"),
1441 filename
, name
, base_opcode
);
1445 fail (_("%s: %s: base_opcode != 0: %s\n"),
1446 filename
, name
, base_opcode
);
1449 fail (_("%s: %s: invalid opcode length: %s\n"),
1450 filename
, name
, opcode_length
);
1455 fprintf (table
, " { ");
1457 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1459 if (!operand_types
[i
])
1462 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1468 fprintf (table
, ",\n ");
1470 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1473 fprintf (table
, " } },\n");
1476 struct opcode_hash_entry
1478 struct opcode_hash_entry
*next
;
1484 /* Calculate the hash value of an opcode hash entry P. */
1487 opcode_hash_hash (const void *p
)
1489 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1490 return htab_hash_string (entry
->name
);
1493 /* Compare a string Q against an opcode hash entry P. */
1496 opcode_hash_eq (const void *p
, const void *q
)
1498 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1499 const char *name
= (const char *) q
;
1500 return strcmp (name
, entry
->name
) == 0;
1504 parse_template (char *buf
, int lineno
)
1506 char sep
, *end
, *name
;
1507 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1508 struct template_instance
*last_inst
= NULL
;
1510 buf
= remove_leading_whitespaces (buf
+ 1);
1511 end
= strchr (buf
, ':');
1513 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1515 remove_trailing_whitespaces (buf
);
1518 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1519 tmpl
->name
= xstrdup (buf
);
1521 tmpl
->params
= NULL
;
1523 struct template_param
*param
;
1525 buf
= remove_leading_whitespaces (end
);
1526 end
= strpbrk (buf
, ":,");
1528 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1532 remove_trailing_whitespaces (buf
);
1534 param
= xmalloc (sizeof (*param
));
1535 param
->name
= xstrdup (buf
);
1536 param
->next
= tmpl
->params
;
1537 tmpl
->params
= param
;
1538 } while (sep
== ':');
1540 tmpl
->instances
= NULL
;
1542 struct template_instance
*inst
;
1544 const struct template_param
*param
;
1546 buf
= remove_leading_whitespaces (end
);
1547 end
= strpbrk (buf
, ",>");
1549 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1554 inst
= xmalloc (sizeof (*inst
));
1558 cur
= next_field (buf
, ':', &next
, end
);
1559 inst
->name
= xstrdup (cur
);
1561 for (param
= tmpl
->params
; param
; param
= param
->next
)
1563 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1565 cur
= next_field (next
, ':', &next
, end
);
1567 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1568 arg
->val
= xstrdup (cur
);
1569 arg
->next
= inst
->args
;
1573 if (tmpl
->instances
)
1574 last_inst
->next
= inst
;
1576 tmpl
->instances
= inst
;
1578 } while (sep
== ',');
1580 buf
= remove_leading_whitespaces (end
);
1582 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1583 filename
, lineno
, buf
);
1585 tmpl
->next
= templates
;
1590 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1591 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1593 static unsigned int idx
, opcode_array_size
;
1594 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1595 struct opcode_hash_entry
**hash_slot
, **entry
;
1596 char *ptr1
= strchr(name
, '<'), *ptr2
;
1600 /* Get the slot in hash table. */
1601 hash_slot
= (struct opcode_hash_entry
**)
1602 htab_find_slot_with_hash (opcode_hash_table
, name
,
1603 htab_hash_string (name
),
1606 if (*hash_slot
== NULL
)
1608 /* It is the new one. Put it on opcode array. */
1609 if (idx
>= opcode_array_size
)
1611 /* Grow the opcode array when needed. */
1612 opcode_array_size
+= 1024;
1613 opcode_array
= (struct opcode_hash_entry
**)
1614 xrealloc (opcode_array
,
1615 sizeof (*opcode_array
) * opcode_array_size
);
1616 *opcode_array_p
= opcode_array
;
1619 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1620 xmalloc (sizeof (struct opcode_hash_entry
));
1621 opcode_array
[idx
]->next
= NULL
;
1622 opcode_array
[idx
]->name
= xstrdup (name
);
1623 opcode_array
[idx
]->opcode
= xstrdup (str
);
1624 opcode_array
[idx
]->lineno
= lineno
;
1625 *hash_slot
= opcode_array
[idx
];
1630 /* Append it to the existing one. */
1632 while ((*entry
) != NULL
)
1633 entry
= &(*entry
)->next
;
1634 *entry
= (struct opcode_hash_entry
*)
1635 xmalloc (sizeof (struct opcode_hash_entry
));
1636 (*entry
)->next
= NULL
;
1637 (*entry
)->name
= (*hash_slot
)->name
;
1638 (*entry
)->opcode
= xstrdup (str
);
1639 (*entry
)->lineno
= lineno
;
1642 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1643 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1646 const struct template *tmpl
;
1647 const struct template_instance
*inst
;
1650 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1651 remove_trailing_whitespaces (ptr1
);
1655 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1656 if (!strcmp(ptr1
, tmpl
->name
))
1659 fail ("reference to unknown template '%s'\n", ptr1
);
1661 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1663 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1664 char *str2
= xmalloc(2 * strlen(str
));
1667 strcpy (name2
, name
);
1668 strcat (name2
, inst
->name
);
1669 strcat (name2
, ptr2
);
1671 for (ptr1
= str2
, src
= str
; *src
; )
1673 const char *ident
= tmpl
->name
, *end
;
1674 const struct template_param
*param
;
1675 const struct template_arg
*arg
;
1677 if ((*ptr1
= *src
++) != '<')
1682 while (ISSPACE(*src
))
1684 while (*ident
&& *src
== *ident
)
1686 while (ISSPACE(*src
))
1688 if (*src
!= ':' || *ident
!= '\0')
1690 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1691 ptr1
+= ident
- tmpl
->name
;
1694 while (ISSPACE(*++src
))
1698 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1701 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1702 param
= param
->next
, arg
= arg
->next
)
1704 if (end
- src
== strlen (param
->name
)
1705 && !memcmp (src
, param
->name
, end
- src
))
1713 fail ("template '%s' has no parameter '%.*s'\n",
1714 tmpl
->name
, (int)(end
- src
), src
);
1716 while (ISSPACE(*src
))
1719 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1721 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1722 ptr1
+= strlen(arg
->val
);
1728 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1740 process_i386_opcodes (FILE *table
)
1745 char *str
, *p
, *last
, *name
;
1746 htab_t opcode_hash_table
;
1747 struct opcode_hash_entry
**opcode_array
= NULL
;
1748 int lineno
= 0, marker
= 0;
1750 filename
= "i386-opc.tbl";
1754 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1755 opcode_hash_eq
, NULL
,
1758 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1759 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1761 /* Put everything on opcode array. */
1764 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1769 p
= remove_leading_whitespaces (buf
);
1771 /* Skip comments. */
1772 str
= strstr (p
, "//");
1776 /* Remove trailing white spaces. */
1777 remove_trailing_whitespaces (p
);
1782 if (!strcmp("### MARKER ###", buf
))
1786 /* Since we ignore all included files (we only care about their
1787 #define-s here), we don't need to monitor filenames. The final
1788 line number directive is going to refer to the main source file
1793 p
= remove_leading_whitespaces (p
+ 1);
1794 if (!strncmp(p
, "line", 4))
1796 ln
= strtoul (p
, &end
, 10);
1797 if (ln
> 1 && ln
< INT_MAX
1798 && *remove_leading_whitespaces (end
) == '"')
1801 /* Ignore comments. */
1806 parse_template (p
, lineno
);
1814 last
= p
+ strlen (p
);
1817 name
= next_field (p
, ',', &str
, last
);
1819 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1823 /* Process opcode array. */
1824 for (j
= 0; j
< i
; j
++)
1826 struct opcode_hash_entry
*next
;
1828 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1832 lineno
= next
->lineno
;
1833 last
= str
+ strlen (str
);
1834 output_i386_opcode (table
, name
, str
, last
, lineno
);
1840 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1842 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1844 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1846 fprintf (table
, " { ");
1847 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1848 fprintf (table
, " } }\n");
1850 fprintf (table
, "};\n");
1854 process_i386_registers (FILE *table
)
1858 char *str
, *p
, *last
;
1859 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1860 char *dw2_32_num
, *dw2_64_num
;
1863 filename
= "i386-reg.tbl";
1864 fp
= fopen (filename
, "r");
1866 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1869 fprintf (table
, "\n/* i386 register table. */\n\n");
1870 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1874 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1879 p
= remove_leading_whitespaces (buf
);
1881 /* Skip comments. */
1882 str
= strstr (p
, "//");
1886 /* Remove trailing white spaces. */
1887 remove_trailing_whitespaces (p
);
1892 fprintf (table
, "%s\n", p
);
1900 last
= p
+ strlen (p
);
1902 /* Find reg_name. */
1903 reg_name
= next_field (p
, ',', &str
, last
);
1905 /* Find reg_type. */
1906 reg_type
= next_field (str
, ',', &str
, last
);
1908 /* Find reg_flags. */
1909 reg_flags
= next_field (str
, ',', &str
, last
);
1912 reg_num
= next_field (str
, ',', &str
, last
);
1914 fprintf (table
, " { \"%s\",\n ", reg_name
);
1916 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1919 /* Find 32-bit Dwarf2 register number. */
1920 dw2_32_num
= next_field (str
, ',', &str
, last
);
1922 /* Find 64-bit Dwarf2 register number. */
1923 dw2_64_num
= next_field (str
, ',', &str
, last
);
1925 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1926 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1931 fprintf (table
, "};\n");
1933 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1937 process_i386_initializers (void)
1940 FILE *fp
= fopen ("i386-init.h", "w");
1944 fail (_("can't create i386-init.h, errno = %s\n"),
1947 process_copyright (fp
);
1949 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1951 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1952 init
= xstrdup (cpu_flag_init
[i
].init
);
1953 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1957 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1959 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1960 init
= xstrdup (operand_type_init
[i
].init
);
1961 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1969 /* Program options. */
1970 #define OPTION_SRCDIR 200
1972 struct option long_options
[] =
1974 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1975 {"debug", no_argument
, NULL
, 'd'},
1976 {"version", no_argument
, NULL
, 'V'},
1977 {"help", no_argument
, NULL
, 'h'},
1978 {0, no_argument
, NULL
, 0}
1982 print_version (void)
1984 printf ("%s: version 1.0\n", program_name
);
1989 usage (FILE * stream
, int status
)
1991 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1997 main (int argc
, char **argv
)
1999 extern int chdir (char *);
2000 char *srcdir
= NULL
;
2002 unsigned int i
, cpumax
;
2005 program_name
= *argv
;
2006 xmalloc_set_program_name (program_name
);
2008 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2033 if (chdir (srcdir
) != 0)
2034 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2035 srcdir
, xstrerror (errno
));
2037 /* cpu_flags isn't sorted by position. */
2039 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2040 if (cpu_flags
[i
].position
> cpumax
)
2041 cpumax
= cpu_flags
[i
].position
;
2043 /* Check the unused bitfield in i386_cpu_flags. */
2045 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2047 if ((cpumax
- 1) != CpuMax
)
2048 fail (_("CpuMax != %d!\n"), cpumax
);
2050 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2052 if (cpumax
!= CpuMax
)
2053 fail (_("CpuMax != %d!\n"), cpumax
);
2055 c
= CpuNumOfBits
- CpuMax
- 1;
2057 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
2060 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2062 /* Check the unused bitfield in i386_operand_type. */
2064 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2067 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2070 c
= OTNumOfBits
- OTNum
;
2072 fail (_("%d unused bits in i386_operand_type.\n"), c
);
2075 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2078 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2079 sizeof (opcode_modifiers
[0]), compare
);
2081 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2082 sizeof (operand_types
[0]), compare
);
2084 table
= fopen ("i386-tbl.h", "w");
2086 fail (_("can't create i386-tbl.h, errno = %s\n"),
2089 process_copyright (table
);
2091 process_i386_opcodes (table
);
2092 process_i386_registers (table
);
2093 process_i386_initializers ();