bfd/
[binutils.git] / opcodes / i386-gen.c
blob9c94e78fdf9271cf409b8fcea64433c79db34ba1
1 /* Copyright 2007, 2008, 2009
2 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
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.
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.
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. */
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"
29 #include "i386-opc.h"
31 #include <libintl.h>
32 #define _(String) gettext (String)
34 static const char *program_name = NULL;
35 static int debug = 0;
37 typedef struct initializer
39 const char *name;
40 const char *init;
41 } initializer;
43 static initializer cpu_flag_init[] =
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|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_P2_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX" },
67 { "CPU_P3_FLAGS",
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX|CpuSSE" },
69 { "CPU_P4_FLAGS",
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuMMX|CpuSSE|CpuSSE2" },
71 { "CPU_NOCONA_FLAGS",
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
73 { "CPU_CORE_FLAGS",
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
75 { "CPU_CORE2_FLAGS",
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
77 { "CPU_COREI7_FLAGS",
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
79 { "CPU_K6_FLAGS",
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
81 { "CPU_K6_2_FLAGS",
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
83 { "CPU_ATHLON_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA" },
85 { "CPU_K8_FLAGS",
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
87 { "CPU_AMDFAM10_FLAGS",
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
89 { "CPU_8087_FLAGS",
90 "Cpu8087" },
91 { "CPU_287_FLAGS",
92 "Cpu287" },
93 { "CPU_387_FLAGS",
94 "Cpu387" },
95 { "CPU_ANY87_FLAGS",
96 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
97 { "CPU_CLFLUSH_FLAGS",
98 "CpuClflush" },
99 { "CPU_SYSCALL_FLAGS",
100 "CpuSYSCALL" },
101 { "CPU_MMX_FLAGS",
102 "CpuMMX" },
103 { "CPU_SSE_FLAGS",
104 "CpuMMX|CpuSSE" },
105 { "CPU_SSE2_FLAGS",
106 "CpuMMX|CpuSSE|CpuSSE2" },
107 { "CPU_SSE3_FLAGS",
108 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
109 { "CPU_SSSE3_FLAGS",
110 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
111 { "CPU_SSE4_1_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
113 { "CPU_SSE4_2_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
115 { "CPU_ANY_SSE_FLAGS",
116 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
117 { "CPU_VMX_FLAGS",
118 "CpuVMX" },
119 { "CPU_SMX_FLAGS",
120 "CpuSMX" },
121 { "CPU_XSAVE_FLAGS",
122 "CpuXsave" },
123 { "CPU_AES_FLAGS",
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
125 { "CPU_PCLMUL_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
127 { "CPU_FMA_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
129 { "CPU_FMA4_FLAGS",
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
131 { "CPU_MOVBE_FLAGS",
132 "CpuMovbe" },
133 { "CPU_RDTSCP_FLAGS",
134 "CpuRdtscp" },
135 { "CPU_EPT_FLAGS",
136 "CpuEPT" },
137 { "CPU_3DNOW_FLAGS",
138 "CpuMMX|Cpu3dnow" },
139 { "CPU_3DNOWA_FLAGS",
140 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
141 { "CPU_PADLOCK_FLAGS",
142 "CpuPadLock" },
143 { "CPU_SVME_FLAGS",
144 "CpuSVME" },
145 { "CPU_SSE4A_FLAGS",
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
147 { "CPU_ABM_FLAGS",
148 "CpuABM" },
149 { "CPU_AVX_FLAGS",
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
151 { "CPU_ANY_AVX_FLAGS",
152 "CpuAVX" },
153 { "CPU_L1OM_FLAGS",
154 "unknown" },
157 static initializer operand_type_init[] =
159 { "OPERAND_TYPE_NONE",
160 "0" },
161 { "OPERAND_TYPE_REG8",
162 "Reg8" },
163 { "OPERAND_TYPE_REG16",
164 "Reg16" },
165 { "OPERAND_TYPE_REG32",
166 "Reg32" },
167 { "OPERAND_TYPE_REG64",
168 "Reg64" },
169 { "OPERAND_TYPE_IMM1",
170 "Imm1" },
171 { "OPERAND_TYPE_IMM8",
172 "Imm8" },
173 { "OPERAND_TYPE_IMM8S",
174 "Imm8S" },
175 { "OPERAND_TYPE_IMM16",
176 "Imm16" },
177 { "OPERAND_TYPE_IMM32",
178 "Imm32" },
179 { "OPERAND_TYPE_IMM32S",
180 "Imm32S" },
181 { "OPERAND_TYPE_IMM64",
182 "Imm64" },
183 { "OPERAND_TYPE_BASEINDEX",
184 "BaseIndex" },
185 { "OPERAND_TYPE_DISP8",
186 "Disp8" },
187 { "OPERAND_TYPE_DISP16",
188 "Disp16" },
189 { "OPERAND_TYPE_DISP32",
190 "Disp32" },
191 { "OPERAND_TYPE_DISP32S",
192 "Disp32S" },
193 { "OPERAND_TYPE_DISP64",
194 "Disp64" },
195 { "OPERAND_TYPE_INOUTPORTREG",
196 "InOutPortReg" },
197 { "OPERAND_TYPE_SHIFTCOUNT",
198 "ShiftCount" },
199 { "OPERAND_TYPE_CONTROL",
200 "Control" },
201 { "OPERAND_TYPE_TEST",
202 "Test" },
203 { "OPERAND_TYPE_DEBUG",
204 "FloatReg" },
205 { "OPERAND_TYPE_FLOATREG",
206 "FloatReg" },
207 { "OPERAND_TYPE_FLOATACC",
208 "FloatAcc" },
209 { "OPERAND_TYPE_SREG2",
210 "SReg2" },
211 { "OPERAND_TYPE_SREG3",
212 "SReg3" },
213 { "OPERAND_TYPE_ACC",
214 "Acc" },
215 { "OPERAND_TYPE_JUMPABSOLUTE",
216 "JumpAbsolute" },
217 { "OPERAND_TYPE_REGMMX",
218 "RegMMX" },
219 { "OPERAND_TYPE_REGXMM",
220 "RegXMM" },
221 { "OPERAND_TYPE_REGYMM",
222 "RegYMM" },
223 { "OPERAND_TYPE_ESSEG",
224 "EsSeg" },
225 { "OPERAND_TYPE_ACC32",
226 "Reg32|Acc|Dword" },
227 { "OPERAND_TYPE_ACC64",
228 "Reg64|Acc|Qword" },
229 { "OPERAND_TYPE_INOUTPORTREG",
230 "InOutPortReg" },
231 { "OPERAND_TYPE_REG16_INOUTPORTREG",
232 "Reg16|InOutPortReg" },
233 { "OPERAND_TYPE_DISP16_32",
234 "Disp16|Disp32" },
235 { "OPERAND_TYPE_ANYDISP",
236 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
237 { "OPERAND_TYPE_IMM16_32",
238 "Imm16|Imm32" },
239 { "OPERAND_TYPE_IMM16_32S",
240 "Imm16|Imm32S" },
241 { "OPERAND_TYPE_IMM16_32_32S",
242 "Imm16|Imm32|Imm32S" },
243 { "OPERAND_TYPE_IMM32_32S_DISP32",
244 "Imm32|Imm32S|Disp32" },
245 { "OPERAND_TYPE_IMM64_DISP64",
246 "Imm64|Disp64" },
247 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
248 "Imm32|Imm32S|Imm64|Disp32" },
249 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
250 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
253 typedef struct bitfield
255 int position;
256 int value;
257 const char *name;
258 } bitfield;
260 #define BITFIELD(n) { n, 0, #n }
262 static bitfield cpu_flags[] =
264 BITFIELD (Cpu186),
265 BITFIELD (Cpu286),
266 BITFIELD (Cpu386),
267 BITFIELD (Cpu486),
268 BITFIELD (Cpu586),
269 BITFIELD (Cpu686),
270 BITFIELD (CpuClflush),
271 BITFIELD (CpuSYSCALL),
272 BITFIELD (Cpu8087),
273 BITFIELD (Cpu287),
274 BITFIELD (Cpu387),
275 BITFIELD (Cpu687),
276 BITFIELD (CpuFISTTP),
277 BITFIELD (CpuMMX),
278 BITFIELD (CpuSSE),
279 BITFIELD (CpuSSE2),
280 BITFIELD (CpuSSE3),
281 BITFIELD (CpuSSSE3),
282 BITFIELD (CpuSSE4_1),
283 BITFIELD (CpuSSE4_2),
284 BITFIELD (CpuAVX),
285 BITFIELD (CpuL1OM),
286 BITFIELD (CpuSSE4a),
287 BITFIELD (Cpu3dnow),
288 BITFIELD (Cpu3dnowA),
289 BITFIELD (CpuPadLock),
290 BITFIELD (CpuSVME),
291 BITFIELD (CpuVMX),
292 BITFIELD (CpuSMX),
293 BITFIELD (CpuABM),
294 BITFIELD (CpuXsave),
295 BITFIELD (CpuAES),
296 BITFIELD (CpuPCLMUL),
297 BITFIELD (CpuFMA),
298 BITFIELD (CpuFMA4),
299 BITFIELD (CpuLM),
300 BITFIELD (CpuMovbe),
301 BITFIELD (CpuEPT),
302 BITFIELD (CpuRdtscp),
303 BITFIELD (Cpu64),
304 BITFIELD (CpuNo64),
305 #ifdef CpuUnused
306 BITFIELD (CpuUnused),
307 #endif
310 static bitfield opcode_modifiers[] =
312 BITFIELD (D),
313 BITFIELD (W),
314 BITFIELD (S),
315 BITFIELD (Modrm),
316 BITFIELD (ShortForm),
317 BITFIELD (Jump),
318 BITFIELD (JumpDword),
319 BITFIELD (JumpByte),
320 BITFIELD (JumpInterSegment),
321 BITFIELD (FloatMF),
322 BITFIELD (FloatR),
323 BITFIELD (FloatD),
324 BITFIELD (Size16),
325 BITFIELD (Size32),
326 BITFIELD (Size64),
327 BITFIELD (IgnoreSize),
328 BITFIELD (DefaultSize),
329 BITFIELD (No_bSuf),
330 BITFIELD (No_wSuf),
331 BITFIELD (No_lSuf),
332 BITFIELD (No_sSuf),
333 BITFIELD (No_qSuf),
334 BITFIELD (No_ldSuf),
335 BITFIELD (FWait),
336 BITFIELD (IsString),
337 BITFIELD (RegKludge),
338 BITFIELD (FirstXmm0),
339 BITFIELD (Implicit1stXmm0),
340 BITFIELD (ByteOkIntel),
341 BITFIELD (ToDword),
342 BITFIELD (ToQword),
343 BITFIELD (AddrPrefixOp0),
344 BITFIELD (IsPrefix),
345 BITFIELD (ImmExt),
346 BITFIELD (NoRex64),
347 BITFIELD (Rex64),
348 BITFIELD (Ugh),
349 BITFIELD (Vex),
350 BITFIELD (Vex256),
351 BITFIELD (VexNDS),
352 BITFIELD (VexNDD),
353 BITFIELD (VexW0),
354 BITFIELD (VexW1),
355 BITFIELD (Vex0F),
356 BITFIELD (Vex0F38),
357 BITFIELD (Vex0F3A),
358 BITFIELD (Vex3Sources),
359 BITFIELD (VexImmExt),
360 BITFIELD (SSE2AVX),
361 BITFIELD (NoAVX),
362 BITFIELD (OldGcc),
363 BITFIELD (ATTMnemonic),
364 BITFIELD (ATTSyntax),
365 BITFIELD (IntelSyntax),
368 static bitfield operand_types[] =
370 BITFIELD (Reg8),
371 BITFIELD (Reg16),
372 BITFIELD (Reg32),
373 BITFIELD (Reg64),
374 BITFIELD (FloatReg),
375 BITFIELD (RegMMX),
376 BITFIELD (RegXMM),
377 BITFIELD (RegYMM),
378 BITFIELD (Imm8),
379 BITFIELD (Imm8S),
380 BITFIELD (Imm16),
381 BITFIELD (Imm32),
382 BITFIELD (Imm32S),
383 BITFIELD (Imm64),
384 BITFIELD (Imm1),
385 BITFIELD (BaseIndex),
386 BITFIELD (Disp8),
387 BITFIELD (Disp16),
388 BITFIELD (Disp32),
389 BITFIELD (Disp32S),
390 BITFIELD (Disp64),
391 BITFIELD (InOutPortReg),
392 BITFIELD (ShiftCount),
393 BITFIELD (Control),
394 BITFIELD (Debug),
395 BITFIELD (Test),
396 BITFIELD (SReg2),
397 BITFIELD (SReg3),
398 BITFIELD (Acc),
399 BITFIELD (FloatAcc),
400 BITFIELD (JumpAbsolute),
401 BITFIELD (EsSeg),
402 BITFIELD (RegMem),
403 BITFIELD (Mem),
404 BITFIELD (Byte),
405 BITFIELD (Word),
406 BITFIELD (Dword),
407 BITFIELD (Fword),
408 BITFIELD (Qword),
409 BITFIELD (Tbyte),
410 BITFIELD (Xmmword),
411 BITFIELD (Ymmword),
412 BITFIELD (Unspecified),
413 BITFIELD (Anysize),
414 #ifdef OTUnused
415 BITFIELD (OTUnused),
416 #endif
419 static const char *filename;
421 static int
422 compare (const void *x, const void *y)
424 const bitfield *xp = (const bitfield *) x;
425 const bitfield *yp = (const bitfield *) y;
426 return xp->position - yp->position;
429 static void
430 fail (const char *message, ...)
432 va_list args;
434 va_start (args, message);
435 fprintf (stderr, _("%s: Error: "), program_name);
436 vfprintf (stderr, message, args);
437 va_end (args);
438 xexit (1);
441 static void
442 process_copyright (FILE *fp)
444 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
445 /* Copyright 2007, 2008, 2009\n\
446 Free Software Foundation, Inc.\n\
448 This file is part of the GNU opcodes library.\n\
450 This library is free software; you can redistribute it and/or modify\n\
451 it under the terms of the GNU General Public License as published by\n\
452 the Free Software Foundation; either version 3, or (at your option)\n\
453 any later version.\n\
455 It is distributed in the hope that it will be useful, but WITHOUT\n\
456 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
457 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
458 License for more details.\n\
460 You should have received a copy of the GNU General Public License\n\
461 along with this program; if not, write to the Free Software\n\
462 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
463 MA 02110-1301, USA. */\n");
466 /* Remove leading white spaces. */
468 static char *
469 remove_leading_whitespaces (char *str)
471 while (ISSPACE (*str))
472 str++;
473 return str;
476 /* Remove trailing white spaces. */
478 static void
479 remove_trailing_whitespaces (char *str)
481 size_t last = strlen (str);
483 if (last == 0)
484 return;
488 last--;
489 if (ISSPACE (str [last]))
490 str[last] = '\0';
491 else
492 break;
494 while (last != 0);
497 /* Find next field separated by SEP and terminate it. Return a
498 pointer to the one after it. */
500 static char *
501 next_field (char *str, char sep, char **next, char *last)
503 char *p;
505 p = remove_leading_whitespaces (str);
506 for (str = p; *str != sep && *str != '\0'; str++);
508 *str = '\0';
509 remove_trailing_whitespaces (p);
511 *next = str + 1;
513 if (p >= last)
514 abort ();
516 return p;
519 static void
520 set_bitfield (const char *f, bitfield *array, int value,
521 unsigned int size, int lineno)
523 unsigned int i;
525 if (strcmp (f, "CpuFP") == 0)
527 set_bitfield("Cpu387", array, value, size, lineno);
528 set_bitfield("Cpu287", array, value, size, lineno);
529 f = "Cpu8087";
531 else if (strcmp (f, "Mmword") == 0)
532 f= "Qword";
533 else if (strcmp (f, "Oword") == 0)
534 f= "Xmmword";
536 for (i = 0; i < size; i++)
537 if (strcasecmp (array[i].name, f) == 0)
539 array[i].value = value;
540 return;
543 if (lineno != -1)
544 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
545 else
546 fail (_("Unknown bitfield: %s\n"), f);
549 static void
550 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
551 int macro, const char *comma, const char *indent)
553 unsigned int i;
555 fprintf (table, "%s{ { ", indent);
557 for (i = 0; i < size - 1; i++)
559 fprintf (table, "%d, ", flags[i].value);
560 if (((i + 1) % 20) == 0)
562 /* We need \\ for macro. */
563 if (macro)
564 fprintf (table, " \\\n %s", indent);
565 else
566 fprintf (table, "\n %s", indent);
570 fprintf (table, "%d } }%s\n", flags[i].value, comma);
573 static void
574 process_i386_cpu_flag (FILE *table, char *flag, int macro,
575 const char *comma, const char *indent,
576 int lineno)
578 char *str, *next, *last;
579 unsigned int i;
580 bitfield flags [ARRAY_SIZE (cpu_flags)];
582 /* Copy the default cpu flags. */
583 memcpy (flags, cpu_flags, sizeof (cpu_flags));
585 if (strcasecmp (flag, "unknown") == 0)
587 /* We turn on everything except for cpu64 in case of
588 CPU_UNKNOWN_FLAGS. */
589 for (i = 0; i < ARRAY_SIZE (flags); i++)
590 if (flags[i].position != Cpu64)
591 flags[i].value = 1;
593 else if (flag[0] == '~')
595 last = flag + strlen (flag);
597 if (flag[1] == '(')
599 last -= 1;
600 next = flag + 2;
601 if (*last != ')')
602 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
603 lineno, flag);
604 *last = '\0';
606 else
607 next = flag + 1;
609 /* First we turn on everything except for cpu64. */
610 for (i = 0; i < ARRAY_SIZE (flags); i++)
611 if (flags[i].position != Cpu64)
612 flags[i].value = 1;
614 /* Turn off selective bits. */
615 for (; next && next < last; )
617 str = next_field (next, '|', &next, last);
618 if (str)
619 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
622 else if (strcmp (flag, "0"))
624 /* Turn on selective bits. */
625 last = flag + strlen (flag);
626 for (next = flag; next && next < last; )
628 str = next_field (next, '|', &next, last);
629 if (str)
630 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
634 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
635 comma, indent);
638 static void
639 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
641 unsigned int i;
643 fprintf (table, " { ");
645 for (i = 0; i < size - 1; i++)
647 fprintf (table, "%d, ", modifier[i].value);
648 if (((i + 1) % 20) == 0)
649 fprintf (table, "\n ");
652 fprintf (table, "%d },\n", modifier[i].value);
655 static void
656 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
658 char *str, *next, *last;
659 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
661 /* Copy the default opcode modifier. */
662 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
664 if (strcmp (mod, "0"))
666 last = mod + strlen (mod);
667 for (next = mod; next && next < last; )
669 str = next_field (next, '|', &next, last);
670 if (str)
671 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
672 lineno);
675 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
678 static void
679 output_operand_type (FILE *table, bitfield *types, unsigned int size,
680 int macro, const char *indent)
682 unsigned int i;
684 fprintf (table, "{ { ");
686 for (i = 0; i < size - 1; i++)
688 fprintf (table, "%d, ", types[i].value);
689 if (((i + 1) % 20) == 0)
691 /* We need \\ for macro. */
692 if (macro)
693 fprintf (table, "\\\n%s", indent);
694 else
695 fprintf (table, "\n%s", indent);
699 fprintf (table, "%d } }", types[i].value);
702 static void
703 process_i386_operand_type (FILE *table, char *op, int macro,
704 const char *indent, int lineno)
706 char *str, *next, *last;
707 bitfield types [ARRAY_SIZE (operand_types)];
709 /* Copy the default operand type. */
710 memcpy (types, operand_types, sizeof (types));
712 if (strcmp (op, "0"))
714 last = op + strlen (op);
715 for (next = op; next && next < last; )
717 str = next_field (next, '|', &next, last);
718 if (str)
719 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
722 output_operand_type (table, types, ARRAY_SIZE (types), macro,
723 indent);
726 static void
727 output_i386_opcode (FILE *table, const char *name, char *str,
728 char *last, int lineno)
730 unsigned int i;
731 char *operands, *base_opcode, *extension_opcode, *opcode_length;
732 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
734 /* Find number of operands. */
735 operands = next_field (str, ',', &str, last);
737 /* Find base_opcode. */
738 base_opcode = next_field (str, ',', &str, last);
740 /* Find extension_opcode. */
741 extension_opcode = next_field (str, ',', &str, last);
743 /* Find opcode_length. */
744 opcode_length = next_field (str, ',', &str, last);
746 /* Find cpu_flags. */
747 cpu_flags = next_field (str, ',', &str, last);
749 /* Find opcode_modifier. */
750 opcode_modifier = next_field (str, ',', &str, last);
752 /* Remove the first {. */
753 str = remove_leading_whitespaces (str);
754 if (*str != '{')
755 abort ();
756 str = remove_leading_whitespaces (str + 1);
758 i = strlen (str);
760 /* There are at least "X}". */
761 if (i < 2)
762 abort ();
764 /* Remove trailing white spaces and }. */
767 i--;
768 if (ISSPACE (str[i]) || str[i] == '}')
769 str[i] = '\0';
770 else
771 break;
773 while (i != 0);
775 last = str + i;
777 /* Find operand_types. */
778 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
780 if (str >= last)
782 operand_types [i] = NULL;
783 break;
786 operand_types [i] = next_field (str, ',', &str, last);
787 if (*operand_types[i] == '0')
789 if (i != 0)
790 operand_types[i] = NULL;
791 break;
795 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
796 name, operands, base_opcode, extension_opcode,
797 opcode_length);
799 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
801 process_i386_opcode_modifier (table, opcode_modifier, lineno);
803 fprintf (table, " { ");
805 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
807 if (operand_types[i] == NULL || *operand_types[i] == '0')
809 if (i == 0)
810 process_i386_operand_type (table, "0", 0, "\t ", lineno);
811 break;
814 if (i != 0)
815 fprintf (table, ",\n ");
817 process_i386_operand_type (table, operand_types[i], 0,
818 "\t ", lineno);
820 fprintf (table, " } },\n");
823 struct opcode_hash_entry
825 struct opcode_hash_entry *next;
826 char *name;
827 char *opcode;
828 int lineno;
831 /* Calculate the hash value of an opcode hash entry P. */
833 static hashval_t
834 opcode_hash_hash (const void *p)
836 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
837 return htab_hash_string (entry->name);
840 /* Compare a string Q against an opcode hash entry P. */
842 static int
843 opcode_hash_eq (const void *p, const void *q)
845 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
846 const char *name = (const char *) q;
847 return strcmp (name, entry->name) == 0;
850 static void
851 process_i386_opcodes (FILE *table)
853 FILE *fp;
854 char buf[2048];
855 unsigned int i, j;
856 char *str, *p, *last, *name;
857 struct opcode_hash_entry **hash_slot, **entry, *next;
858 htab_t opcode_hash_table;
859 struct opcode_hash_entry **opcode_array;
860 unsigned int opcode_array_size = 1024;
861 int lineno = 0;
863 filename = "i386-opc.tbl";
864 fp = fopen (filename, "r");
866 if (fp == NULL)
867 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
868 xstrerror (errno));
870 i = 0;
871 opcode_array = (struct opcode_hash_entry **)
872 xmalloc (sizeof (*opcode_array) * opcode_array_size);
874 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
875 opcode_hash_eq, NULL,
876 xcalloc, free);
878 fprintf (table, "\n/* i386 opcode table. */\n\n");
879 fprintf (table, "const template i386_optab[] =\n{\n");
881 /* Put everything on opcode array. */
882 while (!feof (fp))
884 if (fgets (buf, sizeof (buf), fp) == NULL)
885 break;
887 lineno++;
889 p = remove_leading_whitespaces (buf);
891 /* Skip comments. */
892 str = strstr (p, "//");
893 if (str != NULL)
894 str[0] = '\0';
896 /* Remove trailing white spaces. */
897 remove_trailing_whitespaces (p);
899 switch (p[0])
901 case '#':
902 /* Ignore comments. */
903 case '\0':
904 continue;
905 break;
906 default:
907 break;
910 last = p + strlen (p);
912 /* Find name. */
913 name = next_field (p, ',', &str, last);
915 /* Get the slot in hash table. */
916 hash_slot = (struct opcode_hash_entry **)
917 htab_find_slot_with_hash (opcode_hash_table, name,
918 htab_hash_string (name),
919 INSERT);
921 if (*hash_slot == NULL)
923 /* It is the new one. Put it on opcode array. */
924 if (i >= opcode_array_size)
926 /* Grow the opcode array when needed. */
927 opcode_array_size += 1024;
928 opcode_array = (struct opcode_hash_entry **)
929 xrealloc (opcode_array,
930 sizeof (*opcode_array) * opcode_array_size);
933 opcode_array[i] = (struct opcode_hash_entry *)
934 xmalloc (sizeof (struct opcode_hash_entry));
935 opcode_array[i]->next = NULL;
936 opcode_array[i]->name = xstrdup (name);
937 opcode_array[i]->opcode = xstrdup (str);
938 opcode_array[i]->lineno = lineno;
939 *hash_slot = opcode_array[i];
940 i++;
942 else
944 /* Append it to the existing one. */
945 entry = hash_slot;
946 while ((*entry) != NULL)
947 entry = &(*entry)->next;
948 *entry = (struct opcode_hash_entry *)
949 xmalloc (sizeof (struct opcode_hash_entry));
950 (*entry)->next = NULL;
951 (*entry)->name = (*hash_slot)->name;
952 (*entry)->opcode = xstrdup (str);
953 (*entry)->lineno = lineno;
957 /* Process opcode array. */
958 for (j = 0; j < i; j++)
960 for (next = opcode_array[j]; next; next = next->next)
962 name = next->name;
963 str = next->opcode;
964 lineno = next->lineno;
965 last = str + strlen (str);
966 output_i386_opcode (table, name, str, last, lineno);
970 fclose (fp);
972 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
974 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
976 process_i386_opcode_modifier (table, "0", -1);
978 fprintf (table, " { ");
979 process_i386_operand_type (table, "0", 0, "\t ", -1);
980 fprintf (table, " } }\n");
982 fprintf (table, "};\n");
985 static void
986 process_i386_registers (FILE *table)
988 FILE *fp;
989 char buf[2048];
990 char *str, *p, *last;
991 char *reg_name, *reg_type, *reg_flags, *reg_num;
992 char *dw2_32_num, *dw2_64_num;
993 int lineno = 0;
995 filename = "i386-reg.tbl";
996 fp = fopen (filename, "r");
997 if (fp == NULL)
998 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
999 xstrerror (errno));
1001 fprintf (table, "\n/* i386 register table. */\n\n");
1002 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1004 while (!feof (fp))
1006 if (fgets (buf, sizeof (buf), fp) == NULL)
1007 break;
1009 lineno++;
1011 p = remove_leading_whitespaces (buf);
1013 /* Skip comments. */
1014 str = strstr (p, "//");
1015 if (str != NULL)
1016 str[0] = '\0';
1018 /* Remove trailing white spaces. */
1019 remove_trailing_whitespaces (p);
1021 switch (p[0])
1023 case '#':
1024 fprintf (table, "%s\n", p);
1025 case '\0':
1026 continue;
1027 break;
1028 default:
1029 break;
1032 last = p + strlen (p);
1034 /* Find reg_name. */
1035 reg_name = next_field (p, ',', &str, last);
1037 /* Find reg_type. */
1038 reg_type = next_field (str, ',', &str, last);
1040 /* Find reg_flags. */
1041 reg_flags = next_field (str, ',', &str, last);
1043 /* Find reg_num. */
1044 reg_num = next_field (str, ',', &str, last);
1046 fprintf (table, " { \"%s\",\n ", reg_name);
1048 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1050 /* Find 32-bit Dwarf2 register number. */
1051 dw2_32_num = next_field (str, ',', &str, last);
1053 /* Find 64-bit Dwarf2 register number. */
1054 dw2_64_num = next_field (str, ',', &str, last);
1056 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1057 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1060 fclose (fp);
1062 fprintf (table, "};\n");
1064 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1067 static void
1068 process_i386_initializers (void)
1070 unsigned int i;
1071 FILE *fp = fopen ("i386-init.h", "w");
1072 char *init;
1074 if (fp == NULL)
1075 fail (_("can't create i386-init.h, errno = %s\n"),
1076 xstrerror (errno));
1078 process_copyright (fp);
1080 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1082 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1083 init = xstrdup (cpu_flag_init[i].init);
1084 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1085 free (init);
1088 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1090 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1091 init = xstrdup (operand_type_init[i].init);
1092 process_i386_operand_type (fp, init, 1, " ", -1);
1093 free (init);
1095 fprintf (fp, "\n");
1097 fclose (fp);
1100 /* Program options. */
1101 #define OPTION_SRCDIR 200
1103 struct option long_options[] =
1105 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1106 {"debug", no_argument, NULL, 'd'},
1107 {"version", no_argument, NULL, 'V'},
1108 {"help", no_argument, NULL, 'h'},
1109 {0, no_argument, NULL, 0}
1112 static void
1113 print_version (void)
1115 printf ("%s: version 1.0\n", program_name);
1116 xexit (0);
1119 static void
1120 usage (FILE * stream, int status)
1122 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1123 program_name);
1124 xexit (status);
1128 main (int argc, char **argv)
1130 extern int chdir (char *);
1131 char *srcdir = NULL;
1132 int c;
1133 FILE *table;
1135 program_name = *argv;
1136 xmalloc_set_program_name (program_name);
1138 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1139 switch (c)
1141 case OPTION_SRCDIR:
1142 srcdir = optarg;
1143 break;
1144 case 'V':
1145 case 'v':
1146 print_version ();
1147 break;
1148 case 'd':
1149 debug = 1;
1150 break;
1151 case 'h':
1152 case '?':
1153 usage (stderr, 0);
1154 default:
1155 case 0:
1156 break;
1159 if (optind != argc)
1160 usage (stdout, 1);
1162 if (srcdir != NULL)
1163 if (chdir (srcdir) != 0)
1164 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1165 srcdir, xstrerror (errno));
1167 /* Check the unused bitfield in i386_cpu_flags. */
1168 #ifndef CpuUnused
1169 c = CpuNumOfBits - CpuMax - 1;
1170 if (c)
1171 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1172 #endif
1174 /* Check the unused bitfield in i386_operand_type. */
1175 #ifndef OTUnused
1176 c = OTNumOfBits - OTMax - 1;
1177 if (c)
1178 fail (_("%d unused bits in i386_operand_type.\n"), c);
1179 #endif
1181 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1182 compare);
1184 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1185 sizeof (opcode_modifiers [0]), compare);
1187 qsort (operand_types, ARRAY_SIZE (operand_types),
1188 sizeof (operand_types [0]), compare);
1190 table = fopen ("i386-tbl.h", "w");
1191 if (table == NULL)
1192 fail (_("can't create i386-tbl.h, errno = %s\n"),
1193 xstrerror (errno));
1195 process_copyright (table);
1197 process_i386_opcodes (table);
1198 process_i386_registers (table);
1199 process_i386_initializers ();
1201 fclose (table);
1203 exit (0);