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