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_AVX512_VP2INTERSECT_FLAGS",
307 "CpuAVX512_VP2INTERSECT" },
310 { "CPU_MCOMMIT_FLAGS",
312 { "CPU_SEV_ES_FLAGS",
314 { "CPU_ANY_X87_FLAGS",
315 "CPU_ANY_287_FLAGS|Cpu8087" },
316 { "CPU_ANY_287_FLAGS",
317 "CPU_ANY_387_FLAGS|Cpu287" },
318 { "CPU_ANY_387_FLAGS",
319 "CPU_ANY_687_FLAGS|Cpu387" },
320 { "CPU_ANY_687_FLAGS",
321 "Cpu687|CpuFISTTP" },
322 { "CPU_ANY_CMOV_FLAGS",
324 { "CPU_ANY_FXSR_FLAGS",
326 { "CPU_ANY_MMX_FLAGS",
327 "CPU_3DNOWA_FLAGS" },
328 { "CPU_ANY_SSE_FLAGS",
329 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
330 { "CPU_ANY_SSE2_FLAGS",
331 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
332 { "CPU_ANY_SSE3_FLAGS",
333 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
334 { "CPU_ANY_SSSE3_FLAGS",
335 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
336 { "CPU_ANY_SSE4_1_FLAGS",
337 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
338 { "CPU_ANY_SSE4_2_FLAGS",
340 { "CPU_ANY_SSE4A_FLAGS",
342 { "CPU_ANY_AVX_FLAGS",
343 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
344 { "CPU_ANY_AVX2_FLAGS",
345 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
346 { "CPU_ANY_AVX512F_FLAGS",
347 "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" },
348 { "CPU_ANY_AVX512CD_FLAGS",
350 { "CPU_ANY_AVX512ER_FLAGS",
352 { "CPU_ANY_AVX512PF_FLAGS",
354 { "CPU_ANY_AVX512DQ_FLAGS",
356 { "CPU_ANY_AVX512BW_FLAGS",
358 { "CPU_ANY_AVX512VL_FLAGS",
360 { "CPU_ANY_AVX512IFMA_FLAGS",
362 { "CPU_ANY_AVX512VBMI_FLAGS",
364 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
365 "CpuAVX512_4FMAPS" },
366 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
367 "CpuAVX512_4VNNIW" },
368 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
369 "CpuAVX512_VPOPCNTDQ" },
370 { "CPU_ANY_IBT_FLAGS",
372 { "CPU_ANY_SHSTK_FLAGS",
374 { "CPU_ANY_AVX512_VBMI2_FLAGS",
376 { "CPU_ANY_AVX512_VNNI_FLAGS",
378 { "CPU_ANY_AVX512_BITALG_FLAGS",
379 "CpuAVX512_BITALG" },
380 { "CPU_ANY_AVX512_BF16_FLAGS",
382 { "CPU_ANY_MOVDIRI_FLAGS",
384 { "CPU_ANY_MOVDIR64B_FLAGS",
386 { "CPU_ANY_ENQCMD_FLAGS",
388 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
389 "CpuAVX512_VP2INTERSECT" },
392 static initializer operand_type_init
[] =
394 { "OPERAND_TYPE_NONE",
396 { "OPERAND_TYPE_REG8",
398 { "OPERAND_TYPE_REG16",
400 { "OPERAND_TYPE_REG32",
402 { "OPERAND_TYPE_REG64",
404 { "OPERAND_TYPE_IMM1",
406 { "OPERAND_TYPE_IMM8",
408 { "OPERAND_TYPE_IMM8S",
410 { "OPERAND_TYPE_IMM16",
412 { "OPERAND_TYPE_IMM32",
414 { "OPERAND_TYPE_IMM32S",
416 { "OPERAND_TYPE_IMM64",
418 { "OPERAND_TYPE_BASEINDEX",
420 { "OPERAND_TYPE_DISP8",
422 { "OPERAND_TYPE_DISP16",
424 { "OPERAND_TYPE_DISP32",
426 { "OPERAND_TYPE_DISP32S",
428 { "OPERAND_TYPE_DISP64",
430 { "OPERAND_TYPE_INOUTPORTREG",
431 "Instance=RegD|Word" },
432 { "OPERAND_TYPE_SHIFTCOUNT",
433 "Instance=RegC|Byte" },
434 { "OPERAND_TYPE_CONTROL",
436 { "OPERAND_TYPE_TEST",
438 { "OPERAND_TYPE_DEBUG",
440 { "OPERAND_TYPE_FLOATREG",
442 { "OPERAND_TYPE_FLOATACC",
443 "Instance=Accum|Tbyte" },
444 { "OPERAND_TYPE_SREG",
446 { "OPERAND_TYPE_REGMMX",
448 { "OPERAND_TYPE_REGXMM",
449 "Class=RegSIMD|Xmmword" },
450 { "OPERAND_TYPE_REGYMM",
451 "Class=RegSIMD|Ymmword" },
452 { "OPERAND_TYPE_REGZMM",
453 "Class=RegSIMD|Zmmword" },
454 { "OPERAND_TYPE_REGMASK",
456 { "OPERAND_TYPE_REGBND",
458 { "OPERAND_TYPE_ACC8",
459 "Instance=Accum|Byte" },
460 { "OPERAND_TYPE_ACC16",
461 "Instance=Accum|Word" },
462 { "OPERAND_TYPE_ACC32",
463 "Instance=Accum|Dword" },
464 { "OPERAND_TYPE_ACC64",
465 "Instance=Accum|Qword" },
466 { "OPERAND_TYPE_DISP16_32",
468 { "OPERAND_TYPE_ANYDISP",
469 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
470 { "OPERAND_TYPE_IMM16_32",
472 { "OPERAND_TYPE_IMM16_32S",
474 { "OPERAND_TYPE_IMM16_32_32S",
475 "Imm16|Imm32|Imm32S" },
476 { "OPERAND_TYPE_IMM32_64",
478 { "OPERAND_TYPE_IMM32_32S_DISP32",
479 "Imm32|Imm32S|Disp32" },
480 { "OPERAND_TYPE_IMM64_DISP64",
482 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
483 "Imm32|Imm32S|Imm64|Disp32" },
484 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
485 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
486 { "OPERAND_TYPE_ANYIMM",
487 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
490 typedef struct bitfield
497 #define BITFIELD(n) { n, 0, #n }
499 static bitfield cpu_flags
[] =
509 BITFIELD (CpuClflush
),
511 BITFIELD (CpuSYSCALL
),
516 BITFIELD (CpuFISTTP
),
522 BITFIELD (CpuSSE4_1
),
523 BITFIELD (CpuSSE4_2
),
526 BITFIELD (CpuAVX512F
),
527 BITFIELD (CpuAVX512CD
),
528 BITFIELD (CpuAVX512ER
),
529 BITFIELD (CpuAVX512PF
),
530 BITFIELD (CpuAVX512VL
),
531 BITFIELD (CpuAVX512DQ
),
532 BITFIELD (CpuAVX512BW
),
538 BITFIELD (Cpu3dnowA
),
539 BITFIELD (CpuPadLock
),
544 BITFIELD (CpuXsaveopt
),
546 BITFIELD (CpuPCLMUL
),
557 BITFIELD (CpuRdtscp
),
558 BITFIELD (CpuFSGSBase
),
563 BITFIELD (CpuPOPCNT
),
566 BITFIELD (CpuINVPCID
),
567 BITFIELD (CpuVMFUNC
),
568 BITFIELD (CpuRDSEED
),
570 BITFIELD (CpuPRFCHW
),
573 BITFIELD (CpuClflushOpt
),
574 BITFIELD (CpuXSAVES
),
575 BITFIELD (CpuXSAVEC
),
576 BITFIELD (CpuPREFETCHWT1
),
582 BITFIELD (CpuAVX512IFMA
),
583 BITFIELD (CpuAVX512VBMI
),
584 BITFIELD (CpuAVX512_4FMAPS
),
585 BITFIELD (CpuAVX512_4VNNIW
),
586 BITFIELD (CpuAVX512_VPOPCNTDQ
),
587 BITFIELD (CpuAVX512_VBMI2
),
588 BITFIELD (CpuAVX512_VNNI
),
589 BITFIELD (CpuAVX512_BITALG
),
590 BITFIELD (CpuAVX512_BF16
),
591 BITFIELD (CpuAVX512_VP2INTERSECT
),
592 BITFIELD (CpuMWAITX
),
593 BITFIELD (CpuCLZERO
),
596 BITFIELD (CpuPTWRITE
),
601 BITFIELD (CpuVPCLMULQDQ
),
602 BITFIELD (CpuWBNOINVD
),
603 BITFIELD (CpuPCONFIG
),
604 BITFIELD (CpuWAITPKG
),
605 BITFIELD (CpuCLDEMOTE
),
606 BITFIELD (CpuMOVDIRI
),
607 BITFIELD (CpuMOVDIR64B
),
608 BITFIELD (CpuENQCMD
),
610 BITFIELD (CpuMCOMMIT
),
611 BITFIELD (CpuSEV_ES
),
613 BITFIELD (CpuUnused
),
617 static bitfield opcode_modifiers
[] =
627 BITFIELD (CheckRegSize
),
628 BITFIELD (MnemonicSize
),
639 BITFIELD (BNDPrefixOk
),
640 BITFIELD (NoTrackPrefixOk
),
641 BITFIELD (IsLockable
),
642 BITFIELD (RegKludge
),
643 BITFIELD (Implicit1stXmm0
),
644 BITFIELD (RepPrefixOk
),
645 BITFIELD (HLEPrefixOk
),
648 BITFIELD (AddrPrefixOpReg
),
656 BITFIELD (VexOpcode
),
657 BITFIELD (VexSources
),
663 BITFIELD (Broadcast
),
664 BITFIELD (StaticRounding
),
666 BITFIELD (Disp8MemShift
),
667 BITFIELD (NoDefMask
),
668 BITFIELD (ImplicitQuadGroup
),
670 BITFIELD (ATTMnemonic
),
671 BITFIELD (ATTSyntax
),
672 BITFIELD (IntelSyntax
),
676 #define CLASS(n) #n, n
678 static const struct {
680 enum operand_class value
;
681 } operand_classes
[] = {
695 #define INSTANCE(n) #n, n
697 static const struct {
699 enum operand_instance value
;
700 } operand_instances
[] = {
709 static bitfield operand_types
[] =
718 BITFIELD (BaseIndex
),
733 BITFIELD (Unspecified
),
739 static const char *filename
;
740 static i386_cpu_flags active_cpu_flags
;
741 static int active_isstring
;
743 struct template_arg
{
744 const struct template_arg
*next
;
748 struct template_instance
{
749 const struct template_instance
*next
;
751 const struct template_arg
*args
;
754 struct template_param
{
755 const struct template_param
*next
;
760 const struct template *next
;
762 const struct template_instance
*instances
;
763 const struct template_param
*params
;
766 static const struct template *templates
;
769 compare (const void *x
, const void *y
)
771 const bitfield
*xp
= (const bitfield
*) x
;
772 const bitfield
*yp
= (const bitfield
*) y
;
773 return xp
->position
- yp
->position
;
777 fail (const char *message
, ...)
781 va_start (args
, message
);
782 fprintf (stderr
, _("%s: error: "), program_name
);
783 vfprintf (stderr
, message
, args
);
789 process_copyright (FILE *fp
)
791 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
792 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
794 This file is part of the GNU opcodes library.\n\
796 This library is free software; you can redistribute it and/or modify\n\
797 it under the terms of the GNU General Public License as published by\n\
798 the Free Software Foundation; either version 3, or (at your option)\n\
799 any later version.\n\
801 It is distributed in the hope that it will be useful, but WITHOUT\n\
802 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
803 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
804 License for more details.\n\
806 You should have received a copy of the GNU General Public License\n\
807 along with this program; if not, write to the Free Software\n\
808 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
809 MA 02110-1301, USA. */\n");
812 /* Remove leading white spaces. */
815 remove_leading_whitespaces (char *str
)
817 while (ISSPACE (*str
))
822 /* Remove trailing white spaces. */
825 remove_trailing_whitespaces (char *str
)
827 size_t last
= strlen (str
);
835 if (ISSPACE (str
[last
]))
843 /* Find next field separated by SEP and terminate it. Return a
844 pointer to the one after it. */
847 next_field (char *str
, char sep
, char **next
, char *last
)
851 p
= remove_leading_whitespaces (str
);
852 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
855 remove_trailing_whitespaces (p
);
865 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
868 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
871 char *str
, *next
, *last
;
874 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
875 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
877 /* Turn on selective bits. */
878 char *init
= xstrdup (cpu_flag_init
[i
].init
);
879 last
= init
+ strlen (init
);
880 for (next
= init
; next
&& next
< last
; )
882 str
= next_field (next
, '|', &next
, last
);
884 set_bitfield (str
, array
, 1, size
, lineno
);
894 set_bitfield (char *f
, bitfield
*array
, int value
,
895 unsigned int size
, int lineno
)
899 if (strcmp (f
, "CpuFP") == 0)
901 set_bitfield("Cpu387", array
, value
, size
, lineno
);
902 set_bitfield("Cpu287", array
, value
, size
, lineno
);
905 else if (strcmp (f
, "Mmword") == 0)
907 else if (strcmp (f
, "Oword") == 0)
910 for (i
= 0; i
< size
; i
++)
911 if (strcasecmp (array
[i
].name
, f
) == 0)
913 array
[i
].value
= value
;
919 const char *v
= strchr (f
, '=');
926 for (i
= 0; i
< size
; i
++)
927 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
929 value
= strtol (v
+ 1, &end
, 0);
932 array
[i
].value
= value
;
940 /* Handle CPU_XXX_FLAGS. */
941 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
945 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
947 fail (_("unknown bitfield: %s\n"), f
);
951 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
952 int macro
, const char *comma
, const char *indent
)
956 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
958 fprintf (table
, "%s{ { ", indent
);
960 for (i
= 0; i
< size
- 1; i
++)
962 if (((i
+ 1) % 20) != 0)
963 fprintf (table
, "%d, ", flags
[i
].value
);
965 fprintf (table
, "%d,", flags
[i
].value
);
966 if (((i
+ 1) % 20) == 0)
968 /* We need \\ for macro. */
970 fprintf (table
, " \\\n %s", indent
);
972 fprintf (table
, "\n %s", indent
);
975 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
978 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
982 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
983 const char *comma
, const char *indent
,
986 char *str
, *next
, *last
;
988 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
990 /* Copy the default cpu flags. */
991 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
993 if (strcasecmp (flag
, "unknown") == 0)
995 /* We turn on everything except for cpu64 in case of
996 CPU_UNKNOWN_FLAGS. */
997 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
998 if (flags
[i
].position
!= Cpu64
)
1001 else if (flag
[0] == '~')
1003 last
= flag
+ strlen (flag
);
1010 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1017 /* First we turn on everything except for cpu64. */
1018 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1019 if (flags
[i
].position
!= Cpu64
)
1022 /* Turn off selective bits. */
1023 for (; next
&& next
< last
; )
1025 str
= next_field (next
, '|', &next
, last
);
1027 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1030 else if (strcmp (flag
, "0"))
1032 /* Turn on selective bits. */
1033 last
= flag
+ strlen (flag
);
1034 for (next
= flag
; next
&& next
< last
; )
1036 str
= next_field (next
, '|', &next
, last
);
1038 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1042 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1047 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1051 fprintf (table
, " { ");
1053 for (i
= 0; i
< size
- 1; i
++)
1055 if (((i
+ 1) % 20) != 0)
1056 fprintf (table
, "%d, ", modifier
[i
].value
);
1058 fprintf (table
, "%d,", modifier
[i
].value
);
1059 if (((i
+ 1) % 20) == 0)
1060 fprintf (table
, "\n ");
1063 fprintf (table
, "%d },\n", modifier
[i
].value
);
1067 adjust_broadcast_modifier (char **opnd
)
1069 char *str
, *next
, *last
, *op
;
1070 int bcst_type
= INT_MAX
;
1072 /* Skip the immediate operand. */
1074 if (strcasecmp(op
, "Imm8") == 0)
1078 last
= op
+ strlen (op
);
1079 for (next
= op
; next
&& next
< last
; )
1081 str
= next_field (next
, '|', &next
, last
);
1084 if (strcasecmp(str
, "Byte") == 0)
1086 /* The smalest broadcast type, no need to check
1088 bcst_type
= BYTE_BROADCAST
;
1091 else if (strcasecmp(str
, "Word") == 0)
1093 if (bcst_type
> WORD_BROADCAST
)
1094 bcst_type
= WORD_BROADCAST
;
1096 else if (strcasecmp(str
, "Dword") == 0)
1098 if (bcst_type
> DWORD_BROADCAST
)
1099 bcst_type
= DWORD_BROADCAST
;
1101 else if (strcasecmp(str
, "Qword") == 0)
1103 if (bcst_type
> QWORD_BROADCAST
)
1104 bcst_type
= QWORD_BROADCAST
;
1110 if (bcst_type
== INT_MAX
)
1111 fail (_("unknown broadcast operand: %s\n"), op
);
1117 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1119 char *str
, *next
, *last
;
1120 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1122 active_isstring
= 0;
1124 /* Copy the default opcode modifier. */
1125 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1127 if (strcmp (mod
, "0"))
1129 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1131 last
= mod
+ strlen (mod
);
1132 for (next
= mod
; next
&& next
< last
; )
1134 str
= next_field (next
, '|', &next
, last
);
1138 if (strcasecmp(str
, "Broadcast") == 0)
1139 val
= adjust_broadcast_modifier (opnd
);
1140 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1142 if (strcasecmp(str
, "IsString") == 0)
1143 active_isstring
= 1;
1145 if (strcasecmp(str
, "W") == 0)
1148 if (strcasecmp(str
, "No_bSuf") == 0)
1150 if (strcasecmp(str
, "No_wSuf") == 0)
1152 if (strcasecmp(str
, "No_lSuf") == 0)
1154 if (strcasecmp(str
, "No_qSuf") == 0)
1159 if (have_w
&& !bwlq_suf
)
1160 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1161 if (have_w
&& !(bwlq_suf
& 1))
1162 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1164 if (have_w
&& !(bwlq_suf
& ~1))
1166 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1169 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1179 output_operand_type (FILE *table
, enum operand_class
class,
1180 enum operand_instance instance
,
1181 const bitfield
*types
, unsigned int size
,
1182 enum stage stage
, const char *indent
)
1186 fprintf (table
, "{ { %d, %d, ", class, instance
);
1188 for (i
= 0; i
< size
- 1; i
++)
1190 if (((i
+ 3) % 20) != 0)
1191 fprintf (table
, "%d, ", types
[i
].value
);
1193 fprintf (table
, "%d,", types
[i
].value
);
1194 if (((i
+ 3) % 20) == 0)
1196 /* We need \\ for macro. */
1197 if (stage
== stage_macros
)
1198 fprintf (table
, " \\\n%s", indent
);
1200 fprintf (table
, "\n%s", indent
);
1204 fprintf (table
, "%d } }", types
[i
].value
);
1208 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1209 const char *indent
, int lineno
)
1211 char *str
, *next
, *last
;
1212 enum operand_class
class = ClassNone
;
1213 enum operand_instance instance
= InstanceNone
;
1214 bitfield types
[ARRAY_SIZE (operand_types
)];
1216 /* Copy the default operand type. */
1217 memcpy (types
, operand_types
, sizeof (types
));
1219 if (strcmp (op
, "0"))
1223 last
= op
+ strlen (op
);
1224 for (next
= op
; next
&& next
< last
; )
1226 str
= next_field (next
, '|', &next
, last
);
1231 if (!strncmp(str
, "Class=", 6))
1233 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1234 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1236 class = operand_classes
[i
].value
;
1242 if (str
&& !strncmp(str
, "Instance=", 9))
1244 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1245 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1247 instance
= operand_instances
[i
].value
;
1255 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1256 if (strcasecmp(str
, "BaseIndex") == 0)
1261 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1263 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1264 if (!active_cpu_flags
.bitfield
.cpu64
1265 && !active_cpu_flags
.bitfield
.cpumpx
)
1266 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1267 if (!active_cpu_flags
.bitfield
.cpu64
)
1268 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1269 if (!active_cpu_flags
.bitfield
.cpuno64
)
1270 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1273 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1278 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1279 char *last
, int lineno
)
1282 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1283 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1285 /* Find number of operands. */
1286 operands
= next_field (str
, ',', &str
, last
);
1288 /* Find base_opcode. */
1289 base_opcode
= next_field (str
, ',', &str
, last
);
1291 /* Find extension_opcode. */
1292 extension_opcode
= next_field (str
, ',', &str
, last
);
1294 /* Find opcode_length. */
1295 opcode_length
= next_field (str
, ',', &str
, last
);
1297 /* Find cpu_flags. */
1298 cpu_flags
= next_field (str
, ',', &str
, last
);
1300 /* Find opcode_modifier. */
1301 opcode_modifier
= next_field (str
, ',', &str
, last
);
1303 /* Remove the first {. */
1304 str
= remove_leading_whitespaces (str
);
1307 str
= remove_leading_whitespaces (str
+ 1);
1311 /* There are at least "X}". */
1315 /* Remove trailing white spaces and }. */
1319 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1328 /* Find operand_types. */
1329 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1333 operand_types
[i
] = NULL
;
1337 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1338 if (*operand_types
[i
] == '0')
1341 operand_types
[i
] = NULL
;
1346 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1347 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1349 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1351 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1353 fprintf (table
, " { ");
1355 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1357 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1360 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1366 fprintf (table
, ",\n ");
1368 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1371 fprintf (table
, " } },\n");
1374 struct opcode_hash_entry
1376 struct opcode_hash_entry
*next
;
1382 /* Calculate the hash value of an opcode hash entry P. */
1385 opcode_hash_hash (const void *p
)
1387 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1388 return htab_hash_string (entry
->name
);
1391 /* Compare a string Q against an opcode hash entry P. */
1394 opcode_hash_eq (const void *p
, const void *q
)
1396 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1397 const char *name
= (const char *) q
;
1398 return strcmp (name
, entry
->name
) == 0;
1402 parse_template (char *buf
, int lineno
)
1404 char sep
, *end
, *name
;
1405 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1406 struct template_instance
*last_inst
= NULL
;
1408 buf
= remove_leading_whitespaces (buf
+ 1);
1409 end
= strchr (buf
, ':');
1411 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1413 remove_trailing_whitespaces (buf
);
1416 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1417 tmpl
->name
= xstrdup (buf
);
1419 tmpl
->params
= NULL
;
1421 struct template_param
*param
;
1423 buf
= remove_leading_whitespaces (end
);
1424 end
= strpbrk (buf
, ":,");
1426 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1430 remove_trailing_whitespaces (buf
);
1432 param
= xmalloc (sizeof (*param
));
1433 param
->name
= xstrdup (buf
);
1434 param
->next
= tmpl
->params
;
1435 tmpl
->params
= param
;
1436 } while (sep
== ':');
1438 tmpl
->instances
= NULL
;
1440 struct template_instance
*inst
;
1442 const struct template_param
*param
;
1444 buf
= remove_leading_whitespaces (end
);
1445 end
= strpbrk (buf
, ",>");
1447 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1452 inst
= xmalloc (sizeof (*inst
));
1454 cur
= next_field (buf
, ':', &next
, end
);
1455 inst
->name
= xstrdup (cur
);
1457 for (param
= tmpl
->params
; param
; param
= param
->next
)
1459 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1461 cur
= next_field (next
, ':', &next
, end
);
1463 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1464 arg
->val
= xstrdup (cur
);
1465 arg
->next
= inst
->args
;
1469 if (tmpl
->instances
)
1470 last_inst
->next
= inst
;
1472 tmpl
->instances
= inst
;
1474 } while (sep
== ',');
1476 buf
= remove_leading_whitespaces (end
);
1478 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1479 filename
, lineno
, buf
);
1481 tmpl
->next
= templates
;
1486 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1487 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1489 static unsigned int idx
, opcode_array_size
;
1490 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1491 struct opcode_hash_entry
**hash_slot
, **entry
;
1492 char *ptr1
= strchr(name
, '<'), *ptr2
;
1496 /* Get the slot in hash table. */
1497 hash_slot
= (struct opcode_hash_entry
**)
1498 htab_find_slot_with_hash (opcode_hash_table
, name
,
1499 htab_hash_string (name
),
1502 if (*hash_slot
== NULL
)
1504 /* It is the new one. Put it on opcode array. */
1505 if (idx
>= opcode_array_size
)
1507 /* Grow the opcode array when needed. */
1508 opcode_array_size
+= 1024;
1509 opcode_array
= (struct opcode_hash_entry
**)
1510 xrealloc (opcode_array
,
1511 sizeof (*opcode_array
) * opcode_array_size
);
1512 *opcode_array_p
= opcode_array
;
1515 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1516 xmalloc (sizeof (struct opcode_hash_entry
));
1517 opcode_array
[idx
]->next
= NULL
;
1518 opcode_array
[idx
]->name
= xstrdup (name
);
1519 opcode_array
[idx
]->opcode
= xstrdup (str
);
1520 opcode_array
[idx
]->lineno
= lineno
;
1521 *hash_slot
= opcode_array
[idx
];
1526 /* Append it to the existing one. */
1528 while ((*entry
) != NULL
)
1529 entry
= &(*entry
)->next
;
1530 *entry
= (struct opcode_hash_entry
*)
1531 xmalloc (sizeof (struct opcode_hash_entry
));
1532 (*entry
)->next
= NULL
;
1533 (*entry
)->name
= (*hash_slot
)->name
;
1534 (*entry
)->opcode
= xstrdup (str
);
1535 (*entry
)->lineno
= lineno
;
1538 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1539 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1542 const struct template *tmpl
;
1543 const struct template_instance
*inst
;
1546 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1547 remove_trailing_whitespaces (ptr1
);
1551 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1552 if (!strcmp(ptr1
, tmpl
->name
))
1555 fail ("reference to unknown template '%s'\n", ptr1
);
1557 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1559 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1560 char *str2
= xmalloc(2 * strlen(str
));
1563 strcpy (name2
, name
);
1564 strcat (name2
, inst
->name
);
1565 strcat (name2
, ptr2
);
1567 for (ptr1
= str2
, src
= str
; *src
; )
1569 const char *ident
= tmpl
->name
, *end
;
1570 const struct template_param
*param
;
1571 const struct template_arg
*arg
;
1573 if ((*ptr1
= *src
++) != '<')
1578 while (ISSPACE(*src
))
1580 while (*ident
&& *src
== *ident
)
1582 while (ISSPACE(*src
))
1584 if (*src
!= ':' || *ident
!= '\0')
1586 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1587 ptr1
+= ident
- tmpl
->name
;
1590 while (ISSPACE(*++src
))
1594 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1597 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1598 param
= param
->next
, arg
= arg
->next
)
1600 if (end
- src
== strlen (param
->name
)
1601 && !memcmp (src
, param
->name
, end
- src
))
1609 fail ("template '%s' has no parameter '%.*s'\n",
1610 tmpl
->name
, (int)(end
- src
), src
);
1612 while (ISSPACE(*src
))
1615 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1617 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1618 ptr1
+= strlen(arg
->val
);
1624 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1636 process_i386_opcodes (FILE *table
)
1641 char *str
, *p
, *last
, *name
;
1642 htab_t opcode_hash_table
;
1643 struct opcode_hash_entry
**opcode_array
= NULL
;
1644 int lineno
= 0, marker
= 0;
1646 filename
= "i386-opc.tbl";
1650 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1651 opcode_hash_eq
, NULL
,
1654 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1655 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1657 /* Put everything on opcode array. */
1660 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1665 p
= remove_leading_whitespaces (buf
);
1667 /* Skip comments. */
1668 str
= strstr (p
, "//");
1672 /* Remove trailing white spaces. */
1673 remove_trailing_whitespaces (p
);
1678 if (!strcmp("### MARKER ###", buf
))
1682 /* Since we ignore all included files (we only care about their
1683 #define-s here), we don't need to monitor filenames. The final
1684 line number directive is going to refer to the main source file
1689 p
= remove_leading_whitespaces (p
+ 1);
1690 if (!strncmp(p
, "line", 4))
1692 ln
= strtoul (p
, &end
, 10);
1693 if (ln
> 1 && ln
< INT_MAX
1694 && *remove_leading_whitespaces (end
) == '"')
1697 /* Ignore comments. */
1702 parse_template (p
, lineno
);
1710 last
= p
+ strlen (p
);
1713 name
= next_field (p
, ',', &str
, last
);
1715 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1719 /* Process opcode array. */
1720 for (j
= 0; j
< i
; j
++)
1722 struct opcode_hash_entry
*next
;
1724 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1728 lineno
= next
->lineno
;
1729 last
= str
+ strlen (str
);
1730 output_i386_opcode (table
, name
, str
, last
, lineno
);
1736 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1738 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1740 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1742 fprintf (table
, " { ");
1743 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1744 fprintf (table
, " } }\n");
1746 fprintf (table
, "};\n");
1750 process_i386_registers (FILE *table
)
1754 char *str
, *p
, *last
;
1755 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1756 char *dw2_32_num
, *dw2_64_num
;
1759 filename
= "i386-reg.tbl";
1760 fp
= fopen (filename
, "r");
1762 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1765 fprintf (table
, "\n/* i386 register table. */\n\n");
1766 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1770 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1775 p
= remove_leading_whitespaces (buf
);
1777 /* Skip comments. */
1778 str
= strstr (p
, "//");
1782 /* Remove trailing white spaces. */
1783 remove_trailing_whitespaces (p
);
1788 fprintf (table
, "%s\n", p
);
1796 last
= p
+ strlen (p
);
1798 /* Find reg_name. */
1799 reg_name
= next_field (p
, ',', &str
, last
);
1801 /* Find reg_type. */
1802 reg_type
= next_field (str
, ',', &str
, last
);
1804 /* Find reg_flags. */
1805 reg_flags
= next_field (str
, ',', &str
, last
);
1808 reg_num
= next_field (str
, ',', &str
, last
);
1810 fprintf (table
, " { \"%s\",\n ", reg_name
);
1812 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1815 /* Find 32-bit Dwarf2 register number. */
1816 dw2_32_num
= next_field (str
, ',', &str
, last
);
1818 /* Find 64-bit Dwarf2 register number. */
1819 dw2_64_num
= next_field (str
, ',', &str
, last
);
1821 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1822 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1827 fprintf (table
, "};\n");
1829 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1833 process_i386_initializers (void)
1836 FILE *fp
= fopen ("i386-init.h", "w");
1840 fail (_("can't create i386-init.h, errno = %s\n"),
1843 process_copyright (fp
);
1845 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1847 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1848 init
= xstrdup (cpu_flag_init
[i
].init
);
1849 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1853 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1855 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1856 init
= xstrdup (operand_type_init
[i
].init
);
1857 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1865 /* Program options. */
1866 #define OPTION_SRCDIR 200
1868 struct option long_options
[] =
1870 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1871 {"debug", no_argument
, NULL
, 'd'},
1872 {"version", no_argument
, NULL
, 'V'},
1873 {"help", no_argument
, NULL
, 'h'},
1874 {0, no_argument
, NULL
, 0}
1878 print_version (void)
1880 printf ("%s: version 1.0\n", program_name
);
1885 usage (FILE * stream
, int status
)
1887 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1893 main (int argc
, char **argv
)
1895 extern int chdir (char *);
1896 char *srcdir
= NULL
;
1898 unsigned int i
, cpumax
;
1901 program_name
= *argv
;
1902 xmalloc_set_program_name (program_name
);
1904 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1929 if (chdir (srcdir
) != 0)
1930 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1931 srcdir
, xstrerror (errno
));
1933 /* cpu_flags isn't sorted by position. */
1935 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1936 if (cpu_flags
[i
].position
> cpumax
)
1937 cpumax
= cpu_flags
[i
].position
;
1939 /* Check the unused bitfield in i386_cpu_flags. */
1941 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
1943 if ((cpumax
- 1) != CpuMax
)
1944 fail (_("CpuMax != %d!\n"), cpumax
);
1946 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
1948 if (cpumax
!= CpuMax
)
1949 fail (_("CpuMax != %d!\n"), cpumax
);
1951 c
= CpuNumOfBits
- CpuMax
- 1;
1953 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1956 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
1958 /* Check the unused bitfield in i386_operand_type. */
1960 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1963 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1966 c
= OTNumOfBits
- OTNum
;
1968 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1971 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1974 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1975 sizeof (opcode_modifiers
[0]), compare
);
1977 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1978 sizeof (operand_types
[0]), compare
);
1980 table
= fopen ("i386-tbl.h", "w");
1982 fail (_("can't create i386-tbl.h, errno = %s\n"),
1985 process_copyright (table
);
1987 process_i386_opcodes (table
);
1988 process_i386_registers (table
);
1989 process_i386_initializers ();