bfd:
[binutils.git] / opcodes / i386-gen.c
blob4dd75a203df892410669caa762813e2217a43014
1 /* Copyright 2007, 2008, 2009, 2010, 2011
2 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 #include "sysdep.h"
22 #include <stdio.h>
23 #include <errno.h>
24 #include "getopt.h"
25 #include "libiberty.h"
26 #include "hashtab.h"
27 #include "safe-ctype.h"
29 #include "i386-opc.h"
31 #include <libintl.h>
32 #define _(String) gettext (String)
34 static const char *program_name = NULL;
35 static int debug = 0;
37 typedef struct initializer
39 const char *name;
40 const char *init;
41 } initializer;
43 static initializer cpu_flag_init[] =
45 { "CPU_UNKNOWN_FLAGS",
46 "~(CpuL1OM|CpuK1OM)" },
47 { "CPU_GENERIC32_FLAGS",
48 "Cpu186|Cpu286|Cpu386" },
49 { "CPU_GENERIC64_FLAGS",
50 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
51 { "CPU_NONE_FLAGS",
52 "0" },
53 { "CPU_I186_FLAGS",
54 "Cpu186" },
55 { "CPU_I286_FLAGS",
56 "Cpu186|Cpu286" },
57 { "CPU_I386_FLAGS",
58 "Cpu186|Cpu286|Cpu386" },
59 { "CPU_I486_FLAGS",
60 "Cpu186|Cpu286|Cpu386|Cpu486" },
61 { "CPU_I586_FLAGS",
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
63 { "CPU_I686_FLAGS",
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
65 { "CPU_PENTIUMPRO_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
67 { "CPU_P2_FLAGS",
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
69 { "CPU_P3_FLAGS",
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
71 { "CPU_P4_FLAGS",
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
73 { "CPU_NOCONA_FLAGS",
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
75 { "CPU_CORE_FLAGS",
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
77 { "CPU_CORE2_FLAGS",
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
79 { "CPU_COREI7_FLAGS",
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
81 { "CPU_K6_FLAGS",
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
83 { "CPU_K6_2_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuNop|CpuMMX|Cpu3dnow" },
85 { "CPU_ATHLON_FLAGS",
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
87 { "CPU_K8_FLAGS",
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
89 { "CPU_AMDFAM10_FLAGS",
90 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
91 { "CPU_BDVER1_FLAGS",
92 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP" },
93 { "CPU_BDVER2_FLAGS",
94 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C" },
95 { "CPU_8087_FLAGS",
96 "Cpu8087" },
97 { "CPU_287_FLAGS",
98 "Cpu287" },
99 { "CPU_387_FLAGS",
100 "Cpu387" },
101 { "CPU_ANY87_FLAGS",
102 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
103 { "CPU_CLFLUSH_FLAGS",
104 "CpuClflush" },
105 { "CPU_NOP_FLAGS",
106 "CpuNop" },
107 { "CPU_SYSCALL_FLAGS",
108 "CpuSYSCALL" },
109 { "CPU_MMX_FLAGS",
110 "CpuMMX" },
111 { "CPU_SSE_FLAGS",
112 "CpuMMX|CpuSSE" },
113 { "CPU_SSE2_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2" },
115 { "CPU_SSE3_FLAGS",
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
117 { "CPU_SSSE3_FLAGS",
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
119 { "CPU_SSE4_1_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
121 { "CPU_SSE4_2_FLAGS",
122 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
123 { "CPU_ANY_SSE_FLAGS",
124 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2" },
125 { "CPU_VMX_FLAGS",
126 "CpuVMX" },
127 { "CPU_SMX_FLAGS",
128 "CpuSMX" },
129 { "CPU_XSAVE_FLAGS",
130 "CpuXsave" },
131 { "CPU_XSAVEOPT_FLAGS",
132 "CpuXsaveopt" },
133 { "CPU_AES_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
135 { "CPU_PCLMUL_FLAGS",
136 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
137 { "CPU_FMA_FLAGS",
138 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
139 { "CPU_FMA4_FLAGS",
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
141 { "CPU_XOP_FLAGS",
142 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
143 { "CPU_LWP_FLAGS",
144 "CpuLWP" },
145 { "CPU_BMI_FLAGS",
146 "CpuBMI" },
147 { "CPU_TBM_FLAGS",
148 "CpuTBM" },
149 { "CPU_MOVBE_FLAGS",
150 "CpuMovbe" },
151 { "CPU_RDTSCP_FLAGS",
152 "CpuRdtscp" },
153 { "CPU_EPT_FLAGS",
154 "CpuEPT" },
155 { "CPU_FSGSBASE_FLAGS",
156 "CpuFSGSBase" },
157 { "CPU_RDRND_FLAGS",
158 "CpuRdRnd" },
159 { "CPU_F16C_FLAGS",
160 "CpuF16C" },
161 { "CPU_BMI2_FLAGS",
162 "CpuBMI2" },
163 { "CPU_LZCNT_FLAGS",
164 "CpuLZCNT" },
165 { "CPU_INVPCID_FLAGS",
166 "CpuINVPCID" },
167 { "CPU_3DNOW_FLAGS",
168 "CpuMMX|Cpu3dnow" },
169 { "CPU_3DNOWA_FLAGS",
170 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
171 { "CPU_PADLOCK_FLAGS",
172 "CpuPadLock" },
173 { "CPU_SVME_FLAGS",
174 "CpuSVME" },
175 { "CPU_SSE4A_FLAGS",
176 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
177 { "CPU_ABM_FLAGS",
178 "CpuABM" },
179 { "CPU_AVX_FLAGS",
180 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
181 { "CPU_AVX2_FLAGS",
182 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
183 { "CPU_ANY_AVX_FLAGS",
184 "CpuAVX|CpuAVX2" },
185 { "CPU_L1OM_FLAGS",
186 "unknown" },
187 { "CPU_K1OM_FLAGS",
188 "unknown" },
191 static initializer operand_type_init[] =
193 { "OPERAND_TYPE_NONE",
194 "0" },
195 { "OPERAND_TYPE_REG8",
196 "Reg8" },
197 { "OPERAND_TYPE_REG16",
198 "Reg16" },
199 { "OPERAND_TYPE_REG32",
200 "Reg32" },
201 { "OPERAND_TYPE_REG64",
202 "Reg64" },
203 { "OPERAND_TYPE_IMM1",
204 "Imm1" },
205 { "OPERAND_TYPE_IMM8",
206 "Imm8" },
207 { "OPERAND_TYPE_IMM8S",
208 "Imm8S" },
209 { "OPERAND_TYPE_IMM16",
210 "Imm16" },
211 { "OPERAND_TYPE_IMM32",
212 "Imm32" },
213 { "OPERAND_TYPE_IMM32S",
214 "Imm32S" },
215 { "OPERAND_TYPE_IMM64",
216 "Imm64" },
217 { "OPERAND_TYPE_BASEINDEX",
218 "BaseIndex" },
219 { "OPERAND_TYPE_DISP8",
220 "Disp8" },
221 { "OPERAND_TYPE_DISP16",
222 "Disp16" },
223 { "OPERAND_TYPE_DISP32",
224 "Disp32" },
225 { "OPERAND_TYPE_DISP32S",
226 "Disp32S" },
227 { "OPERAND_TYPE_DISP64",
228 "Disp64" },
229 { "OPERAND_TYPE_INOUTPORTREG",
230 "InOutPortReg" },
231 { "OPERAND_TYPE_SHIFTCOUNT",
232 "ShiftCount" },
233 { "OPERAND_TYPE_CONTROL",
234 "Control" },
235 { "OPERAND_TYPE_TEST",
236 "Test" },
237 { "OPERAND_TYPE_DEBUG",
238 "FloatReg" },
239 { "OPERAND_TYPE_FLOATREG",
240 "FloatReg" },
241 { "OPERAND_TYPE_FLOATACC",
242 "FloatAcc" },
243 { "OPERAND_TYPE_SREG2",
244 "SReg2" },
245 { "OPERAND_TYPE_SREG3",
246 "SReg3" },
247 { "OPERAND_TYPE_ACC",
248 "Acc" },
249 { "OPERAND_TYPE_JUMPABSOLUTE",
250 "JumpAbsolute" },
251 { "OPERAND_TYPE_REGMMX",
252 "RegMMX" },
253 { "OPERAND_TYPE_REGXMM",
254 "RegXMM" },
255 { "OPERAND_TYPE_REGYMM",
256 "RegYMM" },
257 { "OPERAND_TYPE_ESSEG",
258 "EsSeg" },
259 { "OPERAND_TYPE_ACC32",
260 "Reg32|Acc|Dword" },
261 { "OPERAND_TYPE_ACC64",
262 "Reg64|Acc|Qword" },
263 { "OPERAND_TYPE_INOUTPORTREG",
264 "InOutPortReg" },
265 { "OPERAND_TYPE_REG16_INOUTPORTREG",
266 "Reg16|InOutPortReg" },
267 { "OPERAND_TYPE_DISP16_32",
268 "Disp16|Disp32" },
269 { "OPERAND_TYPE_ANYDISP",
270 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
271 { "OPERAND_TYPE_IMM16_32",
272 "Imm16|Imm32" },
273 { "OPERAND_TYPE_IMM16_32S",
274 "Imm16|Imm32S" },
275 { "OPERAND_TYPE_IMM16_32_32S",
276 "Imm16|Imm32|Imm32S" },
277 { "OPERAND_TYPE_IMM32_32S_DISP32",
278 "Imm32|Imm32S|Disp32" },
279 { "OPERAND_TYPE_IMM64_DISP64",
280 "Imm64|Disp64" },
281 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
282 "Imm32|Imm32S|Imm64|Disp32" },
283 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
284 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
285 { "OPERAND_TYPE_VEC_IMM4",
286 "Vec_Imm4" },
289 typedef struct bitfield
291 int position;
292 int value;
293 const char *name;
294 } bitfield;
296 #define BITFIELD(n) { n, 0, #n }
298 static bitfield cpu_flags[] =
300 BITFIELD (Cpu186),
301 BITFIELD (Cpu286),
302 BITFIELD (Cpu386),
303 BITFIELD (Cpu486),
304 BITFIELD (Cpu586),
305 BITFIELD (Cpu686),
306 BITFIELD (CpuClflush),
307 BITFIELD (CpuNop),
308 BITFIELD (CpuSYSCALL),
309 BITFIELD (Cpu8087),
310 BITFIELD (Cpu287),
311 BITFIELD (Cpu387),
312 BITFIELD (Cpu687),
313 BITFIELD (CpuFISTTP),
314 BITFIELD (CpuMMX),
315 BITFIELD (CpuSSE),
316 BITFIELD (CpuSSE2),
317 BITFIELD (CpuSSE3),
318 BITFIELD (CpuSSSE3),
319 BITFIELD (CpuSSE4_1),
320 BITFIELD (CpuSSE4_2),
321 BITFIELD (CpuAVX),
322 BITFIELD (CpuAVX2),
323 BITFIELD (CpuL1OM),
324 BITFIELD (CpuK1OM),
325 BITFIELD (CpuSSE4a),
326 BITFIELD (Cpu3dnow),
327 BITFIELD (Cpu3dnowA),
328 BITFIELD (CpuPadLock),
329 BITFIELD (CpuSVME),
330 BITFIELD (CpuVMX),
331 BITFIELD (CpuSMX),
332 BITFIELD (CpuABM),
333 BITFIELD (CpuXsave),
334 BITFIELD (CpuXsaveopt),
335 BITFIELD (CpuAES),
336 BITFIELD (CpuPCLMUL),
337 BITFIELD (CpuFMA),
338 BITFIELD (CpuFMA4),
339 BITFIELD (CpuXOP),
340 BITFIELD (CpuLWP),
341 BITFIELD (CpuBMI),
342 BITFIELD (CpuTBM),
343 BITFIELD (CpuLM),
344 BITFIELD (CpuMovbe),
345 BITFIELD (CpuEPT),
346 BITFIELD (CpuRdtscp),
347 BITFIELD (CpuFSGSBase),
348 BITFIELD (CpuRdRnd),
349 BITFIELD (CpuF16C),
350 BITFIELD (CpuBMI2),
351 BITFIELD (CpuLZCNT),
352 BITFIELD (CpuINVPCID),
353 BITFIELD (Cpu64),
354 BITFIELD (CpuNo64),
355 #ifdef CpuUnused
356 BITFIELD (CpuUnused),
357 #endif
360 static bitfield opcode_modifiers[] =
362 BITFIELD (D),
363 BITFIELD (W),
364 BITFIELD (S),
365 BITFIELD (Modrm),
366 BITFIELD (ShortForm),
367 BITFIELD (Jump),
368 BITFIELD (JumpDword),
369 BITFIELD (JumpByte),
370 BITFIELD (JumpInterSegment),
371 BITFIELD (FloatMF),
372 BITFIELD (FloatR),
373 BITFIELD (FloatD),
374 BITFIELD (Size16),
375 BITFIELD (Size32),
376 BITFIELD (Size64),
377 BITFIELD (CheckRegSize),
378 BITFIELD (IgnoreSize),
379 BITFIELD (DefaultSize),
380 BITFIELD (No_bSuf),
381 BITFIELD (No_wSuf),
382 BITFIELD (No_lSuf),
383 BITFIELD (No_sSuf),
384 BITFIELD (No_qSuf),
385 BITFIELD (No_ldSuf),
386 BITFIELD (FWait),
387 BITFIELD (IsString),
388 BITFIELD (IsLockable),
389 BITFIELD (RegKludge),
390 BITFIELD (FirstXmm0),
391 BITFIELD (Implicit1stXmm0),
392 BITFIELD (ToDword),
393 BITFIELD (ToQword),
394 BITFIELD (AddrPrefixOp0),
395 BITFIELD (IsPrefix),
396 BITFIELD (ImmExt),
397 BITFIELD (NoRex64),
398 BITFIELD (Rex64),
399 BITFIELD (Ugh),
400 BITFIELD (Vex),
401 BITFIELD (VexVVVV),
402 BITFIELD (VexW),
403 BITFIELD (VexOpcode),
404 BITFIELD (VexSources),
405 BITFIELD (VexImmExt),
406 BITFIELD (VecSIB),
407 BITFIELD (SSE2AVX),
408 BITFIELD (NoAVX),
409 BITFIELD (OldGcc),
410 BITFIELD (ATTMnemonic),
411 BITFIELD (ATTSyntax),
412 BITFIELD (IntelSyntax),
415 static bitfield operand_types[] =
417 BITFIELD (Reg8),
418 BITFIELD (Reg16),
419 BITFIELD (Reg32),
420 BITFIELD (Reg64),
421 BITFIELD (FloatReg),
422 BITFIELD (RegMMX),
423 BITFIELD (RegXMM),
424 BITFIELD (RegYMM),
425 BITFIELD (Imm1),
426 BITFIELD (Imm8),
427 BITFIELD (Imm8S),
428 BITFIELD (Imm16),
429 BITFIELD (Imm32),
430 BITFIELD (Imm32S),
431 BITFIELD (Imm64),
432 BITFIELD (BaseIndex),
433 BITFIELD (Disp8),
434 BITFIELD (Disp16),
435 BITFIELD (Disp32),
436 BITFIELD (Disp32S),
437 BITFIELD (Disp64),
438 BITFIELD (InOutPortReg),
439 BITFIELD (ShiftCount),
440 BITFIELD (Control),
441 BITFIELD (Debug),
442 BITFIELD (Test),
443 BITFIELD (SReg2),
444 BITFIELD (SReg3),
445 BITFIELD (Acc),
446 BITFIELD (FloatAcc),
447 BITFIELD (JumpAbsolute),
448 BITFIELD (EsSeg),
449 BITFIELD (RegMem),
450 BITFIELD (Mem),
451 BITFIELD (Byte),
452 BITFIELD (Word),
453 BITFIELD (Dword),
454 BITFIELD (Fword),
455 BITFIELD (Qword),
456 BITFIELD (Tbyte),
457 BITFIELD (Xmmword),
458 BITFIELD (Ymmword),
459 BITFIELD (Unspecified),
460 BITFIELD (Anysize),
461 BITFIELD (Vec_Imm4),
462 #ifdef OTUnused
463 BITFIELD (OTUnused),
464 #endif
467 static const char *filename;
469 static int
470 compare (const void *x, const void *y)
472 const bitfield *xp = (const bitfield *) x;
473 const bitfield *yp = (const bitfield *) y;
474 return xp->position - yp->position;
477 static void
478 fail (const char *message, ...)
480 va_list args;
482 va_start (args, message);
483 fprintf (stderr, _("%s: Error: "), program_name);
484 vfprintf (stderr, message, args);
485 va_end (args);
486 xexit (1);
489 static void
490 process_copyright (FILE *fp)
492 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
493 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
494 Free Software Foundation, Inc.\n\
496 This file is part of the GNU opcodes library.\n\
498 This library is free software; you can redistribute it and/or modify\n\
499 it under the terms of the GNU General Public License as published by\n\
500 the Free Software Foundation; either version 3, or (at your option)\n\
501 any later version.\n\
503 It is distributed in the hope that it will be useful, but WITHOUT\n\
504 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
505 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
506 License for more details.\n\
508 You should have received a copy of the GNU General Public License\n\
509 along with this program; if not, write to the Free Software\n\
510 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
511 MA 02110-1301, USA. */\n");
514 /* Remove leading white spaces. */
516 static char *
517 remove_leading_whitespaces (char *str)
519 while (ISSPACE (*str))
520 str++;
521 return str;
524 /* Remove trailing white spaces. */
526 static void
527 remove_trailing_whitespaces (char *str)
529 size_t last = strlen (str);
531 if (last == 0)
532 return;
536 last--;
537 if (ISSPACE (str [last]))
538 str[last] = '\0';
539 else
540 break;
542 while (last != 0);
545 /* Find next field separated by SEP and terminate it. Return a
546 pointer to the one after it. */
548 static char *
549 next_field (char *str, char sep, char **next, char *last)
551 char *p;
553 p = remove_leading_whitespaces (str);
554 for (str = p; *str != sep && *str != '\0'; str++);
556 *str = '\0';
557 remove_trailing_whitespaces (p);
559 *next = str + 1;
561 if (p >= last)
562 abort ();
564 return p;
567 static void
568 set_bitfield (const char *f, bitfield *array, int value,
569 unsigned int size, int lineno)
571 unsigned int i;
573 if (strcmp (f, "CpuFP") == 0)
575 set_bitfield("Cpu387", array, value, size, lineno);
576 set_bitfield("Cpu287", array, value, size, lineno);
577 f = "Cpu8087";
579 else if (strcmp (f, "Mmword") == 0)
580 f= "Qword";
581 else if (strcmp (f, "Oword") == 0)
582 f= "Xmmword";
584 for (i = 0; i < size; i++)
585 if (strcasecmp (array[i].name, f) == 0)
587 array[i].value = value;
588 return;
591 if (value)
593 const char *v = strchr (f, '=');
595 if (v)
597 size_t n = v - f;
598 char *end;
600 for (i = 0; i < size; i++)
601 if (strncasecmp (array[i].name, f, n) == 0)
603 value = strtol (v + 1, &end, 0);
604 if (*end == '\0')
606 array[i].value = value;
607 return;
609 break;
614 if (lineno != -1)
615 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
616 else
617 fail (_("Unknown bitfield: %s\n"), f);
620 static void
621 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
622 int macro, const char *comma, const char *indent)
624 unsigned int i;
626 fprintf (table, "%s{ { ", indent);
628 for (i = 0; i < size - 1; i++)
630 fprintf (table, "%d, ", flags[i].value);
631 if (((i + 1) % 20) == 0)
633 /* We need \\ for macro. */
634 if (macro)
635 fprintf (table, " \\\n %s", indent);
636 else
637 fprintf (table, "\n %s", indent);
641 fprintf (table, "%d } }%s\n", flags[i].value, comma);
644 static void
645 process_i386_cpu_flag (FILE *table, char *flag, int macro,
646 const char *comma, const char *indent,
647 int lineno)
649 char *str, *next, *last;
650 unsigned int i;
651 bitfield flags [ARRAY_SIZE (cpu_flags)];
653 /* Copy the default cpu flags. */
654 memcpy (flags, cpu_flags, sizeof (cpu_flags));
656 if (strcasecmp (flag, "unknown") == 0)
658 /* We turn on everything except for cpu64 in case of
659 CPU_UNKNOWN_FLAGS. */
660 for (i = 0; i < ARRAY_SIZE (flags); i++)
661 if (flags[i].position != Cpu64)
662 flags[i].value = 1;
664 else if (flag[0] == '~')
666 last = flag + strlen (flag);
668 if (flag[1] == '(')
670 last -= 1;
671 next = flag + 2;
672 if (*last != ')')
673 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
674 lineno, flag);
675 *last = '\0';
677 else
678 next = flag + 1;
680 /* First we turn on everything except for cpu64. */
681 for (i = 0; i < ARRAY_SIZE (flags); i++)
682 if (flags[i].position != Cpu64)
683 flags[i].value = 1;
685 /* Turn off selective bits. */
686 for (; next && next < last; )
688 str = next_field (next, '|', &next, last);
689 if (str)
690 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
693 else if (strcmp (flag, "0"))
695 /* Turn on selective bits. */
696 last = flag + strlen (flag);
697 for (next = flag; next && next < last; )
699 str = next_field (next, '|', &next, last);
700 if (str)
701 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
705 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
706 comma, indent);
709 static void
710 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
712 unsigned int i;
714 fprintf (table, " { ");
716 for (i = 0; i < size - 1; i++)
718 fprintf (table, "%d, ", modifier[i].value);
719 if (((i + 1) % 20) == 0)
720 fprintf (table, "\n ");
723 fprintf (table, "%d },\n", modifier[i].value);
726 static void
727 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
729 char *str, *next, *last;
730 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
732 /* Copy the default opcode modifier. */
733 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
735 if (strcmp (mod, "0"))
737 last = mod + strlen (mod);
738 for (next = mod; next && next < last; )
740 str = next_field (next, '|', &next, last);
741 if (str)
742 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
743 lineno);
746 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
749 static void
750 output_operand_type (FILE *table, bitfield *types, unsigned int size,
751 int macro, const char *indent)
753 unsigned int i;
755 fprintf (table, "{ { ");
757 for (i = 0; i < size - 1; i++)
759 fprintf (table, "%d, ", types[i].value);
760 if (((i + 1) % 20) == 0)
762 /* We need \\ for macro. */
763 if (macro)
764 fprintf (table, "\\\n%s", indent);
765 else
766 fprintf (table, "\n%s", indent);
770 fprintf (table, "%d } }", types[i].value);
773 static void
774 process_i386_operand_type (FILE *table, char *op, int macro,
775 const char *indent, int lineno)
777 char *str, *next, *last;
778 bitfield types [ARRAY_SIZE (operand_types)];
780 /* Copy the default operand type. */
781 memcpy (types, operand_types, sizeof (types));
783 if (strcmp (op, "0"))
785 last = op + strlen (op);
786 for (next = op; next && next < last; )
788 str = next_field (next, '|', &next, last);
789 if (str)
790 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
793 output_operand_type (table, types, ARRAY_SIZE (types), macro,
794 indent);
797 static void
798 output_i386_opcode (FILE *table, const char *name, char *str,
799 char *last, int lineno)
801 unsigned int i;
802 char *operands, *base_opcode, *extension_opcode, *opcode_length;
803 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
805 /* Find number of operands. */
806 operands = next_field (str, ',', &str, last);
808 /* Find base_opcode. */
809 base_opcode = next_field (str, ',', &str, last);
811 /* Find extension_opcode. */
812 extension_opcode = next_field (str, ',', &str, last);
814 /* Find opcode_length. */
815 opcode_length = next_field (str, ',', &str, last);
817 /* Find cpu_flags. */
818 cpu_flags = next_field (str, ',', &str, last);
820 /* Find opcode_modifier. */
821 opcode_modifier = next_field (str, ',', &str, last);
823 /* Remove the first {. */
824 str = remove_leading_whitespaces (str);
825 if (*str != '{')
826 abort ();
827 str = remove_leading_whitespaces (str + 1);
829 i = strlen (str);
831 /* There are at least "X}". */
832 if (i < 2)
833 abort ();
835 /* Remove trailing white spaces and }. */
838 i--;
839 if (ISSPACE (str[i]) || str[i] == '}')
840 str[i] = '\0';
841 else
842 break;
844 while (i != 0);
846 last = str + i;
848 /* Find operand_types. */
849 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
851 if (str >= last)
853 operand_types [i] = NULL;
854 break;
857 operand_types [i] = next_field (str, ',', &str, last);
858 if (*operand_types[i] == '0')
860 if (i != 0)
861 operand_types[i] = NULL;
862 break;
866 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
867 name, operands, base_opcode, extension_opcode,
868 opcode_length);
870 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
872 process_i386_opcode_modifier (table, opcode_modifier, lineno);
874 fprintf (table, " { ");
876 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
878 if (operand_types[i] == NULL || *operand_types[i] == '0')
880 if (i == 0)
881 process_i386_operand_type (table, "0", 0, "\t ", lineno);
882 break;
885 if (i != 0)
886 fprintf (table, ",\n ");
888 process_i386_operand_type (table, operand_types[i], 0,
889 "\t ", lineno);
891 fprintf (table, " } },\n");
894 struct opcode_hash_entry
896 struct opcode_hash_entry *next;
897 char *name;
898 char *opcode;
899 int lineno;
902 /* Calculate the hash value of an opcode hash entry P. */
904 static hashval_t
905 opcode_hash_hash (const void *p)
907 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
908 return htab_hash_string (entry->name);
911 /* Compare a string Q against an opcode hash entry P. */
913 static int
914 opcode_hash_eq (const void *p, const void *q)
916 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
917 const char *name = (const char *) q;
918 return strcmp (name, entry->name) == 0;
921 static void
922 process_i386_opcodes (FILE *table)
924 FILE *fp;
925 char buf[2048];
926 unsigned int i, j;
927 char *str, *p, *last, *name;
928 struct opcode_hash_entry **hash_slot, **entry, *next;
929 htab_t opcode_hash_table;
930 struct opcode_hash_entry **opcode_array;
931 unsigned int opcode_array_size = 1024;
932 int lineno = 0;
934 filename = "i386-opc.tbl";
935 fp = fopen (filename, "r");
937 if (fp == NULL)
938 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
939 xstrerror (errno));
941 i = 0;
942 opcode_array = (struct opcode_hash_entry **)
943 xmalloc (sizeof (*opcode_array) * opcode_array_size);
945 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
946 opcode_hash_eq, NULL,
947 xcalloc, free);
949 fprintf (table, "\n/* i386 opcode table. */\n\n");
950 fprintf (table, "const insn_template i386_optab[] =\n{\n");
952 /* Put everything on opcode array. */
953 while (!feof (fp))
955 if (fgets (buf, sizeof (buf), fp) == NULL)
956 break;
958 lineno++;
960 p = remove_leading_whitespaces (buf);
962 /* Skip comments. */
963 str = strstr (p, "//");
964 if (str != NULL)
965 str[0] = '\0';
967 /* Remove trailing white spaces. */
968 remove_trailing_whitespaces (p);
970 switch (p[0])
972 case '#':
973 /* Ignore comments. */
974 case '\0':
975 continue;
976 break;
977 default:
978 break;
981 last = p + strlen (p);
983 /* Find name. */
984 name = next_field (p, ',', &str, last);
986 /* Get the slot in hash table. */
987 hash_slot = (struct opcode_hash_entry **)
988 htab_find_slot_with_hash (opcode_hash_table, name,
989 htab_hash_string (name),
990 INSERT);
992 if (*hash_slot == NULL)
994 /* It is the new one. Put it on opcode array. */
995 if (i >= opcode_array_size)
997 /* Grow the opcode array when needed. */
998 opcode_array_size += 1024;
999 opcode_array = (struct opcode_hash_entry **)
1000 xrealloc (opcode_array,
1001 sizeof (*opcode_array) * opcode_array_size);
1004 opcode_array[i] = (struct opcode_hash_entry *)
1005 xmalloc (sizeof (struct opcode_hash_entry));
1006 opcode_array[i]->next = NULL;
1007 opcode_array[i]->name = xstrdup (name);
1008 opcode_array[i]->opcode = xstrdup (str);
1009 opcode_array[i]->lineno = lineno;
1010 *hash_slot = opcode_array[i];
1011 i++;
1013 else
1015 /* Append it to the existing one. */
1016 entry = hash_slot;
1017 while ((*entry) != NULL)
1018 entry = &(*entry)->next;
1019 *entry = (struct opcode_hash_entry *)
1020 xmalloc (sizeof (struct opcode_hash_entry));
1021 (*entry)->next = NULL;
1022 (*entry)->name = (*hash_slot)->name;
1023 (*entry)->opcode = xstrdup (str);
1024 (*entry)->lineno = lineno;
1028 /* Process opcode array. */
1029 for (j = 0; j < i; j++)
1031 for (next = opcode_array[j]; next; next = next->next)
1033 name = next->name;
1034 str = next->opcode;
1035 lineno = next->lineno;
1036 last = str + strlen (str);
1037 output_i386_opcode (table, name, str, last, lineno);
1041 fclose (fp);
1043 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1045 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1047 process_i386_opcode_modifier (table, "0", -1);
1049 fprintf (table, " { ");
1050 process_i386_operand_type (table, "0", 0, "\t ", -1);
1051 fprintf (table, " } }\n");
1053 fprintf (table, "};\n");
1056 static void
1057 process_i386_registers (FILE *table)
1059 FILE *fp;
1060 char buf[2048];
1061 char *str, *p, *last;
1062 char *reg_name, *reg_type, *reg_flags, *reg_num;
1063 char *dw2_32_num, *dw2_64_num;
1064 int lineno = 0;
1066 filename = "i386-reg.tbl";
1067 fp = fopen (filename, "r");
1068 if (fp == NULL)
1069 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1070 xstrerror (errno));
1072 fprintf (table, "\n/* i386 register table. */\n\n");
1073 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1075 while (!feof (fp))
1077 if (fgets (buf, sizeof (buf), fp) == NULL)
1078 break;
1080 lineno++;
1082 p = remove_leading_whitespaces (buf);
1084 /* Skip comments. */
1085 str = strstr (p, "//");
1086 if (str != NULL)
1087 str[0] = '\0';
1089 /* Remove trailing white spaces. */
1090 remove_trailing_whitespaces (p);
1092 switch (p[0])
1094 case '#':
1095 fprintf (table, "%s\n", p);
1096 case '\0':
1097 continue;
1098 break;
1099 default:
1100 break;
1103 last = p + strlen (p);
1105 /* Find reg_name. */
1106 reg_name = next_field (p, ',', &str, last);
1108 /* Find reg_type. */
1109 reg_type = next_field (str, ',', &str, last);
1111 /* Find reg_flags. */
1112 reg_flags = next_field (str, ',', &str, last);
1114 /* Find reg_num. */
1115 reg_num = next_field (str, ',', &str, last);
1117 fprintf (table, " { \"%s\",\n ", reg_name);
1119 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1121 /* Find 32-bit Dwarf2 register number. */
1122 dw2_32_num = next_field (str, ',', &str, last);
1124 /* Find 64-bit Dwarf2 register number. */
1125 dw2_64_num = next_field (str, ',', &str, last);
1127 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1128 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1131 fclose (fp);
1133 fprintf (table, "};\n");
1135 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1138 static void
1139 process_i386_initializers (void)
1141 unsigned int i;
1142 FILE *fp = fopen ("i386-init.h", "w");
1143 char *init;
1145 if (fp == NULL)
1146 fail (_("can't create i386-init.h, errno = %s\n"),
1147 xstrerror (errno));
1149 process_copyright (fp);
1151 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1153 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1154 init = xstrdup (cpu_flag_init[i].init);
1155 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1156 free (init);
1159 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1161 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1162 init = xstrdup (operand_type_init[i].init);
1163 process_i386_operand_type (fp, init, 1, " ", -1);
1164 free (init);
1166 fprintf (fp, "\n");
1168 fclose (fp);
1171 /* Program options. */
1172 #define OPTION_SRCDIR 200
1174 struct option long_options[] =
1176 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1177 {"debug", no_argument, NULL, 'd'},
1178 {"version", no_argument, NULL, 'V'},
1179 {"help", no_argument, NULL, 'h'},
1180 {0, no_argument, NULL, 0}
1183 static void
1184 print_version (void)
1186 printf ("%s: version 1.0\n", program_name);
1187 xexit (0);
1190 static void
1191 usage (FILE * stream, int status)
1193 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1194 program_name);
1195 xexit (status);
1199 main (int argc, char **argv)
1201 extern int chdir (char *);
1202 char *srcdir = NULL;
1203 int c;
1204 FILE *table;
1206 program_name = *argv;
1207 xmalloc_set_program_name (program_name);
1209 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1210 switch (c)
1212 case OPTION_SRCDIR:
1213 srcdir = optarg;
1214 break;
1215 case 'V':
1216 case 'v':
1217 print_version ();
1218 break;
1219 case 'd':
1220 debug = 1;
1221 break;
1222 case 'h':
1223 case '?':
1224 usage (stderr, 0);
1225 default:
1226 case 0:
1227 break;
1230 if (optind != argc)
1231 usage (stdout, 1);
1233 if (srcdir != NULL)
1234 if (chdir (srcdir) != 0)
1235 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1236 srcdir, xstrerror (errno));
1238 /* Check the unused bitfield in i386_cpu_flags. */
1239 #ifndef CpuUnused
1240 c = CpuNumOfBits - CpuMax - 1;
1241 if (c)
1242 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1243 #endif
1245 /* Check the unused bitfield in i386_operand_type. */
1246 #ifndef OTUnused
1247 c = OTNumOfBits - OTMax - 1;
1248 if (c)
1249 fail (_("%d unused bits in i386_operand_type.\n"), c);
1250 #endif
1252 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1253 compare);
1255 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1256 sizeof (opcode_modifiers [0]), compare);
1258 qsort (operand_types, ARRAY_SIZE (operand_types),
1259 sizeof (operand_types [0]), compare);
1261 table = fopen ("i386-tbl.h", "w");
1262 if (table == NULL)
1263 fail (_("can't create i386-tbl.h, errno = %s\n"),
1264 xstrerror (errno));
1266 process_copyright (table);
1268 process_i386_opcodes (table);
1269 process_i386_registers (table);
1270 process_i386_initializers ();
1272 fclose (table);
1274 exit (0);