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_MOVDIRI_FLAGS",
302 { "CPU_MOVDIR64B_FLAGS",
304 { "CPU_ENQCMD_FLAGS",
306 { "CPU_SERIALIZE_FLAGS",
308 { "CPU_AVX512_VP2INTERSECT_FLAGS",
309 "CpuAVX512_VP2INTERSECT" },
312 { "CPU_MCOMMIT_FLAGS",
314 { "CPU_SEV_ES_FLAGS",
316 { "CPU_TSXLDTRK_FLAGS",
318 { "CPU_ANY_X87_FLAGS",
319 "CPU_ANY_287_FLAGS|Cpu8087" },
320 { "CPU_ANY_287_FLAGS",
321 "CPU_ANY_387_FLAGS|Cpu287" },
322 { "CPU_ANY_387_FLAGS",
323 "CPU_ANY_687_FLAGS|Cpu387" },
324 { "CPU_ANY_687_FLAGS",
325 "Cpu687|CpuFISTTP" },
326 { "CPU_ANY_CMOV_FLAGS",
328 { "CPU_ANY_FXSR_FLAGS",
330 { "CPU_ANY_MMX_FLAGS",
331 "CPU_3DNOWA_FLAGS" },
332 { "CPU_ANY_SSE_FLAGS",
333 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
334 { "CPU_ANY_SSE2_FLAGS",
335 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
336 { "CPU_ANY_SSE3_FLAGS",
337 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
338 { "CPU_ANY_SSSE3_FLAGS",
339 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
340 { "CPU_ANY_SSE4_1_FLAGS",
341 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
342 { "CPU_ANY_SSE4_2_FLAGS",
344 { "CPU_ANY_SSE4A_FLAGS",
346 { "CPU_ANY_AVX_FLAGS",
347 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
348 { "CPU_ANY_AVX2_FLAGS",
349 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
350 { "CPU_ANY_AVX512F_FLAGS",
351 "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" },
352 { "CPU_ANY_AVX512CD_FLAGS",
354 { "CPU_ANY_AVX512ER_FLAGS",
356 { "CPU_ANY_AVX512PF_FLAGS",
358 { "CPU_ANY_AVX512DQ_FLAGS",
360 { "CPU_ANY_AVX512BW_FLAGS",
362 { "CPU_ANY_AVX512VL_FLAGS",
364 { "CPU_ANY_AVX512IFMA_FLAGS",
366 { "CPU_ANY_AVX512VBMI_FLAGS",
368 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
369 "CpuAVX512_4FMAPS" },
370 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
371 "CpuAVX512_4VNNIW" },
372 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
373 "CpuAVX512_VPOPCNTDQ" },
374 { "CPU_ANY_IBT_FLAGS",
376 { "CPU_ANY_SHSTK_FLAGS",
378 { "CPU_ANY_AVX512_VBMI2_FLAGS",
380 { "CPU_ANY_AVX512_VNNI_FLAGS",
382 { "CPU_ANY_AVX512_BITALG_FLAGS",
383 "CpuAVX512_BITALG" },
384 { "CPU_ANY_AVX512_BF16_FLAGS",
386 { "CPU_ANY_MOVDIRI_FLAGS",
388 { "CPU_ANY_MOVDIR64B_FLAGS",
390 { "CPU_ANY_ENQCMD_FLAGS",
392 { "CPU_ANY_SERIALIZE_FLAGS",
394 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
395 "CpuAVX512_VP2INTERSECT" },
396 { "CPU_ANY_TSXLDTRK_FLAGS",
400 static initializer operand_type_init
[] =
402 { "OPERAND_TYPE_NONE",
404 { "OPERAND_TYPE_REG8",
406 { "OPERAND_TYPE_REG16",
408 { "OPERAND_TYPE_REG32",
410 { "OPERAND_TYPE_REG64",
412 { "OPERAND_TYPE_IMM1",
414 { "OPERAND_TYPE_IMM8",
416 { "OPERAND_TYPE_IMM8S",
418 { "OPERAND_TYPE_IMM16",
420 { "OPERAND_TYPE_IMM32",
422 { "OPERAND_TYPE_IMM32S",
424 { "OPERAND_TYPE_IMM64",
426 { "OPERAND_TYPE_BASEINDEX",
428 { "OPERAND_TYPE_DISP8",
430 { "OPERAND_TYPE_DISP16",
432 { "OPERAND_TYPE_DISP32",
434 { "OPERAND_TYPE_DISP32S",
436 { "OPERAND_TYPE_DISP64",
438 { "OPERAND_TYPE_INOUTPORTREG",
439 "Instance=RegD|Word" },
440 { "OPERAND_TYPE_SHIFTCOUNT",
441 "Instance=RegC|Byte" },
442 { "OPERAND_TYPE_CONTROL",
444 { "OPERAND_TYPE_TEST",
446 { "OPERAND_TYPE_DEBUG",
448 { "OPERAND_TYPE_FLOATREG",
450 { "OPERAND_TYPE_FLOATACC",
451 "Instance=Accum|Tbyte" },
452 { "OPERAND_TYPE_SREG",
454 { "OPERAND_TYPE_REGMMX",
456 { "OPERAND_TYPE_REGXMM",
457 "Class=RegSIMD|Xmmword" },
458 { "OPERAND_TYPE_REGYMM",
459 "Class=RegSIMD|Ymmword" },
460 { "OPERAND_TYPE_REGZMM",
461 "Class=RegSIMD|Zmmword" },
462 { "OPERAND_TYPE_REGMASK",
464 { "OPERAND_TYPE_REGBND",
466 { "OPERAND_TYPE_ACC8",
467 "Instance=Accum|Byte" },
468 { "OPERAND_TYPE_ACC16",
469 "Instance=Accum|Word" },
470 { "OPERAND_TYPE_ACC32",
471 "Instance=Accum|Dword" },
472 { "OPERAND_TYPE_ACC64",
473 "Instance=Accum|Qword" },
474 { "OPERAND_TYPE_DISP16_32",
476 { "OPERAND_TYPE_ANYDISP",
477 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
478 { "OPERAND_TYPE_IMM16_32",
480 { "OPERAND_TYPE_IMM16_32S",
482 { "OPERAND_TYPE_IMM16_32_32S",
483 "Imm16|Imm32|Imm32S" },
484 { "OPERAND_TYPE_IMM32_64",
486 { "OPERAND_TYPE_IMM32_32S_DISP32",
487 "Imm32|Imm32S|Disp32" },
488 { "OPERAND_TYPE_IMM64_DISP64",
490 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
491 "Imm32|Imm32S|Imm64|Disp32" },
492 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
493 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
494 { "OPERAND_TYPE_ANYIMM",
495 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
498 typedef struct bitfield
505 #define BITFIELD(n) { n, 0, #n }
507 static bitfield cpu_flags
[] =
517 BITFIELD (CpuClflush
),
519 BITFIELD (CpuSYSCALL
),
524 BITFIELD (CpuFISTTP
),
530 BITFIELD (CpuSSE4_1
),
531 BITFIELD (CpuSSE4_2
),
534 BITFIELD (CpuAVX512F
),
535 BITFIELD (CpuAVX512CD
),
536 BITFIELD (CpuAVX512ER
),
537 BITFIELD (CpuAVX512PF
),
538 BITFIELD (CpuAVX512VL
),
539 BITFIELD (CpuAVX512DQ
),
540 BITFIELD (CpuAVX512BW
),
546 BITFIELD (Cpu3dnowA
),
547 BITFIELD (CpuPadLock
),
552 BITFIELD (CpuXsaveopt
),
554 BITFIELD (CpuPCLMUL
),
565 BITFIELD (CpuRdtscp
),
566 BITFIELD (CpuFSGSBase
),
571 BITFIELD (CpuPOPCNT
),
574 BITFIELD (CpuINVPCID
),
575 BITFIELD (CpuVMFUNC
),
576 BITFIELD (CpuRDSEED
),
578 BITFIELD (CpuPRFCHW
),
581 BITFIELD (CpuClflushOpt
),
582 BITFIELD (CpuXSAVES
),
583 BITFIELD (CpuXSAVEC
),
584 BITFIELD (CpuPREFETCHWT1
),
590 BITFIELD (CpuAVX512IFMA
),
591 BITFIELD (CpuAVX512VBMI
),
592 BITFIELD (CpuAVX512_4FMAPS
),
593 BITFIELD (CpuAVX512_4VNNIW
),
594 BITFIELD (CpuAVX512_VPOPCNTDQ
),
595 BITFIELD (CpuAVX512_VBMI2
),
596 BITFIELD (CpuAVX512_VNNI
),
597 BITFIELD (CpuAVX512_BITALG
),
598 BITFIELD (CpuAVX512_BF16
),
599 BITFIELD (CpuAVX512_VP2INTERSECT
),
600 BITFIELD (CpuMWAITX
),
601 BITFIELD (CpuCLZERO
),
604 BITFIELD (CpuPTWRITE
),
609 BITFIELD (CpuVPCLMULQDQ
),
610 BITFIELD (CpuWBNOINVD
),
611 BITFIELD (CpuPCONFIG
),
612 BITFIELD (CpuWAITPKG
),
613 BITFIELD (CpuCLDEMOTE
),
614 BITFIELD (CpuMOVDIRI
),
615 BITFIELD (CpuMOVDIR64B
),
616 BITFIELD (CpuENQCMD
),
617 BITFIELD (CpuSERIALIZE
),
619 BITFIELD (CpuMCOMMIT
),
620 BITFIELD (CpuSEV_ES
),
621 BITFIELD (CpuTSXLDTRK
),
623 BITFIELD (CpuUnused
),
627 static bitfield opcode_modifiers
[] =
637 BITFIELD (CheckRegSize
),
638 BITFIELD (MnemonicSize
),
649 BITFIELD (BNDPrefixOk
),
650 BITFIELD (NoTrackPrefixOk
),
651 BITFIELD (IsLockable
),
652 BITFIELD (RegKludge
),
653 BITFIELD (Implicit1stXmm0
),
654 BITFIELD (RepPrefixOk
),
655 BITFIELD (HLEPrefixOk
),
658 BITFIELD (AddrPrefixOpReg
),
666 BITFIELD (VexOpcode
),
667 BITFIELD (VexSources
),
673 BITFIELD (Broadcast
),
674 BITFIELD (StaticRounding
),
676 BITFIELD (Disp8MemShift
),
677 BITFIELD (NoDefMask
),
678 BITFIELD (ImplicitQuadGroup
),
680 BITFIELD (ATTMnemonic
),
681 BITFIELD (ATTSyntax
),
682 BITFIELD (IntelSyntax
),
686 #define CLASS(n) #n, n
688 static const struct {
690 enum operand_class value
;
691 } operand_classes
[] = {
705 #define INSTANCE(n) #n, n
707 static const struct {
709 enum operand_instance value
;
710 } operand_instances
[] = {
719 static bitfield operand_types
[] =
728 BITFIELD (BaseIndex
),
743 BITFIELD (Unspecified
),
749 static const char *filename
;
750 static i386_cpu_flags active_cpu_flags
;
751 static int active_isstring
;
753 struct template_arg
{
754 const struct template_arg
*next
;
758 struct template_instance
{
759 const struct template_instance
*next
;
761 const struct template_arg
*args
;
764 struct template_param
{
765 const struct template_param
*next
;
770 const struct template *next
;
772 const struct template_instance
*instances
;
773 const struct template_param
*params
;
776 static const struct template *templates
;
779 compare (const void *x
, const void *y
)
781 const bitfield
*xp
= (const bitfield
*) x
;
782 const bitfield
*yp
= (const bitfield
*) y
;
783 return xp
->position
- yp
->position
;
787 fail (const char *message
, ...)
791 va_start (args
, message
);
792 fprintf (stderr
, _("%s: error: "), program_name
);
793 vfprintf (stderr
, message
, args
);
799 process_copyright (FILE *fp
)
801 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
802 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
804 This file is part of the GNU opcodes library.\n\
806 This library is free software; you can redistribute it and/or modify\n\
807 it under the terms of the GNU General Public License as published by\n\
808 the Free Software Foundation; either version 3, or (at your option)\n\
809 any later version.\n\
811 It is distributed in the hope that it will be useful, but WITHOUT\n\
812 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
813 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
814 License for more details.\n\
816 You should have received a copy of the GNU General Public License\n\
817 along with this program; if not, write to the Free Software\n\
818 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
819 MA 02110-1301, USA. */\n");
822 /* Remove leading white spaces. */
825 remove_leading_whitespaces (char *str
)
827 while (ISSPACE (*str
))
832 /* Remove trailing white spaces. */
835 remove_trailing_whitespaces (char *str
)
837 size_t last
= strlen (str
);
845 if (ISSPACE (str
[last
]))
853 /* Find next field separated by SEP and terminate it. Return a
854 pointer to the one after it. */
857 next_field (char *str
, char sep
, char **next
, char *last
)
861 p
= remove_leading_whitespaces (str
);
862 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
865 remove_trailing_whitespaces (p
);
875 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
878 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
881 char *str
, *next
, *last
;
884 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
885 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
887 /* Turn on selective bits. */
888 char *init
= xstrdup (cpu_flag_init
[i
].init
);
889 last
= init
+ strlen (init
);
890 for (next
= init
; next
&& next
< last
; )
892 str
= next_field (next
, '|', &next
, last
);
894 set_bitfield (str
, array
, 1, size
, lineno
);
904 set_bitfield (char *f
, bitfield
*array
, int value
,
905 unsigned int size
, int lineno
)
909 /* Ignore empty fields; they may result from template expansions. */
913 if (strcmp (f
, "CpuFP") == 0)
915 set_bitfield("Cpu387", array
, value
, size
, lineno
);
916 set_bitfield("Cpu287", array
, value
, size
, lineno
);
919 else if (strcmp (f
, "Mmword") == 0)
921 else if (strcmp (f
, "Oword") == 0)
924 for (i
= 0; i
< size
; i
++)
925 if (strcasecmp (array
[i
].name
, f
) == 0)
927 array
[i
].value
= value
;
933 const char *v
= strchr (f
, '=');
940 for (i
= 0; i
< size
; i
++)
941 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
943 value
= strtol (v
+ 1, &end
, 0);
946 array
[i
].value
= value
;
954 /* Handle CPU_XXX_FLAGS. */
955 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
959 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
961 fail (_("unknown bitfield: %s\n"), f
);
965 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
966 int macro
, const char *comma
, const char *indent
)
970 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
972 fprintf (table
, "%s{ { ", indent
);
974 for (i
= 0; i
< size
- 1; i
++)
976 if (((i
+ 1) % 20) != 0)
977 fprintf (table
, "%d, ", flags
[i
].value
);
979 fprintf (table
, "%d,", flags
[i
].value
);
980 if (((i
+ 1) % 20) == 0)
982 /* We need \\ for macro. */
984 fprintf (table
, " \\\n %s", indent
);
986 fprintf (table
, "\n %s", indent
);
989 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
992 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
996 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
997 const char *comma
, const char *indent
,
1000 char *str
, *next
, *last
;
1002 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1004 /* Copy the default cpu flags. */
1005 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1007 if (strcasecmp (flag
, "unknown") == 0)
1009 /* We turn on everything except for cpu64 in case of
1010 CPU_UNKNOWN_FLAGS. */
1011 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1012 if (flags
[i
].position
!= Cpu64
)
1015 else if (flag
[0] == '~')
1017 last
= flag
+ strlen (flag
);
1024 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1031 /* First we turn on everything except for cpu64. */
1032 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1033 if (flags
[i
].position
!= Cpu64
)
1036 /* Turn off selective bits. */
1037 for (; next
&& next
< last
; )
1039 str
= next_field (next
, '|', &next
, last
);
1041 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1044 else if (strcmp (flag
, "0"))
1046 /* Turn on selective bits. */
1047 last
= flag
+ strlen (flag
);
1048 for (next
= flag
; next
&& next
< last
; )
1050 str
= next_field (next
, '|', &next
, last
);
1052 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1056 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1061 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1065 fprintf (table
, " { ");
1067 for (i
= 0; i
< size
- 1; i
++)
1069 if (((i
+ 1) % 20) != 0)
1070 fprintf (table
, "%d, ", modifier
[i
].value
);
1072 fprintf (table
, "%d,", modifier
[i
].value
);
1073 if (((i
+ 1) % 20) == 0)
1074 fprintf (table
, "\n ");
1077 fprintf (table
, "%d },\n", modifier
[i
].value
);
1081 adjust_broadcast_modifier (char **opnd
)
1083 char *str
, *next
, *last
, *op
;
1084 int bcst_type
= INT_MAX
;
1086 /* Skip the immediate operand. */
1088 if (strcasecmp(op
, "Imm8") == 0)
1092 last
= op
+ strlen (op
);
1093 for (next
= op
; next
&& next
< last
; )
1095 str
= next_field (next
, '|', &next
, last
);
1098 if (strcasecmp(str
, "Byte") == 0)
1100 /* The smalest broadcast type, no need to check
1102 bcst_type
= BYTE_BROADCAST
;
1105 else if (strcasecmp(str
, "Word") == 0)
1107 if (bcst_type
> WORD_BROADCAST
)
1108 bcst_type
= WORD_BROADCAST
;
1110 else if (strcasecmp(str
, "Dword") == 0)
1112 if (bcst_type
> DWORD_BROADCAST
)
1113 bcst_type
= DWORD_BROADCAST
;
1115 else if (strcasecmp(str
, "Qword") == 0)
1117 if (bcst_type
> QWORD_BROADCAST
)
1118 bcst_type
= QWORD_BROADCAST
;
1124 if (bcst_type
== INT_MAX
)
1125 fail (_("unknown broadcast operand: %s\n"), op
);
1131 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1133 char *str
, *next
, *last
;
1134 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1136 active_isstring
= 0;
1138 /* Copy the default opcode modifier. */
1139 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1141 if (strcmp (mod
, "0"))
1143 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1145 last
= mod
+ strlen (mod
);
1146 for (next
= mod
; next
&& next
< last
; )
1148 str
= next_field (next
, '|', &next
, last
);
1152 if (strcasecmp(str
, "Broadcast") == 0)
1153 val
= adjust_broadcast_modifier (opnd
);
1154 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1156 if (strcasecmp(str
, "IsString") == 0)
1157 active_isstring
= 1;
1159 if (strcasecmp(str
, "W") == 0)
1162 if (strcasecmp(str
, "No_bSuf") == 0)
1164 if (strcasecmp(str
, "No_wSuf") == 0)
1166 if (strcasecmp(str
, "No_lSuf") == 0)
1168 if (strcasecmp(str
, "No_qSuf") == 0)
1173 if (have_w
&& !bwlq_suf
)
1174 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1175 if (have_w
&& !(bwlq_suf
& 1))
1176 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1178 if (have_w
&& !(bwlq_suf
& ~1))
1180 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1183 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1193 output_operand_type (FILE *table
, enum operand_class
class,
1194 enum operand_instance instance
,
1195 const bitfield
*types
, unsigned int size
,
1196 enum stage stage
, const char *indent
)
1200 fprintf (table
, "{ { %d, %d, ", class, instance
);
1202 for (i
= 0; i
< size
- 1; i
++)
1204 if (((i
+ 3) % 20) != 0)
1205 fprintf (table
, "%d, ", types
[i
].value
);
1207 fprintf (table
, "%d,", types
[i
].value
);
1208 if (((i
+ 3) % 20) == 0)
1210 /* We need \\ for macro. */
1211 if (stage
== stage_macros
)
1212 fprintf (table
, " \\\n%s", indent
);
1214 fprintf (table
, "\n%s", indent
);
1218 fprintf (table
, "%d } }", types
[i
].value
);
1222 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1223 const char *indent
, int lineno
)
1225 char *str
, *next
, *last
;
1226 enum operand_class
class = ClassNone
;
1227 enum operand_instance instance
= InstanceNone
;
1228 bitfield types
[ARRAY_SIZE (operand_types
)];
1230 /* Copy the default operand type. */
1231 memcpy (types
, operand_types
, sizeof (types
));
1233 if (strcmp (op
, "0"))
1237 last
= op
+ strlen (op
);
1238 for (next
= op
; next
&& next
< last
; )
1240 str
= next_field (next
, '|', &next
, last
);
1245 if (!strncmp(str
, "Class=", 6))
1247 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1248 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1250 class = operand_classes
[i
].value
;
1256 if (str
&& !strncmp(str
, "Instance=", 9))
1258 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1259 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1261 instance
= operand_instances
[i
].value
;
1269 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1270 if (strcasecmp(str
, "BaseIndex") == 0)
1275 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1277 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1278 if (!active_cpu_flags
.bitfield
.cpu64
1279 && !active_cpu_flags
.bitfield
.cpumpx
)
1280 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1281 if (!active_cpu_flags
.bitfield
.cpu64
)
1282 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1283 if (!active_cpu_flags
.bitfield
.cpuno64
)
1284 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1287 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1292 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1293 char *last
, int lineno
)
1296 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1297 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1299 /* Find number of operands. */
1300 operands
= next_field (str
, ',', &str
, last
);
1302 /* Find base_opcode. */
1303 base_opcode
= next_field (str
, ',', &str
, last
);
1305 /* Find extension_opcode. */
1306 extension_opcode
= next_field (str
, ',', &str
, last
);
1308 /* Find opcode_length. */
1309 opcode_length
= next_field (str
, ',', &str
, last
);
1311 /* Find cpu_flags. */
1312 cpu_flags
= next_field (str
, ',', &str
, last
);
1314 /* Find opcode_modifier. */
1315 opcode_modifier
= next_field (str
, ',', &str
, last
);
1317 /* Remove the first {. */
1318 str
= remove_leading_whitespaces (str
);
1321 str
= remove_leading_whitespaces (str
+ 1);
1325 /* There are at least "X}". */
1329 /* Remove trailing white spaces and }. */
1333 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1342 /* Find operand_types. */
1343 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1347 operand_types
[i
] = NULL
;
1351 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1352 if (*operand_types
[i
] == '0')
1355 operand_types
[i
] = NULL
;
1360 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1361 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1363 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1365 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1367 fprintf (table
, " { ");
1369 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1371 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1374 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1380 fprintf (table
, ",\n ");
1382 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1385 fprintf (table
, " } },\n");
1388 struct opcode_hash_entry
1390 struct opcode_hash_entry
*next
;
1396 /* Calculate the hash value of an opcode hash entry P. */
1399 opcode_hash_hash (const void *p
)
1401 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1402 return htab_hash_string (entry
->name
);
1405 /* Compare a string Q against an opcode hash entry P. */
1408 opcode_hash_eq (const void *p
, const void *q
)
1410 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1411 const char *name
= (const char *) q
;
1412 return strcmp (name
, entry
->name
) == 0;
1416 parse_template (char *buf
, int lineno
)
1418 char sep
, *end
, *name
;
1419 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1420 struct template_instance
*last_inst
= NULL
;
1422 buf
= remove_leading_whitespaces (buf
+ 1);
1423 end
= strchr (buf
, ':');
1425 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1427 remove_trailing_whitespaces (buf
);
1430 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1431 tmpl
->name
= xstrdup (buf
);
1433 tmpl
->params
= NULL
;
1435 struct template_param
*param
;
1437 buf
= remove_leading_whitespaces (end
);
1438 end
= strpbrk (buf
, ":,");
1440 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1444 remove_trailing_whitespaces (buf
);
1446 param
= xmalloc (sizeof (*param
));
1447 param
->name
= xstrdup (buf
);
1448 param
->next
= tmpl
->params
;
1449 tmpl
->params
= param
;
1450 } while (sep
== ':');
1452 tmpl
->instances
= NULL
;
1454 struct template_instance
*inst
;
1456 const struct template_param
*param
;
1458 buf
= remove_leading_whitespaces (end
);
1459 end
= strpbrk (buf
, ",>");
1461 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1466 inst
= xmalloc (sizeof (*inst
));
1468 cur
= next_field (buf
, ':', &next
, end
);
1469 inst
->name
= xstrdup (cur
);
1471 for (param
= tmpl
->params
; param
; param
= param
->next
)
1473 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1475 cur
= next_field (next
, ':', &next
, end
);
1477 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1478 arg
->val
= xstrdup (cur
);
1479 arg
->next
= inst
->args
;
1483 if (tmpl
->instances
)
1484 last_inst
->next
= inst
;
1486 tmpl
->instances
= inst
;
1488 } while (sep
== ',');
1490 buf
= remove_leading_whitespaces (end
);
1492 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1493 filename
, lineno
, buf
);
1495 tmpl
->next
= templates
;
1500 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1501 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1503 static unsigned int idx
, opcode_array_size
;
1504 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1505 struct opcode_hash_entry
**hash_slot
, **entry
;
1506 char *ptr1
= strchr(name
, '<'), *ptr2
;
1510 /* Get the slot in hash table. */
1511 hash_slot
= (struct opcode_hash_entry
**)
1512 htab_find_slot_with_hash (opcode_hash_table
, name
,
1513 htab_hash_string (name
),
1516 if (*hash_slot
== NULL
)
1518 /* It is the new one. Put it on opcode array. */
1519 if (idx
>= opcode_array_size
)
1521 /* Grow the opcode array when needed. */
1522 opcode_array_size
+= 1024;
1523 opcode_array
= (struct opcode_hash_entry
**)
1524 xrealloc (opcode_array
,
1525 sizeof (*opcode_array
) * opcode_array_size
);
1526 *opcode_array_p
= opcode_array
;
1529 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1530 xmalloc (sizeof (struct opcode_hash_entry
));
1531 opcode_array
[idx
]->next
= NULL
;
1532 opcode_array
[idx
]->name
= xstrdup (name
);
1533 opcode_array
[idx
]->opcode
= xstrdup (str
);
1534 opcode_array
[idx
]->lineno
= lineno
;
1535 *hash_slot
= opcode_array
[idx
];
1540 /* Append it to the existing one. */
1542 while ((*entry
) != NULL
)
1543 entry
= &(*entry
)->next
;
1544 *entry
= (struct opcode_hash_entry
*)
1545 xmalloc (sizeof (struct opcode_hash_entry
));
1546 (*entry
)->next
= NULL
;
1547 (*entry
)->name
= (*hash_slot
)->name
;
1548 (*entry
)->opcode
= xstrdup (str
);
1549 (*entry
)->lineno
= lineno
;
1552 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1553 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1556 const struct template *tmpl
;
1557 const struct template_instance
*inst
;
1560 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1561 remove_trailing_whitespaces (ptr1
);
1565 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1566 if (!strcmp(ptr1
, tmpl
->name
))
1569 fail ("reference to unknown template '%s'\n", ptr1
);
1571 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1573 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1574 char *str2
= xmalloc(2 * strlen(str
));
1577 strcpy (name2
, name
);
1578 strcat (name2
, inst
->name
);
1579 strcat (name2
, ptr2
);
1581 for (ptr1
= str2
, src
= str
; *src
; )
1583 const char *ident
= tmpl
->name
, *end
;
1584 const struct template_param
*param
;
1585 const struct template_arg
*arg
;
1587 if ((*ptr1
= *src
++) != '<')
1592 while (ISSPACE(*src
))
1594 while (*ident
&& *src
== *ident
)
1596 while (ISSPACE(*src
))
1598 if (*src
!= ':' || *ident
!= '\0')
1600 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1601 ptr1
+= ident
- tmpl
->name
;
1604 while (ISSPACE(*++src
))
1608 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1611 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1612 param
= param
->next
, arg
= arg
->next
)
1614 if (end
- src
== strlen (param
->name
)
1615 && !memcmp (src
, param
->name
, end
- src
))
1623 fail ("template '%s' has no parameter '%.*s'\n",
1624 tmpl
->name
, (int)(end
- src
), src
);
1626 while (ISSPACE(*src
))
1629 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1631 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1632 ptr1
+= strlen(arg
->val
);
1638 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1650 process_i386_opcodes (FILE *table
)
1655 char *str
, *p
, *last
, *name
;
1656 htab_t opcode_hash_table
;
1657 struct opcode_hash_entry
**opcode_array
= NULL
;
1658 int lineno
= 0, marker
= 0;
1660 filename
= "i386-opc.tbl";
1664 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1665 opcode_hash_eq
, NULL
,
1668 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1669 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1671 /* Put everything on opcode array. */
1674 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1679 p
= remove_leading_whitespaces (buf
);
1681 /* Skip comments. */
1682 str
= strstr (p
, "//");
1686 /* Remove trailing white spaces. */
1687 remove_trailing_whitespaces (p
);
1692 if (!strcmp("### MARKER ###", buf
))
1696 /* Since we ignore all included files (we only care about their
1697 #define-s here), we don't need to monitor filenames. The final
1698 line number directive is going to refer to the main source file
1703 p
= remove_leading_whitespaces (p
+ 1);
1704 if (!strncmp(p
, "line", 4))
1706 ln
= strtoul (p
, &end
, 10);
1707 if (ln
> 1 && ln
< INT_MAX
1708 && *remove_leading_whitespaces (end
) == '"')
1711 /* Ignore comments. */
1716 parse_template (p
, lineno
);
1724 last
= p
+ strlen (p
);
1727 name
= next_field (p
, ',', &str
, last
);
1729 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1733 /* Process opcode array. */
1734 for (j
= 0; j
< i
; j
++)
1736 struct opcode_hash_entry
*next
;
1738 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1742 lineno
= next
->lineno
;
1743 last
= str
+ strlen (str
);
1744 output_i386_opcode (table
, name
, str
, last
, lineno
);
1750 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1752 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1754 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1756 fprintf (table
, " { ");
1757 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1758 fprintf (table
, " } }\n");
1760 fprintf (table
, "};\n");
1764 process_i386_registers (FILE *table
)
1768 char *str
, *p
, *last
;
1769 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1770 char *dw2_32_num
, *dw2_64_num
;
1773 filename
= "i386-reg.tbl";
1774 fp
= fopen (filename
, "r");
1776 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1779 fprintf (table
, "\n/* i386 register table. */\n\n");
1780 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1784 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1789 p
= remove_leading_whitespaces (buf
);
1791 /* Skip comments. */
1792 str
= strstr (p
, "//");
1796 /* Remove trailing white spaces. */
1797 remove_trailing_whitespaces (p
);
1802 fprintf (table
, "%s\n", p
);
1810 last
= p
+ strlen (p
);
1812 /* Find reg_name. */
1813 reg_name
= next_field (p
, ',', &str
, last
);
1815 /* Find reg_type. */
1816 reg_type
= next_field (str
, ',', &str
, last
);
1818 /* Find reg_flags. */
1819 reg_flags
= next_field (str
, ',', &str
, last
);
1822 reg_num
= next_field (str
, ',', &str
, last
);
1824 fprintf (table
, " { \"%s\",\n ", reg_name
);
1826 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1829 /* Find 32-bit Dwarf2 register number. */
1830 dw2_32_num
= next_field (str
, ',', &str
, last
);
1832 /* Find 64-bit Dwarf2 register number. */
1833 dw2_64_num
= next_field (str
, ',', &str
, last
);
1835 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1836 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1841 fprintf (table
, "};\n");
1843 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1847 process_i386_initializers (void)
1850 FILE *fp
= fopen ("i386-init.h", "w");
1854 fail (_("can't create i386-init.h, errno = %s\n"),
1857 process_copyright (fp
);
1859 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1861 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1862 init
= xstrdup (cpu_flag_init
[i
].init
);
1863 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1867 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1869 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1870 init
= xstrdup (operand_type_init
[i
].init
);
1871 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1879 /* Program options. */
1880 #define OPTION_SRCDIR 200
1882 struct option long_options
[] =
1884 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1885 {"debug", no_argument
, NULL
, 'd'},
1886 {"version", no_argument
, NULL
, 'V'},
1887 {"help", no_argument
, NULL
, 'h'},
1888 {0, no_argument
, NULL
, 0}
1892 print_version (void)
1894 printf ("%s: version 1.0\n", program_name
);
1899 usage (FILE * stream
, int status
)
1901 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1907 main (int argc
, char **argv
)
1909 extern int chdir (char *);
1910 char *srcdir
= NULL
;
1912 unsigned int i
, cpumax
;
1915 program_name
= *argv
;
1916 xmalloc_set_program_name (program_name
);
1918 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1943 if (chdir (srcdir
) != 0)
1944 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1945 srcdir
, xstrerror (errno
));
1947 /* cpu_flags isn't sorted by position. */
1949 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1950 if (cpu_flags
[i
].position
> cpumax
)
1951 cpumax
= cpu_flags
[i
].position
;
1953 /* Check the unused bitfield in i386_cpu_flags. */
1955 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
1957 if ((cpumax
- 1) != CpuMax
)
1958 fail (_("CpuMax != %d!\n"), cpumax
);
1960 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
1962 if (cpumax
!= CpuMax
)
1963 fail (_("CpuMax != %d!\n"), cpumax
);
1965 c
= CpuNumOfBits
- CpuMax
- 1;
1967 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1970 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
1972 /* Check the unused bitfield in i386_operand_type. */
1974 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1977 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1980 c
= OTNumOfBits
- OTNum
;
1982 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1985 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1988 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1989 sizeof (opcode_modifiers
[0]), compare
);
1991 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1992 sizeof (operand_types
[0]), compare
);
1994 table
= fopen ("i386-tbl.h", "w");
1996 fail (_("can't create i386-tbl.h, errno = %s\n"),
1999 process_copyright (table
);
2001 process_i386_opcodes (table
);
2002 process_i386_registers (table
);
2003 process_i386_initializers ();