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