PR 11123
[binutils.git] / opcodes / i386-gen.c
blobdde7c2c9f56bdb6903cedd88397263ac0ca56f65
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_XOP_FLAGS",
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
133 { "CPU_LWP_FLAGS",
134 "CpuLWP" },
135 { "CPU_MOVBE_FLAGS",
136 "CpuMovbe" },
137 { "CPU_RDTSCP_FLAGS",
138 "CpuRdtscp" },
139 { "CPU_EPT_FLAGS",
140 "CpuEPT" },
141 { "CPU_3DNOW_FLAGS",
142 "CpuMMX|Cpu3dnow" },
143 { "CPU_3DNOWA_FLAGS",
144 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
145 { "CPU_PADLOCK_FLAGS",
146 "CpuPadLock" },
147 { "CPU_SVME_FLAGS",
148 "CpuSVME" },
149 { "CPU_SSE4A_FLAGS",
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
151 { "CPU_ABM_FLAGS",
152 "CpuABM" },
153 { "CPU_AVX_FLAGS",
154 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
155 { "CPU_ANY_AVX_FLAGS",
156 "CpuAVX" },
157 { "CPU_L1OM_FLAGS",
158 "unknown" },
161 static initializer operand_type_init[] =
163 { "OPERAND_TYPE_NONE",
164 "0" },
165 { "OPERAND_TYPE_REG8",
166 "Reg8" },
167 { "OPERAND_TYPE_REG16",
168 "Reg16" },
169 { "OPERAND_TYPE_REG32",
170 "Reg32" },
171 { "OPERAND_TYPE_REG64",
172 "Reg64" },
173 { "OPERAND_TYPE_IMM1",
174 "Imm1" },
175 { "OPERAND_TYPE_IMM8",
176 "Imm8" },
177 { "OPERAND_TYPE_IMM8S",
178 "Imm8S" },
179 { "OPERAND_TYPE_IMM16",
180 "Imm16" },
181 { "OPERAND_TYPE_IMM32",
182 "Imm32" },
183 { "OPERAND_TYPE_IMM32S",
184 "Imm32S" },
185 { "OPERAND_TYPE_IMM64",
186 "Imm64" },
187 { "OPERAND_TYPE_BASEINDEX",
188 "BaseIndex" },
189 { "OPERAND_TYPE_DISP8",
190 "Disp8" },
191 { "OPERAND_TYPE_DISP16",
192 "Disp16" },
193 { "OPERAND_TYPE_DISP32",
194 "Disp32" },
195 { "OPERAND_TYPE_DISP32S",
196 "Disp32S" },
197 { "OPERAND_TYPE_DISP64",
198 "Disp64" },
199 { "OPERAND_TYPE_INOUTPORTREG",
200 "InOutPortReg" },
201 { "OPERAND_TYPE_SHIFTCOUNT",
202 "ShiftCount" },
203 { "OPERAND_TYPE_CONTROL",
204 "Control" },
205 { "OPERAND_TYPE_TEST",
206 "Test" },
207 { "OPERAND_TYPE_DEBUG",
208 "FloatReg" },
209 { "OPERAND_TYPE_FLOATREG",
210 "FloatReg" },
211 { "OPERAND_TYPE_FLOATACC",
212 "FloatAcc" },
213 { "OPERAND_TYPE_SREG2",
214 "SReg2" },
215 { "OPERAND_TYPE_SREG3",
216 "SReg3" },
217 { "OPERAND_TYPE_ACC",
218 "Acc" },
219 { "OPERAND_TYPE_JUMPABSOLUTE",
220 "JumpAbsolute" },
221 { "OPERAND_TYPE_REGMMX",
222 "RegMMX" },
223 { "OPERAND_TYPE_REGXMM",
224 "RegXMM" },
225 { "OPERAND_TYPE_REGYMM",
226 "RegYMM" },
227 { "OPERAND_TYPE_ESSEG",
228 "EsSeg" },
229 { "OPERAND_TYPE_ACC32",
230 "Reg32|Acc|Dword" },
231 { "OPERAND_TYPE_ACC64",
232 "Reg64|Acc|Qword" },
233 { "OPERAND_TYPE_INOUTPORTREG",
234 "InOutPortReg" },
235 { "OPERAND_TYPE_REG16_INOUTPORTREG",
236 "Reg16|InOutPortReg" },
237 { "OPERAND_TYPE_DISP16_32",
238 "Disp16|Disp32" },
239 { "OPERAND_TYPE_ANYDISP",
240 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
241 { "OPERAND_TYPE_IMM16_32",
242 "Imm16|Imm32" },
243 { "OPERAND_TYPE_IMM16_32S",
244 "Imm16|Imm32S" },
245 { "OPERAND_TYPE_IMM16_32_32S",
246 "Imm16|Imm32|Imm32S" },
247 { "OPERAND_TYPE_IMM32_32S_DISP32",
248 "Imm32|Imm32S|Disp32" },
249 { "OPERAND_TYPE_IMM64_DISP64",
250 "Imm64|Disp64" },
251 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
252 "Imm32|Imm32S|Imm64|Disp32" },
253 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
254 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
257 typedef struct bitfield
259 int position;
260 int value;
261 const char *name;
262 } bitfield;
264 #define BITFIELD(n) { n, 0, #n }
266 static bitfield cpu_flags[] =
268 BITFIELD (Cpu186),
269 BITFIELD (Cpu286),
270 BITFIELD (Cpu386),
271 BITFIELD (Cpu486),
272 BITFIELD (Cpu586),
273 BITFIELD (Cpu686),
274 BITFIELD (CpuClflush),
275 BITFIELD (CpuSYSCALL),
276 BITFIELD (Cpu8087),
277 BITFIELD (Cpu287),
278 BITFIELD (Cpu387),
279 BITFIELD (Cpu687),
280 BITFIELD (CpuFISTTP),
281 BITFIELD (CpuMMX),
282 BITFIELD (CpuSSE),
283 BITFIELD (CpuSSE2),
284 BITFIELD (CpuSSE3),
285 BITFIELD (CpuSSSE3),
286 BITFIELD (CpuSSE4_1),
287 BITFIELD (CpuSSE4_2),
288 BITFIELD (CpuAVX),
289 BITFIELD (CpuL1OM),
290 BITFIELD (CpuSSE4a),
291 BITFIELD (Cpu3dnow),
292 BITFIELD (Cpu3dnowA),
293 BITFIELD (CpuPadLock),
294 BITFIELD (CpuSVME),
295 BITFIELD (CpuVMX),
296 BITFIELD (CpuSMX),
297 BITFIELD (CpuABM),
298 BITFIELD (CpuXsave),
299 BITFIELD (CpuAES),
300 BITFIELD (CpuPCLMUL),
301 BITFIELD (CpuFMA),
302 BITFIELD (CpuFMA4),
303 BITFIELD (CpuXOP),
304 BITFIELD (CpuLWP),
305 BITFIELD (CpuLM),
306 BITFIELD (CpuMovbe),
307 BITFIELD (CpuEPT),
308 BITFIELD (CpuRdtscp),
309 BITFIELD (Cpu64),
310 BITFIELD (CpuNo64),
311 #ifdef CpuUnused
312 BITFIELD (CpuUnused),
313 #endif
316 static bitfield opcode_modifiers[] =
318 BITFIELD (D),
319 BITFIELD (W),
320 BITFIELD (S),
321 BITFIELD (Modrm),
322 BITFIELD (ShortForm),
323 BITFIELD (Jump),
324 BITFIELD (JumpDword),
325 BITFIELD (JumpByte),
326 BITFIELD (JumpInterSegment),
327 BITFIELD (FloatMF),
328 BITFIELD (FloatR),
329 BITFIELD (FloatD),
330 BITFIELD (Size16),
331 BITFIELD (Size32),
332 BITFIELD (Size64),
333 BITFIELD (IgnoreSize),
334 BITFIELD (DefaultSize),
335 BITFIELD (No_bSuf),
336 BITFIELD (No_wSuf),
337 BITFIELD (No_lSuf),
338 BITFIELD (No_sSuf),
339 BITFIELD (No_qSuf),
340 BITFIELD (No_ldSuf),
341 BITFIELD (FWait),
342 BITFIELD (IsString),
343 BITFIELD (IsLockable),
344 BITFIELD (RegKludge),
345 BITFIELD (FirstXmm0),
346 BITFIELD (Implicit1stXmm0),
347 BITFIELD (ToDword),
348 BITFIELD (ToQword),
349 BITFIELD (AddrPrefixOp0),
350 BITFIELD (IsPrefix),
351 BITFIELD (ImmExt),
352 BITFIELD (NoRex64),
353 BITFIELD (Rex64),
354 BITFIELD (Ugh),
355 BITFIELD (Vex),
356 BITFIELD (VexVVVV),
357 BITFIELD (VexW),
358 BITFIELD (VexOpcode),
359 BITFIELD (VexSources),
360 BITFIELD (VexImmExt),
361 BITFIELD (SSE2AVX),
362 BITFIELD (NoAVX),
363 BITFIELD (OldGcc),
364 BITFIELD (ATTMnemonic),
365 BITFIELD (ATTSyntax),
366 BITFIELD (IntelSyntax),
369 static bitfield operand_types[] =
371 BITFIELD (Reg8),
372 BITFIELD (Reg16),
373 BITFIELD (Reg32),
374 BITFIELD (Reg64),
375 BITFIELD (FloatReg),
376 BITFIELD (RegMMX),
377 BITFIELD (RegXMM),
378 BITFIELD (RegYMM),
379 BITFIELD (Imm1),
380 BITFIELD (Imm8),
381 BITFIELD (Imm8S),
382 BITFIELD (Imm16),
383 BITFIELD (Imm32),
384 BITFIELD (Imm32S),
385 BITFIELD (Imm64),
386 BITFIELD (BaseIndex),
387 BITFIELD (Disp8),
388 BITFIELD (Disp16),
389 BITFIELD (Disp32),
390 BITFIELD (Disp32S),
391 BITFIELD (Disp64),
392 BITFIELD (InOutPortReg),
393 BITFIELD (ShiftCount),
394 BITFIELD (Control),
395 BITFIELD (Debug),
396 BITFIELD (Test),
397 BITFIELD (SReg2),
398 BITFIELD (SReg3),
399 BITFIELD (Acc),
400 BITFIELD (FloatAcc),
401 BITFIELD (JumpAbsolute),
402 BITFIELD (EsSeg),
403 BITFIELD (RegMem),
404 BITFIELD (Mem),
405 BITFIELD (Byte),
406 BITFIELD (Word),
407 BITFIELD (Dword),
408 BITFIELD (Fword),
409 BITFIELD (Qword),
410 BITFIELD (Tbyte),
411 BITFIELD (Xmmword),
412 BITFIELD (Ymmword),
413 BITFIELD (Unspecified),
414 BITFIELD (Anysize),
415 #ifdef OTUnused
416 BITFIELD (OTUnused),
417 #endif
420 static const char *filename;
422 static int
423 compare (const void *x, const void *y)
425 const bitfield *xp = (const bitfield *) x;
426 const bitfield *yp = (const bitfield *) y;
427 return xp->position - yp->position;
430 static void
431 fail (const char *message, ...)
433 va_list args;
435 va_start (args, message);
436 fprintf (stderr, _("%s: Error: "), program_name);
437 vfprintf (stderr, message, args);
438 va_end (args);
439 xexit (1);
442 static void
443 process_copyright (FILE *fp)
445 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
446 /* Copyright 2007, 2008, 2009\n\
447 Free Software Foundation, Inc.\n\
449 This file is part of the GNU opcodes library.\n\
451 This library is free software; you can redistribute it and/or modify\n\
452 it under the terms of the GNU General Public License as published by\n\
453 the Free Software Foundation; either version 3, or (at your option)\n\
454 any later version.\n\
456 It is distributed in the hope that it will be useful, but WITHOUT\n\
457 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
458 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
459 License for more details.\n\
461 You should have received a copy of the GNU General Public License\n\
462 along with this program; if not, write to the Free Software\n\
463 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
464 MA 02110-1301, USA. */\n");
467 /* Remove leading white spaces. */
469 static char *
470 remove_leading_whitespaces (char *str)
472 while (ISSPACE (*str))
473 str++;
474 return str;
477 /* Remove trailing white spaces. */
479 static void
480 remove_trailing_whitespaces (char *str)
482 size_t last = strlen (str);
484 if (last == 0)
485 return;
489 last--;
490 if (ISSPACE (str [last]))
491 str[last] = '\0';
492 else
493 break;
495 while (last != 0);
498 /* Find next field separated by SEP and terminate it. Return a
499 pointer to the one after it. */
501 static char *
502 next_field (char *str, char sep, char **next, char *last)
504 char *p;
506 p = remove_leading_whitespaces (str);
507 for (str = p; *str != sep && *str != '\0'; str++);
509 *str = '\0';
510 remove_trailing_whitespaces (p);
512 *next = str + 1;
514 if (p >= last)
515 abort ();
517 return p;
520 static void
521 set_bitfield (const char *f, bitfield *array, int value,
522 unsigned int size, int lineno)
524 unsigned int i;
526 if (strcmp (f, "CpuFP") == 0)
528 set_bitfield("Cpu387", array, value, size, lineno);
529 set_bitfield("Cpu287", array, value, size, lineno);
530 f = "Cpu8087";
532 else if (strcmp (f, "Mmword") == 0)
533 f= "Qword";
534 else if (strcmp (f, "Oword") == 0)
535 f= "Xmmword";
537 for (i = 0; i < size; i++)
538 if (strcasecmp (array[i].name, f) == 0)
540 array[i].value = value;
541 return;
544 if (value)
546 const char *v = strchr (f, '=');
548 if (v)
550 size_t n = v - f;
551 char *end;
553 for (i = 0; i < size; i++)
554 if (strncasecmp (array[i].name, f, n) == 0)
556 value = strtol (v + 1, &end, 0);
557 if (*end == '\0')
559 array[i].value = value;
560 return;
562 break;
567 if (lineno != -1)
568 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
569 else
570 fail (_("Unknown bitfield: %s\n"), f);
573 static void
574 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
575 int macro, const char *comma, const char *indent)
577 unsigned int i;
579 fprintf (table, "%s{ { ", indent);
581 for (i = 0; i < size - 1; i++)
583 fprintf (table, "%d, ", flags[i].value);
584 if (((i + 1) % 20) == 0)
586 /* We need \\ for macro. */
587 if (macro)
588 fprintf (table, " \\\n %s", indent);
589 else
590 fprintf (table, "\n %s", indent);
594 fprintf (table, "%d } }%s\n", flags[i].value, comma);
597 static void
598 process_i386_cpu_flag (FILE *table, char *flag, int macro,
599 const char *comma, const char *indent,
600 int lineno)
602 char *str, *next, *last;
603 unsigned int i;
604 bitfield flags [ARRAY_SIZE (cpu_flags)];
606 /* Copy the default cpu flags. */
607 memcpy (flags, cpu_flags, sizeof (cpu_flags));
609 if (strcasecmp (flag, "unknown") == 0)
611 /* We turn on everything except for cpu64 in case of
612 CPU_UNKNOWN_FLAGS. */
613 for (i = 0; i < ARRAY_SIZE (flags); i++)
614 if (flags[i].position != Cpu64)
615 flags[i].value = 1;
617 else if (flag[0] == '~')
619 last = flag + strlen (flag);
621 if (flag[1] == '(')
623 last -= 1;
624 next = flag + 2;
625 if (*last != ')')
626 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
627 lineno, flag);
628 *last = '\0';
630 else
631 next = flag + 1;
633 /* First we turn on everything except for cpu64. */
634 for (i = 0; i < ARRAY_SIZE (flags); i++)
635 if (flags[i].position != Cpu64)
636 flags[i].value = 1;
638 /* Turn off selective bits. */
639 for (; next && next < last; )
641 str = next_field (next, '|', &next, last);
642 if (str)
643 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
646 else if (strcmp (flag, "0"))
648 /* Turn on selective bits. */
649 last = flag + strlen (flag);
650 for (next = flag; next && next < last; )
652 str = next_field (next, '|', &next, last);
653 if (str)
654 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
658 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
659 comma, indent);
662 static void
663 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
665 unsigned int i;
667 fprintf (table, " { ");
669 for (i = 0; i < size - 1; i++)
671 fprintf (table, "%d, ", modifier[i].value);
672 if (((i + 1) % 20) == 0)
673 fprintf (table, "\n ");
676 fprintf (table, "%d },\n", modifier[i].value);
679 static void
680 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
682 char *str, *next, *last;
683 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
685 /* Copy the default opcode modifier. */
686 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
688 if (strcmp (mod, "0"))
690 last = mod + strlen (mod);
691 for (next = mod; next && next < last; )
693 str = next_field (next, '|', &next, last);
694 if (str)
695 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
696 lineno);
699 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
702 static void
703 output_operand_type (FILE *table, bitfield *types, unsigned int size,
704 int macro, const char *indent)
706 unsigned int i;
708 fprintf (table, "{ { ");
710 for (i = 0; i < size - 1; i++)
712 fprintf (table, "%d, ", types[i].value);
713 if (((i + 1) % 20) == 0)
715 /* We need \\ for macro. */
716 if (macro)
717 fprintf (table, "\\\n%s", indent);
718 else
719 fprintf (table, "\n%s", indent);
723 fprintf (table, "%d } }", types[i].value);
726 static void
727 process_i386_operand_type (FILE *table, char *op, int macro,
728 const char *indent, int lineno)
730 char *str, *next, *last;
731 bitfield types [ARRAY_SIZE (operand_types)];
733 /* Copy the default operand type. */
734 memcpy (types, operand_types, sizeof (types));
736 if (strcmp (op, "0"))
738 last = op + strlen (op);
739 for (next = op; next && next < last; )
741 str = next_field (next, '|', &next, last);
742 if (str)
743 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
746 output_operand_type (table, types, ARRAY_SIZE (types), macro,
747 indent);
750 static void
751 output_i386_opcode (FILE *table, const char *name, char *str,
752 char *last, int lineno)
754 unsigned int i;
755 char *operands, *base_opcode, *extension_opcode, *opcode_length;
756 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
758 /* Find number of operands. */
759 operands = next_field (str, ',', &str, last);
761 /* Find base_opcode. */
762 base_opcode = next_field (str, ',', &str, last);
764 /* Find extension_opcode. */
765 extension_opcode = next_field (str, ',', &str, last);
767 /* Find opcode_length. */
768 opcode_length = next_field (str, ',', &str, last);
770 /* Find cpu_flags. */
771 cpu_flags = next_field (str, ',', &str, last);
773 /* Find opcode_modifier. */
774 opcode_modifier = next_field (str, ',', &str, last);
776 /* Remove the first {. */
777 str = remove_leading_whitespaces (str);
778 if (*str != '{')
779 abort ();
780 str = remove_leading_whitespaces (str + 1);
782 i = strlen (str);
784 /* There are at least "X}". */
785 if (i < 2)
786 abort ();
788 /* Remove trailing white spaces and }. */
791 i--;
792 if (ISSPACE (str[i]) || str[i] == '}')
793 str[i] = '\0';
794 else
795 break;
797 while (i != 0);
799 last = str + i;
801 /* Find operand_types. */
802 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
804 if (str >= last)
806 operand_types [i] = NULL;
807 break;
810 operand_types [i] = next_field (str, ',', &str, last);
811 if (*operand_types[i] == '0')
813 if (i != 0)
814 operand_types[i] = NULL;
815 break;
819 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
820 name, operands, base_opcode, extension_opcode,
821 opcode_length);
823 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
825 process_i386_opcode_modifier (table, opcode_modifier, lineno);
827 fprintf (table, " { ");
829 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
831 if (operand_types[i] == NULL || *operand_types[i] == '0')
833 if (i == 0)
834 process_i386_operand_type (table, "0", 0, "\t ", lineno);
835 break;
838 if (i != 0)
839 fprintf (table, ",\n ");
841 process_i386_operand_type (table, operand_types[i], 0,
842 "\t ", lineno);
844 fprintf (table, " } },\n");
847 struct opcode_hash_entry
849 struct opcode_hash_entry *next;
850 char *name;
851 char *opcode;
852 int lineno;
855 /* Calculate the hash value of an opcode hash entry P. */
857 static hashval_t
858 opcode_hash_hash (const void *p)
860 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
861 return htab_hash_string (entry->name);
864 /* Compare a string Q against an opcode hash entry P. */
866 static int
867 opcode_hash_eq (const void *p, const void *q)
869 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
870 const char *name = (const char *) q;
871 return strcmp (name, entry->name) == 0;
874 static void
875 process_i386_opcodes (FILE *table)
877 FILE *fp;
878 char buf[2048];
879 unsigned int i, j;
880 char *str, *p, *last, *name;
881 struct opcode_hash_entry **hash_slot, **entry, *next;
882 htab_t opcode_hash_table;
883 struct opcode_hash_entry **opcode_array;
884 unsigned int opcode_array_size = 1024;
885 int lineno = 0;
887 filename = "i386-opc.tbl";
888 fp = fopen (filename, "r");
890 if (fp == NULL)
891 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
892 xstrerror (errno));
894 i = 0;
895 opcode_array = (struct opcode_hash_entry **)
896 xmalloc (sizeof (*opcode_array) * opcode_array_size);
898 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
899 opcode_hash_eq, NULL,
900 xcalloc, free);
902 fprintf (table, "\n/* i386 opcode table. */\n\n");
903 fprintf (table, "const insn_template i386_optab[] =\n{\n");
905 /* Put everything on opcode array. */
906 while (!feof (fp))
908 if (fgets (buf, sizeof (buf), fp) == NULL)
909 break;
911 lineno++;
913 p = remove_leading_whitespaces (buf);
915 /* Skip comments. */
916 str = strstr (p, "//");
917 if (str != NULL)
918 str[0] = '\0';
920 /* Remove trailing white spaces. */
921 remove_trailing_whitespaces (p);
923 switch (p[0])
925 case '#':
926 /* Ignore comments. */
927 case '\0':
928 continue;
929 break;
930 default:
931 break;
934 last = p + strlen (p);
936 /* Find name. */
937 name = next_field (p, ',', &str, last);
939 /* Get the slot in hash table. */
940 hash_slot = (struct opcode_hash_entry **)
941 htab_find_slot_with_hash (opcode_hash_table, name,
942 htab_hash_string (name),
943 INSERT);
945 if (*hash_slot == NULL)
947 /* It is the new one. Put it on opcode array. */
948 if (i >= opcode_array_size)
950 /* Grow the opcode array when needed. */
951 opcode_array_size += 1024;
952 opcode_array = (struct opcode_hash_entry **)
953 xrealloc (opcode_array,
954 sizeof (*opcode_array) * opcode_array_size);
957 opcode_array[i] = (struct opcode_hash_entry *)
958 xmalloc (sizeof (struct opcode_hash_entry));
959 opcode_array[i]->next = NULL;
960 opcode_array[i]->name = xstrdup (name);
961 opcode_array[i]->opcode = xstrdup (str);
962 opcode_array[i]->lineno = lineno;
963 *hash_slot = opcode_array[i];
964 i++;
966 else
968 /* Append it to the existing one. */
969 entry = hash_slot;
970 while ((*entry) != NULL)
971 entry = &(*entry)->next;
972 *entry = (struct opcode_hash_entry *)
973 xmalloc (sizeof (struct opcode_hash_entry));
974 (*entry)->next = NULL;
975 (*entry)->name = (*hash_slot)->name;
976 (*entry)->opcode = xstrdup (str);
977 (*entry)->lineno = lineno;
981 /* Process opcode array. */
982 for (j = 0; j < i; j++)
984 for (next = opcode_array[j]; next; next = next->next)
986 name = next->name;
987 str = next->opcode;
988 lineno = next->lineno;
989 last = str + strlen (str);
990 output_i386_opcode (table, name, str, last, lineno);
994 fclose (fp);
996 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
998 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1000 process_i386_opcode_modifier (table, "0", -1);
1002 fprintf (table, " { ");
1003 process_i386_operand_type (table, "0", 0, "\t ", -1);
1004 fprintf (table, " } }\n");
1006 fprintf (table, "};\n");
1009 static void
1010 process_i386_registers (FILE *table)
1012 FILE *fp;
1013 char buf[2048];
1014 char *str, *p, *last;
1015 char *reg_name, *reg_type, *reg_flags, *reg_num;
1016 char *dw2_32_num, *dw2_64_num;
1017 int lineno = 0;
1019 filename = "i386-reg.tbl";
1020 fp = fopen (filename, "r");
1021 if (fp == NULL)
1022 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1023 xstrerror (errno));
1025 fprintf (table, "\n/* i386 register table. */\n\n");
1026 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1028 while (!feof (fp))
1030 if (fgets (buf, sizeof (buf), fp) == NULL)
1031 break;
1033 lineno++;
1035 p = remove_leading_whitespaces (buf);
1037 /* Skip comments. */
1038 str = strstr (p, "//");
1039 if (str != NULL)
1040 str[0] = '\0';
1042 /* Remove trailing white spaces. */
1043 remove_trailing_whitespaces (p);
1045 switch (p[0])
1047 case '#':
1048 fprintf (table, "%s\n", p);
1049 case '\0':
1050 continue;
1051 break;
1052 default:
1053 break;
1056 last = p + strlen (p);
1058 /* Find reg_name. */
1059 reg_name = next_field (p, ',', &str, last);
1061 /* Find reg_type. */
1062 reg_type = next_field (str, ',', &str, last);
1064 /* Find reg_flags. */
1065 reg_flags = next_field (str, ',', &str, last);
1067 /* Find reg_num. */
1068 reg_num = next_field (str, ',', &str, last);
1070 fprintf (table, " { \"%s\",\n ", reg_name);
1072 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1074 /* Find 32-bit Dwarf2 register number. */
1075 dw2_32_num = next_field (str, ',', &str, last);
1077 /* Find 64-bit Dwarf2 register number. */
1078 dw2_64_num = next_field (str, ',', &str, last);
1080 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1081 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1084 fclose (fp);
1086 fprintf (table, "};\n");
1088 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1091 static void
1092 process_i386_initializers (void)
1094 unsigned int i;
1095 FILE *fp = fopen ("i386-init.h", "w");
1096 char *init;
1098 if (fp == NULL)
1099 fail (_("can't create i386-init.h, errno = %s\n"),
1100 xstrerror (errno));
1102 process_copyright (fp);
1104 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1106 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1107 init = xstrdup (cpu_flag_init[i].init);
1108 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1109 free (init);
1112 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1114 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1115 init = xstrdup (operand_type_init[i].init);
1116 process_i386_operand_type (fp, init, 1, " ", -1);
1117 free (init);
1119 fprintf (fp, "\n");
1121 fclose (fp);
1124 /* Program options. */
1125 #define OPTION_SRCDIR 200
1127 struct option long_options[] =
1129 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1130 {"debug", no_argument, NULL, 'd'},
1131 {"version", no_argument, NULL, 'V'},
1132 {"help", no_argument, NULL, 'h'},
1133 {0, no_argument, NULL, 0}
1136 static void
1137 print_version (void)
1139 printf ("%s: version 1.0\n", program_name);
1140 xexit (0);
1143 static void
1144 usage (FILE * stream, int status)
1146 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1147 program_name);
1148 xexit (status);
1152 main (int argc, char **argv)
1154 extern int chdir (char *);
1155 char *srcdir = NULL;
1156 int c;
1157 FILE *table;
1159 program_name = *argv;
1160 xmalloc_set_program_name (program_name);
1162 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1163 switch (c)
1165 case OPTION_SRCDIR:
1166 srcdir = optarg;
1167 break;
1168 case 'V':
1169 case 'v':
1170 print_version ();
1171 break;
1172 case 'd':
1173 debug = 1;
1174 break;
1175 case 'h':
1176 case '?':
1177 usage (stderr, 0);
1178 default:
1179 case 0:
1180 break;
1183 if (optind != argc)
1184 usage (stdout, 1);
1186 if (srcdir != NULL)
1187 if (chdir (srcdir) != 0)
1188 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1189 srcdir, xstrerror (errno));
1191 /* Check the unused bitfield in i386_cpu_flags. */
1192 #ifndef CpuUnused
1193 c = CpuNumOfBits - CpuMax - 1;
1194 if (c)
1195 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1196 #endif
1198 /* Check the unused bitfield in i386_operand_type. */
1199 #ifndef OTUnused
1200 c = OTNumOfBits - OTMax - 1;
1201 if (c)
1202 fail (_("%d unused bits in i386_operand_type.\n"), c);
1203 #endif
1205 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1206 compare);
1208 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1209 sizeof (opcode_modifiers [0]), compare);
1211 qsort (operand_types, ARRAY_SIZE (operand_types),
1212 sizeof (operand_types [0]), compare);
1214 table = fopen ("i386-tbl.h", "w");
1215 if (table == NULL)
1216 fail (_("can't create i386-tbl.h, errno = %s\n"),
1217 xstrerror (errno));
1219 process_copyright (table);
1221 process_i386_opcodes (table);
1222 process_i386_registers (table);
1223 process_i386_initializers ();
1225 fclose (table);
1227 exit (0);