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",
298 { "CPU_CLDEMOTE_FLAGS",
300 { "CPU_AMX_INT8_FLAGS",
302 { "CPU_AMX_BF16_FLAGS",
304 { "CPU_AMX_TILE_FLAGS",
306 { "CPU_MOVDIRI_FLAGS",
308 { "CPU_MOVDIR64B_FLAGS",
310 { "CPU_ENQCMD_FLAGS",
312 { "CPU_SERIALIZE_FLAGS",
314 { "CPU_AVX512_VP2INTERSECT_FLAGS",
315 "CpuAVX512_VP2INTERSECT" },
318 { "CPU_MCOMMIT_FLAGS",
320 { "CPU_SEV_ES_FLAGS",
322 { "CPU_TSXLDTRK_FLAGS",
324 { "CPU_ANY_X87_FLAGS",
325 "CPU_ANY_287_FLAGS|Cpu8087" },
326 { "CPU_ANY_287_FLAGS",
327 "CPU_ANY_387_FLAGS|Cpu287" },
328 { "CPU_ANY_387_FLAGS",
329 "CPU_ANY_687_FLAGS|Cpu387" },
330 { "CPU_ANY_687_FLAGS",
331 "Cpu687|CpuFISTTP" },
332 { "CPU_ANY_CMOV_FLAGS",
334 { "CPU_ANY_FXSR_FLAGS",
336 { "CPU_ANY_MMX_FLAGS",
337 "CPU_3DNOWA_FLAGS" },
338 { "CPU_ANY_SSE_FLAGS",
339 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
340 { "CPU_ANY_SSE2_FLAGS",
341 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
342 { "CPU_ANY_SSE3_FLAGS",
343 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
344 { "CPU_ANY_SSSE3_FLAGS",
345 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
346 { "CPU_ANY_SSE4_1_FLAGS",
347 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
348 { "CPU_ANY_SSE4_2_FLAGS",
350 { "CPU_ANY_SSE4A_FLAGS",
352 { "CPU_ANY_AVX_FLAGS",
353 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
354 { "CPU_ANY_AVX2_FLAGS",
355 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
356 { "CPU_ANY_AVX512F_FLAGS",
357 "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" },
358 { "CPU_ANY_AVX512CD_FLAGS",
360 { "CPU_ANY_AVX512ER_FLAGS",
362 { "CPU_ANY_AVX512PF_FLAGS",
364 { "CPU_ANY_AVX512DQ_FLAGS",
366 { "CPU_ANY_AVX512BW_FLAGS",
368 { "CPU_ANY_AVX512VL_FLAGS",
370 { "CPU_ANY_AVX512IFMA_FLAGS",
372 { "CPU_ANY_AVX512VBMI_FLAGS",
374 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
375 "CpuAVX512_4FMAPS" },
376 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
377 "CpuAVX512_4VNNIW" },
378 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
379 "CpuAVX512_VPOPCNTDQ" },
380 { "CPU_ANY_IBT_FLAGS",
382 { "CPU_ANY_SHSTK_FLAGS",
384 { "CPU_ANY_AVX512_VBMI2_FLAGS",
386 { "CPU_ANY_AVX512_VNNI_FLAGS",
388 { "CPU_ANY_AVX512_BITALG_FLAGS",
389 "CpuAVX512_BITALG" },
390 { "CPU_ANY_AVX512_BF16_FLAGS",
392 { "CPU_ANY_AMX_INT8_FLAGS",
394 { "CPU_ANY_AMX_BF16_FLAGS",
396 { "CPU_ANY_AMX_TILE_FLAGS",
397 "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" },
398 { "CPU_ANY_MOVDIRI_FLAGS",
400 { "CPU_ANY_MOVDIR64B_FLAGS",
402 { "CPU_ANY_ENQCMD_FLAGS",
404 { "CPU_ANY_SERIALIZE_FLAGS",
406 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
407 "CpuAVX512_VP2INTERSECT" },
408 { "CPU_ANY_TSXLDTRK_FLAGS",
412 static initializer operand_type_init
[] =
414 { "OPERAND_TYPE_NONE",
416 { "OPERAND_TYPE_REG8",
418 { "OPERAND_TYPE_REG16",
420 { "OPERAND_TYPE_REG32",
422 { "OPERAND_TYPE_REG64",
424 { "OPERAND_TYPE_IMM1",
426 { "OPERAND_TYPE_IMM8",
428 { "OPERAND_TYPE_IMM8S",
430 { "OPERAND_TYPE_IMM16",
432 { "OPERAND_TYPE_IMM32",
434 { "OPERAND_TYPE_IMM32S",
436 { "OPERAND_TYPE_IMM64",
438 { "OPERAND_TYPE_BASEINDEX",
440 { "OPERAND_TYPE_DISP8",
442 { "OPERAND_TYPE_DISP16",
444 { "OPERAND_TYPE_DISP32",
446 { "OPERAND_TYPE_DISP32S",
448 { "OPERAND_TYPE_DISP64",
450 { "OPERAND_TYPE_INOUTPORTREG",
451 "Instance=RegD|Word" },
452 { "OPERAND_TYPE_SHIFTCOUNT",
453 "Instance=RegC|Byte" },
454 { "OPERAND_TYPE_CONTROL",
456 { "OPERAND_TYPE_TEST",
458 { "OPERAND_TYPE_DEBUG",
460 { "OPERAND_TYPE_FLOATREG",
462 { "OPERAND_TYPE_FLOATACC",
463 "Instance=Accum|Tbyte" },
464 { "OPERAND_TYPE_SREG",
466 { "OPERAND_TYPE_REGMMX",
468 { "OPERAND_TYPE_REGXMM",
469 "Class=RegSIMD|Xmmword" },
470 { "OPERAND_TYPE_REGYMM",
471 "Class=RegSIMD|Ymmword" },
472 { "OPERAND_TYPE_REGZMM",
473 "Class=RegSIMD|Zmmword" },
474 { "OPERAND_TYPE_REGTMM",
475 "Class=RegSIMD|Tmmword" },
476 { "OPERAND_TYPE_REGMASK",
478 { "OPERAND_TYPE_REGBND",
480 { "OPERAND_TYPE_ACC8",
481 "Instance=Accum|Byte" },
482 { "OPERAND_TYPE_ACC16",
483 "Instance=Accum|Word" },
484 { "OPERAND_TYPE_ACC32",
485 "Instance=Accum|Dword" },
486 { "OPERAND_TYPE_ACC64",
487 "Instance=Accum|Qword" },
488 { "OPERAND_TYPE_DISP16_32",
490 { "OPERAND_TYPE_ANYDISP",
491 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
492 { "OPERAND_TYPE_IMM16_32",
494 { "OPERAND_TYPE_IMM16_32S",
496 { "OPERAND_TYPE_IMM16_32_32S",
497 "Imm16|Imm32|Imm32S" },
498 { "OPERAND_TYPE_IMM32_64",
500 { "OPERAND_TYPE_IMM32_32S_DISP32",
501 "Imm32|Imm32S|Disp32" },
502 { "OPERAND_TYPE_IMM64_DISP64",
504 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
505 "Imm32|Imm32S|Imm64|Disp32" },
506 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
507 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
508 { "OPERAND_TYPE_ANYIMM",
509 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
512 typedef struct bitfield
519 #define BITFIELD(n) { n, 0, #n }
521 static bitfield cpu_flags
[] =
531 BITFIELD (CpuClflush
),
533 BITFIELD (CpuSYSCALL
),
538 BITFIELD (CpuFISTTP
),
544 BITFIELD (CpuSSE4_1
),
545 BITFIELD (CpuSSE4_2
),
548 BITFIELD (CpuAVX512F
),
549 BITFIELD (CpuAVX512CD
),
550 BITFIELD (CpuAVX512ER
),
551 BITFIELD (CpuAVX512PF
),
552 BITFIELD (CpuAVX512VL
),
553 BITFIELD (CpuAVX512DQ
),
554 BITFIELD (CpuAVX512BW
),
560 BITFIELD (Cpu3dnowA
),
561 BITFIELD (CpuPadLock
),
566 BITFIELD (CpuXsaveopt
),
568 BITFIELD (CpuPCLMUL
),
579 BITFIELD (CpuRdtscp
),
580 BITFIELD (CpuFSGSBase
),
585 BITFIELD (CpuPOPCNT
),
588 BITFIELD (CpuINVPCID
),
589 BITFIELD (CpuVMFUNC
),
590 BITFIELD (CpuRDSEED
),
592 BITFIELD (CpuPRFCHW
),
595 BITFIELD (CpuClflushOpt
),
596 BITFIELD (CpuXSAVES
),
597 BITFIELD (CpuXSAVEC
),
598 BITFIELD (CpuPREFETCHWT1
),
604 BITFIELD (CpuAVX512IFMA
),
605 BITFIELD (CpuAVX512VBMI
),
606 BITFIELD (CpuAVX512_4FMAPS
),
607 BITFIELD (CpuAVX512_4VNNIW
),
608 BITFIELD (CpuAVX512_VPOPCNTDQ
),
609 BITFIELD (CpuAVX512_VBMI2
),
610 BITFIELD (CpuAVX512_VNNI
),
611 BITFIELD (CpuAVX512_BITALG
),
612 BITFIELD (CpuAVX512_BF16
),
613 BITFIELD (CpuAVX512_VP2INTERSECT
),
614 BITFIELD (CpuMWAITX
),
615 BITFIELD (CpuCLZERO
),
618 BITFIELD (CpuPTWRITE
),
623 BITFIELD (CpuVPCLMULQDQ
),
624 BITFIELD (CpuWBNOINVD
),
625 BITFIELD (CpuPCONFIG
),
626 BITFIELD (CpuWAITPKG
),
627 BITFIELD (CpuCLDEMOTE
),
628 BITFIELD (CpuAMX_INT8
),
629 BITFIELD (CpuAMX_BF16
),
630 BITFIELD (CpuAMX_TILE
),
631 BITFIELD (CpuMOVDIRI
),
632 BITFIELD (CpuMOVDIR64B
),
633 BITFIELD (CpuENQCMD
),
634 BITFIELD (CpuSERIALIZE
),
636 BITFIELD (CpuMCOMMIT
),
637 BITFIELD (CpuSEV_ES
),
638 BITFIELD (CpuTSXLDTRK
),
640 BITFIELD (CpuUnused
),
644 static bitfield opcode_modifiers
[] =
654 BITFIELD (CheckRegSize
),
655 BITFIELD (MnemonicSize
),
666 BITFIELD (BNDPrefixOk
),
667 BITFIELD (NoTrackPrefixOk
),
668 BITFIELD (IsLockable
),
669 BITFIELD (RegKludge
),
670 BITFIELD (Implicit1stXmm0
),
671 BITFIELD (RepPrefixOk
),
672 BITFIELD (HLEPrefixOk
),
675 BITFIELD (AddrPrefixOpReg
),
683 BITFIELD (VexOpcode
),
684 BITFIELD (VexSources
),
690 BITFIELD (Broadcast
),
691 BITFIELD (StaticRounding
),
693 BITFIELD (Disp8MemShift
),
694 BITFIELD (NoDefMask
),
695 BITFIELD (ImplicitQuadGroup
),
696 BITFIELD (SwapSources
),
698 BITFIELD (ATTMnemonic
),
699 BITFIELD (ATTSyntax
),
700 BITFIELD (IntelSyntax
),
704 #define CLASS(n) #n, n
706 static const struct {
708 enum operand_class value
;
709 } operand_classes
[] = {
723 #define INSTANCE(n) #n, n
725 static const struct {
727 enum operand_instance value
;
728 } operand_instances
[] = {
737 static bitfield operand_types
[] =
746 BITFIELD (BaseIndex
),
762 BITFIELD (Unspecified
),
768 static const char *filename
;
769 static i386_cpu_flags active_cpu_flags
;
770 static int active_isstring
;
772 struct template_arg
{
773 const struct template_arg
*next
;
777 struct template_instance
{
778 const struct template_instance
*next
;
780 const struct template_arg
*args
;
783 struct template_param
{
784 const struct template_param
*next
;
789 const struct template *next
;
791 const struct template_instance
*instances
;
792 const struct template_param
*params
;
795 static const struct template *templates
;
798 compare (const void *x
, const void *y
)
800 const bitfield
*xp
= (const bitfield
*) x
;
801 const bitfield
*yp
= (const bitfield
*) y
;
802 return xp
->position
- yp
->position
;
806 fail (const char *message
, ...)
810 va_start (args
, message
);
811 fprintf (stderr
, _("%s: error: "), program_name
);
812 vfprintf (stderr
, message
, args
);
818 process_copyright (FILE *fp
)
820 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
821 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
823 This file is part of the GNU opcodes library.\n\
825 This library is free software; you can redistribute it and/or modify\n\
826 it under the terms of the GNU General Public License as published by\n\
827 the Free Software Foundation; either version 3, or (at your option)\n\
828 any later version.\n\
830 It is distributed in the hope that it will be useful, but WITHOUT\n\
831 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
832 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
833 License for more details.\n\
835 You should have received a copy of the GNU General Public License\n\
836 along with this program; if not, write to the Free Software\n\
837 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
838 MA 02110-1301, USA. */\n");
841 /* Remove leading white spaces. */
844 remove_leading_whitespaces (char *str
)
846 while (ISSPACE (*str
))
851 /* Remove trailing white spaces. */
854 remove_trailing_whitespaces (char *str
)
856 size_t last
= strlen (str
);
864 if (ISSPACE (str
[last
]))
872 /* Find next field separated by SEP and terminate it. Return a
873 pointer to the one after it. */
876 next_field (char *str
, char sep
, char **next
, char *last
)
880 p
= remove_leading_whitespaces (str
);
881 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
884 remove_trailing_whitespaces (p
);
894 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
897 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
900 char *str
, *next
, *last
;
903 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
904 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
906 /* Turn on selective bits. */
907 char *init
= xstrdup (cpu_flag_init
[i
].init
);
908 last
= init
+ strlen (init
);
909 for (next
= init
; next
&& next
< last
; )
911 str
= next_field (next
, '|', &next
, last
);
913 set_bitfield (str
, array
, 1, size
, lineno
);
923 set_bitfield (char *f
, bitfield
*array
, int value
,
924 unsigned int size
, int lineno
)
928 /* Ignore empty fields; they may result from template expansions. */
932 if (strcmp (f
, "CpuFP") == 0)
934 set_bitfield("Cpu387", array
, value
, size
, lineno
);
935 set_bitfield("Cpu287", array
, value
, size
, lineno
);
938 else if (strcmp (f
, "Mmword") == 0)
940 else if (strcmp (f
, "Oword") == 0)
943 for (i
= 0; i
< size
; i
++)
944 if (strcasecmp (array
[i
].name
, f
) == 0)
946 array
[i
].value
= value
;
952 const char *v
= strchr (f
, '=');
959 for (i
= 0; i
< size
; i
++)
960 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
962 value
= strtol (v
+ 1, &end
, 0);
965 array
[i
].value
= value
;
973 /* Handle CPU_XXX_FLAGS. */
974 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
978 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
980 fail (_("unknown bitfield: %s\n"), f
);
984 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
985 int macro
, const char *comma
, const char *indent
)
989 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
991 fprintf (table
, "%s{ { ", indent
);
993 for (i
= 0; i
< size
- 1; i
++)
995 if (((i
+ 1) % 20) != 0)
996 fprintf (table
, "%d, ", flags
[i
].value
);
998 fprintf (table
, "%d,", flags
[i
].value
);
999 if (((i
+ 1) % 20) == 0)
1001 /* We need \\ for macro. */
1003 fprintf (table
, " \\\n %s", indent
);
1005 fprintf (table
, "\n %s", indent
);
1008 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
1011 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
1015 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
1016 const char *comma
, const char *indent
,
1019 char *str
, *next
, *last
;
1021 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1023 /* Copy the default cpu flags. */
1024 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1026 if (strcasecmp (flag
, "unknown") == 0)
1028 /* We turn on everything except for cpu64 in case of
1029 CPU_UNKNOWN_FLAGS. */
1030 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1031 if (flags
[i
].position
!= Cpu64
)
1034 else if (flag
[0] == '~')
1036 last
= flag
+ strlen (flag
);
1043 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1050 /* First we turn on everything except for cpu64. */
1051 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1052 if (flags
[i
].position
!= Cpu64
)
1055 /* Turn off selective bits. */
1056 for (; next
&& next
< last
; )
1058 str
= next_field (next
, '|', &next
, last
);
1060 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1063 else if (strcmp (flag
, "0"))
1065 /* Turn on selective bits. */
1066 last
= flag
+ strlen (flag
);
1067 for (next
= flag
; next
&& next
< last
; )
1069 str
= next_field (next
, '|', &next
, last
);
1071 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1075 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1080 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1084 fprintf (table
, " { ");
1086 for (i
= 0; i
< size
- 1; i
++)
1088 if (((i
+ 1) % 20) != 0)
1089 fprintf (table
, "%d, ", modifier
[i
].value
);
1091 fprintf (table
, "%d,", modifier
[i
].value
);
1092 if (((i
+ 1) % 20) == 0)
1093 fprintf (table
, "\n ");
1096 fprintf (table
, "%d },\n", modifier
[i
].value
);
1100 adjust_broadcast_modifier (char **opnd
)
1102 char *str
, *next
, *last
, *op
;
1103 int bcst_type
= INT_MAX
;
1105 /* Skip the immediate operand. */
1107 if (strcasecmp(op
, "Imm8") == 0)
1111 last
= op
+ strlen (op
);
1112 for (next
= op
; next
&& next
< last
; )
1114 str
= next_field (next
, '|', &next
, last
);
1117 if (strcasecmp(str
, "Byte") == 0)
1119 /* The smalest broadcast type, no need to check
1121 bcst_type
= BYTE_BROADCAST
;
1124 else if (strcasecmp(str
, "Word") == 0)
1126 if (bcst_type
> WORD_BROADCAST
)
1127 bcst_type
= WORD_BROADCAST
;
1129 else if (strcasecmp(str
, "Dword") == 0)
1131 if (bcst_type
> DWORD_BROADCAST
)
1132 bcst_type
= DWORD_BROADCAST
;
1134 else if (strcasecmp(str
, "Qword") == 0)
1136 if (bcst_type
> QWORD_BROADCAST
)
1137 bcst_type
= QWORD_BROADCAST
;
1143 if (bcst_type
== INT_MAX
)
1144 fail (_("unknown broadcast operand: %s\n"), op
);
1150 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1152 char *str
, *next
, *last
;
1153 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1155 active_isstring
= 0;
1157 /* Copy the default opcode modifier. */
1158 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1160 if (strcmp (mod
, "0"))
1162 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1164 last
= mod
+ strlen (mod
);
1165 for (next
= mod
; next
&& next
< last
; )
1167 str
= next_field (next
, '|', &next
, last
);
1171 if (strcasecmp(str
, "Broadcast") == 0)
1172 val
= adjust_broadcast_modifier (opnd
);
1173 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1175 if (strcasecmp(str
, "IsString") == 0)
1176 active_isstring
= 1;
1178 if (strcasecmp(str
, "W") == 0)
1181 if (strcasecmp(str
, "No_bSuf") == 0)
1183 if (strcasecmp(str
, "No_wSuf") == 0)
1185 if (strcasecmp(str
, "No_lSuf") == 0)
1187 if (strcasecmp(str
, "No_qSuf") == 0)
1192 if (have_w
&& !bwlq_suf
)
1193 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1194 if (have_w
&& !(bwlq_suf
& 1))
1195 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1197 if (have_w
&& !(bwlq_suf
& ~1))
1199 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1202 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1212 output_operand_type (FILE *table
, enum operand_class
class,
1213 enum operand_instance instance
,
1214 const bitfield
*types
, unsigned int size
,
1215 enum stage stage
, const char *indent
)
1219 fprintf (table
, "{ { %d, %d, ", class, instance
);
1221 for (i
= 0; i
< size
- 1; i
++)
1223 if (((i
+ 3) % 20) != 0)
1224 fprintf (table
, "%d, ", types
[i
].value
);
1226 fprintf (table
, "%d,", types
[i
].value
);
1227 if (((i
+ 3) % 20) == 0)
1229 /* We need \\ for macro. */
1230 if (stage
== stage_macros
)
1231 fprintf (table
, " \\\n%s", indent
);
1233 fprintf (table
, "\n%s", indent
);
1237 fprintf (table
, "%d } }", types
[i
].value
);
1241 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1242 const char *indent
, int lineno
)
1244 char *str
, *next
, *last
;
1245 enum operand_class
class = ClassNone
;
1246 enum operand_instance instance
= InstanceNone
;
1247 bitfield types
[ARRAY_SIZE (operand_types
)];
1249 /* Copy the default operand type. */
1250 memcpy (types
, operand_types
, sizeof (types
));
1252 if (strcmp (op
, "0"))
1256 last
= op
+ strlen (op
);
1257 for (next
= op
; next
&& next
< last
; )
1259 str
= next_field (next
, '|', &next
, last
);
1264 if (!strncmp(str
, "Class=", 6))
1266 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1267 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1269 class = operand_classes
[i
].value
;
1275 if (str
&& !strncmp(str
, "Instance=", 9))
1277 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1278 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1280 instance
= operand_instances
[i
].value
;
1288 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1289 if (strcasecmp(str
, "BaseIndex") == 0)
1294 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1296 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1297 if (!active_cpu_flags
.bitfield
.cpu64
1298 && !active_cpu_flags
.bitfield
.cpumpx
)
1299 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1300 if (!active_cpu_flags
.bitfield
.cpu64
)
1301 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1302 if (!active_cpu_flags
.bitfield
.cpuno64
)
1303 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1306 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1311 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1312 char *last
, int lineno
)
1315 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1316 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1318 /* Find number of operands. */
1319 operands
= next_field (str
, ',', &str
, last
);
1321 /* Find base_opcode. */
1322 base_opcode
= next_field (str
, ',', &str
, last
);
1324 /* Find extension_opcode. */
1325 extension_opcode
= next_field (str
, ',', &str
, last
);
1327 /* Find opcode_length. */
1328 opcode_length
= next_field (str
, ',', &str
, last
);
1330 /* Find cpu_flags. */
1331 cpu_flags
= next_field (str
, ',', &str
, last
);
1333 /* Find opcode_modifier. */
1334 opcode_modifier
= next_field (str
, ',', &str
, last
);
1336 /* Remove the first {. */
1337 str
= remove_leading_whitespaces (str
);
1340 str
= remove_leading_whitespaces (str
+ 1);
1344 /* There are at least "X}". */
1348 /* Remove trailing white spaces and }. */
1352 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1361 /* Find operand_types. */
1362 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1366 operand_types
[i
] = NULL
;
1370 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1371 if (*operand_types
[i
] == '0')
1374 operand_types
[i
] = NULL
;
1379 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1380 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1382 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1384 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1386 fprintf (table
, " { ");
1388 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1390 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1393 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1399 fprintf (table
, ",\n ");
1401 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1404 fprintf (table
, " } },\n");
1407 struct opcode_hash_entry
1409 struct opcode_hash_entry
*next
;
1415 /* Calculate the hash value of an opcode hash entry P. */
1418 opcode_hash_hash (const void *p
)
1420 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1421 return htab_hash_string (entry
->name
);
1424 /* Compare a string Q against an opcode hash entry P. */
1427 opcode_hash_eq (const void *p
, const void *q
)
1429 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1430 const char *name
= (const char *) q
;
1431 return strcmp (name
, entry
->name
) == 0;
1435 parse_template (char *buf
, int lineno
)
1437 char sep
, *end
, *name
;
1438 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1439 struct template_instance
*last_inst
= NULL
;
1441 buf
= remove_leading_whitespaces (buf
+ 1);
1442 end
= strchr (buf
, ':');
1444 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1446 remove_trailing_whitespaces (buf
);
1449 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1450 tmpl
->name
= xstrdup (buf
);
1452 tmpl
->params
= NULL
;
1454 struct template_param
*param
;
1456 buf
= remove_leading_whitespaces (end
);
1457 end
= strpbrk (buf
, ":,");
1459 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1463 remove_trailing_whitespaces (buf
);
1465 param
= xmalloc (sizeof (*param
));
1466 param
->name
= xstrdup (buf
);
1467 param
->next
= tmpl
->params
;
1468 tmpl
->params
= param
;
1469 } while (sep
== ':');
1471 tmpl
->instances
= NULL
;
1473 struct template_instance
*inst
;
1475 const struct template_param
*param
;
1477 buf
= remove_leading_whitespaces (end
);
1478 end
= strpbrk (buf
, ",>");
1480 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1485 inst
= xmalloc (sizeof (*inst
));
1487 cur
= next_field (buf
, ':', &next
, end
);
1488 inst
->name
= xstrdup (cur
);
1490 for (param
= tmpl
->params
; param
; param
= param
->next
)
1492 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1494 cur
= next_field (next
, ':', &next
, end
);
1496 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1497 arg
->val
= xstrdup (cur
);
1498 arg
->next
= inst
->args
;
1502 if (tmpl
->instances
)
1503 last_inst
->next
= inst
;
1505 tmpl
->instances
= inst
;
1507 } while (sep
== ',');
1509 buf
= remove_leading_whitespaces (end
);
1511 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1512 filename
, lineno
, buf
);
1514 tmpl
->next
= templates
;
1519 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1520 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1522 static unsigned int idx
, opcode_array_size
;
1523 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1524 struct opcode_hash_entry
**hash_slot
, **entry
;
1525 char *ptr1
= strchr(name
, '<'), *ptr2
;
1529 /* Get the slot in hash table. */
1530 hash_slot
= (struct opcode_hash_entry
**)
1531 htab_find_slot_with_hash (opcode_hash_table
, name
,
1532 htab_hash_string (name
),
1535 if (*hash_slot
== NULL
)
1537 /* It is the new one. Put it on opcode array. */
1538 if (idx
>= opcode_array_size
)
1540 /* Grow the opcode array when needed. */
1541 opcode_array_size
+= 1024;
1542 opcode_array
= (struct opcode_hash_entry
**)
1543 xrealloc (opcode_array
,
1544 sizeof (*opcode_array
) * opcode_array_size
);
1545 *opcode_array_p
= opcode_array
;
1548 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1549 xmalloc (sizeof (struct opcode_hash_entry
));
1550 opcode_array
[idx
]->next
= NULL
;
1551 opcode_array
[idx
]->name
= xstrdup (name
);
1552 opcode_array
[idx
]->opcode
= xstrdup (str
);
1553 opcode_array
[idx
]->lineno
= lineno
;
1554 *hash_slot
= opcode_array
[idx
];
1559 /* Append it to the existing one. */
1561 while ((*entry
) != NULL
)
1562 entry
= &(*entry
)->next
;
1563 *entry
= (struct opcode_hash_entry
*)
1564 xmalloc (sizeof (struct opcode_hash_entry
));
1565 (*entry
)->next
= NULL
;
1566 (*entry
)->name
= (*hash_slot
)->name
;
1567 (*entry
)->opcode
= xstrdup (str
);
1568 (*entry
)->lineno
= lineno
;
1571 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1572 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1575 const struct template *tmpl
;
1576 const struct template_instance
*inst
;
1579 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1580 remove_trailing_whitespaces (ptr1
);
1584 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1585 if (!strcmp(ptr1
, tmpl
->name
))
1588 fail ("reference to unknown template '%s'\n", ptr1
);
1590 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1592 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1593 char *str2
= xmalloc(2 * strlen(str
));
1596 strcpy (name2
, name
);
1597 strcat (name2
, inst
->name
);
1598 strcat (name2
, ptr2
);
1600 for (ptr1
= str2
, src
= str
; *src
; )
1602 const char *ident
= tmpl
->name
, *end
;
1603 const struct template_param
*param
;
1604 const struct template_arg
*arg
;
1606 if ((*ptr1
= *src
++) != '<')
1611 while (ISSPACE(*src
))
1613 while (*ident
&& *src
== *ident
)
1615 while (ISSPACE(*src
))
1617 if (*src
!= ':' || *ident
!= '\0')
1619 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1620 ptr1
+= ident
- tmpl
->name
;
1623 while (ISSPACE(*++src
))
1627 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1630 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1631 param
= param
->next
, arg
= arg
->next
)
1633 if (end
- src
== strlen (param
->name
)
1634 && !memcmp (src
, param
->name
, end
- src
))
1642 fail ("template '%s' has no parameter '%.*s'\n",
1643 tmpl
->name
, (int)(end
- src
), src
);
1645 while (ISSPACE(*src
))
1648 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1650 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1651 ptr1
+= strlen(arg
->val
);
1657 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1669 process_i386_opcodes (FILE *table
)
1674 char *str
, *p
, *last
, *name
;
1675 htab_t opcode_hash_table
;
1676 struct opcode_hash_entry
**opcode_array
= NULL
;
1677 int lineno
= 0, marker
= 0;
1679 filename
= "i386-opc.tbl";
1683 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1684 opcode_hash_eq
, NULL
,
1687 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1688 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1690 /* Put everything on opcode array. */
1693 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1698 p
= remove_leading_whitespaces (buf
);
1700 /* Skip comments. */
1701 str
= strstr (p
, "//");
1705 /* Remove trailing white spaces. */
1706 remove_trailing_whitespaces (p
);
1711 if (!strcmp("### MARKER ###", buf
))
1715 /* Since we ignore all included files (we only care about their
1716 #define-s here), we don't need to monitor filenames. The final
1717 line number directive is going to refer to the main source file
1722 p
= remove_leading_whitespaces (p
+ 1);
1723 if (!strncmp(p
, "line", 4))
1725 ln
= strtoul (p
, &end
, 10);
1726 if (ln
> 1 && ln
< INT_MAX
1727 && *remove_leading_whitespaces (end
) == '"')
1730 /* Ignore comments. */
1735 parse_template (p
, lineno
);
1743 last
= p
+ strlen (p
);
1746 name
= next_field (p
, ',', &str
, last
);
1748 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1752 /* Process opcode array. */
1753 for (j
= 0; j
< i
; j
++)
1755 struct opcode_hash_entry
*next
;
1757 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1761 lineno
= next
->lineno
;
1762 last
= str
+ strlen (str
);
1763 output_i386_opcode (table
, name
, str
, last
, lineno
);
1769 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1771 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1773 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1775 fprintf (table
, " { ");
1776 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1777 fprintf (table
, " } }\n");
1779 fprintf (table
, "};\n");
1783 process_i386_registers (FILE *table
)
1787 char *str
, *p
, *last
;
1788 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1789 char *dw2_32_num
, *dw2_64_num
;
1792 filename
= "i386-reg.tbl";
1793 fp
= fopen (filename
, "r");
1795 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1798 fprintf (table
, "\n/* i386 register table. */\n\n");
1799 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1803 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1808 p
= remove_leading_whitespaces (buf
);
1810 /* Skip comments. */
1811 str
= strstr (p
, "//");
1815 /* Remove trailing white spaces. */
1816 remove_trailing_whitespaces (p
);
1821 fprintf (table
, "%s\n", p
);
1829 last
= p
+ strlen (p
);
1831 /* Find reg_name. */
1832 reg_name
= next_field (p
, ',', &str
, last
);
1834 /* Find reg_type. */
1835 reg_type
= next_field (str
, ',', &str
, last
);
1837 /* Find reg_flags. */
1838 reg_flags
= next_field (str
, ',', &str
, last
);
1841 reg_num
= next_field (str
, ',', &str
, last
);
1843 fprintf (table
, " { \"%s\",\n ", reg_name
);
1845 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1848 /* Find 32-bit Dwarf2 register number. */
1849 dw2_32_num
= next_field (str
, ',', &str
, last
);
1851 /* Find 64-bit Dwarf2 register number. */
1852 dw2_64_num
= next_field (str
, ',', &str
, last
);
1854 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1855 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1860 fprintf (table
, "};\n");
1862 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1866 process_i386_initializers (void)
1869 FILE *fp
= fopen ("i386-init.h", "w");
1873 fail (_("can't create i386-init.h, errno = %s\n"),
1876 process_copyright (fp
);
1878 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1880 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1881 init
= xstrdup (cpu_flag_init
[i
].init
);
1882 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1886 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1888 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1889 init
= xstrdup (operand_type_init
[i
].init
);
1890 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1898 /* Program options. */
1899 #define OPTION_SRCDIR 200
1901 struct option long_options
[] =
1903 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1904 {"debug", no_argument
, NULL
, 'd'},
1905 {"version", no_argument
, NULL
, 'V'},
1906 {"help", no_argument
, NULL
, 'h'},
1907 {0, no_argument
, NULL
, 0}
1911 print_version (void)
1913 printf ("%s: version 1.0\n", program_name
);
1918 usage (FILE * stream
, int status
)
1920 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1926 main (int argc
, char **argv
)
1928 extern int chdir (char *);
1929 char *srcdir
= NULL
;
1931 unsigned int i
, cpumax
;
1934 program_name
= *argv
;
1935 xmalloc_set_program_name (program_name
);
1937 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1962 if (chdir (srcdir
) != 0)
1963 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1964 srcdir
, xstrerror (errno
));
1966 /* cpu_flags isn't sorted by position. */
1968 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1969 if (cpu_flags
[i
].position
> cpumax
)
1970 cpumax
= cpu_flags
[i
].position
;
1972 /* Check the unused bitfield in i386_cpu_flags. */
1974 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
1976 if ((cpumax
- 1) != CpuMax
)
1977 fail (_("CpuMax != %d!\n"), cpumax
);
1979 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
1981 if (cpumax
!= CpuMax
)
1982 fail (_("CpuMax != %d!\n"), cpumax
);
1984 c
= CpuNumOfBits
- CpuMax
- 1;
1986 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1989 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
1991 /* Check the unused bitfield in i386_operand_type. */
1993 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1996 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1999 c
= OTNumOfBits
- OTNum
;
2001 fail (_("%d unused bits in i386_operand_type.\n"), c
);
2004 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2007 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2008 sizeof (opcode_modifiers
[0]), compare
);
2010 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2011 sizeof (operand_types
[0]), compare
);
2013 table
= fopen ("i386-tbl.h", "w");
2015 fail (_("can't create i386-tbl.h, errno = %s\n"),
2018 process_copyright (table
);
2020 process_i386_opcodes (table
);
2021 process_i386_registers (table
);
2022 process_i386_initializers ();