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
),
679 BITFIELD (SwapSources
),
681 BITFIELD (ATTMnemonic
),
682 BITFIELD (ATTSyntax
),
683 BITFIELD (IntelSyntax
),
687 #define CLASS(n) #n, n
689 static const struct {
691 enum operand_class value
;
692 } operand_classes
[] = {
706 #define INSTANCE(n) #n, n
708 static const struct {
710 enum operand_instance value
;
711 } operand_instances
[] = {
720 static bitfield operand_types
[] =
729 BITFIELD (BaseIndex
),
744 BITFIELD (Unspecified
),
750 static const char *filename
;
751 static i386_cpu_flags active_cpu_flags
;
752 static int active_isstring
;
754 struct template_arg
{
755 const struct template_arg
*next
;
759 struct template_instance
{
760 const struct template_instance
*next
;
762 const struct template_arg
*args
;
765 struct template_param
{
766 const struct template_param
*next
;
771 const struct template *next
;
773 const struct template_instance
*instances
;
774 const struct template_param
*params
;
777 static const struct template *templates
;
780 compare (const void *x
, const void *y
)
782 const bitfield
*xp
= (const bitfield
*) x
;
783 const bitfield
*yp
= (const bitfield
*) y
;
784 return xp
->position
- yp
->position
;
788 fail (const char *message
, ...)
792 va_start (args
, message
);
793 fprintf (stderr
, _("%s: error: "), program_name
);
794 vfprintf (stderr
, message
, args
);
800 process_copyright (FILE *fp
)
802 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
803 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
805 This file is part of the GNU opcodes library.\n\
807 This library is free software; you can redistribute it and/or modify\n\
808 it under the terms of the GNU General Public License as published by\n\
809 the Free Software Foundation; either version 3, or (at your option)\n\
810 any later version.\n\
812 It is distributed in the hope that it will be useful, but WITHOUT\n\
813 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
814 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
815 License for more details.\n\
817 You should have received a copy of the GNU General Public License\n\
818 along with this program; if not, write to the Free Software\n\
819 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
820 MA 02110-1301, USA. */\n");
823 /* Remove leading white spaces. */
826 remove_leading_whitespaces (char *str
)
828 while (ISSPACE (*str
))
833 /* Remove trailing white spaces. */
836 remove_trailing_whitespaces (char *str
)
838 size_t last
= strlen (str
);
846 if (ISSPACE (str
[last
]))
854 /* Find next field separated by SEP and terminate it. Return a
855 pointer to the one after it. */
858 next_field (char *str
, char sep
, char **next
, char *last
)
862 p
= remove_leading_whitespaces (str
);
863 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
866 remove_trailing_whitespaces (p
);
876 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
879 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
882 char *str
, *next
, *last
;
885 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
886 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
888 /* Turn on selective bits. */
889 char *init
= xstrdup (cpu_flag_init
[i
].init
);
890 last
= init
+ strlen (init
);
891 for (next
= init
; next
&& next
< last
; )
893 str
= next_field (next
, '|', &next
, last
);
895 set_bitfield (str
, array
, 1, size
, lineno
);
905 set_bitfield (char *f
, bitfield
*array
, int value
,
906 unsigned int size
, int lineno
)
910 /* Ignore empty fields; they may result from template expansions. */
914 if (strcmp (f
, "CpuFP") == 0)
916 set_bitfield("Cpu387", array
, value
, size
, lineno
);
917 set_bitfield("Cpu287", array
, value
, size
, lineno
);
920 else if (strcmp (f
, "Mmword") == 0)
922 else if (strcmp (f
, "Oword") == 0)
925 for (i
= 0; i
< size
; i
++)
926 if (strcasecmp (array
[i
].name
, f
) == 0)
928 array
[i
].value
= value
;
934 const char *v
= strchr (f
, '=');
941 for (i
= 0; i
< size
; i
++)
942 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
944 value
= strtol (v
+ 1, &end
, 0);
947 array
[i
].value
= value
;
955 /* Handle CPU_XXX_FLAGS. */
956 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
960 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
962 fail (_("unknown bitfield: %s\n"), f
);
966 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
967 int macro
, const char *comma
, const char *indent
)
971 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
973 fprintf (table
, "%s{ { ", indent
);
975 for (i
= 0; i
< size
- 1; i
++)
977 if (((i
+ 1) % 20) != 0)
978 fprintf (table
, "%d, ", flags
[i
].value
);
980 fprintf (table
, "%d,", flags
[i
].value
);
981 if (((i
+ 1) % 20) == 0)
983 /* We need \\ for macro. */
985 fprintf (table
, " \\\n %s", indent
);
987 fprintf (table
, "\n %s", indent
);
990 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
993 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
997 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
998 const char *comma
, const char *indent
,
1001 char *str
, *next
, *last
;
1003 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
1005 /* Copy the default cpu flags. */
1006 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1008 if (strcasecmp (flag
, "unknown") == 0)
1010 /* We turn on everything except for cpu64 in case of
1011 CPU_UNKNOWN_FLAGS. */
1012 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1013 if (flags
[i
].position
!= Cpu64
)
1016 else if (flag
[0] == '~')
1018 last
= flag
+ strlen (flag
);
1025 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1032 /* First we turn on everything except for cpu64. */
1033 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1034 if (flags
[i
].position
!= Cpu64
)
1037 /* Turn off selective bits. */
1038 for (; next
&& next
< last
; )
1040 str
= next_field (next
, '|', &next
, last
);
1042 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1045 else if (strcmp (flag
, "0"))
1047 /* Turn on selective bits. */
1048 last
= flag
+ strlen (flag
);
1049 for (next
= flag
; next
&& next
< last
; )
1051 str
= next_field (next
, '|', &next
, last
);
1053 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1057 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1062 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1066 fprintf (table
, " { ");
1068 for (i
= 0; i
< size
- 1; i
++)
1070 if (((i
+ 1) % 20) != 0)
1071 fprintf (table
, "%d, ", modifier
[i
].value
);
1073 fprintf (table
, "%d,", modifier
[i
].value
);
1074 if (((i
+ 1) % 20) == 0)
1075 fprintf (table
, "\n ");
1078 fprintf (table
, "%d },\n", modifier
[i
].value
);
1082 adjust_broadcast_modifier (char **opnd
)
1084 char *str
, *next
, *last
, *op
;
1085 int bcst_type
= INT_MAX
;
1087 /* Skip the immediate operand. */
1089 if (strcasecmp(op
, "Imm8") == 0)
1093 last
= op
+ strlen (op
);
1094 for (next
= op
; next
&& next
< last
; )
1096 str
= next_field (next
, '|', &next
, last
);
1099 if (strcasecmp(str
, "Byte") == 0)
1101 /* The smalest broadcast type, no need to check
1103 bcst_type
= BYTE_BROADCAST
;
1106 else if (strcasecmp(str
, "Word") == 0)
1108 if (bcst_type
> WORD_BROADCAST
)
1109 bcst_type
= WORD_BROADCAST
;
1111 else if (strcasecmp(str
, "Dword") == 0)
1113 if (bcst_type
> DWORD_BROADCAST
)
1114 bcst_type
= DWORD_BROADCAST
;
1116 else if (strcasecmp(str
, "Qword") == 0)
1118 if (bcst_type
> QWORD_BROADCAST
)
1119 bcst_type
= QWORD_BROADCAST
;
1125 if (bcst_type
== INT_MAX
)
1126 fail (_("unknown broadcast operand: %s\n"), op
);
1132 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1134 char *str
, *next
, *last
;
1135 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1137 active_isstring
= 0;
1139 /* Copy the default opcode modifier. */
1140 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1142 if (strcmp (mod
, "0"))
1144 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1146 last
= mod
+ strlen (mod
);
1147 for (next
= mod
; next
&& next
< last
; )
1149 str
= next_field (next
, '|', &next
, last
);
1153 if (strcasecmp(str
, "Broadcast") == 0)
1154 val
= adjust_broadcast_modifier (opnd
);
1155 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1157 if (strcasecmp(str
, "IsString") == 0)
1158 active_isstring
= 1;
1160 if (strcasecmp(str
, "W") == 0)
1163 if (strcasecmp(str
, "No_bSuf") == 0)
1165 if (strcasecmp(str
, "No_wSuf") == 0)
1167 if (strcasecmp(str
, "No_lSuf") == 0)
1169 if (strcasecmp(str
, "No_qSuf") == 0)
1174 if (have_w
&& !bwlq_suf
)
1175 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1176 if (have_w
&& !(bwlq_suf
& 1))
1177 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1179 if (have_w
&& !(bwlq_suf
& ~1))
1181 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1184 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1194 output_operand_type (FILE *table
, enum operand_class
class,
1195 enum operand_instance instance
,
1196 const bitfield
*types
, unsigned int size
,
1197 enum stage stage
, const char *indent
)
1201 fprintf (table
, "{ { %d, %d, ", class, instance
);
1203 for (i
= 0; i
< size
- 1; i
++)
1205 if (((i
+ 3) % 20) != 0)
1206 fprintf (table
, "%d, ", types
[i
].value
);
1208 fprintf (table
, "%d,", types
[i
].value
);
1209 if (((i
+ 3) % 20) == 0)
1211 /* We need \\ for macro. */
1212 if (stage
== stage_macros
)
1213 fprintf (table
, " \\\n%s", indent
);
1215 fprintf (table
, "\n%s", indent
);
1219 fprintf (table
, "%d } }", types
[i
].value
);
1223 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1224 const char *indent
, int lineno
)
1226 char *str
, *next
, *last
;
1227 enum operand_class
class = ClassNone
;
1228 enum operand_instance instance
= InstanceNone
;
1229 bitfield types
[ARRAY_SIZE (operand_types
)];
1231 /* Copy the default operand type. */
1232 memcpy (types
, operand_types
, sizeof (types
));
1234 if (strcmp (op
, "0"))
1238 last
= op
+ strlen (op
);
1239 for (next
= op
; next
&& next
< last
; )
1241 str
= next_field (next
, '|', &next
, last
);
1246 if (!strncmp(str
, "Class=", 6))
1248 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1249 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1251 class = operand_classes
[i
].value
;
1257 if (str
&& !strncmp(str
, "Instance=", 9))
1259 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1260 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1262 instance
= operand_instances
[i
].value
;
1270 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1271 if (strcasecmp(str
, "BaseIndex") == 0)
1276 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1278 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1279 if (!active_cpu_flags
.bitfield
.cpu64
1280 && !active_cpu_flags
.bitfield
.cpumpx
)
1281 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1282 if (!active_cpu_flags
.bitfield
.cpu64
)
1283 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1284 if (!active_cpu_flags
.bitfield
.cpuno64
)
1285 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1288 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1293 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1294 char *last
, int lineno
)
1297 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1298 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1300 /* Find number of operands. */
1301 operands
= next_field (str
, ',', &str
, last
);
1303 /* Find base_opcode. */
1304 base_opcode
= next_field (str
, ',', &str
, last
);
1306 /* Find extension_opcode. */
1307 extension_opcode
= next_field (str
, ',', &str
, last
);
1309 /* Find opcode_length. */
1310 opcode_length
= next_field (str
, ',', &str
, last
);
1312 /* Find cpu_flags. */
1313 cpu_flags
= next_field (str
, ',', &str
, last
);
1315 /* Find opcode_modifier. */
1316 opcode_modifier
= next_field (str
, ',', &str
, last
);
1318 /* Remove the first {. */
1319 str
= remove_leading_whitespaces (str
);
1322 str
= remove_leading_whitespaces (str
+ 1);
1326 /* There are at least "X}". */
1330 /* Remove trailing white spaces and }. */
1334 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1343 /* Find operand_types. */
1344 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1348 operand_types
[i
] = NULL
;
1352 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1353 if (*operand_types
[i
] == '0')
1356 operand_types
[i
] = NULL
;
1361 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1362 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1364 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1366 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1368 fprintf (table
, " { ");
1370 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1372 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1375 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1381 fprintf (table
, ",\n ");
1383 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1386 fprintf (table
, " } },\n");
1389 struct opcode_hash_entry
1391 struct opcode_hash_entry
*next
;
1397 /* Calculate the hash value of an opcode hash entry P. */
1400 opcode_hash_hash (const void *p
)
1402 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1403 return htab_hash_string (entry
->name
);
1406 /* Compare a string Q against an opcode hash entry P. */
1409 opcode_hash_eq (const void *p
, const void *q
)
1411 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1412 const char *name
= (const char *) q
;
1413 return strcmp (name
, entry
->name
) == 0;
1417 parse_template (char *buf
, int lineno
)
1419 char sep
, *end
, *name
;
1420 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1421 struct template_instance
*last_inst
= NULL
;
1423 buf
= remove_leading_whitespaces (buf
+ 1);
1424 end
= strchr (buf
, ':');
1426 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1428 remove_trailing_whitespaces (buf
);
1431 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1432 tmpl
->name
= xstrdup (buf
);
1434 tmpl
->params
= NULL
;
1436 struct template_param
*param
;
1438 buf
= remove_leading_whitespaces (end
);
1439 end
= strpbrk (buf
, ":,");
1441 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1445 remove_trailing_whitespaces (buf
);
1447 param
= xmalloc (sizeof (*param
));
1448 param
->name
= xstrdup (buf
);
1449 param
->next
= tmpl
->params
;
1450 tmpl
->params
= param
;
1451 } while (sep
== ':');
1453 tmpl
->instances
= NULL
;
1455 struct template_instance
*inst
;
1457 const struct template_param
*param
;
1459 buf
= remove_leading_whitespaces (end
);
1460 end
= strpbrk (buf
, ",>");
1462 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1467 inst
= xmalloc (sizeof (*inst
));
1469 cur
= next_field (buf
, ':', &next
, end
);
1470 inst
->name
= xstrdup (cur
);
1472 for (param
= tmpl
->params
; param
; param
= param
->next
)
1474 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1476 cur
= next_field (next
, ':', &next
, end
);
1478 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1479 arg
->val
= xstrdup (cur
);
1480 arg
->next
= inst
->args
;
1484 if (tmpl
->instances
)
1485 last_inst
->next
= inst
;
1487 tmpl
->instances
= inst
;
1489 } while (sep
== ',');
1491 buf
= remove_leading_whitespaces (end
);
1493 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1494 filename
, lineno
, buf
);
1496 tmpl
->next
= templates
;
1501 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1502 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1504 static unsigned int idx
, opcode_array_size
;
1505 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1506 struct opcode_hash_entry
**hash_slot
, **entry
;
1507 char *ptr1
= strchr(name
, '<'), *ptr2
;
1511 /* Get the slot in hash table. */
1512 hash_slot
= (struct opcode_hash_entry
**)
1513 htab_find_slot_with_hash (opcode_hash_table
, name
,
1514 htab_hash_string (name
),
1517 if (*hash_slot
== NULL
)
1519 /* It is the new one. Put it on opcode array. */
1520 if (idx
>= opcode_array_size
)
1522 /* Grow the opcode array when needed. */
1523 opcode_array_size
+= 1024;
1524 opcode_array
= (struct opcode_hash_entry
**)
1525 xrealloc (opcode_array
,
1526 sizeof (*opcode_array
) * opcode_array_size
);
1527 *opcode_array_p
= opcode_array
;
1530 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1531 xmalloc (sizeof (struct opcode_hash_entry
));
1532 opcode_array
[idx
]->next
= NULL
;
1533 opcode_array
[idx
]->name
= xstrdup (name
);
1534 opcode_array
[idx
]->opcode
= xstrdup (str
);
1535 opcode_array
[idx
]->lineno
= lineno
;
1536 *hash_slot
= opcode_array
[idx
];
1541 /* Append it to the existing one. */
1543 while ((*entry
) != NULL
)
1544 entry
= &(*entry
)->next
;
1545 *entry
= (struct opcode_hash_entry
*)
1546 xmalloc (sizeof (struct opcode_hash_entry
));
1547 (*entry
)->next
= NULL
;
1548 (*entry
)->name
= (*hash_slot
)->name
;
1549 (*entry
)->opcode
= xstrdup (str
);
1550 (*entry
)->lineno
= lineno
;
1553 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1554 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1557 const struct template *tmpl
;
1558 const struct template_instance
*inst
;
1561 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1562 remove_trailing_whitespaces (ptr1
);
1566 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1567 if (!strcmp(ptr1
, tmpl
->name
))
1570 fail ("reference to unknown template '%s'\n", ptr1
);
1572 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1574 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1575 char *str2
= xmalloc(2 * strlen(str
));
1578 strcpy (name2
, name
);
1579 strcat (name2
, inst
->name
);
1580 strcat (name2
, ptr2
);
1582 for (ptr1
= str2
, src
= str
; *src
; )
1584 const char *ident
= tmpl
->name
, *end
;
1585 const struct template_param
*param
;
1586 const struct template_arg
*arg
;
1588 if ((*ptr1
= *src
++) != '<')
1593 while (ISSPACE(*src
))
1595 while (*ident
&& *src
== *ident
)
1597 while (ISSPACE(*src
))
1599 if (*src
!= ':' || *ident
!= '\0')
1601 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1602 ptr1
+= ident
- tmpl
->name
;
1605 while (ISSPACE(*++src
))
1609 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1612 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1613 param
= param
->next
, arg
= arg
->next
)
1615 if (end
- src
== strlen (param
->name
)
1616 && !memcmp (src
, param
->name
, end
- src
))
1624 fail ("template '%s' has no parameter '%.*s'\n",
1625 tmpl
->name
, (int)(end
- src
), src
);
1627 while (ISSPACE(*src
))
1630 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1632 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1633 ptr1
+= strlen(arg
->val
);
1639 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1651 process_i386_opcodes (FILE *table
)
1656 char *str
, *p
, *last
, *name
;
1657 htab_t opcode_hash_table
;
1658 struct opcode_hash_entry
**opcode_array
= NULL
;
1659 int lineno
= 0, marker
= 0;
1661 filename
= "i386-opc.tbl";
1665 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1666 opcode_hash_eq
, NULL
,
1669 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1670 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1672 /* Put everything on opcode array. */
1675 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1680 p
= remove_leading_whitespaces (buf
);
1682 /* Skip comments. */
1683 str
= strstr (p
, "//");
1687 /* Remove trailing white spaces. */
1688 remove_trailing_whitespaces (p
);
1693 if (!strcmp("### MARKER ###", buf
))
1697 /* Since we ignore all included files (we only care about their
1698 #define-s here), we don't need to monitor filenames. The final
1699 line number directive is going to refer to the main source file
1704 p
= remove_leading_whitespaces (p
+ 1);
1705 if (!strncmp(p
, "line", 4))
1707 ln
= strtoul (p
, &end
, 10);
1708 if (ln
> 1 && ln
< INT_MAX
1709 && *remove_leading_whitespaces (end
) == '"')
1712 /* Ignore comments. */
1717 parse_template (p
, lineno
);
1725 last
= p
+ strlen (p
);
1728 name
= next_field (p
, ',', &str
, last
);
1730 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1734 /* Process opcode array. */
1735 for (j
= 0; j
< i
; j
++)
1737 struct opcode_hash_entry
*next
;
1739 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1743 lineno
= next
->lineno
;
1744 last
= str
+ strlen (str
);
1745 output_i386_opcode (table
, name
, str
, last
, lineno
);
1751 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1753 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1755 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1757 fprintf (table
, " { ");
1758 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1759 fprintf (table
, " } }\n");
1761 fprintf (table
, "};\n");
1765 process_i386_registers (FILE *table
)
1769 char *str
, *p
, *last
;
1770 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1771 char *dw2_32_num
, *dw2_64_num
;
1774 filename
= "i386-reg.tbl";
1775 fp
= fopen (filename
, "r");
1777 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1780 fprintf (table
, "\n/* i386 register table. */\n\n");
1781 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1785 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1790 p
= remove_leading_whitespaces (buf
);
1792 /* Skip comments. */
1793 str
= strstr (p
, "//");
1797 /* Remove trailing white spaces. */
1798 remove_trailing_whitespaces (p
);
1803 fprintf (table
, "%s\n", p
);
1811 last
= p
+ strlen (p
);
1813 /* Find reg_name. */
1814 reg_name
= next_field (p
, ',', &str
, last
);
1816 /* Find reg_type. */
1817 reg_type
= next_field (str
, ',', &str
, last
);
1819 /* Find reg_flags. */
1820 reg_flags
= next_field (str
, ',', &str
, last
);
1823 reg_num
= next_field (str
, ',', &str
, last
);
1825 fprintf (table
, " { \"%s\",\n ", reg_name
);
1827 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1830 /* Find 32-bit Dwarf2 register number. */
1831 dw2_32_num
= next_field (str
, ',', &str
, last
);
1833 /* Find 64-bit Dwarf2 register number. */
1834 dw2_64_num
= next_field (str
, ',', &str
, last
);
1836 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1837 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1842 fprintf (table
, "};\n");
1844 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1848 process_i386_initializers (void)
1851 FILE *fp
= fopen ("i386-init.h", "w");
1855 fail (_("can't create i386-init.h, errno = %s\n"),
1858 process_copyright (fp
);
1860 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1862 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1863 init
= xstrdup (cpu_flag_init
[i
].init
);
1864 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1868 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1870 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1871 init
= xstrdup (operand_type_init
[i
].init
);
1872 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1880 /* Program options. */
1881 #define OPTION_SRCDIR 200
1883 struct option long_options
[] =
1885 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1886 {"debug", no_argument
, NULL
, 'd'},
1887 {"version", no_argument
, NULL
, 'V'},
1888 {"help", no_argument
, NULL
, 'h'},
1889 {0, no_argument
, NULL
, 0}
1893 print_version (void)
1895 printf ("%s: version 1.0\n", program_name
);
1900 usage (FILE * stream
, int status
)
1902 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1908 main (int argc
, char **argv
)
1910 extern int chdir (char *);
1911 char *srcdir
= NULL
;
1913 unsigned int i
, cpumax
;
1916 program_name
= *argv
;
1917 xmalloc_set_program_name (program_name
);
1919 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1944 if (chdir (srcdir
) != 0)
1945 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1946 srcdir
, xstrerror (errno
));
1948 /* cpu_flags isn't sorted by position. */
1950 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1951 if (cpu_flags
[i
].position
> cpumax
)
1952 cpumax
= cpu_flags
[i
].position
;
1954 /* Check the unused bitfield in i386_cpu_flags. */
1956 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
1958 if ((cpumax
- 1) != CpuMax
)
1959 fail (_("CpuMax != %d!\n"), cpumax
);
1961 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
1963 if (cpumax
!= CpuMax
)
1964 fail (_("CpuMax != %d!\n"), cpumax
);
1966 c
= CpuNumOfBits
- CpuMax
- 1;
1968 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1971 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
1973 /* Check the unused bitfield in i386_operand_type. */
1975 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1978 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1981 c
= OTNumOfBits
- OTNum
;
1983 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1986 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1989 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1990 sizeof (opcode_modifiers
[0]), compare
);
1992 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1993 sizeof (operand_types
[0]), compare
);
1995 table
= fopen ("i386-tbl.h", "w");
1997 fail (_("can't create i386-tbl.h, errno = %s\n"),
2000 process_copyright (table
);
2002 process_i386_opcodes (table
);
2003 process_i386_registers (table
);
2004 process_i386_initializers ();