2 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
25 #include "libiberty.h"
27 #include "safe-ctype.h"
32 #define _(String) gettext (String)
34 static const char *program_name
= NULL
;
37 typedef struct initializer
43 static initializer cpu_flag_init
[] =
45 { "CPU_UNKNOWN_FLAGS",
46 "~(CpuL1OM|CpuK1OM)" },
47 { "CPU_GENERIC32_FLAGS",
48 "Cpu186|Cpu286|Cpu386" },
49 { "CPU_GENERIC64_FLAGS",
50 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
58 "Cpu186|Cpu286|Cpu386" },
60 "Cpu186|Cpu286|Cpu386|Cpu486" },
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
65 { "CPU_PENTIUMPRO_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM|CpuCX16" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuCX16" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM|CpuCX16" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM|CpuCX16" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
89 { "CPU_AMDFAM10_FLAGS",
90 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
92 "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" },
94 "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" },
96 "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" },
98 "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" },
100 "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" },
101 { "CPU_BTVER2_FLAGS",
102 "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" },
110 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
111 { "CPU_CLFLUSH_FLAGS",
115 { "CPU_SYSCALL_FLAGS",
122 "CpuMMX|CpuSSE|CpuSSE2" },
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
127 { "CPU_SSE4_1_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
129 { "CPU_SSE4_2_FLAGS",
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
131 { "CPU_ANY_SSE_FLAGS",
132 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
139 { "CPU_XSAVEOPT_FLAGS",
142 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
143 { "CPU_PCLMUL_FLAGS",
144 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
148 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
161 { "CPU_RDTSCP_FLAGS",
165 { "CPU_FSGSBASE_FLAGS",
179 { "CPU_INVPCID_FLAGS",
181 { "CPU_VMFUNC_FLAGS",
185 { "CPU_3DNOWA_FLAGS",
186 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
187 { "CPU_PADLOCK_FLAGS",
192 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
196 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
198 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
199 { "CPU_AVX512F_FLAGS",
200 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
201 { "CPU_AVX512CD_FLAGS",
202 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
203 { "CPU_AVX512ER_FLAGS",
204 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
205 { "CPU_AVX512PF_FLAGS",
206 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
207 { "CPU_ANY_AVX_FLAGS",
208 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
215 { "CPU_RDSEED_FLAGS",
217 { "CPU_PRFCHW_FLAGS",
225 { "CPU_CLFLUSHOPT_FLAGS",
227 { "CPU_XSAVES_FLAGS",
229 { "CPU_XSAVEC_FLAGS",
231 { "CPU_PREFETCHWT1_FLAGS",
235 static initializer operand_type_init
[] =
237 { "OPERAND_TYPE_NONE",
239 { "OPERAND_TYPE_REG8",
241 { "OPERAND_TYPE_REG16",
243 { "OPERAND_TYPE_REG32",
245 { "OPERAND_TYPE_REG64",
247 { "OPERAND_TYPE_IMM1",
249 { "OPERAND_TYPE_IMM8",
251 { "OPERAND_TYPE_IMM8S",
253 { "OPERAND_TYPE_IMM16",
255 { "OPERAND_TYPE_IMM32",
257 { "OPERAND_TYPE_IMM32S",
259 { "OPERAND_TYPE_IMM64",
261 { "OPERAND_TYPE_BASEINDEX",
263 { "OPERAND_TYPE_DISP8",
265 { "OPERAND_TYPE_DISP16",
267 { "OPERAND_TYPE_DISP32",
269 { "OPERAND_TYPE_DISP32S",
271 { "OPERAND_TYPE_DISP64",
273 { "OPERAND_TYPE_INOUTPORTREG",
275 { "OPERAND_TYPE_SHIFTCOUNT",
277 { "OPERAND_TYPE_CONTROL",
279 { "OPERAND_TYPE_TEST",
281 { "OPERAND_TYPE_DEBUG",
283 { "OPERAND_TYPE_FLOATREG",
285 { "OPERAND_TYPE_FLOATACC",
287 { "OPERAND_TYPE_SREG2",
289 { "OPERAND_TYPE_SREG3",
291 { "OPERAND_TYPE_ACC",
293 { "OPERAND_TYPE_JUMPABSOLUTE",
295 { "OPERAND_TYPE_REGMMX",
297 { "OPERAND_TYPE_REGXMM",
299 { "OPERAND_TYPE_REGYMM",
301 { "OPERAND_TYPE_REGZMM",
303 { "OPERAND_TYPE_REGMASK",
305 { "OPERAND_TYPE_ESSEG",
307 { "OPERAND_TYPE_ACC32",
309 { "OPERAND_TYPE_ACC64",
311 { "OPERAND_TYPE_INOUTPORTREG",
313 { "OPERAND_TYPE_REG16_INOUTPORTREG",
314 "Reg16|InOutPortReg" },
315 { "OPERAND_TYPE_DISP16_32",
317 { "OPERAND_TYPE_ANYDISP",
318 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
319 { "OPERAND_TYPE_IMM16_32",
321 { "OPERAND_TYPE_IMM16_32S",
323 { "OPERAND_TYPE_IMM16_32_32S",
324 "Imm16|Imm32|Imm32S" },
325 { "OPERAND_TYPE_IMM32_64",
327 { "OPERAND_TYPE_IMM32_32S_DISP32",
328 "Imm32|Imm32S|Disp32" },
329 { "OPERAND_TYPE_IMM64_DISP64",
331 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
332 "Imm32|Imm32S|Imm64|Disp32" },
333 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
334 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
335 { "OPERAND_TYPE_VEC_IMM4",
337 { "OPERAND_TYPE_REGBND",
339 { "OPERAND_TYPE_VEC_DISP8",
343 typedef struct bitfield
350 #define BITFIELD(n) { n, 0, #n }
352 static bitfield cpu_flags
[] =
360 BITFIELD (CpuClflush
),
362 BITFIELD (CpuSYSCALL
),
367 BITFIELD (CpuFISTTP
),
373 BITFIELD (CpuSSE4_1
),
374 BITFIELD (CpuSSE4_2
),
377 BITFIELD (CpuAVX512F
),
378 BITFIELD (CpuAVX512CD
),
379 BITFIELD (CpuAVX512ER
),
380 BITFIELD (CpuAVX512PF
),
385 BITFIELD (Cpu3dnowA
),
386 BITFIELD (CpuPadLock
),
392 BITFIELD (CpuXsaveopt
),
394 BITFIELD (CpuPCLMUL
),
405 BITFIELD (CpuRdtscp
),
406 BITFIELD (CpuFSGSBase
),
413 BITFIELD (CpuINVPCID
),
414 BITFIELD (CpuVMFUNC
),
415 BITFIELD (CpuRDSEED
),
417 BITFIELD (CpuPRFCHW
),
421 BITFIELD (CpuClflushOpt
),
422 BITFIELD (CpuXSAVES
),
423 BITFIELD (CpuXSAVEC
),
424 BITFIELD (CpuPREFETCHWT1
),
429 BITFIELD (CpuUnused
),
433 static bitfield opcode_modifiers
[] =
439 BITFIELD (ShortForm
),
441 BITFIELD (JumpDword
),
443 BITFIELD (JumpInterSegment
),
450 BITFIELD (CheckRegSize
),
451 BITFIELD (IgnoreSize
),
452 BITFIELD (DefaultSize
),
461 BITFIELD (BNDPrefixOk
),
462 BITFIELD (IsLockable
),
463 BITFIELD (RegKludge
),
464 BITFIELD (FirstXmm0
),
465 BITFIELD (Implicit1stXmm0
),
466 BITFIELD (RepPrefixOk
),
467 BITFIELD (HLEPrefixOk
),
470 BITFIELD (AddrPrefixOp0
),
479 BITFIELD (VexOpcode
),
480 BITFIELD (VexSources
),
481 BITFIELD (VexImmExt
),
488 BITFIELD (Broadcast
),
489 BITFIELD (StaticRounding
),
491 BITFIELD (Disp8MemShift
),
492 BITFIELD (NoDefMask
),
494 BITFIELD (ATTMnemonic
),
495 BITFIELD (ATTSyntax
),
496 BITFIELD (IntelSyntax
),
499 static bitfield operand_types
[] =
518 BITFIELD (BaseIndex
),
524 BITFIELD (InOutPortReg
),
525 BITFIELD (ShiftCount
),
533 BITFIELD (JumpAbsolute
),
546 BITFIELD (Unspecified
),
550 BITFIELD (Vec_Disp8
),
556 static const char *filename
;
559 compare (const void *x
, const void *y
)
561 const bitfield
*xp
= (const bitfield
*) x
;
562 const bitfield
*yp
= (const bitfield
*) y
;
563 return xp
->position
- yp
->position
;
567 fail (const char *message
, ...)
571 va_start (args
, message
);
572 fprintf (stderr
, _("%s: Error: "), program_name
);
573 vfprintf (stderr
, message
, args
);
579 process_copyright (FILE *fp
)
581 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
582 /* Copyright 2007-2014 Free Software Foundation, Inc.\n\
584 This file is part of the GNU opcodes library.\n\
586 This library is free software; you can redistribute it and/or modify\n\
587 it under the terms of the GNU General Public License as published by\n\
588 the Free Software Foundation; either version 3, or (at your option)\n\
589 any later version.\n\
591 It is distributed in the hope that it will be useful, but WITHOUT\n\
592 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
593 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
594 License for more details.\n\
596 You should have received a copy of the GNU General Public License\n\
597 along with this program; if not, write to the Free Software\n\
598 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
599 MA 02110-1301, USA. */\n");
602 /* Remove leading white spaces. */
605 remove_leading_whitespaces (char *str
)
607 while (ISSPACE (*str
))
612 /* Remove trailing white spaces. */
615 remove_trailing_whitespaces (char *str
)
617 size_t last
= strlen (str
);
625 if (ISSPACE (str
[last
]))
633 /* Find next field separated by SEP and terminate it. Return a
634 pointer to the one after it. */
637 next_field (char *str
, char sep
, char **next
, char *last
)
641 p
= remove_leading_whitespaces (str
);
642 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
645 remove_trailing_whitespaces (p
);
656 set_bitfield (const char *f
, bitfield
*array
, int value
,
657 unsigned int size
, int lineno
)
661 if (strcmp (f
, "CpuFP") == 0)
663 set_bitfield("Cpu387", array
, value
, size
, lineno
);
664 set_bitfield("Cpu287", array
, value
, size
, lineno
);
667 else if (strcmp (f
, "Mmword") == 0)
669 else if (strcmp (f
, "Oword") == 0)
672 for (i
= 0; i
< size
; i
++)
673 if (strcasecmp (array
[i
].name
, f
) == 0)
675 array
[i
].value
= value
;
681 const char *v
= strchr (f
, '=');
688 for (i
= 0; i
< size
; i
++)
689 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
691 value
= strtol (v
+ 1, &end
, 0);
694 array
[i
].value
= value
;
703 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
705 fail (_("Unknown bitfield: %s\n"), f
);
709 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
710 int macro
, const char *comma
, const char *indent
)
714 fprintf (table
, "%s{ { ", indent
);
716 for (i
= 0; i
< size
- 1; i
++)
718 if (((i
+ 1) % 20) != 0)
719 fprintf (table
, "%d, ", flags
[i
].value
);
721 fprintf (table
, "%d,", flags
[i
].value
);
722 if (((i
+ 1) % 20) == 0)
724 /* We need \\ for macro. */
726 fprintf (table
, " \\\n %s", indent
);
728 fprintf (table
, "\n %s", indent
);
732 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
736 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
737 const char *comma
, const char *indent
,
740 char *str
, *next
, *last
;
742 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
744 /* Copy the default cpu flags. */
745 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
747 if (strcasecmp (flag
, "unknown") == 0)
749 /* We turn on everything except for cpu64 in case of
750 CPU_UNKNOWN_FLAGS. */
751 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
752 if (flags
[i
].position
!= Cpu64
)
755 else if (flag
[0] == '~')
757 last
= flag
+ strlen (flag
);
764 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
771 /* First we turn on everything except for cpu64. */
772 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
773 if (flags
[i
].position
!= Cpu64
)
776 /* Turn off selective bits. */
777 for (; next
&& next
< last
; )
779 str
= next_field (next
, '|', &next
, last
);
781 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
784 else if (strcmp (flag
, "0"))
786 /* Turn on selective bits. */
787 last
= flag
+ strlen (flag
);
788 for (next
= flag
; next
&& next
< last
; )
790 str
= next_field (next
, '|', &next
, last
);
792 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
796 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
801 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
805 fprintf (table
, " { ");
807 for (i
= 0; i
< size
- 1; i
++)
809 if (((i
+ 1) % 20) != 0)
810 fprintf (table
, "%d, ", modifier
[i
].value
);
812 fprintf (table
, "%d,", modifier
[i
].value
);
813 if (((i
+ 1) % 20) == 0)
814 fprintf (table
, "\n ");
817 fprintf (table
, "%d },\n", modifier
[i
].value
);
821 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
823 char *str
, *next
, *last
;
824 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
826 /* Copy the default opcode modifier. */
827 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
829 if (strcmp (mod
, "0"))
831 last
= mod
+ strlen (mod
);
832 for (next
= mod
; next
&& next
< last
; )
834 str
= next_field (next
, '|', &next
, last
);
836 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
840 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
844 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
845 int macro
, const char *indent
)
849 fprintf (table
, "{ { ");
851 for (i
= 0; i
< size
- 1; i
++)
853 if (((i
+ 1) % 20) != 0)
854 fprintf (table
, "%d, ", types
[i
].value
);
856 fprintf (table
, "%d,", types
[i
].value
);
857 if (((i
+ 1) % 20) == 0)
859 /* We need \\ for macro. */
861 fprintf (table
, " \\\n%s", indent
);
863 fprintf (table
, "\n%s", indent
);
867 fprintf (table
, "%d } }", types
[i
].value
);
871 process_i386_operand_type (FILE *table
, char *op
, int macro
,
872 const char *indent
, int lineno
)
874 char *str
, *next
, *last
;
875 bitfield types
[ARRAY_SIZE (operand_types
)];
877 /* Copy the default operand type. */
878 memcpy (types
, operand_types
, sizeof (types
));
880 if (strcmp (op
, "0"))
882 last
= op
+ strlen (op
);
883 for (next
= op
; next
&& next
< last
; )
885 str
= next_field (next
, '|', &next
, last
);
887 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
890 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
895 output_i386_opcode (FILE *table
, const char *name
, char *str
,
896 char *last
, int lineno
)
899 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
900 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
902 /* Find number of operands. */
903 operands
= next_field (str
, ',', &str
, last
);
905 /* Find base_opcode. */
906 base_opcode
= next_field (str
, ',', &str
, last
);
908 /* Find extension_opcode. */
909 extension_opcode
= next_field (str
, ',', &str
, last
);
911 /* Find opcode_length. */
912 opcode_length
= next_field (str
, ',', &str
, last
);
914 /* Find cpu_flags. */
915 cpu_flags
= next_field (str
, ',', &str
, last
);
917 /* Find opcode_modifier. */
918 opcode_modifier
= next_field (str
, ',', &str
, last
);
920 /* Remove the first {. */
921 str
= remove_leading_whitespaces (str
);
924 str
= remove_leading_whitespaces (str
+ 1);
928 /* There are at least "X}". */
932 /* Remove trailing white spaces and }. */
936 if (ISSPACE (str
[i
]) || str
[i
] == '}')
945 /* Find operand_types. */
946 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
950 operand_types
[i
] = NULL
;
954 operand_types
[i
] = next_field (str
, ',', &str
, last
);
955 if (*operand_types
[i
] == '0')
958 operand_types
[i
] = NULL
;
963 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
964 name
, operands
, base_opcode
, extension_opcode
,
967 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
969 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
971 fprintf (table
, " { ");
973 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
975 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
978 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
983 fprintf (table
, ",\n ");
985 process_i386_operand_type (table
, operand_types
[i
], 0,
988 fprintf (table
, " } },\n");
991 struct opcode_hash_entry
993 struct opcode_hash_entry
*next
;
999 /* Calculate the hash value of an opcode hash entry P. */
1002 opcode_hash_hash (const void *p
)
1004 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1005 return htab_hash_string (entry
->name
);
1008 /* Compare a string Q against an opcode hash entry P. */
1011 opcode_hash_eq (const void *p
, const void *q
)
1013 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1014 const char *name
= (const char *) q
;
1015 return strcmp (name
, entry
->name
) == 0;
1019 process_i386_opcodes (FILE *table
)
1024 char *str
, *p
, *last
, *name
;
1025 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1026 htab_t opcode_hash_table
;
1027 struct opcode_hash_entry
**opcode_array
;
1028 unsigned int opcode_array_size
= 1024;
1031 filename
= "i386-opc.tbl";
1032 fp
= fopen (filename
, "r");
1035 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1039 opcode_array
= (struct opcode_hash_entry
**)
1040 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1042 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1043 opcode_hash_eq
, NULL
,
1046 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1047 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1049 /* Put everything on opcode array. */
1052 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1057 p
= remove_leading_whitespaces (buf
);
1059 /* Skip comments. */
1060 str
= strstr (p
, "//");
1064 /* Remove trailing white spaces. */
1065 remove_trailing_whitespaces (p
);
1070 /* Ignore comments. */
1078 last
= p
+ strlen (p
);
1081 name
= next_field (p
, ',', &str
, last
);
1083 /* Get the slot in hash table. */
1084 hash_slot
= (struct opcode_hash_entry
**)
1085 htab_find_slot_with_hash (opcode_hash_table
, name
,
1086 htab_hash_string (name
),
1089 if (*hash_slot
== NULL
)
1091 /* It is the new one. Put it on opcode array. */
1092 if (i
>= opcode_array_size
)
1094 /* Grow the opcode array when needed. */
1095 opcode_array_size
+= 1024;
1096 opcode_array
= (struct opcode_hash_entry
**)
1097 xrealloc (opcode_array
,
1098 sizeof (*opcode_array
) * opcode_array_size
);
1101 opcode_array
[i
] = (struct opcode_hash_entry
*)
1102 xmalloc (sizeof (struct opcode_hash_entry
));
1103 opcode_array
[i
]->next
= NULL
;
1104 opcode_array
[i
]->name
= xstrdup (name
);
1105 opcode_array
[i
]->opcode
= xstrdup (str
);
1106 opcode_array
[i
]->lineno
= lineno
;
1107 *hash_slot
= opcode_array
[i
];
1112 /* Append it to the existing one. */
1114 while ((*entry
) != NULL
)
1115 entry
= &(*entry
)->next
;
1116 *entry
= (struct opcode_hash_entry
*)
1117 xmalloc (sizeof (struct opcode_hash_entry
));
1118 (*entry
)->next
= NULL
;
1119 (*entry
)->name
= (*hash_slot
)->name
;
1120 (*entry
)->opcode
= xstrdup (str
);
1121 (*entry
)->lineno
= lineno
;
1125 /* Process opcode array. */
1126 for (j
= 0; j
< i
; j
++)
1128 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1132 lineno
= next
->lineno
;
1133 last
= str
+ strlen (str
);
1134 output_i386_opcode (table
, name
, str
, last
, lineno
);
1140 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1142 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1144 process_i386_opcode_modifier (table
, "0", -1);
1146 fprintf (table
, " { ");
1147 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1148 fprintf (table
, " } }\n");
1150 fprintf (table
, "};\n");
1154 process_i386_registers (FILE *table
)
1158 char *str
, *p
, *last
;
1159 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1160 char *dw2_32_num
, *dw2_64_num
;
1163 filename
= "i386-reg.tbl";
1164 fp
= fopen (filename
, "r");
1166 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1169 fprintf (table
, "\n/* i386 register table. */\n\n");
1170 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1174 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1179 p
= remove_leading_whitespaces (buf
);
1181 /* Skip comments. */
1182 str
= strstr (p
, "//");
1186 /* Remove trailing white spaces. */
1187 remove_trailing_whitespaces (p
);
1192 fprintf (table
, "%s\n", p
);
1200 last
= p
+ strlen (p
);
1202 /* Find reg_name. */
1203 reg_name
= next_field (p
, ',', &str
, last
);
1205 /* Find reg_type. */
1206 reg_type
= next_field (str
, ',', &str
, last
);
1208 /* Find reg_flags. */
1209 reg_flags
= next_field (str
, ',', &str
, last
);
1212 reg_num
= next_field (str
, ',', &str
, last
);
1214 fprintf (table
, " { \"%s\",\n ", reg_name
);
1216 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1218 /* Find 32-bit Dwarf2 register number. */
1219 dw2_32_num
= next_field (str
, ',', &str
, last
);
1221 /* Find 64-bit Dwarf2 register number. */
1222 dw2_64_num
= next_field (str
, ',', &str
, last
);
1224 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1225 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1230 fprintf (table
, "};\n");
1232 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1236 process_i386_initializers (void)
1239 FILE *fp
= fopen ("i386-init.h", "w");
1243 fail (_("can't create i386-init.h, errno = %s\n"),
1246 process_copyright (fp
);
1248 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1250 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1251 init
= xstrdup (cpu_flag_init
[i
].init
);
1252 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1256 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1258 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1259 init
= xstrdup (operand_type_init
[i
].init
);
1260 process_i386_operand_type (fp
, init
, 1, " ", -1);
1268 /* Program options. */
1269 #define OPTION_SRCDIR 200
1271 struct option long_options
[] =
1273 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1274 {"debug", no_argument
, NULL
, 'd'},
1275 {"version", no_argument
, NULL
, 'V'},
1276 {"help", no_argument
, NULL
, 'h'},
1277 {0, no_argument
, NULL
, 0}
1281 print_version (void)
1283 printf ("%s: version 1.0\n", program_name
);
1288 usage (FILE * stream
, int status
)
1290 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1296 main (int argc
, char **argv
)
1298 extern int chdir (char *);
1299 char *srcdir
= NULL
;
1303 program_name
= *argv
;
1304 xmalloc_set_program_name (program_name
);
1306 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1331 if (chdir (srcdir
) != 0)
1332 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1333 srcdir
, xstrerror (errno
));
1335 /* Check the unused bitfield in i386_cpu_flags. */
1337 c
= CpuNumOfBits
- CpuMax
- 1;
1339 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1342 /* Check the unused bitfield in i386_operand_type. */
1344 c
= OTNumOfBits
- OTMax
- 1;
1346 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1349 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1352 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1353 sizeof (opcode_modifiers
[0]), compare
);
1355 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1356 sizeof (operand_types
[0]), compare
);
1358 table
= fopen ("i386-tbl.h", "w");
1360 fail (_("can't create i386-tbl.h, errno = %s\n"),
1363 process_copyright (table
);
1365 process_i386_opcodes (table
);
1366 process_i386_registers (table
);
1367 process_i386_initializers ();