]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/i386-gen.c
x86: re-use insn mnemonic strings as much as possible
[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 #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 int mnemonic_cmp(const void *p1, const void *p2)
1580 {
1581 const struct opcode_hash_entry *const *e1 = p1, *const *e2 = p2;
1582 const char *s1 = (*e1)->name, *s2 = (*e2)->name;
1583 unsigned int i;
1584 size_t l1 = strlen (s1), l2 = strlen (s2);
1585
1586 for (i = 1; i <= l1 && i <= l2; ++i)
1587 {
1588 if (s1[l1 - i] != s2[l2 - i])
1589 return (unsigned char)s1[l1 - i] - (unsigned char)s2[l2 - i];
1590 }
1591
1592 return (int)(l1 - l2);
1593 }
1594
1595 static void
1596 process_i386_opcodes (FILE *table)
1597 {
1598 FILE *fp;
1599 char buf[2048];
1600 unsigned int i, j, nr, offs;
1601 size_t l;
1602 char *str, *p, *last, *name;
1603 htab_t opcode_hash_table;
1604 struct opcode_hash_entry **opcode_array = NULL;
1605 int lineno = 0, marker = 0;
1606
1607 filename = "i386-opc.tbl";
1608 fp = stdin;
1609
1610 i = 0;
1611 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1612 opcode_hash_eq, NULL,
1613 xcalloc, free);
1614
1615 fprintf (table, "\n#include \"i386-mnem.h\"\n");
1616 fprintf (table, "\n/* i386 opcode table. */\n\n");
1617 fprintf (table, "static const insn_template i386_optab[] =\n{\n");
1618
1619 /* Put everything on opcode array. */
1620 while (!feof (fp))
1621 {
1622 if (fgets (buf, sizeof (buf), fp) == NULL)
1623 break;
1624
1625 p = remove_leading_whitespaces (buf);
1626
1627 for ( ; ; )
1628 {
1629 lineno++;
1630
1631 /* Skip comments. */
1632 str = strstr (p, "//");
1633 if (str != NULL)
1634 {
1635 str[0] = '\0';
1636 remove_trailing_whitespaces (p);
1637 break;
1638 }
1639
1640 /* Look for line continuation character. */
1641 remove_trailing_whitespaces (p);
1642 j = strlen (buf);
1643 if (!j || buf[j - 1] != '+')
1644 break;
1645 if (j >= sizeof (buf) - 1)
1646 fail (_("%s: %d: (continued) line too long\n"), filename, lineno);
1647
1648 if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
1649 {
1650 fprintf (stderr, "%s: Line continuation on last line?\n",
1651 filename);
1652 break;
1653 }
1654 }
1655
1656 switch (p[0])
1657 {
1658 case '#':
1659 if (!strcmp("### MARKER ###", buf))
1660 marker = 1;
1661 else
1662 {
1663 /* Since we ignore all included files (we only care about their
1664 #define-s here), we don't need to monitor filenames. The final
1665 line number directive is going to refer to the main source file
1666 again. */
1667 char *end;
1668 unsigned long ln;
1669
1670 p = remove_leading_whitespaces (p + 1);
1671 if (!strncmp(p, "line", 4))
1672 p += 4;
1673 ln = strtoul (p, &end, 10);
1674 if (ln > 1 && ln < INT_MAX
1675 && *remove_leading_whitespaces (end) == '"')
1676 lineno = ln - 1;
1677 }
1678 /* Ignore comments. */
1679 case '\0':
1680 continue;
1681 break;
1682 case '<':
1683 parse_template (p, lineno);
1684 continue;
1685 default:
1686 if (!marker)
1687 continue;
1688 break;
1689 }
1690
1691 last = p + strlen (p);
1692
1693 /* Find name. */
1694 name = next_field (p, ',', &str, last);
1695
1696 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1697 lineno);
1698 }
1699
1700 /* Process opcode array. */
1701 for (j = 0; j < i; j++)
1702 {
1703 struct opcode_hash_entry *next;
1704
1705 for (next = opcode_array[j]; next; next = next->next)
1706 {
1707 name = next->name;
1708 str = next->opcode;
1709 lineno = next->lineno;
1710 last = str + strlen (str);
1711 output_i386_opcode (table, name, str, last, lineno);
1712 }
1713 }
1714
1715 fclose (fp);
1716
1717 fprintf (table, "};\n");
1718
1719 /* Generate opcode sets array. */
1720 fprintf (table, "\n/* i386 opcode sets table. */\n\n");
1721 fprintf (table, "static const insn_template *const i386_op_sets[] =\n{\n");
1722 fprintf (table, " i386_optab,\n");
1723
1724 for (nr = j = 0; j < i; j++)
1725 {
1726 struct opcode_hash_entry *next = opcode_array[j];
1727
1728 do
1729 {
1730 ++nr;
1731 next = next->next;
1732 }
1733 while (next);
1734 fprintf (table, " i386_optab + %u,\n", nr);
1735 }
1736
1737 fprintf (table, "};\n");
1738
1739 /* Emit mnemonics and associated #define-s. */
1740 qsort (opcode_array, i, sizeof (*opcode_array), mnemonic_cmp);
1741
1742 fp = fopen ("i386-mnem.h", "w");
1743 if (fp == NULL)
1744 fail (_("can't create i386-mnem.h, errno = %s\n"),
1745 xstrerror (errno));
1746
1747 process_copyright (fp);
1748
1749 fprintf (table, "\n/* i386 mnemonics table. */\n\n");
1750 fprintf (table, "const char i386_mnemonics[] =\n");
1751 fprintf (fp, "\nextern const char i386_mnemonics[];\n\n");
1752
1753 for (l = strlen (opcode_array[offs = j = 0]->name); j < i; j++)
1754 {
1755 const char *next = NULL;
1756 size_t l1 = j + 1 < i ? strlen(next = opcode_array[j + 1]->name) : 0;
1757
1758 name = opcode_array[j]->name;
1759 str = mkident (name);
1760 if (l < l1 && !strcmp(name, next + l1 - l))
1761 {
1762 fprintf (fp, "#define MN_%s ", str);
1763 free (str);
1764 str = mkident (next);
1765 fprintf (fp, "(MN_%s + %u)\n", str, l1 - l);
1766 }
1767 else
1768 {
1769 fprintf (table, " \"\\0\"\"%s\"\n", name);
1770 fprintf (fp, "#define MN_%s %#x\n", str, offs + 1);
1771 offs += strlen (name) + 1;
1772 }
1773 free (str);
1774 l = l1;
1775 }
1776
1777 fprintf (table, ";\n");
1778
1779 fclose (fp);
1780 }
1781
1782 static void
1783 process_i386_registers (FILE *table)
1784 {
1785 FILE *fp;
1786 char buf[2048];
1787 char *str, *p, *last;
1788 char *reg_name, *reg_type, *reg_flags, *reg_num;
1789 char *dw2_32_num, *dw2_64_num;
1790 int lineno = 0;
1791
1792 filename = "i386-reg.tbl";
1793 fp = fopen (filename, "r");
1794 if (fp == NULL)
1795 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1796 xstrerror (errno));
1797
1798 fprintf (table, "\n/* i386 register table. */\n\n");
1799 fprintf (table, "static const reg_entry i386_regtab[] =\n{\n");
1800
1801 while (!feof (fp))
1802 {
1803 if (fgets (buf, sizeof (buf), fp) == NULL)
1804 break;
1805
1806 lineno++;
1807
1808 p = remove_leading_whitespaces (buf);
1809
1810 /* Skip comments. */
1811 str = strstr (p, "//");
1812 if (str != NULL)
1813 str[0] = '\0';
1814
1815 /* Remove trailing white spaces. */
1816 remove_trailing_whitespaces (p);
1817
1818 switch (p[0])
1819 {
1820 case '#':
1821 fprintf (table, "%s\n", p);
1822 case '\0':
1823 continue;
1824 break;
1825 default:
1826 break;
1827 }
1828
1829 last = p + strlen (p);
1830
1831 /* Find reg_name. */
1832 reg_name = next_field (p, ',', &str, last);
1833
1834 /* Find reg_type. */
1835 reg_type = next_field (str, ',', &str, last);
1836
1837 /* Find reg_flags. */
1838 reg_flags = next_field (str, ',', &str, last);
1839
1840 /* Find reg_num. */
1841 reg_num = next_field (str, ',', &str, last);
1842
1843 fprintf (table, " { \"%s\",\n ", reg_name);
1844
1845 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1846 lineno);
1847
1848 /* Find 32-bit Dwarf2 register number. */
1849 dw2_32_num = next_field (str, ',', &str, last);
1850
1851 /* Find 64-bit Dwarf2 register number. */
1852 dw2_64_num = next_field (str, ',', &str, last);
1853
1854 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1855 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1856 }
1857
1858 fclose (fp);
1859
1860 fprintf (table, "};\n");
1861
1862 fprintf (table, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1863 }
1864
1865 static void
1866 process_i386_initializers (void)
1867 {
1868 unsigned int i;
1869 FILE *fp = fopen ("i386-init.h", "w");
1870
1871 if (fp == NULL)
1872 fail (_("can't create i386-init.h, errno = %s\n"),
1873 xstrerror (errno));
1874
1875 process_copyright (fp);
1876
1877 for (i = 0; i < Cpu64; i++)
1878 process_i386_cpu_flag (fp, "0", cpu_flags[i].name, "", " ", -1, i);
1879
1880 for (i = 0; i < ARRAY_SIZE (isa_dependencies); i++)
1881 {
1882 char *deps = xstrdup (isa_dependencies[i].deps);
1883
1884 process_i386_cpu_flag (fp, deps, isa_dependencies[i].name,
1885 "", " ", -1, CpuMax);
1886 free (deps);
1887 }
1888
1889 /* Early x87 is somewhat special: Both 287 and 387 not only add new insns
1890 but also remove some. Hence 8087 isn't a prereq to 287, and 287 isn't
1891 one to 387. We want the reverse to be true though: Disabling 8087 also
1892 is to disable 287+ and later; disabling 287 also means disabling 387+. */
1893 memcpy (isa_reverse_deps[Cpu287], isa_reverse_deps[Cpu387],
1894 sizeof (isa_reverse_deps[0]));
1895 isa_reverse_deps[Cpu287][Cpu387] = 1;
1896 memcpy (isa_reverse_deps[Cpu8087], isa_reverse_deps[Cpu287],
1897 sizeof (isa_reverse_deps[0]));
1898 isa_reverse_deps[Cpu8087][Cpu287] = 1;
1899
1900 /* While we treat POPCNT as a prereq to SSE4.2, its disabling should not
1901 lead to disabling of anything else. */
1902 memset (isa_reverse_deps[CpuPOPCNT], 0, sizeof (isa_reverse_deps[0]));
1903
1904 for (i = Cpu686 + 1; i < ARRAY_SIZE (isa_reverse_deps); i++)
1905 {
1906 size_t len;
1907 char *upper;
1908
1909 if (memchr(isa_reverse_deps[i], 1,
1910 ARRAY_SIZE (isa_reverse_deps[0])) == NULL)
1911 continue;
1912
1913 isa_reverse_deps[i][i] = 1;
1914 process_i386_cpu_flag (fp, NULL, cpu_flags[i].name, "", " ", -1, i);
1915 }
1916
1917 fprintf (fp, "\n");
1918
1919 fclose (fp);
1920 }
1921
1922 /* Program options. */
1923 #define OPTION_SRCDIR 200
1924
1925 struct option long_options[] =
1926 {
1927 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1928 {"debug", no_argument, NULL, 'd'},
1929 {"version", no_argument, NULL, 'V'},
1930 {"help", no_argument, NULL, 'h'},
1931 {0, no_argument, NULL, 0}
1932 };
1933
1934 static void
1935 print_version (void)
1936 {
1937 printf ("%s: version 1.0\n", program_name);
1938 xexit (0);
1939 }
1940
1941 static void
1942 usage (FILE * stream, int status)
1943 {
1944 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1945 program_name);
1946 xexit (status);
1947 }
1948
1949 int
1950 main (int argc, char **argv)
1951 {
1952 extern int chdir (char *);
1953 char *srcdir = NULL;
1954 int c;
1955 unsigned int i, cpumax;
1956 FILE *table;
1957
1958 program_name = *argv;
1959 xmalloc_set_program_name (program_name);
1960
1961 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1962 switch (c)
1963 {
1964 case OPTION_SRCDIR:
1965 srcdir = optarg;
1966 break;
1967 case 'V':
1968 case 'v':
1969 print_version ();
1970 break;
1971 case 'd':
1972 debug = 1;
1973 break;
1974 case 'h':
1975 case '?':
1976 usage (stderr, 0);
1977 default:
1978 case 0:
1979 break;
1980 }
1981
1982 if (optind != argc)
1983 usage (stdout, 1);
1984
1985 if (srcdir != NULL)
1986 if (chdir (srcdir) != 0)
1987 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1988 srcdir, xstrerror (errno));
1989
1990 /* cpu_flags isn't sorted by position. */
1991 cpumax = 0;
1992 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1993 if (cpu_flags[i].position > cpumax)
1994 cpumax = cpu_flags[i].position;
1995
1996 /* Check the unused bitfield in i386_cpu_flags. */
1997 #ifdef CpuUnused
1998 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1999
2000 if ((cpumax - 1) != CpuMax)
2001 fail (_("CpuMax != %d!\n"), cpumax);
2002 #else
2003 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2004
2005 if (cpumax != CpuMax)
2006 fail (_("CpuMax != %d!\n"), cpumax);
2007
2008 c = CpuNumOfBits - CpuMax - 1;
2009 if (c)
2010 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2011 #endif
2012
2013 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2014
2015 /* Check the unused bitfield in i386_operand_type. */
2016 #ifdef OTUnused
2017 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2018 == OTNum + 1);
2019 #else
2020 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2021 == OTNum);
2022
2023 c = OTNumOfBits - OTNum;
2024 if (c)
2025 fail (_("%d unused bits in i386_operand_type.\n"), c);
2026 #endif
2027
2028 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2029 compare);
2030
2031 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2032 sizeof (opcode_modifiers [0]), compare);
2033
2034 qsort (operand_types, ARRAY_SIZE (operand_types),
2035 sizeof (operand_types [0]), compare);
2036
2037 table = fopen ("i386-tbl.h", "w");
2038 if (table == NULL)
2039 fail (_("can't create i386-tbl.h, errno = %s\n"),
2040 xstrerror (errno));
2041
2042 process_copyright (table);
2043
2044 process_i386_opcodes (table);
2045 process_i386_registers (table);
2046 process_i386_initializers ();
2047
2048 fclose (table);
2049
2050 exit (0);
2051 }