gas:
[binutils.git] / opcodes / i386-gen.c
blob21f600f034ab818c117b30e3b095a3c14e33791f
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_HLE_FLAGS",
166 "CpuHLE" },
167 { "CPU_RTM_FLAGS",
168 "CpuRTM" },
169 { "CPU_INVPCID_FLAGS",
170 "CpuINVPCID" },
171 { "CPU_VMFUNC_FLAGS",
172 "CpuVMFUNC" },
173 { "CPU_3DNOW_FLAGS",
174 "CpuMMX|Cpu3dnow" },
175 { "CPU_3DNOWA_FLAGS",
176 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
177 { "CPU_PADLOCK_FLAGS",
178 "CpuPadLock" },
179 { "CPU_SVME_FLAGS",
180 "CpuSVME" },
181 { "CPU_SSE4A_FLAGS",
182 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
183 { "CPU_ABM_FLAGS",
184 "CpuABM" },
185 { "CPU_AVX_FLAGS",
186 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
187 { "CPU_AVX2_FLAGS",
188 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
189 { "CPU_ANY_AVX_FLAGS",
190 "CpuAVX|CpuAVX2" },
191 { "CPU_L1OM_FLAGS",
192 "unknown" },
193 { "CPU_K1OM_FLAGS",
194 "unknown" },
197 static initializer operand_type_init[] =
199 { "OPERAND_TYPE_NONE",
200 "0" },
201 { "OPERAND_TYPE_REG8",
202 "Reg8" },
203 { "OPERAND_TYPE_REG16",
204 "Reg16" },
205 { "OPERAND_TYPE_REG32",
206 "Reg32" },
207 { "OPERAND_TYPE_REG64",
208 "Reg64" },
209 { "OPERAND_TYPE_IMM1",
210 "Imm1" },
211 { "OPERAND_TYPE_IMM8",
212 "Imm8" },
213 { "OPERAND_TYPE_IMM8S",
214 "Imm8S" },
215 { "OPERAND_TYPE_IMM16",
216 "Imm16" },
217 { "OPERAND_TYPE_IMM32",
218 "Imm32" },
219 { "OPERAND_TYPE_IMM32S",
220 "Imm32S" },
221 { "OPERAND_TYPE_IMM64",
222 "Imm64" },
223 { "OPERAND_TYPE_BASEINDEX",
224 "BaseIndex" },
225 { "OPERAND_TYPE_DISP8",
226 "Disp8" },
227 { "OPERAND_TYPE_DISP16",
228 "Disp16" },
229 { "OPERAND_TYPE_DISP32",
230 "Disp32" },
231 { "OPERAND_TYPE_DISP32S",
232 "Disp32S" },
233 { "OPERAND_TYPE_DISP64",
234 "Disp64" },
235 { "OPERAND_TYPE_INOUTPORTREG",
236 "InOutPortReg" },
237 { "OPERAND_TYPE_SHIFTCOUNT",
238 "ShiftCount" },
239 { "OPERAND_TYPE_CONTROL",
240 "Control" },
241 { "OPERAND_TYPE_TEST",
242 "Test" },
243 { "OPERAND_TYPE_DEBUG",
244 "FloatReg" },
245 { "OPERAND_TYPE_FLOATREG",
246 "FloatReg" },
247 { "OPERAND_TYPE_FLOATACC",
248 "FloatAcc" },
249 { "OPERAND_TYPE_SREG2",
250 "SReg2" },
251 { "OPERAND_TYPE_SREG3",
252 "SReg3" },
253 { "OPERAND_TYPE_ACC",
254 "Acc" },
255 { "OPERAND_TYPE_JUMPABSOLUTE",
256 "JumpAbsolute" },
257 { "OPERAND_TYPE_REGMMX",
258 "RegMMX" },
259 { "OPERAND_TYPE_REGXMM",
260 "RegXMM" },
261 { "OPERAND_TYPE_REGYMM",
262 "RegYMM" },
263 { "OPERAND_TYPE_ESSEG",
264 "EsSeg" },
265 { "OPERAND_TYPE_ACC32",
266 "Reg32|Acc|Dword" },
267 { "OPERAND_TYPE_ACC64",
268 "Reg64|Acc|Qword" },
269 { "OPERAND_TYPE_INOUTPORTREG",
270 "InOutPortReg" },
271 { "OPERAND_TYPE_REG16_INOUTPORTREG",
272 "Reg16|InOutPortReg" },
273 { "OPERAND_TYPE_DISP16_32",
274 "Disp16|Disp32" },
275 { "OPERAND_TYPE_ANYDISP",
276 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
277 { "OPERAND_TYPE_IMM16_32",
278 "Imm16|Imm32" },
279 { "OPERAND_TYPE_IMM16_32S",
280 "Imm16|Imm32S" },
281 { "OPERAND_TYPE_IMM16_32_32S",
282 "Imm16|Imm32|Imm32S" },
283 { "OPERAND_TYPE_IMM32_32S_DISP32",
284 "Imm32|Imm32S|Disp32" },
285 { "OPERAND_TYPE_IMM64_DISP64",
286 "Imm64|Disp64" },
287 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
288 "Imm32|Imm32S|Imm64|Disp32" },
289 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
290 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
291 { "OPERAND_TYPE_VEC_IMM4",
292 "Vec_Imm4" },
295 typedef struct bitfield
297 int position;
298 int value;
299 const char *name;
300 } bitfield;
302 #define BITFIELD(n) { n, 0, #n }
304 static bitfield cpu_flags[] =
306 BITFIELD (Cpu186),
307 BITFIELD (Cpu286),
308 BITFIELD (Cpu386),
309 BITFIELD (Cpu486),
310 BITFIELD (Cpu586),
311 BITFIELD (Cpu686),
312 BITFIELD (CpuClflush),
313 BITFIELD (CpuNop),
314 BITFIELD (CpuSYSCALL),
315 BITFIELD (Cpu8087),
316 BITFIELD (Cpu287),
317 BITFIELD (Cpu387),
318 BITFIELD (Cpu687),
319 BITFIELD (CpuFISTTP),
320 BITFIELD (CpuMMX),
321 BITFIELD (CpuSSE),
322 BITFIELD (CpuSSE2),
323 BITFIELD (CpuSSE3),
324 BITFIELD (CpuSSSE3),
325 BITFIELD (CpuSSE4_1),
326 BITFIELD (CpuSSE4_2),
327 BITFIELD (CpuAVX),
328 BITFIELD (CpuAVX2),
329 BITFIELD (CpuL1OM),
330 BITFIELD (CpuK1OM),
331 BITFIELD (CpuSSE4a),
332 BITFIELD (Cpu3dnow),
333 BITFIELD (Cpu3dnowA),
334 BITFIELD (CpuPadLock),
335 BITFIELD (CpuSVME),
336 BITFIELD (CpuVMX),
337 BITFIELD (CpuSMX),
338 BITFIELD (CpuABM),
339 BITFIELD (CpuXsave),
340 BITFIELD (CpuXsaveopt),
341 BITFIELD (CpuAES),
342 BITFIELD (CpuPCLMUL),
343 BITFIELD (CpuFMA),
344 BITFIELD (CpuFMA4),
345 BITFIELD (CpuXOP),
346 BITFIELD (CpuLWP),
347 BITFIELD (CpuBMI),
348 BITFIELD (CpuTBM),
349 BITFIELD (CpuLM),
350 BITFIELD (CpuMovbe),
351 BITFIELD (CpuEPT),
352 BITFIELD (CpuRdtscp),
353 BITFIELD (CpuFSGSBase),
354 BITFIELD (CpuRdRnd),
355 BITFIELD (CpuF16C),
356 BITFIELD (CpuBMI2),
357 BITFIELD (CpuLZCNT),
358 BITFIELD (CpuHLE),
359 BITFIELD (CpuRTM),
360 BITFIELD (CpuINVPCID),
361 BITFIELD (CpuVMFUNC),
362 BITFIELD (Cpu64),
363 BITFIELD (CpuNo64),
364 #ifdef CpuUnused
365 BITFIELD (CpuUnused),
366 #endif
369 static bitfield opcode_modifiers[] =
371 BITFIELD (D),
372 BITFIELD (W),
373 BITFIELD (S),
374 BITFIELD (Modrm),
375 BITFIELD (ShortForm),
376 BITFIELD (Jump),
377 BITFIELD (JumpDword),
378 BITFIELD (JumpByte),
379 BITFIELD (JumpInterSegment),
380 BITFIELD (FloatMF),
381 BITFIELD (FloatR),
382 BITFIELD (FloatD),
383 BITFIELD (Size16),
384 BITFIELD (Size32),
385 BITFIELD (Size64),
386 BITFIELD (CheckRegSize),
387 BITFIELD (IgnoreSize),
388 BITFIELD (DefaultSize),
389 BITFIELD (No_bSuf),
390 BITFIELD (No_wSuf),
391 BITFIELD (No_lSuf),
392 BITFIELD (No_sSuf),
393 BITFIELD (No_qSuf),
394 BITFIELD (No_ldSuf),
395 BITFIELD (FWait),
396 BITFIELD (IsString),
397 BITFIELD (IsLockable),
398 BITFIELD (RegKludge),
399 BITFIELD (FirstXmm0),
400 BITFIELD (Implicit1stXmm0),
401 BITFIELD (HLEPrefixOk),
402 BITFIELD (ToDword),
403 BITFIELD (ToQword),
404 BITFIELD (AddrPrefixOp0),
405 BITFIELD (IsPrefix),
406 BITFIELD (ImmExt),
407 BITFIELD (NoRex64),
408 BITFIELD (Rex64),
409 BITFIELD (Ugh),
410 BITFIELD (Vex),
411 BITFIELD (VexVVVV),
412 BITFIELD (VexW),
413 BITFIELD (VexOpcode),
414 BITFIELD (VexSources),
415 BITFIELD (VexImmExt),
416 BITFIELD (VecSIB),
417 BITFIELD (SSE2AVX),
418 BITFIELD (NoAVX),
419 BITFIELD (OldGcc),
420 BITFIELD (ATTMnemonic),
421 BITFIELD (ATTSyntax),
422 BITFIELD (IntelSyntax),
425 static bitfield operand_types[] =
427 BITFIELD (Reg8),
428 BITFIELD (Reg16),
429 BITFIELD (Reg32),
430 BITFIELD (Reg64),
431 BITFIELD (FloatReg),
432 BITFIELD (RegMMX),
433 BITFIELD (RegXMM),
434 BITFIELD (RegYMM),
435 BITFIELD (Imm1),
436 BITFIELD (Imm8),
437 BITFIELD (Imm8S),
438 BITFIELD (Imm16),
439 BITFIELD (Imm32),
440 BITFIELD (Imm32S),
441 BITFIELD (Imm64),
442 BITFIELD (BaseIndex),
443 BITFIELD (Disp8),
444 BITFIELD (Disp16),
445 BITFIELD (Disp32),
446 BITFIELD (Disp32S),
447 BITFIELD (Disp64),
448 BITFIELD (InOutPortReg),
449 BITFIELD (ShiftCount),
450 BITFIELD (Control),
451 BITFIELD (Debug),
452 BITFIELD (Test),
453 BITFIELD (SReg2),
454 BITFIELD (SReg3),
455 BITFIELD (Acc),
456 BITFIELD (FloatAcc),
457 BITFIELD (JumpAbsolute),
458 BITFIELD (EsSeg),
459 BITFIELD (RegMem),
460 BITFIELD (Mem),
461 BITFIELD (Byte),
462 BITFIELD (Word),
463 BITFIELD (Dword),
464 BITFIELD (Fword),
465 BITFIELD (Qword),
466 BITFIELD (Tbyte),
467 BITFIELD (Xmmword),
468 BITFIELD (Ymmword),
469 BITFIELD (Unspecified),
470 BITFIELD (Anysize),
471 BITFIELD (Vec_Imm4),
472 #ifdef OTUnused
473 BITFIELD (OTUnused),
474 #endif
477 static const char *filename;
479 static int
480 compare (const void *x, const void *y)
482 const bitfield *xp = (const bitfield *) x;
483 const bitfield *yp = (const bitfield *) y;
484 return xp->position - yp->position;
487 static void
488 fail (const char *message, ...)
490 va_list args;
492 va_start (args, message);
493 fprintf (stderr, _("%s: Error: "), program_name);
494 vfprintf (stderr, message, args);
495 va_end (args);
496 xexit (1);
499 static void
500 process_copyright (FILE *fp)
502 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
503 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
504 Free Software Foundation, Inc.\n\
506 This file is part of the GNU opcodes library.\n\
508 This library is free software; you can redistribute it and/or modify\n\
509 it under the terms of the GNU General Public License as published by\n\
510 the Free Software Foundation; either version 3, or (at your option)\n\
511 any later version.\n\
513 It is distributed in the hope that it will be useful, but WITHOUT\n\
514 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
515 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
516 License for more details.\n\
518 You should have received a copy of the GNU General Public License\n\
519 along with this program; if not, write to the Free Software\n\
520 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
521 MA 02110-1301, USA. */\n");
524 /* Remove leading white spaces. */
526 static char *
527 remove_leading_whitespaces (char *str)
529 while (ISSPACE (*str))
530 str++;
531 return str;
534 /* Remove trailing white spaces. */
536 static void
537 remove_trailing_whitespaces (char *str)
539 size_t last = strlen (str);
541 if (last == 0)
542 return;
546 last--;
547 if (ISSPACE (str [last]))
548 str[last] = '\0';
549 else
550 break;
552 while (last != 0);
555 /* Find next field separated by SEP and terminate it. Return a
556 pointer to the one after it. */
558 static char *
559 next_field (char *str, char sep, char **next, char *last)
561 char *p;
563 p = remove_leading_whitespaces (str);
564 for (str = p; *str != sep && *str != '\0'; str++);
566 *str = '\0';
567 remove_trailing_whitespaces (p);
569 *next = str + 1;
571 if (p >= last)
572 abort ();
574 return p;
577 static void
578 set_bitfield (const char *f, bitfield *array, int value,
579 unsigned int size, int lineno)
581 unsigned int i;
583 if (strcmp (f, "CpuFP") == 0)
585 set_bitfield("Cpu387", array, value, size, lineno);
586 set_bitfield("Cpu287", array, value, size, lineno);
587 f = "Cpu8087";
589 else if (strcmp (f, "Mmword") == 0)
590 f= "Qword";
591 else if (strcmp (f, "Oword") == 0)
592 f= "Xmmword";
594 for (i = 0; i < size; i++)
595 if (strcasecmp (array[i].name, f) == 0)
597 array[i].value = value;
598 return;
601 if (value)
603 const char *v = strchr (f, '=');
605 if (v)
607 size_t n = v - f;
608 char *end;
610 for (i = 0; i < size; i++)
611 if (strncasecmp (array[i].name, f, n) == 0)
613 value = strtol (v + 1, &end, 0);
614 if (*end == '\0')
616 array[i].value = value;
617 return;
619 break;
624 if (lineno != -1)
625 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
626 else
627 fail (_("Unknown bitfield: %s\n"), f);
630 static void
631 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
632 int macro, const char *comma, const char *indent)
634 unsigned int i;
636 fprintf (table, "%s{ { ", indent);
638 for (i = 0; i < size - 1; i++)
640 fprintf (table, "%d, ", flags[i].value);
641 if (((i + 1) % 20) == 0)
643 /* We need \\ for macro. */
644 if (macro)
645 fprintf (table, " \\\n %s", indent);
646 else
647 fprintf (table, "\n %s", indent);
651 fprintf (table, "%d } }%s\n", flags[i].value, comma);
654 static void
655 process_i386_cpu_flag (FILE *table, char *flag, int macro,
656 const char *comma, const char *indent,
657 int lineno)
659 char *str, *next, *last;
660 unsigned int i;
661 bitfield flags [ARRAY_SIZE (cpu_flags)];
663 /* Copy the default cpu flags. */
664 memcpy (flags, cpu_flags, sizeof (cpu_flags));
666 if (strcasecmp (flag, "unknown") == 0)
668 /* We turn on everything except for cpu64 in case of
669 CPU_UNKNOWN_FLAGS. */
670 for (i = 0; i < ARRAY_SIZE (flags); i++)
671 if (flags[i].position != Cpu64)
672 flags[i].value = 1;
674 else if (flag[0] == '~')
676 last = flag + strlen (flag);
678 if (flag[1] == '(')
680 last -= 1;
681 next = flag + 2;
682 if (*last != ')')
683 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
684 lineno, flag);
685 *last = '\0';
687 else
688 next = flag + 1;
690 /* First we turn on everything except for cpu64. */
691 for (i = 0; i < ARRAY_SIZE (flags); i++)
692 if (flags[i].position != Cpu64)
693 flags[i].value = 1;
695 /* Turn off selective bits. */
696 for (; next && next < last; )
698 str = next_field (next, '|', &next, last);
699 if (str)
700 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
703 else if (strcmp (flag, "0"))
705 /* Turn on selective bits. */
706 last = flag + strlen (flag);
707 for (next = flag; next && next < last; )
709 str = next_field (next, '|', &next, last);
710 if (str)
711 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
715 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
716 comma, indent);
719 static void
720 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
722 unsigned int i;
724 fprintf (table, " { ");
726 for (i = 0; i < size - 1; i++)
728 fprintf (table, "%d, ", modifier[i].value);
729 if (((i + 1) % 20) == 0)
730 fprintf (table, "\n ");
733 fprintf (table, "%d },\n", modifier[i].value);
736 static void
737 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
739 char *str, *next, *last;
740 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
742 /* Copy the default opcode modifier. */
743 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
745 if (strcmp (mod, "0"))
747 last = mod + strlen (mod);
748 for (next = mod; next && next < last; )
750 str = next_field (next, '|', &next, last);
751 if (str)
752 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
753 lineno);
756 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
759 static void
760 output_operand_type (FILE *table, bitfield *types, unsigned int size,
761 int macro, const char *indent)
763 unsigned int i;
765 fprintf (table, "{ { ");
767 for (i = 0; i < size - 1; i++)
769 fprintf (table, "%d, ", types[i].value);
770 if (((i + 1) % 20) == 0)
772 /* We need \\ for macro. */
773 if (macro)
774 fprintf (table, "\\\n%s", indent);
775 else
776 fprintf (table, "\n%s", indent);
780 fprintf (table, "%d } }", types[i].value);
783 static void
784 process_i386_operand_type (FILE *table, char *op, int macro,
785 const char *indent, int lineno)
787 char *str, *next, *last;
788 bitfield types [ARRAY_SIZE (operand_types)];
790 /* Copy the default operand type. */
791 memcpy (types, operand_types, sizeof (types));
793 if (strcmp (op, "0"))
795 last = op + strlen (op);
796 for (next = op; next && next < last; )
798 str = next_field (next, '|', &next, last);
799 if (str)
800 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
803 output_operand_type (table, types, ARRAY_SIZE (types), macro,
804 indent);
807 static void
808 output_i386_opcode (FILE *table, const char *name, char *str,
809 char *last, int lineno)
811 unsigned int i;
812 char *operands, *base_opcode, *extension_opcode, *opcode_length;
813 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
815 /* Find number of operands. */
816 operands = next_field (str, ',', &str, last);
818 /* Find base_opcode. */
819 base_opcode = next_field (str, ',', &str, last);
821 /* Find extension_opcode. */
822 extension_opcode = next_field (str, ',', &str, last);
824 /* Find opcode_length. */
825 opcode_length = next_field (str, ',', &str, last);
827 /* Find cpu_flags. */
828 cpu_flags = next_field (str, ',', &str, last);
830 /* Find opcode_modifier. */
831 opcode_modifier = next_field (str, ',', &str, last);
833 /* Remove the first {. */
834 str = remove_leading_whitespaces (str);
835 if (*str != '{')
836 abort ();
837 str = remove_leading_whitespaces (str + 1);
839 i = strlen (str);
841 /* There are at least "X}". */
842 if (i < 2)
843 abort ();
845 /* Remove trailing white spaces and }. */
848 i--;
849 if (ISSPACE (str[i]) || str[i] == '}')
850 str[i] = '\0';
851 else
852 break;
854 while (i != 0);
856 last = str + i;
858 /* Find operand_types. */
859 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
861 if (str >= last)
863 operand_types [i] = NULL;
864 break;
867 operand_types [i] = next_field (str, ',', &str, last);
868 if (*operand_types[i] == '0')
870 if (i != 0)
871 operand_types[i] = NULL;
872 break;
876 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
877 name, operands, base_opcode, extension_opcode,
878 opcode_length);
880 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
882 process_i386_opcode_modifier (table, opcode_modifier, lineno);
884 fprintf (table, " { ");
886 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
888 if (operand_types[i] == NULL || *operand_types[i] == '0')
890 if (i == 0)
891 process_i386_operand_type (table, "0", 0, "\t ", lineno);
892 break;
895 if (i != 0)
896 fprintf (table, ",\n ");
898 process_i386_operand_type (table, operand_types[i], 0,
899 "\t ", lineno);
901 fprintf (table, " } },\n");
904 struct opcode_hash_entry
906 struct opcode_hash_entry *next;
907 char *name;
908 char *opcode;
909 int lineno;
912 /* Calculate the hash value of an opcode hash entry P. */
914 static hashval_t
915 opcode_hash_hash (const void *p)
917 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
918 return htab_hash_string (entry->name);
921 /* Compare a string Q against an opcode hash entry P. */
923 static int
924 opcode_hash_eq (const void *p, const void *q)
926 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
927 const char *name = (const char *) q;
928 return strcmp (name, entry->name) == 0;
931 static void
932 process_i386_opcodes (FILE *table)
934 FILE *fp;
935 char buf[2048];
936 unsigned int i, j;
937 char *str, *p, *last, *name;
938 struct opcode_hash_entry **hash_slot, **entry, *next;
939 htab_t opcode_hash_table;
940 struct opcode_hash_entry **opcode_array;
941 unsigned int opcode_array_size = 1024;
942 int lineno = 0;
944 filename = "i386-opc.tbl";
945 fp = fopen (filename, "r");
947 if (fp == NULL)
948 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
949 xstrerror (errno));
951 i = 0;
952 opcode_array = (struct opcode_hash_entry **)
953 xmalloc (sizeof (*opcode_array) * opcode_array_size);
955 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
956 opcode_hash_eq, NULL,
957 xcalloc, free);
959 fprintf (table, "\n/* i386 opcode table. */\n\n");
960 fprintf (table, "const insn_template i386_optab[] =\n{\n");
962 /* Put everything on opcode array. */
963 while (!feof (fp))
965 if (fgets (buf, sizeof (buf), fp) == NULL)
966 break;
968 lineno++;
970 p = remove_leading_whitespaces (buf);
972 /* Skip comments. */
973 str = strstr (p, "//");
974 if (str != NULL)
975 str[0] = '\0';
977 /* Remove trailing white spaces. */
978 remove_trailing_whitespaces (p);
980 switch (p[0])
982 case '#':
983 /* Ignore comments. */
984 case '\0':
985 continue;
986 break;
987 default:
988 break;
991 last = p + strlen (p);
993 /* Find name. */
994 name = next_field (p, ',', &str, last);
996 /* Get the slot in hash table. */
997 hash_slot = (struct opcode_hash_entry **)
998 htab_find_slot_with_hash (opcode_hash_table, name,
999 htab_hash_string (name),
1000 INSERT);
1002 if (*hash_slot == NULL)
1004 /* It is the new one. Put it on opcode array. */
1005 if (i >= opcode_array_size)
1007 /* Grow the opcode array when needed. */
1008 opcode_array_size += 1024;
1009 opcode_array = (struct opcode_hash_entry **)
1010 xrealloc (opcode_array,
1011 sizeof (*opcode_array) * opcode_array_size);
1014 opcode_array[i] = (struct opcode_hash_entry *)
1015 xmalloc (sizeof (struct opcode_hash_entry));
1016 opcode_array[i]->next = NULL;
1017 opcode_array[i]->name = xstrdup (name);
1018 opcode_array[i]->opcode = xstrdup (str);
1019 opcode_array[i]->lineno = lineno;
1020 *hash_slot = opcode_array[i];
1021 i++;
1023 else
1025 /* Append it to the existing one. */
1026 entry = hash_slot;
1027 while ((*entry) != NULL)
1028 entry = &(*entry)->next;
1029 *entry = (struct opcode_hash_entry *)
1030 xmalloc (sizeof (struct opcode_hash_entry));
1031 (*entry)->next = NULL;
1032 (*entry)->name = (*hash_slot)->name;
1033 (*entry)->opcode = xstrdup (str);
1034 (*entry)->lineno = lineno;
1038 /* Process opcode array. */
1039 for (j = 0; j < i; j++)
1041 for (next = opcode_array[j]; next; next = next->next)
1043 name = next->name;
1044 str = next->opcode;
1045 lineno = next->lineno;
1046 last = str + strlen (str);
1047 output_i386_opcode (table, name, str, last, lineno);
1051 fclose (fp);
1053 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1055 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1057 process_i386_opcode_modifier (table, "0", -1);
1059 fprintf (table, " { ");
1060 process_i386_operand_type (table, "0", 0, "\t ", -1);
1061 fprintf (table, " } }\n");
1063 fprintf (table, "};\n");
1066 static void
1067 process_i386_registers (FILE *table)
1069 FILE *fp;
1070 char buf[2048];
1071 char *str, *p, *last;
1072 char *reg_name, *reg_type, *reg_flags, *reg_num;
1073 char *dw2_32_num, *dw2_64_num;
1074 int lineno = 0;
1076 filename = "i386-reg.tbl";
1077 fp = fopen (filename, "r");
1078 if (fp == NULL)
1079 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1080 xstrerror (errno));
1082 fprintf (table, "\n/* i386 register table. */\n\n");
1083 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1085 while (!feof (fp))
1087 if (fgets (buf, sizeof (buf), fp) == NULL)
1088 break;
1090 lineno++;
1092 p = remove_leading_whitespaces (buf);
1094 /* Skip comments. */
1095 str = strstr (p, "//");
1096 if (str != NULL)
1097 str[0] = '\0';
1099 /* Remove trailing white spaces. */
1100 remove_trailing_whitespaces (p);
1102 switch (p[0])
1104 case '#':
1105 fprintf (table, "%s\n", p);
1106 case '\0':
1107 continue;
1108 break;
1109 default:
1110 break;
1113 last = p + strlen (p);
1115 /* Find reg_name. */
1116 reg_name = next_field (p, ',', &str, last);
1118 /* Find reg_type. */
1119 reg_type = next_field (str, ',', &str, last);
1121 /* Find reg_flags. */
1122 reg_flags = next_field (str, ',', &str, last);
1124 /* Find reg_num. */
1125 reg_num = next_field (str, ',', &str, last);
1127 fprintf (table, " { \"%s\",\n ", reg_name);
1129 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1131 /* Find 32-bit Dwarf2 register number. */
1132 dw2_32_num = next_field (str, ',', &str, last);
1134 /* Find 64-bit Dwarf2 register number. */
1135 dw2_64_num = next_field (str, ',', &str, last);
1137 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1138 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1141 fclose (fp);
1143 fprintf (table, "};\n");
1145 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1148 static void
1149 process_i386_initializers (void)
1151 unsigned int i;
1152 FILE *fp = fopen ("i386-init.h", "w");
1153 char *init;
1155 if (fp == NULL)
1156 fail (_("can't create i386-init.h, errno = %s\n"),
1157 xstrerror (errno));
1159 process_copyright (fp);
1161 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1163 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1164 init = xstrdup (cpu_flag_init[i].init);
1165 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1166 free (init);
1169 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1171 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1172 init = xstrdup (operand_type_init[i].init);
1173 process_i386_operand_type (fp, init, 1, " ", -1);
1174 free (init);
1176 fprintf (fp, "\n");
1178 fclose (fp);
1181 /* Program options. */
1182 #define OPTION_SRCDIR 200
1184 struct option long_options[] =
1186 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1187 {"debug", no_argument, NULL, 'd'},
1188 {"version", no_argument, NULL, 'V'},
1189 {"help", no_argument, NULL, 'h'},
1190 {0, no_argument, NULL, 0}
1193 static void
1194 print_version (void)
1196 printf ("%s: version 1.0\n", program_name);
1197 xexit (0);
1200 static void
1201 usage (FILE * stream, int status)
1203 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1204 program_name);
1205 xexit (status);
1209 main (int argc, char **argv)
1211 extern int chdir (char *);
1212 char *srcdir = NULL;
1213 int c;
1214 FILE *table;
1216 program_name = *argv;
1217 xmalloc_set_program_name (program_name);
1219 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1220 switch (c)
1222 case OPTION_SRCDIR:
1223 srcdir = optarg;
1224 break;
1225 case 'V':
1226 case 'v':
1227 print_version ();
1228 break;
1229 case 'd':
1230 debug = 1;
1231 break;
1232 case 'h':
1233 case '?':
1234 usage (stderr, 0);
1235 default:
1236 case 0:
1237 break;
1240 if (optind != argc)
1241 usage (stdout, 1);
1243 if (srcdir != NULL)
1244 if (chdir (srcdir) != 0)
1245 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1246 srcdir, xstrerror (errno));
1248 /* Check the unused bitfield in i386_cpu_flags. */
1249 #ifndef CpuUnused
1250 c = CpuNumOfBits - CpuMax - 1;
1251 if (c)
1252 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1253 #endif
1255 /* Check the unused bitfield in i386_operand_type. */
1256 #ifndef OTUnused
1257 c = OTNumOfBits - OTMax - 1;
1258 if (c)
1259 fail (_("%d unused bits in i386_operand_type.\n"), c);
1260 #endif
1262 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1263 compare);
1265 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1266 sizeof (opcode_modifiers [0]), compare);
1268 qsort (operand_types, ARRAY_SIZE (operand_types),
1269 sizeof (operand_types [0]), compare);
1271 table = fopen ("i386-tbl.h", "w");
1272 if (table == NULL)
1273 fail (_("can't create i386-tbl.h, errno = %s\n"),
1274 xstrerror (errno));
1276 process_copyright (table);
1278 process_i386_opcodes (table);
1279 process_i386_registers (table);
1280 process_i386_initializers ();
1282 fclose (table);
1284 exit (0);