Implement Intel Transactional Synchronization Extensions
[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_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" },
195 };
196
197 static initializer operand_type_init[] =
198 {
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" },
293 };
294
295 typedef struct bitfield
296 {
297 int position;
298 int value;
299 const char *name;
300 } bitfield;
301
302 #define BITFIELD(n) { n, 0, #n }
303
304 static bitfield cpu_flags[] =
305 {
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
367 };
368
369 static bitfield opcode_modifiers[] =
370 {
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),
423 };
424
425 static bitfield operand_types[] =
426 {
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
475 };
476
477 static const char *filename;
478
479 static int
480 compare (const void *x, const void *y)
481 {
482 const bitfield *xp = (const bitfield *) x;
483 const bitfield *yp = (const bitfield *) y;
484 return xp->position - yp->position;
485 }
486
487 static void
488 fail (const char *message, ...)
489 {
490 va_list args;
491
492 va_start (args, message);
493 fprintf (stderr, _("%s: Error: "), program_name);
494 vfprintf (stderr, message, args);
495 va_end (args);
496 xexit (1);
497 }
498
499 static void
500 process_copyright (FILE *fp)
501 {
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\
505 \n\
506 This file is part of the GNU opcodes library.\n\
507 \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\
512 \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\
517 \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");
522 }
523
524 /* Remove leading white spaces. */
525
526 static char *
527 remove_leading_whitespaces (char *str)
528 {
529 while (ISSPACE (*str))
530 str++;
531 return str;
532 }
533
534 /* Remove trailing white spaces. */
535
536 static void
537 remove_trailing_whitespaces (char *str)
538 {
539 size_t last = strlen (str);
540
541 if (last == 0)
542 return;
543
544 do
545 {
546 last--;
547 if (ISSPACE (str [last]))
548 str[last] = '\0';
549 else
550 break;
551 }
552 while (last != 0);
553 }
554
555 /* Find next field separated by SEP and terminate it. Return a
556 pointer to the one after it. */
557
558 static char *
559 next_field (char *str, char sep, char **next, char *last)
560 {
561 char *p;
562
563 p = remove_leading_whitespaces (str);
564 for (str = p; *str != sep && *str != '\0'; str++);
565
566 *str = '\0';
567 remove_trailing_whitespaces (p);
568
569 *next = str + 1;
570
571 if (p >= last)
572 abort ();
573
574 return p;
575 }
576
577 static void
578 set_bitfield (const char *f, bitfield *array, int value,
579 unsigned int size, int lineno)
580 {
581 unsigned int i;
582
583 if (strcmp (f, "CpuFP") == 0)
584 {
585 set_bitfield("Cpu387", array, value, size, lineno);
586 set_bitfield("Cpu287", array, value, size, lineno);
587 f = "Cpu8087";
588 }
589 else if (strcmp (f, "Mmword") == 0)
590 f= "Qword";
591 else if (strcmp (f, "Oword") == 0)
592 f= "Xmmword";
593
594 for (i = 0; i < size; i++)
595 if (strcasecmp (array[i].name, f) == 0)
596 {
597 array[i].value = value;
598 return;
599 }
600
601 if (value)
602 {
603 const char *v = strchr (f, '=');
604
605 if (v)
606 {
607 size_t n = v - f;
608 char *end;
609
610 for (i = 0; i < size; i++)
611 if (strncasecmp (array[i].name, f, n) == 0)
612 {
613 value = strtol (v + 1, &end, 0);
614 if (*end == '\0')
615 {
616 array[i].value = value;
617 return;
618 }
619 break;
620 }
621 }
622 }
623
624 if (lineno != -1)
625 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
626 else
627 fail (_("Unknown bitfield: %s\n"), f);
628 }
629
630 static void
631 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
632 int macro, const char *comma, const char *indent)
633 {
634 unsigned int i;
635
636 fprintf (table, "%s{ { ", indent);
637
638 for (i = 0; i < size - 1; i++)
639 {
640 fprintf (table, "%d, ", flags[i].value);
641 if (((i + 1) % 20) == 0)
642 {
643 /* We need \\ for macro. */
644 if (macro)
645 fprintf (table, " \\\n %s", indent);
646 else
647 fprintf (table, "\n %s", indent);
648 }
649 }
650
651 fprintf (table, "%d } }%s\n", flags[i].value, comma);
652 }
653
654 static void
655 process_i386_cpu_flag (FILE *table, char *flag, int macro,
656 const char *comma, const char *indent,
657 int lineno)
658 {
659 char *str, *next, *last;
660 unsigned int i;
661 bitfield flags [ARRAY_SIZE (cpu_flags)];
662
663 /* Copy the default cpu flags. */
664 memcpy (flags, cpu_flags, sizeof (cpu_flags));
665
666 if (strcasecmp (flag, "unknown") == 0)
667 {
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;
673 }
674 else if (flag[0] == '~')
675 {
676 last = flag + strlen (flag);
677
678 if (flag[1] == '(')
679 {
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';
686 }
687 else
688 next = flag + 1;
689
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;
694
695 /* Turn off selective bits. */
696 for (; next && next < last; )
697 {
698 str = next_field (next, '|', &next, last);
699 if (str)
700 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
701 }
702 }
703 else if (strcmp (flag, "0"))
704 {
705 /* Turn on selective bits. */
706 last = flag + strlen (flag);
707 for (next = flag; next && next < last; )
708 {
709 str = next_field (next, '|', &next, last);
710 if (str)
711 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
712 }
713 }
714
715 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
716 comma, indent);
717 }
718
719 static void
720 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
721 {
722 unsigned int i;
723
724 fprintf (table, " { ");
725
726 for (i = 0; i < size - 1; i++)
727 {
728 fprintf (table, "%d, ", modifier[i].value);
729 if (((i + 1) % 20) == 0)
730 fprintf (table, "\n ");
731 }
732
733 fprintf (table, "%d },\n", modifier[i].value);
734 }
735
736 static void
737 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
738 {
739 char *str, *next, *last;
740 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
741
742 /* Copy the default opcode modifier. */
743 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
744
745 if (strcmp (mod, "0"))
746 {
747 last = mod + strlen (mod);
748 for (next = mod; next && next < last; )
749 {
750 str = next_field (next, '|', &next, last);
751 if (str)
752 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
753 lineno);
754 }
755 }
756 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
757 }
758
759 static void
760 output_operand_type (FILE *table, bitfield *types, unsigned int size,
761 int macro, const char *indent)
762 {
763 unsigned int i;
764
765 fprintf (table, "{ { ");
766
767 for (i = 0; i < size - 1; i++)
768 {
769 fprintf (table, "%d, ", types[i].value);
770 if (((i + 1) % 20) == 0)
771 {
772 /* We need \\ for macro. */
773 if (macro)
774 fprintf (table, "\\\n%s", indent);
775 else
776 fprintf (table, "\n%s", indent);
777 }
778 }
779
780 fprintf (table, "%d } }", types[i].value);
781 }
782
783 static void
784 process_i386_operand_type (FILE *table, char *op, int macro,
785 const char *indent, int lineno)
786 {
787 char *str, *next, *last;
788 bitfield types [ARRAY_SIZE (operand_types)];
789
790 /* Copy the default operand type. */
791 memcpy (types, operand_types, sizeof (types));
792
793 if (strcmp (op, "0"))
794 {
795 last = op + strlen (op);
796 for (next = op; next && next < last; )
797 {
798 str = next_field (next, '|', &next, last);
799 if (str)
800 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
801 }
802 }
803 output_operand_type (table, types, ARRAY_SIZE (types), macro,
804 indent);
805 }
806
807 static void
808 output_i386_opcode (FILE *table, const char *name, char *str,
809 char *last, int lineno)
810 {
811 unsigned int i;
812 char *operands, *base_opcode, *extension_opcode, *opcode_length;
813 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
814
815 /* Find number of operands. */
816 operands = next_field (str, ',', &str, last);
817
818 /* Find base_opcode. */
819 base_opcode = next_field (str, ',', &str, last);
820
821 /* Find extension_opcode. */
822 extension_opcode = next_field (str, ',', &str, last);
823
824 /* Find opcode_length. */
825 opcode_length = next_field (str, ',', &str, last);
826
827 /* Find cpu_flags. */
828 cpu_flags = next_field (str, ',', &str, last);
829
830 /* Find opcode_modifier. */
831 opcode_modifier = next_field (str, ',', &str, last);
832
833 /* Remove the first {. */
834 str = remove_leading_whitespaces (str);
835 if (*str != '{')
836 abort ();
837 str = remove_leading_whitespaces (str + 1);
838
839 i = strlen (str);
840
841 /* There are at least "X}". */
842 if (i < 2)
843 abort ();
844
845 /* Remove trailing white spaces and }. */
846 do
847 {
848 i--;
849 if (ISSPACE (str[i]) || str[i] == '}')
850 str[i] = '\0';
851 else
852 break;
853 }
854 while (i != 0);
855
856 last = str + i;
857
858 /* Find operand_types. */
859 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
860 {
861 if (str >= last)
862 {
863 operand_types [i] = NULL;
864 break;
865 }
866
867 operand_types [i] = next_field (str, ',', &str, last);
868 if (*operand_types[i] == '0')
869 {
870 if (i != 0)
871 operand_types[i] = NULL;
872 break;
873 }
874 }
875
876 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
877 name, operands, base_opcode, extension_opcode,
878 opcode_length);
879
880 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
881
882 process_i386_opcode_modifier (table, opcode_modifier, lineno);
883
884 fprintf (table, " { ");
885
886 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
887 {
888 if (operand_types[i] == NULL || *operand_types[i] == '0')
889 {
890 if (i == 0)
891 process_i386_operand_type (table, "0", 0, "\t ", lineno);
892 break;
893 }
894
895 if (i != 0)
896 fprintf (table, ",\n ");
897
898 process_i386_operand_type (table, operand_types[i], 0,
899 "\t ", lineno);
900 }
901 fprintf (table, " } },\n");
902 }
903
904 struct opcode_hash_entry
905 {
906 struct opcode_hash_entry *next;
907 char *name;
908 char *opcode;
909 int lineno;
910 };
911
912 /* Calculate the hash value of an opcode hash entry P. */
913
914 static hashval_t
915 opcode_hash_hash (const void *p)
916 {
917 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
918 return htab_hash_string (entry->name);
919 }
920
921 /* Compare a string Q against an opcode hash entry P. */
922
923 static int
924 opcode_hash_eq (const void *p, const void *q)
925 {
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;
929 }
930
931 static void
932 process_i386_opcodes (FILE *table)
933 {
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;
943
944 filename = "i386-opc.tbl";
945 fp = fopen (filename, "r");
946
947 if (fp == NULL)
948 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
949 xstrerror (errno));
950
951 i = 0;
952 opcode_array = (struct opcode_hash_entry **)
953 xmalloc (sizeof (*opcode_array) * opcode_array_size);
954
955 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
956 opcode_hash_eq, NULL,
957 xcalloc, free);
958
959 fprintf (table, "\n/* i386 opcode table. */\n\n");
960 fprintf (table, "const insn_template i386_optab[] =\n{\n");
961
962 /* Put everything on opcode array. */
963 while (!feof (fp))
964 {
965 if (fgets (buf, sizeof (buf), fp) == NULL)
966 break;
967
968 lineno++;
969
970 p = remove_leading_whitespaces (buf);
971
972 /* Skip comments. */
973 str = strstr (p, "//");
974 if (str != NULL)
975 str[0] = '\0';
976
977 /* Remove trailing white spaces. */
978 remove_trailing_whitespaces (p);
979
980 switch (p[0])
981 {
982 case '#':
983 /* Ignore comments. */
984 case '\0':
985 continue;
986 break;
987 default:
988 break;
989 }
990
991 last = p + strlen (p);
992
993 /* Find name. */
994 name = next_field (p, ',', &str, last);
995
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);
1001
1002 if (*hash_slot == NULL)
1003 {
1004 /* It is the new one. Put it on opcode array. */
1005 if (i >= opcode_array_size)
1006 {
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);
1012 }
1013
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++;
1022 }
1023 else
1024 {
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;
1035 }
1036 }
1037
1038 /* Process opcode array. */
1039 for (j = 0; j < i; j++)
1040 {
1041 for (next = opcode_array[j]; next; next = next->next)
1042 {
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);
1048 }
1049 }
1050
1051 fclose (fp);
1052
1053 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1054
1055 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1056
1057 process_i386_opcode_modifier (table, "0", -1);
1058
1059 fprintf (table, " { ");
1060 process_i386_operand_type (table, "0", 0, "\t ", -1);
1061 fprintf (table, " } }\n");
1062
1063 fprintf (table, "};\n");
1064 }
1065
1066 static void
1067 process_i386_registers (FILE *table)
1068 {
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;
1075
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));
1081
1082 fprintf (table, "\n/* i386 register table. */\n\n");
1083 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1084
1085 while (!feof (fp))
1086 {
1087 if (fgets (buf, sizeof (buf), fp) == NULL)
1088 break;
1089
1090 lineno++;
1091
1092 p = remove_leading_whitespaces (buf);
1093
1094 /* Skip comments. */
1095 str = strstr (p, "//");
1096 if (str != NULL)
1097 str[0] = '\0';
1098
1099 /* Remove trailing white spaces. */
1100 remove_trailing_whitespaces (p);
1101
1102 switch (p[0])
1103 {
1104 case '#':
1105 fprintf (table, "%s\n", p);
1106 case '\0':
1107 continue;
1108 break;
1109 default:
1110 break;
1111 }
1112
1113 last = p + strlen (p);
1114
1115 /* Find reg_name. */
1116 reg_name = next_field (p, ',', &str, last);
1117
1118 /* Find reg_type. */
1119 reg_type = next_field (str, ',', &str, last);
1120
1121 /* Find reg_flags. */
1122 reg_flags = next_field (str, ',', &str, last);
1123
1124 /* Find reg_num. */
1125 reg_num = next_field (str, ',', &str, last);
1126
1127 fprintf (table, " { \"%s\",\n ", reg_name);
1128
1129 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1130
1131 /* Find 32-bit Dwarf2 register number. */
1132 dw2_32_num = next_field (str, ',', &str, last);
1133
1134 /* Find 64-bit Dwarf2 register number. */
1135 dw2_64_num = next_field (str, ',', &str, last);
1136
1137 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1138 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1139 }
1140
1141 fclose (fp);
1142
1143 fprintf (table, "};\n");
1144
1145 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1146 }
1147
1148 static void
1149 process_i386_initializers (void)
1150 {
1151 unsigned int i;
1152 FILE *fp = fopen ("i386-init.h", "w");
1153 char *init;
1154
1155 if (fp == NULL)
1156 fail (_("can't create i386-init.h, errno = %s\n"),
1157 xstrerror (errno));
1158
1159 process_copyright (fp);
1160
1161 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1162 {
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);
1167 }
1168
1169 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1170 {
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);
1175 }
1176 fprintf (fp, "\n");
1177
1178 fclose (fp);
1179 }
1180
1181 /* Program options. */
1182 #define OPTION_SRCDIR 200
1183
1184 struct option long_options[] =
1185 {
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}
1191 };
1192
1193 static void
1194 print_version (void)
1195 {
1196 printf ("%s: version 1.0\n", program_name);
1197 xexit (0);
1198 }
1199
1200 static void
1201 usage (FILE * stream, int status)
1202 {
1203 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1204 program_name);
1205 xexit (status);
1206 }
1207
1208 int
1209 main (int argc, char **argv)
1210 {
1211 extern int chdir (char *);
1212 char *srcdir = NULL;
1213 int c;
1214 FILE *table;
1215
1216 program_name = *argv;
1217 xmalloc_set_program_name (program_name);
1218
1219 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1220 switch (c)
1221 {
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;
1238 }
1239
1240 if (optind != argc)
1241 usage (stdout, 1);
1242
1243 if (srcdir != NULL)
1244 if (chdir (srcdir) != 0)
1245 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1246 srcdir, xstrerror (errno));
1247
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
1254
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
1261
1262 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1263 compare);
1264
1265 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1266 sizeof (opcode_modifiers [0]), compare);
1267
1268 qsort (operand_types, ARRAY_SIZE (operand_types),
1269 sizeof (operand_types [0]), compare);
1270
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));
1275
1276 process_copyright (table);
1277
1278 process_i386_opcodes (table);
1279 process_i386_registers (table);
1280 process_i386_initializers ();
1281
1282 fclose (table);
1283
1284 exit (0);
1285 }
This page took 0.054897 seconds and 5 git commands to generate.