Automatic date update in version.in
[binutils-gdb.git] / opcodes / i386-gen.c
blob2133121648648c73bb72d223048d77ed2adc91b9
1 /* Copyright (C) 2007-2024 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)
8 any later version.
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. */
20 #include "sysdep.h"
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include "getopt.h"
25 #include "libiberty.h"
26 #include "hashtab.h"
27 #include "safe-ctype.h"
29 #include "i386-opc.h"
31 /* Build-time checks are preferrable over runtime ones. Use this construct
32 in preference where possible. */
33 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
35 static const char *program_name = NULL;
36 static int debug = 0;
38 typedef struct dependency
40 const char *name;
41 /* Note: Only direct dependencies should be enumerated. */
42 const char *deps;
43 } dependency;
45 static const dependency isa_dependencies[] =
47 { "UNKNOWN",
48 "~IAMCU" },
49 { "GENERIC32",
50 "386" },
51 { "GENERIC64",
52 "PENTIUMPRO|Clflush|SYSCALL|MMX|SSE2|LM" },
53 { "NONE",
54 "0" },
55 { "PENTIUMPRO",
56 "686|Nop" },
57 { "P2",
58 "PENTIUMPRO|MMX" },
59 { "P3",
60 "P2|SSE" },
61 { "P4",
62 "P3|Clflush|SSE2" },
63 { "NOCONA",
64 "GENERIC64|FISTTP|SSE3|MONITOR|CX16" },
65 { "CORE",
66 "P4|FISTTP|SSE3|MONITOR" },
67 { "CORE2",
68 "NOCONA|SSSE3" },
69 { "COREI7",
70 "CORE2|SSE4_2|Rdtscp|LAHF_SAHF" },
71 { "K6",
72 "186|286|386|486|586|SYSCALL|387|MMX" },
73 { "K6_2",
74 "K6|3dnow" },
75 { "ATHLON",
76 "K6_2|686:min|687|Nop|3dnowA" },
77 { "K8",
78 "ATHLON|Rdtscp|SSE2|LM" },
79 { "AMDFAM10",
80 "K8|FISTTP|SSE4A|ABM|MONITOR" },
81 { "BDVER1",
82 "GENERIC64|FISTTP|Rdtscp|MONITOR|CX16|LAHF_SAHF|XOP|ABM|LWP|SVME|AES|PCLMULQDQ|PRFCHW" },
83 { "BDVER2",
84 "BDVER1|FMA|BMI|TBM|F16C" },
85 { "BDVER3",
86 "BDVER2|Xsaveopt|FSGSBase" },
87 { "BDVER4",
88 "BDVER3|AVX2|Movbe|BMI2|RdRnd|MWAITX" },
89 { "ZNVER1",
90 "GENERIC64|FISTTP|Rdtscp|MONITOR|CX16|LAHF_SAHF|AVX2|SSE4A|ABM|SVME|AES|PCLMULQDQ|PRFCHW|FMA|BMI|F16C|Xsaveopt|FSGSBase|Movbe|BMI2|RdRnd|ADX|RdSeed|SMAP|SHA|XSAVEC|XSAVES|ClflushOpt|CLZERO|MWAITX" },
91 { "ZNVER2",
92 "ZNVER1|CLWB|RDPID|RDPRU|MCOMMIT|WBNOINVD" },
93 { "ZNVER3",
94 "ZNVER2|INVLPGB|TLBSYNC|VAES|VPCLMULQDQ|INVPCID|SNP|OSPKE" },
95 { "ZNVER4",
96 "ZNVER3|AVX512F|AVX512DQ|AVX512IFMA|AVX512CD|AVX512BW|AVX512VL|AVX512_BF16|AVX512VBMI|AVX512_VBMI2|AVX512_VNNI|AVX512_BITALG|AVX512_VPOPCNTDQ|GFNI|RMPQUERY" },
97 { "ZNVER5",
98 "ZNVER4|AVX_VNNI|MOVDIRI|MOVDIR64B|AVX512_VP2INTERSECT|PREFETCHI" },
99 { "BTVER1",
100 "GENERIC64|FISTTP|MONITOR|CX16|LAHF_SAHF|Rdtscp|SSSE3|SSE4A|ABM|PRFCHW|Clflush|FISTTP|SVME" },
101 { "BTVER2",
102 "BTVER1|AVX|BMI|F16C|AES|PCLMULQDQ|Movbe|Xsaveopt|PRFCHW" },
103 { "286",
104 "186" },
105 { "386",
106 "286" },
107 { "486",
108 "386" },
109 { "586",
110 "486|387" },
111 { "586:nofpu",
112 "486" },
113 { "686",
114 "586|687|CMOV|FXSR" },
115 { "686:min",
116 "586|687" },
117 { "687",
118 "387" },
119 { "FISTTP",
120 "687" },
121 { "SSE",
122 "FXSR" },
123 { "SSE2",
124 "SSE" },
125 { "SSE3",
126 "SSE2" },
127 { "SSSE3",
128 "SSE3" },
129 { "SSE4_1",
130 "SSSE3" },
131 { "SSE4_2",
132 "SSE4_1|POPCNT" },
133 { "Xsaveopt",
134 "XSAVE" },
135 { "AES",
136 "SSE2" },
137 { "PCLMULQDQ",
138 "SSE2" },
139 { "FMA",
140 "AVX" },
141 { "FMA4",
142 "AVX" },
143 { "XOP",
144 "SSE4A|FMA4" },
145 { "LWP",
146 "XSAVE" },
147 { "F16C",
148 "AVX" },
149 { "3dnow",
150 "MMX" },
151 { "3dnowA",
152 "3dnow" },
153 { "SSE4a",
154 "SSE3" },
155 { "ABM",
156 "LZCNT|POPCNT" },
157 { "AVX",
158 "SSE4_2|XSAVE" },
159 { "AVX2",
160 "AVX" },
161 { "AVX_VNNI",
162 "AVX2" },
163 { "AVX_IFMA",
164 "AVX2" },
165 { "AVX_VNNI_INT8",
166 "AVX2" },
167 { "AVX_VNNI_INT16",
168 "AVX2" },
169 { "AVX_NE_CONVERT",
170 "AVX2" },
171 { "CX16",
172 "64" },
173 { "LKGS",
174 "64" },
175 { "FRED",
176 "LKGS" },
177 { "AVX512F",
178 "AVX2" },
179 { "AVX512CD",
180 "AVX512F" },
181 { "AVX512ER",
182 "AVX512F" },
183 { "AVX512PF",
184 "AVX512F" },
185 { "AVX512DQ",
186 "AVX512F" },
187 { "AVX512BW",
188 "AVX512F" },
189 { "AVX512VL",
190 "AVX512F" },
191 { "AVX512IFMA",
192 "AVX512F" },
193 { "AVX512VBMI",
194 "AVX512BW" },
195 { "AVX512_4FMAPS",
196 "AVX512F" },
197 { "AVX512_4VNNIW",
198 "AVX512F" },
199 { "AVX512_VPOPCNTDQ",
200 "AVX512F" },
201 { "AVX512_VBMI2",
202 "AVX512BW" },
203 { "AVX512_VNNI",
204 "AVX512F" },
205 { "AVX512_BITALG",
206 "AVX512BW" },
207 { "AVX512_VP2INTERSECT",
208 "AVX512F" },
209 { "AVX512_BF16",
210 "AVX512BW" },
211 { "AVX512_FP16",
212 "AVX512BW" },
213 { "IAMCU",
214 "586:nofpu" },
215 { "EPT",
216 "VMX" },
217 { "VMFUNC",
218 "VMX" },
219 { "MPX",
220 "XSAVE" },
221 { "SHA",
222 "SSE2" },
223 { "SHA512",
224 "AVX2" },
225 { "SM3",
226 "AVX" },
227 { "SM4",
228 "AVX2" },
229 { "XSAVES",
230 "XSAVEC" },
231 { "XSAVEC",
232 "XSAVE" },
233 { "OSPKE",
234 "XSAVE" },
235 { "GFNI",
236 "SSE2" },
237 { "VAES",
238 "AVX2|AES" },
239 { "VPCLMULQDQ",
240 "AVX2|PCLMULQDQ" },
241 { "AVX10_1",
242 "AVX512VL|AVX512DQ|AVX512CD|AVX512VBMI|AVX512_VBMI2|AVX512IFMA"
243 "|AVX512_VNNI|AVX512_BF16|AVX512_FP16|AVX512_VPOPCNTDQ|AVX512_BITALG" },
244 { "SEV_ES",
245 "SVME" },
246 { "SNP",
247 "SEV_ES" },
248 { "RMPQUERY",
249 "SNP|64" },
250 { "TSX",
251 "RTM|HLE" },
252 { "TSXLDTRK",
253 "RTM" },
254 { "AMX_TILE",
255 "XSAVE|64" },
256 { "AMX_INT8",
257 "AMX_TILE" },
258 { "AMX_BF16",
259 "AMX_TILE" },
260 { "AMX_FP16",
261 "AMX_TILE" },
262 { "AMX_COMPLEX",
263 "AMX_TILE" },
264 { "KL",
265 "SSE2" },
266 { "WIDEKL",
267 "KL" },
268 { "PBNDKB",
269 "64" },
270 { "UINTR",
271 "64" },
272 { "PREFETCHI",
273 "64" },
274 { "CMPCCXADD",
275 "64" },
276 { "MSRLIST",
277 "64" },
278 { "USER_MSR",
279 "64" },
280 { "APX_F",
281 "XSAVE|64" },
284 /* This array is populated as process_i386_initializers() walks cpu_flags[]. */
285 static unsigned char isa_reverse_deps[CpuMax][CpuMax];
287 typedef struct bitfield
289 int position;
290 int value;
291 const char *name;
292 } bitfield;
294 #define BITFIELD(n) { Cpu##n, 0, #n }
296 static bitfield cpu_flags[] =
298 BITFIELD (186),
299 BITFIELD (286),
300 BITFIELD (386),
301 BITFIELD (486),
302 BITFIELD (586),
303 BITFIELD (686),
304 BITFIELD (CMOV),
305 BITFIELD (FXSR),
306 BITFIELD (Clflush),
307 BITFIELD (Nop),
308 BITFIELD (SYSCALL),
309 BITFIELD (8087),
310 BITFIELD (287),
311 BITFIELD (387),
312 BITFIELD (687),
313 BITFIELD (FISTTP),
314 BITFIELD (MMX),
315 BITFIELD (SSE),
316 BITFIELD (SSE2),
317 BITFIELD (SSE3),
318 BITFIELD (SSSE3),
319 BITFIELD (SSE4_1),
320 BITFIELD (SSE4_2),
321 BITFIELD (AVX),
322 BITFIELD (AVX2),
323 BITFIELD (AVX512F),
324 BITFIELD (AVX512CD),
325 BITFIELD (AVX512ER),
326 BITFIELD (AVX512PF),
327 BITFIELD (AVX512VL),
328 BITFIELD (AVX512DQ),
329 BITFIELD (AVX512BW),
330 BITFIELD (IAMCU),
331 BITFIELD (SSE4a),
332 BITFIELD (3dnow),
333 BITFIELD (3dnowA),
334 BITFIELD (PadLock),
335 BITFIELD (SVME),
336 BITFIELD (VMX),
337 BITFIELD (SMX),
338 BITFIELD (Xsave),
339 BITFIELD (Xsaveopt),
340 BITFIELD (AES),
341 BITFIELD (PCLMULQDQ),
342 BITFIELD (FMA),
343 BITFIELD (FMA4),
344 BITFIELD (XOP),
345 BITFIELD (LWP),
346 BITFIELD (BMI),
347 BITFIELD (TBM),
348 BITFIELD (Movbe),
349 BITFIELD (CX16),
350 BITFIELD (LAHF_SAHF),
351 BITFIELD (EPT),
352 BITFIELD (Rdtscp),
353 BITFIELD (FSGSBase),
354 BITFIELD (RdRnd),
355 BITFIELD (F16C),
356 BITFIELD (BMI2),
357 BITFIELD (LZCNT),
358 BITFIELD (POPCNT),
359 BITFIELD (MONITOR),
360 BITFIELD (HLE),
361 BITFIELD (RTM),
362 BITFIELD (INVPCID),
363 BITFIELD (VMFUNC),
364 BITFIELD (RDSEED),
365 BITFIELD (ADX),
366 BITFIELD (PRFCHW),
367 BITFIELD (SMAP),
368 BITFIELD (SHA),
369 BITFIELD (SHA512),
370 BITFIELD (SM3),
371 BITFIELD (SM4),
372 BITFIELD (ClflushOpt),
373 BITFIELD (XSAVES),
374 BITFIELD (XSAVEC),
375 BITFIELD (PREFETCHWT1),
376 BITFIELD (SE1),
377 BITFIELD (CLWB),
378 BITFIELD (MPX),
379 BITFIELD (AVX512IFMA),
380 BITFIELD (AVX512VBMI),
381 BITFIELD (AVX512_4FMAPS),
382 BITFIELD (AVX512_4VNNIW),
383 BITFIELD (AVX512_VPOPCNTDQ),
384 BITFIELD (AVX512_VBMI2),
385 BITFIELD (AVX512_VNNI),
386 BITFIELD (AVX512_BITALG),
387 BITFIELD (AVX512_BF16),
388 BITFIELD (AVX512_VP2INTERSECT),
389 BITFIELD (TDX),
390 BITFIELD (AVX_VNNI),
391 BITFIELD (AVX512_FP16),
392 BITFIELD (PREFETCHI),
393 BITFIELD (AVX_IFMA),
394 BITFIELD (AVX_VNNI_INT8),
395 BITFIELD (AVX_VNNI_INT16),
396 BITFIELD (CMPCCXADD),
397 BITFIELD (WRMSRNS),
398 BITFIELD (MSRLIST),
399 BITFIELD (AVX_NE_CONVERT),
400 BITFIELD (RAO_INT),
401 BITFIELD (FRED),
402 BITFIELD (LKGS),
403 BITFIELD (USER_MSR),
404 BITFIELD (APX_F),
405 BITFIELD (MWAITX),
406 BITFIELD (CLZERO),
407 BITFIELD (OSPKE),
408 BITFIELD (RDPID),
409 BITFIELD (PTWRITE),
410 BITFIELD (IBT),
411 BITFIELD (SHSTK),
412 BITFIELD (GFNI),
413 BITFIELD (VAES),
414 BITFIELD (VPCLMULQDQ),
415 BITFIELD (WBNOINVD),
416 BITFIELD (PCONFIG),
417 BITFIELD (PBNDKB),
418 BITFIELD (WAITPKG),
419 BITFIELD (UINTR),
420 BITFIELD (CLDEMOTE),
421 BITFIELD (AMX_INT8),
422 BITFIELD (AMX_BF16),
423 BITFIELD (AMX_FP16),
424 BITFIELD (AMX_COMPLEX),
425 BITFIELD (AMX_TILE),
426 BITFIELD (MOVDIRI),
427 BITFIELD (MOVDIR64B),
428 BITFIELD (ENQCMD),
429 BITFIELD (SERIALIZE),
430 BITFIELD (RDPRU),
431 BITFIELD (MCOMMIT),
432 BITFIELD (SEV_ES),
433 BITFIELD (TSXLDTRK),
434 BITFIELD (KL),
435 BITFIELD (WideKL),
436 BITFIELD (HRESET),
437 BITFIELD (INVLPGB),
438 BITFIELD (TLBSYNC),
439 BITFIELD (SNP),
440 BITFIELD (RMPQUERY),
441 BITFIELD (64),
442 BITFIELD (No64),
443 #ifdef CpuUnused
444 BITFIELD (Unused),
445 #endif
448 #undef BITFIELD
449 #define BITFIELD(n) { n, 0, #n }
451 static bitfield opcode_modifiers[] =
453 BITFIELD (D),
454 BITFIELD (W),
455 BITFIELD (Load),
456 BITFIELD (Modrm),
457 BITFIELD (Jump),
458 BITFIELD (FloatMF),
459 BITFIELD (Size),
460 BITFIELD (CheckOperandSize),
461 BITFIELD (OperandConstraint),
462 BITFIELD (MnemonicSize),
463 BITFIELD (No_bSuf),
464 BITFIELD (No_wSuf),
465 BITFIELD (No_lSuf),
466 BITFIELD (No_sSuf),
467 BITFIELD (No_qSuf),
468 BITFIELD (FWait),
469 BITFIELD (IsString),
470 BITFIELD (RegMem),
471 BITFIELD (BNDPrefixOk),
472 BITFIELD (PrefixOk),
473 BITFIELD (IsPrefix),
474 BITFIELD (ImmExt),
475 BITFIELD (NoRex64),
476 BITFIELD (Vex),
477 BITFIELD (VexVVVV),
478 BITFIELD (VexW),
479 BITFIELD (OpcodePrefix),
480 BITFIELD (SIB),
481 BITFIELD (SSE2AVX),
482 BITFIELD (EVex),
483 BITFIELD (Masking),
484 BITFIELD (Broadcast),
485 BITFIELD (StaticRounding),
486 BITFIELD (SAE),
487 BITFIELD (Disp8MemShift),
488 BITFIELD (Optimize),
489 BITFIELD (Dialect),
490 BITFIELD (ISA64),
491 BITFIELD (NoEgpr),
492 BITFIELD (NF),
493 BITFIELD (Rex2),
496 #define CLASS(n) #n, n
498 static const struct {
499 const char *name;
500 enum operand_class value;
501 } operand_classes[] = {
502 CLASS (Reg),
503 CLASS (SReg),
504 CLASS (RegCR),
505 CLASS (RegDR),
506 CLASS (RegTR),
507 CLASS (RegMMX),
508 CLASS (RegSIMD),
509 CLASS (RegMask),
510 CLASS (RegBND),
513 #undef CLASS
515 #define INSTANCE(n) #n, n
517 static const struct {
518 const char *name;
519 enum operand_instance value;
520 } operand_instances[] = {
521 INSTANCE (Accum),
522 INSTANCE (RegC),
523 INSTANCE (RegD),
524 INSTANCE (RegB),
527 #undef INSTANCE
529 static bitfield operand_types[] =
531 BITFIELD (Imm1),
532 BITFIELD (Imm8),
533 BITFIELD (Imm8S),
534 BITFIELD (Imm16),
535 BITFIELD (Imm32),
536 BITFIELD (Imm32S),
537 BITFIELD (Imm64),
538 BITFIELD (BaseIndex),
539 BITFIELD (Disp8),
540 BITFIELD (Disp16),
541 BITFIELD (Disp32),
542 BITFIELD (Disp64),
543 BITFIELD (Byte),
544 BITFIELD (Word),
545 BITFIELD (Dword),
546 BITFIELD (Fword),
547 BITFIELD (Qword),
548 BITFIELD (Tbyte),
549 BITFIELD (Xmmword),
550 BITFIELD (Ymmword),
551 BITFIELD (Zmmword),
552 BITFIELD (Tmmword),
553 BITFIELD (Unspecified),
554 #ifdef OTUnused
555 BITFIELD (OTUnused),
556 #endif
559 static const char *filename;
560 static i386_cpu_flags active_cpu_flags;
561 static int active_isstring;
563 struct template_arg {
564 const struct template_arg *next;
565 const char *val;
568 struct template_instance {
569 const struct template_instance *next;
570 const char *name;
571 const struct template_arg *args;
574 struct template_param {
575 const struct template_param *next;
576 const char *name;
579 struct template {
580 struct template *next;
581 const char *name;
582 const struct template_instance *instances;
583 const struct template_param *params;
586 static struct template *templates;
588 static int
589 compare (const void *x, const void *y)
591 const bitfield *xp = (const bitfield *) x;
592 const bitfield *yp = (const bitfield *) y;
593 return xp->position - yp->position;
596 static void
597 fail (const char *message, ...)
599 va_list args;
601 va_start (args, message);
602 fprintf (stderr, "%s: error: ", program_name);
603 vfprintf (stderr, message, args);
604 va_end (args);
605 xexit (1);
608 static void
609 process_copyright (FILE *fp)
611 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
612 /* Copyright (C) 2007-2024 Free Software Foundation, Inc.\n\
614 This file is part of the GNU opcodes library.\n\
616 This library is free software; you can redistribute it and/or modify\n\
617 it under the terms of the GNU General Public License as published by\n\
618 the Free Software Foundation; either version 3, or (at your option)\n\
619 any later version.\n\
621 It is distributed in the hope that it will be useful, but WITHOUT\n\
622 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
623 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
624 License for more details.\n\
626 You should have received a copy of the GNU General Public License\n\
627 along with this program; if not, write to the Free Software\n\
628 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
629 MA 02110-1301, USA. */\n");
632 /* Remove leading white spaces. */
634 static char *
635 remove_leading_whitespaces (char *str)
637 while (ISSPACE (*str))
638 str++;
639 return str;
642 /* Remove trailing white spaces. */
644 static void
645 remove_trailing_whitespaces (char *str)
647 size_t last = strlen (str);
649 if (last == 0)
650 return;
654 last--;
655 if (ISSPACE (str [last]))
656 str[last] = '\0';
657 else
658 break;
660 while (last != 0);
663 /* Find next field separated by SEP and terminate it. Return a
664 pointer to the one after it. */
666 static char *
667 next_field (char *str, char sep, char **next, char *last)
669 char *p;
671 p = remove_leading_whitespaces (str);
672 for (str = p; *str != sep && *str != '\0'; str++);
674 *str = '\0';
675 remove_trailing_whitespaces (p);
677 *next = str + 1;
679 if (p >= last)
680 abort ();
682 return p;
685 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
687 static void
688 set_bitfield (char *f, bitfield *array, int value,
689 unsigned int size, int lineno)
691 unsigned int i;
693 /* Ignore empty fields; they may result from template expansions. */
694 if (*f == '\0')
695 return;
697 for (i = 0; i < size; i++)
698 if (strcasecmp (array[i].name, f) == 0)
700 array[i].value = value;
701 return;
704 if (value)
706 const char *v = strchr (f, '=');
708 if (v)
710 size_t n = v - f;
711 char *end;
713 for (i = 0; i < size; i++)
714 if (strncasecmp (array[i].name, f, n) == 0)
716 value = strtol (v + 1, &end, 0);
717 if (*end == '\0')
719 array[i].value = value;
720 return;
722 break;
727 if (lineno != -1)
728 fail ("%s: %d: unknown bitfield: %s\n", filename, lineno, f);
729 else
730 fail ("unknown bitfield: %s\n", f);
733 static void
734 add_isa_dependencies (bitfield *flags, const char *f, int value,
735 unsigned int reverse)
737 unsigned int i;
738 char *str = NULL;
739 const char *isa = f;
740 static bool is_avx;
741 bool is_isa = false, orig_is_avx = is_avx;
743 /* Need to find base entry for references to auxiliary ones. */
744 if (strchr (f, ':'))
746 str = xstrdup (f);
747 *strchr (str, ':') = '\0';
748 isa = str;
750 /* isa_dependencies[] prefers "LM" over "64". */
751 else if (!strcmp (f, "LM"))
752 isa = "64";
753 for (i = 0; i < CpuMax; ++i)
754 if (strcasecmp (flags[i].name, isa) == 0)
756 flags[i].value = value;
757 if (reverse < ARRAY_SIZE (isa_reverse_deps[0])
758 /* Don't record the feature itself here. */
759 && reverse != i
760 /* Don't record base architectures. */
761 && reverse > Cpu686)
762 isa_reverse_deps[i][reverse] = 1;
763 is_isa = true;
764 if (i == CpuAVX || i == CpuXOP || i == CpuVAES || i == CpuVPCLMULQDQ)
765 is_avx = true;
766 break;
768 free (str);
770 /* Do not turn off dependencies. */
771 if (is_isa && !value)
773 is_avx = orig_is_avx;
774 return;
777 for (i = 0; i < ARRAY_SIZE (isa_dependencies); ++i)
778 if (strcasecmp (isa_dependencies[i].name, f) == 0)
780 char *deps = xstrdup (isa_dependencies[i].deps);
781 char *next = deps;
782 char *last = deps + strlen (deps);
784 for (; next && next < last; )
786 char *str = next_field (next, '|', &next, last);
788 /* No AVX/XOP -> SSE reverse dependencies. */
789 if (is_avx && strncmp (str, "SSE", 3) == 0)
790 add_isa_dependencies (flags, str, value, CpuMax);
791 else
792 add_isa_dependencies (flags, str, value, reverse);
794 free (deps);
796 /* ISA extensions with dependencies need CPU_ANY_*_FLAGS emitted,
797 unless the sole dependency is the "64-bit mode only" one. */
798 if (reverse < ARRAY_SIZE (isa_reverse_deps[0])
799 && strcmp (isa_dependencies[i].deps, "64"))
800 isa_reverse_deps[reverse][reverse] = 1;
802 is_avx = orig_is_avx;
803 return;
806 if (!is_isa)
807 fail ("unknown bitfield: %s\n", f);
809 is_avx = orig_is_avx;
812 static void
813 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
814 int mode, const char *comma, const char *indent, int lineno)
816 unsigned int i = 0, j = 0;
818 if (mode < 0)
819 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
821 fprintf (table, "%s{ { ", indent);
823 if (mode <= 0)
825 for (j = ~0u; i < CpuAttrEnums; i++)
827 if (!flags[i].value)
828 continue;
830 if (j < ~0u)
831 fail ("%s: %d: invalid combination of CPU identifiers\n",
832 filename, lineno);
833 j = i;
834 if (mode)
835 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
838 /* Write 0 to indicate "no associated flag". */
839 fprintf (table, "%u, ", j + 1);
841 j = 1;
844 for (; i < size - 1; i++, j++)
846 if (((j + 1) % 20) != 0)
847 fprintf (table, "%d, ", flags[i].value);
848 else
849 fprintf (table, "%d,", flags[i].value);
850 if (((j + 1) % 20) == 0)
852 /* We need \\ for macro. */
853 if (mode > 0)
854 fprintf (table, " \\\n %s", indent);
855 else
856 fprintf (table, "\n %s", indent);
858 if (mode < 0 && flags[i].value)
859 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
862 #if defined(CpuAttrUnused) != defined(CpuUnused)
863 if (mode <= 0)
864 # ifdef CpuUnused
865 fprintf (table, " } }%s\n", comma);
866 # else
867 fprintf (table, "%d, 0 } }%s\n", flags[i].value, comma);
868 # endif
869 else
870 #endif
871 fprintf (table, "%d } }%s\n", flags[i].value, comma);
874 static void
875 process_i386_cpu_flag (FILE *table, char *flag,
876 const char *name,
877 const char *comma, const char *indent,
878 int lineno, unsigned int reverse)
880 char *str, *next = flag, *last;
881 unsigned int i;
882 int value = 1;
883 bool is_isa = false;
884 bitfield all [ARRAY_SIZE (cpu_flags)];
885 bitfield any [ARRAY_SIZE (cpu_flags)];
887 /* Copy the default cpu flags. */
888 memcpy (all, cpu_flags, sizeof (cpu_flags));
889 memcpy (any, cpu_flags, sizeof (cpu_flags));
891 if (flag == NULL)
893 for (i = 0; i < ARRAY_SIZE (isa_reverse_deps[0]); ++i)
894 any[i].value = isa_reverse_deps[reverse][i];
895 goto output;
898 if (flag[0] == '~')
900 last = flag + strlen (flag);
902 if (flag[1] == '(')
904 last -= 1;
905 next = flag + 2;
906 if (*last != ')')
907 fail ("%s: %d: missing `)' in bitfield: %s\n", filename,
908 lineno, flag);
909 *last = '\0';
911 else
912 next = flag + 1;
914 /* First we turn on everything except for cpuno64 and - if
915 present - the padding field. */
916 for (i = 0; i < ARRAY_SIZE (any); i++)
917 if (any[i].position < CpuNo64)
918 any[i].value = 1;
920 /* Turn off selective bits. */
921 value = 0;
924 if (name != NULL && value != 0)
926 for (i = 0; i < ARRAY_SIZE (any); i++)
927 if (strcasecmp (any[i].name, name) == 0)
929 add_isa_dependencies (any, name, 1, reverse);
930 is_isa = true;
931 break;
935 if (strcmp (flag, "0"))
937 bool combined = false;
939 if (is_isa)
940 return;
942 /* Turn on/off selective bits. */
943 last = flag + strlen (flag);
944 if (name == NULL && strchr (flag, '&'))
946 for (; next < last && *next != '('; )
948 str = next_field (next, '&', &next, last);
949 set_bitfield (str, all, value, ARRAY_SIZE (all), lineno);
951 if (*next == '(')
953 if (*--last != ')')
954 fail ("%s: %d: missing `)' in bitfield: %s\n", filename,
955 lineno, flag);
956 ++next;
957 *last = '\0';
959 combined = true;
961 for (; next && next < last; )
963 str = next_field (next, '|', &next, last);
964 if (name)
965 add_isa_dependencies (any, str, value, reverse);
966 else if (combined || next < last)
967 set_bitfield (str, any, value, ARRAY_SIZE (any), lineno);
968 else /* Singular specifiers go into "all". */
969 set_bitfield (str, all, value, ARRAY_SIZE (all), lineno);
970 combined = true;
974 output:
975 if (name != NULL)
977 size_t len = strlen (name);
978 char *upper = xmalloc (len + 1);
980 /* Cpu64 is special: It specifies a mode dependency, not an ISA one. Zap
981 the flag from ISA initializer macros (and from CPU_ANY_64_FLAGS
982 itself we only care about tracking its dependents. Also don't emit the
983 (otherwise all zero) CPU_64_FLAGS. */
984 if (flag != NULL && reverse == Cpu64)
985 return;
986 if (is_isa || flag == NULL)
987 any[Cpu64].value = 0;
989 for (i = 0; i < len; ++i)
991 /* Don't emit #define-s for auxiliary entries. */
992 if (name[i] == ':')
993 return;
994 upper[i] = TOUPPER (name[i]);
996 upper[i] = '\0';
997 fprintf (table, "\n#define CPU_%s%s_FLAGS \\\n",
998 flag != NULL ? "": "ANY_", upper);
999 free (upper);
1001 else
1003 /* Synthesize "64-bit mode only" dependencies from the dependencies we
1004 have accumulated. */
1005 for (i = 0; i < ARRAY_SIZE (isa_reverse_deps[0]); ++i)
1006 if (all[i].value && isa_reverse_deps[Cpu64][i])
1007 all[Cpu64].value = 1;
1009 output_cpu_flags(table, all, ARRAY_SIZE (all), -1, comma, indent, lineno);
1012 output_cpu_flags (table, any, ARRAY_SIZE (any), name != NULL,
1013 comma, indent, lineno);
1016 static void
1017 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1019 unsigned int i;
1021 fprintf (table, " { ");
1023 for (i = 0; i < size - 1; i++)
1025 if (((i + 1) % 20) != 0)
1026 fprintf (table, "%d, ", modifier[i].value);
1027 else
1028 fprintf (table, "%d,", modifier[i].value);
1029 if (((i + 1) % 20) == 0)
1030 fprintf (table, "\n ");
1033 fprintf (table, "%d },\n", modifier[i].value);
1036 /* Returns LOG2 of element size. */
1037 static int
1038 get_element_size (char **opnd, int lineno)
1040 char *str, *next, *last, *op;
1041 const char *full = opnd[0];
1042 int elem_size = INT_MAX;
1044 /* Find the memory operand. */
1045 while (full != NULL && strstr(full, "BaseIndex") == NULL)
1046 full = *++opnd;
1047 if (full == NULL)
1048 fail ("%s: %d: no memory operand\n", filename, lineno);
1050 op = xstrdup (full);
1051 last = op + strlen (op);
1052 for (next = op; next && next < last; )
1054 str = next_field (next, '|', &next, last);
1055 if (str)
1057 if (strcasecmp(str, "Byte") == 0)
1059 /* The smallest element size, no need to check
1060 further. */
1061 elem_size = 0;
1062 break;
1064 else if (strcasecmp(str, "Word") == 0)
1066 if (elem_size > 1)
1067 elem_size = 1;
1069 else if (strcasecmp(str, "Dword") == 0)
1071 if (elem_size > 2)
1072 elem_size = 2;
1074 else if (strcasecmp(str, "Qword") == 0)
1076 if (elem_size > 3)
1077 elem_size = 3;
1081 free (op);
1083 if (elem_size == INT_MAX)
1084 fail ("%s: %d: unknown element size: %s\n", filename, lineno, full);
1086 return elem_size;
1089 static bool
1090 rex2_disallowed (const unsigned long long opcode, unsigned int length,
1091 unsigned int space, const char *cpu_flags)
1093 /* Some opcodes encode a ModR/M-like byte directly in the opcode. */
1094 unsigned int base_opcode = opcode >> (8 * length - 8);
1096 /* All opcodes listed map0 0x4*, 0x7*, 0xa*, 0xe* and map1 0x3*, 0x8*
1097 are reserved under REX2 and triggers #UD when prefixed with REX2 */
1098 if (space == 0)
1099 switch (base_opcode >> 4)
1101 case 0x4:
1102 case 0x7:
1103 case 0xA:
1104 case 0xE:
1105 return true;
1106 default:
1107 return false;
1110 if (space == SPACE_0F)
1111 switch (base_opcode >> 4)
1113 case 0x3:
1114 case 0x8:
1115 return true;
1116 default:
1117 return false;
1120 return false;
1123 static void
1124 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1125 unsigned int prefix, const char *extension_opcode,
1126 char **opnd, int lineno, bool rex2_disallowed)
1128 char *str, *next, *last;
1129 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1130 static const char *const spaces[] = {
1131 #define SPACE(n) [SPACE_##n] = #n
1132 SPACE(BASE),
1133 SPACE(0F),
1134 SPACE(0F38),
1135 SPACE(0F3A),
1136 SPACE(EVEXMAP4),
1137 SPACE(EVEXMAP5),
1138 SPACE(EVEXMAP6),
1139 SPACE(VEXMAP7),
1140 SPACE(XOP08),
1141 SPACE(XOP09),
1142 SPACE(XOP0A),
1143 #undef SPACE
1146 active_isstring = 0;
1148 /* Copy the default opcode modifier. */
1149 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1151 if (strcmp (mod, "0"))
1153 unsigned int have_w = 0, bwlq_suf = 0xf;
1155 last = mod + strlen (mod);
1156 for (next = mod; next && next < last; )
1158 str = next_field (next, '|', &next, last);
1159 if (str)
1161 int val = 1;
1163 if (strncmp(str, "OpcodeSpace", 11) == 0)
1165 char *end;
1167 if (str[11] != '=')
1168 fail ("%s:%d: Missing value for `OpcodeSpace'\n",
1169 filename, lineno);
1171 val = strtol (str + 12, &end, 0);
1172 if (*end)
1173 fail ("%s:%d: Bogus value `%s' for `OpcodeSpace'\n",
1174 filename, lineno, end);
1176 if (space)
1178 if (val != space)
1179 fail ("%s:%d: Conflicting opcode space specifications\n",
1180 filename, lineno);
1181 fprintf (stderr,
1182 "%s:%d: Warning: redundant opcode space specification\n",
1183 filename, lineno);
1186 space = val;
1187 continue;
1190 if (strcasecmp(str, "Broadcast") == 0)
1191 val = get_element_size (opnd, lineno) + BYTE_BROADCAST;
1192 else if (strcasecmp(str, "Disp8MemShift") == 0)
1193 val = get_element_size (opnd, lineno);
1195 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1196 lineno);
1197 if (strcasecmp(str, "IsString") == 0)
1198 active_isstring = 1;
1200 if (strcasecmp(str, "W") == 0)
1201 have_w = 1;
1203 if (strcasecmp(str, "No_bSuf") == 0)
1204 bwlq_suf &= ~1;
1205 if (strcasecmp(str, "No_wSuf") == 0)
1206 bwlq_suf &= ~2;
1207 if (strcasecmp(str, "No_lSuf") == 0)
1208 bwlq_suf &= ~4;
1209 if (strcasecmp(str, "No_qSuf") == 0)
1210 bwlq_suf &= ~8;
1214 if (prefix)
1216 if (!modifiers[OpcodePrefix].value)
1217 modifiers[OpcodePrefix].value = prefix;
1218 else if (modifiers[OpcodePrefix].value != prefix)
1219 fail ("%s:%d: Conflicting prefix specifications\n",
1220 filename, lineno);
1221 else
1222 fprintf (stderr,
1223 "%s:%d: Warning: redundant prefix specification\n",
1224 filename, lineno);
1227 if (have_w && !bwlq_suf)
1228 fail ("%s: %d: stray W modifier\n", filename, lineno);
1229 if (have_w && !(bwlq_suf & 1))
1230 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1231 filename, lineno);
1232 if (have_w && !(bwlq_suf & ~1))
1233 fprintf (stderr,
1234 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1235 filename, lineno);
1238 if (space >= ARRAY_SIZE (spaces) || !spaces[space])
1239 fail ("%s:%d: Unknown opcode space %u\n", filename, lineno, space);
1241 fprintf (table, " SPACE_%s, %s,\n",
1242 spaces[space], extension_opcode ? extension_opcode : "None");
1244 /* Rather than evaluating multiple conditions at runtime to determine
1245 whether an EVEX encoding is being dealt with, derive that information
1246 right here. A missing EVex attribute means "dynamic". */
1247 if (!modifiers[EVex].value
1248 && (modifiers[Disp8MemShift].value
1249 || modifiers[Broadcast].value
1250 || modifiers[Masking].value
1251 || modifiers[SAE].value))
1252 modifiers[EVex].value = EVEXDYN;
1254 /* Vex, legacy map2 and map3 and rex2_disallowed do not support EGPR.
1255 For templates supporting both Vex and EVex allowing EGPR. */
1256 if ((modifiers[Vex].value || space > SPACE_0F || rex2_disallowed)
1257 && !modifiers[EVex].value)
1258 modifiers[NoEgpr].value = 1;
1260 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1263 enum stage {
1264 stage_macros,
1265 stage_opcodes,
1266 stage_registers,
1269 static void
1270 output_operand_type (FILE *table, enum operand_class class,
1271 enum operand_instance instance,
1272 const bitfield *types, unsigned int size,
1273 enum stage stage, const char *indent)
1275 unsigned int i;
1277 fprintf (table, "{ { %d, %d, ", class, instance);
1279 for (i = 0; i < size - 1; i++)
1281 if (((i + 3) % 20) != 0)
1282 fprintf (table, "%d, ", types[i].value);
1283 else
1284 fprintf (table, "%d,", types[i].value);
1285 if (((i + 3) % 20) == 0)
1287 /* We need \\ for macro. */
1288 if (stage == stage_macros)
1289 fprintf (table, " \\\n%s", indent);
1290 else
1291 fprintf (table, "\n%s", indent);
1295 fprintf (table, "%d } }", types[i].value);
1298 static void
1299 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1300 const char *indent, int lineno)
1302 char *str, *next, *last;
1303 enum operand_class class = ClassNone;
1304 enum operand_instance instance = InstanceNone;
1305 bitfield types [ARRAY_SIZE (operand_types)];
1307 /* Copy the default operand type. */
1308 memcpy (types, operand_types, sizeof (types));
1310 if (strcmp (op, "0"))
1312 int baseindex = 0;
1314 last = op + strlen (op);
1315 for (next = op; next && next < last; )
1317 str = next_field (next, '|', &next, last);
1318 if (str)
1320 unsigned int i;
1322 if (!strncmp(str, "Class=", 6))
1324 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1325 if (!strcmp(str + 6, operand_classes[i].name))
1327 class = operand_classes[i].value;
1328 str = NULL;
1329 break;
1333 if (str && !strncmp(str, "Instance=", 9))
1335 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1336 if (!strcmp(str + 9, operand_instances[i].name))
1338 instance = operand_instances[i].value;
1339 str = NULL;
1340 break;
1344 if (str)
1346 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1347 if (strcasecmp(str, "BaseIndex") == 0)
1348 baseindex = 1;
1352 if (stage == stage_opcodes && baseindex && !active_isstring)
1354 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1355 if (!active_cpu_flags.bitfield.cpu64
1356 && !active_cpu_flags.bitfield.cpumpx)
1357 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1358 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1361 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1362 stage, indent);
1365 static char *mkident (const char *mnem)
1367 char *ident = xstrdup (mnem), *p = ident;
1371 if (!ISALNUM (*p))
1372 *p = '_';
1374 while (*++p);
1376 return ident;
1379 static void
1380 output_i386_opcode (FILE *table, const char *name, char *str,
1381 char *last, int lineno)
1383 unsigned int i, length, prefix = 0, space = 0;
1384 char *base_opcode, *extension_opcode, *end, *ident;
1385 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1386 unsigned long long opcode;
1388 /* Find base_opcode. */
1389 base_opcode = next_field (str, ',', &str, last);
1391 /* Find extension_opcode, if any. */
1392 extension_opcode = strchr (base_opcode, '/');
1393 if (extension_opcode)
1394 *extension_opcode++ = '\0';
1396 /* Find cpu_flags. */
1397 cpu_flags = next_field (str, ',', &str, last);
1399 /* Find opcode_modifier. */
1400 opcode_modifier = next_field (str, ',', &str, last);
1402 /* Remove the first {. */
1403 str = remove_leading_whitespaces (str);
1404 if (*str != '{')
1405 abort ();
1406 str = remove_leading_whitespaces (str + 1);
1407 remove_trailing_whitespaces (str);
1409 /* Remove } and trailing white space. */
1410 i = strlen (str);
1411 if (!i || str[i - 1] != '}')
1412 abort ();
1413 str[--i] = '\0';
1414 remove_trailing_whitespaces (str);
1416 if (!*str)
1417 operand_types [i = 0] = NULL;
1418 else
1420 last = str + strlen (str);
1422 /* Find operand_types. */
1423 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1425 if (str >= last)
1427 operand_types [i] = NULL;
1428 break;
1431 operand_types [i] = next_field (str, ',', &str, last);
1435 opcode = strtoull (base_opcode, &end, 0);
1437 /* Determine opcode length. */
1438 for (length = 1; length < 8; ++length)
1439 if (!(opcode >> (8 * length)))
1440 break;
1442 /* Transform prefixes encoded in the opcode into opcode modifier
1443 representation. */
1444 if (length > 1)
1446 switch (opcode >> (8 * length - 8))
1448 case 0x66: prefix = PREFIX_0X66; break;
1449 case 0xF3: prefix = PREFIX_0XF3; break;
1450 case 0xF2: prefix = PREFIX_0XF2; break;
1453 if (prefix)
1454 opcode &= (1ULL << (8 * --length)) - 1;
1457 /* Transform opcode space encoded in the opcode into opcode modifier
1458 representation. */
1459 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1461 switch ((opcode >> (8 * length - 16)) & 0xff)
1463 default: space = SPACE_0F; break;
1464 case 0x38: space = SPACE_0F38; break;
1465 case 0x3A: space = SPACE_0F3A; break;
1468 if (space != SPACE_0F && --length == 1)
1469 fail ("%s:%d: %s: unrecognized opcode encoding space\n",
1470 filename, lineno, name);
1471 opcode &= (1ULL << (8 * --length)) - 1;
1474 if (length > 2)
1475 fail ("%s:%d: %s: residual opcode (0x%0*llx) too large\n",
1476 filename, lineno, name, 2 * length, opcode);
1478 ident = mkident (name);
1479 fprintf (table, " { MN_%s, 0x%0*llx%s, %u,",
1480 ident, 2 * (int)length, opcode, end, i);
1481 free (ident);
1483 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1484 extension_opcode, operand_types, lineno,
1485 rex2_disallowed (opcode, length, space,
1486 cpu_flags));
1488 process_i386_cpu_flag (table, cpu_flags, NULL, ",", " ", lineno, CpuMax);
1490 fprintf (table, " { ");
1492 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1494 if (!operand_types[i])
1496 if (i == 0)
1497 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1498 lineno);
1499 break;
1502 if (i != 0)
1503 fprintf (table, ",\n ");
1505 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1506 "\t ", lineno);
1508 fprintf (table, " } },\n");
1511 struct opcode_hash_entry
1513 const char *name;
1514 struct opcode_entry
1516 struct opcode_entry *next;
1517 char *opcode;
1518 int lineno;
1519 } entry;
1522 /* Calculate the hash value of an opcode hash entry P. */
1524 static hashval_t
1525 opcode_hash_hash (const void *p)
1527 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1528 return htab_hash_string (entry->name);
1531 /* Compare a string Q against an opcode hash entry P. */
1533 static int
1534 opcode_hash_eq (const void *p, const void *q)
1536 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1537 const char *name = (const char *) q;
1538 return strcmp (name, entry->name) == 0;
1541 static void
1542 parse_template (char *buf, int lineno)
1544 char sep, *end, *name;
1545 struct template *tmpl;
1546 struct template_instance *last_inst = NULL;
1548 buf = remove_leading_whitespaces (buf + 1);
1549 end = strchr (buf, ':');
1550 if (end == NULL)
1552 struct template *prev = NULL;
1554 end = strchr (buf, '>');
1555 if (end == NULL)
1556 fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
1557 if (*remove_leading_whitespaces (end + 1))
1558 fail ("%s: %d: malformed template purge\n", filename, lineno);
1559 *end = '\0';
1560 remove_trailing_whitespaces (buf);
1561 /* Don't bother freeing the various structures. */
1562 for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
1563 if (!strcmp (buf, tmpl->name))
1564 break;
1565 if (tmpl == NULL)
1566 fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
1567 if (prev)
1568 prev->next = tmpl->next;
1569 else
1570 templates = tmpl->next;
1571 return;
1573 *end++ = '\0';
1574 remove_trailing_whitespaces (buf);
1576 if (*buf == '\0')
1577 fail ("%s: %d: missing template identifier\n", filename, lineno);
1578 tmpl = xmalloc (sizeof (*tmpl));
1579 tmpl->name = xstrdup (buf);
1581 tmpl->params = NULL;
1582 do {
1583 struct template_param *param;
1585 buf = remove_leading_whitespaces (end);
1586 end = strpbrk (buf, ":,");
1587 if (end == NULL)
1588 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1590 sep = *end;
1591 *end++ = '\0';
1592 remove_trailing_whitespaces (buf);
1594 param = xmalloc (sizeof (*param));
1595 param->name = xstrdup (buf);
1596 param->next = tmpl->params;
1597 tmpl->params = param;
1598 } while (sep == ':');
1600 tmpl->instances = NULL;
1601 do {
1602 struct template_instance *inst;
1603 char *cur, *next;
1604 const struct template_param *param;
1606 buf = remove_leading_whitespaces (end);
1607 end = strpbrk (buf, ",>");
1608 if (end == NULL)
1609 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1611 sep = *end;
1612 *end++ = '\0';
1614 inst = xmalloc (sizeof (*inst));
1615 inst->next = NULL;
1616 inst->args = NULL;
1618 cur = next_field (buf, ':', &next, end);
1619 inst->name = *cur != '$' ? xstrdup (cur) : "";
1621 for (param = tmpl->params; param; param = param->next)
1623 struct template_arg *arg = xmalloc (sizeof (*arg));
1625 cur = next_field (next, ':', &next, end);
1626 if (next > end)
1627 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1628 arg->val = xstrdup (cur);
1629 arg->next = inst->args;
1630 inst->args = arg;
1633 if (tmpl->instances)
1634 last_inst->next = inst;
1635 else
1636 tmpl->instances = inst;
1637 last_inst = inst;
1638 } while (sep == ',');
1640 buf = remove_leading_whitespaces (end);
1641 if (*buf)
1642 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1643 filename, lineno, buf);
1645 tmpl->next = templates;
1646 templates = tmpl;
1649 static unsigned int
1650 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1651 struct opcode_hash_entry ***opcode_array_p, int lineno)
1653 static unsigned int idx, opcode_array_size;
1654 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1655 struct opcode_hash_entry **hash_slot;
1656 struct opcode_entry *entry;
1657 char *ptr1 = strchr(name, '<'), *ptr2;
1659 if (ptr1 == NULL)
1661 /* Get the slot in hash table. */
1662 hash_slot = (struct opcode_hash_entry **)
1663 htab_find_slot_with_hash (opcode_hash_table, name,
1664 htab_hash_string (name),
1665 INSERT);
1667 if (*hash_slot == NULL)
1669 /* It is the new one. Put it on opcode array. */
1670 if (idx >= opcode_array_size)
1672 /* Grow the opcode array when needed. */
1673 opcode_array_size += 1024;
1674 opcode_array = (struct opcode_hash_entry **)
1675 xrealloc (opcode_array,
1676 sizeof (*opcode_array) * opcode_array_size);
1677 *opcode_array_p = opcode_array;
1680 opcode_array[idx] = (struct opcode_hash_entry *)
1681 xmalloc (sizeof (struct opcode_hash_entry));
1682 opcode_array[idx]->name = xstrdup (name);
1683 *hash_slot = opcode_array[idx];
1684 entry = &opcode_array[idx]->entry;
1685 idx++;
1687 else
1689 /* Append it to the existing one. */
1690 struct opcode_entry **entryp = &(*hash_slot)->entry.next;
1692 while (*entryp != NULL)
1693 entryp = &(*entryp)->next;
1694 entry = (struct opcode_entry *)xmalloc (sizeof (struct opcode_entry));
1695 *entryp = entry;
1698 entry->next = NULL;
1699 entry->opcode = xstrdup (str);
1700 entry->lineno = lineno;
1702 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1703 fail ("%s: %d: missing '>'\n", filename, lineno);
1704 else
1706 const struct template *tmpl;
1707 const struct template_instance *inst;
1709 *ptr1 = '\0';
1710 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1711 remove_trailing_whitespaces (ptr1);
1713 *ptr2++ = '\0';
1715 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1716 if (!strcmp(ptr1, tmpl->name))
1717 break;
1718 if (!tmpl)
1719 fail ("reference to unknown template '%s'\n", ptr1);
1721 for (inst = tmpl->instances; inst; inst = inst->next)
1723 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1724 char *str2 = xmalloc(2 * strlen(str));
1725 const char *src;
1727 strcpy (name2, name);
1728 strcat (name2, inst->name);
1729 strcat (name2, ptr2);
1731 for (ptr1 = str2, src = str; *src; )
1733 const char *ident = tmpl->name, *end;
1734 const struct template_param *param;
1735 const struct template_arg *arg;
1737 if ((*ptr1 = *src++) != '<')
1739 ++ptr1;
1740 continue;
1742 while (ISSPACE(*src))
1743 ++src;
1744 while (*ident && *src == *ident)
1745 ++src, ++ident;
1746 while (ISSPACE(*src))
1747 ++src;
1748 if (*src != ':' || *ident != '\0')
1750 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1751 ptr1 += ident - tmpl->name;
1752 continue;
1754 while (ISSPACE(*++src))
1757 end = src;
1758 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1759 ++end;
1761 for (param = tmpl->params, arg = inst->args; param;
1762 param = param->next, arg = arg->next)
1764 if (end - src == strlen (param->name)
1765 && !memcmp (src, param->name, end - src))
1767 src = end;
1768 break;
1772 if (param == NULL)
1773 fail ("template '%s' has no parameter '%.*s'\n",
1774 tmpl->name, (int)(end - src), src);
1776 while (ISSPACE(*src))
1777 ++src;
1778 if (*src != '>')
1779 fail ("%s: %d: missing '>'\n", filename, lineno);
1781 memcpy(ptr1, arg->val, strlen(arg->val));
1782 ptr1 += strlen(arg->val);
1783 ++src;
1786 *ptr1 = '\0';
1788 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1789 lineno);
1791 free (str2);
1792 free (name2);
1796 return idx;
1799 static int mnemonic_cmp(const void *p1, const void *p2)
1801 const struct opcode_hash_entry *const *e1 = p1, *const *e2 = p2;
1802 const char *s1 = (*e1)->name, *s2 = (*e2)->name;
1803 unsigned int i;
1804 size_t l1 = strlen (s1), l2 = strlen (s2);
1806 for (i = 1; i <= l1 && i <= l2; ++i)
1808 if (s1[l1 - i] != s2[l2 - i])
1809 return (unsigned char)s1[l1 - i] - (unsigned char)s2[l2 - i];
1812 return (int)(l1 - l2);
1815 static void
1816 process_i386_opcodes (FILE *table)
1818 FILE *fp;
1819 char buf[2048];
1820 unsigned int i, j, nr, offs;
1821 size_t l;
1822 char *str, *p, *last;
1823 htab_t opcode_hash_table;
1824 struct opcode_hash_entry **opcode_array = NULL;
1825 int lineno = 0, marker = 0;
1827 filename = "i386-opc.tbl";
1828 fp = stdin;
1830 i = 0;
1831 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1832 opcode_hash_eq, NULL,
1833 xcalloc, free);
1835 fprintf (table, "\n#include \"i386-mnem.h\"\n");
1836 fprintf (table, "\n/* i386 opcode table. */\n\n");
1837 fprintf (table, "static const insn_template i386_optab[] =\n{\n");
1839 /* Put everything on opcode array. */
1840 while (!feof (fp))
1842 char *name;
1844 if (fgets (buf, sizeof (buf), fp) == NULL)
1845 break;
1847 p = remove_leading_whitespaces (buf);
1849 for ( ; ; )
1851 lineno++;
1853 /* Skip comments. */
1854 str = strstr (p, "//");
1855 if (str != NULL)
1857 str[0] = '\0';
1858 remove_trailing_whitespaces (p);
1859 break;
1862 /* Look for line continuation character. */
1863 remove_trailing_whitespaces (p);
1864 j = strlen (buf);
1865 if (!j || buf[j - 1] != '+')
1866 break;
1867 if (j >= sizeof (buf) - 1)
1868 fail ("%s: %d: (continued) line too long\n", filename, lineno);
1870 if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
1872 fprintf (stderr, "%s: Line continuation on last line?\n",
1873 filename);
1874 break;
1878 switch (p[0])
1880 case '#':
1881 if (!strcmp("### MARKER ###", buf))
1882 marker = 1;
1883 else
1885 /* Since we ignore all included files (we only care about their
1886 #define-s here), we don't need to monitor filenames. The final
1887 line number directive is going to refer to the main source file
1888 again. */
1889 char *end;
1890 unsigned long ln;
1892 p = remove_leading_whitespaces (p + 1);
1893 if (!strncmp(p, "line", 4))
1894 p += 4;
1895 ln = strtoul (p, &end, 10);
1896 if (ln > 1 && ln < INT_MAX
1897 && *remove_leading_whitespaces (end) == '"')
1898 lineno = ln - 1;
1900 /* Ignore comments. */
1901 case '\0':
1902 continue;
1903 break;
1904 case '<':
1905 parse_template (p, lineno);
1906 continue;
1907 default:
1908 if (!marker)
1909 continue;
1910 break;
1913 last = p + strlen (p);
1915 /* Find name. */
1916 name = next_field (p, ',', &str, last);
1918 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1919 lineno);
1922 /* Process opcode array. */
1923 for (j = 0; j < i; j++)
1925 const char *name = opcode_array[j]->name;
1926 struct opcode_entry *next;
1928 for (next = &opcode_array[j]->entry; next; next = next->next)
1930 str = next->opcode;
1931 lineno = next->lineno;
1932 last = str + strlen (str);
1933 output_i386_opcode (table, name, str, last, lineno);
1937 fclose (fp);
1939 fprintf (table, "};\n");
1941 /* Generate opcode sets array. */
1942 fprintf (table, "\n/* i386 opcode sets table. */\n\n");
1943 fprintf (table, "typedef unsigned short i386_op_off_t;\n");
1944 fprintf (table, "static const i386_op_off_t i386_op_sets[] =\n{\n ");
1946 for (nr = j = 0; j < i; j++)
1948 struct opcode_entry *next = &opcode_array[j]->entry;
1950 if ((j + 1) % 8 != 0)
1951 fprintf (table, "%5u,", nr);
1952 else
1953 fprintf (table, "%5u,\n ", nr);
1956 ++nr;
1957 next = next->next;
1959 while (next);
1962 fprintf (table, "%5u\n};\n", nr);
1964 /* Emit mnemonics and associated #define-s. */
1965 qsort (opcode_array, i, sizeof (*opcode_array), mnemonic_cmp);
1967 fp = fopen ("i386-mnem.h", "w");
1968 if (fp == NULL)
1969 fail ("can't create i386-mnem.h, errno = %s\n",
1970 xstrerror (errno));
1972 process_copyright (fp);
1974 fprintf (table, "\n/* i386 mnemonics table. */\n\n");
1975 fprintf (table, "const char i386_mnemonics[] =\n");
1976 fprintf (fp, "\nextern const char i386_mnemonics[];\n\n");
1978 str = NULL;
1979 for (l = strlen (opcode_array[offs = j = 0]->name); j < i; j++)
1981 const char *name = opcode_array[j]->name;
1982 const char *next = NULL;
1983 size_t l1 = j + 1 < i ? strlen(next = opcode_array[j + 1]->name) : 0;
1985 if (str == NULL)
1986 str = mkident (name);
1987 if (l < l1 && !strcmp(name, next + l1 - l))
1989 fprintf (fp, "#define MN_%s ", str);
1990 free (str);
1991 str = mkident (next);
1992 fprintf (fp, "(MN_%s + %zu)\n", str, l1 - l);
1994 else
1996 fprintf (table, " \"\\0\"\"%s\"\n", name);
1997 fprintf (fp, "#define MN_%s %#x\n", str, offs + 1);
1998 offs += strlen (name) + 1;
1999 free (str);
2000 str = NULL;
2002 l = l1;
2005 fprintf (table, " \"\\0\"\".insn\"\n");
2006 fprintf (fp, "#define MN__insn %#x\n", offs + 1);
2008 fprintf (table, ";\n");
2010 fclose (fp);
2013 static void
2014 process_i386_registers (FILE *table)
2016 FILE *fp;
2017 char buf[2048];
2018 char *str, *p, *last;
2019 char *reg_name, *reg_type, *reg_flags, *reg_num;
2020 char *dw2_32_num, *dw2_64_num;
2021 int lineno = 0;
2023 filename = "i386-reg.tbl";
2024 fp = fopen (filename, "r");
2025 if (fp == NULL)
2026 fail ("can't find i386-reg.tbl for reading, errno = %s\n",
2027 xstrerror (errno));
2029 fprintf (table, "\n/* i386 register table. */\n\n");
2030 fprintf (table, "static const reg_entry i386_regtab[] =\n{\n");
2032 while (!feof (fp))
2034 if (fgets (buf, sizeof (buf), fp) == NULL)
2035 break;
2037 lineno++;
2039 p = remove_leading_whitespaces (buf);
2041 /* Skip comments. */
2042 str = strstr (p, "//");
2043 if (str != NULL)
2044 str[0] = '\0';
2046 /* Remove trailing white spaces. */
2047 remove_trailing_whitespaces (p);
2049 switch (p[0])
2051 case '#':
2052 fprintf (table, "%s\n", p);
2053 case '\0':
2054 continue;
2055 break;
2056 default:
2057 break;
2060 last = p + strlen (p);
2062 /* Find reg_name. */
2063 reg_name = next_field (p, ',', &str, last);
2065 /* Find reg_type. */
2066 reg_type = next_field (str, ',', &str, last);
2068 /* Find reg_flags. */
2069 reg_flags = next_field (str, ',', &str, last);
2071 /* Find reg_num. */
2072 reg_num = next_field (str, ',', &str, last);
2074 fprintf (table, " { \"%s\",\n ", reg_name);
2076 process_i386_operand_type (table, reg_type, stage_registers, "\t",
2077 lineno);
2079 /* Find 32-bit Dwarf2 register number. */
2080 dw2_32_num = next_field (str, ',', &str, last);
2082 /* Find 64-bit Dwarf2 register number. */
2083 dw2_64_num = next_field (str, ',', &str, last);
2085 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
2086 reg_flags, reg_num, dw2_32_num, dw2_64_num);
2089 fclose (fp);
2091 fprintf (table, "};\n");
2093 fprintf (table, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
2096 static void
2097 process_i386_initializers (void)
2099 unsigned int i;
2100 FILE *fp = fopen ("i386-init.h", "w");
2102 if (fp == NULL)
2103 fail ("can't create i386-init.h, errno = %s\n",
2104 xstrerror (errno));
2106 process_copyright (fp);
2108 for (i = 0; i < CpuMax; i++)
2109 process_i386_cpu_flag (fp, "0", cpu_flags[i].name, "", " ", -1, i);
2111 for (i = 0; i < ARRAY_SIZE (isa_dependencies); i++)
2113 char *deps = xstrdup (isa_dependencies[i].deps);
2115 process_i386_cpu_flag (fp, deps, isa_dependencies[i].name,
2116 "", " ", -1, CpuMax);
2117 free (deps);
2120 /* Early x87 is somewhat special: Both 287 and 387 not only add new insns
2121 but also remove some. Hence 8087 isn't a prereq to 287, and 287 isn't
2122 one to 387. We want the reverse to be true though: Disabling 8087 also
2123 is to disable 287+ and later; disabling 287 also means disabling 387+. */
2124 memcpy (isa_reverse_deps[Cpu287], isa_reverse_deps[Cpu387],
2125 sizeof (isa_reverse_deps[0]));
2126 isa_reverse_deps[Cpu287][Cpu387] = 1;
2127 memcpy (isa_reverse_deps[Cpu8087], isa_reverse_deps[Cpu287],
2128 sizeof (isa_reverse_deps[0]));
2129 isa_reverse_deps[Cpu8087][Cpu287] = 1;
2131 /* While we treat POPCNT as a prereq to SSE4.2, its disabling should not
2132 lead to disabling of anything else. */
2133 memset (isa_reverse_deps[CpuPOPCNT], 0, sizeof (isa_reverse_deps[0]));
2135 for (i = Cpu686 + 1; i < ARRAY_SIZE (isa_reverse_deps); i++)
2137 size_t len;
2138 char *upper;
2140 if (memchr(isa_reverse_deps[i], 1,
2141 ARRAY_SIZE (isa_reverse_deps[0])) == NULL)
2142 continue;
2144 isa_reverse_deps[i][i] = 1;
2145 process_i386_cpu_flag (fp, NULL, cpu_flags[i].name, "", " ", -1, i);
2148 fprintf (fp, "\n");
2150 fclose (fp);
2153 /* Program options. */
2154 #define OPTION_SRCDIR 200
2156 struct option long_options[] =
2158 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
2159 {"debug", no_argument, NULL, 'd'},
2160 {"version", no_argument, NULL, 'V'},
2161 {"help", no_argument, NULL, 'h'},
2162 {0, no_argument, NULL, 0}
2165 static void
2166 print_version (void)
2168 printf ("%s: version 1.0\n", program_name);
2169 xexit (0);
2172 static void
2173 usage (FILE * stream, int status)
2175 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2176 program_name);
2177 xexit (status);
2181 main (int argc, char **argv)
2183 extern int chdir (char *);
2184 char *srcdir = NULL;
2185 int c;
2186 unsigned int i, cpumax;
2187 FILE *table;
2189 program_name = *argv;
2190 xmalloc_set_program_name (program_name);
2192 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2193 switch (c)
2195 case OPTION_SRCDIR:
2196 srcdir = optarg;
2197 break;
2198 case 'V':
2199 case 'v':
2200 print_version ();
2201 break;
2202 case 'd':
2203 debug = 1;
2204 break;
2205 case 'h':
2206 case '?':
2207 usage (stderr, 0);
2208 default:
2209 case 0:
2210 break;
2213 if (optind != argc)
2214 usage (stdout, 1);
2216 if (srcdir != NULL)
2217 if (chdir (srcdir) != 0)
2218 fail ("unable to change directory to \"%s\", errno = %s\n",
2219 srcdir, xstrerror (errno));
2221 /* cpu_flags isn't sorted by position. */
2222 cpumax = 0;
2223 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2224 if (cpu_flags[i].position > cpumax)
2225 cpumax = cpu_flags[i].position;
2227 /* Check the unused bitfield in i386_cpu_flags. */
2228 #ifdef CpuUnused
2229 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2231 if ((cpumax - 1) != CpuMax)
2232 fail ("CpuMax != %d!\n", cpumax);
2233 #else
2234 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2236 if (cpumax != CpuMax)
2237 fail ("CpuMax != %d!\n", cpumax);
2239 c = CpuNumOfBits - CpuMax - 1;
2240 if (c)
2241 fail ("%d unused bits in i386_cpu_flags.\n", c);
2242 #endif
2244 /* If this triggers, CpuIsaBits needs to be increased. */
2245 static_assert (CpuAttrEnums <= (1u << CpuIsaBits));
2247 /* Check the unused bitfield in i386_cpu_attr. */
2248 #ifndef CpuAttrUnused
2249 c = CpuAttrNumOfBits - (CpuIsaBits + CpuMax + 1 - CpuAttrEnums);
2250 if (c)
2251 fail ("%d unused bits in i386_cpu_attr.\n", c);
2252 #endif
2254 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2256 /* Check the unused bitfield in i386_operand_type. */
2257 #ifdef OTUnused
2258 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2259 == OTNum + 1);
2260 #else
2261 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2262 == OTNum);
2264 c = OTNumOfBits - OTNum;
2265 if (c)
2266 fail ("%d unused bits in i386_operand_type.\n", c);
2267 #endif
2269 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2270 compare);
2272 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2273 sizeof (opcode_modifiers [0]), compare);
2275 qsort (operand_types, ARRAY_SIZE (operand_types),
2276 sizeof (operand_types [0]), compare);
2278 process_i386_initializers ();
2280 table = fopen ("i386-tbl.h", "w");
2281 if (table == NULL)
2282 fail ("can't create i386-tbl.h, errno = %s\n",
2283 xstrerror (errno));
2285 process_copyright (table);
2287 process_i386_opcodes (table);
2288 process_i386_registers (table);
2290 fclose (table);
2292 exit (0);