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 /* Ignore empty fields; they may result from template expansions. */
903 if (strcmp (f
, "CpuFP") == 0)
905 set_bitfield("Cpu387", array
, value
, size
, lineno
);
906 set_bitfield("Cpu287", array
, value
, size
, lineno
);
909 else if (strcmp (f
, "Mmword") == 0)
911 else if (strcmp (f
, "Oword") == 0)
914 for (i
= 0; i
< size
; i
++)
915 if (strcasecmp (array
[i
].name
, f
) == 0)
917 array
[i
].value
= value
;
923 const char *v
= strchr (f
, '=');
930 for (i
= 0; i
< size
; i
++)
931 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
933 value
= strtol (v
+ 1, &end
, 0);
936 array
[i
].value
= value
;
944 /* Handle CPU_XXX_FLAGS. */
945 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
949 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
951 fail (_("unknown bitfield: %s\n"), f
);
955 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
956 int macro
, const char *comma
, const char *indent
)
960 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
962 fprintf (table
, "%s{ { ", indent
);
964 for (i
= 0; i
< size
- 1; i
++)
966 if (((i
+ 1) % 20) != 0)
967 fprintf (table
, "%d, ", flags
[i
].value
);
969 fprintf (table
, "%d,", flags
[i
].value
);
970 if (((i
+ 1) % 20) == 0)
972 /* We need \\ for macro. */
974 fprintf (table
, " \\\n %s", indent
);
976 fprintf (table
, "\n %s", indent
);
979 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
982 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
986 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
987 const char *comma
, const char *indent
,
990 char *str
, *next
, *last
;
992 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
994 /* Copy the default cpu flags. */
995 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
997 if (strcasecmp (flag
, "unknown") == 0)
999 /* We turn on everything except for cpu64 in case of
1000 CPU_UNKNOWN_FLAGS. */
1001 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1002 if (flags
[i
].position
!= Cpu64
)
1005 else if (flag
[0] == '~')
1007 last
= flag
+ strlen (flag
);
1014 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1021 /* First we turn on everything except for cpu64. */
1022 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1023 if (flags
[i
].position
!= Cpu64
)
1026 /* Turn off selective bits. */
1027 for (; next
&& next
< last
; )
1029 str
= next_field (next
, '|', &next
, last
);
1031 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1034 else if (strcmp (flag
, "0"))
1036 /* Turn on selective bits. */
1037 last
= flag
+ strlen (flag
);
1038 for (next
= flag
; next
&& next
< last
; )
1040 str
= next_field (next
, '|', &next
, last
);
1042 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1046 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1051 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1055 fprintf (table
, " { ");
1057 for (i
= 0; i
< size
- 1; i
++)
1059 if (((i
+ 1) % 20) != 0)
1060 fprintf (table
, "%d, ", modifier
[i
].value
);
1062 fprintf (table
, "%d,", modifier
[i
].value
);
1063 if (((i
+ 1) % 20) == 0)
1064 fprintf (table
, "\n ");
1067 fprintf (table
, "%d },\n", modifier
[i
].value
);
1071 adjust_broadcast_modifier (char **opnd
)
1073 char *str
, *next
, *last
, *op
;
1074 int bcst_type
= INT_MAX
;
1076 /* Skip the immediate operand. */
1078 if (strcasecmp(op
, "Imm8") == 0)
1082 last
= op
+ strlen (op
);
1083 for (next
= op
; next
&& next
< last
; )
1085 str
= next_field (next
, '|', &next
, last
);
1088 if (strcasecmp(str
, "Byte") == 0)
1090 /* The smalest broadcast type, no need to check
1092 bcst_type
= BYTE_BROADCAST
;
1095 else if (strcasecmp(str
, "Word") == 0)
1097 if (bcst_type
> WORD_BROADCAST
)
1098 bcst_type
= WORD_BROADCAST
;
1100 else if (strcasecmp(str
, "Dword") == 0)
1102 if (bcst_type
> DWORD_BROADCAST
)
1103 bcst_type
= DWORD_BROADCAST
;
1105 else if (strcasecmp(str
, "Qword") == 0)
1107 if (bcst_type
> QWORD_BROADCAST
)
1108 bcst_type
= QWORD_BROADCAST
;
1114 if (bcst_type
== INT_MAX
)
1115 fail (_("unknown broadcast operand: %s\n"), op
);
1121 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1123 char *str
, *next
, *last
;
1124 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1126 active_isstring
= 0;
1128 /* Copy the default opcode modifier. */
1129 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1131 if (strcmp (mod
, "0"))
1133 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1135 last
= mod
+ strlen (mod
);
1136 for (next
= mod
; next
&& next
< last
; )
1138 str
= next_field (next
, '|', &next
, last
);
1142 if (strcasecmp(str
, "Broadcast") == 0)
1143 val
= adjust_broadcast_modifier (opnd
);
1144 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1146 if (strcasecmp(str
, "IsString") == 0)
1147 active_isstring
= 1;
1149 if (strcasecmp(str
, "W") == 0)
1152 if (strcasecmp(str
, "No_bSuf") == 0)
1154 if (strcasecmp(str
, "No_wSuf") == 0)
1156 if (strcasecmp(str
, "No_lSuf") == 0)
1158 if (strcasecmp(str
, "No_qSuf") == 0)
1163 if (have_w
&& !bwlq_suf
)
1164 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1165 if (have_w
&& !(bwlq_suf
& 1))
1166 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1168 if (have_w
&& !(bwlq_suf
& ~1))
1170 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1173 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1183 output_operand_type (FILE *table
, enum operand_class
class,
1184 enum operand_instance instance
,
1185 const bitfield
*types
, unsigned int size
,
1186 enum stage stage
, const char *indent
)
1190 fprintf (table
, "{ { %d, %d, ", class, instance
);
1192 for (i
= 0; i
< size
- 1; i
++)
1194 if (((i
+ 3) % 20) != 0)
1195 fprintf (table
, "%d, ", types
[i
].value
);
1197 fprintf (table
, "%d,", types
[i
].value
);
1198 if (((i
+ 3) % 20) == 0)
1200 /* We need \\ for macro. */
1201 if (stage
== stage_macros
)
1202 fprintf (table
, " \\\n%s", indent
);
1204 fprintf (table
, "\n%s", indent
);
1208 fprintf (table
, "%d } }", types
[i
].value
);
1212 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1213 const char *indent
, int lineno
)
1215 char *str
, *next
, *last
;
1216 enum operand_class
class = ClassNone
;
1217 enum operand_instance instance
= InstanceNone
;
1218 bitfield types
[ARRAY_SIZE (operand_types
)];
1220 /* Copy the default operand type. */
1221 memcpy (types
, operand_types
, sizeof (types
));
1223 if (strcmp (op
, "0"))
1227 last
= op
+ strlen (op
);
1228 for (next
= op
; next
&& next
< last
; )
1230 str
= next_field (next
, '|', &next
, last
);
1235 if (!strncmp(str
, "Class=", 6))
1237 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1238 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1240 class = operand_classes
[i
].value
;
1246 if (str
&& !strncmp(str
, "Instance=", 9))
1248 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1249 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1251 instance
= operand_instances
[i
].value
;
1259 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1260 if (strcasecmp(str
, "BaseIndex") == 0)
1265 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1267 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1268 if (!active_cpu_flags
.bitfield
.cpu64
1269 && !active_cpu_flags
.bitfield
.cpumpx
)
1270 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1271 if (!active_cpu_flags
.bitfield
.cpu64
)
1272 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1273 if (!active_cpu_flags
.bitfield
.cpuno64
)
1274 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1277 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1282 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1283 char *last
, int lineno
)
1286 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1287 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1289 /* Find number of operands. */
1290 operands
= next_field (str
, ',', &str
, last
);
1292 /* Find base_opcode. */
1293 base_opcode
= next_field (str
, ',', &str
, last
);
1295 /* Find extension_opcode. */
1296 extension_opcode
= next_field (str
, ',', &str
, last
);
1298 /* Find opcode_length. */
1299 opcode_length
= next_field (str
, ',', &str
, last
);
1301 /* Find cpu_flags. */
1302 cpu_flags
= next_field (str
, ',', &str
, last
);
1304 /* Find opcode_modifier. */
1305 opcode_modifier
= next_field (str
, ',', &str
, last
);
1307 /* Remove the first {. */
1308 str
= remove_leading_whitespaces (str
);
1311 str
= remove_leading_whitespaces (str
+ 1);
1315 /* There are at least "X}". */
1319 /* Remove trailing white spaces and }. */
1323 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1332 /* Find operand_types. */
1333 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1337 operand_types
[i
] = NULL
;
1341 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1342 if (*operand_types
[i
] == '0')
1345 operand_types
[i
] = NULL
;
1350 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1351 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1353 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1355 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1357 fprintf (table
, " { ");
1359 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1361 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1364 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1370 fprintf (table
, ",\n ");
1372 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1375 fprintf (table
, " } },\n");
1378 struct opcode_hash_entry
1380 struct opcode_hash_entry
*next
;
1386 /* Calculate the hash value of an opcode hash entry P. */
1389 opcode_hash_hash (const void *p
)
1391 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1392 return htab_hash_string (entry
->name
);
1395 /* Compare a string Q against an opcode hash entry P. */
1398 opcode_hash_eq (const void *p
, const void *q
)
1400 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1401 const char *name
= (const char *) q
;
1402 return strcmp (name
, entry
->name
) == 0;
1406 parse_template (char *buf
, int lineno
)
1408 char sep
, *end
, *name
;
1409 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1410 struct template_instance
*last_inst
= NULL
;
1412 buf
= remove_leading_whitespaces (buf
+ 1);
1413 end
= strchr (buf
, ':');
1415 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1417 remove_trailing_whitespaces (buf
);
1420 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1421 tmpl
->name
= xstrdup (buf
);
1423 tmpl
->params
= NULL
;
1425 struct template_param
*param
;
1427 buf
= remove_leading_whitespaces (end
);
1428 end
= strpbrk (buf
, ":,");
1430 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1434 remove_trailing_whitespaces (buf
);
1436 param
= xmalloc (sizeof (*param
));
1437 param
->name
= xstrdup (buf
);
1438 param
->next
= tmpl
->params
;
1439 tmpl
->params
= param
;
1440 } while (sep
== ':');
1442 tmpl
->instances
= NULL
;
1444 struct template_instance
*inst
;
1446 const struct template_param
*param
;
1448 buf
= remove_leading_whitespaces (end
);
1449 end
= strpbrk (buf
, ",>");
1451 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1456 inst
= xmalloc (sizeof (*inst
));
1458 cur
= next_field (buf
, ':', &next
, end
);
1459 inst
->name
= xstrdup (cur
);
1461 for (param
= tmpl
->params
; param
; param
= param
->next
)
1463 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1465 cur
= next_field (next
, ':', &next
, end
);
1467 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1468 arg
->val
= xstrdup (cur
);
1469 arg
->next
= inst
->args
;
1473 if (tmpl
->instances
)
1474 last_inst
->next
= inst
;
1476 tmpl
->instances
= inst
;
1478 } while (sep
== ',');
1480 buf
= remove_leading_whitespaces (end
);
1482 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1483 filename
, lineno
, buf
);
1485 tmpl
->next
= templates
;
1490 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1491 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1493 static unsigned int idx
, opcode_array_size
;
1494 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1495 struct opcode_hash_entry
**hash_slot
, **entry
;
1496 char *ptr1
= strchr(name
, '<'), *ptr2
;
1500 /* Get the slot in hash table. */
1501 hash_slot
= (struct opcode_hash_entry
**)
1502 htab_find_slot_with_hash (opcode_hash_table
, name
,
1503 htab_hash_string (name
),
1506 if (*hash_slot
== NULL
)
1508 /* It is the new one. Put it on opcode array. */
1509 if (idx
>= opcode_array_size
)
1511 /* Grow the opcode array when needed. */
1512 opcode_array_size
+= 1024;
1513 opcode_array
= (struct opcode_hash_entry
**)
1514 xrealloc (opcode_array
,
1515 sizeof (*opcode_array
) * opcode_array_size
);
1516 *opcode_array_p
= opcode_array
;
1519 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1520 xmalloc (sizeof (struct opcode_hash_entry
));
1521 opcode_array
[idx
]->next
= NULL
;
1522 opcode_array
[idx
]->name
= xstrdup (name
);
1523 opcode_array
[idx
]->opcode
= xstrdup (str
);
1524 opcode_array
[idx
]->lineno
= lineno
;
1525 *hash_slot
= opcode_array
[idx
];
1530 /* Append it to the existing one. */
1532 while ((*entry
) != NULL
)
1533 entry
= &(*entry
)->next
;
1534 *entry
= (struct opcode_hash_entry
*)
1535 xmalloc (sizeof (struct opcode_hash_entry
));
1536 (*entry
)->next
= NULL
;
1537 (*entry
)->name
= (*hash_slot
)->name
;
1538 (*entry
)->opcode
= xstrdup (str
);
1539 (*entry
)->lineno
= lineno
;
1542 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1543 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1546 const struct template *tmpl
;
1547 const struct template_instance
*inst
;
1550 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1551 remove_trailing_whitespaces (ptr1
);
1555 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1556 if (!strcmp(ptr1
, tmpl
->name
))
1559 fail ("reference to unknown template '%s'\n", ptr1
);
1561 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1563 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1564 char *str2
= xmalloc(2 * strlen(str
));
1567 strcpy (name2
, name
);
1568 strcat (name2
, inst
->name
);
1569 strcat (name2
, ptr2
);
1571 for (ptr1
= str2
, src
= str
; *src
; )
1573 const char *ident
= tmpl
->name
, *end
;
1574 const struct template_param
*param
;
1575 const struct template_arg
*arg
;
1577 if ((*ptr1
= *src
++) != '<')
1582 while (ISSPACE(*src
))
1584 while (*ident
&& *src
== *ident
)
1586 while (ISSPACE(*src
))
1588 if (*src
!= ':' || *ident
!= '\0')
1590 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1591 ptr1
+= ident
- tmpl
->name
;
1594 while (ISSPACE(*++src
))
1598 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1601 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1602 param
= param
->next
, arg
= arg
->next
)
1604 if (end
- src
== strlen (param
->name
)
1605 && !memcmp (src
, param
->name
, end
- src
))
1613 fail ("template '%s' has no parameter '%.*s'\n",
1614 tmpl
->name
, (int)(end
- src
), src
);
1616 while (ISSPACE(*src
))
1619 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1621 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1622 ptr1
+= strlen(arg
->val
);
1628 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1640 process_i386_opcodes (FILE *table
)
1645 char *str
, *p
, *last
, *name
;
1646 htab_t opcode_hash_table
;
1647 struct opcode_hash_entry
**opcode_array
= NULL
;
1648 int lineno
= 0, marker
= 0;
1650 filename
= "i386-opc.tbl";
1654 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1655 opcode_hash_eq
, NULL
,
1658 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1659 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1661 /* Put everything on opcode array. */
1664 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1669 p
= remove_leading_whitespaces (buf
);
1671 /* Skip comments. */
1672 str
= strstr (p
, "//");
1676 /* Remove trailing white spaces. */
1677 remove_trailing_whitespaces (p
);
1682 if (!strcmp("### MARKER ###", buf
))
1686 /* Since we ignore all included files (we only care about their
1687 #define-s here), we don't need to monitor filenames. The final
1688 line number directive is going to refer to the main source file
1693 p
= remove_leading_whitespaces (p
+ 1);
1694 if (!strncmp(p
, "line", 4))
1696 ln
= strtoul (p
, &end
, 10);
1697 if (ln
> 1 && ln
< INT_MAX
1698 && *remove_leading_whitespaces (end
) == '"')
1701 /* Ignore comments. */
1706 parse_template (p
, lineno
);
1714 last
= p
+ strlen (p
);
1717 name
= next_field (p
, ',', &str
, last
);
1719 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1723 /* Process opcode array. */
1724 for (j
= 0; j
< i
; j
++)
1726 struct opcode_hash_entry
*next
;
1728 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1732 lineno
= next
->lineno
;
1733 last
= str
+ strlen (str
);
1734 output_i386_opcode (table
, name
, str
, last
, lineno
);
1740 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1742 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1744 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1746 fprintf (table
, " { ");
1747 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1748 fprintf (table
, " } }\n");
1750 fprintf (table
, "};\n");
1754 process_i386_registers (FILE *table
)
1758 char *str
, *p
, *last
;
1759 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1760 char *dw2_32_num
, *dw2_64_num
;
1763 filename
= "i386-reg.tbl";
1764 fp
= fopen (filename
, "r");
1766 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1769 fprintf (table
, "\n/* i386 register table. */\n\n");
1770 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1774 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1779 p
= remove_leading_whitespaces (buf
);
1781 /* Skip comments. */
1782 str
= strstr (p
, "//");
1786 /* Remove trailing white spaces. */
1787 remove_trailing_whitespaces (p
);
1792 fprintf (table
, "%s\n", p
);
1800 last
= p
+ strlen (p
);
1802 /* Find reg_name. */
1803 reg_name
= next_field (p
, ',', &str
, last
);
1805 /* Find reg_type. */
1806 reg_type
= next_field (str
, ',', &str
, last
);
1808 /* Find reg_flags. */
1809 reg_flags
= next_field (str
, ',', &str
, last
);
1812 reg_num
= next_field (str
, ',', &str
, last
);
1814 fprintf (table
, " { \"%s\",\n ", reg_name
);
1816 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1819 /* Find 32-bit Dwarf2 register number. */
1820 dw2_32_num
= next_field (str
, ',', &str
, last
);
1822 /* Find 64-bit Dwarf2 register number. */
1823 dw2_64_num
= next_field (str
, ',', &str
, last
);
1825 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1826 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1831 fprintf (table
, "};\n");
1833 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1837 process_i386_initializers (void)
1840 FILE *fp
= fopen ("i386-init.h", "w");
1844 fail (_("can't create i386-init.h, errno = %s\n"),
1847 process_copyright (fp
);
1849 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1851 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1852 init
= xstrdup (cpu_flag_init
[i
].init
);
1853 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1857 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1859 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1860 init
= xstrdup (operand_type_init
[i
].init
);
1861 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1869 /* Program options. */
1870 #define OPTION_SRCDIR 200
1872 struct option long_options
[] =
1874 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1875 {"debug", no_argument
, NULL
, 'd'},
1876 {"version", no_argument
, NULL
, 'V'},
1877 {"help", no_argument
, NULL
, 'h'},
1878 {0, no_argument
, NULL
, 0}
1882 print_version (void)
1884 printf ("%s: version 1.0\n", program_name
);
1889 usage (FILE * stream
, int status
)
1891 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1897 main (int argc
, char **argv
)
1899 extern int chdir (char *);
1900 char *srcdir
= NULL
;
1902 unsigned int i
, cpumax
;
1905 program_name
= *argv
;
1906 xmalloc_set_program_name (program_name
);
1908 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1933 if (chdir (srcdir
) != 0)
1934 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1935 srcdir
, xstrerror (errno
));
1937 /* cpu_flags isn't sorted by position. */
1939 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1940 if (cpu_flags
[i
].position
> cpumax
)
1941 cpumax
= cpu_flags
[i
].position
;
1943 /* Check the unused bitfield in i386_cpu_flags. */
1945 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
1947 if ((cpumax
- 1) != CpuMax
)
1948 fail (_("CpuMax != %d!\n"), cpumax
);
1950 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
1952 if (cpumax
!= CpuMax
)
1953 fail (_("CpuMax != %d!\n"), cpumax
);
1955 c
= CpuNumOfBits
- CpuMax
- 1;
1957 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1960 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
1962 /* Check the unused bitfield in i386_operand_type. */
1964 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1967 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1970 c
= OTNumOfBits
- OTNum
;
1972 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1975 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1978 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1979 sizeof (opcode_modifiers
[0]), compare
);
1981 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1982 sizeof (operand_types
[0]), compare
);
1984 table
= fopen ("i386-tbl.h", "w");
1986 fail (_("can't create i386-tbl.h, errno = %s\n"),
1989 process_copyright (table
);
1991 process_i386_opcodes (table
);
1992 process_i386_registers (table
);
1993 process_i386_initializers ();