1 /* Copyright (C) 2007-2018 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 static const char *program_name
= NULL
;
36 typedef struct initializer
42 static initializer cpu_flag_init
[] =
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
55 "CPU_I186_FLAGS|Cpu286" },
57 "CPU_I286_FLAGS|Cpu386" },
59 "CPU_I386_FLAGS|Cpu486" },
61 "CPU_I486_FLAGS|CPU_387_FLAGS|Cpu586" },
63 "CPU_I586_FLAGS|Cpu686|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "CPU_I686_FLAGS|CpuNop" },
67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
83 "CPU_K6_FLAGS|Cpu3dnow" },
85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuFMA4|CpuXOP|CpuLWP|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
99 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_BTVER1_FLAGS",
101 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
102 { "CPU_BTVER2_FLAGS",
103 "CPU_BTVER1_FLAGS|CPU_SSE4_2_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW" },
107 "CPU_8087_FLAGS|Cpu287" },
109 "CPU_287_FLAGS|Cpu387" },
111 "CPU_387_FLAGS|Cpu687" },
112 { "CPU_CLFLUSH_FLAGS",
116 { "CPU_SYSCALL_FLAGS",
119 "CpuRegMMX|CpuMMX" },
121 "CpuRegXMM|CpuSSE" },
123 "CPU_SSE_FLAGS|CpuSSE2" },
125 "CPU_SSE2_FLAGS|CpuSSE3" },
127 "CPU_SSE3_FLAGS|CpuSSSE3" },
128 { "CPU_SSE4_1_FLAGS",
129 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
130 { "CPU_SSE4_2_FLAGS",
131 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
138 { "CPU_XSAVEOPT_FLAGS",
139 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
141 "CPU_SSE2_FLAGS|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CPU_SSE2_FLAGS|CpuPCLMUL" },
145 "CPU_AVX_FLAGS|CpuFMA" },
147 "CPU_AVX_FLAGS|CpuFMA4" },
149 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
160 { "CPU_RDTSCP_FLAGS",
164 { "CPU_FSGSBASE_FLAGS",
169 "CPU_AVX_FLAGS|CpuF16C" },
178 { "CPU_INVPCID_FLAGS",
180 { "CPU_VMFUNC_FLAGS",
183 "CPU_MMX_FLAGS|Cpu3dnow" },
184 { "CPU_3DNOWA_FLAGS",
185 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
191 "CPU_SSE3_FLAGS|CpuSSE4a" },
195 "CPU_SSE4_2_FLAGS|CpuRegYMM|CpuAVX" },
197 "CPU_AVX_FLAGS|CpuAVX2" },
198 /* Don't use CPU_AVX2_FLAGS on CPU_AVX512F_FLAGS since AVX512F doesn't
199 support YMM registers. */
200 { "CPU_AVX512F_FLAGS",
201 "CpuVREX|CPU_SSE4_2_FLAGS|CpuRegZMM|CpuRegMask|CpuAVX|CpuAVX2|CpuAVX512F" },
202 { "CPU_AVX512CD_FLAGS",
203 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
204 { "CPU_AVX512ER_FLAGS",
205 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
206 { "CPU_AVX512PF_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
208 { "CPU_AVX512DQ_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
210 { "CPU_AVX512BW_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
212 { "CPU_AVX512VL_FLAGS",
213 /* Use CPU_AVX2_FLAGS on CPU_AVX512VL_FLAGS since AVX512VL supports YMM
215 "CPU_AVX512F_FLAGS|CPU_AVX2_FLAGS|CpuAVX512VL" },
216 { "CPU_AVX512IFMA_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
218 { "CPU_AVX512VBMI_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
220 { "CPU_AVX512_4FMAPS_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
222 { "CPU_AVX512_4VNNIW_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
224 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
226 { "CPU_AVX512_VBMI2_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
228 { "CPU_AVX512_VNNI_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
230 { "CPU_AVX512_BITALG_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
237 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
240 { "CPU_RDSEED_FLAGS",
242 { "CPU_PRFCHW_FLAGS",
249 "CPU_SSE2_FLAGS|CpuSHA" },
250 { "CPU_CLFLUSHOPT_FLAGS",
252 { "CPU_XSAVES_FLAGS",
253 "CPU_XSAVE_FLAGS|CpuXSAVES" },
254 { "CPU_XSAVEC_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
256 { "CPU_PREFETCHWT1_FLAGS",
262 { "CPU_CLZERO_FLAGS",
264 { "CPU_MWAITX_FLAGS",
270 { "CPU_PTWRITE_FLAGS",
280 { "CPU_VPCLMULQDQ_FLAGS",
282 { "CPU_WBNOINVD_FLAGS",
284 { "CPU_ANY_X87_FLAGS",
285 "CPU_ANY_287_FLAGS|Cpu8087" },
286 { "CPU_ANY_287_FLAGS",
287 "CPU_ANY_387_FLAGS|Cpu287" },
288 { "CPU_ANY_387_FLAGS",
289 "CPU_ANY_687_FLAGS|Cpu387" },
290 { "CPU_ANY_687_FLAGS",
291 "Cpu687|CpuFISTTP" },
292 { "CPU_ANY_MMX_FLAGS",
293 "CPU_3DNOWA_FLAGS" },
294 { "CPU_ANY_SSE_FLAGS",
295 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
296 { "CPU_ANY_SSE2_FLAGS",
297 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
298 { "CPU_ANY_SSE3_FLAGS",
299 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
300 { "CPU_ANY_SSSE3_FLAGS",
301 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
302 { "CPU_ANY_SSE4_1_FLAGS",
303 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
304 { "CPU_ANY_SSE4_2_FLAGS",
306 { "CPU_ANY_AVX_FLAGS",
307 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
308 { "CPU_ANY_AVX2_FLAGS",
310 { "CPU_ANY_AVX512F_FLAGS",
311 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
312 { "CPU_ANY_AVX512CD_FLAGS",
314 { "CPU_ANY_AVX512ER_FLAGS",
316 { "CPU_ANY_AVX512PF_FLAGS",
318 { "CPU_ANY_AVX512DQ_FLAGS",
320 { "CPU_ANY_AVX512BW_FLAGS",
322 { "CPU_ANY_AVX512VL_FLAGS",
324 { "CPU_ANY_AVX512IFMA_FLAGS",
326 { "CPU_ANY_AVX512VBMI_FLAGS",
328 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
329 "CpuAVX512_4FMAPS" },
330 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
331 "CpuAVX512_4VNNIW" },
332 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
333 "CpuAVX512_VPOPCNTDQ" },
334 { "CPU_ANY_IBT_FLAGS",
336 { "CPU_ANY_SHSTK_FLAGS",
338 { "CPU_ANY_AVX512_VBMI2_FLAGS",
340 { "CPU_ANY_AVX512_VNNI_FLAGS",
342 { "CPU_ANY_AVX512_BITALG_FLAGS",
343 "CpuAVX512_BITALG" },
346 static const initializer operand_type_shorthands
[] =
348 { "Reg8", "Reg|Byte" },
349 { "Reg16", "Reg|Word" },
350 { "Reg32", "Reg|Dword" },
351 { "Reg64", "Reg|Qword" },
352 { "FloatAcc", "Acc|Tbyte" },
353 { "FloatReg", "Reg|Tbyte" },
354 { "RegXMM", "RegSIMD|Xmmword" },
355 { "RegYMM", "RegSIMD|Ymmword" },
356 { "RegZMM", "RegSIMD|Zmmword" },
359 static initializer operand_type_init
[] =
361 { "OPERAND_TYPE_NONE",
363 { "OPERAND_TYPE_REG8",
365 { "OPERAND_TYPE_REG16",
367 { "OPERAND_TYPE_REG32",
369 { "OPERAND_TYPE_REG64",
371 { "OPERAND_TYPE_IMM1",
373 { "OPERAND_TYPE_IMM8",
375 { "OPERAND_TYPE_IMM8S",
377 { "OPERAND_TYPE_IMM16",
379 { "OPERAND_TYPE_IMM32",
381 { "OPERAND_TYPE_IMM32S",
383 { "OPERAND_TYPE_IMM64",
385 { "OPERAND_TYPE_BASEINDEX",
387 { "OPERAND_TYPE_DISP8",
389 { "OPERAND_TYPE_DISP16",
391 { "OPERAND_TYPE_DISP32",
393 { "OPERAND_TYPE_DISP32S",
395 { "OPERAND_TYPE_DISP64",
397 { "OPERAND_TYPE_INOUTPORTREG",
399 { "OPERAND_TYPE_SHIFTCOUNT",
401 { "OPERAND_TYPE_CONTROL",
403 { "OPERAND_TYPE_TEST",
405 { "OPERAND_TYPE_DEBUG",
407 { "OPERAND_TYPE_FLOATREG",
409 { "OPERAND_TYPE_FLOATACC",
411 { "OPERAND_TYPE_SREG2",
413 { "OPERAND_TYPE_SREG3",
415 { "OPERAND_TYPE_ACC",
417 { "OPERAND_TYPE_JUMPABSOLUTE",
419 { "OPERAND_TYPE_REGMMX",
421 { "OPERAND_TYPE_REGXMM",
423 { "OPERAND_TYPE_REGYMM",
425 { "OPERAND_TYPE_REGZMM",
427 { "OPERAND_TYPE_REGMASK",
429 { "OPERAND_TYPE_ESSEG",
431 { "OPERAND_TYPE_ACC32",
433 { "OPERAND_TYPE_ACC64",
435 { "OPERAND_TYPE_INOUTPORTREG",
437 { "OPERAND_TYPE_REG16_INOUTPORTREG",
438 "Reg16|InOutPortReg" },
439 { "OPERAND_TYPE_DISP16_32",
441 { "OPERAND_TYPE_ANYDISP",
442 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
443 { "OPERAND_TYPE_IMM16_32",
445 { "OPERAND_TYPE_IMM16_32S",
447 { "OPERAND_TYPE_IMM16_32_32S",
448 "Imm16|Imm32|Imm32S" },
449 { "OPERAND_TYPE_IMM32_64",
451 { "OPERAND_TYPE_IMM32_32S_DISP32",
452 "Imm32|Imm32S|Disp32" },
453 { "OPERAND_TYPE_IMM64_DISP64",
455 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
456 "Imm32|Imm32S|Imm64|Disp32" },
457 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
458 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
459 { "OPERAND_TYPE_VEC_IMM4",
461 { "OPERAND_TYPE_REGBND",
465 typedef struct bitfield
472 #define BITFIELD(n) { n, 0, #n }
474 static bitfield cpu_flags
[] =
482 BITFIELD (CpuClflush
),
484 BITFIELD (CpuSYSCALL
),
489 BITFIELD (CpuFISTTP
),
495 BITFIELD (CpuSSE4_1
),
496 BITFIELD (CpuSSE4_2
),
499 BITFIELD (CpuAVX512F
),
500 BITFIELD (CpuAVX512CD
),
501 BITFIELD (CpuAVX512ER
),
502 BITFIELD (CpuAVX512PF
),
503 BITFIELD (CpuAVX512VL
),
504 BITFIELD (CpuAVX512DQ
),
505 BITFIELD (CpuAVX512BW
),
511 BITFIELD (Cpu3dnowA
),
512 BITFIELD (CpuPadLock
),
518 BITFIELD (CpuXsaveopt
),
520 BITFIELD (CpuPCLMUL
),
531 BITFIELD (CpuRdtscp
),
532 BITFIELD (CpuFSGSBase
),
539 BITFIELD (CpuINVPCID
),
540 BITFIELD (CpuVMFUNC
),
541 BITFIELD (CpuRDSEED
),
543 BITFIELD (CpuPRFCHW
),
547 BITFIELD (CpuClflushOpt
),
548 BITFIELD (CpuXSAVES
),
549 BITFIELD (CpuXSAVEC
),
550 BITFIELD (CpuPREFETCHWT1
),
556 BITFIELD (CpuAVX512IFMA
),
557 BITFIELD (CpuAVX512VBMI
),
558 BITFIELD (CpuAVX512_4FMAPS
),
559 BITFIELD (CpuAVX512_4VNNIW
),
560 BITFIELD (CpuAVX512_VPOPCNTDQ
),
561 BITFIELD (CpuAVX512_VBMI2
),
562 BITFIELD (CpuAVX512_VNNI
),
563 BITFIELD (CpuAVX512_BITALG
),
564 BITFIELD (CpuMWAITX
),
565 BITFIELD (CpuCLZERO
),
568 BITFIELD (CpuPTWRITE
),
573 BITFIELD (CpuVPCLMULQDQ
),
574 BITFIELD (CpuWBNOINVD
),
575 BITFIELD (CpuRegMMX
),
576 BITFIELD (CpuRegXMM
),
577 BITFIELD (CpuRegYMM
),
578 BITFIELD (CpuRegZMM
),
579 BITFIELD (CpuRegMask
),
581 BITFIELD (CpuUnused
),
585 static bitfield opcode_modifiers
[] =
591 BITFIELD (ShortForm
),
593 BITFIELD (JumpDword
),
595 BITFIELD (JumpInterSegment
),
602 BITFIELD (CheckRegSize
),
603 BITFIELD (IgnoreSize
),
604 BITFIELD (DefaultSize
),
613 BITFIELD (BNDPrefixOk
),
614 BITFIELD (NoTrackPrefixOk
),
615 BITFIELD (IsLockable
),
616 BITFIELD (RegKludge
),
617 BITFIELD (Implicit1stXmm0
),
618 BITFIELD (RepPrefixOk
),
619 BITFIELD (HLEPrefixOk
),
622 BITFIELD (AddrPrefixOp0
),
631 BITFIELD (VexOpcode
),
632 BITFIELD (VexSources
),
633 BITFIELD (VexImmExt
),
640 BITFIELD (Broadcast
),
641 BITFIELD (StaticRounding
),
643 BITFIELD (Disp8MemShift
),
644 BITFIELD (NoDefMask
),
645 BITFIELD (ImplicitQuadGroup
),
647 BITFIELD (ATTMnemonic
),
648 BITFIELD (ATTSyntax
),
649 BITFIELD (IntelSyntax
),
654 static bitfield operand_types
[] =
667 BITFIELD (BaseIndex
),
673 BITFIELD (InOutPortReg
),
674 BITFIELD (ShiftCount
),
681 BITFIELD (JumpAbsolute
),
694 BITFIELD (Unspecified
),
703 static const char *filename
;
704 static i386_cpu_flags active_cpu_flags
;
705 static int active_isstring
;
708 compare (const void *x
, const void *y
)
710 const bitfield
*xp
= (const bitfield
*) x
;
711 const bitfield
*yp
= (const bitfield
*) y
;
712 return xp
->position
- yp
->position
;
716 fail (const char *message
, ...)
720 va_start (args
, message
);
721 fprintf (stderr
, _("%s: Error: "), program_name
);
722 vfprintf (stderr
, message
, args
);
728 process_copyright (FILE *fp
)
730 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
731 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
733 This file is part of the GNU opcodes library.\n\
735 This library is free software; you can redistribute it and/or modify\n\
736 it under the terms of the GNU General Public License as published by\n\
737 the Free Software Foundation; either version 3, or (at your option)\n\
738 any later version.\n\
740 It is distributed in the hope that it will be useful, but WITHOUT\n\
741 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
742 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
743 License for more details.\n\
745 You should have received a copy of the GNU General Public License\n\
746 along with this program; if not, write to the Free Software\n\
747 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
748 MA 02110-1301, USA. */\n");
751 /* Remove leading white spaces. */
754 remove_leading_whitespaces (char *str
)
756 while (ISSPACE (*str
))
761 /* Remove trailing white spaces. */
764 remove_trailing_whitespaces (char *str
)
766 size_t last
= strlen (str
);
774 if (ISSPACE (str
[last
]))
782 /* Find next field separated by SEP and terminate it. Return a
783 pointer to the one after it. */
786 next_field (char *str
, char sep
, char **next
, char *last
)
790 p
= remove_leading_whitespaces (str
);
791 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
794 remove_trailing_whitespaces (p
);
804 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
807 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
810 char *str
, *next
, *last
;
813 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
814 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
816 /* Turn on selective bits. */
817 char *init
= xstrdup (cpu_flag_init
[i
].init
);
818 last
= init
+ strlen (init
);
819 for (next
= init
; next
&& next
< last
; )
821 str
= next_field (next
, '|', &next
, last
);
823 set_bitfield (str
, array
, 1, size
, lineno
);
829 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
830 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
832 /* Turn on selective bits. */
833 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
834 last
= init
+ strlen (init
);
835 for (next
= init
; next
&& next
< last
; )
837 str
= next_field (next
, '|', &next
, last
);
839 set_bitfield (str
, array
, 1, size
, lineno
);
849 set_bitfield (char *f
, bitfield
*array
, int value
,
850 unsigned int size
, int lineno
)
854 if (strcmp (f
, "CpuFP") == 0)
856 set_bitfield("Cpu387", array
, value
, size
, lineno
);
857 set_bitfield("Cpu287", array
, value
, size
, lineno
);
860 else if (strcmp (f
, "Mmword") == 0)
862 else if (strcmp (f
, "Oword") == 0)
865 for (i
= 0; i
< size
; i
++)
866 if (strcasecmp (array
[i
].name
, f
) == 0)
868 array
[i
].value
= value
;
874 const char *v
= strchr (f
, '=');
881 for (i
= 0; i
< size
; i
++)
882 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
884 value
= strtol (v
+ 1, &end
, 0);
887 array
[i
].value
= value
;
895 /* Handle shorthands. */
896 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
900 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
902 fail (_("Unknown bitfield: %s\n"), f
);
906 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
907 int macro
, const char *comma
, const char *indent
)
911 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
913 fprintf (table
, "%s{ { ", indent
);
915 for (i
= 0; i
< size
- 1; i
++)
917 if (((i
+ 1) % 20) != 0)
918 fprintf (table
, "%d, ", flags
[i
].value
);
920 fprintf (table
, "%d,", flags
[i
].value
);
921 if (((i
+ 1) % 20) == 0)
923 /* We need \\ for macro. */
925 fprintf (table
, " \\\n %s", indent
);
927 fprintf (table
, "\n %s", indent
);
930 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
933 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
937 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
938 const char *comma
, const char *indent
,
941 char *str
, *next
, *last
;
943 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
945 /* Copy the default cpu flags. */
946 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
948 if (strcasecmp (flag
, "unknown") == 0)
950 /* We turn on everything except for cpu64 in case of
951 CPU_UNKNOWN_FLAGS. */
952 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
953 if (flags
[i
].position
!= Cpu64
)
956 else if (flag
[0] == '~')
958 last
= flag
+ strlen (flag
);
965 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
972 /* First we turn on everything except for cpu64. */
973 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
974 if (flags
[i
].position
!= Cpu64
)
977 /* Turn off selective bits. */
978 for (; next
&& next
< last
; )
980 str
= next_field (next
, '|', &next
, last
);
982 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
985 else if (strcmp (flag
, "0"))
987 /* Turn on selective bits. */
988 last
= flag
+ strlen (flag
);
989 for (next
= flag
; next
&& next
< last
; )
991 str
= next_field (next
, '|', &next
, last
);
993 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
997 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1002 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1006 fprintf (table
, " { ");
1008 for (i
= 0; i
< size
- 1; i
++)
1010 if (((i
+ 1) % 20) != 0)
1011 fprintf (table
, "%d, ", modifier
[i
].value
);
1013 fprintf (table
, "%d,", modifier
[i
].value
);
1014 if (((i
+ 1) % 20) == 0)
1015 fprintf (table
, "\n ");
1018 fprintf (table
, "%d },\n", modifier
[i
].value
);
1022 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
1024 char *str
, *next
, *last
;
1025 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1027 active_isstring
= 0;
1029 /* Copy the default opcode modifier. */
1030 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1032 if (strcmp (mod
, "0"))
1034 last
= mod
+ strlen (mod
);
1035 for (next
= mod
; next
&& next
< last
; )
1037 str
= next_field (next
, '|', &next
, last
);
1040 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1042 if (strcasecmp(str
, "IsString") == 0)
1043 active_isstring
= 1;
1047 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1057 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1058 enum stage stage
, const char *indent
)
1062 fprintf (table
, "{ { ");
1064 for (i
= 0; i
< size
- 1; i
++)
1066 if (((i
+ 1) % 20) != 0)
1067 fprintf (table
, "%d, ", types
[i
].value
);
1069 fprintf (table
, "%d,", types
[i
].value
);
1070 if (((i
+ 1) % 20) == 0)
1072 /* We need \\ for macro. */
1073 if (stage
== stage_macros
)
1074 fprintf (table
, " \\\n%s", indent
);
1076 fprintf (table
, "\n%s", indent
);
1080 fprintf (table
, "%d } }", types
[i
].value
);
1084 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1085 const char *indent
, int lineno
)
1087 char *str
, *next
, *last
;
1088 bitfield types
[ARRAY_SIZE (operand_types
)];
1090 /* Copy the default operand type. */
1091 memcpy (types
, operand_types
, sizeof (types
));
1093 if (strcmp (op
, "0"))
1097 last
= op
+ strlen (op
);
1098 for (next
= op
; next
&& next
< last
; )
1100 str
= next_field (next
, '|', &next
, last
);
1103 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1104 if (strcasecmp(str
, "BaseIndex") == 0)
1109 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1111 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1112 if (!active_cpu_flags
.bitfield
.cpu64
1113 && !active_cpu_flags
.bitfield
.cpumpx
)
1114 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1115 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1116 if (!active_cpu_flags
.bitfield
.cpuno64
)
1117 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1120 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1125 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1126 char *last
, int lineno
)
1129 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1130 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1132 /* Find number of operands. */
1133 operands
= next_field (str
, ',', &str
, last
);
1135 /* Find base_opcode. */
1136 base_opcode
= next_field (str
, ',', &str
, last
);
1138 /* Find extension_opcode. */
1139 extension_opcode
= next_field (str
, ',', &str
, last
);
1141 /* Find opcode_length. */
1142 opcode_length
= next_field (str
, ',', &str
, last
);
1144 /* Find cpu_flags. */
1145 cpu_flags
= next_field (str
, ',', &str
, last
);
1147 /* Find opcode_modifier. */
1148 opcode_modifier
= next_field (str
, ',', &str
, last
);
1150 /* Remove the first {. */
1151 str
= remove_leading_whitespaces (str
);
1154 str
= remove_leading_whitespaces (str
+ 1);
1158 /* There are at least "X}". */
1162 /* Remove trailing white spaces and }. */
1166 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1175 /* Find operand_types. */
1176 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1180 operand_types
[i
] = NULL
;
1184 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1185 if (*operand_types
[i
] == '0')
1188 operand_types
[i
] = NULL
;
1193 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1194 name
, operands
, base_opcode
, extension_opcode
,
1197 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1199 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1201 fprintf (table
, " { ");
1203 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1205 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1208 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1214 fprintf (table
, ",\n ");
1216 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1219 fprintf (table
, " } },\n");
1222 struct opcode_hash_entry
1224 struct opcode_hash_entry
*next
;
1230 /* Calculate the hash value of an opcode hash entry P. */
1233 opcode_hash_hash (const void *p
)
1235 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1236 return htab_hash_string (entry
->name
);
1239 /* Compare a string Q against an opcode hash entry P. */
1242 opcode_hash_eq (const void *p
, const void *q
)
1244 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1245 const char *name
= (const char *) q
;
1246 return strcmp (name
, entry
->name
) == 0;
1250 process_i386_opcodes (FILE *table
)
1255 char *str
, *p
, *last
, *name
;
1256 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1257 htab_t opcode_hash_table
;
1258 struct opcode_hash_entry
**opcode_array
;
1259 unsigned int opcode_array_size
= 1024;
1262 filename
= "i386-opc.tbl";
1263 fp
= fopen (filename
, "r");
1266 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1270 opcode_array
= (struct opcode_hash_entry
**)
1271 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1273 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1274 opcode_hash_eq
, NULL
,
1277 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1278 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1280 /* Put everything on opcode array. */
1283 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1288 p
= remove_leading_whitespaces (buf
);
1290 /* Skip comments. */
1291 str
= strstr (p
, "//");
1295 /* Remove trailing white spaces. */
1296 remove_trailing_whitespaces (p
);
1301 /* Ignore comments. */
1309 last
= p
+ strlen (p
);
1312 name
= next_field (p
, ',', &str
, last
);
1314 /* Get the slot in hash table. */
1315 hash_slot
= (struct opcode_hash_entry
**)
1316 htab_find_slot_with_hash (opcode_hash_table
, name
,
1317 htab_hash_string (name
),
1320 if (*hash_slot
== NULL
)
1322 /* It is the new one. Put it on opcode array. */
1323 if (i
>= opcode_array_size
)
1325 /* Grow the opcode array when needed. */
1326 opcode_array_size
+= 1024;
1327 opcode_array
= (struct opcode_hash_entry
**)
1328 xrealloc (opcode_array
,
1329 sizeof (*opcode_array
) * opcode_array_size
);
1332 opcode_array
[i
] = (struct opcode_hash_entry
*)
1333 xmalloc (sizeof (struct opcode_hash_entry
));
1334 opcode_array
[i
]->next
= NULL
;
1335 opcode_array
[i
]->name
= xstrdup (name
);
1336 opcode_array
[i
]->opcode
= xstrdup (str
);
1337 opcode_array
[i
]->lineno
= lineno
;
1338 *hash_slot
= opcode_array
[i
];
1343 /* Append it to the existing one. */
1345 while ((*entry
) != NULL
)
1346 entry
= &(*entry
)->next
;
1347 *entry
= (struct opcode_hash_entry
*)
1348 xmalloc (sizeof (struct opcode_hash_entry
));
1349 (*entry
)->next
= NULL
;
1350 (*entry
)->name
= (*hash_slot
)->name
;
1351 (*entry
)->opcode
= xstrdup (str
);
1352 (*entry
)->lineno
= lineno
;
1356 /* Process opcode array. */
1357 for (j
= 0; j
< i
; j
++)
1359 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1363 lineno
= next
->lineno
;
1364 last
= str
+ strlen (str
);
1365 output_i386_opcode (table
, name
, str
, last
, lineno
);
1371 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1373 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1375 process_i386_opcode_modifier (table
, "0", -1);
1377 fprintf (table
, " { ");
1378 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1379 fprintf (table
, " } }\n");
1381 fprintf (table
, "};\n");
1385 process_i386_registers (FILE *table
)
1389 char *str
, *p
, *last
;
1390 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1391 char *dw2_32_num
, *dw2_64_num
;
1394 filename
= "i386-reg.tbl";
1395 fp
= fopen (filename
, "r");
1397 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1400 fprintf (table
, "\n/* i386 register table. */\n\n");
1401 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1405 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1410 p
= remove_leading_whitespaces (buf
);
1412 /* Skip comments. */
1413 str
= strstr (p
, "//");
1417 /* Remove trailing white spaces. */
1418 remove_trailing_whitespaces (p
);
1423 fprintf (table
, "%s\n", p
);
1431 last
= p
+ strlen (p
);
1433 /* Find reg_name. */
1434 reg_name
= next_field (p
, ',', &str
, last
);
1436 /* Find reg_type. */
1437 reg_type
= next_field (str
, ',', &str
, last
);
1439 /* Find reg_flags. */
1440 reg_flags
= next_field (str
, ',', &str
, last
);
1443 reg_num
= next_field (str
, ',', &str
, last
);
1445 fprintf (table
, " { \"%s\",\n ", reg_name
);
1447 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1450 /* Find 32-bit Dwarf2 register number. */
1451 dw2_32_num
= next_field (str
, ',', &str
, last
);
1453 /* Find 64-bit Dwarf2 register number. */
1454 dw2_64_num
= next_field (str
, ',', &str
, last
);
1456 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1457 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1462 fprintf (table
, "};\n");
1464 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1468 process_i386_initializers (void)
1471 FILE *fp
= fopen ("i386-init.h", "w");
1475 fail (_("can't create i386-init.h, errno = %s\n"),
1478 process_copyright (fp
);
1480 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1482 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1483 init
= xstrdup (cpu_flag_init
[i
].init
);
1484 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1488 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1490 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1491 init
= xstrdup (operand_type_init
[i
].init
);
1492 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1500 /* Program options. */
1501 #define OPTION_SRCDIR 200
1503 struct option long_options
[] =
1505 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1506 {"debug", no_argument
, NULL
, 'd'},
1507 {"version", no_argument
, NULL
, 'V'},
1508 {"help", no_argument
, NULL
, 'h'},
1509 {0, no_argument
, NULL
, 0}
1513 print_version (void)
1515 printf ("%s: version 1.0\n", program_name
);
1520 usage (FILE * stream
, int status
)
1522 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1528 main (int argc
, char **argv
)
1530 extern int chdir (char *);
1531 char *srcdir
= NULL
;
1533 unsigned int i
, cpumax
;
1536 program_name
= *argv
;
1537 xmalloc_set_program_name (program_name
);
1539 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1564 if (chdir (srcdir
) != 0)
1565 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1566 srcdir
, xstrerror (errno
));
1568 /* cpu_flags isn't sorted by position. */
1570 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1571 if (cpu_flags
[i
].position
> cpumax
)
1572 cpumax
= cpu_flags
[i
].position
;
1574 /* Check the unused bitfield in i386_cpu_flags. */
1576 if ((cpumax
- 1) != CpuMax
)
1577 fail (_("CpuMax != %d!\n"), cpumax
);
1579 if (cpumax
!= CpuMax
)
1580 fail (_("CpuMax != %d!\n"), cpumax
);
1582 c
= CpuNumOfBits
- CpuMax
- 1;
1584 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1587 /* Check the unused bitfield in i386_operand_type. */
1589 c
= OTNumOfBits
- OTMax
- 1;
1591 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1594 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1597 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1598 sizeof (opcode_modifiers
[0]), compare
);
1600 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1601 sizeof (operand_types
[0]), compare
);
1603 table
= fopen ("i386-tbl.h", "w");
1605 fail (_("can't create i386-tbl.h, errno = %s\n"),
1608 process_copyright (table
);
1610 process_i386_opcodes (table
);
1611 process_i386_registers (table
);
1612 process_i386_initializers ();