1 /* Copyright (C) 2007-2015 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
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)
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.
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. */
24 #include "libiberty.h"
26 #include "safe-ctype.h"
31 #define _(String) gettext (String)
33 static const char *program_name
= NULL
;
36 typedef struct initializer
42 static initializer cpu_flag_init
[] =
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
57 "Cpu186|Cpu286|Cpu386" },
59 "Cpu186|Cpu286|Cpu386|Cpu486" },
61 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
63 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
67 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
69 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
71 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
73 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM|CpuCX16" },
75 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuCX16" },
77 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM|CpuCX16" },
79 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM|CpuCX16" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
83 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
87 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
91 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
95 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase" },
97 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd" },
99 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
100 { "CPU_BTVER2_FLAGS",
101 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuSSE4_1|CpuSSE4_2|CpuABM|CpuLM|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
109 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
110 { "CPU_CLFLUSH_FLAGS",
114 { "CPU_SYSCALL_FLAGS",
121 "CpuMMX|CpuSSE|CpuSSE2" },
123 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
125 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
126 { "CPU_SSE4_1_FLAGS",
127 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
128 { "CPU_SSE4_2_FLAGS",
129 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
130 { "CPU_ANY_SSE_FLAGS",
131 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
138 { "CPU_XSAVEOPT_FLAGS",
141 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
145 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
147 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
149 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
160 { "CPU_RDTSCP_FLAGS",
164 { "CPU_FSGSBASE_FLAGS",
178 { "CPU_INVPCID_FLAGS",
180 { "CPU_VMFUNC_FLAGS",
184 { "CPU_3DNOWA_FLAGS",
185 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
191 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
195 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
197 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
198 { "CPU_AVX512F_FLAGS",
199 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
200 { "CPU_AVX512CD_FLAGS",
201 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
202 { "CPU_AVX512ER_FLAGS",
203 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
204 { "CPU_AVX512PF_FLAGS",
205 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
206 { "CPU_ANY_AVX_FLAGS",
207 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
214 { "CPU_RDSEED_FLAGS",
216 { "CPU_PRFCHW_FLAGS",
224 { "CPU_CLFLUSHOPT_FLAGS",
226 { "CPU_XSAVES_FLAGS",
228 { "CPU_XSAVEC_FLAGS",
230 { "CPU_PREFETCHWT1_FLAGS",
234 { "CPU_AVX512DQ_FLAGS",
235 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512DQ" },
236 { "CPU_AVX512BW_FLAGS",
237 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512BW" },
238 { "CPU_AVX512VL_FLAGS",
239 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VL" },
242 { "CPU_PCOMMIT_FLAGS",
244 { "CPU_AVX512IFMA_FLAGS",
245 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512IFMA" },
246 { "CPU_AVX512VBMI_FLAGS",
247 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VBMI" },
250 static initializer operand_type_init
[] =
252 { "OPERAND_TYPE_NONE",
254 { "OPERAND_TYPE_REG8",
256 { "OPERAND_TYPE_REG16",
258 { "OPERAND_TYPE_REG32",
260 { "OPERAND_TYPE_REG64",
262 { "OPERAND_TYPE_IMM1",
264 { "OPERAND_TYPE_IMM8",
266 { "OPERAND_TYPE_IMM8S",
268 { "OPERAND_TYPE_IMM16",
270 { "OPERAND_TYPE_IMM32",
272 { "OPERAND_TYPE_IMM32S",
274 { "OPERAND_TYPE_IMM64",
276 { "OPERAND_TYPE_BASEINDEX",
278 { "OPERAND_TYPE_DISP8",
280 { "OPERAND_TYPE_DISP16",
282 { "OPERAND_TYPE_DISP32",
284 { "OPERAND_TYPE_DISP32S",
286 { "OPERAND_TYPE_DISP64",
288 { "OPERAND_TYPE_INOUTPORTREG",
290 { "OPERAND_TYPE_SHIFTCOUNT",
292 { "OPERAND_TYPE_CONTROL",
294 { "OPERAND_TYPE_TEST",
296 { "OPERAND_TYPE_DEBUG",
298 { "OPERAND_TYPE_FLOATREG",
300 { "OPERAND_TYPE_FLOATACC",
302 { "OPERAND_TYPE_SREG2",
304 { "OPERAND_TYPE_SREG3",
306 { "OPERAND_TYPE_ACC",
308 { "OPERAND_TYPE_JUMPABSOLUTE",
310 { "OPERAND_TYPE_REGMMX",
312 { "OPERAND_TYPE_REGXMM",
314 { "OPERAND_TYPE_REGYMM",
316 { "OPERAND_TYPE_REGZMM",
318 { "OPERAND_TYPE_REGMASK",
320 { "OPERAND_TYPE_ESSEG",
322 { "OPERAND_TYPE_ACC32",
324 { "OPERAND_TYPE_ACC64",
326 { "OPERAND_TYPE_INOUTPORTREG",
328 { "OPERAND_TYPE_REG16_INOUTPORTREG",
329 "Reg16|InOutPortReg" },
330 { "OPERAND_TYPE_DISP16_32",
332 { "OPERAND_TYPE_ANYDISP",
333 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
334 { "OPERAND_TYPE_IMM16_32",
336 { "OPERAND_TYPE_IMM16_32S",
338 { "OPERAND_TYPE_IMM16_32_32S",
339 "Imm16|Imm32|Imm32S" },
340 { "OPERAND_TYPE_IMM32_64",
342 { "OPERAND_TYPE_IMM32_32S_DISP32",
343 "Imm32|Imm32S|Disp32" },
344 { "OPERAND_TYPE_IMM64_DISP64",
346 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
347 "Imm32|Imm32S|Imm64|Disp32" },
348 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
349 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
350 { "OPERAND_TYPE_VEC_IMM4",
352 { "OPERAND_TYPE_REGBND",
354 { "OPERAND_TYPE_VEC_DISP8",
358 typedef struct bitfield
365 #define BITFIELD(n) { n, 0, #n }
367 static bitfield cpu_flags
[] =
375 BITFIELD (CpuClflush
),
377 BITFIELD (CpuSYSCALL
),
382 BITFIELD (CpuFISTTP
),
388 BITFIELD (CpuSSE4_1
),
389 BITFIELD (CpuSSE4_2
),
392 BITFIELD (CpuAVX512F
),
393 BITFIELD (CpuAVX512CD
),
394 BITFIELD (CpuAVX512ER
),
395 BITFIELD (CpuAVX512PF
),
396 BITFIELD (CpuAVX512VL
),
397 BITFIELD (CpuAVX512DQ
),
398 BITFIELD (CpuAVX512BW
),
403 BITFIELD (Cpu3dnowA
),
404 BITFIELD (CpuPadLock
),
410 BITFIELD (CpuXsaveopt
),
412 BITFIELD (CpuPCLMUL
),
423 BITFIELD (CpuRdtscp
),
424 BITFIELD (CpuFSGSBase
),
431 BITFIELD (CpuINVPCID
),
432 BITFIELD (CpuVMFUNC
),
433 BITFIELD (CpuRDSEED
),
435 BITFIELD (CpuPRFCHW
),
439 BITFIELD (CpuClflushOpt
),
440 BITFIELD (CpuXSAVES
),
441 BITFIELD (CpuXSAVEC
),
442 BITFIELD (CpuPREFETCHWT1
),
445 BITFIELD (CpuPCOMMIT
),
449 BITFIELD (CpuAVX512IFMA
),
450 BITFIELD (CpuAVX512VBMI
),
452 BITFIELD (CpuUnused
),
456 static bitfield opcode_modifiers
[] =
462 BITFIELD (ShortForm
),
464 BITFIELD (JumpDword
),
466 BITFIELD (JumpInterSegment
),
473 BITFIELD (CheckRegSize
),
474 BITFIELD (IgnoreSize
),
475 BITFIELD (DefaultSize
),
484 BITFIELD (BNDPrefixOk
),
485 BITFIELD (IsLockable
),
486 BITFIELD (RegKludge
),
487 BITFIELD (FirstXmm0
),
488 BITFIELD (Implicit1stXmm0
),
489 BITFIELD (RepPrefixOk
),
490 BITFIELD (HLEPrefixOk
),
493 BITFIELD (AddrPrefixOp0
),
502 BITFIELD (VexOpcode
),
503 BITFIELD (VexSources
),
504 BITFIELD (VexImmExt
),
511 BITFIELD (Broadcast
),
512 BITFIELD (StaticRounding
),
514 BITFIELD (Disp8MemShift
),
515 BITFIELD (NoDefMask
),
517 BITFIELD (ATTMnemonic
),
518 BITFIELD (ATTSyntax
),
519 BITFIELD (IntelSyntax
),
522 static bitfield operand_types
[] =
541 BITFIELD (BaseIndex
),
547 BITFIELD (InOutPortReg
),
548 BITFIELD (ShiftCount
),
556 BITFIELD (JumpAbsolute
),
569 BITFIELD (Unspecified
),
573 BITFIELD (Vec_Disp8
),
579 static const char *filename
;
582 compare (const void *x
, const void *y
)
584 const bitfield
*xp
= (const bitfield
*) x
;
585 const bitfield
*yp
= (const bitfield
*) y
;
586 return xp
->position
- yp
->position
;
590 fail (const char *message
, ...)
594 va_start (args
, message
);
595 fprintf (stderr
, _("%s: Error: "), program_name
);
596 vfprintf (stderr
, message
, args
);
602 process_copyright (FILE *fp
)
604 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
605 /* Copyright (C) 2007-2015 Free Software Foundation, Inc.\n\
607 This file is part of the GNU opcodes library.\n\
609 This library is free software; you can redistribute it and/or modify\n\
610 it under the terms of the GNU General Public License as published by\n\
611 the Free Software Foundation; either version 3, or (at your option)\n\
612 any later version.\n\
614 It is distributed in the hope that it will be useful, but WITHOUT\n\
615 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
616 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
617 License for more details.\n\
619 You should have received a copy of the GNU General Public License\n\
620 along with this program; if not, write to the Free Software\n\
621 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
622 MA 02110-1301, USA. */\n");
625 /* Remove leading white spaces. */
628 remove_leading_whitespaces (char *str
)
630 while (ISSPACE (*str
))
635 /* Remove trailing white spaces. */
638 remove_trailing_whitespaces (char *str
)
640 size_t last
= strlen (str
);
648 if (ISSPACE (str
[last
]))
656 /* Find next field separated by SEP and terminate it. Return a
657 pointer to the one after it. */
660 next_field (char *str
, char sep
, char **next
, char *last
)
664 p
= remove_leading_whitespaces (str
);
665 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
668 remove_trailing_whitespaces (p
);
679 set_bitfield (const char *f
, bitfield
*array
, int value
,
680 unsigned int size
, int lineno
)
684 if (strcmp (f
, "CpuFP") == 0)
686 set_bitfield("Cpu387", array
, value
, size
, lineno
);
687 set_bitfield("Cpu287", array
, value
, size
, lineno
);
690 else if (strcmp (f
, "Mmword") == 0)
692 else if (strcmp (f
, "Oword") == 0)
695 for (i
= 0; i
< size
; i
++)
696 if (strcasecmp (array
[i
].name
, f
) == 0)
698 array
[i
].value
= value
;
704 const char *v
= strchr (f
, '=');
711 for (i
= 0; i
< size
; i
++)
712 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
714 value
= strtol (v
+ 1, &end
, 0);
717 array
[i
].value
= value
;
726 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
728 fail (_("Unknown bitfield: %s\n"), f
);
732 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
733 int macro
, const char *comma
, const char *indent
)
737 fprintf (table
, "%s{ { ", indent
);
739 for (i
= 0; i
< size
- 1; i
++)
741 if (((i
+ 1) % 20) != 0)
742 fprintf (table
, "%d, ", flags
[i
].value
);
744 fprintf (table
, "%d,", flags
[i
].value
);
745 if (((i
+ 1) % 20) == 0)
747 /* We need \\ for macro. */
749 fprintf (table
, " \\\n %s", indent
);
751 fprintf (table
, "\n %s", indent
);
755 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
759 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
760 const char *comma
, const char *indent
,
763 char *str
, *next
, *last
;
765 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
767 /* Copy the default cpu flags. */
768 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
770 if (strcasecmp (flag
, "unknown") == 0)
772 /* We turn on everything except for cpu64 in case of
773 CPU_UNKNOWN_FLAGS. */
774 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
775 if (flags
[i
].position
!= Cpu64
)
778 else if (flag
[0] == '~')
780 last
= flag
+ strlen (flag
);
787 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
794 /* First we turn on everything except for cpu64. */
795 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
796 if (flags
[i
].position
!= Cpu64
)
799 /* Turn off selective bits. */
800 for (; next
&& next
< last
; )
802 str
= next_field (next
, '|', &next
, last
);
804 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
807 else if (strcmp (flag
, "0"))
809 /* Turn on selective bits. */
810 last
= flag
+ strlen (flag
);
811 for (next
= flag
; next
&& next
< last
; )
813 str
= next_field (next
, '|', &next
, last
);
815 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
819 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
824 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
828 fprintf (table
, " { ");
830 for (i
= 0; i
< size
- 1; i
++)
832 if (((i
+ 1) % 20) != 0)
833 fprintf (table
, "%d, ", modifier
[i
].value
);
835 fprintf (table
, "%d,", modifier
[i
].value
);
836 if (((i
+ 1) % 20) == 0)
837 fprintf (table
, "\n ");
840 fprintf (table
, "%d },\n", modifier
[i
].value
);
844 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
846 char *str
, *next
, *last
;
847 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
849 /* Copy the default opcode modifier. */
850 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
852 if (strcmp (mod
, "0"))
854 last
= mod
+ strlen (mod
);
855 for (next
= mod
; next
&& next
< last
; )
857 str
= next_field (next
, '|', &next
, last
);
859 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
863 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
867 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
868 int macro
, const char *indent
)
872 fprintf (table
, "{ { ");
874 for (i
= 0; i
< size
- 1; i
++)
876 if (((i
+ 1) % 20) != 0)
877 fprintf (table
, "%d, ", types
[i
].value
);
879 fprintf (table
, "%d,", types
[i
].value
);
880 if (((i
+ 1) % 20) == 0)
882 /* We need \\ for macro. */
884 fprintf (table
, " \\\n%s", indent
);
886 fprintf (table
, "\n%s", indent
);
890 fprintf (table
, "%d } }", types
[i
].value
);
894 process_i386_operand_type (FILE *table
, char *op
, int macro
,
895 const char *indent
, int lineno
)
897 char *str
, *next
, *last
;
898 bitfield types
[ARRAY_SIZE (operand_types
)];
900 /* Copy the default operand type. */
901 memcpy (types
, operand_types
, sizeof (types
));
903 if (strcmp (op
, "0"))
905 last
= op
+ strlen (op
);
906 for (next
= op
; next
&& next
< last
; )
908 str
= next_field (next
, '|', &next
, last
);
910 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
913 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
918 output_i386_opcode (FILE *table
, const char *name
, char *str
,
919 char *last
, int lineno
)
922 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
923 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
925 /* Find number of operands. */
926 operands
= next_field (str
, ',', &str
, last
);
928 /* Find base_opcode. */
929 base_opcode
= next_field (str
, ',', &str
, last
);
931 /* Find extension_opcode. */
932 extension_opcode
= next_field (str
, ',', &str
, last
);
934 /* Find opcode_length. */
935 opcode_length
= next_field (str
, ',', &str
, last
);
937 /* Find cpu_flags. */
938 cpu_flags
= next_field (str
, ',', &str
, last
);
940 /* Find opcode_modifier. */
941 opcode_modifier
= next_field (str
, ',', &str
, last
);
943 /* Remove the first {. */
944 str
= remove_leading_whitespaces (str
);
947 str
= remove_leading_whitespaces (str
+ 1);
951 /* There are at least "X}". */
955 /* Remove trailing white spaces and }. */
959 if (ISSPACE (str
[i
]) || str
[i
] == '}')
968 /* Find operand_types. */
969 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
973 operand_types
[i
] = NULL
;
977 operand_types
[i
] = next_field (str
, ',', &str
, last
);
978 if (*operand_types
[i
] == '0')
981 operand_types
[i
] = NULL
;
986 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
987 name
, operands
, base_opcode
, extension_opcode
,
990 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
992 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
994 fprintf (table
, " { ");
996 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
998 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1001 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1006 fprintf (table
, ",\n ");
1008 process_i386_operand_type (table
, operand_types
[i
], 0,
1011 fprintf (table
, " } },\n");
1014 struct opcode_hash_entry
1016 struct opcode_hash_entry
*next
;
1022 /* Calculate the hash value of an opcode hash entry P. */
1025 opcode_hash_hash (const void *p
)
1027 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1028 return htab_hash_string (entry
->name
);
1031 /* Compare a string Q against an opcode hash entry P. */
1034 opcode_hash_eq (const void *p
, const void *q
)
1036 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1037 const char *name
= (const char *) q
;
1038 return strcmp (name
, entry
->name
) == 0;
1042 process_i386_opcodes (FILE *table
)
1047 char *str
, *p
, *last
, *name
;
1048 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1049 htab_t opcode_hash_table
;
1050 struct opcode_hash_entry
**opcode_array
;
1051 unsigned int opcode_array_size
= 1024;
1054 filename
= "i386-opc.tbl";
1055 fp
= fopen (filename
, "r");
1058 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1062 opcode_array
= (struct opcode_hash_entry
**)
1063 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1065 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1066 opcode_hash_eq
, NULL
,
1069 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1070 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1072 /* Put everything on opcode array. */
1075 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1080 p
= remove_leading_whitespaces (buf
);
1082 /* Skip comments. */
1083 str
= strstr (p
, "//");
1087 /* Remove trailing white spaces. */
1088 remove_trailing_whitespaces (p
);
1093 /* Ignore comments. */
1101 last
= p
+ strlen (p
);
1104 name
= next_field (p
, ',', &str
, last
);
1106 /* Get the slot in hash table. */
1107 hash_slot
= (struct opcode_hash_entry
**)
1108 htab_find_slot_with_hash (opcode_hash_table
, name
,
1109 htab_hash_string (name
),
1112 if (*hash_slot
== NULL
)
1114 /* It is the new one. Put it on opcode array. */
1115 if (i
>= opcode_array_size
)
1117 /* Grow the opcode array when needed. */
1118 opcode_array_size
+= 1024;
1119 opcode_array
= (struct opcode_hash_entry
**)
1120 xrealloc (opcode_array
,
1121 sizeof (*opcode_array
) * opcode_array_size
);
1124 opcode_array
[i
] = (struct opcode_hash_entry
*)
1125 xmalloc (sizeof (struct opcode_hash_entry
));
1126 opcode_array
[i
]->next
= NULL
;
1127 opcode_array
[i
]->name
= xstrdup (name
);
1128 opcode_array
[i
]->opcode
= xstrdup (str
);
1129 opcode_array
[i
]->lineno
= lineno
;
1130 *hash_slot
= opcode_array
[i
];
1135 /* Append it to the existing one. */
1137 while ((*entry
) != NULL
)
1138 entry
= &(*entry
)->next
;
1139 *entry
= (struct opcode_hash_entry
*)
1140 xmalloc (sizeof (struct opcode_hash_entry
));
1141 (*entry
)->next
= NULL
;
1142 (*entry
)->name
= (*hash_slot
)->name
;
1143 (*entry
)->opcode
= xstrdup (str
);
1144 (*entry
)->lineno
= lineno
;
1148 /* Process opcode array. */
1149 for (j
= 0; j
< i
; j
++)
1151 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1155 lineno
= next
->lineno
;
1156 last
= str
+ strlen (str
);
1157 output_i386_opcode (table
, name
, str
, last
, lineno
);
1163 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1165 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1167 process_i386_opcode_modifier (table
, "0", -1);
1169 fprintf (table
, " { ");
1170 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1171 fprintf (table
, " } }\n");
1173 fprintf (table
, "};\n");
1177 process_i386_registers (FILE *table
)
1181 char *str
, *p
, *last
;
1182 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1183 char *dw2_32_num
, *dw2_64_num
;
1186 filename
= "i386-reg.tbl";
1187 fp
= fopen (filename
, "r");
1189 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1192 fprintf (table
, "\n/* i386 register table. */\n\n");
1193 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1197 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1202 p
= remove_leading_whitespaces (buf
);
1204 /* Skip comments. */
1205 str
= strstr (p
, "//");
1209 /* Remove trailing white spaces. */
1210 remove_trailing_whitespaces (p
);
1215 fprintf (table
, "%s\n", p
);
1223 last
= p
+ strlen (p
);
1225 /* Find reg_name. */
1226 reg_name
= next_field (p
, ',', &str
, last
);
1228 /* Find reg_type. */
1229 reg_type
= next_field (str
, ',', &str
, last
);
1231 /* Find reg_flags. */
1232 reg_flags
= next_field (str
, ',', &str
, last
);
1235 reg_num
= next_field (str
, ',', &str
, last
);
1237 fprintf (table
, " { \"%s\",\n ", reg_name
);
1239 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1241 /* Find 32-bit Dwarf2 register number. */
1242 dw2_32_num
= next_field (str
, ',', &str
, last
);
1244 /* Find 64-bit Dwarf2 register number. */
1245 dw2_64_num
= next_field (str
, ',', &str
, last
);
1247 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1248 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1253 fprintf (table
, "};\n");
1255 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1259 process_i386_initializers (void)
1262 FILE *fp
= fopen ("i386-init.h", "w");
1266 fail (_("can't create i386-init.h, errno = %s\n"),
1269 process_copyright (fp
);
1271 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1273 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1274 init
= xstrdup (cpu_flag_init
[i
].init
);
1275 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1279 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1281 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1282 init
= xstrdup (operand_type_init
[i
].init
);
1283 process_i386_operand_type (fp
, init
, 1, " ", -1);
1291 /* Program options. */
1292 #define OPTION_SRCDIR 200
1294 struct option long_options
[] =
1296 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1297 {"debug", no_argument
, NULL
, 'd'},
1298 {"version", no_argument
, NULL
, 'V'},
1299 {"help", no_argument
, NULL
, 'h'},
1300 {0, no_argument
, NULL
, 0}
1304 print_version (void)
1306 printf ("%s: version 1.0\n", program_name
);
1311 usage (FILE * stream
, int status
)
1313 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1319 main (int argc
, char **argv
)
1321 extern int chdir (char *);
1322 char *srcdir
= NULL
;
1326 program_name
= *argv
;
1327 xmalloc_set_program_name (program_name
);
1329 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1354 if (chdir (srcdir
) != 0)
1355 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1356 srcdir
, xstrerror (errno
));
1358 /* Check the unused bitfield in i386_cpu_flags. */
1360 c
= CpuNumOfBits
- CpuMax
- 1;
1362 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1365 /* Check the unused bitfield in i386_operand_type. */
1367 c
= OTNumOfBits
- OTMax
- 1;
1369 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1372 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1375 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1376 sizeof (opcode_modifiers
[0]), compare
);
1378 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1379 sizeof (operand_types
[0]), compare
);
1381 table
= fopen ("i386-tbl.h", "w");
1383 fail (_("can't create i386-tbl.h, errno = %s\n"),
1386 process_copyright (table
);
1388 process_i386_opcodes (table
);
1389 process_i386_registers (table
);
1390 process_i386_initializers ();