x86: Intel Core processors do not support CMPXCHG16B
[binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2023 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
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.
9
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.
14
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. */
19
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"
28
29 #include "i386-opc.h"
30
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); }))
34
35 static const char *program_name = NULL;
36 static int debug = 0;
37
38 typedef struct dependency
39 {
40 const char *name;
41 /* Note: Only direct dependencies should be enumerated. */
42 const char *deps;
43 } dependency;
44
45 static const dependency isa_dependencies[] =
46 {
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 { "BTVER1",
98 "GENERIC64|FISTTP|MONITOR|CX16|LAHF_SAHF|Rdtscp|SSSE3|SSE4A|ABM|PRFCHW|Clflush|FISTTP|SVME" },
99 { "BTVER2",
100 "BTVER1|AVX|BMI|F16C|AES|PCLMULQDQ|Movbe|Xsaveopt|PRFCHW" },
101 { "286",
102 "186" },
103 { "386",
104 "286" },
105 { "486",
106 "386" },
107 { "586",
108 "486|387" },
109 { "586:nofpu",
110 "486" },
111 { "686",
112 "586|687|CMOV|FXSR" },
113 { "686:min",
114 "586|687" },
115 { "687",
116 "387" },
117 { "FISTTP",
118 "687" },
119 { "SSE",
120 "FXSR" },
121 { "SSE2",
122 "SSE" },
123 { "SSE3",
124 "SSE2" },
125 { "SSSE3",
126 "SSE3" },
127 { "SSE4_1",
128 "SSSE3" },
129 { "SSE4_2",
130 "SSE4_1|POPCNT" },
131 { "Xsaveopt",
132 "XSAVE" },
133 { "AES",
134 "SSE2" },
135 { "PCLMULQDQ",
136 "SSE2" },
137 { "FMA",
138 "AVX" },
139 { "FMA4",
140 "AVX" },
141 { "XOP",
142 "SSE4A|FMA4" },
143 { "LWP",
144 "XSAVE" },
145 { "F16C",
146 "AVX" },
147 { "3dnow",
148 "MMX" },
149 { "3dnowA",
150 "3dnow" },
151 { "SSE4a",
152 "SSE3" },
153 { "ABM",
154 "LZCNT|POPCNT" },
155 { "AVX",
156 "SSE4_2|XSAVE" },
157 { "AVX2",
158 "AVX" },
159 { "AVX_VNNI",
160 "AVX2" },
161 { "AVX_IFMA",
162 "AVX2" },
163 { "AVX_VNNI_INT8",
164 "AVX2" },
165 { "AVX_VNNI_INT16",
166 "AVX2" },
167 { "AVX_NE_CONVERT",
168 "AVX2" },
169 { "FRED",
170 "LKGS" },
171 { "AVX512F",
172 "AVX2" },
173 { "AVX512CD",
174 "AVX512F" },
175 { "AVX512ER",
176 "AVX512F" },
177 { "AVX512PF",
178 "AVX512F" },
179 { "AVX512DQ",
180 "AVX512F" },
181 { "AVX512BW",
182 "AVX512F" },
183 { "AVX512VL",
184 "AVX512F" },
185 { "AVX512IFMA",
186 "AVX512F" },
187 { "AVX512VBMI",
188 "AVX512BW" },
189 { "AVX512_4FMAPS",
190 "AVX512F" },
191 { "AVX512_4VNNIW",
192 "AVX512F" },
193 { "AVX512_VPOPCNTDQ",
194 "AVX512F" },
195 { "AVX512_VBMI2",
196 "AVX512BW" },
197 { "AVX512_VNNI",
198 "AVX512F" },
199 { "AVX512_BITALG",
200 "AVX512BW" },
201 { "AVX512_VP2INTERSECT",
202 "AVX512F" },
203 { "AVX512_BF16",
204 "AVX512BW" },
205 { "AVX512_FP16",
206 "AVX512BW" },
207 { "IAMCU",
208 "586:nofpu" },
209 { "EPT",
210 "VMX" },
211 { "VMFUNC",
212 "VMX" },
213 { "MPX",
214 "XSAVE" },
215 { "SHA",
216 "SSE2" },
217 { "SHA512",
218 "AVX2" },
219 { "SM3",
220 "AVX" },
221 { "SM4",
222 "AVX2" },
223 { "XSAVES",
224 "XSAVEC" },
225 { "XSAVEC",
226 "XSAVE" },
227 { "OSPKE",
228 "XSAVE" },
229 { "GFNI",
230 "SSE2" },
231 { "VAES",
232 "AVX2|AES" },
233 { "VPCLMULQDQ",
234 "AVX2|PCLMULQDQ" },
235 { "AVX10_1",
236 "AVX512VL|AVX512DQ|AVX512CD|AVX512VBMI|AVX512_VBMI2|AVX512IFMA"
237 "|AVX512_VNNI|AVX512_BF16|AVX512_FP16|AVX512_VPOPCNTDQ|AVX512_BITALG" },
238 { "SEV_ES",
239 "SVME" },
240 { "SNP",
241 "SEV_ES" },
242 { "RMPQUERY",
243 "SNP" },
244 { "TSX",
245 "RTM|HLE" },
246 { "TSXLDTRK",
247 "RTM" },
248 { "AMX_TILE",
249 "XSAVE" },
250 { "AMX_INT8",
251 "AMX_TILE" },
252 { "AMX_BF16",
253 "AMX_TILE" },
254 { "AMX_FP16",
255 "AMX_TILE" },
256 { "AMX_COMPLEX",
257 "AMX_TILE" },
258 { "KL",
259 "SSE2" },
260 { "WIDEKL",
261 "KL" },
262 };
263
264 /* This array is populated as process_i386_initializers() walks cpu_flags[]. */
265 static unsigned char isa_reverse_deps[CpuMax][CpuMax];
266
267 typedef struct bitfield
268 {
269 int position;
270 int value;
271 const char *name;
272 } bitfield;
273
274 #define BITFIELD(n) { Cpu##n, 0, #n }
275
276 static bitfield cpu_flags[] =
277 {
278 BITFIELD (186),
279 BITFIELD (286),
280 BITFIELD (386),
281 BITFIELD (486),
282 BITFIELD (586),
283 BITFIELD (686),
284 BITFIELD (CMOV),
285 BITFIELD (FXSR),
286 BITFIELD (Clflush),
287 BITFIELD (Nop),
288 BITFIELD (SYSCALL),
289 BITFIELD (8087),
290 BITFIELD (287),
291 BITFIELD (387),
292 BITFIELD (687),
293 BITFIELD (FISTTP),
294 BITFIELD (MMX),
295 BITFIELD (SSE),
296 BITFIELD (SSE2),
297 BITFIELD (SSE3),
298 BITFIELD (SSSE3),
299 BITFIELD (SSE4_1),
300 BITFIELD (SSE4_2),
301 BITFIELD (AVX),
302 BITFIELD (AVX2),
303 BITFIELD (AVX512F),
304 BITFIELD (AVX512CD),
305 BITFIELD (AVX512ER),
306 BITFIELD (AVX512PF),
307 BITFIELD (AVX512VL),
308 BITFIELD (AVX512DQ),
309 BITFIELD (AVX512BW),
310 BITFIELD (IAMCU),
311 BITFIELD (SSE4a),
312 BITFIELD (3dnow),
313 BITFIELD (3dnowA),
314 BITFIELD (PadLock),
315 BITFIELD (SVME),
316 BITFIELD (VMX),
317 BITFIELD (SMX),
318 BITFIELD (Xsave),
319 BITFIELD (Xsaveopt),
320 BITFIELD (AES),
321 BITFIELD (PCLMULQDQ),
322 BITFIELD (FMA),
323 BITFIELD (FMA4),
324 BITFIELD (XOP),
325 BITFIELD (LWP),
326 BITFIELD (BMI),
327 BITFIELD (TBM),
328 BITFIELD (Movbe),
329 BITFIELD (CX16),
330 BITFIELD (LAHF_SAHF),
331 BITFIELD (EPT),
332 BITFIELD (Rdtscp),
333 BITFIELD (FSGSBase),
334 BITFIELD (RdRnd),
335 BITFIELD (F16C),
336 BITFIELD (BMI2),
337 BITFIELD (LZCNT),
338 BITFIELD (POPCNT),
339 BITFIELD (MONITOR),
340 BITFIELD (HLE),
341 BITFIELD (RTM),
342 BITFIELD (INVPCID),
343 BITFIELD (VMFUNC),
344 BITFIELD (RDSEED),
345 BITFIELD (ADX),
346 BITFIELD (PRFCHW),
347 BITFIELD (SMAP),
348 BITFIELD (SHA),
349 BITFIELD (SHA512),
350 BITFIELD (SM3),
351 BITFIELD (SM4),
352 BITFIELD (ClflushOpt),
353 BITFIELD (XSAVES),
354 BITFIELD (XSAVEC),
355 BITFIELD (PREFETCHWT1),
356 BITFIELD (SE1),
357 BITFIELD (CLWB),
358 BITFIELD (MPX),
359 BITFIELD (AVX512IFMA),
360 BITFIELD (AVX512VBMI),
361 BITFIELD (AVX512_4FMAPS),
362 BITFIELD (AVX512_4VNNIW),
363 BITFIELD (AVX512_VPOPCNTDQ),
364 BITFIELD (AVX512_VBMI2),
365 BITFIELD (AVX512_VNNI),
366 BITFIELD (AVX512_BITALG),
367 BITFIELD (AVX512_BF16),
368 BITFIELD (AVX512_VP2INTERSECT),
369 BITFIELD (TDX),
370 BITFIELD (AVX_VNNI),
371 BITFIELD (AVX512_FP16),
372 BITFIELD (PREFETCHI),
373 BITFIELD (AVX_IFMA),
374 BITFIELD (AVX_VNNI_INT8),
375 BITFIELD (AVX_VNNI_INT16),
376 BITFIELD (CMPCCXADD),
377 BITFIELD (WRMSRNS),
378 BITFIELD (MSRLIST),
379 BITFIELD (AVX_NE_CONVERT),
380 BITFIELD (RAO_INT),
381 BITFIELD (FRED),
382 BITFIELD (LKGS),
383 BITFIELD (USER_MSR),
384 BITFIELD (MWAITX),
385 BITFIELD (CLZERO),
386 BITFIELD (OSPKE),
387 BITFIELD (RDPID),
388 BITFIELD (PTWRITE),
389 BITFIELD (IBT),
390 BITFIELD (SHSTK),
391 BITFIELD (GFNI),
392 BITFIELD (VAES),
393 BITFIELD (VPCLMULQDQ),
394 BITFIELD (WBNOINVD),
395 BITFIELD (PCONFIG),
396 BITFIELD (PBNDKB),
397 BITFIELD (WAITPKG),
398 BITFIELD (UINTR),
399 BITFIELD (CLDEMOTE),
400 BITFIELD (AMX_INT8),
401 BITFIELD (AMX_BF16),
402 BITFIELD (AMX_FP16),
403 BITFIELD (AMX_COMPLEX),
404 BITFIELD (AMX_TILE),
405 BITFIELD (MOVDIRI),
406 BITFIELD (MOVDIR64B),
407 BITFIELD (ENQCMD),
408 BITFIELD (SERIALIZE),
409 BITFIELD (RDPRU),
410 BITFIELD (MCOMMIT),
411 BITFIELD (SEV_ES),
412 BITFIELD (TSXLDTRK),
413 BITFIELD (KL),
414 BITFIELD (WideKL),
415 BITFIELD (HRESET),
416 BITFIELD (INVLPGB),
417 BITFIELD (TLBSYNC),
418 BITFIELD (SNP),
419 BITFIELD (RMPQUERY),
420 BITFIELD (64),
421 BITFIELD (No64),
422 #ifdef CpuUnused
423 BITFIELD (Unused),
424 #endif
425 };
426
427 #undef BITFIELD
428 #define BITFIELD(n) { n, 0, #n }
429
430 static bitfield opcode_modifiers[] =
431 {
432 BITFIELD (D),
433 BITFIELD (W),
434 BITFIELD (Load),
435 BITFIELD (Modrm),
436 BITFIELD (Jump),
437 BITFIELD (FloatMF),
438 BITFIELD (Size),
439 BITFIELD (CheckOperandSize),
440 BITFIELD (OperandConstraint),
441 BITFIELD (MnemonicSize),
442 BITFIELD (No_bSuf),
443 BITFIELD (No_wSuf),
444 BITFIELD (No_lSuf),
445 BITFIELD (No_sSuf),
446 BITFIELD (No_qSuf),
447 BITFIELD (FWait),
448 BITFIELD (IsString),
449 BITFIELD (RegMem),
450 BITFIELD (BNDPrefixOk),
451 BITFIELD (PrefixOk),
452 BITFIELD (IsPrefix),
453 BITFIELD (ImmExt),
454 BITFIELD (NoRex64),
455 BITFIELD (Vex),
456 BITFIELD (VexVVVV),
457 BITFIELD (VexW),
458 BITFIELD (OpcodePrefix),
459 BITFIELD (SIB),
460 BITFIELD (SSE2AVX),
461 BITFIELD (EVex),
462 BITFIELD (Masking),
463 BITFIELD (Broadcast),
464 BITFIELD (StaticRounding),
465 BITFIELD (SAE),
466 BITFIELD (Disp8MemShift),
467 BITFIELD (Vsz),
468 BITFIELD (Optimize),
469 BITFIELD (ATTMnemonic),
470 BITFIELD (ATTSyntax),
471 BITFIELD (IntelSyntax),
472 BITFIELD (ISA64),
473 };
474
475 #define CLASS(n) #n, n
476
477 static const struct {
478 const char *name;
479 enum operand_class value;
480 } operand_classes[] = {
481 CLASS (Reg),
482 CLASS (SReg),
483 CLASS (RegCR),
484 CLASS (RegDR),
485 CLASS (RegTR),
486 CLASS (RegMMX),
487 CLASS (RegSIMD),
488 CLASS (RegMask),
489 CLASS (RegBND),
490 };
491
492 #undef CLASS
493
494 #define INSTANCE(n) #n, n
495
496 static const struct {
497 const char *name;
498 enum operand_instance value;
499 } operand_instances[] = {
500 INSTANCE (Accum),
501 INSTANCE (RegC),
502 INSTANCE (RegD),
503 INSTANCE (RegB),
504 };
505
506 #undef INSTANCE
507
508 static bitfield operand_types[] =
509 {
510 BITFIELD (Imm1),
511 BITFIELD (Imm8),
512 BITFIELD (Imm8S),
513 BITFIELD (Imm16),
514 BITFIELD (Imm32),
515 BITFIELD (Imm32S),
516 BITFIELD (Imm64),
517 BITFIELD (BaseIndex),
518 BITFIELD (Disp8),
519 BITFIELD (Disp16),
520 BITFIELD (Disp32),
521 BITFIELD (Disp64),
522 BITFIELD (Byte),
523 BITFIELD (Word),
524 BITFIELD (Dword),
525 BITFIELD (Fword),
526 BITFIELD (Qword),
527 BITFIELD (Tbyte),
528 BITFIELD (Xmmword),
529 BITFIELD (Ymmword),
530 BITFIELD (Zmmword),
531 BITFIELD (Tmmword),
532 BITFIELD (Unspecified),
533 #ifdef OTUnused
534 BITFIELD (OTUnused),
535 #endif
536 };
537
538 static const char *filename;
539 static i386_cpu_flags active_cpu_flags;
540 static int active_isstring;
541
542 struct template_arg {
543 const struct template_arg *next;
544 const char *val;
545 };
546
547 struct template_instance {
548 const struct template_instance *next;
549 const char *name;
550 const struct template_arg *args;
551 };
552
553 struct template_param {
554 const struct template_param *next;
555 const char *name;
556 };
557
558 struct template {
559 struct template *next;
560 const char *name;
561 const struct template_instance *instances;
562 const struct template_param *params;
563 };
564
565 static struct template *templates;
566
567 static int
568 compare (const void *x, const void *y)
569 {
570 const bitfield *xp = (const bitfield *) x;
571 const bitfield *yp = (const bitfield *) y;
572 return xp->position - yp->position;
573 }
574
575 static void
576 fail (const char *message, ...)
577 {
578 va_list args;
579
580 va_start (args, message);
581 fprintf (stderr, "%s: error: ", program_name);
582 vfprintf (stderr, message, args);
583 va_end (args);
584 xexit (1);
585 }
586
587 static void
588 process_copyright (FILE *fp)
589 {
590 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
591 /* Copyright (C) 2007-2023 Free Software Foundation, Inc.\n\
592 \n\
593 This file is part of the GNU opcodes library.\n\
594 \n\
595 This library is free software; you can redistribute it and/or modify\n\
596 it under the terms of the GNU General Public License as published by\n\
597 the Free Software Foundation; either version 3, or (at your option)\n\
598 any later version.\n\
599 \n\
600 It is distributed in the hope that it will be useful, but WITHOUT\n\
601 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
602 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
603 License for more details.\n\
604 \n\
605 You should have received a copy of the GNU General Public License\n\
606 along with this program; if not, write to the Free Software\n\
607 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
608 MA 02110-1301, USA. */\n");
609 }
610
611 /* Remove leading white spaces. */
612
613 static char *
614 remove_leading_whitespaces (char *str)
615 {
616 while (ISSPACE (*str))
617 str++;
618 return str;
619 }
620
621 /* Remove trailing white spaces. */
622
623 static void
624 remove_trailing_whitespaces (char *str)
625 {
626 size_t last = strlen (str);
627
628 if (last == 0)
629 return;
630
631 do
632 {
633 last--;
634 if (ISSPACE (str [last]))
635 str[last] = '\0';
636 else
637 break;
638 }
639 while (last != 0);
640 }
641
642 /* Find next field separated by SEP and terminate it. Return a
643 pointer to the one after it. */
644
645 static char *
646 next_field (char *str, char sep, char **next, char *last)
647 {
648 char *p;
649
650 p = remove_leading_whitespaces (str);
651 for (str = p; *str != sep && *str != '\0'; str++);
652
653 *str = '\0';
654 remove_trailing_whitespaces (p);
655
656 *next = str + 1;
657
658 if (p >= last)
659 abort ();
660
661 return p;
662 }
663
664 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
665
666 static void
667 set_bitfield (char *f, bitfield *array, int value,
668 unsigned int size, int lineno)
669 {
670 unsigned int i;
671
672 /* Ignore empty fields; they may result from template expansions. */
673 if (*f == '\0')
674 return;
675
676 for (i = 0; i < size; i++)
677 if (strcasecmp (array[i].name, f) == 0)
678 {
679 array[i].value = value;
680 return;
681 }
682
683 if (value)
684 {
685 const char *v = strchr (f, '=');
686
687 if (v)
688 {
689 size_t n = v - f;
690 char *end;
691
692 for (i = 0; i < size; i++)
693 if (strncasecmp (array[i].name, f, n) == 0)
694 {
695 value = strtol (v + 1, &end, 0);
696 if (*end == '\0')
697 {
698 array[i].value = value;
699 return;
700 }
701 break;
702 }
703 }
704 }
705
706 if (lineno != -1)
707 fail ("%s: %d: unknown bitfield: %s\n", filename, lineno, f);
708 else
709 fail ("unknown bitfield: %s\n", f);
710 }
711
712 static void
713 add_isa_dependencies (bitfield *flags, const char *f, int value,
714 unsigned int reverse)
715 {
716 unsigned int i;
717 char *str = NULL;
718 const char *isa = f;
719 static bool is_avx;
720 bool is_isa = false, orig_is_avx = is_avx;
721
722 /* Need to find base entry for references to auxiliary ones. */
723 if (strchr (f, ':'))
724 {
725 str = xstrdup (f);
726 *strchr (str, ':') = '\0';
727 isa = str;
728 }
729 /* isa_dependencies[] prefers "LM" over "64". */
730 else if (!strcmp (f, "LM"))
731 isa = "64";
732 for (i = 0; i < CpuMax; ++i)
733 if (strcasecmp (flags[i].name, isa) == 0)
734 {
735 flags[i].value = value;
736 if (reverse < ARRAY_SIZE (isa_reverse_deps[0])
737 /* Don't record the feature itself here. */
738 && reverse != i
739 /* Don't record base architectures. */
740 && reverse > Cpu686)
741 isa_reverse_deps[i][reverse] = 1;
742 is_isa = true;
743 if (i == CpuAVX || i == CpuXOP || i == CpuVAES || i == CpuVPCLMULQDQ)
744 is_avx = true;
745 break;
746 }
747 free (str);
748
749 /* Do not turn off dependencies. */
750 if (is_isa && !value)
751 {
752 is_avx = orig_is_avx;
753 return;
754 }
755
756 for (i = 0; i < ARRAY_SIZE (isa_dependencies); ++i)
757 if (strcasecmp (isa_dependencies[i].name, f) == 0)
758 {
759 char *deps = xstrdup (isa_dependencies[i].deps);
760 char *next = deps;
761 char *last = deps + strlen (deps);
762
763 for (; next && next < last; )
764 {
765 char *str = next_field (next, '|', &next, last);
766
767 /* No AVX/XOP -> SSE reverse dependencies. */
768 if (is_avx && strncmp (str, "SSE", 3) == 0)
769 add_isa_dependencies (flags, str, value, CpuMax);
770 else
771 add_isa_dependencies (flags, str, value, reverse);
772 }
773 free (deps);
774
775 /* ISA extensions with dependencies need CPU_ANY_*_FLAGS emitted. */
776 if (reverse < ARRAY_SIZE (isa_reverse_deps[0]))
777 isa_reverse_deps[reverse][reverse] = 1;
778
779 is_avx = orig_is_avx;
780 return;
781 }
782
783 if (!is_isa)
784 fail ("unknown bitfield: %s\n", f);
785
786 is_avx = orig_is_avx;
787 }
788
789 static void
790 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
791 int macro, const char *comma, const char *indent, int lineno)
792 {
793 unsigned int i = 0, j = 0;
794
795 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
796
797 fprintf (table, "%s{ { ", indent);
798
799 if (!macro)
800 {
801 for (j = ~0u; i < CpuAttrEnums; i++)
802 {
803 if (!flags[i].value)
804 continue;
805
806 if (j < ~0u)
807 fail ("%s: %d: invalid combination of CPU identifiers\n",
808 filename, lineno);
809 j = i;
810 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
811 }
812
813 /* Write 0 to indicate "no associated flag". */
814 fprintf (table, "%u, ", j + 1);
815
816 j = 1;
817 }
818
819 for (; i < size - 1; i++, j++)
820 {
821 if (((j + 1) % 20) != 0)
822 fprintf (table, "%d, ", flags[i].value);
823 else
824 fprintf (table, "%d,", flags[i].value);
825 if (((j + 1) % 20) == 0)
826 {
827 /* We need \\ for macro. */
828 if (macro)
829 fprintf (table, " \\\n %s", indent);
830 else
831 fprintf (table, "\n %s", indent);
832 }
833 if (flags[i].value)
834 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
835 }
836
837 fprintf (table, "%d } }%s\n", flags[i].value, comma);
838 }
839
840 static void
841 process_i386_cpu_flag (FILE *table, char *flag,
842 const char *name,
843 const char *comma, const char *indent,
844 int lineno, unsigned int reverse)
845 {
846 char *str, *next = flag, *last;
847 unsigned int i;
848 int value = 1;
849 bool is_isa = false;
850 bitfield flags [ARRAY_SIZE (cpu_flags)];
851
852 /* Copy the default cpu flags. */
853 memcpy (flags, cpu_flags, sizeof (cpu_flags));
854
855 if (flag == NULL)
856 {
857 for (i = 0; i < ARRAY_SIZE (isa_reverse_deps[0]); ++i)
858 flags[i].value = isa_reverse_deps[reverse][i];
859 goto output;
860 }
861
862 if (flag[0] == '~')
863 {
864 last = flag + strlen (flag);
865
866 if (flag[1] == '(')
867 {
868 last -= 1;
869 next = flag + 2;
870 if (*last != ')')
871 fail ("%s: %d: missing `)' in bitfield: %s\n", filename,
872 lineno, flag);
873 *last = '\0';
874 }
875 else
876 next = flag + 1;
877
878 /* First we turn on everything except for cpuno64 and - if
879 present - the padding field. */
880 for (i = 0; i < ARRAY_SIZE (flags); i++)
881 if (flags[i].position < CpuNo64)
882 flags[i].value = 1;
883
884 /* Turn off selective bits. */
885 value = 0;
886 }
887
888 if (name != NULL && value != 0)
889 {
890 for (i = 0; i < ARRAY_SIZE (flags); i++)
891 if (strcasecmp (flags[i].name, name) == 0)
892 {
893 add_isa_dependencies (flags, name, 1, reverse);
894 is_isa = true;
895 break;
896 }
897 }
898
899 if (strcmp (flag, "0"))
900 {
901 if (is_isa)
902 return;
903
904 /* Turn on/off selective bits. */
905 last = flag + strlen (flag);
906 for (; next && next < last; )
907 {
908 str = next_field (next, '|', &next, last);
909 if (name == NULL)
910 set_bitfield (str, flags, value, ARRAY_SIZE (flags), lineno);
911 else
912 add_isa_dependencies (flags, str, value, reverse);
913 }
914 }
915
916 output:
917 if (name != NULL)
918 {
919 size_t len = strlen (name);
920 char *upper = xmalloc (len + 1);
921
922 for (i = 0; i < len; ++i)
923 {
924 /* Don't emit #define-s for auxiliary entries. */
925 if (name[i] == ':')
926 return;
927 upper[i] = TOUPPER (name[i]);
928 }
929 upper[i] = '\0';
930 fprintf (table, "\n#define CPU_%s%s_FLAGS \\\n",
931 flag != NULL ? "": "ANY_", upper);
932 free (upper);
933 }
934
935 output_cpu_flags (table, flags, ARRAY_SIZE (flags), name != NULL,
936 comma, indent, lineno);
937 }
938
939 static void
940 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
941 {
942 unsigned int i;
943
944 fprintf (table, " { ");
945
946 for (i = 0; i < size - 1; i++)
947 {
948 if (((i + 1) % 20) != 0)
949 fprintf (table, "%d, ", modifier[i].value);
950 else
951 fprintf (table, "%d,", modifier[i].value);
952 if (((i + 1) % 20) == 0)
953 fprintf (table, "\n ");
954 }
955
956 fprintf (table, "%d },\n", modifier[i].value);
957 }
958
959 /* Returns LOG2 of element size. */
960 static int
961 get_element_size (char **opnd, int lineno)
962 {
963 char *str, *next, *last, *op;
964 const char *full = opnd[0];
965 int elem_size = INT_MAX;
966
967 /* Find the memory operand. */
968 while (full != NULL && strstr(full, "BaseIndex") == NULL)
969 full = *++opnd;
970 if (full == NULL)
971 fail ("%s: %d: no memory operand\n", filename, lineno);
972
973 op = xstrdup (full);
974 last = op + strlen (op);
975 for (next = op; next && next < last; )
976 {
977 str = next_field (next, '|', &next, last);
978 if (str)
979 {
980 if (strcasecmp(str, "Byte") == 0)
981 {
982 /* The smallest element size, no need to check
983 further. */
984 elem_size = 0;
985 break;
986 }
987 else if (strcasecmp(str, "Word") == 0)
988 {
989 if (elem_size > 1)
990 elem_size = 1;
991 }
992 else if (strcasecmp(str, "Dword") == 0)
993 {
994 if (elem_size > 2)
995 elem_size = 2;
996 }
997 else if (strcasecmp(str, "Qword") == 0)
998 {
999 if (elem_size > 3)
1000 elem_size = 3;
1001 }
1002 }
1003 }
1004 free (op);
1005
1006 if (elem_size == INT_MAX)
1007 fail ("%s: %d: unknown element size: %s\n", filename, lineno, full);
1008
1009 return elem_size;
1010 }
1011
1012 static void
1013 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1014 unsigned int prefix, const char *extension_opcode,
1015 char **opnd, int lineno)
1016 {
1017 char *str, *next, *last;
1018 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1019 static const char *const spaces[] = {
1020 #define SPACE(n) [SPACE_##n] = #n
1021 SPACE(BASE),
1022 SPACE(0F),
1023 SPACE(0F38),
1024 SPACE(0F3A),
1025 SPACE(EVEXMAP5),
1026 SPACE(EVEXMAP6),
1027 SPACE(VEXMAP7),
1028 SPACE(XOP08),
1029 SPACE(XOP09),
1030 SPACE(XOP0A),
1031 #undef SPACE
1032 };
1033
1034 active_isstring = 0;
1035
1036 /* Copy the default opcode modifier. */
1037 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1038
1039 if (strcmp (mod, "0"))
1040 {
1041 unsigned int have_w = 0, bwlq_suf = 0xf;
1042
1043 last = mod + strlen (mod);
1044 for (next = mod; next && next < last; )
1045 {
1046 str = next_field (next, '|', &next, last);
1047 if (str)
1048 {
1049 int val = 1;
1050
1051 if (strncmp(str, "OpcodeSpace", 11) == 0)
1052 {
1053 char *end;
1054
1055 if (str[11] != '=')
1056 fail ("%s:%d: Missing value for `OpcodeSpace'\n",
1057 filename, lineno);
1058
1059 val = strtol (str + 12, &end, 0);
1060 if (*end)
1061 fail ("%s:%d: Bogus value `%s' for `OpcodeSpace'\n",
1062 filename, lineno, end);
1063
1064 if (space)
1065 {
1066 if (val != space)
1067 fail ("%s:%d: Conflicting opcode space specifications\n",
1068 filename, lineno);
1069 fprintf (stderr,
1070 "%s:%d: Warning: redundant opcode space specification\n",
1071 filename, lineno);
1072 }
1073
1074 space = val;
1075 continue;
1076 }
1077
1078 if (strcasecmp(str, "Broadcast") == 0)
1079 val = get_element_size (opnd, lineno) + BYTE_BROADCAST;
1080 else if (strcasecmp(str, "Disp8MemShift") == 0)
1081 val = get_element_size (opnd, lineno);
1082
1083 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1084 lineno);
1085 if (strcasecmp(str, "IsString") == 0)
1086 active_isstring = 1;
1087
1088 if (strcasecmp(str, "W") == 0)
1089 have_w = 1;
1090
1091 if (strcasecmp(str, "No_bSuf") == 0)
1092 bwlq_suf &= ~1;
1093 if (strcasecmp(str, "No_wSuf") == 0)
1094 bwlq_suf &= ~2;
1095 if (strcasecmp(str, "No_lSuf") == 0)
1096 bwlq_suf &= ~4;
1097 if (strcasecmp(str, "No_qSuf") == 0)
1098 bwlq_suf &= ~8;
1099 }
1100 }
1101
1102 if (prefix)
1103 {
1104 if (!modifiers[OpcodePrefix].value)
1105 modifiers[OpcodePrefix].value = prefix;
1106 else if (modifiers[OpcodePrefix].value != prefix)
1107 fail ("%s:%d: Conflicting prefix specifications\n",
1108 filename, lineno);
1109 else
1110 fprintf (stderr,
1111 "%s:%d: Warning: redundant prefix specification\n",
1112 filename, lineno);
1113 }
1114
1115 if (have_w && !bwlq_suf)
1116 fail ("%s: %d: stray W modifier\n", filename, lineno);
1117 if (have_w && !(bwlq_suf & 1))
1118 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1119 filename, lineno);
1120 if (have_w && !(bwlq_suf & ~1))
1121 fprintf (stderr,
1122 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1123 filename, lineno);
1124 }
1125
1126 if (space >= ARRAY_SIZE (spaces) || !spaces[space])
1127 fail ("%s:%d: Unknown opcode space %u\n", filename, lineno, space);
1128
1129 fprintf (table, " SPACE_%s, %s,\n",
1130 spaces[space], extension_opcode ? extension_opcode : "None");
1131
1132 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1133 }
1134
1135 enum stage {
1136 stage_macros,
1137 stage_opcodes,
1138 stage_registers,
1139 };
1140
1141 static void
1142 output_operand_type (FILE *table, enum operand_class class,
1143 enum operand_instance instance,
1144 const bitfield *types, unsigned int size,
1145 enum stage stage, const char *indent)
1146 {
1147 unsigned int i;
1148
1149 fprintf (table, "{ { %d, %d, ", class, instance);
1150
1151 for (i = 0; i < size - 1; i++)
1152 {
1153 if (((i + 3) % 20) != 0)
1154 fprintf (table, "%d, ", types[i].value);
1155 else
1156 fprintf (table, "%d,", types[i].value);
1157 if (((i + 3) % 20) == 0)
1158 {
1159 /* We need \\ for macro. */
1160 if (stage == stage_macros)
1161 fprintf (table, " \\\n%s", indent);
1162 else
1163 fprintf (table, "\n%s", indent);
1164 }
1165 }
1166
1167 fprintf (table, "%d } }", types[i].value);
1168 }
1169
1170 static void
1171 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1172 const char *indent, int lineno)
1173 {
1174 char *str, *next, *last;
1175 enum operand_class class = ClassNone;
1176 enum operand_instance instance = InstanceNone;
1177 bitfield types [ARRAY_SIZE (operand_types)];
1178
1179 /* Copy the default operand type. */
1180 memcpy (types, operand_types, sizeof (types));
1181
1182 if (strcmp (op, "0"))
1183 {
1184 int baseindex = 0;
1185
1186 last = op + strlen (op);
1187 for (next = op; next && next < last; )
1188 {
1189 str = next_field (next, '|', &next, last);
1190 if (str)
1191 {
1192 unsigned int i;
1193
1194 if (!strncmp(str, "Class=", 6))
1195 {
1196 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1197 if (!strcmp(str + 6, operand_classes[i].name))
1198 {
1199 class = operand_classes[i].value;
1200 str = NULL;
1201 break;
1202 }
1203 }
1204
1205 if (str && !strncmp(str, "Instance=", 9))
1206 {
1207 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1208 if (!strcmp(str + 9, operand_instances[i].name))
1209 {
1210 instance = operand_instances[i].value;
1211 str = NULL;
1212 break;
1213 }
1214 }
1215 }
1216 if (str)
1217 {
1218 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1219 if (strcasecmp(str, "BaseIndex") == 0)
1220 baseindex = 1;
1221 }
1222 }
1223
1224 if (stage == stage_opcodes && baseindex && !active_isstring)
1225 {
1226 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1227 if (!active_cpu_flags.bitfield.cpu64
1228 && !active_cpu_flags.bitfield.cpumpx)
1229 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1230 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1231 }
1232 }
1233 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1234 stage, indent);
1235 }
1236
1237 static char *mkident (const char *mnem)
1238 {
1239 char *ident = xstrdup (mnem), *p = ident;
1240
1241 do
1242 {
1243 if (!ISALNUM (*p))
1244 *p = '_';
1245 }
1246 while (*++p);
1247
1248 return ident;
1249 }
1250
1251 static void
1252 output_i386_opcode (FILE *table, const char *name, char *str,
1253 char *last, int lineno)
1254 {
1255 unsigned int i, length, prefix = 0, space = 0;
1256 char *base_opcode, *extension_opcode, *end, *ident;
1257 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1258 unsigned long long opcode;
1259
1260 /* Find base_opcode. */
1261 base_opcode = next_field (str, ',', &str, last);
1262
1263 /* Find extension_opcode, if any. */
1264 extension_opcode = strchr (base_opcode, '/');
1265 if (extension_opcode)
1266 *extension_opcode++ = '\0';
1267
1268 /* Find cpu_flags. */
1269 cpu_flags = next_field (str, ',', &str, last);
1270
1271 /* Find opcode_modifier. */
1272 opcode_modifier = next_field (str, ',', &str, last);
1273
1274 /* Remove the first {. */
1275 str = remove_leading_whitespaces (str);
1276 if (*str != '{')
1277 abort ();
1278 str = remove_leading_whitespaces (str + 1);
1279 remove_trailing_whitespaces (str);
1280
1281 /* Remove } and trailing white space. */
1282 i = strlen (str);
1283 if (!i || str[i - 1] != '}')
1284 abort ();
1285 str[--i] = '\0';
1286 remove_trailing_whitespaces (str);
1287
1288 if (!*str)
1289 operand_types [i = 0] = NULL;
1290 else
1291 {
1292 last = str + strlen (str);
1293
1294 /* Find operand_types. */
1295 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1296 {
1297 if (str >= last)
1298 {
1299 operand_types [i] = NULL;
1300 break;
1301 }
1302
1303 operand_types [i] = next_field (str, ',', &str, last);
1304 }
1305 }
1306
1307 opcode = strtoull (base_opcode, &end, 0);
1308
1309 /* Determine opcode length. */
1310 for (length = 1; length < 8; ++length)
1311 if (!(opcode >> (8 * length)))
1312 break;
1313
1314 /* Transform prefixes encoded in the opcode into opcode modifier
1315 representation. */
1316 if (length > 1)
1317 {
1318 switch (opcode >> (8 * length - 8))
1319 {
1320 case 0x66: prefix = PREFIX_0X66; break;
1321 case 0xF3: prefix = PREFIX_0XF3; break;
1322 case 0xF2: prefix = PREFIX_0XF2; break;
1323 }
1324
1325 if (prefix)
1326 opcode &= (1ULL << (8 * --length)) - 1;
1327 }
1328
1329 /* Transform opcode space encoded in the opcode into opcode modifier
1330 representation. */
1331 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1332 {
1333 switch ((opcode >> (8 * length - 16)) & 0xff)
1334 {
1335 default: space = SPACE_0F; break;
1336 case 0x38: space = SPACE_0F38; break;
1337 case 0x3A: space = SPACE_0F3A; break;
1338 }
1339
1340 if (space != SPACE_0F && --length == 1)
1341 fail ("%s:%d: %s: unrecognized opcode encoding space\n",
1342 filename, lineno, name);
1343 opcode &= (1ULL << (8 * --length)) - 1;
1344 }
1345
1346 if (length > 2)
1347 fail ("%s:%d: %s: residual opcode (0x%0*llx) too large\n",
1348 filename, lineno, name, 2 * length, opcode);
1349
1350 ident = mkident (name);
1351 fprintf (table, " { MN_%s, 0x%0*llx%s, %u,",
1352 ident, 2 * (int)length, opcode, end, i);
1353 free (ident);
1354
1355 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1356 extension_opcode, operand_types, lineno);
1357
1358 process_i386_cpu_flag (table, cpu_flags, NULL, ",", " ", lineno, CpuMax);
1359
1360 fprintf (table, " { ");
1361
1362 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1363 {
1364 if (!operand_types[i])
1365 {
1366 if (i == 0)
1367 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1368 lineno);
1369 break;
1370 }
1371
1372 if (i != 0)
1373 fprintf (table, ",\n ");
1374
1375 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1376 "\t ", lineno);
1377 }
1378 fprintf (table, " } },\n");
1379 }
1380
1381 struct opcode_hash_entry
1382 {
1383 const char *name;
1384 struct opcode_entry
1385 {
1386 struct opcode_entry *next;
1387 char *opcode;
1388 int lineno;
1389 } entry;
1390 };
1391
1392 /* Calculate the hash value of an opcode hash entry P. */
1393
1394 static hashval_t
1395 opcode_hash_hash (const void *p)
1396 {
1397 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1398 return htab_hash_string (entry->name);
1399 }
1400
1401 /* Compare a string Q against an opcode hash entry P. */
1402
1403 static int
1404 opcode_hash_eq (const void *p, const void *q)
1405 {
1406 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1407 const char *name = (const char *) q;
1408 return strcmp (name, entry->name) == 0;
1409 }
1410
1411 static void
1412 parse_template (char *buf, int lineno)
1413 {
1414 char sep, *end, *name;
1415 struct template *tmpl;
1416 struct template_instance *last_inst = NULL;
1417
1418 buf = remove_leading_whitespaces (buf + 1);
1419 end = strchr (buf, ':');
1420 if (end == NULL)
1421 {
1422 struct template *prev = NULL;
1423
1424 end = strchr (buf, '>');
1425 if (end == NULL)
1426 fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
1427 if (*remove_leading_whitespaces (end + 1))
1428 fail ("%s: %d: malformed template purge\n", filename, lineno);
1429 *end = '\0';
1430 remove_trailing_whitespaces (buf);
1431 /* Don't bother freeing the various structures. */
1432 for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
1433 if (!strcmp (buf, tmpl->name))
1434 break;
1435 if (tmpl == NULL)
1436 fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
1437 if (prev)
1438 prev->next = tmpl->next;
1439 else
1440 templates = tmpl->next;
1441 return;
1442 }
1443 *end++ = '\0';
1444 remove_trailing_whitespaces (buf);
1445
1446 if (*buf == '\0')
1447 fail ("%s: %d: missing template identifier\n", filename, lineno);
1448 tmpl = xmalloc (sizeof (*tmpl));
1449 tmpl->name = xstrdup (buf);
1450
1451 tmpl->params = NULL;
1452 do {
1453 struct template_param *param;
1454
1455 buf = remove_leading_whitespaces (end);
1456 end = strpbrk (buf, ":,");
1457 if (end == NULL)
1458 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1459
1460 sep = *end;
1461 *end++ = '\0';
1462 remove_trailing_whitespaces (buf);
1463
1464 param = xmalloc (sizeof (*param));
1465 param->name = xstrdup (buf);
1466 param->next = tmpl->params;
1467 tmpl->params = param;
1468 } while (sep == ':');
1469
1470 tmpl->instances = NULL;
1471 do {
1472 struct template_instance *inst;
1473 char *cur, *next;
1474 const struct template_param *param;
1475
1476 buf = remove_leading_whitespaces (end);
1477 end = strpbrk (buf, ",>");
1478 if (end == NULL)
1479 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1480
1481 sep = *end;
1482 *end++ = '\0';
1483
1484 inst = xmalloc (sizeof (*inst));
1485 inst->next = NULL;
1486 inst->args = NULL;
1487
1488 cur = next_field (buf, ':', &next, end);
1489 inst->name = *cur != '$' ? xstrdup (cur) : "";
1490
1491 for (param = tmpl->params; param; param = param->next)
1492 {
1493 struct template_arg *arg = xmalloc (sizeof (*arg));
1494
1495 cur = next_field (next, ':', &next, end);
1496 if (next > end)
1497 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1498 arg->val = xstrdup (cur);
1499 arg->next = inst->args;
1500 inst->args = arg;
1501 }
1502
1503 if (tmpl->instances)
1504 last_inst->next = inst;
1505 else
1506 tmpl->instances = inst;
1507 last_inst = inst;
1508 } while (sep == ',');
1509
1510 buf = remove_leading_whitespaces (end);
1511 if (*buf)
1512 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1513 filename, lineno, buf);
1514
1515 tmpl->next = templates;
1516 templates = tmpl;
1517 }
1518
1519 static unsigned int
1520 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1521 struct opcode_hash_entry ***opcode_array_p, int lineno)
1522 {
1523 static unsigned int idx, opcode_array_size;
1524 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1525 struct opcode_hash_entry **hash_slot;
1526 struct opcode_entry *entry;
1527 char *ptr1 = strchr(name, '<'), *ptr2;
1528
1529 if (ptr1 == NULL)
1530 {
1531 /* Get the slot in hash table. */
1532 hash_slot = (struct opcode_hash_entry **)
1533 htab_find_slot_with_hash (opcode_hash_table, name,
1534 htab_hash_string (name),
1535 INSERT);
1536
1537 if (*hash_slot == NULL)
1538 {
1539 /* It is the new one. Put it on opcode array. */
1540 if (idx >= opcode_array_size)
1541 {
1542 /* Grow the opcode array when needed. */
1543 opcode_array_size += 1024;
1544 opcode_array = (struct opcode_hash_entry **)
1545 xrealloc (opcode_array,
1546 sizeof (*opcode_array) * opcode_array_size);
1547 *opcode_array_p = opcode_array;
1548 }
1549
1550 opcode_array[idx] = (struct opcode_hash_entry *)
1551 xmalloc (sizeof (struct opcode_hash_entry));
1552 opcode_array[idx]->name = xstrdup (name);
1553 *hash_slot = opcode_array[idx];
1554 entry = &opcode_array[idx]->entry;
1555 idx++;
1556 }
1557 else
1558 {
1559 /* Append it to the existing one. */
1560 struct opcode_entry **entryp = &(*hash_slot)->entry.next;
1561
1562 while (*entryp != NULL)
1563 entryp = &(*entryp)->next;
1564 entry = (struct opcode_entry *)xmalloc (sizeof (struct opcode_entry));
1565 *entryp = entry;
1566 }
1567
1568 entry->next = NULL;
1569 entry->opcode = xstrdup (str);
1570 entry->lineno = lineno;
1571 }
1572 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1573 fail ("%s: %d: missing '>'\n", filename, lineno);
1574 else
1575 {
1576 const struct template *tmpl;
1577 const struct template_instance *inst;
1578
1579 *ptr1 = '\0';
1580 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1581 remove_trailing_whitespaces (ptr1);
1582
1583 *ptr2++ = '\0';
1584
1585 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1586 if (!strcmp(ptr1, tmpl->name))
1587 break;
1588 if (!tmpl)
1589 fail ("reference to unknown template '%s'\n", ptr1);
1590
1591 for (inst = tmpl->instances; inst; inst = inst->next)
1592 {
1593 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1594 char *str2 = xmalloc(2 * strlen(str));
1595 const char *src;
1596
1597 strcpy (name2, name);
1598 strcat (name2, inst->name);
1599 strcat (name2, ptr2);
1600
1601 for (ptr1 = str2, src = str; *src; )
1602 {
1603 const char *ident = tmpl->name, *end;
1604 const struct template_param *param;
1605 const struct template_arg *arg;
1606
1607 if ((*ptr1 = *src++) != '<')
1608 {
1609 ++ptr1;
1610 continue;
1611 }
1612 while (ISSPACE(*src))
1613 ++src;
1614 while (*ident && *src == *ident)
1615 ++src, ++ident;
1616 while (ISSPACE(*src))
1617 ++src;
1618 if (*src != ':' || *ident != '\0')
1619 {
1620 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1621 ptr1 += ident - tmpl->name;
1622 continue;
1623 }
1624 while (ISSPACE(*++src))
1625 ;
1626
1627 end = src;
1628 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1629 ++end;
1630
1631 for (param = tmpl->params, arg = inst->args; param;
1632 param = param->next, arg = arg->next)
1633 {
1634 if (end - src == strlen (param->name)
1635 && !memcmp (src, param->name, end - src))
1636 {
1637 src = end;
1638 break;
1639 }
1640 }
1641
1642 if (param == NULL)
1643 fail ("template '%s' has no parameter '%.*s'\n",
1644 tmpl->name, (int)(end - src), src);
1645
1646 while (ISSPACE(*src))
1647 ++src;
1648 if (*src != '>')
1649 fail ("%s: %d: missing '>'\n", filename, lineno);
1650
1651 memcpy(ptr1, arg->val, strlen(arg->val));
1652 ptr1 += strlen(arg->val);
1653 ++src;
1654 }
1655
1656 *ptr1 = '\0';
1657
1658 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1659 lineno);
1660
1661 free (str2);
1662 free (name2);
1663 }
1664 }
1665
1666 return idx;
1667 }
1668
1669 static int mnemonic_cmp(const void *p1, const void *p2)
1670 {
1671 const struct opcode_hash_entry *const *e1 = p1, *const *e2 = p2;
1672 const char *s1 = (*e1)->name, *s2 = (*e2)->name;
1673 unsigned int i;
1674 size_t l1 = strlen (s1), l2 = strlen (s2);
1675
1676 for (i = 1; i <= l1 && i <= l2; ++i)
1677 {
1678 if (s1[l1 - i] != s2[l2 - i])
1679 return (unsigned char)s1[l1 - i] - (unsigned char)s2[l2 - i];
1680 }
1681
1682 return (int)(l1 - l2);
1683 }
1684
1685 static void
1686 process_i386_opcodes (FILE *table)
1687 {
1688 FILE *fp;
1689 char buf[2048];
1690 unsigned int i, j, nr, offs;
1691 size_t l;
1692 char *str, *p, *last;
1693 htab_t opcode_hash_table;
1694 struct opcode_hash_entry **opcode_array = NULL;
1695 int lineno = 0, marker = 0;
1696
1697 filename = "i386-opc.tbl";
1698 fp = stdin;
1699
1700 i = 0;
1701 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1702 opcode_hash_eq, NULL,
1703 xcalloc, free);
1704
1705 fprintf (table, "\n#include \"i386-mnem.h\"\n");
1706 fprintf (table, "\n/* i386 opcode table. */\n\n");
1707 fprintf (table, "static const insn_template i386_optab[] =\n{\n");
1708
1709 /* Put everything on opcode array. */
1710 while (!feof (fp))
1711 {
1712 char *name;
1713
1714 if (fgets (buf, sizeof (buf), fp) == NULL)
1715 break;
1716
1717 p = remove_leading_whitespaces (buf);
1718
1719 for ( ; ; )
1720 {
1721 lineno++;
1722
1723 /* Skip comments. */
1724 str = strstr (p, "//");
1725 if (str != NULL)
1726 {
1727 str[0] = '\0';
1728 remove_trailing_whitespaces (p);
1729 break;
1730 }
1731
1732 /* Look for line continuation character. */
1733 remove_trailing_whitespaces (p);
1734 j = strlen (buf);
1735 if (!j || buf[j - 1] != '+')
1736 break;
1737 if (j >= sizeof (buf) - 1)
1738 fail ("%s: %d: (continued) line too long\n", filename, lineno);
1739
1740 if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
1741 {
1742 fprintf (stderr, "%s: Line continuation on last line?\n",
1743 filename);
1744 break;
1745 }
1746 }
1747
1748 switch (p[0])
1749 {
1750 case '#':
1751 if (!strcmp("### MARKER ###", buf))
1752 marker = 1;
1753 else
1754 {
1755 /* Since we ignore all included files (we only care about their
1756 #define-s here), we don't need to monitor filenames. The final
1757 line number directive is going to refer to the main source file
1758 again. */
1759 char *end;
1760 unsigned long ln;
1761
1762 p = remove_leading_whitespaces (p + 1);
1763 if (!strncmp(p, "line", 4))
1764 p += 4;
1765 ln = strtoul (p, &end, 10);
1766 if (ln > 1 && ln < INT_MAX
1767 && *remove_leading_whitespaces (end) == '"')
1768 lineno = ln - 1;
1769 }
1770 /* Ignore comments. */
1771 case '\0':
1772 continue;
1773 break;
1774 case '<':
1775 parse_template (p, lineno);
1776 continue;
1777 default:
1778 if (!marker)
1779 continue;
1780 break;
1781 }
1782
1783 last = p + strlen (p);
1784
1785 /* Find name. */
1786 name = next_field (p, ',', &str, last);
1787
1788 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1789 lineno);
1790 }
1791
1792 /* Process opcode array. */
1793 for (j = 0; j < i; j++)
1794 {
1795 const char *name = opcode_array[j]->name;
1796 struct opcode_entry *next;
1797
1798 for (next = &opcode_array[j]->entry; next; next = next->next)
1799 {
1800 str = next->opcode;
1801 lineno = next->lineno;
1802 last = str + strlen (str);
1803 output_i386_opcode (table, name, str, last, lineno);
1804 }
1805 }
1806
1807 fclose (fp);
1808
1809 fprintf (table, "};\n");
1810
1811 /* Generate opcode sets array. */
1812 fprintf (table, "\n/* i386 opcode sets table. */\n\n");
1813 fprintf (table, "static const insn_template *const i386_op_sets[] =\n{\n");
1814 fprintf (table, " i386_optab,\n");
1815
1816 for (nr = j = 0; j < i; j++)
1817 {
1818 struct opcode_entry *next = &opcode_array[j]->entry;
1819
1820 do
1821 {
1822 ++nr;
1823 next = next->next;
1824 }
1825 while (next);
1826 fprintf (table, " i386_optab + %u,\n", nr);
1827 }
1828
1829 fprintf (table, "};\n");
1830
1831 /* Emit mnemonics and associated #define-s. */
1832 qsort (opcode_array, i, sizeof (*opcode_array), mnemonic_cmp);
1833
1834 fp = fopen ("i386-mnem.h", "w");
1835 if (fp == NULL)
1836 fail ("can't create i386-mnem.h, errno = %s\n",
1837 xstrerror (errno));
1838
1839 process_copyright (fp);
1840
1841 fprintf (table, "\n/* i386 mnemonics table. */\n\n");
1842 fprintf (table, "const char i386_mnemonics[] =\n");
1843 fprintf (fp, "\nextern const char i386_mnemonics[];\n\n");
1844
1845 str = NULL;
1846 for (l = strlen (opcode_array[offs = j = 0]->name); j < i; j++)
1847 {
1848 const char *name = opcode_array[j]->name;
1849 const char *next = NULL;
1850 size_t l1 = j + 1 < i ? strlen(next = opcode_array[j + 1]->name) : 0;
1851
1852 if (str == NULL)
1853 str = mkident (name);
1854 if (l < l1 && !strcmp(name, next + l1 - l))
1855 {
1856 fprintf (fp, "#define MN_%s ", str);
1857 free (str);
1858 str = mkident (next);
1859 fprintf (fp, "(MN_%s + %zu)\n", str, l1 - l);
1860 }
1861 else
1862 {
1863 fprintf (table, " \"\\0\"\"%s\"\n", name);
1864 fprintf (fp, "#define MN_%s %#x\n", str, offs + 1);
1865 offs += strlen (name) + 1;
1866 free (str);
1867 str = NULL;
1868 }
1869 l = l1;
1870 }
1871
1872 fprintf (table, " \"\\0\"\".insn\"\n");
1873 fprintf (fp, "#define MN__insn %#x\n", offs + 1);
1874
1875 fprintf (table, ";\n");
1876
1877 fclose (fp);
1878 }
1879
1880 static void
1881 process_i386_registers (FILE *table)
1882 {
1883 FILE *fp;
1884 char buf[2048];
1885 char *str, *p, *last;
1886 char *reg_name, *reg_type, *reg_flags, *reg_num;
1887 char *dw2_32_num, *dw2_64_num;
1888 int lineno = 0;
1889
1890 filename = "i386-reg.tbl";
1891 fp = fopen (filename, "r");
1892 if (fp == NULL)
1893 fail ("can't find i386-reg.tbl for reading, errno = %s\n",
1894 xstrerror (errno));
1895
1896 fprintf (table, "\n/* i386 register table. */\n\n");
1897 fprintf (table, "static const reg_entry i386_regtab[] =\n{\n");
1898
1899 while (!feof (fp))
1900 {
1901 if (fgets (buf, sizeof (buf), fp) == NULL)
1902 break;
1903
1904 lineno++;
1905
1906 p = remove_leading_whitespaces (buf);
1907
1908 /* Skip comments. */
1909 str = strstr (p, "//");
1910 if (str != NULL)
1911 str[0] = '\0';
1912
1913 /* Remove trailing white spaces. */
1914 remove_trailing_whitespaces (p);
1915
1916 switch (p[0])
1917 {
1918 case '#':
1919 fprintf (table, "%s\n", p);
1920 case '\0':
1921 continue;
1922 break;
1923 default:
1924 break;
1925 }
1926
1927 last = p + strlen (p);
1928
1929 /* Find reg_name. */
1930 reg_name = next_field (p, ',', &str, last);
1931
1932 /* Find reg_type. */
1933 reg_type = next_field (str, ',', &str, last);
1934
1935 /* Find reg_flags. */
1936 reg_flags = next_field (str, ',', &str, last);
1937
1938 /* Find reg_num. */
1939 reg_num = next_field (str, ',', &str, last);
1940
1941 fprintf (table, " { \"%s\",\n ", reg_name);
1942
1943 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1944 lineno);
1945
1946 /* Find 32-bit Dwarf2 register number. */
1947 dw2_32_num = next_field (str, ',', &str, last);
1948
1949 /* Find 64-bit Dwarf2 register number. */
1950 dw2_64_num = next_field (str, ',', &str, last);
1951
1952 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1953 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1954 }
1955
1956 fclose (fp);
1957
1958 fprintf (table, "};\n");
1959
1960 fprintf (table, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1961 }
1962
1963 static void
1964 process_i386_initializers (void)
1965 {
1966 unsigned int i;
1967 FILE *fp = fopen ("i386-init.h", "w");
1968
1969 if (fp == NULL)
1970 fail ("can't create i386-init.h, errno = %s\n",
1971 xstrerror (errno));
1972
1973 process_copyright (fp);
1974
1975 for (i = 0; i < CpuMax; i++)
1976 process_i386_cpu_flag (fp, "0", cpu_flags[i].name, "", " ", -1, i);
1977
1978 for (i = 0; i < ARRAY_SIZE (isa_dependencies); i++)
1979 {
1980 char *deps = xstrdup (isa_dependencies[i].deps);
1981
1982 process_i386_cpu_flag (fp, deps, isa_dependencies[i].name,
1983 "", " ", -1, CpuMax);
1984 free (deps);
1985 }
1986
1987 /* Early x87 is somewhat special: Both 287 and 387 not only add new insns
1988 but also remove some. Hence 8087 isn't a prereq to 287, and 287 isn't
1989 one to 387. We want the reverse to be true though: Disabling 8087 also
1990 is to disable 287+ and later; disabling 287 also means disabling 387+. */
1991 memcpy (isa_reverse_deps[Cpu287], isa_reverse_deps[Cpu387],
1992 sizeof (isa_reverse_deps[0]));
1993 isa_reverse_deps[Cpu287][Cpu387] = 1;
1994 memcpy (isa_reverse_deps[Cpu8087], isa_reverse_deps[Cpu287],
1995 sizeof (isa_reverse_deps[0]));
1996 isa_reverse_deps[Cpu8087][Cpu287] = 1;
1997
1998 /* While we treat POPCNT as a prereq to SSE4.2, its disabling should not
1999 lead to disabling of anything else. */
2000 memset (isa_reverse_deps[CpuPOPCNT], 0, sizeof (isa_reverse_deps[0]));
2001
2002 for (i = Cpu686 + 1; i < ARRAY_SIZE (isa_reverse_deps); i++)
2003 {
2004 size_t len;
2005 char *upper;
2006
2007 if (memchr(isa_reverse_deps[i], 1,
2008 ARRAY_SIZE (isa_reverse_deps[0])) == NULL)
2009 continue;
2010
2011 isa_reverse_deps[i][i] = 1;
2012 process_i386_cpu_flag (fp, NULL, cpu_flags[i].name, "", " ", -1, i);
2013 }
2014
2015 fprintf (fp, "\n");
2016
2017 fclose (fp);
2018 }
2019
2020 /* Program options. */
2021 #define OPTION_SRCDIR 200
2022
2023 struct option long_options[] =
2024 {
2025 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
2026 {"debug", no_argument, NULL, 'd'},
2027 {"version", no_argument, NULL, 'V'},
2028 {"help", no_argument, NULL, 'h'},
2029 {0, no_argument, NULL, 0}
2030 };
2031
2032 static void
2033 print_version (void)
2034 {
2035 printf ("%s: version 1.0\n", program_name);
2036 xexit (0);
2037 }
2038
2039 static void
2040 usage (FILE * stream, int status)
2041 {
2042 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2043 program_name);
2044 xexit (status);
2045 }
2046
2047 int
2048 main (int argc, char **argv)
2049 {
2050 extern int chdir (char *);
2051 char *srcdir = NULL;
2052 int c;
2053 unsigned int i, cpumax;
2054 FILE *table;
2055
2056 program_name = *argv;
2057 xmalloc_set_program_name (program_name);
2058
2059 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2060 switch (c)
2061 {
2062 case OPTION_SRCDIR:
2063 srcdir = optarg;
2064 break;
2065 case 'V':
2066 case 'v':
2067 print_version ();
2068 break;
2069 case 'd':
2070 debug = 1;
2071 break;
2072 case 'h':
2073 case '?':
2074 usage (stderr, 0);
2075 default:
2076 case 0:
2077 break;
2078 }
2079
2080 if (optind != argc)
2081 usage (stdout, 1);
2082
2083 if (srcdir != NULL)
2084 if (chdir (srcdir) != 0)
2085 fail ("unable to change directory to \"%s\", errno = %s\n",
2086 srcdir, xstrerror (errno));
2087
2088 /* cpu_flags isn't sorted by position. */
2089 cpumax = 0;
2090 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2091 if (cpu_flags[i].position > cpumax)
2092 cpumax = cpu_flags[i].position;
2093
2094 /* Check the unused bitfield in i386_cpu_flags. */
2095 #ifdef CpuUnused
2096 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2097
2098 if ((cpumax - 1) != CpuMax)
2099 fail ("CpuMax != %d!\n", cpumax);
2100 #else
2101 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2102
2103 if (cpumax != CpuMax)
2104 fail ("CpuMax != %d!\n", cpumax);
2105
2106 c = CpuNumOfBits - CpuMax - 1;
2107 if (c)
2108 fail ("%d unused bits in i386_cpu_flags.\n", c);
2109 #endif
2110
2111 /* If this triggers, CpuIsaBits needs to be increased. */
2112 static_assert (CpuAttrEnums <= (1u << CpuIsaBits));
2113
2114 /* Check the unused bitfield in i386_cpu_attr. */
2115 #ifndef CpuAttrUnused
2116 c = CpuAttrNumOfBits - (CpuIsaBits + CpuMax + 1 - CpuAttrEnums);
2117 if (c)
2118 fail ("%d unused bits in i386_cpu_attr.\n", c);
2119 #endif
2120
2121 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2122
2123 /* Check the unused bitfield in i386_operand_type. */
2124 #ifdef OTUnused
2125 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2126 == OTNum + 1);
2127 #else
2128 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2129 == OTNum);
2130
2131 c = OTNumOfBits - OTNum;
2132 if (c)
2133 fail ("%d unused bits in i386_operand_type.\n", c);
2134 #endif
2135
2136 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2137 compare);
2138
2139 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2140 sizeof (opcode_modifiers [0]), compare);
2141
2142 qsort (operand_types, ARRAY_SIZE (operand_types),
2143 sizeof (operand_types [0]), compare);
2144
2145 table = fopen ("i386-tbl.h", "w");
2146 if (table == NULL)
2147 fail ("can't create i386-tbl.h, errno = %s\n",
2148 xstrerror (errno));
2149
2150 process_copyright (table);
2151
2152 process_i386_opcodes (table);
2153 process_i386_registers (table);
2154 process_i386_initializers ();
2155
2156 fclose (table);
2157
2158 exit (0);
2159 }