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