1 /* Copyright (C) 2007-2014 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" },
248 static initializer operand_type_init
[] =
250 { "OPERAND_TYPE_NONE",
252 { "OPERAND_TYPE_REG8",
254 { "OPERAND_TYPE_REG16",
256 { "OPERAND_TYPE_REG32",
258 { "OPERAND_TYPE_REG64",
260 { "OPERAND_TYPE_IMM1",
262 { "OPERAND_TYPE_IMM8",
264 { "OPERAND_TYPE_IMM8S",
266 { "OPERAND_TYPE_IMM16",
268 { "OPERAND_TYPE_IMM32",
270 { "OPERAND_TYPE_IMM32S",
272 { "OPERAND_TYPE_IMM64",
274 { "OPERAND_TYPE_BASEINDEX",
276 { "OPERAND_TYPE_DISP8",
278 { "OPERAND_TYPE_DISP16",
280 { "OPERAND_TYPE_DISP32",
282 { "OPERAND_TYPE_DISP32S",
284 { "OPERAND_TYPE_DISP64",
286 { "OPERAND_TYPE_INOUTPORTREG",
288 { "OPERAND_TYPE_SHIFTCOUNT",
290 { "OPERAND_TYPE_CONTROL",
292 { "OPERAND_TYPE_TEST",
294 { "OPERAND_TYPE_DEBUG",
296 { "OPERAND_TYPE_FLOATREG",
298 { "OPERAND_TYPE_FLOATACC",
300 { "OPERAND_TYPE_SREG2",
302 { "OPERAND_TYPE_SREG3",
304 { "OPERAND_TYPE_ACC",
306 { "OPERAND_TYPE_JUMPABSOLUTE",
308 { "OPERAND_TYPE_REGMMX",
310 { "OPERAND_TYPE_REGXMM",
312 { "OPERAND_TYPE_REGYMM",
314 { "OPERAND_TYPE_REGZMM",
316 { "OPERAND_TYPE_REGMASK",
318 { "OPERAND_TYPE_ESSEG",
320 { "OPERAND_TYPE_ACC32",
322 { "OPERAND_TYPE_ACC64",
324 { "OPERAND_TYPE_INOUTPORTREG",
326 { "OPERAND_TYPE_REG16_INOUTPORTREG",
327 "Reg16|InOutPortReg" },
328 { "OPERAND_TYPE_DISP16_32",
330 { "OPERAND_TYPE_ANYDISP",
331 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
332 { "OPERAND_TYPE_IMM16_32",
334 { "OPERAND_TYPE_IMM16_32S",
336 { "OPERAND_TYPE_IMM16_32_32S",
337 "Imm16|Imm32|Imm32S" },
338 { "OPERAND_TYPE_IMM32_64",
340 { "OPERAND_TYPE_IMM32_32S_DISP32",
341 "Imm32|Imm32S|Disp32" },
342 { "OPERAND_TYPE_IMM64_DISP64",
344 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
345 "Imm32|Imm32S|Imm64|Disp32" },
346 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
347 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
348 { "OPERAND_TYPE_VEC_IMM4",
350 { "OPERAND_TYPE_REGBND",
352 { "OPERAND_TYPE_VEC_DISP8",
356 typedef struct bitfield
363 #define BITFIELD(n) { n, 0, #n }
365 static bitfield cpu_flags
[] =
373 BITFIELD (CpuClflush
),
375 BITFIELD (CpuSYSCALL
),
380 BITFIELD (CpuFISTTP
),
386 BITFIELD (CpuSSE4_1
),
387 BITFIELD (CpuSSE4_2
),
390 BITFIELD (CpuAVX512F
),
391 BITFIELD (CpuAVX512CD
),
392 BITFIELD (CpuAVX512ER
),
393 BITFIELD (CpuAVX512PF
),
394 BITFIELD (CpuAVX512VL
),
395 BITFIELD (CpuAVX512DQ
),
396 BITFIELD (CpuAVX512BW
),
401 BITFIELD (Cpu3dnowA
),
402 BITFIELD (CpuPadLock
),
408 BITFIELD (CpuXsaveopt
),
410 BITFIELD (CpuPCLMUL
),
421 BITFIELD (CpuRdtscp
),
422 BITFIELD (CpuFSGSBase
),
429 BITFIELD (CpuINVPCID
),
430 BITFIELD (CpuVMFUNC
),
431 BITFIELD (CpuRDSEED
),
433 BITFIELD (CpuPRFCHW
),
437 BITFIELD (CpuClflushOpt
),
438 BITFIELD (CpuXSAVES
),
439 BITFIELD (CpuXSAVEC
),
440 BITFIELD (CpuPREFETCHWT1
),
443 BITFIELD (CpuPCOMMIT
),
447 BITFIELD (CpuAVX512IFMA
),
449 BITFIELD (CpuUnused
),
453 static bitfield opcode_modifiers
[] =
459 BITFIELD (ShortForm
),
461 BITFIELD (JumpDword
),
463 BITFIELD (JumpInterSegment
),
470 BITFIELD (CheckRegSize
),
471 BITFIELD (IgnoreSize
),
472 BITFIELD (DefaultSize
),
481 BITFIELD (BNDPrefixOk
),
482 BITFIELD (IsLockable
),
483 BITFIELD (RegKludge
),
484 BITFIELD (FirstXmm0
),
485 BITFIELD (Implicit1stXmm0
),
486 BITFIELD (RepPrefixOk
),
487 BITFIELD (HLEPrefixOk
),
490 BITFIELD (AddrPrefixOp0
),
499 BITFIELD (VexOpcode
),
500 BITFIELD (VexSources
),
501 BITFIELD (VexImmExt
),
508 BITFIELD (Broadcast
),
509 BITFIELD (StaticRounding
),
511 BITFIELD (Disp8MemShift
),
512 BITFIELD (NoDefMask
),
514 BITFIELD (ATTMnemonic
),
515 BITFIELD (ATTSyntax
),
516 BITFIELD (IntelSyntax
),
519 static bitfield operand_types
[] =
538 BITFIELD (BaseIndex
),
544 BITFIELD (InOutPortReg
),
545 BITFIELD (ShiftCount
),
553 BITFIELD (JumpAbsolute
),
566 BITFIELD (Unspecified
),
570 BITFIELD (Vec_Disp8
),
576 static const char *filename
;
579 compare (const void *x
, const void *y
)
581 const bitfield
*xp
= (const bitfield
*) x
;
582 const bitfield
*yp
= (const bitfield
*) y
;
583 return xp
->position
- yp
->position
;
587 fail (const char *message
, ...)
591 va_start (args
, message
);
592 fprintf (stderr
, _("%s: Error: "), program_name
);
593 vfprintf (stderr
, message
, args
);
599 process_copyright (FILE *fp
)
601 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
602 /* Copyright (C) 2007-2014 Free Software Foundation, Inc.\n\
604 This file is part of the GNU opcodes library.\n\
606 This library is free software; you can redistribute it and/or modify\n\
607 it under the terms of the GNU General Public License as published by\n\
608 the Free Software Foundation; either version 3, or (at your option)\n\
609 any later version.\n\
611 It is distributed in the hope that it will be useful, but WITHOUT\n\
612 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
613 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
614 License for more details.\n\
616 You should have received a copy of the GNU General Public License\n\
617 along with this program; if not, write to the Free Software\n\
618 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
619 MA 02110-1301, USA. */\n");
622 /* Remove leading white spaces. */
625 remove_leading_whitespaces (char *str
)
627 while (ISSPACE (*str
))
632 /* Remove trailing white spaces. */
635 remove_trailing_whitespaces (char *str
)
637 size_t last
= strlen (str
);
645 if (ISSPACE (str
[last
]))
653 /* Find next field separated by SEP and terminate it. Return a
654 pointer to the one after it. */
657 next_field (char *str
, char sep
, char **next
, char *last
)
661 p
= remove_leading_whitespaces (str
);
662 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
665 remove_trailing_whitespaces (p
);
676 set_bitfield (const char *f
, bitfield
*array
, int value
,
677 unsigned int size
, int lineno
)
681 if (strcmp (f
, "CpuFP") == 0)
683 set_bitfield("Cpu387", array
, value
, size
, lineno
);
684 set_bitfield("Cpu287", array
, value
, size
, lineno
);
687 else if (strcmp (f
, "Mmword") == 0)
689 else if (strcmp (f
, "Oword") == 0)
692 for (i
= 0; i
< size
; i
++)
693 if (strcasecmp (array
[i
].name
, f
) == 0)
695 array
[i
].value
= value
;
701 const char *v
= strchr (f
, '=');
708 for (i
= 0; i
< size
; i
++)
709 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
711 value
= strtol (v
+ 1, &end
, 0);
714 array
[i
].value
= value
;
723 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
725 fail (_("Unknown bitfield: %s\n"), f
);
729 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
730 int macro
, const char *comma
, const char *indent
)
734 fprintf (table
, "%s{ { ", indent
);
736 for (i
= 0; i
< size
- 1; i
++)
738 if (((i
+ 1) % 20) != 0)
739 fprintf (table
, "%d, ", flags
[i
].value
);
741 fprintf (table
, "%d,", flags
[i
].value
);
742 if (((i
+ 1) % 20) == 0)
744 /* We need \\ for macro. */
746 fprintf (table
, " \\\n %s", indent
);
748 fprintf (table
, "\n %s", indent
);
752 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
756 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
757 const char *comma
, const char *indent
,
760 char *str
, *next
, *last
;
762 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
764 /* Copy the default cpu flags. */
765 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
767 if (strcasecmp (flag
, "unknown") == 0)
769 /* We turn on everything except for cpu64 in case of
770 CPU_UNKNOWN_FLAGS. */
771 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
772 if (flags
[i
].position
!= Cpu64
)
775 else if (flag
[0] == '~')
777 last
= flag
+ strlen (flag
);
784 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
791 /* First we turn on everything except for cpu64. */
792 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
793 if (flags
[i
].position
!= Cpu64
)
796 /* Turn off selective bits. */
797 for (; next
&& next
< last
; )
799 str
= next_field (next
, '|', &next
, last
);
801 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
804 else if (strcmp (flag
, "0"))
806 /* Turn on selective bits. */
807 last
= flag
+ strlen (flag
);
808 for (next
= flag
; next
&& next
< last
; )
810 str
= next_field (next
, '|', &next
, last
);
812 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
816 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
821 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
825 fprintf (table
, " { ");
827 for (i
= 0; i
< size
- 1; i
++)
829 if (((i
+ 1) % 20) != 0)
830 fprintf (table
, "%d, ", modifier
[i
].value
);
832 fprintf (table
, "%d,", modifier
[i
].value
);
833 if (((i
+ 1) % 20) == 0)
834 fprintf (table
, "\n ");
837 fprintf (table
, "%d },\n", modifier
[i
].value
);
841 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
843 char *str
, *next
, *last
;
844 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
846 /* Copy the default opcode modifier. */
847 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
849 if (strcmp (mod
, "0"))
851 last
= mod
+ strlen (mod
);
852 for (next
= mod
; next
&& next
< last
; )
854 str
= next_field (next
, '|', &next
, last
);
856 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
860 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
864 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
865 int macro
, const char *indent
)
869 fprintf (table
, "{ { ");
871 for (i
= 0; i
< size
- 1; i
++)
873 if (((i
+ 1) % 20) != 0)
874 fprintf (table
, "%d, ", types
[i
].value
);
876 fprintf (table
, "%d,", types
[i
].value
);
877 if (((i
+ 1) % 20) == 0)
879 /* We need \\ for macro. */
881 fprintf (table
, " \\\n%s", indent
);
883 fprintf (table
, "\n%s", indent
);
887 fprintf (table
, "%d } }", types
[i
].value
);
891 process_i386_operand_type (FILE *table
, char *op
, int macro
,
892 const char *indent
, int lineno
)
894 char *str
, *next
, *last
;
895 bitfield types
[ARRAY_SIZE (operand_types
)];
897 /* Copy the default operand type. */
898 memcpy (types
, operand_types
, sizeof (types
));
900 if (strcmp (op
, "0"))
902 last
= op
+ strlen (op
);
903 for (next
= op
; next
&& next
< last
; )
905 str
= next_field (next
, '|', &next
, last
);
907 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
910 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
915 output_i386_opcode (FILE *table
, const char *name
, char *str
,
916 char *last
, int lineno
)
919 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
920 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
922 /* Find number of operands. */
923 operands
= next_field (str
, ',', &str
, last
);
925 /* Find base_opcode. */
926 base_opcode
= next_field (str
, ',', &str
, last
);
928 /* Find extension_opcode. */
929 extension_opcode
= next_field (str
, ',', &str
, last
);
931 /* Find opcode_length. */
932 opcode_length
= next_field (str
, ',', &str
, last
);
934 /* Find cpu_flags. */
935 cpu_flags
= next_field (str
, ',', &str
, last
);
937 /* Find opcode_modifier. */
938 opcode_modifier
= next_field (str
, ',', &str
, last
);
940 /* Remove the first {. */
941 str
= remove_leading_whitespaces (str
);
944 str
= remove_leading_whitespaces (str
+ 1);
948 /* There are at least "X}". */
952 /* Remove trailing white spaces and }. */
956 if (ISSPACE (str
[i
]) || str
[i
] == '}')
965 /* Find operand_types. */
966 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
970 operand_types
[i
] = NULL
;
974 operand_types
[i
] = next_field (str
, ',', &str
, last
);
975 if (*operand_types
[i
] == '0')
978 operand_types
[i
] = NULL
;
983 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
984 name
, operands
, base_opcode
, extension_opcode
,
987 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
989 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
991 fprintf (table
, " { ");
993 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
995 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
998 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1003 fprintf (table
, ",\n ");
1005 process_i386_operand_type (table
, operand_types
[i
], 0,
1008 fprintf (table
, " } },\n");
1011 struct opcode_hash_entry
1013 struct opcode_hash_entry
*next
;
1019 /* Calculate the hash value of an opcode hash entry P. */
1022 opcode_hash_hash (const void *p
)
1024 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1025 return htab_hash_string (entry
->name
);
1028 /* Compare a string Q against an opcode hash entry P. */
1031 opcode_hash_eq (const void *p
, const void *q
)
1033 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1034 const char *name
= (const char *) q
;
1035 return strcmp (name
, entry
->name
) == 0;
1039 process_i386_opcodes (FILE *table
)
1044 char *str
, *p
, *last
, *name
;
1045 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1046 htab_t opcode_hash_table
;
1047 struct opcode_hash_entry
**opcode_array
;
1048 unsigned int opcode_array_size
= 1024;
1051 filename
= "i386-opc.tbl";
1052 fp
= fopen (filename
, "r");
1055 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1059 opcode_array
= (struct opcode_hash_entry
**)
1060 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1062 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1063 opcode_hash_eq
, NULL
,
1066 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1067 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1069 /* Put everything on opcode array. */
1072 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1077 p
= remove_leading_whitespaces (buf
);
1079 /* Skip comments. */
1080 str
= strstr (p
, "//");
1084 /* Remove trailing white spaces. */
1085 remove_trailing_whitespaces (p
);
1090 /* Ignore comments. */
1098 last
= p
+ strlen (p
);
1101 name
= next_field (p
, ',', &str
, last
);
1103 /* Get the slot in hash table. */
1104 hash_slot
= (struct opcode_hash_entry
**)
1105 htab_find_slot_with_hash (opcode_hash_table
, name
,
1106 htab_hash_string (name
),
1109 if (*hash_slot
== NULL
)
1111 /* It is the new one. Put it on opcode array. */
1112 if (i
>= opcode_array_size
)
1114 /* Grow the opcode array when needed. */
1115 opcode_array_size
+= 1024;
1116 opcode_array
= (struct opcode_hash_entry
**)
1117 xrealloc (opcode_array
,
1118 sizeof (*opcode_array
) * opcode_array_size
);
1121 opcode_array
[i
] = (struct opcode_hash_entry
*)
1122 xmalloc (sizeof (struct opcode_hash_entry
));
1123 opcode_array
[i
]->next
= NULL
;
1124 opcode_array
[i
]->name
= xstrdup (name
);
1125 opcode_array
[i
]->opcode
= xstrdup (str
);
1126 opcode_array
[i
]->lineno
= lineno
;
1127 *hash_slot
= opcode_array
[i
];
1132 /* Append it to the existing one. */
1134 while ((*entry
) != NULL
)
1135 entry
= &(*entry
)->next
;
1136 *entry
= (struct opcode_hash_entry
*)
1137 xmalloc (sizeof (struct opcode_hash_entry
));
1138 (*entry
)->next
= NULL
;
1139 (*entry
)->name
= (*hash_slot
)->name
;
1140 (*entry
)->opcode
= xstrdup (str
);
1141 (*entry
)->lineno
= lineno
;
1145 /* Process opcode array. */
1146 for (j
= 0; j
< i
; j
++)
1148 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1152 lineno
= next
->lineno
;
1153 last
= str
+ strlen (str
);
1154 output_i386_opcode (table
, name
, str
, last
, lineno
);
1160 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1162 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1164 process_i386_opcode_modifier (table
, "0", -1);
1166 fprintf (table
, " { ");
1167 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1168 fprintf (table
, " } }\n");
1170 fprintf (table
, "};\n");
1174 process_i386_registers (FILE *table
)
1178 char *str
, *p
, *last
;
1179 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1180 char *dw2_32_num
, *dw2_64_num
;
1183 filename
= "i386-reg.tbl";
1184 fp
= fopen (filename
, "r");
1186 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1189 fprintf (table
, "\n/* i386 register table. */\n\n");
1190 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1194 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1199 p
= remove_leading_whitespaces (buf
);
1201 /* Skip comments. */
1202 str
= strstr (p
, "//");
1206 /* Remove trailing white spaces. */
1207 remove_trailing_whitespaces (p
);
1212 fprintf (table
, "%s\n", p
);
1220 last
= p
+ strlen (p
);
1222 /* Find reg_name. */
1223 reg_name
= next_field (p
, ',', &str
, last
);
1225 /* Find reg_type. */
1226 reg_type
= next_field (str
, ',', &str
, last
);
1228 /* Find reg_flags. */
1229 reg_flags
= next_field (str
, ',', &str
, last
);
1232 reg_num
= next_field (str
, ',', &str
, last
);
1234 fprintf (table
, " { \"%s\",\n ", reg_name
);
1236 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1238 /* Find 32-bit Dwarf2 register number. */
1239 dw2_32_num
= next_field (str
, ',', &str
, last
);
1241 /* Find 64-bit Dwarf2 register number. */
1242 dw2_64_num
= next_field (str
, ',', &str
, last
);
1244 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1245 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1250 fprintf (table
, "};\n");
1252 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1256 process_i386_initializers (void)
1259 FILE *fp
= fopen ("i386-init.h", "w");
1263 fail (_("can't create i386-init.h, errno = %s\n"),
1266 process_copyright (fp
);
1268 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1270 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1271 init
= xstrdup (cpu_flag_init
[i
].init
);
1272 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1276 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1278 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1279 init
= xstrdup (operand_type_init
[i
].init
);
1280 process_i386_operand_type (fp
, init
, 1, " ", -1);
1288 /* Program options. */
1289 #define OPTION_SRCDIR 200
1291 struct option long_options
[] =
1293 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1294 {"debug", no_argument
, NULL
, 'd'},
1295 {"version", no_argument
, NULL
, 'V'},
1296 {"help", no_argument
, NULL
, 'h'},
1297 {0, no_argument
, NULL
, 0}
1301 print_version (void)
1303 printf ("%s: version 1.0\n", program_name
);
1308 usage (FILE * stream
, int status
)
1310 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1316 main (int argc
, char **argv
)
1318 extern int chdir (char *);
1319 char *srcdir
= NULL
;
1323 program_name
= *argv
;
1324 xmalloc_set_program_name (program_name
);
1326 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1351 if (chdir (srcdir
) != 0)
1352 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1353 srcdir
, xstrerror (errno
));
1355 /* Check the unused bitfield in i386_cpu_flags. */
1357 c
= CpuNumOfBits
- CpuMax
- 1;
1359 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1362 /* Check the unused bitfield in i386_operand_type. */
1364 c
= OTNumOfBits
- OTMax
- 1;
1366 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1369 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1372 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1373 sizeof (opcode_modifiers
[0]), compare
);
1375 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1376 sizeof (operand_types
[0]), compare
);
1378 table
= fopen ("i386-tbl.h", "w");
1380 fail (_("can't create i386-tbl.h, errno = %s\n"),
1383 process_copyright (table
);
1385 process_i386_opcodes (table
);
1386 process_i386_registers (table
);
1387 process_i386_initializers ();