1 /* Copyright (C) 2007-2020 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_BTVER1_FLAGS",
107 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
108 { "CPU_BTVER2_FLAGS",
109 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
117 "CPU_387_FLAGS|Cpu687" },
122 { "CPU_CLFLUSH_FLAGS",
126 { "CPU_SYSCALL_FLAGS",
133 "CPU_SSE_FLAGS|CpuSSE2" },
135 "CPU_SSE2_FLAGS|CpuSSE3" },
137 "CPU_SSE3_FLAGS|CpuSSSE3" },
138 { "CPU_SSE4_1_FLAGS",
139 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
140 { "CPU_SSE4_2_FLAGS",
141 "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
148 { "CPU_XSAVEOPT_FLAGS",
149 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
151 "CPU_SSE2_FLAGS|CpuAES" },
152 { "CPU_PCLMUL_FLAGS",
153 "CPU_SSE2_FLAGS|CpuPCLMUL" },
155 "CPU_AVX_FLAGS|CpuFMA" },
157 "CPU_AVX_FLAGS|CpuFMA4" },
159 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
161 "CPU_XSAVE_FLAGS|CpuLWP" },
170 { "CPU_RDTSCP_FLAGS",
174 { "CPU_FSGSBASE_FLAGS",
179 "CPU_AVX_FLAGS|CpuF16C" },
184 { "CPU_POPCNT_FLAGS",
190 { "CPU_INVPCID_FLAGS",
192 { "CPU_VMFUNC_FLAGS",
195 "CPU_MMX_FLAGS|Cpu3dnow" },
196 { "CPU_3DNOWA_FLAGS",
197 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
198 { "CPU_PADLOCK_FLAGS",
203 "CPU_SSE3_FLAGS|CpuSSE4a" },
205 "CpuLZCNT|CpuPOPCNT" },
207 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
209 "CPU_AVX_FLAGS|CpuAVX2" },
210 { "CPU_AVX512F_FLAGS",
211 "CPU_AVX2_FLAGS|CpuAVX512F" },
212 { "CPU_AVX512CD_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
214 { "CPU_AVX512ER_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
216 { "CPU_AVX512PF_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
218 { "CPU_AVX512DQ_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
220 { "CPU_AVX512BW_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
222 { "CPU_AVX512VL_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
224 { "CPU_AVX512IFMA_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
226 { "CPU_AVX512VBMI_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
228 { "CPU_AVX512_4FMAPS_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
230 { "CPU_AVX512_4VNNIW_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
232 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
234 { "CPU_AVX512_VBMI2_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
236 { "CPU_AVX512_VNNI_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
238 { "CPU_AVX512_BITALG_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
240 { "CPU_AVX512_BF16_FLAGS",
241 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
247 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
250 { "CPU_RDSEED_FLAGS",
252 { "CPU_PRFCHW_FLAGS",
257 "CPU_XSAVE_FLAGS|CpuMPX" },
259 "CPU_SSE2_FLAGS|CpuSHA" },
260 { "CPU_CLFLUSHOPT_FLAGS",
262 { "CPU_XSAVES_FLAGS",
263 "CPU_XSAVE_FLAGS|CpuXSAVES" },
264 { "CPU_XSAVEC_FLAGS",
265 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
266 { "CPU_PREFETCHWT1_FLAGS",
272 { "CPU_CLZERO_FLAGS",
274 { "CPU_MWAITX_FLAGS",
277 "CPU_XSAVE_FLAGS|CpuOSPKE" },
280 { "CPU_PTWRITE_FLAGS",
290 { "CPU_VPCLMULQDQ_FLAGS",
292 { "CPU_WBNOINVD_FLAGS",
294 { "CPU_PCONFIG_FLAGS",
296 { "CPU_WAITPKG_FLAGS",
300 { "CPU_CLDEMOTE_FLAGS",
302 { "CPU_AMX_INT8_FLAGS",
304 { "CPU_AMX_BF16_FLAGS",
306 { "CPU_AMX_TILE_FLAGS",
308 { "CPU_MOVDIRI_FLAGS",
310 { "CPU_MOVDIR64B_FLAGS",
312 { "CPU_ENQCMD_FLAGS",
314 { "CPU_SERIALIZE_FLAGS",
316 { "CPU_AVX512_VP2INTERSECT_FLAGS",
317 "CpuAVX512_VP2INTERSECT" },
322 { "CPU_MCOMMIT_FLAGS",
324 { "CPU_SEV_ES_FLAGS",
326 { "CPU_TSXLDTRK_FLAGS",
330 { "CPU_WIDEKL_FLAGS",
332 { "CPU_ANY_X87_FLAGS",
333 "CPU_ANY_287_FLAGS|Cpu8087" },
334 { "CPU_ANY_287_FLAGS",
335 "CPU_ANY_387_FLAGS|Cpu287" },
336 { "CPU_ANY_387_FLAGS",
337 "CPU_ANY_687_FLAGS|Cpu387" },
338 { "CPU_ANY_687_FLAGS",
339 "Cpu687|CpuFISTTP" },
340 { "CPU_ANY_CMOV_FLAGS",
342 { "CPU_ANY_FXSR_FLAGS",
344 { "CPU_ANY_MMX_FLAGS",
345 "CPU_3DNOWA_FLAGS" },
346 { "CPU_ANY_SSE_FLAGS",
347 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
348 { "CPU_ANY_SSE2_FLAGS",
349 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
350 { "CPU_ANY_SSE3_FLAGS",
351 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
352 { "CPU_ANY_SSSE3_FLAGS",
353 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
354 { "CPU_ANY_SSE4_1_FLAGS",
355 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
356 { "CPU_ANY_SSE4_2_FLAGS",
358 { "CPU_ANY_SSE4A_FLAGS",
360 { "CPU_ANY_AVX_FLAGS",
361 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
362 { "CPU_ANY_AVX2_FLAGS",
363 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
364 { "CPU_ANY_AVX512F_FLAGS",
365 "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" },
366 { "CPU_ANY_AVX512CD_FLAGS",
368 { "CPU_ANY_AVX512ER_FLAGS",
370 { "CPU_ANY_AVX512PF_FLAGS",
372 { "CPU_ANY_AVX512DQ_FLAGS",
374 { "CPU_ANY_AVX512BW_FLAGS",
376 { "CPU_ANY_AVX512VL_FLAGS",
378 { "CPU_ANY_AVX512IFMA_FLAGS",
380 { "CPU_ANY_AVX512VBMI_FLAGS",
382 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
383 "CpuAVX512_4FMAPS" },
384 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
385 "CpuAVX512_4VNNIW" },
386 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
387 "CpuAVX512_VPOPCNTDQ" },
388 { "CPU_ANY_IBT_FLAGS",
390 { "CPU_ANY_SHSTK_FLAGS",
392 { "CPU_ANY_AVX512_VBMI2_FLAGS",
394 { "CPU_ANY_AVX512_VNNI_FLAGS",
396 { "CPU_ANY_AVX512_BITALG_FLAGS",
397 "CpuAVX512_BITALG" },
398 { "CPU_ANY_AVX512_BF16_FLAGS",
400 { "CPU_ANY_AMX_INT8_FLAGS",
402 { "CPU_ANY_AMX_BF16_FLAGS",
404 { "CPU_ANY_AMX_TILE_FLAGS",
405 "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" },
406 { "CPU_ANY_MOVDIRI_FLAGS",
408 { "CPU_ANY_UINTR_FLAGS",
410 { "CPU_ANY_MOVDIR64B_FLAGS",
412 { "CPU_ANY_ENQCMD_FLAGS",
414 { "CPU_ANY_SERIALIZE_FLAGS",
416 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
417 "CpuAVX512_VP2INTERSECT" },
418 { "CPU_ANY_TDX_FLAGS",
420 { "CPU_ANY_TSXLDTRK_FLAGS",
422 { "CPU_ANY_KL_FLAGS",
424 { "CPU_ANY_WIDEKL_FLAGS",
428 static initializer operand_type_init
[] =
430 { "OPERAND_TYPE_NONE",
432 { "OPERAND_TYPE_REG8",
434 { "OPERAND_TYPE_REG16",
436 { "OPERAND_TYPE_REG32",
438 { "OPERAND_TYPE_REG64",
440 { "OPERAND_TYPE_IMM1",
442 { "OPERAND_TYPE_IMM8",
444 { "OPERAND_TYPE_IMM8S",
446 { "OPERAND_TYPE_IMM16",
448 { "OPERAND_TYPE_IMM32",
450 { "OPERAND_TYPE_IMM32S",
452 { "OPERAND_TYPE_IMM64",
454 { "OPERAND_TYPE_BASEINDEX",
456 { "OPERAND_TYPE_DISP8",
458 { "OPERAND_TYPE_DISP16",
460 { "OPERAND_TYPE_DISP32",
462 { "OPERAND_TYPE_DISP32S",
464 { "OPERAND_TYPE_DISP64",
466 { "OPERAND_TYPE_INOUTPORTREG",
467 "Instance=RegD|Word" },
468 { "OPERAND_TYPE_SHIFTCOUNT",
469 "Instance=RegC|Byte" },
470 { "OPERAND_TYPE_CONTROL",
472 { "OPERAND_TYPE_TEST",
474 { "OPERAND_TYPE_DEBUG",
476 { "OPERAND_TYPE_FLOATREG",
478 { "OPERAND_TYPE_FLOATACC",
479 "Instance=Accum|Tbyte" },
480 { "OPERAND_TYPE_SREG",
482 { "OPERAND_TYPE_REGMMX",
484 { "OPERAND_TYPE_REGXMM",
485 "Class=RegSIMD|Xmmword" },
486 { "OPERAND_TYPE_REGYMM",
487 "Class=RegSIMD|Ymmword" },
488 { "OPERAND_TYPE_REGZMM",
489 "Class=RegSIMD|Zmmword" },
490 { "OPERAND_TYPE_REGTMM",
491 "Class=RegSIMD|Tmmword" },
492 { "OPERAND_TYPE_REGMASK",
494 { "OPERAND_TYPE_REGBND",
496 { "OPERAND_TYPE_ACC8",
497 "Instance=Accum|Byte" },
498 { "OPERAND_TYPE_ACC16",
499 "Instance=Accum|Word" },
500 { "OPERAND_TYPE_ACC32",
501 "Instance=Accum|Dword" },
502 { "OPERAND_TYPE_ACC64",
503 "Instance=Accum|Qword" },
504 { "OPERAND_TYPE_DISP16_32",
506 { "OPERAND_TYPE_ANYDISP",
507 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
508 { "OPERAND_TYPE_IMM16_32",
510 { "OPERAND_TYPE_IMM16_32S",
512 { "OPERAND_TYPE_IMM16_32_32S",
513 "Imm16|Imm32|Imm32S" },
514 { "OPERAND_TYPE_IMM32_64",
516 { "OPERAND_TYPE_IMM32_32S_DISP32",
517 "Imm32|Imm32S|Disp32" },
518 { "OPERAND_TYPE_IMM64_DISP64",
520 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
521 "Imm32|Imm32S|Imm64|Disp32" },
522 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
523 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
524 { "OPERAND_TYPE_ANYIMM",
525 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
528 typedef struct bitfield
535 #define BITFIELD(n) { n, 0, #n }
537 static bitfield cpu_flags
[] =
547 BITFIELD (CpuClflush
),
549 BITFIELD (CpuSYSCALL
),
554 BITFIELD (CpuFISTTP
),
560 BITFIELD (CpuSSE4_1
),
561 BITFIELD (CpuSSE4_2
),
564 BITFIELD (CpuAVX512F
),
565 BITFIELD (CpuAVX512CD
),
566 BITFIELD (CpuAVX512ER
),
567 BITFIELD (CpuAVX512PF
),
568 BITFIELD (CpuAVX512VL
),
569 BITFIELD (CpuAVX512DQ
),
570 BITFIELD (CpuAVX512BW
),
576 BITFIELD (Cpu3dnowA
),
577 BITFIELD (CpuPadLock
),
582 BITFIELD (CpuXsaveopt
),
584 BITFIELD (CpuPCLMUL
),
595 BITFIELD (CpuRdtscp
),
596 BITFIELD (CpuFSGSBase
),
601 BITFIELD (CpuPOPCNT
),
604 BITFIELD (CpuINVPCID
),
605 BITFIELD (CpuVMFUNC
),
606 BITFIELD (CpuRDSEED
),
608 BITFIELD (CpuPRFCHW
),
611 BITFIELD (CpuClflushOpt
),
612 BITFIELD (CpuXSAVES
),
613 BITFIELD (CpuXSAVEC
),
614 BITFIELD (CpuPREFETCHWT1
),
620 BITFIELD (CpuAVX512IFMA
),
621 BITFIELD (CpuAVX512VBMI
),
622 BITFIELD (CpuAVX512_4FMAPS
),
623 BITFIELD (CpuAVX512_4VNNIW
),
624 BITFIELD (CpuAVX512_VPOPCNTDQ
),
625 BITFIELD (CpuAVX512_VBMI2
),
626 BITFIELD (CpuAVX512_VNNI
),
627 BITFIELD (CpuAVX512_BITALG
),
628 BITFIELD (CpuAVX512_BF16
),
629 BITFIELD (CpuAVX512_VP2INTERSECT
),
631 BITFIELD (CpuMWAITX
),
632 BITFIELD (CpuCLZERO
),
635 BITFIELD (CpuPTWRITE
),
640 BITFIELD (CpuVPCLMULQDQ
),
641 BITFIELD (CpuWBNOINVD
),
642 BITFIELD (CpuPCONFIG
),
643 BITFIELD (CpuWAITPKG
),
645 BITFIELD (CpuCLDEMOTE
),
646 BITFIELD (CpuAMX_INT8
),
647 BITFIELD (CpuAMX_BF16
),
648 BITFIELD (CpuAMX_TILE
),
649 BITFIELD (CpuMOVDIRI
),
650 BITFIELD (CpuMOVDIR64B
),
651 BITFIELD (CpuENQCMD
),
652 BITFIELD (CpuSERIALIZE
),
654 BITFIELD (CpuMCOMMIT
),
655 BITFIELD (CpuSEV_ES
),
656 BITFIELD (CpuTSXLDTRK
),
658 BITFIELD (CpuWideKL
),
660 BITFIELD (CpuUnused
),
664 static bitfield opcode_modifiers
[] =
674 BITFIELD (CheckRegSize
),
675 BITFIELD (MnemonicSize
),
686 BITFIELD (BNDPrefixOk
),
687 BITFIELD (NoTrackPrefixOk
),
688 BITFIELD (IsLockable
),
689 BITFIELD (RegKludge
),
690 BITFIELD (Implicit1stXmm0
),
691 BITFIELD (RepPrefixOk
),
692 BITFIELD (HLEPrefixOk
),
695 BITFIELD (AddrPrefixOpReg
),
703 BITFIELD (OpcodePrefix
),
704 BITFIELD (VexSources
),
710 BITFIELD (Broadcast
),
711 BITFIELD (StaticRounding
),
713 BITFIELD (Disp8MemShift
),
714 BITFIELD (NoDefMask
),
715 BITFIELD (ImplicitQuadGroup
),
716 BITFIELD (SwapSources
),
718 BITFIELD (ATTMnemonic
),
719 BITFIELD (ATTSyntax
),
720 BITFIELD (IntelSyntax
),
724 #define CLASS(n) #n, n
726 static const struct {
728 enum operand_class value
;
729 } operand_classes
[] = {
743 #define INSTANCE(n) #n, n
745 static const struct {
747 enum operand_instance value
;
748 } operand_instances
[] = {
757 static bitfield operand_types
[] =
766 BITFIELD (BaseIndex
),
782 BITFIELD (Unspecified
),
788 static const char *filename
;
789 static i386_cpu_flags active_cpu_flags
;
790 static int active_isstring
;
792 struct template_arg
{
793 const struct template_arg
*next
;
797 struct template_instance
{
798 const struct template_instance
*next
;
800 const struct template_arg
*args
;
803 struct template_param
{
804 const struct template_param
*next
;
809 const struct template *next
;
811 const struct template_instance
*instances
;
812 const struct template_param
*params
;
815 static const struct template *templates
;
818 compare (const void *x
, const void *y
)
820 const bitfield
*xp
= (const bitfield
*) x
;
821 const bitfield
*yp
= (const bitfield
*) y
;
822 return xp
->position
- yp
->position
;
826 fail (const char *message
, ...)
830 va_start (args
, message
);
831 fprintf (stderr
, _("%s: error: "), program_name
);
832 vfprintf (stderr
, message
, args
);
838 process_copyright (FILE *fp
)
840 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
841 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
843 This file is part of the GNU opcodes library.\n\
845 This library is free software; you can redistribute it and/or modify\n\
846 it under the terms of the GNU General Public License as published by\n\
847 the Free Software Foundation; either version 3, or (at your option)\n\
848 any later version.\n\
850 It is distributed in the hope that it will be useful, but WITHOUT\n\
851 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
852 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
853 License for more details.\n\
855 You should have received a copy of the GNU General Public License\n\
856 along with this program; if not, write to the Free Software\n\
857 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
858 MA 02110-1301, USA. */\n");
861 /* Remove leading white spaces. */
864 remove_leading_whitespaces (char *str
)
866 while (ISSPACE (*str
))
871 /* Remove trailing white spaces. */
874 remove_trailing_whitespaces (char *str
)
876 size_t last
= strlen (str
);
884 if (ISSPACE (str
[last
]))
892 /* Find next field separated by SEP and terminate it. Return a
893 pointer to the one after it. */
896 next_field (char *str
, char sep
, char **next
, char *last
)
900 p
= remove_leading_whitespaces (str
);
901 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
904 remove_trailing_whitespaces (p
);
914 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
917 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
920 char *str
, *next
, *last
;
923 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
924 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
926 /* Turn on selective bits. */
927 char *init
= xstrdup (cpu_flag_init
[i
].init
);
928 last
= init
+ strlen (init
);
929 for (next
= init
; next
&& next
< last
; )
931 str
= next_field (next
, '|', &next
, last
);
933 set_bitfield (str
, array
, 1, size
, lineno
);
943 set_bitfield (char *f
, bitfield
*array
, int value
,
944 unsigned int size
, int lineno
)
948 /* Ignore empty fields; they may result from template expansions. */
952 if (strcmp (f
, "CpuFP") == 0)
954 set_bitfield("Cpu387", array
, value
, size
, lineno
);
955 set_bitfield("Cpu287", array
, value
, size
, lineno
);
958 else if (strcmp (f
, "Mmword") == 0)
960 else if (strcmp (f
, "Oword") == 0)
963 for (i
= 0; i
< size
; i
++)
964 if (strcasecmp (array
[i
].name
, f
) == 0)
966 array
[i
].value
= value
;
972 const char *v
= strchr (f
, '=');
979 for (i
= 0; i
< size
; i
++)
980 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
982 value
= strtol (v
+ 1, &end
, 0);
985 array
[i
].value
= value
;
993 /* Handle CPU_XXX_FLAGS. */
994 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
998 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
1000 fail (_("unknown bitfield: %s\n"), f
);
1004 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
1005 int macro
, const char *comma
, const char *indent
)
1009 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
1011 fprintf (table
, "%s{ { ", indent
);
1013 for (i
= 0; i
< size
- 1; i
++)
1015 if (((i
+ 1) % 20) != 0)
1016 fprintf (table
, "%d, ", flags
[i
].value
);
1018 fprintf (table
, "%d,", flags
[i
].value
);
1019 if (((i
+ 1) % 20) == 0)
1021 /* We need \\ for macro. */
1023 fprintf (table
, " \\\n %s", indent
);
1025 fprintf (table
, "\n %s", indent
);
1028 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
1031 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
1035 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
1036 const char *comma
, const char *indent
,
1039 char *str
, *next
, *last
;
1041 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1043 /* Copy the default cpu flags. */
1044 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1046 if (strcasecmp (flag
, "unknown") == 0)
1048 /* We turn on everything except for cpu64 in case of
1049 CPU_UNKNOWN_FLAGS. */
1050 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1051 if (flags
[i
].position
!= Cpu64
)
1054 else if (flag
[0] == '~')
1056 last
= flag
+ strlen (flag
);
1063 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1070 /* First we turn on everything except for cpu64. */
1071 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1072 if (flags
[i
].position
!= Cpu64
)
1075 /* Turn off selective bits. */
1076 for (; next
&& next
< last
; )
1078 str
= next_field (next
, '|', &next
, last
);
1080 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1083 else if (strcmp (flag
, "0"))
1085 /* Turn on selective bits. */
1086 last
= flag
+ strlen (flag
);
1087 for (next
= flag
; next
&& next
< last
; )
1089 str
= next_field (next
, '|', &next
, last
);
1091 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1095 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1100 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1104 fprintf (table
, " { ");
1106 for (i
= 0; i
< size
- 1; i
++)
1108 if (((i
+ 1) % 20) != 0)
1109 fprintf (table
, "%d, ", modifier
[i
].value
);
1111 fprintf (table
, "%d,", modifier
[i
].value
);
1112 if (((i
+ 1) % 20) == 0)
1113 fprintf (table
, "\n ");
1116 fprintf (table
, "%d },\n", modifier
[i
].value
);
1120 adjust_broadcast_modifier (char **opnd
)
1122 char *str
, *next
, *last
, *op
;
1123 int bcst_type
= INT_MAX
;
1125 /* Skip the immediate operand. */
1127 if (strcasecmp(op
, "Imm8") == 0)
1131 last
= op
+ strlen (op
);
1132 for (next
= op
; next
&& next
< last
; )
1134 str
= next_field (next
, '|', &next
, last
);
1137 if (strcasecmp(str
, "Byte") == 0)
1139 /* The smalest broadcast type, no need to check
1141 bcst_type
= BYTE_BROADCAST
;
1144 else if (strcasecmp(str
, "Word") == 0)
1146 if (bcst_type
> WORD_BROADCAST
)
1147 bcst_type
= WORD_BROADCAST
;
1149 else if (strcasecmp(str
, "Dword") == 0)
1151 if (bcst_type
> DWORD_BROADCAST
)
1152 bcst_type
= DWORD_BROADCAST
;
1154 else if (strcasecmp(str
, "Qword") == 0)
1156 if (bcst_type
> QWORD_BROADCAST
)
1157 bcst_type
= QWORD_BROADCAST
;
1163 if (bcst_type
== INT_MAX
)
1164 fail (_("unknown broadcast operand: %s\n"), op
);
1170 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1172 char *str
, *next
, *last
;
1173 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1174 unsigned int regular_encoding
= 1;
1176 active_isstring
= 0;
1178 /* Copy the default opcode modifier. */
1179 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1181 if (strcmp (mod
, "0"))
1183 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1185 last
= mod
+ strlen (mod
);
1186 for (next
= mod
; next
&& next
< last
; )
1188 str
= next_field (next
, '|', &next
, last
);
1192 if (strcasecmp(str
, "Broadcast") == 0)
1194 val
= adjust_broadcast_modifier (opnd
);
1195 regular_encoding
= 0;
1197 else if (strcasecmp(str
, "Vex") == 0
1198 || strncasecmp(str
, "Vex=", 4) == 0
1199 || strcasecmp(str
, "EVex") == 0
1200 || strncasecmp(str
, "EVex=", 5) == 0
1201 || strncasecmp(str
, "Disp8MemShift=", 14) == 0
1202 || strncasecmp(str
, "Masking=", 8) == 0
1203 || strcasecmp(str
, "SAE") == 0
1204 || strcasecmp(str
, "IsPrefix") == 0)
1205 regular_encoding
= 0;
1207 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1209 if (strcasecmp(str
, "IsString") == 0)
1210 active_isstring
= 1;
1212 if (strcasecmp(str
, "W") == 0)
1215 if (strcasecmp(str
, "No_bSuf") == 0)
1217 if (strcasecmp(str
, "No_wSuf") == 0)
1219 if (strcasecmp(str
, "No_lSuf") == 0)
1221 if (strcasecmp(str
, "No_qSuf") == 0)
1226 if (have_w
&& !bwlq_suf
)
1227 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1228 if (have_w
&& !(bwlq_suf
& 1))
1229 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1231 if (have_w
&& !(bwlq_suf
& ~1))
1233 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1236 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1238 return regular_encoding
;
1248 output_operand_type (FILE *table
, enum operand_class
class,
1249 enum operand_instance instance
,
1250 const bitfield
*types
, unsigned int size
,
1251 enum stage stage
, const char *indent
)
1255 fprintf (table
, "{ { %d, %d, ", class, instance
);
1257 for (i
= 0; i
< size
- 1; i
++)
1259 if (((i
+ 3) % 20) != 0)
1260 fprintf (table
, "%d, ", types
[i
].value
);
1262 fprintf (table
, "%d,", types
[i
].value
);
1263 if (((i
+ 3) % 20) == 0)
1265 /* We need \\ for macro. */
1266 if (stage
== stage_macros
)
1267 fprintf (table
, " \\\n%s", indent
);
1269 fprintf (table
, "\n%s", indent
);
1273 fprintf (table
, "%d } }", types
[i
].value
);
1277 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1278 const char *indent
, int lineno
)
1280 char *str
, *next
, *last
;
1281 enum operand_class
class = ClassNone
;
1282 enum operand_instance instance
= InstanceNone
;
1283 bitfield types
[ARRAY_SIZE (operand_types
)];
1285 /* Copy the default operand type. */
1286 memcpy (types
, operand_types
, sizeof (types
));
1288 if (strcmp (op
, "0"))
1292 last
= op
+ strlen (op
);
1293 for (next
= op
; next
&& next
< last
; )
1295 str
= next_field (next
, '|', &next
, last
);
1300 if (!strncmp(str
, "Class=", 6))
1302 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1303 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1305 class = operand_classes
[i
].value
;
1311 if (str
&& !strncmp(str
, "Instance=", 9))
1313 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1314 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1316 instance
= operand_instances
[i
].value
;
1324 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1325 if (strcasecmp(str
, "BaseIndex") == 0)
1330 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1332 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1333 if (!active_cpu_flags
.bitfield
.cpu64
1334 && !active_cpu_flags
.bitfield
.cpumpx
)
1335 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1336 if (!active_cpu_flags
.bitfield
.cpu64
)
1337 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1338 if (!active_cpu_flags
.bitfield
.cpuno64
)
1339 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1342 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1347 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1348 char *last
, int lineno
)
1351 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1352 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1354 /* Find number of operands. */
1355 operands
= next_field (str
, ',', &str
, last
);
1357 /* Find base_opcode. */
1358 base_opcode
= next_field (str
, ',', &str
, last
);
1360 /* Find extension_opcode. */
1361 extension_opcode
= next_field (str
, ',', &str
, last
);
1363 /* Find opcode_length. */
1364 opcode_length
= next_field (str
, ',', &str
, last
);
1366 /* Find cpu_flags. */
1367 cpu_flags
= next_field (str
, ',', &str
, last
);
1369 /* Find opcode_modifier. */
1370 opcode_modifier
= next_field (str
, ',', &str
, last
);
1372 /* Remove the first {. */
1373 str
= remove_leading_whitespaces (str
);
1376 str
= remove_leading_whitespaces (str
+ 1);
1380 /* There are at least "X}". */
1384 /* Remove trailing white spaces and }. */
1388 if (ISSPACE (str
[i
]) || str
[i
] == '}')
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
);
1407 if (*operand_types
[i
] == '0')
1410 operand_types
[i
] = NULL
;
1415 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1416 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1418 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1420 if (process_i386_opcode_modifier (table
, opcode_modifier
,
1421 operand_types
, lineno
))
1424 unsigned long int length
= strtoul (opcode_length
, &end
, 0);
1425 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
] == NULL
|| *operand_types
[i
] == '0')
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
));
1556 cur
= next_field (buf
, ':', &next
, end
);
1557 inst
->name
= xstrdup (cur
);
1559 for (param
= tmpl
->params
; param
; param
= param
->next
)
1561 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1563 cur
= next_field (next
, ':', &next
, end
);
1565 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1566 arg
->val
= xstrdup (cur
);
1567 arg
->next
= inst
->args
;
1571 if (tmpl
->instances
)
1572 last_inst
->next
= inst
;
1574 tmpl
->instances
= inst
;
1576 } while (sep
== ',');
1578 buf
= remove_leading_whitespaces (end
);
1580 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1581 filename
, lineno
, buf
);
1583 tmpl
->next
= templates
;
1588 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1589 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1591 static unsigned int idx
, opcode_array_size
;
1592 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1593 struct opcode_hash_entry
**hash_slot
, **entry
;
1594 char *ptr1
= strchr(name
, '<'), *ptr2
;
1598 /* Get the slot in hash table. */
1599 hash_slot
= (struct opcode_hash_entry
**)
1600 htab_find_slot_with_hash (opcode_hash_table
, name
,
1601 htab_hash_string (name
),
1604 if (*hash_slot
== NULL
)
1606 /* It is the new one. Put it on opcode array. */
1607 if (idx
>= opcode_array_size
)
1609 /* Grow the opcode array when needed. */
1610 opcode_array_size
+= 1024;
1611 opcode_array
= (struct opcode_hash_entry
**)
1612 xrealloc (opcode_array
,
1613 sizeof (*opcode_array
) * opcode_array_size
);
1614 *opcode_array_p
= opcode_array
;
1617 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1618 xmalloc (sizeof (struct opcode_hash_entry
));
1619 opcode_array
[idx
]->next
= NULL
;
1620 opcode_array
[idx
]->name
= xstrdup (name
);
1621 opcode_array
[idx
]->opcode
= xstrdup (str
);
1622 opcode_array
[idx
]->lineno
= lineno
;
1623 *hash_slot
= opcode_array
[idx
];
1628 /* Append it to the existing one. */
1630 while ((*entry
) != NULL
)
1631 entry
= &(*entry
)->next
;
1632 *entry
= (struct opcode_hash_entry
*)
1633 xmalloc (sizeof (struct opcode_hash_entry
));
1634 (*entry
)->next
= NULL
;
1635 (*entry
)->name
= (*hash_slot
)->name
;
1636 (*entry
)->opcode
= xstrdup (str
);
1637 (*entry
)->lineno
= lineno
;
1640 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1641 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1644 const struct template *tmpl
;
1645 const struct template_instance
*inst
;
1648 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1649 remove_trailing_whitespaces (ptr1
);
1653 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1654 if (!strcmp(ptr1
, tmpl
->name
))
1657 fail ("reference to unknown template '%s'\n", ptr1
);
1659 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1661 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1662 char *str2
= xmalloc(2 * strlen(str
));
1665 strcpy (name2
, name
);
1666 strcat (name2
, inst
->name
);
1667 strcat (name2
, ptr2
);
1669 for (ptr1
= str2
, src
= str
; *src
; )
1671 const char *ident
= tmpl
->name
, *end
;
1672 const struct template_param
*param
;
1673 const struct template_arg
*arg
;
1675 if ((*ptr1
= *src
++) != '<')
1680 while (ISSPACE(*src
))
1682 while (*ident
&& *src
== *ident
)
1684 while (ISSPACE(*src
))
1686 if (*src
!= ':' || *ident
!= '\0')
1688 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1689 ptr1
+= ident
- tmpl
->name
;
1692 while (ISSPACE(*++src
))
1696 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1699 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1700 param
= param
->next
, arg
= arg
->next
)
1702 if (end
- src
== strlen (param
->name
)
1703 && !memcmp (src
, param
->name
, end
- src
))
1711 fail ("template '%s' has no parameter '%.*s'\n",
1712 tmpl
->name
, (int)(end
- src
), src
);
1714 while (ISSPACE(*src
))
1717 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1719 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1720 ptr1
+= strlen(arg
->val
);
1726 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1738 process_i386_opcodes (FILE *table
)
1743 char *str
, *p
, *last
, *name
;
1744 htab_t opcode_hash_table
;
1745 struct opcode_hash_entry
**opcode_array
= NULL
;
1746 int lineno
= 0, marker
= 0;
1748 filename
= "i386-opc.tbl";
1752 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1753 opcode_hash_eq
, NULL
,
1756 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1757 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1759 /* Put everything on opcode array. */
1762 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1767 p
= remove_leading_whitespaces (buf
);
1769 /* Skip comments. */
1770 str
= strstr (p
, "//");
1774 /* Remove trailing white spaces. */
1775 remove_trailing_whitespaces (p
);
1780 if (!strcmp("### MARKER ###", buf
))
1784 /* Since we ignore all included files (we only care about their
1785 #define-s here), we don't need to monitor filenames. The final
1786 line number directive is going to refer to the main source file
1791 p
= remove_leading_whitespaces (p
+ 1);
1792 if (!strncmp(p
, "line", 4))
1794 ln
= strtoul (p
, &end
, 10);
1795 if (ln
> 1 && ln
< INT_MAX
1796 && *remove_leading_whitespaces (end
) == '"')
1799 /* Ignore comments. */
1804 parse_template (p
, lineno
);
1812 last
= p
+ strlen (p
);
1815 name
= next_field (p
, ',', &str
, last
);
1817 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1821 /* Process opcode array. */
1822 for (j
= 0; j
< i
; j
++)
1824 struct opcode_hash_entry
*next
;
1826 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1830 lineno
= next
->lineno
;
1831 last
= str
+ strlen (str
);
1832 output_i386_opcode (table
, name
, str
, last
, lineno
);
1838 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1840 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1842 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1844 fprintf (table
, " { ");
1845 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1846 fprintf (table
, " } }\n");
1848 fprintf (table
, "};\n");
1852 process_i386_registers (FILE *table
)
1856 char *str
, *p
, *last
;
1857 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1858 char *dw2_32_num
, *dw2_64_num
;
1861 filename
= "i386-reg.tbl";
1862 fp
= fopen (filename
, "r");
1864 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1867 fprintf (table
, "\n/* i386 register table. */\n\n");
1868 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1872 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1877 p
= remove_leading_whitespaces (buf
);
1879 /* Skip comments. */
1880 str
= strstr (p
, "//");
1884 /* Remove trailing white spaces. */
1885 remove_trailing_whitespaces (p
);
1890 fprintf (table
, "%s\n", p
);
1898 last
= p
+ strlen (p
);
1900 /* Find reg_name. */
1901 reg_name
= next_field (p
, ',', &str
, last
);
1903 /* Find reg_type. */
1904 reg_type
= next_field (str
, ',', &str
, last
);
1906 /* Find reg_flags. */
1907 reg_flags
= next_field (str
, ',', &str
, last
);
1910 reg_num
= next_field (str
, ',', &str
, last
);
1912 fprintf (table
, " { \"%s\",\n ", reg_name
);
1914 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1917 /* Find 32-bit Dwarf2 register number. */
1918 dw2_32_num
= next_field (str
, ',', &str
, last
);
1920 /* Find 64-bit Dwarf2 register number. */
1921 dw2_64_num
= next_field (str
, ',', &str
, last
);
1923 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1924 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1929 fprintf (table
, "};\n");
1931 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1935 process_i386_initializers (void)
1938 FILE *fp
= fopen ("i386-init.h", "w");
1942 fail (_("can't create i386-init.h, errno = %s\n"),
1945 process_copyright (fp
);
1947 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1949 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1950 init
= xstrdup (cpu_flag_init
[i
].init
);
1951 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1955 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1957 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1958 init
= xstrdup (operand_type_init
[i
].init
);
1959 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1967 /* Program options. */
1968 #define OPTION_SRCDIR 200
1970 struct option long_options
[] =
1972 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1973 {"debug", no_argument
, NULL
, 'd'},
1974 {"version", no_argument
, NULL
, 'V'},
1975 {"help", no_argument
, NULL
, 'h'},
1976 {0, no_argument
, NULL
, 0}
1980 print_version (void)
1982 printf ("%s: version 1.0\n", program_name
);
1987 usage (FILE * stream
, int status
)
1989 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1995 main (int argc
, char **argv
)
1997 extern int chdir (char *);
1998 char *srcdir
= NULL
;
2000 unsigned int i
, cpumax
;
2003 program_name
= *argv
;
2004 xmalloc_set_program_name (program_name
);
2006 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2031 if (chdir (srcdir
) != 0)
2032 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2033 srcdir
, xstrerror (errno
));
2035 /* cpu_flags isn't sorted by position. */
2037 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2038 if (cpu_flags
[i
].position
> cpumax
)
2039 cpumax
= cpu_flags
[i
].position
;
2041 /* Check the unused bitfield in i386_cpu_flags. */
2043 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2045 if ((cpumax
- 1) != CpuMax
)
2046 fail (_("CpuMax != %d!\n"), cpumax
);
2048 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2050 if (cpumax
!= CpuMax
)
2051 fail (_("CpuMax != %d!\n"), cpumax
);
2053 c
= CpuNumOfBits
- CpuMax
- 1;
2055 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
2058 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2060 /* Check the unused bitfield in i386_operand_type. */
2062 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2065 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2068 c
= OTNumOfBits
- OTNum
;
2070 fail (_("%d unused bits in i386_operand_type.\n"), c
);
2073 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2076 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2077 sizeof (opcode_modifiers
[0]), compare
);
2079 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2080 sizeof (operand_types
[0]), compare
);
2082 table
= fopen ("i386-tbl.h", "w");
2084 fail (_("can't create i386-tbl.h, errno = %s\n"),
2087 process_copyright (table
);
2089 process_i386_opcodes (table
);
2090 process_i386_registers (table
);
2091 process_i386_initializers ();