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