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