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 (OpcodePrefix
),
723 BITFIELD (VexSources
),
729 BITFIELD (Broadcast
),
730 BITFIELD (StaticRounding
),
732 BITFIELD (Disp8MemShift
),
733 BITFIELD (NoDefMask
),
734 BITFIELD (ImplicitQuadGroup
),
735 BITFIELD (SwapSources
),
737 BITFIELD (ATTMnemonic
),
738 BITFIELD (ATTSyntax
),
739 BITFIELD (IntelSyntax
),
743 #define CLASS(n) #n, n
745 static const struct {
747 enum operand_class value
;
748 } operand_classes
[] = {
762 #define INSTANCE(n) #n, n
764 static const struct {
766 enum operand_instance value
;
767 } operand_instances
[] = {
776 static bitfield operand_types
[] =
785 BITFIELD (BaseIndex
),
801 BITFIELD (Unspecified
),
807 static const char *filename
;
808 static i386_cpu_flags active_cpu_flags
;
809 static int active_isstring
;
811 struct template_arg
{
812 const struct template_arg
*next
;
816 struct template_instance
{
817 const struct template_instance
*next
;
819 const struct template_arg
*args
;
822 struct template_param
{
823 const struct template_param
*next
;
828 const struct template *next
;
830 const struct template_instance
*instances
;
831 const struct template_param
*params
;
834 static const struct template *templates
;
837 compare (const void *x
, const void *y
)
839 const bitfield
*xp
= (const bitfield
*) x
;
840 const bitfield
*yp
= (const bitfield
*) y
;
841 return xp
->position
- yp
->position
;
845 fail (const char *message
, ...)
849 va_start (args
, message
);
850 fprintf (stderr
, _("%s: error: "), program_name
);
851 vfprintf (stderr
, message
, args
);
857 process_copyright (FILE *fp
)
859 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
860 /* Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\
862 This file is part of the GNU opcodes library.\n\
864 This library is free software; you can redistribute it and/or modify\n\
865 it under the terms of the GNU General Public License as published by\n\
866 the Free Software Foundation; either version 3, or (at your option)\n\
867 any later version.\n\
869 It is distributed in the hope that it will be useful, but WITHOUT\n\
870 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
871 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
872 License for more details.\n\
874 You should have received a copy of the GNU General Public License\n\
875 along with this program; if not, write to the Free Software\n\
876 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
877 MA 02110-1301, USA. */\n");
880 /* Remove leading white spaces. */
883 remove_leading_whitespaces (char *str
)
885 while (ISSPACE (*str
))
890 /* Remove trailing white spaces. */
893 remove_trailing_whitespaces (char *str
)
895 size_t last
= strlen (str
);
903 if (ISSPACE (str
[last
]))
911 /* Find next field separated by SEP and terminate it. Return a
912 pointer to the one after it. */
915 next_field (char *str
, char sep
, char **next
, char *last
)
919 p
= remove_leading_whitespaces (str
);
920 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
923 remove_trailing_whitespaces (p
);
933 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
936 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
939 char *str
, *next
, *last
;
942 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
943 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
945 /* Turn on selective bits. */
946 char *init
= xstrdup (cpu_flag_init
[i
].init
);
947 last
= init
+ strlen (init
);
948 for (next
= init
; next
&& next
< last
; )
950 str
= next_field (next
, '|', &next
, last
);
952 set_bitfield (str
, array
, 1, size
, lineno
);
962 set_bitfield (char *f
, bitfield
*array
, int value
,
963 unsigned int size
, int lineno
)
967 /* Ignore empty fields; they may result from template expansions. */
971 for (i
= 0; i
< size
; i
++)
972 if (strcasecmp (array
[i
].name
, f
) == 0)
974 array
[i
].value
= value
;
980 const char *v
= strchr (f
, '=');
987 for (i
= 0; i
< size
; i
++)
988 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
990 value
= strtol (v
+ 1, &end
, 0);
993 array
[i
].value
= value
;
1001 /* Handle CPU_XXX_FLAGS. */
1002 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
1006 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
1008 fail (_("unknown bitfield: %s\n"), f
);
1012 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
1013 int macro
, const char *comma
, const char *indent
)
1017 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
1019 fprintf (table
, "%s{ { ", indent
);
1021 for (i
= 0; i
< size
- 1; i
++)
1023 if (((i
+ 1) % 20) != 0)
1024 fprintf (table
, "%d, ", flags
[i
].value
);
1026 fprintf (table
, "%d,", flags
[i
].value
);
1027 if (((i
+ 1) % 20) == 0)
1029 /* We need \\ for macro. */
1031 fprintf (table
, " \\\n %s", indent
);
1033 fprintf (table
, "\n %s", indent
);
1036 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
1039 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
1043 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
1044 const char *comma
, const char *indent
,
1047 char *str
, *next
, *last
;
1049 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1051 /* Copy the default cpu flags. */
1052 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1054 if (strcasecmp (flag
, "unknown") == 0)
1056 /* We turn on everything except for cpu64 in case of
1057 CPU_UNKNOWN_FLAGS. */
1058 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1059 if (flags
[i
].position
!= Cpu64
)
1062 else if (flag
[0] == '~')
1064 last
= flag
+ strlen (flag
);
1071 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1078 /* First we turn on everything except for cpu64. */
1079 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1080 if (flags
[i
].position
!= Cpu64
)
1083 /* Turn off selective bits. */
1084 for (; next
&& next
< last
; )
1086 str
= next_field (next
, '|', &next
, last
);
1088 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1091 else if (strcmp (flag
, "0"))
1093 /* Turn on selective bits. */
1094 last
= flag
+ strlen (flag
);
1095 for (next
= flag
; next
&& next
< last
; )
1097 str
= next_field (next
, '|', &next
, last
);
1099 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1103 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1108 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1112 fprintf (table
, " { ");
1114 for (i
= 0; i
< size
- 1; i
++)
1116 if (((i
+ 1) % 20) != 0)
1117 fprintf (table
, "%d, ", modifier
[i
].value
);
1119 fprintf (table
, "%d,", modifier
[i
].value
);
1120 if (((i
+ 1) % 20) == 0)
1121 fprintf (table
, "\n ");
1124 fprintf (table
, "%d },\n", modifier
[i
].value
);
1128 adjust_broadcast_modifier (char **opnd
)
1130 char *str
, *next
, *last
, *op
;
1131 int bcst_type
= INT_MAX
;
1133 /* Skip the immediate operand. */
1135 if (strcasecmp(op
, "Imm8") == 0)
1139 last
= op
+ strlen (op
);
1140 for (next
= op
; next
&& next
< last
; )
1142 str
= next_field (next
, '|', &next
, last
);
1145 if (strcasecmp(str
, "Byte") == 0)
1147 /* The smalest broadcast type, no need to check
1149 bcst_type
= BYTE_BROADCAST
;
1152 else if (strcasecmp(str
, "Word") == 0)
1154 if (bcst_type
> WORD_BROADCAST
)
1155 bcst_type
= WORD_BROADCAST
;
1157 else if (strcasecmp(str
, "Dword") == 0)
1159 if (bcst_type
> DWORD_BROADCAST
)
1160 bcst_type
= DWORD_BROADCAST
;
1162 else if (strcasecmp(str
, "Qword") == 0)
1164 if (bcst_type
> QWORD_BROADCAST
)
1165 bcst_type
= QWORD_BROADCAST
;
1171 if (bcst_type
== INT_MAX
)
1172 fail (_("unknown broadcast operand: %s\n"), op
);
1178 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1180 char *str
, *next
, *last
;
1181 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1182 unsigned int regular_encoding
= 1;
1184 active_isstring
= 0;
1186 /* Copy the default opcode modifier. */
1187 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1189 if (strcmp (mod
, "0"))
1191 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1193 last
= mod
+ strlen (mod
);
1194 for (next
= mod
; next
&& next
< last
; )
1196 str
= next_field (next
, '|', &next
, last
);
1200 if (strcasecmp(str
, "Broadcast") == 0)
1202 val
= adjust_broadcast_modifier (opnd
);
1203 regular_encoding
= 0;
1205 else if (strcasecmp(str
, "Vex") == 0
1206 || strncasecmp(str
, "Vex=", 4) == 0
1207 || strcasecmp(str
, "EVex") == 0
1208 || strncasecmp(str
, "EVex=", 5) == 0
1209 || strncasecmp(str
, "Disp8MemShift=", 14) == 0
1210 || strncasecmp(str
, "Masking=", 8) == 0
1211 || strcasecmp(str
, "SAE") == 0
1212 || strcasecmp(str
, "IsPrefix") == 0)
1213 regular_encoding
= 0;
1215 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1217 if (strcasecmp(str
, "IsString") == 0)
1218 active_isstring
= 1;
1220 if (strcasecmp(str
, "W") == 0)
1223 if (strcasecmp(str
, "No_bSuf") == 0)
1225 if (strcasecmp(str
, "No_wSuf") == 0)
1227 if (strcasecmp(str
, "No_lSuf") == 0)
1229 if (strcasecmp(str
, "No_qSuf") == 0)
1234 if (have_w
&& !bwlq_suf
)
1235 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1236 if (have_w
&& !(bwlq_suf
& 1))
1237 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1239 if (have_w
&& !(bwlq_suf
& ~1))
1241 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1244 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1246 return regular_encoding
;
1256 output_operand_type (FILE *table
, enum operand_class
class,
1257 enum operand_instance instance
,
1258 const bitfield
*types
, unsigned int size
,
1259 enum stage stage
, const char *indent
)
1263 fprintf (table
, "{ { %d, %d, ", class, instance
);
1265 for (i
= 0; i
< size
- 1; i
++)
1267 if (((i
+ 3) % 20) != 0)
1268 fprintf (table
, "%d, ", types
[i
].value
);
1270 fprintf (table
, "%d,", types
[i
].value
);
1271 if (((i
+ 3) % 20) == 0)
1273 /* We need \\ for macro. */
1274 if (stage
== stage_macros
)
1275 fprintf (table
, " \\\n%s", indent
);
1277 fprintf (table
, "\n%s", indent
);
1281 fprintf (table
, "%d } }", types
[i
].value
);
1285 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1286 const char *indent
, int lineno
)
1288 char *str
, *next
, *last
;
1289 enum operand_class
class = ClassNone
;
1290 enum operand_instance instance
= InstanceNone
;
1291 bitfield types
[ARRAY_SIZE (operand_types
)];
1293 /* Copy the default operand type. */
1294 memcpy (types
, operand_types
, sizeof (types
));
1296 if (strcmp (op
, "0"))
1300 last
= op
+ strlen (op
);
1301 for (next
= op
; next
&& next
< last
; )
1303 str
= next_field (next
, '|', &next
, last
);
1308 if (!strncmp(str
, "Class=", 6))
1310 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1311 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1313 class = operand_classes
[i
].value
;
1319 if (str
&& !strncmp(str
, "Instance=", 9))
1321 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1322 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1324 instance
= operand_instances
[i
].value
;
1332 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1333 if (strcasecmp(str
, "BaseIndex") == 0)
1338 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1340 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1341 if (!active_cpu_flags
.bitfield
.cpu64
1342 && !active_cpu_flags
.bitfield
.cpumpx
)
1343 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1344 if (!active_cpu_flags
.bitfield
.cpu64
)
1345 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1346 if (!active_cpu_flags
.bitfield
.cpuno64
)
1347 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1350 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1355 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1356 char *last
, int lineno
)
1359 char *base_opcode
, *extension_opcode
, *opcode_length
;
1360 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1362 /* Find base_opcode. */
1363 base_opcode
= next_field (str
, ',', &str
, last
);
1365 /* Find extension_opcode. */
1366 extension_opcode
= next_field (str
, ',', &str
, last
);
1368 /* Find opcode_length. */
1369 opcode_length
= next_field (str
, ',', &str
, last
);
1371 /* Find cpu_flags. */
1372 cpu_flags
= next_field (str
, ',', &str
, last
);
1374 /* Find opcode_modifier. */
1375 opcode_modifier
= next_field (str
, ',', &str
, last
);
1377 /* Remove the first {. */
1378 str
= remove_leading_whitespaces (str
);
1381 str
= remove_leading_whitespaces (str
+ 1);
1382 remove_trailing_whitespaces (str
);
1384 /* Remove } and trailing white space. */
1386 if (!i
|| str
[i
- 1] != '}')
1389 remove_trailing_whitespaces (str
);
1392 operand_types
[i
= 0] = NULL
;
1395 last
= str
+ strlen (str
);
1397 /* Find operand_types. */
1398 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1402 operand_types
[i
] = NULL
;
1406 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1410 fprintf (table
, " { \"%s\", %s, %s, %s, %u,\n",
1411 name
, base_opcode
, extension_opcode
, opcode_length
, i
);
1413 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1415 if (process_i386_opcode_modifier (table
, opcode_modifier
,
1416 operand_types
, lineno
))
1419 unsigned long int length
= strtoul (opcode_length
, &end
, 0);
1420 unsigned long int opcode
= strtoul (base_opcode
, &end
, 0);
1426 if ((opcode
>> 24) != 0)
1427 fail (_("%s: %s: (base_opcode >> 24) != 0: %s\n"),
1428 filename
, name
, base_opcode
);
1431 if ((opcode
>> 16) != 0)
1432 fail (_("%s: %s: (base_opcode >> 16) != 0: %s\n"),
1433 filename
, name
, base_opcode
);
1436 if ((opcode
>> 8) != 0)
1437 fail (_("%s: %s: (base_opcode >> 8) != 0: %s\n"),
1438 filename
, name
, base_opcode
);
1442 fail (_("%s: %s: base_opcode != 0: %s\n"),
1443 filename
, name
, base_opcode
);
1446 fail (_("%s: %s: invalid opcode length: %s\n"),
1447 filename
, name
, opcode_length
);
1452 fprintf (table
, " { ");
1454 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1456 if (!operand_types
[i
])
1459 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1465 fprintf (table
, ",\n ");
1467 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1470 fprintf (table
, " } },\n");
1473 struct opcode_hash_entry
1475 struct opcode_hash_entry
*next
;
1481 /* Calculate the hash value of an opcode hash entry P. */
1484 opcode_hash_hash (const void *p
)
1486 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1487 return htab_hash_string (entry
->name
);
1490 /* Compare a string Q against an opcode hash entry P. */
1493 opcode_hash_eq (const void *p
, const void *q
)
1495 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1496 const char *name
= (const char *) q
;
1497 return strcmp (name
, entry
->name
) == 0;
1501 parse_template (char *buf
, int lineno
)
1503 char sep
, *end
, *name
;
1504 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1505 struct template_instance
*last_inst
= NULL
;
1507 buf
= remove_leading_whitespaces (buf
+ 1);
1508 end
= strchr (buf
, ':');
1510 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1512 remove_trailing_whitespaces (buf
);
1515 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1516 tmpl
->name
= xstrdup (buf
);
1518 tmpl
->params
= NULL
;
1520 struct template_param
*param
;
1522 buf
= remove_leading_whitespaces (end
);
1523 end
= strpbrk (buf
, ":,");
1525 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1529 remove_trailing_whitespaces (buf
);
1531 param
= xmalloc (sizeof (*param
));
1532 param
->name
= xstrdup (buf
);
1533 param
->next
= tmpl
->params
;
1534 tmpl
->params
= param
;
1535 } while (sep
== ':');
1537 tmpl
->instances
= NULL
;
1539 struct template_instance
*inst
;
1541 const struct template_param
*param
;
1543 buf
= remove_leading_whitespaces (end
);
1544 end
= strpbrk (buf
, ",>");
1546 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1551 inst
= xmalloc (sizeof (*inst
));
1555 cur
= next_field (buf
, ':', &next
, end
);
1556 inst
->name
= xstrdup (cur
);
1558 for (param
= tmpl
->params
; param
; param
= param
->next
)
1560 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1562 cur
= next_field (next
, ':', &next
, end
);
1564 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1565 arg
->val
= xstrdup (cur
);
1566 arg
->next
= inst
->args
;
1570 if (tmpl
->instances
)
1571 last_inst
->next
= inst
;
1573 tmpl
->instances
= inst
;
1575 } while (sep
== ',');
1577 buf
= remove_leading_whitespaces (end
);
1579 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1580 filename
, lineno
, buf
);
1582 tmpl
->next
= templates
;
1587 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1588 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1590 static unsigned int idx
, opcode_array_size
;
1591 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1592 struct opcode_hash_entry
**hash_slot
, **entry
;
1593 char *ptr1
= strchr(name
, '<'), *ptr2
;
1597 /* Get the slot in hash table. */
1598 hash_slot
= (struct opcode_hash_entry
**)
1599 htab_find_slot_with_hash (opcode_hash_table
, name
,
1600 htab_hash_string (name
),
1603 if (*hash_slot
== NULL
)
1605 /* It is the new one. Put it on opcode array. */
1606 if (idx
>= opcode_array_size
)
1608 /* Grow the opcode array when needed. */
1609 opcode_array_size
+= 1024;
1610 opcode_array
= (struct opcode_hash_entry
**)
1611 xrealloc (opcode_array
,
1612 sizeof (*opcode_array
) * opcode_array_size
);
1613 *opcode_array_p
= opcode_array
;
1616 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1617 xmalloc (sizeof (struct opcode_hash_entry
));
1618 opcode_array
[idx
]->next
= NULL
;
1619 opcode_array
[idx
]->name
= xstrdup (name
);
1620 opcode_array
[idx
]->opcode
= xstrdup (str
);
1621 opcode_array
[idx
]->lineno
= lineno
;
1622 *hash_slot
= opcode_array
[idx
];
1627 /* Append it to the existing one. */
1629 while ((*entry
) != NULL
)
1630 entry
= &(*entry
)->next
;
1631 *entry
= (struct opcode_hash_entry
*)
1632 xmalloc (sizeof (struct opcode_hash_entry
));
1633 (*entry
)->next
= NULL
;
1634 (*entry
)->name
= (*hash_slot
)->name
;
1635 (*entry
)->opcode
= xstrdup (str
);
1636 (*entry
)->lineno
= lineno
;
1639 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1640 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1643 const struct template *tmpl
;
1644 const struct template_instance
*inst
;
1647 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1648 remove_trailing_whitespaces (ptr1
);
1652 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1653 if (!strcmp(ptr1
, tmpl
->name
))
1656 fail ("reference to unknown template '%s'\n", ptr1
);
1658 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1660 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1661 char *str2
= xmalloc(2 * strlen(str
));
1664 strcpy (name2
, name
);
1665 strcat (name2
, inst
->name
);
1666 strcat (name2
, ptr2
);
1668 for (ptr1
= str2
, src
= str
; *src
; )
1670 const char *ident
= tmpl
->name
, *end
;
1671 const struct template_param
*param
;
1672 const struct template_arg
*arg
;
1674 if ((*ptr1
= *src
++) != '<')
1679 while (ISSPACE(*src
))
1681 while (*ident
&& *src
== *ident
)
1683 while (ISSPACE(*src
))
1685 if (*src
!= ':' || *ident
!= '\0')
1687 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1688 ptr1
+= ident
- tmpl
->name
;
1691 while (ISSPACE(*++src
))
1695 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1698 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1699 param
= param
->next
, arg
= arg
->next
)
1701 if (end
- src
== strlen (param
->name
)
1702 && !memcmp (src
, param
->name
, end
- src
))
1710 fail ("template '%s' has no parameter '%.*s'\n",
1711 tmpl
->name
, (int)(end
- src
), src
);
1713 while (ISSPACE(*src
))
1716 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1718 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1719 ptr1
+= strlen(arg
->val
);
1725 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1737 process_i386_opcodes (FILE *table
)
1742 char *str
, *p
, *last
, *name
;
1743 htab_t opcode_hash_table
;
1744 struct opcode_hash_entry
**opcode_array
= NULL
;
1745 int lineno
= 0, marker
= 0;
1747 filename
= "i386-opc.tbl";
1751 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1752 opcode_hash_eq
, NULL
,
1755 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1756 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1758 /* Put everything on opcode array. */
1761 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1766 p
= remove_leading_whitespaces (buf
);
1768 /* Skip comments. */
1769 str
= strstr (p
, "//");
1773 /* Remove trailing white spaces. */
1774 remove_trailing_whitespaces (p
);
1779 if (!strcmp("### MARKER ###", buf
))
1783 /* Since we ignore all included files (we only care about their
1784 #define-s here), we don't need to monitor filenames. The final
1785 line number directive is going to refer to the main source file
1790 p
= remove_leading_whitespaces (p
+ 1);
1791 if (!strncmp(p
, "line", 4))
1793 ln
= strtoul (p
, &end
, 10);
1794 if (ln
> 1 && ln
< INT_MAX
1795 && *remove_leading_whitespaces (end
) == '"')
1798 /* Ignore comments. */
1803 parse_template (p
, lineno
);
1811 last
= p
+ strlen (p
);
1814 name
= next_field (p
, ',', &str
, last
);
1816 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1820 /* Process opcode array. */
1821 for (j
= 0; j
< i
; j
++)
1823 struct opcode_hash_entry
*next
;
1825 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1829 lineno
= next
->lineno
;
1830 last
= str
+ strlen (str
);
1831 output_i386_opcode (table
, name
, str
, last
, lineno
);
1837 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1839 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1841 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1843 fprintf (table
, " { ");
1844 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1845 fprintf (table
, " } }\n");
1847 fprintf (table
, "};\n");
1851 process_i386_registers (FILE *table
)
1855 char *str
, *p
, *last
;
1856 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1857 char *dw2_32_num
, *dw2_64_num
;
1860 filename
= "i386-reg.tbl";
1861 fp
= fopen (filename
, "r");
1863 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1866 fprintf (table
, "\n/* i386 register table. */\n\n");
1867 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1871 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1876 p
= remove_leading_whitespaces (buf
);
1878 /* Skip comments. */
1879 str
= strstr (p
, "//");
1883 /* Remove trailing white spaces. */
1884 remove_trailing_whitespaces (p
);
1889 fprintf (table
, "%s\n", p
);
1897 last
= p
+ strlen (p
);
1899 /* Find reg_name. */
1900 reg_name
= next_field (p
, ',', &str
, last
);
1902 /* Find reg_type. */
1903 reg_type
= next_field (str
, ',', &str
, last
);
1905 /* Find reg_flags. */
1906 reg_flags
= next_field (str
, ',', &str
, last
);
1909 reg_num
= next_field (str
, ',', &str
, last
);
1911 fprintf (table
, " { \"%s\",\n ", reg_name
);
1913 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1916 /* Find 32-bit Dwarf2 register number. */
1917 dw2_32_num
= next_field (str
, ',', &str
, last
);
1919 /* Find 64-bit Dwarf2 register number. */
1920 dw2_64_num
= next_field (str
, ',', &str
, last
);
1922 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1923 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1928 fprintf (table
, "};\n");
1930 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1934 process_i386_initializers (void)
1937 FILE *fp
= fopen ("i386-init.h", "w");
1941 fail (_("can't create i386-init.h, errno = %s\n"),
1944 process_copyright (fp
);
1946 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1948 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1949 init
= xstrdup (cpu_flag_init
[i
].init
);
1950 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1954 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1956 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1957 init
= xstrdup (operand_type_init
[i
].init
);
1958 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1966 /* Program options. */
1967 #define OPTION_SRCDIR 200
1969 struct option long_options
[] =
1971 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1972 {"debug", no_argument
, NULL
, 'd'},
1973 {"version", no_argument
, NULL
, 'V'},
1974 {"help", no_argument
, NULL
, 'h'},
1975 {0, no_argument
, NULL
, 0}
1979 print_version (void)
1981 printf ("%s: version 1.0\n", program_name
);
1986 usage (FILE * stream
, int status
)
1988 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1994 main (int argc
, char **argv
)
1996 extern int chdir (char *);
1997 char *srcdir
= NULL
;
1999 unsigned int i
, cpumax
;
2002 program_name
= *argv
;
2003 xmalloc_set_program_name (program_name
);
2005 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2030 if (chdir (srcdir
) != 0)
2031 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2032 srcdir
, xstrerror (errno
));
2034 /* cpu_flags isn't sorted by position. */
2036 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2037 if (cpu_flags
[i
].position
> cpumax
)
2038 cpumax
= cpu_flags
[i
].position
;
2040 /* Check the unused bitfield in i386_cpu_flags. */
2042 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2044 if ((cpumax
- 1) != CpuMax
)
2045 fail (_("CpuMax != %d!\n"), cpumax
);
2047 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2049 if (cpumax
!= CpuMax
)
2050 fail (_("CpuMax != %d!\n"), cpumax
);
2052 c
= CpuNumOfBits
- CpuMax
- 1;
2054 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
2057 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2059 /* Check the unused bitfield in i386_operand_type. */
2061 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2064 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2067 c
= OTNumOfBits
- OTNum
;
2069 fail (_("%d unused bits in i386_operand_type.\n"), c
);
2072 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2075 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2076 sizeof (opcode_modifiers
[0]), compare
);
2078 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2079 sizeof (operand_types
[0]), compare
);
2081 table
= fopen ("i386-tbl.h", "w");
2083 fail (_("can't create i386-tbl.h, errno = %s\n"),
2086 process_copyright (table
);
2088 process_i386_opcodes (table
);
2089 process_i386_registers (table
);
2090 process_i386_initializers ();