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