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