1 /* Copyright (C) 2007-2014 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 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
57 "Cpu186|Cpu286|Cpu386" },
59 "Cpu186|Cpu286|Cpu386|Cpu486" },
61 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
63 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
67 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
69 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
71 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
73 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM|CpuCX16" },
75 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuCX16" },
77 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM|CpuCX16" },
79 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM|CpuCX16" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
83 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
87 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
91 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
95 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase" },
97 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd" },
99 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
100 { "CPU_BTVER2_FLAGS",
101 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuSSE4_1|CpuSSE4_2|CpuABM|CpuLM|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
109 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
110 { "CPU_CLFLUSH_FLAGS",
114 { "CPU_SYSCALL_FLAGS",
121 "CpuMMX|CpuSSE|CpuSSE2" },
123 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
125 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
126 { "CPU_SSE4_1_FLAGS",
127 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
128 { "CPU_SSE4_2_FLAGS",
129 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
130 { "CPU_ANY_SSE_FLAGS",
131 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
138 { "CPU_XSAVEOPT_FLAGS",
141 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
145 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
147 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
149 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
160 { "CPU_RDTSCP_FLAGS",
164 { "CPU_FSGSBASE_FLAGS",
178 { "CPU_INVPCID_FLAGS",
180 { "CPU_VMFUNC_FLAGS",
184 { "CPU_3DNOWA_FLAGS",
185 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
191 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
195 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
197 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
198 { "CPU_AVX512F_FLAGS",
199 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
200 { "CPU_AVX512CD_FLAGS",
201 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
202 { "CPU_AVX512ER_FLAGS",
203 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
204 { "CPU_AVX512PF_FLAGS",
205 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
206 { "CPU_ANY_AVX_FLAGS",
207 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
214 { "CPU_RDSEED_FLAGS",
216 { "CPU_PRFCHW_FLAGS",
224 { "CPU_CLFLUSHOPT_FLAGS",
226 { "CPU_XSAVES_FLAGS",
228 { "CPU_XSAVEC_FLAGS",
230 { "CPU_PREFETCHWT1_FLAGS",
234 { "CPU_AVX512VL_FLAGS",
235 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VL" },
238 static initializer operand_type_init
[] =
240 { "OPERAND_TYPE_NONE",
242 { "OPERAND_TYPE_REG8",
244 { "OPERAND_TYPE_REG16",
246 { "OPERAND_TYPE_REG32",
248 { "OPERAND_TYPE_REG64",
250 { "OPERAND_TYPE_IMM1",
252 { "OPERAND_TYPE_IMM8",
254 { "OPERAND_TYPE_IMM8S",
256 { "OPERAND_TYPE_IMM16",
258 { "OPERAND_TYPE_IMM32",
260 { "OPERAND_TYPE_IMM32S",
262 { "OPERAND_TYPE_IMM64",
264 { "OPERAND_TYPE_BASEINDEX",
266 { "OPERAND_TYPE_DISP8",
268 { "OPERAND_TYPE_DISP16",
270 { "OPERAND_TYPE_DISP32",
272 { "OPERAND_TYPE_DISP32S",
274 { "OPERAND_TYPE_DISP64",
276 { "OPERAND_TYPE_INOUTPORTREG",
278 { "OPERAND_TYPE_SHIFTCOUNT",
280 { "OPERAND_TYPE_CONTROL",
282 { "OPERAND_TYPE_TEST",
284 { "OPERAND_TYPE_DEBUG",
286 { "OPERAND_TYPE_FLOATREG",
288 { "OPERAND_TYPE_FLOATACC",
290 { "OPERAND_TYPE_SREG2",
292 { "OPERAND_TYPE_SREG3",
294 { "OPERAND_TYPE_ACC",
296 { "OPERAND_TYPE_JUMPABSOLUTE",
298 { "OPERAND_TYPE_REGMMX",
300 { "OPERAND_TYPE_REGXMM",
302 { "OPERAND_TYPE_REGYMM",
304 { "OPERAND_TYPE_REGZMM",
306 { "OPERAND_TYPE_REGMASK",
308 { "OPERAND_TYPE_ESSEG",
310 { "OPERAND_TYPE_ACC32",
312 { "OPERAND_TYPE_ACC64",
314 { "OPERAND_TYPE_INOUTPORTREG",
316 { "OPERAND_TYPE_REG16_INOUTPORTREG",
317 "Reg16|InOutPortReg" },
318 { "OPERAND_TYPE_DISP16_32",
320 { "OPERAND_TYPE_ANYDISP",
321 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
322 { "OPERAND_TYPE_IMM16_32",
324 { "OPERAND_TYPE_IMM16_32S",
326 { "OPERAND_TYPE_IMM16_32_32S",
327 "Imm16|Imm32|Imm32S" },
328 { "OPERAND_TYPE_IMM32_64",
330 { "OPERAND_TYPE_IMM32_32S_DISP32",
331 "Imm32|Imm32S|Disp32" },
332 { "OPERAND_TYPE_IMM64_DISP64",
334 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
335 "Imm32|Imm32S|Imm64|Disp32" },
336 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
337 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
338 { "OPERAND_TYPE_VEC_IMM4",
340 { "OPERAND_TYPE_REGBND",
342 { "OPERAND_TYPE_VEC_DISP8",
346 typedef struct bitfield
353 #define BITFIELD(n) { n, 0, #n }
355 static bitfield cpu_flags
[] =
363 BITFIELD (CpuClflush
),
365 BITFIELD (CpuSYSCALL
),
370 BITFIELD (CpuFISTTP
),
376 BITFIELD (CpuSSE4_1
),
377 BITFIELD (CpuSSE4_2
),
380 BITFIELD (CpuAVX512F
),
381 BITFIELD (CpuAVX512CD
),
382 BITFIELD (CpuAVX512ER
),
383 BITFIELD (CpuAVX512PF
),
384 BITFIELD (CpuAVX512VL
),
389 BITFIELD (Cpu3dnowA
),
390 BITFIELD (CpuPadLock
),
396 BITFIELD (CpuXsaveopt
),
398 BITFIELD (CpuPCLMUL
),
409 BITFIELD (CpuRdtscp
),
410 BITFIELD (CpuFSGSBase
),
417 BITFIELD (CpuINVPCID
),
418 BITFIELD (CpuVMFUNC
),
419 BITFIELD (CpuRDSEED
),
421 BITFIELD (CpuPRFCHW
),
425 BITFIELD (CpuClflushOpt
),
426 BITFIELD (CpuXSAVES
),
427 BITFIELD (CpuXSAVEC
),
428 BITFIELD (CpuPREFETCHWT1
),
434 BITFIELD (CpuUnused
),
438 static bitfield opcode_modifiers
[] =
444 BITFIELD (ShortForm
),
446 BITFIELD (JumpDword
),
448 BITFIELD (JumpInterSegment
),
455 BITFIELD (CheckRegSize
),
456 BITFIELD (IgnoreSize
),
457 BITFIELD (DefaultSize
),
466 BITFIELD (BNDPrefixOk
),
467 BITFIELD (IsLockable
),
468 BITFIELD (RegKludge
),
469 BITFIELD (FirstXmm0
),
470 BITFIELD (Implicit1stXmm0
),
471 BITFIELD (RepPrefixOk
),
472 BITFIELD (HLEPrefixOk
),
475 BITFIELD (AddrPrefixOp0
),
484 BITFIELD (VexOpcode
),
485 BITFIELD (VexSources
),
486 BITFIELD (VexImmExt
),
493 BITFIELD (Broadcast
),
494 BITFIELD (StaticRounding
),
496 BITFIELD (Disp8MemShift
),
497 BITFIELD (NoDefMask
),
499 BITFIELD (ATTMnemonic
),
500 BITFIELD (ATTSyntax
),
501 BITFIELD (IntelSyntax
),
504 static bitfield operand_types
[] =
523 BITFIELD (BaseIndex
),
529 BITFIELD (InOutPortReg
),
530 BITFIELD (ShiftCount
),
538 BITFIELD (JumpAbsolute
),
551 BITFIELD (Unspecified
),
555 BITFIELD (Vec_Disp8
),
561 static const char *filename
;
564 compare (const void *x
, const void *y
)
566 const bitfield
*xp
= (const bitfield
*) x
;
567 const bitfield
*yp
= (const bitfield
*) y
;
568 return xp
->position
- yp
->position
;
572 fail (const char *message
, ...)
576 va_start (args
, message
);
577 fprintf (stderr
, _("%s: Error: "), program_name
);
578 vfprintf (stderr
, message
, args
);
584 process_copyright (FILE *fp
)
586 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
587 /* Copyright (C) 2007-2014 Free Software Foundation, Inc.\n\
589 This file is part of the GNU opcodes library.\n\
591 This library is free software; you can redistribute it and/or modify\n\
592 it under the terms of the GNU General Public License as published by\n\
593 the Free Software Foundation; either version 3, or (at your option)\n\
594 any later version.\n\
596 It is distributed in the hope that it will be useful, but WITHOUT\n\
597 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
598 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
599 License for more details.\n\
601 You should have received a copy of the GNU General Public License\n\
602 along with this program; if not, write to the Free Software\n\
603 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
604 MA 02110-1301, USA. */\n");
607 /* Remove leading white spaces. */
610 remove_leading_whitespaces (char *str
)
612 while (ISSPACE (*str
))
617 /* Remove trailing white spaces. */
620 remove_trailing_whitespaces (char *str
)
622 size_t last
= strlen (str
);
630 if (ISSPACE (str
[last
]))
638 /* Find next field separated by SEP and terminate it. Return a
639 pointer to the one after it. */
642 next_field (char *str
, char sep
, char **next
, char *last
)
646 p
= remove_leading_whitespaces (str
);
647 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
650 remove_trailing_whitespaces (p
);
661 set_bitfield (const char *f
, bitfield
*array
, int value
,
662 unsigned int size
, int lineno
)
666 if (strcmp (f
, "CpuFP") == 0)
668 set_bitfield("Cpu387", array
, value
, size
, lineno
);
669 set_bitfield("Cpu287", array
, value
, size
, lineno
);
672 else if (strcmp (f
, "Mmword") == 0)
674 else if (strcmp (f
, "Oword") == 0)
677 for (i
= 0; i
< size
; i
++)
678 if (strcasecmp (array
[i
].name
, f
) == 0)
680 array
[i
].value
= value
;
686 const char *v
= strchr (f
, '=');
693 for (i
= 0; i
< size
; i
++)
694 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
696 value
= strtol (v
+ 1, &end
, 0);
699 array
[i
].value
= value
;
708 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
710 fail (_("Unknown bitfield: %s\n"), f
);
714 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
715 int macro
, const char *comma
, const char *indent
)
719 fprintf (table
, "%s{ { ", indent
);
721 for (i
= 0; i
< size
- 1; i
++)
723 if (((i
+ 1) % 20) != 0)
724 fprintf (table
, "%d, ", flags
[i
].value
);
726 fprintf (table
, "%d,", flags
[i
].value
);
727 if (((i
+ 1) % 20) == 0)
729 /* We need \\ for macro. */
731 fprintf (table
, " \\\n %s", indent
);
733 fprintf (table
, "\n %s", indent
);
737 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
741 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
742 const char *comma
, const char *indent
,
745 char *str
, *next
, *last
;
747 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
749 /* Copy the default cpu flags. */
750 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
752 if (strcasecmp (flag
, "unknown") == 0)
754 /* We turn on everything except for cpu64 in case of
755 CPU_UNKNOWN_FLAGS. */
756 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
757 if (flags
[i
].position
!= Cpu64
)
760 else if (flag
[0] == '~')
762 last
= flag
+ strlen (flag
);
769 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
776 /* First we turn on everything except for cpu64. */
777 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
778 if (flags
[i
].position
!= Cpu64
)
781 /* Turn off selective bits. */
782 for (; next
&& next
< last
; )
784 str
= next_field (next
, '|', &next
, last
);
786 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
789 else if (strcmp (flag
, "0"))
791 /* Turn on selective bits. */
792 last
= flag
+ strlen (flag
);
793 for (next
= flag
; next
&& next
< last
; )
795 str
= next_field (next
, '|', &next
, last
);
797 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
801 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
806 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
810 fprintf (table
, " { ");
812 for (i
= 0; i
< size
- 1; i
++)
814 if (((i
+ 1) % 20) != 0)
815 fprintf (table
, "%d, ", modifier
[i
].value
);
817 fprintf (table
, "%d,", modifier
[i
].value
);
818 if (((i
+ 1) % 20) == 0)
819 fprintf (table
, "\n ");
822 fprintf (table
, "%d },\n", modifier
[i
].value
);
826 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
828 char *str
, *next
, *last
;
829 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
831 /* Copy the default opcode modifier. */
832 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
834 if (strcmp (mod
, "0"))
836 last
= mod
+ strlen (mod
);
837 for (next
= mod
; next
&& next
< last
; )
839 str
= next_field (next
, '|', &next
, last
);
841 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
845 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
849 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
850 int macro
, const char *indent
)
854 fprintf (table
, "{ { ");
856 for (i
= 0; i
< size
- 1; i
++)
858 if (((i
+ 1) % 20) != 0)
859 fprintf (table
, "%d, ", types
[i
].value
);
861 fprintf (table
, "%d,", types
[i
].value
);
862 if (((i
+ 1) % 20) == 0)
864 /* We need \\ for macro. */
866 fprintf (table
, " \\\n%s", indent
);
868 fprintf (table
, "\n%s", indent
);
872 fprintf (table
, "%d } }", types
[i
].value
);
876 process_i386_operand_type (FILE *table
, char *op
, int macro
,
877 const char *indent
, int lineno
)
879 char *str
, *next
, *last
;
880 bitfield types
[ARRAY_SIZE (operand_types
)];
882 /* Copy the default operand type. */
883 memcpy (types
, operand_types
, sizeof (types
));
885 if (strcmp (op
, "0"))
887 last
= op
+ strlen (op
);
888 for (next
= op
; next
&& next
< last
; )
890 str
= next_field (next
, '|', &next
, last
);
892 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
895 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
900 output_i386_opcode (FILE *table
, const char *name
, char *str
,
901 char *last
, int lineno
)
904 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
905 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
907 /* Find number of operands. */
908 operands
= next_field (str
, ',', &str
, last
);
910 /* Find base_opcode. */
911 base_opcode
= next_field (str
, ',', &str
, last
);
913 /* Find extension_opcode. */
914 extension_opcode
= next_field (str
, ',', &str
, last
);
916 /* Find opcode_length. */
917 opcode_length
= next_field (str
, ',', &str
, last
);
919 /* Find cpu_flags. */
920 cpu_flags
= next_field (str
, ',', &str
, last
);
922 /* Find opcode_modifier. */
923 opcode_modifier
= next_field (str
, ',', &str
, last
);
925 /* Remove the first {. */
926 str
= remove_leading_whitespaces (str
);
929 str
= remove_leading_whitespaces (str
+ 1);
933 /* There are at least "X}". */
937 /* Remove trailing white spaces and }. */
941 if (ISSPACE (str
[i
]) || str
[i
] == '}')
950 /* Find operand_types. */
951 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
955 operand_types
[i
] = NULL
;
959 operand_types
[i
] = next_field (str
, ',', &str
, last
);
960 if (*operand_types
[i
] == '0')
963 operand_types
[i
] = NULL
;
968 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
969 name
, operands
, base_opcode
, extension_opcode
,
972 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
974 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
976 fprintf (table
, " { ");
978 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
980 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
983 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
988 fprintf (table
, ",\n ");
990 process_i386_operand_type (table
, operand_types
[i
], 0,
993 fprintf (table
, " } },\n");
996 struct opcode_hash_entry
998 struct opcode_hash_entry
*next
;
1004 /* Calculate the hash value of an opcode hash entry P. */
1007 opcode_hash_hash (const void *p
)
1009 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1010 return htab_hash_string (entry
->name
);
1013 /* Compare a string Q against an opcode hash entry P. */
1016 opcode_hash_eq (const void *p
, const void *q
)
1018 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1019 const char *name
= (const char *) q
;
1020 return strcmp (name
, entry
->name
) == 0;
1024 process_i386_opcodes (FILE *table
)
1029 char *str
, *p
, *last
, *name
;
1030 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1031 htab_t opcode_hash_table
;
1032 struct opcode_hash_entry
**opcode_array
;
1033 unsigned int opcode_array_size
= 1024;
1036 filename
= "i386-opc.tbl";
1037 fp
= fopen (filename
, "r");
1040 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1044 opcode_array
= (struct opcode_hash_entry
**)
1045 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1047 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1048 opcode_hash_eq
, NULL
,
1051 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1052 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1054 /* Put everything on opcode array. */
1057 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1062 p
= remove_leading_whitespaces (buf
);
1064 /* Skip comments. */
1065 str
= strstr (p
, "//");
1069 /* Remove trailing white spaces. */
1070 remove_trailing_whitespaces (p
);
1075 /* Ignore comments. */
1083 last
= p
+ strlen (p
);
1086 name
= next_field (p
, ',', &str
, last
);
1088 /* Get the slot in hash table. */
1089 hash_slot
= (struct opcode_hash_entry
**)
1090 htab_find_slot_with_hash (opcode_hash_table
, name
,
1091 htab_hash_string (name
),
1094 if (*hash_slot
== NULL
)
1096 /* It is the new one. Put it on opcode array. */
1097 if (i
>= opcode_array_size
)
1099 /* Grow the opcode array when needed. */
1100 opcode_array_size
+= 1024;
1101 opcode_array
= (struct opcode_hash_entry
**)
1102 xrealloc (opcode_array
,
1103 sizeof (*opcode_array
) * opcode_array_size
);
1106 opcode_array
[i
] = (struct opcode_hash_entry
*)
1107 xmalloc (sizeof (struct opcode_hash_entry
));
1108 opcode_array
[i
]->next
= NULL
;
1109 opcode_array
[i
]->name
= xstrdup (name
);
1110 opcode_array
[i
]->opcode
= xstrdup (str
);
1111 opcode_array
[i
]->lineno
= lineno
;
1112 *hash_slot
= opcode_array
[i
];
1117 /* Append it to the existing one. */
1119 while ((*entry
) != NULL
)
1120 entry
= &(*entry
)->next
;
1121 *entry
= (struct opcode_hash_entry
*)
1122 xmalloc (sizeof (struct opcode_hash_entry
));
1123 (*entry
)->next
= NULL
;
1124 (*entry
)->name
= (*hash_slot
)->name
;
1125 (*entry
)->opcode
= xstrdup (str
);
1126 (*entry
)->lineno
= lineno
;
1130 /* Process opcode array. */
1131 for (j
= 0; j
< i
; j
++)
1133 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1137 lineno
= next
->lineno
;
1138 last
= str
+ strlen (str
);
1139 output_i386_opcode (table
, name
, str
, last
, lineno
);
1145 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1147 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1149 process_i386_opcode_modifier (table
, "0", -1);
1151 fprintf (table
, " { ");
1152 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1153 fprintf (table
, " } }\n");
1155 fprintf (table
, "};\n");
1159 process_i386_registers (FILE *table
)
1163 char *str
, *p
, *last
;
1164 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1165 char *dw2_32_num
, *dw2_64_num
;
1168 filename
= "i386-reg.tbl";
1169 fp
= fopen (filename
, "r");
1171 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1174 fprintf (table
, "\n/* i386 register table. */\n\n");
1175 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1179 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1184 p
= remove_leading_whitespaces (buf
);
1186 /* Skip comments. */
1187 str
= strstr (p
, "//");
1191 /* Remove trailing white spaces. */
1192 remove_trailing_whitespaces (p
);
1197 fprintf (table
, "%s\n", p
);
1205 last
= p
+ strlen (p
);
1207 /* Find reg_name. */
1208 reg_name
= next_field (p
, ',', &str
, last
);
1210 /* Find reg_type. */
1211 reg_type
= next_field (str
, ',', &str
, last
);
1213 /* Find reg_flags. */
1214 reg_flags
= next_field (str
, ',', &str
, last
);
1217 reg_num
= next_field (str
, ',', &str
, last
);
1219 fprintf (table
, " { \"%s\",\n ", reg_name
);
1221 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1223 /* Find 32-bit Dwarf2 register number. */
1224 dw2_32_num
= next_field (str
, ',', &str
, last
);
1226 /* Find 64-bit Dwarf2 register number. */
1227 dw2_64_num
= next_field (str
, ',', &str
, last
);
1229 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1230 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1235 fprintf (table
, "};\n");
1237 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1241 process_i386_initializers (void)
1244 FILE *fp
= fopen ("i386-init.h", "w");
1248 fail (_("can't create i386-init.h, errno = %s\n"),
1251 process_copyright (fp
);
1253 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1255 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1256 init
= xstrdup (cpu_flag_init
[i
].init
);
1257 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1261 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1263 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1264 init
= xstrdup (operand_type_init
[i
].init
);
1265 process_i386_operand_type (fp
, init
, 1, " ", -1);
1273 /* Program options. */
1274 #define OPTION_SRCDIR 200
1276 struct option long_options
[] =
1278 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1279 {"debug", no_argument
, NULL
, 'd'},
1280 {"version", no_argument
, NULL
, 'V'},
1281 {"help", no_argument
, NULL
, 'h'},
1282 {0, no_argument
, NULL
, 0}
1286 print_version (void)
1288 printf ("%s: version 1.0\n", program_name
);
1293 usage (FILE * stream
, int status
)
1295 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1301 main (int argc
, char **argv
)
1303 extern int chdir (char *);
1304 char *srcdir
= NULL
;
1308 program_name
= *argv
;
1309 xmalloc_set_program_name (program_name
);
1311 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1336 if (chdir (srcdir
) != 0)
1337 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1338 srcdir
, xstrerror (errno
));
1340 /* Check the unused bitfield in i386_cpu_flags. */
1342 c
= CpuNumOfBits
- CpuMax
- 1;
1344 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1347 /* Check the unused bitfield in i386_operand_type. */
1349 c
= OTNumOfBits
- OTMax
- 1;
1351 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1354 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1357 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1358 sizeof (opcode_modifiers
[0]), compare
);
1360 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1361 sizeof (operand_types
[0]), compare
);
1363 table
= fopen ("i386-tbl.h", "w");
1365 fail (_("can't create i386-tbl.h, errno = %s\n"),
1368 process_copyright (table
);
1370 process_i386_opcodes (table
);
1371 process_i386_registers (table
);
1372 process_i386_initializers ();