PR gas/12931
[binutils.git] / opcodes / i386-gen.c
blob84354663a8850378b4ddc9d16245dd4f86ee411e
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" },
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" },
189 static initializer operand_type_init[] =
191 { "OPERAND_TYPE_NONE",
192 "0" },
193 { "OPERAND_TYPE_REG8",
194 "Reg8" },
195 { "OPERAND_TYPE_REG16",
196 "Reg16" },
197 { "OPERAND_TYPE_REG32",
198 "Reg32" },
199 { "OPERAND_TYPE_REG64",
200 "Reg64" },
201 { "OPERAND_TYPE_IMM1",
202 "Imm1" },
203 { "OPERAND_TYPE_IMM8",
204 "Imm8" },
205 { "OPERAND_TYPE_IMM8S",
206 "Imm8S" },
207 { "OPERAND_TYPE_IMM16",
208 "Imm16" },
209 { "OPERAND_TYPE_IMM32",
210 "Imm32" },
211 { "OPERAND_TYPE_IMM32S",
212 "Imm32S" },
213 { "OPERAND_TYPE_IMM64",
214 "Imm64" },
215 { "OPERAND_TYPE_BASEINDEX",
216 "BaseIndex" },
217 { "OPERAND_TYPE_DISP8",
218 "Disp8" },
219 { "OPERAND_TYPE_DISP16",
220 "Disp16" },
221 { "OPERAND_TYPE_DISP32",
222 "Disp32" },
223 { "OPERAND_TYPE_DISP32S",
224 "Disp32S" },
225 { "OPERAND_TYPE_DISP64",
226 "Disp64" },
227 { "OPERAND_TYPE_INOUTPORTREG",
228 "InOutPortReg" },
229 { "OPERAND_TYPE_SHIFTCOUNT",
230 "ShiftCount" },
231 { "OPERAND_TYPE_CONTROL",
232 "Control" },
233 { "OPERAND_TYPE_TEST",
234 "Test" },
235 { "OPERAND_TYPE_DEBUG",
236 "FloatReg" },
237 { "OPERAND_TYPE_FLOATREG",
238 "FloatReg" },
239 { "OPERAND_TYPE_FLOATACC",
240 "FloatAcc" },
241 { "OPERAND_TYPE_SREG2",
242 "SReg2" },
243 { "OPERAND_TYPE_SREG3",
244 "SReg3" },
245 { "OPERAND_TYPE_ACC",
246 "Acc" },
247 { "OPERAND_TYPE_JUMPABSOLUTE",
248 "JumpAbsolute" },
249 { "OPERAND_TYPE_REGMMX",
250 "RegMMX" },
251 { "OPERAND_TYPE_REGXMM",
252 "RegXMM" },
253 { "OPERAND_TYPE_REGYMM",
254 "RegYMM" },
255 { "OPERAND_TYPE_ESSEG",
256 "EsSeg" },
257 { "OPERAND_TYPE_ACC32",
258 "Reg32|Acc|Dword" },
259 { "OPERAND_TYPE_ACC64",
260 "Reg64|Acc|Qword" },
261 { "OPERAND_TYPE_INOUTPORTREG",
262 "InOutPortReg" },
263 { "OPERAND_TYPE_REG16_INOUTPORTREG",
264 "Reg16|InOutPortReg" },
265 { "OPERAND_TYPE_DISP16_32",
266 "Disp16|Disp32" },
267 { "OPERAND_TYPE_ANYDISP",
268 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
269 { "OPERAND_TYPE_IMM16_32",
270 "Imm16|Imm32" },
271 { "OPERAND_TYPE_IMM16_32S",
272 "Imm16|Imm32S" },
273 { "OPERAND_TYPE_IMM16_32_32S",
274 "Imm16|Imm32|Imm32S" },
275 { "OPERAND_TYPE_IMM32_32S_DISP32",
276 "Imm32|Imm32S|Disp32" },
277 { "OPERAND_TYPE_IMM64_DISP64",
278 "Imm64|Disp64" },
279 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
280 "Imm32|Imm32S|Imm64|Disp32" },
281 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
282 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
283 { "OPERAND_TYPE_VEC_IMM4",
284 "Vec_Imm4" },
287 typedef struct bitfield
289 int position;
290 int value;
291 const char *name;
292 } bitfield;
294 #define BITFIELD(n) { n, 0, #n }
296 static bitfield cpu_flags[] =
298 BITFIELD (Cpu186),
299 BITFIELD (Cpu286),
300 BITFIELD (Cpu386),
301 BITFIELD (Cpu486),
302 BITFIELD (Cpu586),
303 BITFIELD (Cpu686),
304 BITFIELD (CpuClflush),
305 BITFIELD (CpuNop),
306 BITFIELD (CpuSYSCALL),
307 BITFIELD (Cpu8087),
308 BITFIELD (Cpu287),
309 BITFIELD (Cpu387),
310 BITFIELD (Cpu687),
311 BITFIELD (CpuFISTTP),
312 BITFIELD (CpuMMX),
313 BITFIELD (CpuSSE),
314 BITFIELD (CpuSSE2),
315 BITFIELD (CpuSSE3),
316 BITFIELD (CpuSSSE3),
317 BITFIELD (CpuSSE4_1),
318 BITFIELD (CpuSSE4_2),
319 BITFIELD (CpuAVX),
320 BITFIELD (CpuAVX2),
321 BITFIELD (CpuL1OM),
322 BITFIELD (CpuSSE4a),
323 BITFIELD (Cpu3dnow),
324 BITFIELD (Cpu3dnowA),
325 BITFIELD (CpuPadLock),
326 BITFIELD (CpuSVME),
327 BITFIELD (CpuVMX),
328 BITFIELD (CpuSMX),
329 BITFIELD (CpuABM),
330 BITFIELD (CpuXsave),
331 BITFIELD (CpuXsaveopt),
332 BITFIELD (CpuAES),
333 BITFIELD (CpuPCLMUL),
334 BITFIELD (CpuFMA),
335 BITFIELD (CpuFMA4),
336 BITFIELD (CpuXOP),
337 BITFIELD (CpuLWP),
338 BITFIELD (CpuBMI),
339 BITFIELD (CpuTBM),
340 BITFIELD (CpuLM),
341 BITFIELD (CpuMovbe),
342 BITFIELD (CpuEPT),
343 BITFIELD (CpuRdtscp),
344 BITFIELD (CpuFSGSBase),
345 BITFIELD (CpuRdRnd),
346 BITFIELD (CpuF16C),
347 BITFIELD (CpuBMI2),
348 BITFIELD (CpuLZCNT),
349 BITFIELD (CpuINVPCID),
350 BITFIELD (Cpu64),
351 BITFIELD (CpuNo64),
352 #ifdef CpuUnused
353 BITFIELD (CpuUnused),
354 #endif
357 static bitfield opcode_modifiers[] =
359 BITFIELD (D),
360 BITFIELD (W),
361 BITFIELD (S),
362 BITFIELD (Modrm),
363 BITFIELD (ShortForm),
364 BITFIELD (Jump),
365 BITFIELD (JumpDword),
366 BITFIELD (JumpByte),
367 BITFIELD (JumpInterSegment),
368 BITFIELD (FloatMF),
369 BITFIELD (FloatR),
370 BITFIELD (FloatD),
371 BITFIELD (Size16),
372 BITFIELD (Size32),
373 BITFIELD (Size64),
374 BITFIELD (CheckRegSize),
375 BITFIELD (IgnoreSize),
376 BITFIELD (DefaultSize),
377 BITFIELD (No_bSuf),
378 BITFIELD (No_wSuf),
379 BITFIELD (No_lSuf),
380 BITFIELD (No_sSuf),
381 BITFIELD (No_qSuf),
382 BITFIELD (No_ldSuf),
383 BITFIELD (FWait),
384 BITFIELD (IsString),
385 BITFIELD (IsLockable),
386 BITFIELD (RegKludge),
387 BITFIELD (FirstXmm0),
388 BITFIELD (Implicit1stXmm0),
389 BITFIELD (ToDword),
390 BITFIELD (ToQword),
391 BITFIELD (AddrPrefixOp0),
392 BITFIELD (IsPrefix),
393 BITFIELD (ImmExt),
394 BITFIELD (NoRex64),
395 BITFIELD (Rex64),
396 BITFIELD (Ugh),
397 BITFIELD (Vex),
398 BITFIELD (VexVVVV),
399 BITFIELD (VexW),
400 BITFIELD (VexOpcode),
401 BITFIELD (VexSources),
402 BITFIELD (VexImmExt),
403 BITFIELD (VecSIB),
404 BITFIELD (SSE2AVX),
405 BITFIELD (NoAVX),
406 BITFIELD (OldGcc),
407 BITFIELD (ATTMnemonic),
408 BITFIELD (ATTSyntax),
409 BITFIELD (IntelSyntax),
412 static bitfield operand_types[] =
414 BITFIELD (Reg8),
415 BITFIELD (Reg16),
416 BITFIELD (Reg32),
417 BITFIELD (Reg64),
418 BITFIELD (FloatReg),
419 BITFIELD (RegMMX),
420 BITFIELD (RegXMM),
421 BITFIELD (RegYMM),
422 BITFIELD (Imm1),
423 BITFIELD (Imm8),
424 BITFIELD (Imm8S),
425 BITFIELD (Imm16),
426 BITFIELD (Imm32),
427 BITFIELD (Imm32S),
428 BITFIELD (Imm64),
429 BITFIELD (BaseIndex),
430 BITFIELD (Disp8),
431 BITFIELD (Disp16),
432 BITFIELD (Disp32),
433 BITFIELD (Disp32S),
434 BITFIELD (Disp64),
435 BITFIELD (InOutPortReg),
436 BITFIELD (ShiftCount),
437 BITFIELD (Control),
438 BITFIELD (Debug),
439 BITFIELD (Test),
440 BITFIELD (SReg2),
441 BITFIELD (SReg3),
442 BITFIELD (Acc),
443 BITFIELD (FloatAcc),
444 BITFIELD (JumpAbsolute),
445 BITFIELD (EsSeg),
446 BITFIELD (RegMem),
447 BITFIELD (Mem),
448 BITFIELD (Byte),
449 BITFIELD (Word),
450 BITFIELD (Dword),
451 BITFIELD (Fword),
452 BITFIELD (Qword),
453 BITFIELD (Tbyte),
454 BITFIELD (Xmmword),
455 BITFIELD (Ymmword),
456 BITFIELD (Unspecified),
457 BITFIELD (Anysize),
458 BITFIELD (Vec_Imm4),
459 #ifdef OTUnused
460 BITFIELD (OTUnused),
461 #endif
464 static const char *filename;
466 static int
467 compare (const void *x, const void *y)
469 const bitfield *xp = (const bitfield *) x;
470 const bitfield *yp = (const bitfield *) y;
471 return xp->position - yp->position;
474 static void
475 fail (const char *message, ...)
477 va_list args;
479 va_start (args, message);
480 fprintf (stderr, _("%s: Error: "), program_name);
481 vfprintf (stderr, message, args);
482 va_end (args);
483 xexit (1);
486 static void
487 process_copyright (FILE *fp)
489 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
490 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
491 Free Software Foundation, Inc.\n\
493 This file is part of the GNU opcodes library.\n\
495 This library is free software; you can redistribute it and/or modify\n\
496 it under the terms of the GNU General Public License as published by\n\
497 the Free Software Foundation; either version 3, or (at your option)\n\
498 any later version.\n\
500 It is distributed in the hope that it will be useful, but WITHOUT\n\
501 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
502 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
503 License for more details.\n\
505 You should have received a copy of the GNU General Public License\n\
506 along with this program; if not, write to the Free Software\n\
507 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
508 MA 02110-1301, USA. */\n");
511 /* Remove leading white spaces. */
513 static char *
514 remove_leading_whitespaces (char *str)
516 while (ISSPACE (*str))
517 str++;
518 return str;
521 /* Remove trailing white spaces. */
523 static void
524 remove_trailing_whitespaces (char *str)
526 size_t last = strlen (str);
528 if (last == 0)
529 return;
533 last--;
534 if (ISSPACE (str [last]))
535 str[last] = '\0';
536 else
537 break;
539 while (last != 0);
542 /* Find next field separated by SEP and terminate it. Return a
543 pointer to the one after it. */
545 static char *
546 next_field (char *str, char sep, char **next, char *last)
548 char *p;
550 p = remove_leading_whitespaces (str);
551 for (str = p; *str != sep && *str != '\0'; str++);
553 *str = '\0';
554 remove_trailing_whitespaces (p);
556 *next = str + 1;
558 if (p >= last)
559 abort ();
561 return p;
564 static void
565 set_bitfield (const char *f, bitfield *array, int value,
566 unsigned int size, int lineno)
568 unsigned int i;
570 if (strcmp (f, "CpuFP") == 0)
572 set_bitfield("Cpu387", array, value, size, lineno);
573 set_bitfield("Cpu287", array, value, size, lineno);
574 f = "Cpu8087";
576 else if (strcmp (f, "Mmword") == 0)
577 f= "Qword";
578 else if (strcmp (f, "Oword") == 0)
579 f= "Xmmword";
581 for (i = 0; i < size; i++)
582 if (strcasecmp (array[i].name, f) == 0)
584 array[i].value = value;
585 return;
588 if (value)
590 const char *v = strchr (f, '=');
592 if (v)
594 size_t n = v - f;
595 char *end;
597 for (i = 0; i < size; i++)
598 if (strncasecmp (array[i].name, f, n) == 0)
600 value = strtol (v + 1, &end, 0);
601 if (*end == '\0')
603 array[i].value = value;
604 return;
606 break;
611 if (lineno != -1)
612 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
613 else
614 fail (_("Unknown bitfield: %s\n"), f);
617 static void
618 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
619 int macro, const char *comma, const char *indent)
621 unsigned int i;
623 fprintf (table, "%s{ { ", indent);
625 for (i = 0; i < size - 1; i++)
627 fprintf (table, "%d, ", flags[i].value);
628 if (((i + 1) % 20) == 0)
630 /* We need \\ for macro. */
631 if (macro)
632 fprintf (table, " \\\n %s", indent);
633 else
634 fprintf (table, "\n %s", indent);
638 fprintf (table, "%d } }%s\n", flags[i].value, comma);
641 static void
642 process_i386_cpu_flag (FILE *table, char *flag, int macro,
643 const char *comma, const char *indent,
644 int lineno)
646 char *str, *next, *last;
647 unsigned int i;
648 bitfield flags [ARRAY_SIZE (cpu_flags)];
650 /* Copy the default cpu flags. */
651 memcpy (flags, cpu_flags, sizeof (cpu_flags));
653 if (strcasecmp (flag, "unknown") == 0)
655 /* We turn on everything except for cpu64 in case of
656 CPU_UNKNOWN_FLAGS. */
657 for (i = 0; i < ARRAY_SIZE (flags); i++)
658 if (flags[i].position != Cpu64)
659 flags[i].value = 1;
661 else if (flag[0] == '~')
663 last = flag + strlen (flag);
665 if (flag[1] == '(')
667 last -= 1;
668 next = flag + 2;
669 if (*last != ')')
670 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
671 lineno, flag);
672 *last = '\0';
674 else
675 next = flag + 1;
677 /* First we turn on everything except for cpu64. */
678 for (i = 0; i < ARRAY_SIZE (flags); i++)
679 if (flags[i].position != Cpu64)
680 flags[i].value = 1;
682 /* Turn off selective bits. */
683 for (; next && next < last; )
685 str = next_field (next, '|', &next, last);
686 if (str)
687 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
690 else if (strcmp (flag, "0"))
692 /* Turn on selective bits. */
693 last = flag + strlen (flag);
694 for (next = flag; next && next < last; )
696 str = next_field (next, '|', &next, last);
697 if (str)
698 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
702 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
703 comma, indent);
706 static void
707 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
709 unsigned int i;
711 fprintf (table, " { ");
713 for (i = 0; i < size - 1; i++)
715 fprintf (table, "%d, ", modifier[i].value);
716 if (((i + 1) % 20) == 0)
717 fprintf (table, "\n ");
720 fprintf (table, "%d },\n", modifier[i].value);
723 static void
724 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
726 char *str, *next, *last;
727 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
729 /* Copy the default opcode modifier. */
730 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
732 if (strcmp (mod, "0"))
734 last = mod + strlen (mod);
735 for (next = mod; next && next < last; )
737 str = next_field (next, '|', &next, last);
738 if (str)
739 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
740 lineno);
743 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
746 static void
747 output_operand_type (FILE *table, bitfield *types, unsigned int size,
748 int macro, const char *indent)
750 unsigned int i;
752 fprintf (table, "{ { ");
754 for (i = 0; i < size - 1; i++)
756 fprintf (table, "%d, ", types[i].value);
757 if (((i + 1) % 20) == 0)
759 /* We need \\ for macro. */
760 if (macro)
761 fprintf (table, "\\\n%s", indent);
762 else
763 fprintf (table, "\n%s", indent);
767 fprintf (table, "%d } }", types[i].value);
770 static void
771 process_i386_operand_type (FILE *table, char *op, int macro,
772 const char *indent, int lineno)
774 char *str, *next, *last;
775 bitfield types [ARRAY_SIZE (operand_types)];
777 /* Copy the default operand type. */
778 memcpy (types, operand_types, sizeof (types));
780 if (strcmp (op, "0"))
782 last = op + strlen (op);
783 for (next = op; next && next < last; )
785 str = next_field (next, '|', &next, last);
786 if (str)
787 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
790 output_operand_type (table, types, ARRAY_SIZE (types), macro,
791 indent);
794 static void
795 output_i386_opcode (FILE *table, const char *name, char *str,
796 char *last, int lineno)
798 unsigned int i;
799 char *operands, *base_opcode, *extension_opcode, *opcode_length;
800 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
802 /* Find number of operands. */
803 operands = next_field (str, ',', &str, last);
805 /* Find base_opcode. */
806 base_opcode = next_field (str, ',', &str, last);
808 /* Find extension_opcode. */
809 extension_opcode = next_field (str, ',', &str, last);
811 /* Find opcode_length. */
812 opcode_length = next_field (str, ',', &str, last);
814 /* Find cpu_flags. */
815 cpu_flags = next_field (str, ',', &str, last);
817 /* Find opcode_modifier. */
818 opcode_modifier = next_field (str, ',', &str, last);
820 /* Remove the first {. */
821 str = remove_leading_whitespaces (str);
822 if (*str != '{')
823 abort ();
824 str = remove_leading_whitespaces (str + 1);
826 i = strlen (str);
828 /* There are at least "X}". */
829 if (i < 2)
830 abort ();
832 /* Remove trailing white spaces and }. */
835 i--;
836 if (ISSPACE (str[i]) || str[i] == '}')
837 str[i] = '\0';
838 else
839 break;
841 while (i != 0);
843 last = str + i;
845 /* Find operand_types. */
846 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
848 if (str >= last)
850 operand_types [i] = NULL;
851 break;
854 operand_types [i] = next_field (str, ',', &str, last);
855 if (*operand_types[i] == '0')
857 if (i != 0)
858 operand_types[i] = NULL;
859 break;
863 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
864 name, operands, base_opcode, extension_opcode,
865 opcode_length);
867 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
869 process_i386_opcode_modifier (table, opcode_modifier, lineno);
871 fprintf (table, " { ");
873 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
875 if (operand_types[i] == NULL || *operand_types[i] == '0')
877 if (i == 0)
878 process_i386_operand_type (table, "0", 0, "\t ", lineno);
879 break;
882 if (i != 0)
883 fprintf (table, ",\n ");
885 process_i386_operand_type (table, operand_types[i], 0,
886 "\t ", lineno);
888 fprintf (table, " } },\n");
891 struct opcode_hash_entry
893 struct opcode_hash_entry *next;
894 char *name;
895 char *opcode;
896 int lineno;
899 /* Calculate the hash value of an opcode hash entry P. */
901 static hashval_t
902 opcode_hash_hash (const void *p)
904 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
905 return htab_hash_string (entry->name);
908 /* Compare a string Q against an opcode hash entry P. */
910 static int
911 opcode_hash_eq (const void *p, const void *q)
913 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
914 const char *name = (const char *) q;
915 return strcmp (name, entry->name) == 0;
918 static void
919 process_i386_opcodes (FILE *table)
921 FILE *fp;
922 char buf[2048];
923 unsigned int i, j;
924 char *str, *p, *last, *name;
925 struct opcode_hash_entry **hash_slot, **entry, *next;
926 htab_t opcode_hash_table;
927 struct opcode_hash_entry **opcode_array;
928 unsigned int opcode_array_size = 1024;
929 int lineno = 0;
931 filename = "i386-opc.tbl";
932 fp = fopen (filename, "r");
934 if (fp == NULL)
935 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
936 xstrerror (errno));
938 i = 0;
939 opcode_array = (struct opcode_hash_entry **)
940 xmalloc (sizeof (*opcode_array) * opcode_array_size);
942 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
943 opcode_hash_eq, NULL,
944 xcalloc, free);
946 fprintf (table, "\n/* i386 opcode table. */\n\n");
947 fprintf (table, "const insn_template i386_optab[] =\n{\n");
949 /* Put everything on opcode array. */
950 while (!feof (fp))
952 if (fgets (buf, sizeof (buf), fp) == NULL)
953 break;
955 lineno++;
957 p = remove_leading_whitespaces (buf);
959 /* Skip comments. */
960 str = strstr (p, "//");
961 if (str != NULL)
962 str[0] = '\0';
964 /* Remove trailing white spaces. */
965 remove_trailing_whitespaces (p);
967 switch (p[0])
969 case '#':
970 /* Ignore comments. */
971 case '\0':
972 continue;
973 break;
974 default:
975 break;
978 last = p + strlen (p);
980 /* Find name. */
981 name = next_field (p, ',', &str, last);
983 /* Get the slot in hash table. */
984 hash_slot = (struct opcode_hash_entry **)
985 htab_find_slot_with_hash (opcode_hash_table, name,
986 htab_hash_string (name),
987 INSERT);
989 if (*hash_slot == NULL)
991 /* It is the new one. Put it on opcode array. */
992 if (i >= opcode_array_size)
994 /* Grow the opcode array when needed. */
995 opcode_array_size += 1024;
996 opcode_array = (struct opcode_hash_entry **)
997 xrealloc (opcode_array,
998 sizeof (*opcode_array) * opcode_array_size);
1001 opcode_array[i] = (struct opcode_hash_entry *)
1002 xmalloc (sizeof (struct opcode_hash_entry));
1003 opcode_array[i]->next = NULL;
1004 opcode_array[i]->name = xstrdup (name);
1005 opcode_array[i]->opcode = xstrdup (str);
1006 opcode_array[i]->lineno = lineno;
1007 *hash_slot = opcode_array[i];
1008 i++;
1010 else
1012 /* Append it to the existing one. */
1013 entry = hash_slot;
1014 while ((*entry) != NULL)
1015 entry = &(*entry)->next;
1016 *entry = (struct opcode_hash_entry *)
1017 xmalloc (sizeof (struct opcode_hash_entry));
1018 (*entry)->next = NULL;
1019 (*entry)->name = (*hash_slot)->name;
1020 (*entry)->opcode = xstrdup (str);
1021 (*entry)->lineno = lineno;
1025 /* Process opcode array. */
1026 for (j = 0; j < i; j++)
1028 for (next = opcode_array[j]; next; next = next->next)
1030 name = next->name;
1031 str = next->opcode;
1032 lineno = next->lineno;
1033 last = str + strlen (str);
1034 output_i386_opcode (table, name, str, last, lineno);
1038 fclose (fp);
1040 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1042 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1044 process_i386_opcode_modifier (table, "0", -1);
1046 fprintf (table, " { ");
1047 process_i386_operand_type (table, "0", 0, "\t ", -1);
1048 fprintf (table, " } }\n");
1050 fprintf (table, "};\n");
1053 static void
1054 process_i386_registers (FILE *table)
1056 FILE *fp;
1057 char buf[2048];
1058 char *str, *p, *last;
1059 char *reg_name, *reg_type, *reg_flags, *reg_num;
1060 char *dw2_32_num, *dw2_64_num;
1061 int lineno = 0;
1063 filename = "i386-reg.tbl";
1064 fp = fopen (filename, "r");
1065 if (fp == NULL)
1066 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1067 xstrerror (errno));
1069 fprintf (table, "\n/* i386 register table. */\n\n");
1070 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1072 while (!feof (fp))
1074 if (fgets (buf, sizeof (buf), fp) == NULL)
1075 break;
1077 lineno++;
1079 p = remove_leading_whitespaces (buf);
1081 /* Skip comments. */
1082 str = strstr (p, "//");
1083 if (str != NULL)
1084 str[0] = '\0';
1086 /* Remove trailing white spaces. */
1087 remove_trailing_whitespaces (p);
1089 switch (p[0])
1091 case '#':
1092 fprintf (table, "%s\n", p);
1093 case '\0':
1094 continue;
1095 break;
1096 default:
1097 break;
1100 last = p + strlen (p);
1102 /* Find reg_name. */
1103 reg_name = next_field (p, ',', &str, last);
1105 /* Find reg_type. */
1106 reg_type = next_field (str, ',', &str, last);
1108 /* Find reg_flags. */
1109 reg_flags = next_field (str, ',', &str, last);
1111 /* Find reg_num. */
1112 reg_num = next_field (str, ',', &str, last);
1114 fprintf (table, " { \"%s\",\n ", reg_name);
1116 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1118 /* Find 32-bit Dwarf2 register number. */
1119 dw2_32_num = next_field (str, ',', &str, last);
1121 /* Find 64-bit Dwarf2 register number. */
1122 dw2_64_num = next_field (str, ',', &str, last);
1124 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1125 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1128 fclose (fp);
1130 fprintf (table, "};\n");
1132 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1135 static void
1136 process_i386_initializers (void)
1138 unsigned int i;
1139 FILE *fp = fopen ("i386-init.h", "w");
1140 char *init;
1142 if (fp == NULL)
1143 fail (_("can't create i386-init.h, errno = %s\n"),
1144 xstrerror (errno));
1146 process_copyright (fp);
1148 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1150 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1151 init = xstrdup (cpu_flag_init[i].init);
1152 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1153 free (init);
1156 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1158 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1159 init = xstrdup (operand_type_init[i].init);
1160 process_i386_operand_type (fp, init, 1, " ", -1);
1161 free (init);
1163 fprintf (fp, "\n");
1165 fclose (fp);
1168 /* Program options. */
1169 #define OPTION_SRCDIR 200
1171 struct option long_options[] =
1173 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1174 {"debug", no_argument, NULL, 'd'},
1175 {"version", no_argument, NULL, 'V'},
1176 {"help", no_argument, NULL, 'h'},
1177 {0, no_argument, NULL, 0}
1180 static void
1181 print_version (void)
1183 printf ("%s: version 1.0\n", program_name);
1184 xexit (0);
1187 static void
1188 usage (FILE * stream, int status)
1190 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1191 program_name);
1192 xexit (status);
1196 main (int argc, char **argv)
1198 extern int chdir (char *);
1199 char *srcdir = NULL;
1200 int c;
1201 FILE *table;
1203 program_name = *argv;
1204 xmalloc_set_program_name (program_name);
1206 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1207 switch (c)
1209 case OPTION_SRCDIR:
1210 srcdir = optarg;
1211 break;
1212 case 'V':
1213 case 'v':
1214 print_version ();
1215 break;
1216 case 'd':
1217 debug = 1;
1218 break;
1219 case 'h':
1220 case '?':
1221 usage (stderr, 0);
1222 default:
1223 case 0:
1224 break;
1227 if (optind != argc)
1228 usage (stdout, 1);
1230 if (srcdir != NULL)
1231 if (chdir (srcdir) != 0)
1232 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1233 srcdir, xstrerror (errno));
1235 /* Check the unused bitfield in i386_cpu_flags. */
1236 #ifndef CpuUnused
1237 c = CpuNumOfBits - CpuMax - 1;
1238 if (c)
1239 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1240 #endif
1242 /* Check the unused bitfield in i386_operand_type. */
1243 #ifndef OTUnused
1244 c = OTNumOfBits - OTMax - 1;
1245 if (c)
1246 fail (_("%d unused bits in i386_operand_type.\n"), c);
1247 #endif
1249 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1250 compare);
1252 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1253 sizeof (opcode_modifiers [0]), compare);
1255 qsort (operand_types, ARRAY_SIZE (operand_types),
1256 sizeof (operand_types [0]), compare);
1258 table = fopen ("i386-tbl.h", "w");
1259 if (table == NULL)
1260 fail (_("can't create i386-tbl.h, errno = %s\n"),
1261 xstrerror (errno));
1263 process_copyright (table);
1265 process_i386_opcodes (table);
1266 process_i386_registers (table);
1267 process_i386_initializers ();
1269 fclose (table);
1271 exit (0);