Remove path name from test case
[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 /* Rather than evaluating multiple conditions at runtime to determine
1196 whether an EVEX encoding is being dealt with, derive that information
1197 right here. A missing EVex attribute means "dynamic". */
1198 if (!modifiers[EVex].value
1199 && (modifiers[Disp8MemShift].value
1200 || modifiers[Broadcast].value
1201 || modifiers[Masking].value
1202 || modifiers[SAE].value))
1203 modifiers[EVex].value = EVEXDYN;
1204
1205 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1206 }
1207
1208 enum stage {
1209 stage_macros,
1210 stage_opcodes,
1211 stage_registers,
1212 };
1213
1214 static void
1215 output_operand_type (FILE *table, enum operand_class class,
1216 enum operand_instance instance,
1217 const bitfield *types, unsigned int size,
1218 enum stage stage, const char *indent)
1219 {
1220 unsigned int i;
1221
1222 fprintf (table, "{ { %d, %d, ", class, instance);
1223
1224 for (i = 0; i < size - 1; i++)
1225 {
1226 if (((i + 3) % 20) != 0)
1227 fprintf (table, "%d, ", types[i].value);
1228 else
1229 fprintf (table, "%d,", types[i].value);
1230 if (((i + 3) % 20) == 0)
1231 {
1232 /* We need \\ for macro. */
1233 if (stage == stage_macros)
1234 fprintf (table, " \\\n%s", indent);
1235 else
1236 fprintf (table, "\n%s", indent);
1237 }
1238 }
1239
1240 fprintf (table, "%d } }", types[i].value);
1241 }
1242
1243 static void
1244 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1245 const char *indent, int lineno)
1246 {
1247 char *str, *next, *last;
1248 enum operand_class class = ClassNone;
1249 enum operand_instance instance = InstanceNone;
1250 bitfield types [ARRAY_SIZE (operand_types)];
1251
1252 /* Copy the default operand type. */
1253 memcpy (types, operand_types, sizeof (types));
1254
1255 if (strcmp (op, "0"))
1256 {
1257 int baseindex = 0;
1258
1259 last = op + strlen (op);
1260 for (next = op; next && next < last; )
1261 {
1262 str = next_field (next, '|', &next, last);
1263 if (str)
1264 {
1265 unsigned int i;
1266
1267 if (!strncmp(str, "Class=", 6))
1268 {
1269 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1270 if (!strcmp(str + 6, operand_classes[i].name))
1271 {
1272 class = operand_classes[i].value;
1273 str = NULL;
1274 break;
1275 }
1276 }
1277
1278 if (str && !strncmp(str, "Instance=", 9))
1279 {
1280 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1281 if (!strcmp(str + 9, operand_instances[i].name))
1282 {
1283 instance = operand_instances[i].value;
1284 str = NULL;
1285 break;
1286 }
1287 }
1288 }
1289 if (str)
1290 {
1291 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1292 if (strcasecmp(str, "BaseIndex") == 0)
1293 baseindex = 1;
1294 }
1295 }
1296
1297 if (stage == stage_opcodes && baseindex && !active_isstring)
1298 {
1299 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1300 if (!active_cpu_flags.bitfield.cpu64
1301 && !active_cpu_flags.bitfield.cpumpx)
1302 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1303 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1304 }
1305 }
1306 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1307 stage, indent);
1308 }
1309
1310 static char *mkident (const char *mnem)
1311 {
1312 char *ident = xstrdup (mnem), *p = ident;
1313
1314 do
1315 {
1316 if (!ISALNUM (*p))
1317 *p = '_';
1318 }
1319 while (*++p);
1320
1321 return ident;
1322 }
1323
1324 static void
1325 output_i386_opcode (FILE *table, const char *name, char *str,
1326 char *last, int lineno)
1327 {
1328 unsigned int i, length, prefix = 0, space = 0;
1329 char *base_opcode, *extension_opcode, *end, *ident;
1330 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1331 unsigned long long opcode;
1332
1333 /* Find base_opcode. */
1334 base_opcode = next_field (str, ',', &str, last);
1335
1336 /* Find extension_opcode, if any. */
1337 extension_opcode = strchr (base_opcode, '/');
1338 if (extension_opcode)
1339 *extension_opcode++ = '\0';
1340
1341 /* Find cpu_flags. */
1342 cpu_flags = next_field (str, ',', &str, last);
1343
1344 /* Find opcode_modifier. */
1345 opcode_modifier = next_field (str, ',', &str, last);
1346
1347 /* Remove the first {. */
1348 str = remove_leading_whitespaces (str);
1349 if (*str != '{')
1350 abort ();
1351 str = remove_leading_whitespaces (str + 1);
1352 remove_trailing_whitespaces (str);
1353
1354 /* Remove } and trailing white space. */
1355 i = strlen (str);
1356 if (!i || str[i - 1] != '}')
1357 abort ();
1358 str[--i] = '\0';
1359 remove_trailing_whitespaces (str);
1360
1361 if (!*str)
1362 operand_types [i = 0] = NULL;
1363 else
1364 {
1365 last = str + strlen (str);
1366
1367 /* Find operand_types. */
1368 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1369 {
1370 if (str >= last)
1371 {
1372 operand_types [i] = NULL;
1373 break;
1374 }
1375
1376 operand_types [i] = next_field (str, ',', &str, last);
1377 }
1378 }
1379
1380 opcode = strtoull (base_opcode, &end, 0);
1381
1382 /* Determine opcode length. */
1383 for (length = 1; length < 8; ++length)
1384 if (!(opcode >> (8 * length)))
1385 break;
1386
1387 /* Transform prefixes encoded in the opcode into opcode modifier
1388 representation. */
1389 if (length > 1)
1390 {
1391 switch (opcode >> (8 * length - 8))
1392 {
1393 case 0x66: prefix = PREFIX_0X66; break;
1394 case 0xF3: prefix = PREFIX_0XF3; break;
1395 case 0xF2: prefix = PREFIX_0XF2; break;
1396 }
1397
1398 if (prefix)
1399 opcode &= (1ULL << (8 * --length)) - 1;
1400 }
1401
1402 /* Transform opcode space encoded in the opcode into opcode modifier
1403 representation. */
1404 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1405 {
1406 switch ((opcode >> (8 * length - 16)) & 0xff)
1407 {
1408 default: space = SPACE_0F; break;
1409 case 0x38: space = SPACE_0F38; break;
1410 case 0x3A: space = SPACE_0F3A; break;
1411 }
1412
1413 if (space != SPACE_0F && --length == 1)
1414 fail ("%s:%d: %s: unrecognized opcode encoding space\n",
1415 filename, lineno, name);
1416 opcode &= (1ULL << (8 * --length)) - 1;
1417 }
1418
1419 if (length > 2)
1420 fail ("%s:%d: %s: residual opcode (0x%0*llx) too large\n",
1421 filename, lineno, name, 2 * length, opcode);
1422
1423 ident = mkident (name);
1424 fprintf (table, " { MN_%s, 0x%0*llx%s, %u,",
1425 ident, 2 * (int)length, opcode, end, i);
1426 free (ident);
1427
1428 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1429 extension_opcode, operand_types, lineno);
1430
1431 process_i386_cpu_flag (table, cpu_flags, NULL, ",", " ", lineno, CpuMax);
1432
1433 fprintf (table, " { ");
1434
1435 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1436 {
1437 if (!operand_types[i])
1438 {
1439 if (i == 0)
1440 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1441 lineno);
1442 break;
1443 }
1444
1445 if (i != 0)
1446 fprintf (table, ",\n ");
1447
1448 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1449 "\t ", lineno);
1450 }
1451 fprintf (table, " } },\n");
1452 }
1453
1454 struct opcode_hash_entry
1455 {
1456 const char *name;
1457 struct opcode_entry
1458 {
1459 struct opcode_entry *next;
1460 char *opcode;
1461 int lineno;
1462 } entry;
1463 };
1464
1465 /* Calculate the hash value of an opcode hash entry P. */
1466
1467 static hashval_t
1468 opcode_hash_hash (const void *p)
1469 {
1470 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1471 return htab_hash_string (entry->name);
1472 }
1473
1474 /* Compare a string Q against an opcode hash entry P. */
1475
1476 static int
1477 opcode_hash_eq (const void *p, const void *q)
1478 {
1479 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1480 const char *name = (const char *) q;
1481 return strcmp (name, entry->name) == 0;
1482 }
1483
1484 static void
1485 parse_template (char *buf, int lineno)
1486 {
1487 char sep, *end, *name;
1488 struct template *tmpl;
1489 struct template_instance *last_inst = NULL;
1490
1491 buf = remove_leading_whitespaces (buf + 1);
1492 end = strchr (buf, ':');
1493 if (end == NULL)
1494 {
1495 struct template *prev = NULL;
1496
1497 end = strchr (buf, '>');
1498 if (end == NULL)
1499 fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
1500 if (*remove_leading_whitespaces (end + 1))
1501 fail ("%s: %d: malformed template purge\n", filename, lineno);
1502 *end = '\0';
1503 remove_trailing_whitespaces (buf);
1504 /* Don't bother freeing the various structures. */
1505 for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
1506 if (!strcmp (buf, tmpl->name))
1507 break;
1508 if (tmpl == NULL)
1509 fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
1510 if (prev)
1511 prev->next = tmpl->next;
1512 else
1513 templates = tmpl->next;
1514 return;
1515 }
1516 *end++ = '\0';
1517 remove_trailing_whitespaces (buf);
1518
1519 if (*buf == '\0')
1520 fail ("%s: %d: missing template identifier\n", filename, lineno);
1521 tmpl = xmalloc (sizeof (*tmpl));
1522 tmpl->name = xstrdup (buf);
1523
1524 tmpl->params = NULL;
1525 do {
1526 struct template_param *param;
1527
1528 buf = remove_leading_whitespaces (end);
1529 end = strpbrk (buf, ":,");
1530 if (end == NULL)
1531 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1532
1533 sep = *end;
1534 *end++ = '\0';
1535 remove_trailing_whitespaces (buf);
1536
1537 param = xmalloc (sizeof (*param));
1538 param->name = xstrdup (buf);
1539 param->next = tmpl->params;
1540 tmpl->params = param;
1541 } while (sep == ':');
1542
1543 tmpl->instances = NULL;
1544 do {
1545 struct template_instance *inst;
1546 char *cur, *next;
1547 const struct template_param *param;
1548
1549 buf = remove_leading_whitespaces (end);
1550 end = strpbrk (buf, ",>");
1551 if (end == NULL)
1552 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1553
1554 sep = *end;
1555 *end++ = '\0';
1556
1557 inst = xmalloc (sizeof (*inst));
1558 inst->next = NULL;
1559 inst->args = NULL;
1560
1561 cur = next_field (buf, ':', &next, end);
1562 inst->name = *cur != '$' ? xstrdup (cur) : "";
1563
1564 for (param = tmpl->params; param; param = param->next)
1565 {
1566 struct template_arg *arg = xmalloc (sizeof (*arg));
1567
1568 cur = next_field (next, ':', &next, end);
1569 if (next > end)
1570 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1571 arg->val = xstrdup (cur);
1572 arg->next = inst->args;
1573 inst->args = arg;
1574 }
1575
1576 if (tmpl->instances)
1577 last_inst->next = inst;
1578 else
1579 tmpl->instances = inst;
1580 last_inst = inst;
1581 } while (sep == ',');
1582
1583 buf = remove_leading_whitespaces (end);
1584 if (*buf)
1585 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1586 filename, lineno, buf);
1587
1588 tmpl->next = templates;
1589 templates = tmpl;
1590 }
1591
1592 static unsigned int
1593 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1594 struct opcode_hash_entry ***opcode_array_p, int lineno)
1595 {
1596 static unsigned int idx, opcode_array_size;
1597 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1598 struct opcode_hash_entry **hash_slot;
1599 struct opcode_entry *entry;
1600 char *ptr1 = strchr(name, '<'), *ptr2;
1601
1602 if (ptr1 == NULL)
1603 {
1604 /* Get the slot in hash table. */
1605 hash_slot = (struct opcode_hash_entry **)
1606 htab_find_slot_with_hash (opcode_hash_table, name,
1607 htab_hash_string (name),
1608 INSERT);
1609
1610 if (*hash_slot == NULL)
1611 {
1612 /* It is the new one. Put it on opcode array. */
1613 if (idx >= opcode_array_size)
1614 {
1615 /* Grow the opcode array when needed. */
1616 opcode_array_size += 1024;
1617 opcode_array = (struct opcode_hash_entry **)
1618 xrealloc (opcode_array,
1619 sizeof (*opcode_array) * opcode_array_size);
1620 *opcode_array_p = opcode_array;
1621 }
1622
1623 opcode_array[idx] = (struct opcode_hash_entry *)
1624 xmalloc (sizeof (struct opcode_hash_entry));
1625 opcode_array[idx]->name = xstrdup (name);
1626 *hash_slot = opcode_array[idx];
1627 entry = &opcode_array[idx]->entry;
1628 idx++;
1629 }
1630 else
1631 {
1632 /* Append it to the existing one. */
1633 struct opcode_entry **entryp = &(*hash_slot)->entry.next;
1634
1635 while (*entryp != NULL)
1636 entryp = &(*entryp)->next;
1637 entry = (struct opcode_entry *)xmalloc (sizeof (struct opcode_entry));
1638 *entryp = entry;
1639 }
1640
1641 entry->next = NULL;
1642 entry->opcode = xstrdup (str);
1643 entry->lineno = lineno;
1644 }
1645 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1646 fail ("%s: %d: missing '>'\n", filename, lineno);
1647 else
1648 {
1649 const struct template *tmpl;
1650 const struct template_instance *inst;
1651
1652 *ptr1 = '\0';
1653 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1654 remove_trailing_whitespaces (ptr1);
1655
1656 *ptr2++ = '\0';
1657
1658 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1659 if (!strcmp(ptr1, tmpl->name))
1660 break;
1661 if (!tmpl)
1662 fail ("reference to unknown template '%s'\n", ptr1);
1663
1664 for (inst = tmpl->instances; inst; inst = inst->next)
1665 {
1666 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1667 char *str2 = xmalloc(2 * strlen(str));
1668 const char *src;
1669
1670 strcpy (name2, name);
1671 strcat (name2, inst->name);
1672 strcat (name2, ptr2);
1673
1674 for (ptr1 = str2, src = str; *src; )
1675 {
1676 const char *ident = tmpl->name, *end;
1677 const struct template_param *param;
1678 const struct template_arg *arg;
1679
1680 if ((*ptr1 = *src++) != '<')
1681 {
1682 ++ptr1;
1683 continue;
1684 }
1685 while (ISSPACE(*src))
1686 ++src;
1687 while (*ident && *src == *ident)
1688 ++src, ++ident;
1689 while (ISSPACE(*src))
1690 ++src;
1691 if (*src != ':' || *ident != '\0')
1692 {
1693 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1694 ptr1 += ident - tmpl->name;
1695 continue;
1696 }
1697 while (ISSPACE(*++src))
1698 ;
1699
1700 end = src;
1701 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1702 ++end;
1703
1704 for (param = tmpl->params, arg = inst->args; param;
1705 param = param->next, arg = arg->next)
1706 {
1707 if (end - src == strlen (param->name)
1708 && !memcmp (src, param->name, end - src))
1709 {
1710 src = end;
1711 break;
1712 }
1713 }
1714
1715 if (param == NULL)
1716 fail ("template '%s' has no parameter '%.*s'\n",
1717 tmpl->name, (int)(end - src), src);
1718
1719 while (ISSPACE(*src))
1720 ++src;
1721 if (*src != '>')
1722 fail ("%s: %d: missing '>'\n", filename, lineno);
1723
1724 memcpy(ptr1, arg->val, strlen(arg->val));
1725 ptr1 += strlen(arg->val);
1726 ++src;
1727 }
1728
1729 *ptr1 = '\0';
1730
1731 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1732 lineno);
1733
1734 free (str2);
1735 free (name2);
1736 }
1737 }
1738
1739 return idx;
1740 }
1741
1742 static int mnemonic_cmp(const void *p1, const void *p2)
1743 {
1744 const struct opcode_hash_entry *const *e1 = p1, *const *e2 = p2;
1745 const char *s1 = (*e1)->name, *s2 = (*e2)->name;
1746 unsigned int i;
1747 size_t l1 = strlen (s1), l2 = strlen (s2);
1748
1749 for (i = 1; i <= l1 && i <= l2; ++i)
1750 {
1751 if (s1[l1 - i] != s2[l2 - i])
1752 return (unsigned char)s1[l1 - i] - (unsigned char)s2[l2 - i];
1753 }
1754
1755 return (int)(l1 - l2);
1756 }
1757
1758 static void
1759 process_i386_opcodes (FILE *table)
1760 {
1761 FILE *fp;
1762 char buf[2048];
1763 unsigned int i, j, nr, offs;
1764 size_t l;
1765 char *str, *p, *last;
1766 htab_t opcode_hash_table;
1767 struct opcode_hash_entry **opcode_array = NULL;
1768 int lineno = 0, marker = 0;
1769
1770 filename = "i386-opc.tbl";
1771 fp = stdin;
1772
1773 i = 0;
1774 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1775 opcode_hash_eq, NULL,
1776 xcalloc, free);
1777
1778 fprintf (table, "\n#include \"i386-mnem.h\"\n");
1779 fprintf (table, "\n/* i386 opcode table. */\n\n");
1780 fprintf (table, "static const insn_template i386_optab[] =\n{\n");
1781
1782 /* Put everything on opcode array. */
1783 while (!feof (fp))
1784 {
1785 char *name;
1786
1787 if (fgets (buf, sizeof (buf), fp) == NULL)
1788 break;
1789
1790 p = remove_leading_whitespaces (buf);
1791
1792 for ( ; ; )
1793 {
1794 lineno++;
1795
1796 /* Skip comments. */
1797 str = strstr (p, "//");
1798 if (str != NULL)
1799 {
1800 str[0] = '\0';
1801 remove_trailing_whitespaces (p);
1802 break;
1803 }
1804
1805 /* Look for line continuation character. */
1806 remove_trailing_whitespaces (p);
1807 j = strlen (buf);
1808 if (!j || buf[j - 1] != '+')
1809 break;
1810 if (j >= sizeof (buf) - 1)
1811 fail ("%s: %d: (continued) line too long\n", filename, lineno);
1812
1813 if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
1814 {
1815 fprintf (stderr, "%s: Line continuation on last line?\n",
1816 filename);
1817 break;
1818 }
1819 }
1820
1821 switch (p[0])
1822 {
1823 case '#':
1824 if (!strcmp("### MARKER ###", buf))
1825 marker = 1;
1826 else
1827 {
1828 /* Since we ignore all included files (we only care about their
1829 #define-s here), we don't need to monitor filenames. The final
1830 line number directive is going to refer to the main source file
1831 again. */
1832 char *end;
1833 unsigned long ln;
1834
1835 p = remove_leading_whitespaces (p + 1);
1836 if (!strncmp(p, "line", 4))
1837 p += 4;
1838 ln = strtoul (p, &end, 10);
1839 if (ln > 1 && ln < INT_MAX
1840 && *remove_leading_whitespaces (end) == '"')
1841 lineno = ln - 1;
1842 }
1843 /* Ignore comments. */
1844 case '\0':
1845 continue;
1846 break;
1847 case '<':
1848 parse_template (p, lineno);
1849 continue;
1850 default:
1851 if (!marker)
1852 continue;
1853 break;
1854 }
1855
1856 last = p + strlen (p);
1857
1858 /* Find name. */
1859 name = next_field (p, ',', &str, last);
1860
1861 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1862 lineno);
1863 }
1864
1865 /* Process opcode array. */
1866 for (j = 0; j < i; j++)
1867 {
1868 const char *name = opcode_array[j]->name;
1869 struct opcode_entry *next;
1870
1871 for (next = &opcode_array[j]->entry; next; next = next->next)
1872 {
1873 str = next->opcode;
1874 lineno = next->lineno;
1875 last = str + strlen (str);
1876 output_i386_opcode (table, name, str, last, lineno);
1877 }
1878 }
1879
1880 fclose (fp);
1881
1882 fprintf (table, "};\n");
1883
1884 /* Generate opcode sets array. */
1885 fprintf (table, "\n/* i386 opcode sets table. */\n\n");
1886 fprintf (table, "static const insn_template *const i386_op_sets[] =\n{\n");
1887 fprintf (table, " i386_optab,\n");
1888
1889 for (nr = j = 0; j < i; j++)
1890 {
1891 struct opcode_entry *next = &opcode_array[j]->entry;
1892
1893 do
1894 {
1895 ++nr;
1896 next = next->next;
1897 }
1898 while (next);
1899 fprintf (table, " i386_optab + %u,\n", nr);
1900 }
1901
1902 fprintf (table, "};\n");
1903
1904 /* Emit mnemonics and associated #define-s. */
1905 qsort (opcode_array, i, sizeof (*opcode_array), mnemonic_cmp);
1906
1907 fp = fopen ("i386-mnem.h", "w");
1908 if (fp == NULL)
1909 fail ("can't create i386-mnem.h, errno = %s\n",
1910 xstrerror (errno));
1911
1912 process_copyright (fp);
1913
1914 fprintf (table, "\n/* i386 mnemonics table. */\n\n");
1915 fprintf (table, "const char i386_mnemonics[] =\n");
1916 fprintf (fp, "\nextern const char i386_mnemonics[];\n\n");
1917
1918 str = NULL;
1919 for (l = strlen (opcode_array[offs = j = 0]->name); j < i; j++)
1920 {
1921 const char *name = opcode_array[j]->name;
1922 const char *next = NULL;
1923 size_t l1 = j + 1 < i ? strlen(next = opcode_array[j + 1]->name) : 0;
1924
1925 if (str == NULL)
1926 str = mkident (name);
1927 if (l < l1 && !strcmp(name, next + l1 - l))
1928 {
1929 fprintf (fp, "#define MN_%s ", str);
1930 free (str);
1931 str = mkident (next);
1932 fprintf (fp, "(MN_%s + %zu)\n", str, l1 - l);
1933 }
1934 else
1935 {
1936 fprintf (table, " \"\\0\"\"%s\"\n", name);
1937 fprintf (fp, "#define MN_%s %#x\n", str, offs + 1);
1938 offs += strlen (name) + 1;
1939 free (str);
1940 str = NULL;
1941 }
1942 l = l1;
1943 }
1944
1945 fprintf (table, " \"\\0\"\".insn\"\n");
1946 fprintf (fp, "#define MN__insn %#x\n", offs + 1);
1947
1948 fprintf (table, ";\n");
1949
1950 fclose (fp);
1951 }
1952
1953 static void
1954 process_i386_registers (FILE *table)
1955 {
1956 FILE *fp;
1957 char buf[2048];
1958 char *str, *p, *last;
1959 char *reg_name, *reg_type, *reg_flags, *reg_num;
1960 char *dw2_32_num, *dw2_64_num;
1961 int lineno = 0;
1962
1963 filename = "i386-reg.tbl";
1964 fp = fopen (filename, "r");
1965 if (fp == NULL)
1966 fail ("can't find i386-reg.tbl for reading, errno = %s\n",
1967 xstrerror (errno));
1968
1969 fprintf (table, "\n/* i386 register table. */\n\n");
1970 fprintf (table, "static const reg_entry i386_regtab[] =\n{\n");
1971
1972 while (!feof (fp))
1973 {
1974 if (fgets (buf, sizeof (buf), fp) == NULL)
1975 break;
1976
1977 lineno++;
1978
1979 p = remove_leading_whitespaces (buf);
1980
1981 /* Skip comments. */
1982 str = strstr (p, "//");
1983 if (str != NULL)
1984 str[0] = '\0';
1985
1986 /* Remove trailing white spaces. */
1987 remove_trailing_whitespaces (p);
1988
1989 switch (p[0])
1990 {
1991 case '#':
1992 fprintf (table, "%s\n", p);
1993 case '\0':
1994 continue;
1995 break;
1996 default:
1997 break;
1998 }
1999
2000 last = p + strlen (p);
2001
2002 /* Find reg_name. */
2003 reg_name = next_field (p, ',', &str, last);
2004
2005 /* Find reg_type. */
2006 reg_type = next_field (str, ',', &str, last);
2007
2008 /* Find reg_flags. */
2009 reg_flags = next_field (str, ',', &str, last);
2010
2011 /* Find reg_num. */
2012 reg_num = next_field (str, ',', &str, last);
2013
2014 fprintf (table, " { \"%s\",\n ", reg_name);
2015
2016 process_i386_operand_type (table, reg_type, stage_registers, "\t",
2017 lineno);
2018
2019 /* Find 32-bit Dwarf2 register number. */
2020 dw2_32_num = next_field (str, ',', &str, last);
2021
2022 /* Find 64-bit Dwarf2 register number. */
2023 dw2_64_num = next_field (str, ',', &str, last);
2024
2025 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
2026 reg_flags, reg_num, dw2_32_num, dw2_64_num);
2027 }
2028
2029 fclose (fp);
2030
2031 fprintf (table, "};\n");
2032
2033 fprintf (table, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
2034 }
2035
2036 static void
2037 process_i386_initializers (void)
2038 {
2039 unsigned int i;
2040 FILE *fp = fopen ("i386-init.h", "w");
2041
2042 if (fp == NULL)
2043 fail ("can't create i386-init.h, errno = %s\n",
2044 xstrerror (errno));
2045
2046 process_copyright (fp);
2047
2048 for (i = 0; i < CpuMax; i++)
2049 process_i386_cpu_flag (fp, "0", cpu_flags[i].name, "", " ", -1, i);
2050
2051 for (i = 0; i < ARRAY_SIZE (isa_dependencies); i++)
2052 {
2053 char *deps = xstrdup (isa_dependencies[i].deps);
2054
2055 process_i386_cpu_flag (fp, deps, isa_dependencies[i].name,
2056 "", " ", -1, CpuMax);
2057 free (deps);
2058 }
2059
2060 /* Early x87 is somewhat special: Both 287 and 387 not only add new insns
2061 but also remove some. Hence 8087 isn't a prereq to 287, and 287 isn't
2062 one to 387. We want the reverse to be true though: Disabling 8087 also
2063 is to disable 287+ and later; disabling 287 also means disabling 387+. */
2064 memcpy (isa_reverse_deps[Cpu287], isa_reverse_deps[Cpu387],
2065 sizeof (isa_reverse_deps[0]));
2066 isa_reverse_deps[Cpu287][Cpu387] = 1;
2067 memcpy (isa_reverse_deps[Cpu8087], isa_reverse_deps[Cpu287],
2068 sizeof (isa_reverse_deps[0]));
2069 isa_reverse_deps[Cpu8087][Cpu287] = 1;
2070
2071 /* While we treat POPCNT as a prereq to SSE4.2, its disabling should not
2072 lead to disabling of anything else. */
2073 memset (isa_reverse_deps[CpuPOPCNT], 0, sizeof (isa_reverse_deps[0]));
2074
2075 for (i = Cpu686 + 1; i < ARRAY_SIZE (isa_reverse_deps); i++)
2076 {
2077 size_t len;
2078 char *upper;
2079
2080 if (memchr(isa_reverse_deps[i], 1,
2081 ARRAY_SIZE (isa_reverse_deps[0])) == NULL)
2082 continue;
2083
2084 isa_reverse_deps[i][i] = 1;
2085 process_i386_cpu_flag (fp, NULL, cpu_flags[i].name, "", " ", -1, i);
2086 }
2087
2088 fprintf (fp, "\n");
2089
2090 fclose (fp);
2091 }
2092
2093 /* Program options. */
2094 #define OPTION_SRCDIR 200
2095
2096 struct option long_options[] =
2097 {
2098 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
2099 {"debug", no_argument, NULL, 'd'},
2100 {"version", no_argument, NULL, 'V'},
2101 {"help", no_argument, NULL, 'h'},
2102 {0, no_argument, NULL, 0}
2103 };
2104
2105 static void
2106 print_version (void)
2107 {
2108 printf ("%s: version 1.0\n", program_name);
2109 xexit (0);
2110 }
2111
2112 static void
2113 usage (FILE * stream, int status)
2114 {
2115 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2116 program_name);
2117 xexit (status);
2118 }
2119
2120 int
2121 main (int argc, char **argv)
2122 {
2123 extern int chdir (char *);
2124 char *srcdir = NULL;
2125 int c;
2126 unsigned int i, cpumax;
2127 FILE *table;
2128
2129 program_name = *argv;
2130 xmalloc_set_program_name (program_name);
2131
2132 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2133 switch (c)
2134 {
2135 case OPTION_SRCDIR:
2136 srcdir = optarg;
2137 break;
2138 case 'V':
2139 case 'v':
2140 print_version ();
2141 break;
2142 case 'd':
2143 debug = 1;
2144 break;
2145 case 'h':
2146 case '?':
2147 usage (stderr, 0);
2148 default:
2149 case 0:
2150 break;
2151 }
2152
2153 if (optind != argc)
2154 usage (stdout, 1);
2155
2156 if (srcdir != NULL)
2157 if (chdir (srcdir) != 0)
2158 fail ("unable to change directory to \"%s\", errno = %s\n",
2159 srcdir, xstrerror (errno));
2160
2161 /* cpu_flags isn't sorted by position. */
2162 cpumax = 0;
2163 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2164 if (cpu_flags[i].position > cpumax)
2165 cpumax = cpu_flags[i].position;
2166
2167 /* Check the unused bitfield in i386_cpu_flags. */
2168 #ifdef CpuUnused
2169 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2170
2171 if ((cpumax - 1) != CpuMax)
2172 fail ("CpuMax != %d!\n", cpumax);
2173 #else
2174 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2175
2176 if (cpumax != CpuMax)
2177 fail ("CpuMax != %d!\n", cpumax);
2178
2179 c = CpuNumOfBits - CpuMax - 1;
2180 if (c)
2181 fail ("%d unused bits in i386_cpu_flags.\n", c);
2182 #endif
2183
2184 /* If this triggers, CpuIsaBits needs to be increased. */
2185 static_assert (CpuAttrEnums <= (1u << CpuIsaBits));
2186
2187 /* Check the unused bitfield in i386_cpu_attr. */
2188 #ifndef CpuAttrUnused
2189 c = CpuAttrNumOfBits - (CpuIsaBits + CpuMax + 1 - CpuAttrEnums);
2190 if (c)
2191 fail ("%d unused bits in i386_cpu_attr.\n", c);
2192 #endif
2193
2194 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2195
2196 /* Check the unused bitfield in i386_operand_type. */
2197 #ifdef OTUnused
2198 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2199 == OTNum + 1);
2200 #else
2201 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2202 == OTNum);
2203
2204 c = OTNumOfBits - OTNum;
2205 if (c)
2206 fail ("%d unused bits in i386_operand_type.\n", c);
2207 #endif
2208
2209 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2210 compare);
2211
2212 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2213 sizeof (opcode_modifiers [0]), compare);
2214
2215 qsort (operand_types, ARRAY_SIZE (operand_types),
2216 sizeof (operand_types [0]), compare);
2217
2218 process_i386_initializers ();
2219
2220 table = fopen ("i386-tbl.h", "w");
2221 if (table == NULL)
2222 fail ("can't create i386-tbl.h, errno = %s\n",
2223 xstrerror (errno));
2224
2225 process_copyright (table);
2226
2227 process_i386_opcodes (table);
2228 process_i386_registers (table);
2229
2230 fclose (table);
2231
2232 exit (0);
2233 }