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_ANY_X87_FLAGS",
317 "CPU_ANY_287_FLAGS|Cpu8087" },
318 { "CPU_ANY_287_FLAGS",
319 "CPU_ANY_387_FLAGS|Cpu287" },
320 { "CPU_ANY_387_FLAGS",
321 "CPU_ANY_687_FLAGS|Cpu387" },
322 { "CPU_ANY_687_FLAGS",
323 "Cpu687|CpuFISTTP" },
324 { "CPU_ANY_CMOV_FLAGS",
326 { "CPU_ANY_FXSR_FLAGS",
328 { "CPU_ANY_MMX_FLAGS",
329 "CPU_3DNOWA_FLAGS" },
330 { "CPU_ANY_SSE_FLAGS",
331 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
332 { "CPU_ANY_SSE2_FLAGS",
333 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
334 { "CPU_ANY_SSE3_FLAGS",
335 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
336 { "CPU_ANY_SSSE3_FLAGS",
337 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
338 { "CPU_ANY_SSE4_1_FLAGS",
339 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
340 { "CPU_ANY_SSE4_2_FLAGS",
342 { "CPU_ANY_SSE4A_FLAGS",
344 { "CPU_ANY_AVX_FLAGS",
345 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
346 { "CPU_ANY_AVX2_FLAGS",
347 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
348 { "CPU_ANY_AVX512F_FLAGS",
349 "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" },
350 { "CPU_ANY_AVX512CD_FLAGS",
352 { "CPU_ANY_AVX512ER_FLAGS",
354 { "CPU_ANY_AVX512PF_FLAGS",
356 { "CPU_ANY_AVX512DQ_FLAGS",
358 { "CPU_ANY_AVX512BW_FLAGS",
360 { "CPU_ANY_AVX512VL_FLAGS",
362 { "CPU_ANY_AVX512IFMA_FLAGS",
364 { "CPU_ANY_AVX512VBMI_FLAGS",
366 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
367 "CpuAVX512_4FMAPS" },
368 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
369 "CpuAVX512_4VNNIW" },
370 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
371 "CpuAVX512_VPOPCNTDQ" },
372 { "CPU_ANY_IBT_FLAGS",
374 { "CPU_ANY_SHSTK_FLAGS",
376 { "CPU_ANY_AVX512_VBMI2_FLAGS",
378 { "CPU_ANY_AVX512_VNNI_FLAGS",
380 { "CPU_ANY_AVX512_BITALG_FLAGS",
381 "CpuAVX512_BITALG" },
382 { "CPU_ANY_AVX512_BF16_FLAGS",
384 { "CPU_ANY_MOVDIRI_FLAGS",
386 { "CPU_ANY_MOVDIR64B_FLAGS",
388 { "CPU_ANY_ENQCMD_FLAGS",
390 { "CPU_ANY_SERIALIZE_FLAGS",
392 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
393 "CpuAVX512_VP2INTERSECT" },
396 static initializer operand_type_init
[] =
398 { "OPERAND_TYPE_NONE",
400 { "OPERAND_TYPE_REG8",
402 { "OPERAND_TYPE_REG16",
404 { "OPERAND_TYPE_REG32",
406 { "OPERAND_TYPE_REG64",
408 { "OPERAND_TYPE_IMM1",
410 { "OPERAND_TYPE_IMM8",
412 { "OPERAND_TYPE_IMM8S",
414 { "OPERAND_TYPE_IMM16",
416 { "OPERAND_TYPE_IMM32",
418 { "OPERAND_TYPE_IMM32S",
420 { "OPERAND_TYPE_IMM64",
422 { "OPERAND_TYPE_BASEINDEX",
424 { "OPERAND_TYPE_DISP8",
426 { "OPERAND_TYPE_DISP16",
428 { "OPERAND_TYPE_DISP32",
430 { "OPERAND_TYPE_DISP32S",
432 { "OPERAND_TYPE_DISP64",
434 { "OPERAND_TYPE_INOUTPORTREG",
435 "Instance=RegD|Word" },
436 { "OPERAND_TYPE_SHIFTCOUNT",
437 "Instance=RegC|Byte" },
438 { "OPERAND_TYPE_CONTROL",
440 { "OPERAND_TYPE_TEST",
442 { "OPERAND_TYPE_DEBUG",
444 { "OPERAND_TYPE_FLOATREG",
446 { "OPERAND_TYPE_FLOATACC",
447 "Instance=Accum|Tbyte" },
448 { "OPERAND_TYPE_SREG",
450 { "OPERAND_TYPE_REGMMX",
452 { "OPERAND_TYPE_REGXMM",
453 "Class=RegSIMD|Xmmword" },
454 { "OPERAND_TYPE_REGYMM",
455 "Class=RegSIMD|Ymmword" },
456 { "OPERAND_TYPE_REGZMM",
457 "Class=RegSIMD|Zmmword" },
458 { "OPERAND_TYPE_REGMASK",
460 { "OPERAND_TYPE_REGBND",
462 { "OPERAND_TYPE_ACC8",
463 "Instance=Accum|Byte" },
464 { "OPERAND_TYPE_ACC16",
465 "Instance=Accum|Word" },
466 { "OPERAND_TYPE_ACC32",
467 "Instance=Accum|Dword" },
468 { "OPERAND_TYPE_ACC64",
469 "Instance=Accum|Qword" },
470 { "OPERAND_TYPE_DISP16_32",
472 { "OPERAND_TYPE_ANYDISP",
473 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
474 { "OPERAND_TYPE_IMM16_32",
476 { "OPERAND_TYPE_IMM16_32S",
478 { "OPERAND_TYPE_IMM16_32_32S",
479 "Imm16|Imm32|Imm32S" },
480 { "OPERAND_TYPE_IMM32_64",
482 { "OPERAND_TYPE_IMM32_32S_DISP32",
483 "Imm32|Imm32S|Disp32" },
484 { "OPERAND_TYPE_IMM64_DISP64",
486 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
487 "Imm32|Imm32S|Imm64|Disp32" },
488 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
489 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
490 { "OPERAND_TYPE_ANYIMM",
491 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
494 typedef struct bitfield
501 #define BITFIELD(n) { n, 0, #n }
503 static bitfield cpu_flags
[] =
513 BITFIELD (CpuClflush
),
515 BITFIELD (CpuSYSCALL
),
520 BITFIELD (CpuFISTTP
),
526 BITFIELD (CpuSSE4_1
),
527 BITFIELD (CpuSSE4_2
),
530 BITFIELD (CpuAVX512F
),
531 BITFIELD (CpuAVX512CD
),
532 BITFIELD (CpuAVX512ER
),
533 BITFIELD (CpuAVX512PF
),
534 BITFIELD (CpuAVX512VL
),
535 BITFIELD (CpuAVX512DQ
),
536 BITFIELD (CpuAVX512BW
),
542 BITFIELD (Cpu3dnowA
),
543 BITFIELD (CpuPadLock
),
548 BITFIELD (CpuXsaveopt
),
550 BITFIELD (CpuPCLMUL
),
561 BITFIELD (CpuRdtscp
),
562 BITFIELD (CpuFSGSBase
),
567 BITFIELD (CpuPOPCNT
),
570 BITFIELD (CpuINVPCID
),
571 BITFIELD (CpuVMFUNC
),
572 BITFIELD (CpuRDSEED
),
574 BITFIELD (CpuPRFCHW
),
577 BITFIELD (CpuClflushOpt
),
578 BITFIELD (CpuXSAVES
),
579 BITFIELD (CpuXSAVEC
),
580 BITFIELD (CpuPREFETCHWT1
),
586 BITFIELD (CpuAVX512IFMA
),
587 BITFIELD (CpuAVX512VBMI
),
588 BITFIELD (CpuAVX512_4FMAPS
),
589 BITFIELD (CpuAVX512_4VNNIW
),
590 BITFIELD (CpuAVX512_VPOPCNTDQ
),
591 BITFIELD (CpuAVX512_VBMI2
),
592 BITFIELD (CpuAVX512_VNNI
),
593 BITFIELD (CpuAVX512_BITALG
),
594 BITFIELD (CpuAVX512_BF16
),
595 BITFIELD (CpuAVX512_VP2INTERSECT
),
596 BITFIELD (CpuMWAITX
),
597 BITFIELD (CpuCLZERO
),
600 BITFIELD (CpuPTWRITE
),
605 BITFIELD (CpuVPCLMULQDQ
),
606 BITFIELD (CpuWBNOINVD
),
607 BITFIELD (CpuPCONFIG
),
608 BITFIELD (CpuWAITPKG
),
609 BITFIELD (CpuCLDEMOTE
),
610 BITFIELD (CpuMOVDIRI
),
611 BITFIELD (CpuMOVDIR64B
),
612 BITFIELD (CpuENQCMD
),
613 BITFIELD (CpuSERIALIZE
),
615 BITFIELD (CpuMCOMMIT
),
616 BITFIELD (CpuSEV_ES
),
618 BITFIELD (CpuUnused
),
622 static bitfield opcode_modifiers
[] =
632 BITFIELD (CheckRegSize
),
633 BITFIELD (MnemonicSize
),
644 BITFIELD (BNDPrefixOk
),
645 BITFIELD (NoTrackPrefixOk
),
646 BITFIELD (IsLockable
),
647 BITFIELD (RegKludge
),
648 BITFIELD (Implicit1stXmm0
),
649 BITFIELD (RepPrefixOk
),
650 BITFIELD (HLEPrefixOk
),
653 BITFIELD (AddrPrefixOpReg
),
661 BITFIELD (VexOpcode
),
662 BITFIELD (VexSources
),
668 BITFIELD (Broadcast
),
669 BITFIELD (StaticRounding
),
671 BITFIELD (Disp8MemShift
),
672 BITFIELD (NoDefMask
),
673 BITFIELD (ImplicitQuadGroup
),
675 BITFIELD (ATTMnemonic
),
676 BITFIELD (ATTSyntax
),
677 BITFIELD (IntelSyntax
),
681 #define CLASS(n) #n, n
683 static const struct {
685 enum operand_class value
;
686 } operand_classes
[] = {
700 #define INSTANCE(n) #n, n
702 static const struct {
704 enum operand_instance value
;
705 } operand_instances
[] = {
714 static bitfield operand_types
[] =
723 BITFIELD (BaseIndex
),
738 BITFIELD (Unspecified
),
744 static const char *filename
;
745 static i386_cpu_flags active_cpu_flags
;
746 static int active_isstring
;
748 struct template_arg
{
749 const struct template_arg
*next
;
753 struct template_instance
{
754 const struct template_instance
*next
;
756 const struct template_arg
*args
;
759 struct template_param
{
760 const struct template_param
*next
;
765 const struct template *next
;
767 const struct template_instance
*instances
;
768 const struct template_param
*params
;
771 static const struct template *templates
;
774 compare (const void *x
, const void *y
)
776 const bitfield
*xp
= (const bitfield
*) x
;
777 const bitfield
*yp
= (const bitfield
*) y
;
778 return xp
->position
- yp
->position
;
782 fail (const char *message
, ...)
786 va_start (args
, message
);
787 fprintf (stderr
, _("%s: error: "), program_name
);
788 vfprintf (stderr
, message
, args
);
794 process_copyright (FILE *fp
)
796 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
797 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
799 This file is part of the GNU opcodes library.\n\
801 This library is free software; you can redistribute it and/or modify\n\
802 it under the terms of the GNU General Public License as published by\n\
803 the Free Software Foundation; either version 3, or (at your option)\n\
804 any later version.\n\
806 It is distributed in the hope that it will be useful, but WITHOUT\n\
807 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
808 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
809 License for more details.\n\
811 You should have received a copy of the GNU General Public License\n\
812 along with this program; if not, write to the Free Software\n\
813 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
814 MA 02110-1301, USA. */\n");
817 /* Remove leading white spaces. */
820 remove_leading_whitespaces (char *str
)
822 while (ISSPACE (*str
))
827 /* Remove trailing white spaces. */
830 remove_trailing_whitespaces (char *str
)
832 size_t last
= strlen (str
);
840 if (ISSPACE (str
[last
]))
848 /* Find next field separated by SEP and terminate it. Return a
849 pointer to the one after it. */
852 next_field (char *str
, char sep
, char **next
, char *last
)
856 p
= remove_leading_whitespaces (str
);
857 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
860 remove_trailing_whitespaces (p
);
870 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
873 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
, unsigned int size
,
876 char *str
, *next
, *last
;
879 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
880 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
882 /* Turn on selective bits. */
883 char *init
= xstrdup (cpu_flag_init
[i
].init
);
884 last
= init
+ strlen (init
);
885 for (next
= init
; next
&& next
< last
; )
887 str
= next_field (next
, '|', &next
, last
);
889 set_bitfield (str
, array
, 1, size
, lineno
);
899 set_bitfield (char *f
, bitfield
*array
, int value
,
900 unsigned int size
, int lineno
)
904 /* Ignore empty fields; they may result from template expansions. */
908 if (strcmp (f
, "CpuFP") == 0)
910 set_bitfield("Cpu387", array
, value
, size
, lineno
);
911 set_bitfield("Cpu287", array
, value
, size
, lineno
);
914 else if (strcmp (f
, "Mmword") == 0)
916 else if (strcmp (f
, "Oword") == 0)
919 for (i
= 0; i
< size
; i
++)
920 if (strcasecmp (array
[i
].name
, f
) == 0)
922 array
[i
].value
= value
;
928 const char *v
= strchr (f
, '=');
935 for (i
= 0; i
< size
; i
++)
936 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
938 value
= strtol (v
+ 1, &end
, 0);
941 array
[i
].value
= value
;
949 /* Handle CPU_XXX_FLAGS. */
950 if (value
== 1 && !set_bitfield_from_cpu_flag_init (f
, array
, size
, lineno
))
954 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
956 fail (_("unknown bitfield: %s\n"), f
);
960 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
961 int macro
, const char *comma
, const char *indent
)
965 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
967 fprintf (table
, "%s{ { ", indent
);
969 for (i
= 0; i
< size
- 1; i
++)
971 if (((i
+ 1) % 20) != 0)
972 fprintf (table
, "%d, ", flags
[i
].value
);
974 fprintf (table
, "%d,", flags
[i
].value
);
975 if (((i
+ 1) % 20) == 0)
977 /* We need \\ for macro. */
979 fprintf (table
, " \\\n %s", indent
);
981 fprintf (table
, "\n %s", indent
);
984 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
987 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
991 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
992 const char *comma
, const char *indent
,
995 char *str
, *next
, *last
;
997 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
999 /* Copy the default cpu flags. */
1000 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
1002 if (strcasecmp (flag
, "unknown") == 0)
1004 /* We turn on everything except for cpu64 in case of
1005 CPU_UNKNOWN_FLAGS. */
1006 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1007 if (flags
[i
].position
!= Cpu64
)
1010 else if (flag
[0] == '~')
1012 last
= flag
+ strlen (flag
);
1019 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
1026 /* First we turn on everything except for cpu64. */
1027 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1028 if (flags
[i
].position
!= Cpu64
)
1031 /* Turn off selective bits. */
1032 for (; next
&& next
< last
; )
1034 str
= next_field (next
, '|', &next
, last
);
1036 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1039 else if (strcmp (flag
, "0"))
1041 /* Turn on selective bits. */
1042 last
= flag
+ strlen (flag
);
1043 for (next
= flag
; next
&& next
< last
; )
1045 str
= next_field (next
, '|', &next
, last
);
1047 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1051 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1056 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1060 fprintf (table
, " { ");
1062 for (i
= 0; i
< size
- 1; i
++)
1064 if (((i
+ 1) % 20) != 0)
1065 fprintf (table
, "%d, ", modifier
[i
].value
);
1067 fprintf (table
, "%d,", modifier
[i
].value
);
1068 if (((i
+ 1) % 20) == 0)
1069 fprintf (table
, "\n ");
1072 fprintf (table
, "%d },\n", modifier
[i
].value
);
1076 adjust_broadcast_modifier (char **opnd
)
1078 char *str
, *next
, *last
, *op
;
1079 int bcst_type
= INT_MAX
;
1081 /* Skip the immediate operand. */
1083 if (strcasecmp(op
, "Imm8") == 0)
1087 last
= op
+ strlen (op
);
1088 for (next
= op
; next
&& next
< last
; )
1090 str
= next_field (next
, '|', &next
, last
);
1093 if (strcasecmp(str
, "Byte") == 0)
1095 /* The smalest broadcast type, no need to check
1097 bcst_type
= BYTE_BROADCAST
;
1100 else if (strcasecmp(str
, "Word") == 0)
1102 if (bcst_type
> WORD_BROADCAST
)
1103 bcst_type
= WORD_BROADCAST
;
1105 else if (strcasecmp(str
, "Dword") == 0)
1107 if (bcst_type
> DWORD_BROADCAST
)
1108 bcst_type
= DWORD_BROADCAST
;
1110 else if (strcasecmp(str
, "Qword") == 0)
1112 if (bcst_type
> QWORD_BROADCAST
)
1113 bcst_type
= QWORD_BROADCAST
;
1119 if (bcst_type
== INT_MAX
)
1120 fail (_("unknown broadcast operand: %s\n"), op
);
1126 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1128 char *str
, *next
, *last
;
1129 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1131 active_isstring
= 0;
1133 /* Copy the default opcode modifier. */
1134 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1136 if (strcmp (mod
, "0"))
1138 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1140 last
= mod
+ strlen (mod
);
1141 for (next
= mod
; next
&& next
< last
; )
1143 str
= next_field (next
, '|', &next
, last
);
1147 if (strcasecmp(str
, "Broadcast") == 0)
1148 val
= adjust_broadcast_modifier (opnd
);
1149 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1151 if (strcasecmp(str
, "IsString") == 0)
1152 active_isstring
= 1;
1154 if (strcasecmp(str
, "W") == 0)
1157 if (strcasecmp(str
, "No_bSuf") == 0)
1159 if (strcasecmp(str
, "No_wSuf") == 0)
1161 if (strcasecmp(str
, "No_lSuf") == 0)
1163 if (strcasecmp(str
, "No_qSuf") == 0)
1168 if (have_w
&& !bwlq_suf
)
1169 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1170 if (have_w
&& !(bwlq_suf
& 1))
1171 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1173 if (have_w
&& !(bwlq_suf
& ~1))
1175 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1178 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1188 output_operand_type (FILE *table
, enum operand_class
class,
1189 enum operand_instance instance
,
1190 const bitfield
*types
, unsigned int size
,
1191 enum stage stage
, const char *indent
)
1195 fprintf (table
, "{ { %d, %d, ", class, instance
);
1197 for (i
= 0; i
< size
- 1; i
++)
1199 if (((i
+ 3) % 20) != 0)
1200 fprintf (table
, "%d, ", types
[i
].value
);
1202 fprintf (table
, "%d,", types
[i
].value
);
1203 if (((i
+ 3) % 20) == 0)
1205 /* We need \\ for macro. */
1206 if (stage
== stage_macros
)
1207 fprintf (table
, " \\\n%s", indent
);
1209 fprintf (table
, "\n%s", indent
);
1213 fprintf (table
, "%d } }", types
[i
].value
);
1217 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1218 const char *indent
, int lineno
)
1220 char *str
, *next
, *last
;
1221 enum operand_class
class = ClassNone
;
1222 enum operand_instance instance
= InstanceNone
;
1223 bitfield types
[ARRAY_SIZE (operand_types
)];
1225 /* Copy the default operand type. */
1226 memcpy (types
, operand_types
, sizeof (types
));
1228 if (strcmp (op
, "0"))
1232 last
= op
+ strlen (op
);
1233 for (next
= op
; next
&& next
< last
; )
1235 str
= next_field (next
, '|', &next
, last
);
1240 if (!strncmp(str
, "Class=", 6))
1242 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1243 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1245 class = operand_classes
[i
].value
;
1251 if (str
&& !strncmp(str
, "Instance=", 9))
1253 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1254 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1256 instance
= operand_instances
[i
].value
;
1264 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1265 if (strcasecmp(str
, "BaseIndex") == 0)
1270 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1272 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1273 if (!active_cpu_flags
.bitfield
.cpu64
1274 && !active_cpu_flags
.bitfield
.cpumpx
)
1275 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1276 if (!active_cpu_flags
.bitfield
.cpu64
)
1277 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1278 if (!active_cpu_flags
.bitfield
.cpuno64
)
1279 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1282 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1287 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1288 char *last
, int lineno
)
1291 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1292 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1294 /* Find number of operands. */
1295 operands
= next_field (str
, ',', &str
, last
);
1297 /* Find base_opcode. */
1298 base_opcode
= next_field (str
, ',', &str
, last
);
1300 /* Find extension_opcode. */
1301 extension_opcode
= next_field (str
, ',', &str
, last
);
1303 /* Find opcode_length. */
1304 opcode_length
= next_field (str
, ',', &str
, last
);
1306 /* Find cpu_flags. */
1307 cpu_flags
= next_field (str
, ',', &str
, last
);
1309 /* Find opcode_modifier. */
1310 opcode_modifier
= next_field (str
, ',', &str
, last
);
1312 /* Remove the first {. */
1313 str
= remove_leading_whitespaces (str
);
1316 str
= remove_leading_whitespaces (str
+ 1);
1320 /* There are at least "X}". */
1324 /* Remove trailing white spaces and }. */
1328 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1337 /* Find operand_types. */
1338 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1342 operand_types
[i
] = NULL
;
1346 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1347 if (*operand_types
[i
] == '0')
1350 operand_types
[i
] = NULL
;
1355 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1356 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1358 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1360 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1362 fprintf (table
, " { ");
1364 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1366 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1369 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1375 fprintf (table
, ",\n ");
1377 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1380 fprintf (table
, " } },\n");
1383 struct opcode_hash_entry
1385 struct opcode_hash_entry
*next
;
1391 /* Calculate the hash value of an opcode hash entry P. */
1394 opcode_hash_hash (const void *p
)
1396 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1397 return htab_hash_string (entry
->name
);
1400 /* Compare a string Q against an opcode hash entry P. */
1403 opcode_hash_eq (const void *p
, const void *q
)
1405 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1406 const char *name
= (const char *) q
;
1407 return strcmp (name
, entry
->name
) == 0;
1411 parse_template (char *buf
, int lineno
)
1413 char sep
, *end
, *name
;
1414 struct template *tmpl
= xmalloc (sizeof (*tmpl
));
1415 struct template_instance
*last_inst
= NULL
;
1417 buf
= remove_leading_whitespaces (buf
+ 1);
1418 end
= strchr (buf
, ':');
1420 fail ("%s: %d: missing ':'\n", filename
, lineno
);
1422 remove_trailing_whitespaces (buf
);
1425 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1426 tmpl
->name
= xstrdup (buf
);
1428 tmpl
->params
= NULL
;
1430 struct template_param
*param
;
1432 buf
= remove_leading_whitespaces (end
);
1433 end
= strpbrk (buf
, ":,");
1435 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1439 remove_trailing_whitespaces (buf
);
1441 param
= xmalloc (sizeof (*param
));
1442 param
->name
= xstrdup (buf
);
1443 param
->next
= tmpl
->params
;
1444 tmpl
->params
= param
;
1445 } while (sep
== ':');
1447 tmpl
->instances
= NULL
;
1449 struct template_instance
*inst
;
1451 const struct template_param
*param
;
1453 buf
= remove_leading_whitespaces (end
);
1454 end
= strpbrk (buf
, ",>");
1456 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1461 inst
= xmalloc (sizeof (*inst
));
1463 cur
= next_field (buf
, ':', &next
, end
);
1464 inst
->name
= xstrdup (cur
);
1466 for (param
= tmpl
->params
; param
; param
= param
->next
)
1468 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1470 cur
= next_field (next
, ':', &next
, end
);
1472 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1473 arg
->val
= xstrdup (cur
);
1474 arg
->next
= inst
->args
;
1478 if (tmpl
->instances
)
1479 last_inst
->next
= inst
;
1481 tmpl
->instances
= inst
;
1483 } while (sep
== ',');
1485 buf
= remove_leading_whitespaces (end
);
1487 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1488 filename
, lineno
, buf
);
1490 tmpl
->next
= templates
;
1495 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1496 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1498 static unsigned int idx
, opcode_array_size
;
1499 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1500 struct opcode_hash_entry
**hash_slot
, **entry
;
1501 char *ptr1
= strchr(name
, '<'), *ptr2
;
1505 /* Get the slot in hash table. */
1506 hash_slot
= (struct opcode_hash_entry
**)
1507 htab_find_slot_with_hash (opcode_hash_table
, name
,
1508 htab_hash_string (name
),
1511 if (*hash_slot
== NULL
)
1513 /* It is the new one. Put it on opcode array. */
1514 if (idx
>= opcode_array_size
)
1516 /* Grow the opcode array when needed. */
1517 opcode_array_size
+= 1024;
1518 opcode_array
= (struct opcode_hash_entry
**)
1519 xrealloc (opcode_array
,
1520 sizeof (*opcode_array
) * opcode_array_size
);
1521 *opcode_array_p
= opcode_array
;
1524 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1525 xmalloc (sizeof (struct opcode_hash_entry
));
1526 opcode_array
[idx
]->next
= NULL
;
1527 opcode_array
[idx
]->name
= xstrdup (name
);
1528 opcode_array
[idx
]->opcode
= xstrdup (str
);
1529 opcode_array
[idx
]->lineno
= lineno
;
1530 *hash_slot
= opcode_array
[idx
];
1535 /* Append it to the existing one. */
1537 while ((*entry
) != NULL
)
1538 entry
= &(*entry
)->next
;
1539 *entry
= (struct opcode_hash_entry
*)
1540 xmalloc (sizeof (struct opcode_hash_entry
));
1541 (*entry
)->next
= NULL
;
1542 (*entry
)->name
= (*hash_slot
)->name
;
1543 (*entry
)->opcode
= xstrdup (str
);
1544 (*entry
)->lineno
= lineno
;
1547 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1548 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1551 const struct template *tmpl
;
1552 const struct template_instance
*inst
;
1555 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1556 remove_trailing_whitespaces (ptr1
);
1560 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1561 if (!strcmp(ptr1
, tmpl
->name
))
1564 fail ("reference to unknown template '%s'\n", ptr1
);
1566 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1568 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1569 char *str2
= xmalloc(2 * strlen(str
));
1572 strcpy (name2
, name
);
1573 strcat (name2
, inst
->name
);
1574 strcat (name2
, ptr2
);
1576 for (ptr1
= str2
, src
= str
; *src
; )
1578 const char *ident
= tmpl
->name
, *end
;
1579 const struct template_param
*param
;
1580 const struct template_arg
*arg
;
1582 if ((*ptr1
= *src
++) != '<')
1587 while (ISSPACE(*src
))
1589 while (*ident
&& *src
== *ident
)
1591 while (ISSPACE(*src
))
1593 if (*src
!= ':' || *ident
!= '\0')
1595 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1596 ptr1
+= ident
- tmpl
->name
;
1599 while (ISSPACE(*++src
))
1603 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1606 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1607 param
= param
->next
, arg
= arg
->next
)
1609 if (end
- src
== strlen (param
->name
)
1610 && !memcmp (src
, param
->name
, end
- src
))
1618 fail ("template '%s' has no parameter '%.*s'\n",
1619 tmpl
->name
, (int)(end
- src
), src
);
1621 while (ISSPACE(*src
))
1624 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1626 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1627 ptr1
+= strlen(arg
->val
);
1633 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1645 process_i386_opcodes (FILE *table
)
1650 char *str
, *p
, *last
, *name
;
1651 htab_t opcode_hash_table
;
1652 struct opcode_hash_entry
**opcode_array
= NULL
;
1653 int lineno
= 0, marker
= 0;
1655 filename
= "i386-opc.tbl";
1659 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1660 opcode_hash_eq
, NULL
,
1663 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1664 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1666 /* Put everything on opcode array. */
1669 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1674 p
= remove_leading_whitespaces (buf
);
1676 /* Skip comments. */
1677 str
= strstr (p
, "//");
1681 /* Remove trailing white spaces. */
1682 remove_trailing_whitespaces (p
);
1687 if (!strcmp("### MARKER ###", buf
))
1691 /* Since we ignore all included files (we only care about their
1692 #define-s here), we don't need to monitor filenames. The final
1693 line number directive is going to refer to the main source file
1698 p
= remove_leading_whitespaces (p
+ 1);
1699 if (!strncmp(p
, "line", 4))
1701 ln
= strtoul (p
, &end
, 10);
1702 if (ln
> 1 && ln
< INT_MAX
1703 && *remove_leading_whitespaces (end
) == '"')
1706 /* Ignore comments. */
1711 parse_template (p
, lineno
);
1719 last
= p
+ strlen (p
);
1722 name
= next_field (p
, ',', &str
, last
);
1724 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1728 /* Process opcode array. */
1729 for (j
= 0; j
< i
; j
++)
1731 struct opcode_hash_entry
*next
;
1733 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1737 lineno
= next
->lineno
;
1738 last
= str
+ strlen (str
);
1739 output_i386_opcode (table
, name
, str
, last
, lineno
);
1745 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1747 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1749 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1751 fprintf (table
, " { ");
1752 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1753 fprintf (table
, " } }\n");
1755 fprintf (table
, "};\n");
1759 process_i386_registers (FILE *table
)
1763 char *str
, *p
, *last
;
1764 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1765 char *dw2_32_num
, *dw2_64_num
;
1768 filename
= "i386-reg.tbl";
1769 fp
= fopen (filename
, "r");
1771 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1774 fprintf (table
, "\n/* i386 register table. */\n\n");
1775 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1779 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1784 p
= remove_leading_whitespaces (buf
);
1786 /* Skip comments. */
1787 str
= strstr (p
, "//");
1791 /* Remove trailing white spaces. */
1792 remove_trailing_whitespaces (p
);
1797 fprintf (table
, "%s\n", p
);
1805 last
= p
+ strlen (p
);
1807 /* Find reg_name. */
1808 reg_name
= next_field (p
, ',', &str
, last
);
1810 /* Find reg_type. */
1811 reg_type
= next_field (str
, ',', &str
, last
);
1813 /* Find reg_flags. */
1814 reg_flags
= next_field (str
, ',', &str
, last
);
1817 reg_num
= next_field (str
, ',', &str
, last
);
1819 fprintf (table
, " { \"%s\",\n ", reg_name
);
1821 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1824 /* Find 32-bit Dwarf2 register number. */
1825 dw2_32_num
= next_field (str
, ',', &str
, last
);
1827 /* Find 64-bit Dwarf2 register number. */
1828 dw2_64_num
= next_field (str
, ',', &str
, last
);
1830 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1831 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1836 fprintf (table
, "};\n");
1838 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1842 process_i386_initializers (void)
1845 FILE *fp
= fopen ("i386-init.h", "w");
1849 fail (_("can't create i386-init.h, errno = %s\n"),
1852 process_copyright (fp
);
1854 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1856 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1857 init
= xstrdup (cpu_flag_init
[i
].init
);
1858 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1862 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1864 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1865 init
= xstrdup (operand_type_init
[i
].init
);
1866 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1874 /* Program options. */
1875 #define OPTION_SRCDIR 200
1877 struct option long_options
[] =
1879 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1880 {"debug", no_argument
, NULL
, 'd'},
1881 {"version", no_argument
, NULL
, 'V'},
1882 {"help", no_argument
, NULL
, 'h'},
1883 {0, no_argument
, NULL
, 0}
1887 print_version (void)
1889 printf ("%s: version 1.0\n", program_name
);
1894 usage (FILE * stream
, int status
)
1896 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1902 main (int argc
, char **argv
)
1904 extern int chdir (char *);
1905 char *srcdir
= NULL
;
1907 unsigned int i
, cpumax
;
1910 program_name
= *argv
;
1911 xmalloc_set_program_name (program_name
);
1913 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1938 if (chdir (srcdir
) != 0)
1939 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1940 srcdir
, xstrerror (errno
));
1942 /* cpu_flags isn't sorted by position. */
1944 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1945 if (cpu_flags
[i
].position
> cpumax
)
1946 cpumax
= cpu_flags
[i
].position
;
1948 /* Check the unused bitfield in i386_cpu_flags. */
1950 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
1952 if ((cpumax
- 1) != CpuMax
)
1953 fail (_("CpuMax != %d!\n"), cpumax
);
1955 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
1957 if (cpumax
!= CpuMax
)
1958 fail (_("CpuMax != %d!\n"), cpumax
);
1960 c
= CpuNumOfBits
- CpuMax
- 1;
1962 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1965 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
1967 /* Check the unused bitfield in i386_operand_type. */
1969 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1972 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
1975 c
= OTNumOfBits
- OTNum
;
1977 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1980 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1983 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1984 sizeof (opcode_modifiers
[0]), compare
);
1986 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1987 sizeof (operand_types
[0]), compare
);
1989 table
= fopen ("i386-tbl.h", "w");
1991 fail (_("can't create i386-tbl.h, errno = %s\n"),
1994 process_copyright (table
);
1996 process_i386_opcodes (table
);
1997 process_i386_registers (table
);
1998 process_i386_initializers ();