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