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