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